Name ixgbe interfaces after systemd's and show link status change event

master
Jiajie Chen 6 years ago
parent d0202c945e
commit c423f10483

@ -1,5 +1,6 @@
use crate::drivers::net::*; use crate::drivers::net::*;
use x86_64::instructions::port::Port; use x86_64::instructions::port::Port;
use alloc::string::String;
const PCI_VENDOR: u32 = 0x00; const PCI_VENDOR: u32 = 0x00;
const PCI_DEVICE: u32 = 0x02; const PCI_DEVICE: u32 = 0x02;
@ -207,11 +208,11 @@ impl PciTag {
// enable MSI interrupt // enable MSI interrupt
let orig_ctrl = self.read(cap_ptr + PCI_MSI_CTRL_CAP, 4); let orig_ctrl = self.read(cap_ptr + PCI_MSI_CTRL_CAP, 4);
self.write(cap_ptr + PCI_MSI_CTRL_CAP, orig_ctrl | 0x10000); 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; msi_found = true;
break; 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); cap_ptr = self.read(cap_ptr + 1, 1);
} }
@ -221,12 +222,12 @@ impl PciTag {
self.write(PCI_COMMAND, orig | 0xf); self.write(PCI_COMMAND, orig | 0xf);
let line = self.read(PCI_INTERRUPT_LINE, 1); let line = self.read(PCI_INTERRUPT_LINE, 1);
let pin = self.read(PCI_INTERRUPT_PIN, 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 vid == 0x8086 {
if did == 0x100e || did == 0x100f || did == 0x10d3 || did == 0x15b8 { if did == 0x100e || did == 0x100f || did == 0x10d3 || did == 0x15b8 {
// 0x100e // 0x100e
@ -237,19 +238,21 @@ pub fn init_driver(vid: u32, did: u32, tag: PciTag) {
// 82574L Gigabit Network Connection // 82574L Gigabit Network Connection
// 0x15b8 // 0x15b8
// Ethernet Connection (2) I219-V // Ethernet Connection (2) I219-V
/*
if let Some((addr, len)) = unsafe { tag.get_bar_mem(0) } { if let Some((addr, len)) = unsafe { tag.get_bar_mem(0) } {
unsafe { unsafe {
tag.enable(); tag.enable();
} }
e1000::e1000_init(addr, len); e1000::e1000_init(addr, len);
} }
*/
} else if did == 0x10fb { } else if did == 0x10fb {
// 82599ES 10-Gigabit SFI/SFP+ Network Connection // 82599ES 10-Gigabit SFI/SFP+ Network Connection
if let Some((addr, len)) = unsafe { tag.get_bar_mem(0) } { if let Some((addr, len)) = unsafe { tag.get_bar_mem(0) } {
unsafe { unsafe {
tag.enable(); 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 { for dev in 0..32 {
let tag = PciTag::new(bus, dev, 0); let tag = PciTag::new(bus, dev, 0);
if let Some((vid, did, next)) = tag.probe() { 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 { if next {
for func in 1..8 { for func in 1..8 {
let tag = PciTag::new(bus, dev, func); let tag = PciTag::new(bus, dev, func);
if let Some((vid, did, _)) = tag.probe() { 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);
} }
} }
} }

@ -140,11 +140,12 @@ pub struct IXGBEInterface {
iface: Mutex<EthernetInterface<'static, 'static, 'static, IXGBEDriver>>, iface: Mutex<EthernetInterface<'static, 'static, 'static, IXGBEDriver>>,
driver: IXGBEDriver, driver: IXGBEDriver,
sockets: Mutex<SocketSet<'static, 'static, 'static>>, sockets: Mutex<SocketSet<'static, 'static, 'static>>,
name: String,
} }
impl Driver for IXGBEInterface { impl Driver for IXGBEInterface {
fn try_handle_interrupt(&self) -> bool { fn try_handle_interrupt(&self) -> bool {
let irq = { let (handled, rx) = {
let driver = self.driver.0.lock(); let driver = self.driver.0.lock();
if let None = active_table().get_entry(driver.header) { if let None = active_table().get_entry(driver.header) {
@ -163,13 +164,29 @@ impl Driver for IXGBEInterface {
if icr != 0 { if icr != 0 {
// clear it // clear it
ixgbe[IXGBE_EICR].write(icr); 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 { } else {
false (false, false)
} }
}; };
if irq { if rx {
let timestamp = Instant::from_millis(crate::trap::uptime_msec() as i64); let timestamp = Instant::from_millis(crate::trap::uptime_msec() as i64);
let mut sockets = self.sockets.lock(); let mut sockets = self.sockets.lock();
match self.iface.lock().poll(&mut sockets, timestamp) { 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 { fn device_type(&self) -> DeviceType {
@ -196,7 +213,7 @@ impl NetDriver for IXGBEInterface {
} }
fn get_ifname(&self) -> String { fn get_ifname(&self) -> String {
format!("ixgbe") self.name.clone()
} }
fn ipv4_address(&self) -> Option<Ipv4Address> { fn ipv4_address(&self) -> Option<Ipv4Address> {
@ -403,8 +420,9 @@ impl phy::TxToken for IXGBETxToken {
bitflags! { bitflags! {
struct IXGBEStatus : u32 { struct IXGBEStatus : u32 {
const LANID0 = 1 << 2; // if LANID1 is clear, this is LAN0
const LABID1 = 1 << 3; // if LANID1 is set, this is LAN1
const LANID1 = 1 << 2;
const LINK_UP = 1 << 7; const LINK_UP = 1 << 7;
const NUM_VFS1 = 1 << 10; const NUM_VFS1 = 1 << 10;
const NUM_VFS2 = 1 << 11; const NUM_VFS2 = 1 << 11;
@ -418,8 +436,7 @@ bitflags! {
} }
} }
pub fn ixgbe_init(header: usize, size: usize) { pub fn ixgbe_init(name: String, header: usize, size: usize) {
info!("Probing ixgbe");
assert_eq!(size_of::<IXGBESendDesc>(), 16); assert_eq!(size_of::<IXGBESendDesc>(), 16);
assert_eq!(size_of::<IXGBERecvDesc>(), 16); assert_eq!(size_of::<IXGBERecvDesc>(), 16);
@ -743,8 +760,8 @@ pub fn ixgbe_init(header: usize, size: usize) {
// clear all interrupt // clear all interrupt
ixgbe[IXGBE_EICR].write(!0); ixgbe[IXGBE_EICR].write(!0);
// Software enables the required interrupt causes by setting the EIMS register. // Software enables the required interrupt causes by setting the EIMS register.
// unmask tx/rx interrupts // unmask rx interrupt and link status change
ixgbe[IXGBE_EIMS].write(1 << 0); ixgbe[IXGBE_EIMS].write((1 << 0) | (1 << 20));
debug!( debug!(
"status after setup: {:#?}", "status after setup: {:#?}",
@ -762,13 +779,17 @@ pub fn ixgbe_init(header: usize, size: usize) {
.neighbor_cache(neighbor_cache) .neighbor_cache(neighbor_cache)
.finalize(); .finalize();
info!("ixgbe: interface {} up", &name);
let ixgbe_iface = IXGBEInterface { let ixgbe_iface = IXGBEInterface {
iface: Mutex::new(iface), iface: Mutex::new(iface),
sockets: Mutex::new(SocketSet::new(vec![])), sockets: Mutex::new(SocketSet::new(vec![])),
driver: net_driver.clone(), driver: net_driver.clone(),
name,
}; };
let driver = Arc::new(ixgbe_iface); let driver = Arc::new(ixgbe_iface);
DRIVERS.write().push(driver.clone()); DRIVERS.write().push(driver.clone());
NET_DRIVERS.write().push(driver); NET_DRIVERS.write().push(driver);
} }

Loading…
Cancel
Save