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