1 use core::{ 2 cell::UnsafeCell, 3 fmt::Debug, 4 ops::{Deref, DerefMut}, 5 }; 6 7 use alloc::{ 8 string::String, 9 sync::{Arc, Weak}, 10 }; 11 use smoltcp::{iface, phy, wire}; 12 use virtio_drivers::{device::net::VirtIONet, transport::Transport}; 13 14 use super::NetDriver; 15 use crate::{ 16 arch::rand::rand, 17 driver::{ 18 base::{ 19 device::{bus::Bus, driver::Driver, Device, DeviceId, IdTable}, 20 kobject::{KObjType, KObject, KObjectState}, 21 }, 22 virtio::{irq::virtio_irq_manager, virtio_impl::HalImpl, VirtIODevice}, 23 }, 24 exception::{irqdesc::IrqReturn, IrqNumber}, 25 kerror, kinfo, 26 libs::spinlock::SpinLock, 27 net::{generate_iface_id, net_core::poll_ifaces_try_lock_onetime, NET_DRIVERS}, 28 time::Instant, 29 }; 30 use system_error::SystemError; 31 32 /// @brief Virtio网络设备驱动(加锁) 33 pub struct VirtioNICDriver<T: Transport> { 34 pub inner: Arc<SpinLock<VirtIONet<HalImpl, T, 2>>>, 35 } 36 37 impl<T: Transport> Clone for VirtioNICDriver<T> { 38 fn clone(&self) -> Self { 39 return VirtioNICDriver { 40 inner: self.inner.clone(), 41 }; 42 } 43 } 44 45 /// 网卡驱动的包裹器,这是为了获取网卡驱动的可变引用而设计的。 46 /// 47 /// 由于smoltcp的设计,导致需要在poll的时候获取网卡驱动的可变引用, 48 /// 同时需要在token的consume里面获取可变引用。为了避免双重加锁,所以需要这个包裹器。 49 struct VirtioNICDriverWrapper<T: Transport>(UnsafeCell<VirtioNICDriver<T>>); 50 unsafe impl<T: Transport> Send for VirtioNICDriverWrapper<T> {} 51 unsafe impl<T: Transport> Sync for VirtioNICDriverWrapper<T> {} 52 53 impl<T: Transport> Deref for VirtioNICDriverWrapper<T> { 54 type Target = VirtioNICDriver<T>; 55 fn deref(&self) -> &Self::Target { 56 unsafe { &*self.0.get() } 57 } 58 } 59 impl<T: Transport> DerefMut for VirtioNICDriverWrapper<T> { 60 fn deref_mut(&mut self) -> &mut Self::Target { 61 unsafe { &mut *self.0.get() } 62 } 63 } 64 65 #[allow(clippy::mut_from_ref)] 66 impl<T: Transport> VirtioNICDriverWrapper<T> { 67 fn force_get_mut(&self) -> &mut VirtioNICDriver<T> { 68 unsafe { &mut *self.0.get() } 69 } 70 } 71 72 impl<T: Transport> Debug for VirtioNICDriver<T> { 73 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 74 f.debug_struct("VirtioNICDriver").finish() 75 } 76 } 77 78 pub struct VirtioInterface<T: Transport> { 79 driver: VirtioNICDriverWrapper<T>, 80 iface_id: usize, 81 iface: SpinLock<iface::Interface>, 82 name: String, 83 dev_id: Arc<DeviceId>, 84 } 85 86 impl<T: Transport> Debug for VirtioInterface<T> { 87 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 88 f.debug_struct("VirtioInterface") 89 .field("driver", self.driver.deref()) 90 .field("iface_id", &self.iface_id) 91 .field("iface", &"smoltcp::iface::Interface") 92 .field("name", &self.name) 93 .finish() 94 } 95 } 96 97 impl<T: Transport> VirtioInterface<T> { 98 pub fn new(mut driver: VirtioNICDriver<T>, dev_id: Arc<DeviceId>) -> Arc<Self> { 99 let iface_id = generate_iface_id(); 100 let mut iface_config = iface::Config::new(wire::HardwareAddress::Ethernet( 101 wire::EthernetAddress(driver.inner.lock().mac_address()), 102 )); 103 iface_config.random_seed = rand() as u64; 104 105 let iface = iface::Interface::new(iface_config, &mut driver, Instant::now().into()); 106 107 let driver: VirtioNICDriverWrapper<T> = VirtioNICDriverWrapper(UnsafeCell::new(driver)); 108 let result = Arc::new(VirtioInterface { 109 driver, 110 iface_id, 111 iface: SpinLock::new(iface), 112 name: format!("eth{}", iface_id), 113 dev_id, 114 }); 115 116 return result; 117 } 118 } 119 120 impl<T: Transport + 'static> VirtIODevice for VirtioInterface<T> { 121 fn handle_irq(&self, _irq: IrqNumber) -> Result<IrqReturn, SystemError> { 122 poll_ifaces_try_lock_onetime().ok(); 123 return Ok(IrqReturn::Handled); 124 } 125 126 fn dev_id(&self) -> &Arc<DeviceId> { 127 return &self.dev_id; 128 } 129 } 130 131 impl<T: Transport> Drop for VirtioInterface<T> { 132 fn drop(&mut self) { 133 // 从全局的网卡接口信息表中删除这个网卡的接口信息 134 NET_DRIVERS.write_irqsave().remove(&self.iface_id); 135 } 136 } 137 138 impl<T: 'static + Transport> VirtioNICDriver<T> { 139 pub fn new(driver_net: VirtIONet<HalImpl, T, 2>) -> Self { 140 let mut iface_config = iface::Config::new(wire::HardwareAddress::Ethernet( 141 wire::EthernetAddress(driver_net.mac_address()), 142 )); 143 144 iface_config.random_seed = rand() as u64; 145 146 let inner: Arc<SpinLock<VirtIONet<HalImpl, T, 2>>> = Arc::new(SpinLock::new(driver_net)); 147 let result = VirtioNICDriver { inner }; 148 return result; 149 } 150 } 151 152 pub struct VirtioNetToken<T: Transport> { 153 driver: VirtioNICDriver<T>, 154 rx_buffer: Option<virtio_drivers::device::net::RxBuffer>, 155 } 156 157 impl<T: Transport> VirtioNetToken<T> { 158 pub fn new( 159 driver: VirtioNICDriver<T>, 160 rx_buffer: Option<virtio_drivers::device::net::RxBuffer>, 161 ) -> Self { 162 return Self { driver, rx_buffer }; 163 } 164 } 165 166 impl<T: Transport> phy::Device for VirtioNICDriver<T> { 167 type RxToken<'a> = VirtioNetToken<T> where Self: 'a; 168 type TxToken<'a> = VirtioNetToken<T> where Self: 'a; 169 170 fn receive( 171 &mut self, 172 _timestamp: smoltcp::time::Instant, 173 ) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { 174 match self.inner.lock().receive() { 175 Ok(buf) => Some(( 176 VirtioNetToken::new(self.clone(), Some(buf)), 177 VirtioNetToken::new(self.clone(), None), 178 )), 179 Err(virtio_drivers::Error::NotReady) => None, 180 Err(err) => panic!("VirtIO receive failed: {}", err), 181 } 182 } 183 184 fn transmit(&mut self, _timestamp: smoltcp::time::Instant) -> Option<Self::TxToken<'_>> { 185 // kdebug!("VirtioNet: transmit"); 186 if self.inner.lock_irqsave().can_send() { 187 // kdebug!("VirtioNet: can send"); 188 return Some(VirtioNetToken::new(self.clone(), None)); 189 } else { 190 // kdebug!("VirtioNet: can not send"); 191 return None; 192 } 193 } 194 195 fn capabilities(&self) -> phy::DeviceCapabilities { 196 let mut caps = phy::DeviceCapabilities::default(); 197 // 网卡的最大传输单元. 请与IP层的MTU进行区分。这个值应当是网卡的最大传输单元,而不是IP层的MTU。 198 caps.max_transmission_unit = 2000; 199 /* 200 Maximum burst size, in terms of MTU. 201 The network device is unable to send or receive bursts large than the value returned by this function. 202 If None, there is no fixed limit on burst size, e.g. if network buffers are dynamically allocated. 203 */ 204 caps.max_burst_size = Some(1); 205 return caps; 206 } 207 } 208 209 impl<T: Transport> phy::TxToken for VirtioNetToken<T> { 210 fn consume<R, F>(self, len: usize, f: F) -> R 211 where 212 F: FnOnce(&mut [u8]) -> R, 213 { 214 // // 为了线程安全,这里需要对VirtioNet进行加【写锁】,以保证对设备的互斥访问。 215 216 let mut driver_net = self.driver.inner.lock(); 217 let mut tx_buf = driver_net.new_tx_buffer(len); 218 let result = f(tx_buf.packet_mut()); 219 driver_net.send(tx_buf).expect("virtio_net send failed"); 220 return result; 221 } 222 } 223 224 impl<T: Transport> phy::RxToken for VirtioNetToken<T> { 225 fn consume<R, F>(self, f: F) -> R 226 where 227 F: FnOnce(&mut [u8]) -> R, 228 { 229 // 为了线程安全,这里需要对VirtioNet进行加【写锁】,以保证对设备的互斥访问。 230 let mut rx_buf = self.rx_buffer.unwrap(); 231 let result = f(rx_buf.packet_mut()); 232 self.driver 233 .inner 234 .lock() 235 .recycle_rx_buffer(rx_buf) 236 .expect("virtio_net recv failed"); 237 result 238 } 239 } 240 241 /// @brief virtio-net 驱动的初始化与测试 242 pub fn virtio_net<T: Transport + 'static>(transport: T, dev_id: Arc<DeviceId>) { 243 let driver_net: VirtIONet<HalImpl, T, 2> = 244 match VirtIONet::<HalImpl, T, 2>::new(transport, 4096) { 245 Ok(net) => net, 246 Err(_) => { 247 kerror!("VirtIONet init failed"); 248 return; 249 } 250 }; 251 let mac = wire::EthernetAddress::from_bytes(&driver_net.mac_address()); 252 let driver: VirtioNICDriver<T> = VirtioNICDriver::new(driver_net); 253 let iface = VirtioInterface::new(driver, dev_id); 254 let name = iface.name.clone(); 255 // 将网卡的接口信息注册到全局的网卡接口信息表中 256 NET_DRIVERS 257 .write_irqsave() 258 .insert(iface.nic_id(), iface.clone()); 259 260 virtio_irq_manager() 261 .register_device(iface.clone()) 262 .expect("Register virtio net failed"); 263 kinfo!( 264 "Virtio-net driver init successfully!\tNetDevID: [{}], MAC: [{}]", 265 name, 266 mac 267 ); 268 } 269 270 impl<T: Transport + 'static> Driver for VirtioInterface<T> { 271 fn id_table(&self) -> Option<IdTable> { 272 todo!() 273 } 274 275 fn add_device(&self, _device: Arc<dyn Device>) { 276 todo!() 277 } 278 279 fn delete_device(&self, _device: &Arc<dyn Device>) { 280 todo!() 281 } 282 283 fn devices(&self) -> alloc::vec::Vec<Arc<dyn Device>> { 284 todo!() 285 } 286 287 fn bus(&self) -> Option<Weak<dyn Bus>> { 288 todo!() 289 } 290 291 fn set_bus(&self, _bus: Option<Weak<dyn Bus>>) { 292 todo!() 293 } 294 } 295 296 impl<T: Transport + 'static> NetDriver for VirtioInterface<T> { 297 fn mac(&self) -> wire::EthernetAddress { 298 let mac: [u8; 6] = self.driver.inner.lock().mac_address(); 299 return wire::EthernetAddress::from_bytes(&mac); 300 } 301 302 #[inline] 303 fn nic_id(&self) -> usize { 304 return self.iface_id; 305 } 306 307 #[inline] 308 fn name(&self) -> String { 309 return self.name.clone(); 310 } 311 312 fn update_ip_addrs(&self, ip_addrs: &[wire::IpCidr]) -> Result<(), SystemError> { 313 if ip_addrs.len() != 1 { 314 return Err(SystemError::EINVAL); 315 } 316 317 self.iface.lock().update_ip_addrs(|addrs| { 318 let dest = addrs.iter_mut().next(); 319 320 if let Some(dest) = dest { 321 *dest = ip_addrs[0]; 322 } else { 323 addrs 324 .push(ip_addrs[0]) 325 .expect("Push wire::IpCidr failed: full"); 326 } 327 }); 328 return Ok(()); 329 } 330 331 fn poll(&self, sockets: &mut iface::SocketSet) -> Result<(), SystemError> { 332 let timestamp: smoltcp::time::Instant = Instant::now().into(); 333 let mut guard = self.iface.lock(); 334 let poll_res = guard.poll(timestamp, self.driver.force_get_mut(), sockets); 335 // todo: notify!!! 336 // kdebug!("Virtio Interface poll:{poll_res}"); 337 if poll_res { 338 return Ok(()); 339 } 340 return Err(SystemError::EAGAIN_OR_EWOULDBLOCK); 341 } 342 343 #[inline(always)] 344 fn inner_iface(&self) -> &SpinLock<iface::Interface> { 345 return &self.iface; 346 } 347 // fn as_any_ref(&'static self) -> &'static dyn core::any::Any { 348 // return self; 349 // } 350 } 351 352 impl<T: Transport + 'static> KObject for VirtioInterface<T> { 353 fn as_any_ref(&self) -> &dyn core::any::Any { 354 self 355 } 356 357 fn set_inode(&self, _inode: Option<Arc<crate::filesystem::kernfs::KernFSInode>>) { 358 todo!() 359 } 360 361 fn inode(&self) -> Option<Arc<crate::filesystem::kernfs::KernFSInode>> { 362 todo!() 363 } 364 365 fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> { 366 todo!() 367 } 368 369 fn set_parent(&self, _parent: Option<alloc::sync::Weak<dyn KObject>>) { 370 todo!() 371 } 372 373 fn kset(&self) -> Option<Arc<crate::driver::base::kset::KSet>> { 374 todo!() 375 } 376 377 fn set_kset(&self, _kset: Option<Arc<crate::driver::base::kset::KSet>>) { 378 todo!() 379 } 380 381 fn kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType> { 382 todo!() 383 } 384 385 fn name(&self) -> String { 386 self.name.clone() 387 } 388 389 fn set_name(&self, _name: String) { 390 todo!() 391 } 392 393 fn kobj_state( 394 &self, 395 ) -> crate::libs::rwlock::RwLockReadGuard<crate::driver::base::kobject::KObjectState> { 396 todo!() 397 } 398 399 fn kobj_state_mut( 400 &self, 401 ) -> crate::libs::rwlock::RwLockWriteGuard<crate::driver::base::kobject::KObjectState> { 402 todo!() 403 } 404 405 fn set_kobj_state(&self, _state: KObjectState) { 406 todo!() 407 } 408 409 fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) { 410 todo!() 411 } 412 } 413 414 // 向编译器保证,VirtioNICDriver在线程之间是安全的. 415 // 由于smoltcp只会在token内真正操作网卡设备,并且在VirtioNetToken的consume 416 // 方法内,会对VirtioNet进行加【写锁】,因此,能够保证对设备操作的的互斥访问, 417 // 因此VirtioNICDriver在线程之间是安全的。 418 // unsafe impl<T: Transport> Sync for VirtioNICDriver<T> {} 419 // unsafe impl<T: Transport> Send for VirtioNICDriver<T> {} 420