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