Fix ixgbe driver

master
Jiajie Chen 6 years ago
parent e3b7efbc94
commit 56f8f128ba

@ -27,12 +27,17 @@ use crate::memory::active_table;
use crate::net::SOCKETS;
use crate::sync::SpinNoIrqLock as Mutex;
use crate::sync::{MutexGuard, SpinNoIrq};
use crate::sync::FlagsGuard;
use crate::HEAP_ALLOCATOR;
use super::super::{provider::Provider, DeviceType, Driver, DRIVERS, NET_DRIVERS, SOCKET_ACTIVITY};
#[derive(Clone)]
struct IXGBEDriver(ixgbe::IXGBEDriver);
struct IXGBEDriver {
inner: ixgbe::IXGBEDriver,
header: usize,
size: usize,
}
pub struct IXGBEInterface {
iface: Mutex<EthernetInterface<'static, 'static, 'static, IXGBEDriver>>,
@ -40,8 +45,6 @@ pub struct IXGBEInterface {
ifname: String,
irq: Option<u32>,
id: String,
header: usize,
size: usize,
}
impl Driver for IXGBEInterface {
@ -52,15 +55,18 @@ impl Driver for IXGBEInterface {
}
let handled = {
if let None = active_table().get_entry(self.header) {
let mut current_addr = self.header;
while current_addr < self.header + self.size {
let _ = FlagsGuard::no_irq_region();
let header = self.driver.header;
let size = self.driver.size;
if let None = active_table().get_entry(header) {
let mut current_addr = header;
while current_addr < header + size {
active_table().map_if_not_exists(current_addr, current_addr);
current_addr = current_addr + PAGE_SIZE;
}
}
self.driver.0.try_handle_interrupt()
self.driver.inner.try_handle_interrupt()
};
if handled {
@ -120,8 +126,18 @@ impl<'a> phy::Device<'a> for IXGBEDriver {
type TxToken = IXGBETxToken;
fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
if self.0.can_send() {
if let Some(data) = self.0.recv() {
let _ = FlagsGuard::no_irq_region();
let header = self.header;
let size = self.size;
if let None = active_table().get_entry(header) {
let mut current_addr = header;
while current_addr < header + size {
active_table().map_if_not_exists(current_addr, current_addr);
current_addr = current_addr + PAGE_SIZE;
}
}
if self.inner.can_send() {
if let Some(data) = self.inner.recv() {
Some((IXGBERxToken(data), IXGBETxToken(self.clone())))
} else {
None
@ -132,7 +148,17 @@ impl<'a> phy::Device<'a> for IXGBEDriver {
}
fn transmit(&'a mut self) -> Option<Self::TxToken> {
if self.0.can_send() {
let _ = FlagsGuard::no_irq_region();
let header = self.header;
let size = self.size;
if let None = active_table().get_entry(header) {
let mut current_addr = header;
while current_addr < header + size {
active_table().map_if_not_exists(current_addr, current_addr);
current_addr = current_addr + PAGE_SIZE;
}
}
if self.inner.can_send() {
Some(IXGBETxToken(self.clone()))
} else {
None
@ -163,10 +189,20 @@ impl phy::TxToken for IXGBETxToken {
where
F: FnOnce(&mut [u8]) -> Result<R>,
{
let _ = FlagsGuard::no_irq_region();
let header = self.0.header;
let size = self.0.size;
if let None = active_table().get_entry(header) {
let mut current_addr = header;
while current_addr < header + size {
active_table().map_if_not_exists(current_addr, current_addr);
current_addr = current_addr + PAGE_SIZE;
}
}
let mut buffer = [0u8; ixgbe::IXGBEDriver::get_mtu()];
let result = f(&mut buffer[..len]);
if result.is_ok() {
(self.0).0.send(&buffer[..len]);
(self.0).inner.send(&buffer[..len]);
}
result
}
@ -178,10 +214,22 @@ pub fn ixgbe_init(
header: usize,
size: usize,
) -> Arc<IXGBEInterface> {
let _ = FlagsGuard::no_irq_region();
if let None = active_table().get_entry(header) {
let mut current_addr = header;
while current_addr < header + size {
active_table().map_if_not_exists(current_addr, current_addr);
current_addr = current_addr + PAGE_SIZE;
}
}
let ixgbe = ixgbe::IXGBEDriver::init(Provider::new(), header, size);
let ethernet_addr = EthernetAddress::from_bytes(&ixgbe.get_mac().as_bytes());
let net_driver = IXGBEDriver(ixgbe);
let net_driver = IXGBEDriver{
inner: ixgbe,
header,
size,
};
let ip_addrs = [IpCidr::new(IpAddress::v4(10, 0, 0, 2), 24)];
let neighbor_cache = NeighborCache::new(BTreeMap::new());
@ -199,8 +247,6 @@ pub fn ixgbe_init(
ifname: name.clone(),
id: name,
irq,
header,
size,
};
let driver = Arc::new(ixgbe_iface);

@ -238,6 +238,12 @@ impl Drop for FlagsGuard {
}
}
impl FlagsGuard {
pub fn no_irq_region() -> Self {
Self(unsafe { interrupt::disable_and_store() })
}
}
impl MutexSupport for SpinNoIrq {
type GuardData = FlagsGuard;
fn new() -> Self {

Loading…
Cancel
Save