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