Split router ports into different ifaces

master
Jiajie Chen 6 years ago
parent 20da06add5
commit 6f5414c531

@ -8,7 +8,6 @@ use alloc::sync::Arc;
use isomorphic_drivers::block::ahci::{AHCI, BLOCK_SIZE}; use isomorphic_drivers::block::ahci::{AHCI, BLOCK_SIZE};
use crate::drivers::provider::Provider; use crate::drivers::provider::Provider;
use crate::drivers::BlockDriver;
use crate::sync::SpinNoIrqLock as Mutex; use crate::sync::SpinNoIrqLock as Mutex;
use super::super::{DeviceType, Driver, BLK_DRIVERS, DRIVERS}; use super::super::{DeviceType, Driver, BLK_DRIVERS, DRIVERS};

@ -11,8 +11,6 @@ use log::*;
use rcore_memory::PAGE_SIZE; use rcore_memory::PAGE_SIZE;
use volatile::Volatile; use volatile::Volatile;
use crate::arch::consts::PHYSICAL_MEMORY_OFFSET;
use crate::drivers::BlockDriver;
use crate::sync::SpinNoIrqLock as Mutex; use crate::sync::SpinNoIrqLock as Mutex;
use super::super::bus::virtio_mmio::*; use super::super::bus::virtio_mmio::*;

