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 crate::drivers::provider::Provider;
use crate::drivers::BlockDriver;
use crate::sync::SpinNoIrqLock as Mutex;
use super::super::{DeviceType, Driver, BLK_DRIVERS, DRIVERS};

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

@ -10,10 +10,8 @@ use smoltcp::phy::{self, DeviceCapabilities};
use smoltcp::time::Instant;
use smoltcp::wire::*;
use smoltcp::Result;
use bitflags::*;
use rcore_memory::PAGE_SIZE;
use crate::drivers::provider::Provider;
use crate::net::SOCKETS;
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_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 {
buffer: Vec<Vec<u8>>,
buffer: [Vec<Vec<u8>>; ENABLED_PORTS as usize],
}
impl Router {
@ -41,13 +59,13 @@ impl Router {
true
}
fn receive_available(&self) -> bool {
self.buffer.len() > 0
fn receive_available(&self, port: u8) -> bool {
self.buffer[port as usize].len() > 0
}
}
#[derive(Clone)]
pub struct RouterDriver(Arc<Mutex<Router>>);
pub struct RouterDriver(Arc<Mutex<Router>>, u8);
pub struct RouterRxToken(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)> {
let driver = self.0.lock();
if driver.transmit_available() && driver.receive_available() {
if driver.transmit_available() && driver.receive_available(self.1) {
// potential racing
Some((RouterRxToken(self.clone()), RouterTxToken(self.clone())))
} else {
@ -89,7 +107,7 @@ impl phy::RxToken for RouterRxToken {
F: FnOnce(&[u8]) -> Result<R>,
{
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)
}
}
@ -105,10 +123,11 @@ impl phy::TxToken for RouterTxToken {
unsafe {
AXI_STREAM_FIFO_TDR.write_volatile(2);
AXI_STREAM_FIFO_TDFD.write_volatile((self.0).1 as u32);
for byte in buffer {
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
}
@ -126,7 +145,7 @@ impl Driver for RouterInterface {
let isr = unsafe { AXI_STREAM_FIFO_ISR.read_volatile() };
if isr > 0 {
debug!("handle router interrupt {:b}", isr);
debug!("handle router interrupt {:?}", AXIStreamFifoInterrupt::from_bits_truncate(isr));
unsafe {
AXI_STREAM_FIFO_ISR.write(isr);
let rdfo = AXI_STREAM_FIFO_RDFO.read_volatile();
@ -134,11 +153,12 @@ impl Driver for RouterInterface {
let mut buffer = Vec::new();
let rlr = AXI_STREAM_FIFO_RLR.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);
}
debug!("got packet of length {}", rdfo);
driver.buffer.push(buffer);
debug!("got packet of length {} port {}", rdfo, port);
driver.buffer[port as usize].push(buffer);
}
drop(driver);
@ -183,7 +203,7 @@ impl Driver for RouterInterface {
}
}
pub fn router_init() -> Arc<RouterInterface> {
pub fn router_init() {
unsafe {
// reset tx fifo
AXI_STREAM_FIFO_TDFR.write_volatile(0xA5);
@ -191,38 +211,37 @@ pub fn router_init() -> Arc<RouterInterface> {
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 = [
IpCidr::new(IpAddress::v4(10, 0, 0, 1), 24),
IpCidr::new(IpAddress::v4(10, 0, 1, 1), 24),
];
let neighbor_cache = NeighborCache::new(BTreeMap::new());
let routes = Routes::new(BTreeMap::new());
let iface = EthernetInterfaceBuilder::new(net_driver.clone())
.ethernet_addr(ethernet_addr)
.ip_addrs(ip_addrs)
.neighbor_cache(neighbor_cache)
.routes(routes)
.finalize();
let ip_addrs = [
IpCidr::new(IpAddress::v4(10, 0, i, 1), 24),
];
let neighbor_cache = NeighborCache::new(BTreeMap::new());
let routes = Routes::new(BTreeMap::new());
let iface = EthernetInterfaceBuilder::new(net_driver.clone())
.ethernet_addr(ethernet_addr)
.ip_addrs(ip_addrs)
.neighbor_cache(neighbor_cache)
.routes(routes)
.finalize();
info!("router interface up");
info!("router interface up #{}", i);
let router_iface = RouterInterface {
iface: Mutex::new(iface),
driver: net_driver,
};
let router_iface = RouterInterface {
iface: Mutex::new(iface),
driver: net_driver,
};
let driver = Arc::new(router_iface);
DRIVERS.write().push(driver.clone());
NET_DRIVERS.write().push(driver.clone());
let driver = Arc::new(router_iface);
DRIVERS.write().push(driver.clone());
NET_DRIVERS.write().push(driver.clone());
}
// Enable Receive Complete Interrupt
unsafe {
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;
use crate::consts::PHYSICAL_MEMORY_OFFSET;
use crate::memory::{alloc_frame, dealloc_frame, phys_to_virt, virt_to_phys};
use isomorphic_drivers::provider;
use rcore_memory::paging::PageTable;
use rcore_memory::PAGE_SIZE;
pub struct Provider;

Loading…
Cancel
Save