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