|
@@ -6,6 +6,7 @@ use core::{
|
|
|
};
|
|
|
|
|
|
use alloc::{
|
|
|
+ collections::LinkedList,
|
|
|
string::{String, ToString},
|
|
|
sync::{Arc, Weak},
|
|
|
vec::Vec,
|
|
@@ -15,7 +16,7 @@ use smoltcp::{iface, phy, wire};
|
|
|
use unified_init::macros::unified_init;
|
|
|
use virtio_drivers::device::net::VirtIONet;
|
|
|
|
|
|
-use super::NetDevice;
|
|
|
+use super::{NetDeivceState, NetDevice, NetDeviceCommonData, Operstate};
|
|
|
use crate::{
|
|
|
arch::rand::rand,
|
|
|
driver::{
|
|
@@ -29,12 +30,13 @@ use crate::{
|
|
|
kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
|
|
|
kset::KSet,
|
|
|
},
|
|
|
+ net::register_netdevice,
|
|
|
virtio::{
|
|
|
- irq::virtio_irq_manager,
|
|
|
sysfs::{virtio_bus, virtio_device_manager, virtio_driver_manager},
|
|
|
transport::VirtIOTransport,
|
|
|
virtio_impl::HalImpl,
|
|
|
- VirtIODevice, VirtIODeviceIndex, VirtIODriver, VIRTIO_VENDOR_ID,
|
|
|
+ VirtIODevice, VirtIODeviceIndex, VirtIODriver, VirtIODriverCommonData, VirtioDeviceId,
|
|
|
+ VIRTIO_VENDOR_ID,
|
|
|
},
|
|
|
},
|
|
|
exception::{irqdesc::IrqReturn, IrqNumber},
|
|
@@ -51,13 +53,245 @@ use system_error::SystemError;
|
|
|
|
|
|
static mut VIRTIO_NET_DRIVER: Option<Arc<VirtIONetDriver>> = None;
|
|
|
|
|
|
-const DEVICE_NAME: &str = "virtio_net";
|
|
|
+const VIRTIO_NET_BASENAME: &str = "virtio_net";
|
|
|
|
|
|
#[inline(always)]
|
|
|
+#[allow(dead_code)]
|
|
|
fn virtio_net_driver() -> Arc<VirtIONetDriver> {
|
|
|
unsafe { VIRTIO_NET_DRIVER.as_ref().unwrap().clone() }
|
|
|
}
|
|
|
|
|
|
+/// virtio net device
|
|
|
+#[derive(Debug)]
|
|
|
+#[cast_to([sync] VirtIODevice)]
|
|
|
+#[cast_to([sync] Device)]
|
|
|
+pub struct VirtIONetDevice {
|
|
|
+ dev_id: Arc<DeviceId>,
|
|
|
+ inner: SpinLock<InnerVirtIONetDevice>,
|
|
|
+ locked_kobj_state: LockedKObjectState,
|
|
|
+}
|
|
|
+
|
|
|
+unsafe impl Send for VirtIONetDevice {}
|
|
|
+unsafe impl Sync for VirtIONetDevice {}
|
|
|
+
|
|
|
+struct InnerVirtIONetDevice {
|
|
|
+ device_inner: VirtIONicDeviceInner,
|
|
|
+ name: Option<String>,
|
|
|
+ virtio_index: Option<VirtIODeviceIndex>,
|
|
|
+ kobj_common: KObjectCommonData,
|
|
|
+ device_common: DeviceCommonData,
|
|
|
+}
|
|
|
+
|
|
|
+impl Debug for InnerVirtIONetDevice {
|
|
|
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
|
|
+ f.debug_struct("InnerVirtIOBlkDevice").finish()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl VirtIONetDevice {
|
|
|
+ pub fn new(transport: VirtIOTransport, dev_id: Arc<DeviceId>) -> Option<Arc<Self>> {
|
|
|
+ let driver_net: VirtIONet<HalImpl, VirtIOTransport, 2> =
|
|
|
+ match VirtIONet::<HalImpl, VirtIOTransport, 2>::new(transport, 4096) {
|
|
|
+ Ok(net) => net,
|
|
|
+ Err(_) => {
|
|
|
+ error!("VirtIONet init failed");
|
|
|
+ return None;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ let mac = wire::EthernetAddress::from_bytes(&driver_net.mac_address());
|
|
|
+ debug!("VirtIONetDevice mac: {:?}", mac);
|
|
|
+ let device_inner = VirtIONicDeviceInner::new(driver_net);
|
|
|
+
|
|
|
+ let dev = Arc::new(Self {
|
|
|
+ dev_id,
|
|
|
+ inner: SpinLock::new(InnerVirtIONetDevice {
|
|
|
+ device_inner,
|
|
|
+ name: None,
|
|
|
+ virtio_index: None,
|
|
|
+ kobj_common: KObjectCommonData::default(),
|
|
|
+ device_common: DeviceCommonData::default(),
|
|
|
+ }),
|
|
|
+ locked_kobj_state: LockedKObjectState::default(),
|
|
|
+ });
|
|
|
+
|
|
|
+ // dev.set_driver(Some(Arc::downgrade(&virtio_net_driver()) as Weak<dyn Driver>));
|
|
|
+
|
|
|
+ return Some(dev);
|
|
|
+ }
|
|
|
+
|
|
|
+ fn inner(&self) -> SpinLockGuard<InnerVirtIONetDevice> {
|
|
|
+ return self.inner.lock();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl KObject for VirtIONetDevice {
|
|
|
+ fn as_any_ref(&self) -> &dyn Any {
|
|
|
+ self
|
|
|
+ }
|
|
|
+
|
|
|
+ fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
|
|
|
+ self.inner().kobj_common.kern_inode = inode;
|
|
|
+ }
|
|
|
+
|
|
|
+ fn inode(&self) -> Option<Arc<KernFSInode>> {
|
|
|
+ self.inner().kobj_common.kern_inode.clone()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn parent(&self) -> Option<Weak<dyn KObject>> {
|
|
|
+ self.inner().kobj_common.parent.clone()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
|
|
|
+ self.inner().kobj_common.parent = parent;
|
|
|
+ }
|
|
|
+
|
|
|
+ fn kset(&self) -> Option<Arc<KSet>> {
|
|
|
+ self.inner().kobj_common.kset.clone()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn set_kset(&self, kset: Option<Arc<KSet>>) {
|
|
|
+ self.inner().kobj_common.kset = kset;
|
|
|
+ }
|
|
|
+
|
|
|
+ fn kobj_type(&self) -> Option<&'static dyn KObjType> {
|
|
|
+ self.inner().kobj_common.kobj_type
|
|
|
+ }
|
|
|
+
|
|
|
+ fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
|
|
|
+ self.inner().kobj_common.kobj_type = ktype;
|
|
|
+ }
|
|
|
+
|
|
|
+ fn name(&self) -> String {
|
|
|
+ self.device_name()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn set_name(&self, _name: String) {
|
|
|
+ // do nothing
|
|
|
+ }
|
|
|
+
|
|
|
+ fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
|
|
|
+ self.locked_kobj_state.read()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
|
|
|
+ self.locked_kobj_state.write()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn set_kobj_state(&self, state: KObjectState) {
|
|
|
+ *self.locked_kobj_state.write() = state;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl Device for VirtIONetDevice {
|
|
|
+ fn dev_type(&self) -> DeviceType {
|
|
|
+ DeviceType::Net
|
|
|
+ }
|
|
|
+
|
|
|
+ fn id_table(&self) -> IdTable {
|
|
|
+ IdTable::new(VIRTIO_NET_BASENAME.to_string(), None)
|
|
|
+ }
|
|
|
+
|
|
|
+ fn bus(&self) -> Option<Weak<dyn Bus>> {
|
|
|
+ self.inner().device_common.bus.clone()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
|
|
|
+ self.inner().device_common.bus = bus;
|
|
|
+ }
|
|
|
+
|
|
|
+ fn class(&self) -> Option<Arc<dyn Class>> {
|
|
|
+ let mut guard = self.inner();
|
|
|
+ let r = guard.device_common.class.clone()?.upgrade();
|
|
|
+ if r.is_none() {
|
|
|
+ guard.device_common.class = None;
|
|
|
+ }
|
|
|
+
|
|
|
+ return r;
|
|
|
+ }
|
|
|
+
|
|
|
+ fn set_class(&self, class: Option<Weak<dyn Class>>) {
|
|
|
+ self.inner().device_common.class = class;
|
|
|
+ }
|
|
|
+
|
|
|
+ fn driver(&self) -> Option<Arc<dyn Driver>> {
|
|
|
+ let r = self.inner().device_common.driver.clone()?.upgrade();
|
|
|
+ if r.is_none() {
|
|
|
+ self.inner().device_common.driver = None;
|
|
|
+ }
|
|
|
+
|
|
|
+ return r;
|
|
|
+ }
|
|
|
+
|
|
|
+ fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
|
|
|
+ self.inner().device_common.driver = driver;
|
|
|
+ }
|
|
|
+
|
|
|
+ fn is_dead(&self) -> bool {
|
|
|
+ false
|
|
|
+ }
|
|
|
+
|
|
|
+ fn can_match(&self) -> bool {
|
|
|
+ self.inner().device_common.can_match
|
|
|
+ }
|
|
|
+
|
|
|
+ fn set_can_match(&self, can_match: bool) {
|
|
|
+ self.inner().device_common.can_match = can_match;
|
|
|
+ }
|
|
|
+ fn state_synced(&self) -> bool {
|
|
|
+ true
|
|
|
+ }
|
|
|
+
|
|
|
+ fn dev_parent(&self) -> Option<Weak<dyn Device>> {
|
|
|
+ self.inner().device_common.get_parent_weak_or_clear()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn set_dev_parent(&self, parent: Option<Weak<dyn Device>>) {
|
|
|
+ self.inner().device_common.parent = parent;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl VirtIODevice for VirtIONetDevice {
|
|
|
+ fn handle_irq(&self, _irq: IrqNumber) -> Result<IrqReturn, SystemError> {
|
|
|
+ poll_ifaces_try_lock_onetime().ok();
|
|
|
+ return Ok(IrqReturn::Handled);
|
|
|
+ }
|
|
|
+
|
|
|
+ fn dev_id(&self) -> &Arc<DeviceId> {
|
|
|
+ return &self.dev_id;
|
|
|
+ }
|
|
|
+
|
|
|
+ fn set_device_name(&self, name: String) {
|
|
|
+ self.inner().name = Some(name);
|
|
|
+ }
|
|
|
+
|
|
|
+ fn device_name(&self) -> String {
|
|
|
+ self.inner()
|
|
|
+ .name
|
|
|
+ .clone()
|
|
|
+ .unwrap_or_else(|| "virtio_net".to_string())
|
|
|
+ }
|
|
|
+
|
|
|
+ fn set_virtio_device_index(&self, index: VirtIODeviceIndex) {
|
|
|
+ self.inner().virtio_index = Some(index);
|
|
|
+ }
|
|
|
+
|
|
|
+ fn virtio_device_index(&self) -> Option<VirtIODeviceIndex> {
|
|
|
+ return self.inner().virtio_index;
|
|
|
+ }
|
|
|
+
|
|
|
+ fn device_type_id(&self) -> u32 {
|
|
|
+ virtio_drivers::transport::DeviceType::Network as u32
|
|
|
+ }
|
|
|
+
|
|
|
+ fn vendor(&self) -> u32 {
|
|
|
+ VIRTIO_VENDOR_ID.into()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn irq(&self) -> Option<IrqNumber> {
|
|
|
+ None
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
pub struct VirtIoNetImpl {
|
|
|
inner: VirtIONet<HalImpl, VirtIOTransport, 2>,
|
|
|
}
|
|
@@ -127,13 +361,12 @@ impl Debug for VirtIONicDeviceInner {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-#[cast_to([sync] VirtIODevice)]
|
|
|
+#[cast_to([sync] NetDevice)]
|
|
|
#[cast_to([sync] Device)]
|
|
|
pub struct VirtioInterface {
|
|
|
device_inner: VirtIONicDeviceInnerWrapper,
|
|
|
iface_id: usize,
|
|
|
iface_name: String,
|
|
|
- dev_id: Arc<DeviceId>,
|
|
|
iface: SpinLock<iface::Interface>,
|
|
|
inner: SpinLock<InnerVirtIOInterface>,
|
|
|
locked_kobj_state: LockedKObjectState,
|
|
@@ -141,10 +374,9 @@ pub struct VirtioInterface {
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
struct InnerVirtIOInterface {
|
|
|
- name: Option<String>,
|
|
|
- virtio_index: Option<VirtIODeviceIndex>,
|
|
|
- device_common: DeviceCommonData,
|
|
|
kobj_common: KObjectCommonData,
|
|
|
+ device_common: DeviceCommonData,
|
|
|
+ netdevice_common: NetDeviceCommonData,
|
|
|
}
|
|
|
|
|
|
impl core::fmt::Debug for VirtioInterface {
|
|
@@ -152,7 +384,6 @@ impl core::fmt::Debug for VirtioInterface {
|
|
|
f.debug_struct("VirtioInterface")
|
|
|
.field("iface_id", &self.iface_id)
|
|
|
.field("iface_name", &self.iface_name)
|
|
|
- .field("dev_id", &self.dev_id)
|
|
|
.field("inner", &self.inner)
|
|
|
.field("locked_kobj_state", &self.locked_kobj_state)
|
|
|
.finish()
|
|
@@ -160,7 +391,7 @@ impl core::fmt::Debug for VirtioInterface {
|
|
|
}
|
|
|
|
|
|
impl VirtioInterface {
|
|
|
- pub fn new(mut device_inner: VirtIONicDeviceInner, dev_id: Arc<DeviceId>) -> Arc<Self> {
|
|
|
+ pub fn new(mut device_inner: VirtIONicDeviceInner) -> Arc<Self> {
|
|
|
let iface_id = generate_iface_id();
|
|
|
let mut iface_config = iface::Config::new(wire::HardwareAddress::Ethernet(
|
|
|
wire::EthernetAddress(device_inner.inner.lock().mac_address()),
|
|
@@ -175,18 +406,13 @@ impl VirtioInterface {
|
|
|
locked_kobj_state: LockedKObjectState::default(),
|
|
|
iface: SpinLock::new(iface),
|
|
|
iface_name: format!("eth{}", iface_id),
|
|
|
- dev_id,
|
|
|
inner: SpinLock::new(InnerVirtIOInterface {
|
|
|
- name: None,
|
|
|
- virtio_index: None,
|
|
|
- device_common: DeviceCommonData::default(),
|
|
|
kobj_common: KObjectCommonData::default(),
|
|
|
+ device_common: DeviceCommonData::default(),
|
|
|
+ netdevice_common: NetDeviceCommonData::default(),
|
|
|
}),
|
|
|
});
|
|
|
|
|
|
- result.inner().device_common.driver =
|
|
|
- Some(Arc::downgrade(&virtio_net_driver()) as Weak<dyn Driver>);
|
|
|
-
|
|
|
return result;
|
|
|
}
|
|
|
|
|
@@ -201,47 +427,6 @@ impl VirtioInterface {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl VirtIODevice for VirtioInterface {
|
|
|
- fn handle_irq(&self, _irq: IrqNumber) -> Result<IrqReturn, SystemError> {
|
|
|
- poll_ifaces_try_lock_onetime().ok();
|
|
|
- return Ok(IrqReturn::Handled);
|
|
|
- }
|
|
|
-
|
|
|
- fn irq(&self) -> Option<IrqNumber> {
|
|
|
- None
|
|
|
- }
|
|
|
-
|
|
|
- fn dev_id(&self) -> &Arc<DeviceId> {
|
|
|
- return &self.dev_id;
|
|
|
- }
|
|
|
- fn set_virtio_device_index(&self, index: VirtIODeviceIndex) {
|
|
|
- self.inner().virtio_index = Some(index);
|
|
|
- }
|
|
|
-
|
|
|
- fn virtio_device_index(&self) -> Option<VirtIODeviceIndex> {
|
|
|
- return self.inner().virtio_index;
|
|
|
- }
|
|
|
-
|
|
|
- fn set_device_name(&self, name: String) {
|
|
|
- self.inner().name = Some(name);
|
|
|
- }
|
|
|
-
|
|
|
- fn device_name(&self) -> String {
|
|
|
- self.inner()
|
|
|
- .name
|
|
|
- .clone()
|
|
|
- .unwrap_or_else(|| "virtio_net".to_string())
|
|
|
- }
|
|
|
-
|
|
|
- fn device_type_id(&self) -> u32 {
|
|
|
- virtio_drivers::transport::DeviceType::Network as u32
|
|
|
- }
|
|
|
-
|
|
|
- fn vendor(&self) -> u32 {
|
|
|
- VIRTIO_VENDOR_ID.into()
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
impl Drop for VirtioInterface {
|
|
|
fn drop(&mut self) {
|
|
|
// 从全局的网卡接口信息表中删除这个网卡的接口信息
|
|
@@ -255,7 +440,7 @@ impl Device for VirtioInterface {
|
|
|
}
|
|
|
|
|
|
fn id_table(&self) -> IdTable {
|
|
|
- IdTable::new(DEVICE_NAME.to_string(), None)
|
|
|
+ IdTable::new(VIRTIO_NET_BASENAME.to_string(), None)
|
|
|
}
|
|
|
|
|
|
fn bus(&self) -> Option<Weak<dyn Bus>> {
|
|
@@ -308,6 +493,14 @@ impl Device for VirtioInterface {
|
|
|
fn state_synced(&self) -> bool {
|
|
|
true
|
|
|
}
|
|
|
+
|
|
|
+ fn dev_parent(&self) -> Option<Weak<dyn Device>> {
|
|
|
+ self.inner().device_common.get_parent_weak_or_clear()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn set_dev_parent(&self, parent: Option<Weak<dyn Device>>) {
|
|
|
+ self.inner().device_common.parent = parent;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
impl VirtIONicDeviceInner {
|
|
@@ -413,22 +606,21 @@ impl phy::RxToken for VirtioNetToken {
|
|
|
}
|
|
|
|
|
|
/// @brief virtio-net 驱动的初始化与测试
|
|
|
-pub fn virtio_net(transport: VirtIOTransport, dev_id: Arc<DeviceId>) {
|
|
|
- let driver_net: VirtIONet<HalImpl, VirtIOTransport, 2> =
|
|
|
- match VirtIONet::<HalImpl, VirtIOTransport, 2>::new(transport, 4096) {
|
|
|
- Ok(net) => net,
|
|
|
- Err(_) => {
|
|
|
- error!("VirtIONet init failed");
|
|
|
- return;
|
|
|
- }
|
|
|
- };
|
|
|
- let mac = wire::EthernetAddress::from_bytes(&driver_net.mac_address());
|
|
|
- let dev_inner = VirtIONicDeviceInner::new(driver_net);
|
|
|
- let iface = VirtioInterface::new(dev_inner, dev_id);
|
|
|
- debug!("To add virtio net: {}, mac: {}", iface.device_name(), mac);
|
|
|
- virtio_device_manager()
|
|
|
- .device_add(iface.clone() as Arc<dyn VirtIODevice>)
|
|
|
- .expect("Add virtio net failed");
|
|
|
+pub fn virtio_net(
|
|
|
+ transport: VirtIOTransport,
|
|
|
+ dev_id: Arc<DeviceId>,
|
|
|
+ dev_parent: Option<Arc<dyn Device>>,
|
|
|
+) {
|
|
|
+ let virtio_net_deivce = VirtIONetDevice::new(transport, dev_id);
|
|
|
+ if let Some(virtio_net_deivce) = virtio_net_deivce {
|
|
|
+ debug!("VirtIONetDevice '{:?}' created", virtio_net_deivce.dev_id);
|
|
|
+ if let Some(dev_parent) = dev_parent {
|
|
|
+ virtio_net_deivce.set_dev_parent(Some(Arc::downgrade(&dev_parent)));
|
|
|
+ }
|
|
|
+ virtio_device_manager()
|
|
|
+ .device_add(virtio_net_deivce.clone() as Arc<dyn VirtIODevice>)
|
|
|
+ .expect("Add virtio net failed");
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
impl NetDevice for VirtioInterface {
|
|
@@ -443,7 +635,7 @@ impl NetDevice for VirtioInterface {
|
|
|
}
|
|
|
|
|
|
#[inline]
|
|
|
- fn name(&self) -> String {
|
|
|
+ fn iface_name(&self) -> String {
|
|
|
return self.iface_name.clone();
|
|
|
}
|
|
|
|
|
@@ -485,6 +677,31 @@ impl NetDevice for VirtioInterface {
|
|
|
// fn as_any_ref(&'static self) -> &'static dyn core::any::Any {
|
|
|
// return self;
|
|
|
// }
|
|
|
+
|
|
|
+ fn addr_assign_type(&self) -> u8 {
|
|
|
+ return self.inner().netdevice_common.addr_assign_type;
|
|
|
+ }
|
|
|
+
|
|
|
+ fn net_device_type(&self) -> u16 {
|
|
|
+ self.inner().netdevice_common.net_device_type = 1; // 以太网设备
|
|
|
+ return self.inner().netdevice_common.net_device_type;
|
|
|
+ }
|
|
|
+
|
|
|
+ fn net_state(&self) -> NetDeivceState {
|
|
|
+ return self.inner().netdevice_common.state;
|
|
|
+ }
|
|
|
+
|
|
|
+ fn set_net_state(&self, state: NetDeivceState) {
|
|
|
+ self.inner().netdevice_common.state |= state;
|
|
|
+ }
|
|
|
+
|
|
|
+ fn operstate(&self) -> Operstate {
|
|
|
+ return self.inner().netdevice_common.operstate;
|
|
|
+ }
|
|
|
+
|
|
|
+ fn set_operstate(&self, state: Operstate) {
|
|
|
+ self.inner().netdevice_common.operstate = state;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
impl KObject for VirtioInterface {
|
|
@@ -521,7 +738,7 @@ impl KObject for VirtioInterface {
|
|
|
}
|
|
|
|
|
|
fn name(&self) -> String {
|
|
|
- self.device_name()
|
|
|
+ self.iface_name.clone()
|
|
|
}
|
|
|
|
|
|
fn set_name(&self, _name: String) {
|
|
@@ -569,13 +786,22 @@ struct VirtIONetDriver {
|
|
|
impl VirtIONetDriver {
|
|
|
pub fn new() -> Arc<Self> {
|
|
|
let inner = InnerVirtIODriver {
|
|
|
+ virtio_driver_common: VirtIODriverCommonData::default(),
|
|
|
driver_common: DriverCommonData::default(),
|
|
|
kobj_common: KObjectCommonData::default(),
|
|
|
};
|
|
|
- Arc::new(VirtIONetDriver {
|
|
|
+
|
|
|
+ let id_table = VirtioDeviceId::new(
|
|
|
+ virtio_drivers::transport::DeviceType::Network as u32,
|
|
|
+ VIRTIO_VENDOR_ID.into(),
|
|
|
+ );
|
|
|
+ let result = VirtIONetDriver {
|
|
|
inner: SpinLock::new(inner),
|
|
|
kobj_state: LockedKObjectState::default(),
|
|
|
- })
|
|
|
+ };
|
|
|
+ result.add_virtio_id(id_table);
|
|
|
+
|
|
|
+ return Arc::new(result);
|
|
|
}
|
|
|
|
|
|
fn inner(&self) -> SpinLockGuard<InnerVirtIODriver> {
|
|
@@ -585,59 +811,74 @@ impl VirtIONetDriver {
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
struct InnerVirtIODriver {
|
|
|
+ virtio_driver_common: VirtIODriverCommonData,
|
|
|
driver_common: DriverCommonData,
|
|
|
kobj_common: KObjectCommonData,
|
|
|
}
|
|
|
|
|
|
impl VirtIODriver for VirtIONetDriver {
|
|
|
fn probe(&self, device: &Arc<dyn VirtIODevice>) -> Result<(), SystemError> {
|
|
|
- let iface = device
|
|
|
+ log::debug!("VirtIONetDriver::probe()");
|
|
|
+ let virtio_net_device = device
|
|
|
.clone()
|
|
|
.arc_any()
|
|
|
- .downcast::<VirtioInterface>()
|
|
|
+ .downcast::<VirtIONetDevice>()
|
|
|
.map_err(|_| {
|
|
|
error!(
|
|
|
- "VirtIONetDriver::probe() failed: device is not a VirtioInterface. Device: '{:?}'",
|
|
|
- device.name()
|
|
|
- );
|
|
|
+ "VirtIONetDriver::probe() failed: device is not a VirtIODevice. Device: '{:?}'",
|
|
|
+ device.name()
|
|
|
+ );
|
|
|
SystemError::EINVAL
|
|
|
})?;
|
|
|
|
|
|
+ let iface: Arc<VirtioInterface> =
|
|
|
+ VirtioInterface::new(virtio_net_device.inner().device_inner.clone());
|
|
|
+ // 标识网络设备已经启动
|
|
|
+ iface.set_net_state(NetDeivceState::__LINK_STATE_START);
|
|
|
+ // 设置iface的父设备为virtio_net_device
|
|
|
+ iface.set_dev_parent(Some(Arc::downgrade(&virtio_net_device) as Weak<dyn Device>));
|
|
|
+ // 在sysfs中注册iface
|
|
|
+ register_netdevice(iface.clone() as Arc<dyn NetDevice>)?;
|
|
|
+
|
|
|
// 将网卡的接口信息注册到全局的网卡接口信息表中
|
|
|
NET_DEVICES
|
|
|
.write_irqsave()
|
|
|
.insert(iface.nic_id(), iface.clone());
|
|
|
|
|
|
- virtio_irq_manager()
|
|
|
- .register_device(iface.clone())
|
|
|
- .expect("Register virtio net failed");
|
|
|
-
|
|
|
return Ok(());
|
|
|
}
|
|
|
+
|
|
|
+ fn virtio_id_table(&self) -> LinkedList<VirtioDeviceId> {
|
|
|
+ self.inner().virtio_driver_common.id_table.clone()
|
|
|
+ }
|
|
|
+
|
|
|
+ fn add_virtio_id(&self, id: VirtioDeviceId) {
|
|
|
+ self.inner().virtio_driver_common.id_table.push_back(id);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
impl Driver for VirtIONetDriver {
|
|
|
fn id_table(&self) -> Option<IdTable> {
|
|
|
- Some(IdTable::new(DEVICE_NAME.to_string(), None))
|
|
|
+ Some(IdTable::new(VIRTIO_NET_BASENAME.to_string(), None))
|
|
|
}
|
|
|
|
|
|
fn add_device(&self, device: Arc<dyn Device>) {
|
|
|
- let iface = device
|
|
|
+ let virtio_net_device = device
|
|
|
.arc_any()
|
|
|
- .downcast::<VirtioInterface>()
|
|
|
+ .downcast::<VirtIONetDevice>()
|
|
|
.expect("VirtIONetDriver::add_device() failed: device is not a VirtioInterface");
|
|
|
|
|
|
self.inner()
|
|
|
.driver_common
|
|
|
.devices
|
|
|
- .push(iface as Arc<dyn Device>);
|
|
|
+ .push(virtio_net_device as Arc<dyn Device>);
|
|
|
}
|
|
|
|
|
|
fn delete_device(&self, device: &Arc<dyn Device>) {
|
|
|
- let _iface = device
|
|
|
+ let _virtio_net_device = device
|
|
|
.clone()
|
|
|
.arc_any()
|
|
|
- .downcast::<VirtioInterface>()
|
|
|
+ .downcast::<VirtIONetDevice>()
|
|
|
.expect("VirtIONetDriver::delete_device() failed: device is not a VirtioInterface");
|
|
|
|
|
|
let mut guard = self.inner();
|
|
@@ -702,7 +943,7 @@ impl KObject for VirtIONetDriver {
|
|
|
}
|
|
|
|
|
|
fn name(&self) -> String {
|
|
|
- DEVICE_NAME.to_string()
|
|
|
+ VIRTIO_NET_BASENAME.to_string()
|
|
|
}
|
|
|
|
|
|
fn set_name(&self, _name: String) {
|