⚠️ VeridianOS Kernel Documentation - This is low-level kernel code. All functions are unsafe unless explicitly marked otherwise. no_std

veridian_kernel/net/
integration.rs

1//! Network Driver Integration Module
2//!
3//! Provides automatic registration of hardware network drivers with the network
4//! stack. Uses PCI bus enumeration to auto-detect network hardware.
5
6use alloc::boxed::Box;
7
8use super::device::{self, NetworkDevice};
9use crate::error::KernelError;
10
11// PCI vendor and device IDs for network cards (only used on x86_64)
12#[cfg(target_arch = "x86_64")]
13const INTEL_VENDOR_ID: u16 = 0x8086;
14#[cfg(target_arch = "x86_64")]
15const E1000_DEVICE_ID: u16 = 0x100E;
16#[cfg(target_arch = "x86_64")]
17const E1000E_DEVICE_ID: u16 = 0x10D3;
18#[cfg(target_arch = "x86_64")]
19const REDHAT_VENDOR_ID: u16 = 0x1AF4;
20#[cfg(target_arch = "x86_64")]
21const VIRTIO_NET_LEGACY_DEVICE_ID: u16 = 0x1000;
22#[cfg(target_arch = "x86_64")]
23const VIRTIO_NET_MODERN_DEVICE_ID: u16 = 0x1041;
24/// Initialize and register all available network drivers
25#[allow(unused_assignments)]
26pub fn register_drivers() -> Result<(), KernelError> {
27    println!("[NET-INTEGRATION] Scanning for network devices...");
28
29    #[allow(unused_variables)] // Used on x86_64/riscv64; AArch64 println! is no-op
30    let mut device_count = 0;
31
32    // Only x86_64 has PCI support
33    #[cfg(target_arch = "x86_64")]
34    {
35        // Check if PCI is initialized before trying to access it
36        if !crate::drivers::pci::is_pci_initialized() {
37            println!("[NET-INTEGRATION] PCI bus not initialized, skipping PCI device scan");
38        } else {
39            // Get PCI bus and enumerate devices
40            let pci_bus = crate::drivers::pci::get_pci_bus();
41            let bus = pci_bus.lock();
42
43            // Ensure PCI enumeration is complete
44            if let Err(_e) = bus.enumerate_devices() {
45                crate::println!(
46                    "[NET-INTEGRATION] Warning: PCI enumeration failed: {:?}",
47                    _e
48                );
49            }
50
51            // Search for Intel E1000 network cards
52            let e1000_devices = bus.find_devices_by_id(INTEL_VENDOR_ID, E1000_DEVICE_ID);
53            for device in e1000_devices {
54                println!(
55                    "[NET-INTEGRATION] Found E1000 at {:02x}:{:02x}.{}",
56                    device.location.bus, device.location.device, device.location.function
57                );
58
59                // Get BAR0 (MMIO base address)
60                if let Some(bar0) = device.bars.first() {
61                    if let Some(address) = bar0.get_memory_address() {
62                        if try_register_e1000(address).is_ok() {
63                            device_count += 1;
64                        }
65                    }
66                }
67            }
68
69            // Search for Intel E1000E network cards
70            let e1000e_devices = bus.find_devices_by_id(INTEL_VENDOR_ID, E1000E_DEVICE_ID);
71            for device in e1000e_devices {
72                println!(
73                    "[NET-INTEGRATION] Found E1000E at {:02x}:{:02x}.{}",
74                    device.location.bus, device.location.device, device.location.function
75                );
76
77                if let Some(bar0) = device.bars.first() {
78                    if let Some(address) = bar0.get_memory_address() {
79                        if try_register_e1000(address).is_ok() {
80                            device_count += 1;
81                        }
82                    }
83                }
84            }
85
86            // Search for VirtIO-Net (legacy and modern)
87            let virtio_legacy =
88                bus.find_devices_by_id(REDHAT_VENDOR_ID, VIRTIO_NET_LEGACY_DEVICE_ID);
89            let virtio_modern =
90                bus.find_devices_by_id(REDHAT_VENDOR_ID, VIRTIO_NET_MODERN_DEVICE_ID);
91
92            for device in virtio_legacy.iter().chain(virtio_modern.iter()) {
93                println!(
94                    "[NET-INTEGRATION] Found VirtIO-Net at {:02x}:{:02x}.{}",
95                    device.location.bus, device.location.device, device.location.function
96                );
97
98                if let Some(bar0) = device.bars.first() {
99                    if let Some(address) = bar0.get_memory_address() {
100                        if try_register_virtio_net(address).is_ok() {
101                            device_count += 1;
102                        }
103                    }
104                }
105            }
106        }
107    }
108
109    // For non-x86_64 architectures, try VirtIO MMIO at known addresses
110    #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
111    {
112        // VirtIO MMIO devices at platform-specific addresses
113        #[cfg(target_arch = "aarch64")]
114        let virtio_bases = [0x0a000000, 0x0a000200, 0x0a000400, 0x0a000600];
115
116        #[cfg(target_arch = "riscv64")]
117        let virtio_bases = [0x10001000, 0x10002000, 0x10003000, 0x10004000];
118
119        for &base in &virtio_bases {
120            if try_register_virtio_net(base as u64).is_ok() {
121                device_count += 1;
122            }
123        }
124    }
125
126    println!(
127        "[NET-INTEGRATION] Network device scan complete: {} devices registered",
128        device_count
129    );
130    Ok(())
131}
132
133/// Try to register E1000 driver if hardware is present
134///
135/// Called from the x86_64 PCI device scan path above.
136#[cfg(target_arch = "x86_64")]
137fn try_register_e1000(bar_address: u64) -> Result<(), KernelError> {
138    use crate::drivers::e1000::E1000Driver;
139
140    // The BAR address is physical — convert to virtual via the bootloader's
141    // physical memory offset mapping.
142    let virt_addr = crate::arch::x86_64::msr::phys_to_virt(bar_address as usize).ok_or(
143        KernelError::NotFound {
144            resource: "e1000_mmio_mapping",
145            id: 0,
146        },
147    )?;
148
149    println!(
150        "[NET-INTEGRATION] Initializing E1000 at phys 0x{:x} (virt 0x{:x})",
151        bar_address, virt_addr
152    );
153
154    match E1000Driver::new(virt_addr) {
155        Ok(driver) => {
156            let name = driver.name();
157            let mac = driver.mac_address();
158
159            println!(
160                "[NET-INTEGRATION] E1000 initialized: {} (MAC: \
161                 {:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x})",
162                name, mac.0[0], mac.0[1], mac.0[2], mac.0[3], mac.0[4], mac.0[5]
163            );
164
165            // Register with network device registry
166            if let Err(e) = device::register_device(Box::new(driver)) {
167                println!(
168                    "[NET-INTEGRATION] Warning: failed to register E1000: {:?}",
169                    e
170                );
171            }
172
173            Ok(())
174        }
175        Err(_) => Err(KernelError::NotFound {
176            resource: "e1000_hardware",
177            id: 0,
178        }),
179    }
180}
181
182/// Try to register VirtIO-Net driver if hardware is present
183fn try_register_virtio_net(bar_address: u64) -> Result<(), KernelError> {
184    use crate::drivers::virtio_net::VirtioNetDriver;
185
186    println!(
187        "[NET-INTEGRATION] Initializing VirtIO-Net at 0x{:x}",
188        bar_address
189    );
190
191    match VirtioNetDriver::new(bar_address as usize) {
192        Ok(driver) => {
193            let name = driver.name();
194            let mac = driver.mac_address();
195
196            println!(
197                "[NET-INTEGRATION] VirtIO-Net initialized: {} (MAC: \
198                 {:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x})",
199                name, mac.0[0], mac.0[1], mac.0[2], mac.0[3], mac.0[4], mac.0[5]
200            );
201
202            // Register with network device registry
203            if let Err(e) = device::register_device(Box::new(driver)) {
204                println!(
205                    "[NET-INTEGRATION] Warning: failed to register VirtIO-Net: {:?}",
206                    e
207                );
208            }
209
210            Ok(())
211        }
212        Err(_) => Err(KernelError::NotFound {
213            resource: "virtio_net_hardware",
214            id: 0,
215        }),
216    }
217}
218
219/// Register a manually-created network device (for testing/debugging)
220pub fn register_device(device: Box<dyn NetworkDevice>) -> Result<(), KernelError> {
221    device::register_device(device)
222}
223
224#[cfg(test)]
225mod tests {
226    use super::*;
227
228    #[test]
229    fn test_integration_init() {
230        // Basic smoke test
231        let result = register_drivers();
232        assert!(result.is_ok() || result.is_err()); // Always returns something
233    }
234}