diff --git a/axdriver_net/Cargo.toml b/axdriver_net/Cargo.toml index ef2f209..751ab37 100644 --- a/axdriver_net/Cargo.toml +++ b/axdriver_net/Cargo.toml @@ -14,9 +14,11 @@ categories.workspace = true [features] default = [] ixgbe = ["dep:ixgbe-driver"] +fxmac = ["dep:fxmac_rs"] [dependencies] spin = "0.9" log = "0.4" axdriver_base = { workspace = true } ixgbe-driver = { git = "https://github.com/KuangjuX/ixgbe-driver.git", rev = "8e5eb74", optional = true} +fxmac_rs = { git = "https://github.com/elliott10/fxmac_rs.git", branch = "main", optional = true } diff --git a/axdriver_net/src/fxmac.rs b/axdriver_net/src/fxmac.rs new file mode 100644 index 0000000..ff3e9bb --- /dev/null +++ b/axdriver_net/src/fxmac.rs @@ -0,0 +1,136 @@ +use alloc::boxed::Box; +use alloc::vec::Vec; +use alloc::collections::VecDeque; +use core::ptr::NonNull; +use axdriver_base::{BaseDriverOps, DevError, DevResult, DeviceType}; +use crate::{EthernetAddress, NetBufPtr, NetDriverOps}; + +use log::*; +use fxmac_rs::{self, FXmac, xmac_init, FXmacLwipPortTx, FXmacRecvHandler}; + +extern crate alloc; + +const QS: usize = 64; +//const NET_BUF_LEN: usize = 1526; + +pub struct FXmacNic { + inner: &'static mut FXmac, + rx_buffer_queue: VecDeque, +} + +unsafe impl Sync for FXmacNic {} +unsafe impl Send for FXmacNic {} + +impl FXmacNic { + pub fn init(mapped_regs: usize) -> DevResult { + info!("FXmacNic init @ {:#x}", mapped_regs); + let rx_buffer_queue = VecDeque::with_capacity(QS); + let hwaddr: [u8; 6] = [0x98, 0x0e, 0x24, 0x00, 0x11, 0x0]; + let inner = xmac_init(&hwaddr); + + let dev = Self { + inner, + rx_buffer_queue, + }; + Ok(dev) + } +} + +impl BaseDriverOps for FXmacNic { + fn device_name(&self) -> &str { + "cdns,phytium-gem-1.0" + } + + fn device_type(&self) -> DeviceType { + DeviceType::Net + } +} + +impl NetDriverOps for FXmacNic { + fn mac_address(&self) -> EthernetAddress { + EthernetAddress([0x98, 0x0e, 0x24, 0x00, 0x11, 0x0]) + } + + fn rx_queue_size(&self) -> usize { + QS + } + + fn tx_queue_size(&self) -> usize { + QS + } + + fn can_receive(&self) -> bool { + !self.rx_buffer_queue.is_empty() + } + + fn can_transmit(&self) -> bool { + //!self.free_tx_bufs.is_empty() + true + } + + fn recycle_rx_buffer(&mut self, rx_buf: NetBufPtr) -> DevResult { + unsafe { + drop(Box::from_raw(rx_buf.raw_ptr::())); + } + drop(rx_buf); + Ok(()) + } + + fn recycle_tx_buffers(&mut self) -> DevResult { + // drop tx_buf + Ok(()) + } + + fn receive(&mut self) -> DevResult { + if !self.rx_buffer_queue.is_empty() { + // RX buffer have received packets. + Ok(self.rx_buffer_queue.pop_front().unwrap()) + } else { + match FXmacRecvHandler(self.inner) { + None => Err(DevError::Again), + Some(packets) => { + for packet in packets { + info!("received packet length {}", packet.len()); + let mut buf = Box::new(packet); + let buf_ptr = buf.as_mut_ptr() as *mut u8; + let buf_len = buf.len(); + let rx_buf = NetBufPtr::new( + NonNull::new(Box::into_raw(buf) as *mut u8).unwrap(), + NonNull::new(buf_ptr).unwrap(), + buf_len, + ); + + self.rx_buffer_queue.push_back(rx_buf); + } + + Ok(self.rx_buffer_queue.pop_front().unwrap()) + } + } + } + } + + fn transmit(&mut self, tx_buf: NetBufPtr) -> DevResult { + let mut tx_vec = Vec::new(); + tx_vec.push(tx_buf.packet().to_vec()); + let ret = FXmacLwipPortTx(self.inner, tx_vec); + unsafe { + drop(Box::from_raw(tx_buf.raw_ptr::())); + } + if ret < 0 { + Err(DevError::Again) + } else { + Ok(()) + } + } + + fn alloc_tx_buffer(&mut self, size: usize) -> DevResult { + let mut tx_buf = Box::new(alloc::vec![0; size]); + let tx_buf_ptr = tx_buf.as_mut_ptr(); + + Ok(NetBufPtr::new( + NonNull::new(Box::into_raw(tx_buf) as *mut u8).unwrap(), + NonNull::new(tx_buf_ptr).unwrap(), + size, + )) + } +} diff --git a/axdriver_net/src/lib.rs b/axdriver_net/src/lib.rs index f0c5935..0002780 100644 --- a/axdriver_net/src/lib.rs +++ b/axdriver_net/src/lib.rs @@ -1,12 +1,13 @@ //! Common traits and types for network device (NIC) drivers. #![no_std] -#![feature(const_mut_refs)] -#![feature(const_slice_from_raw_parts_mut)] #[cfg(feature = "ixgbe")] /// ixgbe NIC device driver. pub mod ixgbe; +#[cfg(feature = "fxmac")] +/// fxmac driver for PhytiumPi +pub mod fxmac; mod net_buf; use core::ptr::NonNull;