From 56f8f128ba62bcf874be3fe17ad80a45c2ac16f3 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Wed, 20 Mar 2019 16:43:40 +0800 Subject: [PATCH] Fix ixgbe driver --- kernel/src/drivers/net/ixgbe.rs | 74 ++++++++++++++++++++++++++------- kernel/src/sync/mutex.rs | 6 +++ 2 files changed, 66 insertions(+), 14 deletions(-) diff --git a/kernel/src/drivers/net/ixgbe.rs b/kernel/src/drivers/net/ixgbe.rs index 96f5dcc..d53910f 100644 --- a/kernel/src/drivers/net/ixgbe.rs +++ b/kernel/src/drivers/net/ixgbe.rs @@ -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>, @@ -40,8 +45,6 @@ pub struct IXGBEInterface { ifname: String, irq: Option, 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 { - 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, { + 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 { + 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); diff --git a/kernel/src/sync/mutex.rs b/kernel/src/sync/mutex.rs index 6fc62c4..dc0158e 100644 --- a/kernel/src/sync/mutex.rs +++ b/kernel/src/sync/mutex.rs @@ -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 {