Hardware Implementations
Relevant source files
This document covers the concrete network hardware driver implementations that provide device-specific functionality within the axdriver network subsystem. These implementations demonstrate how the abstract NetDriverOps
trait is realized for specific network controllers, including buffer management strategies and hardware abstraction layer integration.
For information about the network driver interface abstractions, see Network Driver Interface. For details about buffer management patterns, see Network Buffer Management.
Overview
The axdriver network subsystem includes two primary hardware implementations that showcase different architectural approaches:
Driver | Hardware Target | Buffer Strategy | External Dependencies |
---|---|---|---|
FXmacNic | PhytiumPi Ethernet Controller | Queue-based RX buffering | fxmac_rscrate |
IxgbeNic | Intel 10GbE Controller | Memory pool allocation | ixgbe-drivercrate |
Both implementations provide the same NetDriverOps
interface while handling hardware-specific details internally.
FXmac Network Controller Implementation
Architecture and Integration
The FXmacNic
struct provides an implementation for PhytiumPi Ethernet controllers using a queue-based approach for receive buffer management.
flowchart TD subgraph subGraph2["Trait Implementation"] BASE_OPS["BaseDriverOps"] NET_OPS["NetDriverOps"] DEVICE_NAME["device_name()"] MAC_ADDR["mac_address()"] RECEIVE["receive()"] TRANSMIT["transmit()"] end subgraph subGraph1["External Hardware Layer"] FXMAC_RS["fxmac_rs crate"] XMAC_INIT["xmac_init()"] GET_MAC["FXmacGetMacAddress()"] RECV_HANDLER["FXmacRecvHandler()"] TX_FUNC["FXmacLwipPortTx()"] end subgraph subGraph0["FXmacNic Driver Structure"] FXMAC_STRUCT["FXmacNic"] INNER["inner: &'static mut FXmac"] HWADDR["hwaddr: [u8; 6]"] RX_QUEUE["rx_buffer_queue: VecDeque"] end BASE_OPS --> DEVICE_NAME FXMAC_STRUCT --> BASE_OPS FXMAC_STRUCT --> HWADDR FXMAC_STRUCT --> INNER FXMAC_STRUCT --> NET_OPS FXMAC_STRUCT --> RX_QUEUE HWADDR --> GET_MAC INNER --> XMAC_INIT NET_OPS --> MAC_ADDR NET_OPS --> RECEIVE NET_OPS --> TRANSMIT RECEIVE --> RECV_HANDLER TRANSMIT --> TX_FUNC
Sources: axdriver_net/src/fxmac.rs(L1 - L145)
Initialization and Hardware Integration
The FXmacNic::init()
function demonstrates the initialization pattern for hardware-dependent drivers:
flowchart TD subgraph subGraph0["Initialization Sequence"] MAPPED_REGS["mapped_regs: usize"] INIT_QUEUE["VecDeque::with_capacity(QS)"] GET_MAC_ADDR["FXmacGetMacAddress(&mut hwaddr, 0)"] XMAC_INIT_CALL["xmac_init(&hwaddr)"] CONSTRUCT["FXmacNic { inner, hwaddr, rx_buffer_queue }"] end GET_MAC_ADDR --> XMAC_INIT_CALL INIT_QUEUE --> GET_MAC_ADDR MAPPED_REGS --> INIT_QUEUE XMAC_INIT_CALL --> CONSTRUCT
The driver uses a fixed queue size of 64 (QS = 64
) for both receive and transmit operations, defined as a constant.
Sources: axdriver_net/src/fxmac.rs(L16) axdriver_net/src/fxmac.rs(L30 - L45)
Buffer Management Strategy
The FXmac implementation uses a simple queue-based approach for managing received packets:
- Receive Path: Uses
VecDeque<NetBufPtr>
to queue incoming packets fromFXmacRecvHandler()
- Transmit Path: Allocates
Box<Vec<u8>>
for each transmission - Buffer Recycling: Drops allocated boxes directly using
Box::from_raw()
The receive()
method demonstrates this pattern by first checking the local queue, then polling the hardware.
Sources: axdriver_net/src/fxmac.rs(L92 - L118) axdriver_net/src/fxmac.rs(L134 - L144)
Intel ixgbe Network Controller Implementation
Architecture and Memory Pool Integration
The IxgbeNic
struct implements a more sophisticated memory management approach using pre-allocated memory pools:
flowchart TD subgraph subGraph2["Generic Parameters"] HAL_PARAM["H: IxgbeHal"] QS_PARAM["QS: queue size"] QN_PARAM["QN: queue number"] end subgraph subGraph1["External Hardware Layer"] IXGBE_DRIVER["ixgbe-driver crate"] IXGBE_DEVICE["IxgbeDevice"] MEM_POOL_TYPE["MemPool"] IXGBE_NETBUF["IxgbeNetBuf"] NIC_DEVICE["NicDevice trait"] end subgraph subGraph0["IxgbeNic Driver Structure"] IXGBE_STRUCT["IxgbeNic"] INNER_DEV["inner: IxgbeDevice"] MEM_POOL["mem_pool: Arc"] RX_QUEUE["rx_buffer_queue: VecDeque"] end INNER_DEV --> IXGBE_DEVICE IXGBE_DEVICE --> IXGBE_NETBUF IXGBE_DEVICE --> NIC_DEVICE IXGBE_STRUCT --> HAL_PARAM IXGBE_STRUCT --> INNER_DEV IXGBE_STRUCT --> MEM_POOL IXGBE_STRUCT --> QN_PARAM IXGBE_STRUCT --> QS_PARAM IXGBE_STRUCT --> RX_QUEUE MEM_POOL --> MEM_POOL_TYPE
Sources: axdriver_net/src/ixgbe.rs(L18 - L28)
Memory Pool Configuration
The ixgbe driver uses predefined memory pool parameters for efficient buffer allocation:
Parameter | Value | Purpose |
---|---|---|
MEM_POOL | 4096 | Total memory pool entries |
MEM_POOL_ENTRY_SIZE | 2048 | Size per pool entry in bytes |
RX_BUFFER_SIZE | 1024 | Receive buffer queue capacity |
RECV_BATCH_SIZE | 64 | Batch size for receive operations |
These constants ensure optimal performance for high-throughput network operations.
Sources: axdriver_net/src/ixgbe.rs(L13 - L16)
NetBufPtr Conversion Pattern
The ixgbe implementation demonstrates a sophisticated buffer conversion pattern between IxgbeNetBuf
and NetBufPtr
:
flowchart TD subgraph subGraph0["Buffer Conversion Flow"] IXGBE_BUF["IxgbeNetBuf"] MANUALLY_DROP["ManuallyDrop::new(buf)"] PACKET_PTR["buf.packet_mut().as_mut_ptr()"] NET_BUF_PTR["NetBufPtr::new(raw_ptr, buf_ptr, len)"] subgraph subGraph1["Reverse Conversion"] NET_BUF_PTR_REV["NetBufPtr"] CONSTRUCT["IxgbeNetBuf::construct()"] IXGBE_BUF_REV["IxgbeNetBuf"] POOL_ENTRY["buf.pool_entry() as *mut u8"] end end CONSTRUCT --> IXGBE_BUF_REV IXGBE_BUF --> MANUALLY_DROP MANUALLY_DROP --> PACKET_PTR MANUALLY_DROP --> POOL_ENTRY NET_BUF_PTR_REV --> CONSTRUCT PACKET_PTR --> NET_BUF_PTR POOL_ENTRY --> NET_BUF_PTR
The From<IxgbeNetBuf>
implementation uses ManuallyDrop
to avoid premature deallocation while transferring ownership to the NetBufPtr
abstraction.
Sources: axdriver_net/src/ixgbe.rs(L143 - L162)
Trait Implementation Patterns
BaseDriverOps Implementation
Both drivers implement BaseDriverOps
with device-specific identification:
Driver | device_name()Return Value | Source |
---|---|---|
FXmacNic | "cdns,phytium-gem-1.0" | Hardware device tree compatible string |
IxgbeNic | self.inner.get_driver_name() | Delegated to underlying driver |
Sources: axdriver_net/src/fxmac.rs(L48 - L56) axdriver_net/src/ixgbe.rs(L50 - L58)
NetDriverOps Core Methods
The receive and transmit implementations showcase different architectural approaches:
flowchart TD subgraph subGraph1["Ixgbe Receive Pattern"] IXGBE_CAN_RECV["can_receive(): !queue.is_empty() || inner.can_receive(0)"] IXGBE_RECV_CHECK["Check local queue first"] IXGBE_BATCH_RECV["inner.receive_packets(0, RECV_BATCH_SIZE, closure)"] IXGBE_QUEUE_PUSH["Closure pushes to rx_buffer_queue"] FXMAC_CAN_RECV["can_receive(): !rx_buffer_queue.is_empty()"] FXMAC_RECV_CHECK["Check local queue first"] FXMAC_HW_POLL["FXmacRecvHandler(self.inner)"] FXMAC_QUEUE_PUSH["Push to rx_buffer_queue"] end subgraph subGraph0["FXmac Receive Pattern"] IXGBE_CAN_RECV["can_receive(): !queue.is_empty() || inner.can_receive(0)"] IXGBE_RECV_CHECK["Check local queue first"] IXGBE_BATCH_RECV["inner.receive_packets(0, RECV_BATCH_SIZE, closure)"] IXGBE_QUEUE_PUSH["Closure pushes to rx_buffer_queue"] FXMAC_CAN_RECV["can_receive(): !rx_buffer_queue.is_empty()"] FXMAC_RECV_CHECK["Check local queue first"] FXMAC_HW_POLL["FXmacRecvHandler(self.inner)"] FXMAC_QUEUE_PUSH["Push to rx_buffer_queue"] end FXMAC_CAN_RECV --> FXMAC_RECV_CHECK FXMAC_HW_POLL --> FXMAC_QUEUE_PUSH FXMAC_RECV_CHECK --> FXMAC_HW_POLL IXGBE_BATCH_RECV --> IXGBE_QUEUE_PUSH IXGBE_CAN_RECV --> IXGBE_RECV_CHECK IXGBE_RECV_CHECK --> IXGBE_BATCH_RECV
Sources: axdriver_net/src/fxmac.rs(L71 - L118) axdriver_net/src/ixgbe.rs(L73 - L124)
Hardware Abstraction Layer Integration
External Crate Dependencies
Both implementations demonstrate integration with external hardware abstraction crates:
Driver | External Crate | Key Functions Used |
---|---|---|
FXmacNic | fxmac_rs | xmac_init,FXmacGetMacAddress,FXmacRecvHandler,FXmacLwipPortTx |
IxgbeNic | ixgbe-driver | IxgbeDevice::init,MemPool::allocate,receive_packets,send |
This pattern allows the axdriver framework to leverage existing hardware-specific implementations while providing a unified interface.
Sources: axdriver_net/src/fxmac.rs(L7) axdriver_net/src/ixgbe.rs(L6 - L7)
Error Handling Translation
Both drivers translate hardware-specific errors to the common DevError
type:
flowchart TD subgraph subGraph1["Ixgbe Error Translation"] IXGBE_ERR["IxgbeError"] IXGBE_NOT_READY["IxgbeError::NotReady"] IXGBE_QUEUE_FULL["IxgbeError::QueueFull"] DEV_AGAIN["DevError::Again"] DEV_BAD_STATE["DevError::BadState"] FXMAC_RET["FXmacLwipPortTx return value"] FXMAC_CHECK["ret < 0"] FXMAC_ERROR["DevError::Again"] end subgraph subGraph0["FXmac Error Translation"] IXGBE_NOT_READY["IxgbeError::NotReady"] DEV_AGAIN["DevError::Again"] FXMAC_RET["FXmacLwipPortTx return value"] FXMAC_CHECK["ret < 0"] FXMAC_ERROR["DevError::Again"] end FXMAC_CHECK --> FXMAC_ERROR FXMAC_RET --> FXMAC_CHECK IXGBE_ERR --> DEV_BAD_STATE IXGBE_ERR --> IXGBE_NOT_READY IXGBE_ERR --> IXGBE_QUEUE_FULL IXGBE_NOT_READY --> DEV_AGAIN IXGBE_QUEUE_FULL --> DEV_AGAIN
Sources: axdriver_net/src/fxmac.rs(L127 - L131) axdriver_net/src/ixgbe.rs(L118 - L122) axdriver_net/src/ixgbe.rs(L130 - L134)