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 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);
}
}
}

@ -140,11 +140,12 @@ pub struct IXGBEInterface {
iface: Mutex<EthernetInterface<'static, 'static, 'static, IXGBEDriver>>,
driver: IXGBEDriver,
sockets: Mutex<SocketSet<'static, 'static, 'static>>,
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 {
false
// link down
info!("ixgbe: interface {} link down", &self.name);
}
}
if icr & (1 << 0) != 0 {
// rx interrupt
(true, true)
} else {
(true, false)
}
} else {
(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<Ipv4Address> {
@ -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::<IXGBESendDesc>(), 16);
assert_eq!(size_of::<IXGBERecvDesc>(), 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);
}

Loading…
Cancel
Save