@ -10,10 +10,8 @@ use smoltcp::phy::{self, DeviceCapabilities};
use smoltcp::time::Instant; use smoltcp::time::Instant;
use smoltcp::wire::*; use smoltcp::wire::*;
use smoltcp::Result; use smoltcp::Result;
use bitflags::*;
use rcore_memory::PAGE_SIZE;
use crate::drivers::provider::Provider;
use crate::net::SOCKETS; use crate::net::SOCKETS;
use crate::sync::SpinNoIrqLock as Mutex; use crate::sync::SpinNoIrqLock as Mutex;
@ -32,8 +30,28 @@ const AXI_STREAM_FIFO_RLR: *mut u32 = phys_to_virt(0x64A0_0024) as *mut u32;
const AXI_STREAM_FIFO_TDR: *mut u32 = phys_to_virt(0x64A0_002C) as *mut u32; const AXI_STREAM_FIFO_TDR: *mut u32 = phys_to_virt(0x64A0_002C) as *mut u32;
const AXI_STREAM_FIFO_RDR: *mut u32 = phys_to_virt(0x64A0_0030) as *mut u32; const AXI_STREAM_FIFO_RDR: *mut u32 = phys_to_virt(0x64A0_0030) as *mut u32;
const ENABLED_PORTS: u8 = 2;
bitflags! {
struct AXIStreamFifoInterrupt : u32 {
const RECV_EMPTY = 1 << 19;
const RECV_FULL = 1 << 20;
const TRAN_EMPTY = 1 << 21;
const TRAN_FULL = 1 << 22;
const RECV_RESET = 1 << 23;
const TRAN_RESET = 1 << 24;
const TRAN_SIZE_ERR = 1 << 25;
const RECV_COMPLETE = 1 << 26;
const TRAN_COMPLETE = 1 << 27;
const TRAN_PACKET_OVERRUN_ERR = 1 << 28;
const RECV_PACKET_UNDERRUN_ERR = 1 << 29;
const RECV_PACKET_OVERRUN_READ_ERR = 1 << 30;
const RECV_PACKET_UNDERRUN_READ_ERR = 1 << 31;
}
}
pub struct Router { pub struct Router {
buffer: Vec<Vec<u8>>, buffer: [Vec<Vec<u8>>; ENABLED_PORTS as usize],
} }
impl Router { impl Router {
@ -41,13 +59,13 @@ impl Router {
true true
} }
fn receive_available(&self) -> bool { fn receive_available(&self, port: u8) -> bool {
self.buffer.len() > 0 self.buffer[port as usize].len() > 0
} }
} }
#[derive(Clone)] #[derive(Clone)]
pub struct RouterDriver(Arc<Mutex<Router>>); pub struct RouterDriver(Arc<Mutex<Router>>, u8);
pub struct RouterRxToken(RouterDriver); pub struct RouterRxToken(RouterDriver);
pub struct RouterTxToken(RouterDriver); pub struct RouterTxToken(RouterDriver);
@ -58,7 +76,7 @@ impl<'a> phy::Device<'a> for RouterDriver {
fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> { fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
let driver = self.0.lock(); let driver = self.0.lock();
if driver.transmit_available() && driver.receive_available() { if driver.transmit_available() && driver.receive_available(self.1) {
// potential racing // potential racing
Some((RouterRxToken(self.clone()), RouterTxToken(self.clone()))) Some((RouterRxToken(self.clone()), RouterTxToken(self.clone())))
} else { } else {
@ -89,7 +107,7 @@ impl phy::RxToken for RouterRxToken {
F: FnOnce(&[u8]) -> Result<R>, F: FnOnce(&[u8]) -> Result<R>,
{ {
let mut router = (self.0).0.lock(); let mut router = (self.0).0.lock();
let buffer = router.buffer.pop().unwrap(); let buffer = router.buffer[(self.0).1 as usize].pop().unwrap();
f(&buffer) f(&buffer)
} }
} }
@ -105,10 +123,11 @@ impl phy::TxToken for RouterTxToken {
unsafe { unsafe {
AXI_STREAM_FIFO_TDR.write_volatile(2); AXI_STREAM_FIFO_TDR.write_volatile(2);
AXI_STREAM_FIFO_TDFD.write_volatile((self.0).1 as u32);
for byte in buffer { for byte in buffer {
AXI_STREAM_FIFO_TDFD.write_volatile(byte as u32); AXI_STREAM_FIFO_TDFD.write_volatile(byte as u32);
} }
AXI_STREAM_FIFO_TLR.write((len * 4) as u32); AXI_STREAM_FIFO_TLR.write(((len + 1) * 4) as u32);
} }
res res
} }
@ -126,7 +145,7 @@ impl Driver for RouterInterface {
let isr = unsafe { AXI_STREAM_FIFO_ISR.read_volatile() }; let isr = unsafe { AXI_STREAM_FIFO_ISR.read_volatile() };
if isr > 0 { if isr > 0 {
debug!("handle router interrupt {:b}", isr); debug!("handle router interrupt {:?}", AXIStreamFifoInterrupt::from_bits_truncate(isr));
unsafe { unsafe {
AXI_STREAM_FIFO_ISR.write(isr); AXI_STREAM_FIFO_ISR.write(isr);
let rdfo = AXI_STREAM_FIFO_RDFO.read_volatile(); let rdfo = AXI_STREAM_FIFO_RDFO.read_volatile();
@ -134,11 +153,12 @@ impl Driver for RouterInterface {
let mut buffer = Vec::new(); let mut buffer = Vec::new();
let rlr = AXI_STREAM_FIFO_RLR.read_volatile(); let rlr = AXI_STREAM_FIFO_RLR.read_volatile();
let rdr = AXI_STREAM_FIFO_RDR.read_volatile(); let rdr = AXI_STREAM_FIFO_RDR.read_volatile();
for i in 0..rdfo { let port = AXI_STREAM_FIFO_RDFD.read_volatile();
for i in 1..rdfo {
buffer.push(AXI_STREAM_FIFO_RDFD.read_volatile() as u8); buffer.push(AXI_STREAM_FIFO_RDFD.read_volatile() as u8);
} }
debug!("got packet of length {}", rdfo); debug!("got packet of length {} port {}", rdfo, port);
driver.buffer.push(buffer); driver.buffer[port as usize].push(buffer);
} }
drop(driver); drop(driver);
@ -183,7 +203,7 @@ impl Driver for RouterInterface {
} }
} }
pub fn router_init() -> Arc<RouterInterface> { pub fn router_init() {
unsafe { unsafe {
// reset tx fifo // reset tx fifo
AXI_STREAM_FIFO_TDFR.write_volatile(0xA5); AXI_STREAM_FIFO_TDFR.write_volatile(0xA5);
@ -191,38 +211,37 @@ pub fn router_init() -> Arc<RouterInterface> {
AXI_STREAM_FIFO_RDFR.write_volatile(0xA5); AXI_STREAM_FIFO_RDFR.write_volatile(0xA5);
} }
let ethernet_addr = EthernetAddress::from_bytes(&[2, 2, 3, 3, 0, 0]); for i in 0..ENABLED_PORTS {
let ethernet_addr = EthernetAddress::from_bytes(&[2, 2, 3, 3, 0, i]);
let net_driver = RouterDriver(Arc::new(Mutex::new(Router { buffer: Vec::new() }))); let net_driver = RouterDriver(Arc::new(Mutex::new(Router { buffer: [Vec::new(), Vec::new()] })), i);
let ip_addrs = [ let ip_addrs = [
IpCidr::new(IpAddress::v4(10, 0, 0, 1), 24), IpCidr::new(IpAddress::v4(10, 0, i, 1), 24),
IpCidr::new(IpAddress::v4(10, 0, 1, 1), 24), ];
]; let neighbor_cache = NeighborCache::new(BTreeMap::new());
let neighbor_cache = NeighborCache::new(BTreeMap::new()); let routes = Routes::new(BTreeMap::new());
let routes = Routes::new(BTreeMap::new()); let iface = EthernetInterfaceBuilder::new(net_driver.clone())
let iface = EthernetInterfaceBuilder::new(net_driver.clone()) .ethernet_addr(ethernet_addr)
.ethernet_addr(ethernet_addr) .ip_addrs(ip_addrs)
.ip_addrs(ip_addrs) .neighbor_cache(neighbor_cache)
.neighbor_cache(neighbor_cache) .routes(routes)
.routes(routes) .finalize();
.finalize();
info!("router interface up"); info!("router interface up #{}", i);
let router_iface = RouterInterface { let router_iface = RouterInterface {
iface: Mutex::new(iface), iface: Mutex::new(iface),
driver: net_driver, driver: net_driver,
}; };
let driver = Arc::new(router_iface); let driver = Arc::new(router_iface);
DRIVERS.write().push(driver.clone()); DRIVERS.write().push(driver.clone());
NET_DRIVERS.write().push(driver.clone()); NET_DRIVERS.write().push(driver.clone());
}
// Enable Receive Complete Interrupt // Enable Receive Complete Interrupt
unsafe { unsafe {
AXI_STREAM_FIFO_IER.write_volatile(1 << 26); AXI_STREAM_FIFO_IER.write_volatile(1 << 26);
} }
driver
} }

@ -1,10 +1,6 @@
use alloc::alloc::{alloc_zeroed, dealloc, Layout};
pub use crate::arch::paging::PageTableImpl; pub use crate::arch::paging::PageTableImpl;
use crate::consts::PHYSICAL_MEMORY_OFFSET;
use crate::memory::{alloc_frame, dealloc_frame, phys_to_virt, virt_to_phys}; use crate::memory::{alloc_frame, dealloc_frame, phys_to_virt, virt_to_phys};
use isomorphic_drivers::provider; use isomorphic_drivers::provider;
use rcore_memory::paging::PageTable;
use rcore_memory::PAGE_SIZE; use rcore_memory::PAGE_SIZE;
pub struct Provider; pub struct Provider;

Loading…
Cancel
Save