From c423f10483a445a29b297f8c25809ad5bcd013b2 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Mon, 18 Mar 2019 19:26:47 +0800 Subject: [PATCH] Name ixgbe interfaces after systemd's and show link status change event --- kernel/src/drivers/bus/pci.rs | 19 +++++++++----- kernel/src/drivers/net/ixgbe.rs | 45 ++++++++++++++++++++++++--------- 2 files changed, 45 insertions(+), 19 deletions(-) diff --git a/kernel/src/drivers/bus/pci.rs b/kernel/src/drivers/bus/pci.rs index c214e16..4b61606 100644 --- a/kernel/src/drivers/bus/pci.rs +++ b/kernel/src/drivers/bus/pci.rs @@ -1,5 +1,6 @@ use crate::drivers::net::*; use x86_64::instructions::port::Port; +use alloc::string::String; const PCI_VENDOR: u32 = 0x00; const PCI_DEVICE: u32 = 0x02; @@ -207,11 +208,11 @@ impl PciTag { // enable MSI interrupt let orig_ctrl = self.read(cap_ptr + PCI_MSI_CTRL_CAP, 4); self.write(cap_ptr + PCI_MSI_CTRL_CAP, orig_ctrl | 0x10000); - info!("MSI control {:#b}, enabling MSI interrupts", orig_ctrl >> 16); + debug!("MSI control {:#b}, enabling MSI interrupts", orig_ctrl >> 16); msi_found = true; break; } - info!("PCI device has cap id {} at {:#X}", self.read(cap_ptr, 1), cap_ptr); + debug!("PCI device has cap id {} at {:#X}", self.read(cap_ptr, 1), cap_ptr); cap_ptr = self.read(cap_ptr + 1, 1); } @@ -221,12 +222,12 @@ impl PciTag { self.write(PCI_COMMAND, orig | 0xf); let line = self.read(PCI_INTERRUPT_LINE, 1); let pin = self.read(PCI_INTERRUPT_PIN, 1); - info!("MSI not found, using PCI interrupt line {} pin {}", line, pin); + debug!("MSI not found, using PCI interrupt line {} pin {}", line, pin); } } } -pub fn init_driver(vid: u32, did: u32, tag: PciTag) { +pub fn init_driver(name: String, vid: u32, did: u32, tag: PciTag) { if vid == 0x8086 { if did == 0x100e || did == 0x100f || did == 0x10d3 || did == 0x15b8 { // 0x100e @@ -237,19 +238,21 @@ pub fn init_driver(vid: u32, did: u32, tag: PciTag) { // 82574L Gigabit Network Connection // 0x15b8 // Ethernet Connection (2) I219-V + /* if let Some((addr, len)) = unsafe { tag.get_bar_mem(0) } { unsafe { tag.enable(); } e1000::e1000_init(addr, len); } + */ } else if did == 0x10fb { // 82599ES 10-Gigabit SFI/SFP+ Network Connection if let Some((addr, len)) = unsafe { tag.get_bar_mem(0) } { unsafe { tag.enable(); } - //ixgbe::ixgbe_init(addr, len); + ixgbe::ixgbe_init(name, addr, len); } } } @@ -260,12 +263,14 @@ pub fn init() { for dev in 0..32 { let tag = PciTag::new(bus, dev, 0); if let Some((vid, did, next)) = tag.probe() { - init_driver(vid, did, tag); + let name = format!("enp{}s{}f0", bus, dev); + init_driver(name, vid, did, tag); if next { for func in 1..8 { let tag = PciTag::new(bus, dev, func); if let Some((vid, did, _)) = tag.probe() { - init_driver(vid, did, tag); + let name = format!("enp{}s{}f{}", bus, dev, func); + init_driver(name, vid, did, tag); } } } diff --git a/kernel/src/drivers/net/ixgbe.rs b/kernel/src/drivers/net/ixgbe.rs index 88fe4c6..a844a22 100644 --- a/kernel/src/drivers/net/ixgbe.rs +++ b/kernel/src/drivers/net/ixgbe.rs @@ -140,11 +140,12 @@ pub struct IXGBEInterface { iface: Mutex>, driver: IXGBEDriver, sockets: Mutex>, + name: String, } impl Driver for IXGBEInterface { fn try_handle_interrupt(&self) -> bool { - let irq = { + let (handled, rx) = { let driver = self.driver.0.lock(); if let None = active_table().get_entry(driver.header) { @@ -163,13 +164,29 @@ impl Driver for IXGBEInterface { if icr != 0 { // clear it ixgbe[IXGBE_EICR].write(icr); - true + if icr & (1 << 20) != 0 { + // link status change + let status = ixgbe[IXGBE_LINKS].read(); + if status & (1 << 7) != 0 { + // link up + info!("ixgbe: interface {} link up", &self.name); + } else { + // link down + info!("ixgbe: interface {} link down", &self.name); + } + } + if icr & (1 << 0) != 0 { + // rx interrupt + (true, true) + } else { + (true, false) + } } else { - false + (false, false) } }; - if irq { + if rx { let timestamp = Instant::from_millis(crate::trap::uptime_msec() as i64); let mut sockets = self.sockets.lock(); match self.iface.lock().poll(&mut sockets, timestamp) { @@ -182,7 +199,7 @@ impl Driver for IXGBEInterface { } } - return irq; + return handled; } fn device_type(&self) -> DeviceType { @@ -196,7 +213,7 @@ impl NetDriver for IXGBEInterface { } fn get_ifname(&self) -> String { - format!("ixgbe") + self.name.clone() } fn ipv4_address(&self) -> Option { @@ -403,8 +420,9 @@ impl phy::TxToken for IXGBETxToken { bitflags! { struct IXGBEStatus : u32 { - const LANID0 = 1 << 2; - const LABID1 = 1 << 3; + // if LANID1 is clear, this is LAN0 + // if LANID1 is set, this is LAN1 + const LANID1 = 1 << 2; const LINK_UP = 1 << 7; const NUM_VFS1 = 1 << 10; const NUM_VFS2 = 1 << 11; @@ -418,8 +436,7 @@ bitflags! { } } -pub fn ixgbe_init(header: usize, size: usize) { - info!("Probing ixgbe"); +pub fn ixgbe_init(name: String, header: usize, size: usize) { assert_eq!(size_of::(), 16); assert_eq!(size_of::(), 16); @@ -743,8 +760,8 @@ pub fn ixgbe_init(header: usize, size: usize) { // clear all interrupt ixgbe[IXGBE_EICR].write(!0); // Software enables the required interrupt causes by setting the EIMS register. - // unmask tx/rx interrupts - ixgbe[IXGBE_EIMS].write(1 << 0); + // unmask rx interrupt and link status change + ixgbe[IXGBE_EIMS].write((1 << 0) | (1 << 20)); debug!( "status after setup: {:#?}", @@ -762,13 +779,17 @@ pub fn ixgbe_init(header: usize, size: usize) { .neighbor_cache(neighbor_cache) .finalize(); + info!("ixgbe: interface {} up", &name); + let ixgbe_iface = IXGBEInterface { iface: Mutex::new(iface), sockets: Mutex::new(SocketSet::new(vec![])), driver: net_driver.clone(), + name, }; let driver = Arc::new(ixgbe_iface); DRIVERS.write().push(driver.clone()); NET_DRIVERS.write().push(driver); + }