Skip to main content

axdriver_net/
fxmac.rs

1use alloc::{boxed::Box, collections::VecDeque, vec};
2use core::ptr::NonNull;
3
4use axdriver_base::{BaseDriverOps, DevError, DevResult, DeviceType};
5pub use fxmac_rs::KernelFunc;
6use fxmac_rs::{self, FXmac, FXmacGetMacAddress, FXmacLwipPortTx, FXmacRecvHandler, xmac_init};
7use log::*;
8
9use crate::{EthernetAddress, NetBufPtr, NetDriverOps};
10
11const QS: usize = 64;
12
13/// fxmac driver device
14pub struct FXmacNic {
15    inner: &'static mut FXmac,
16    hwaddr: [u8; 6],
17    rx_buffer_queue: VecDeque<NetBufPtr>,
18}
19
20unsafe impl Sync for FXmacNic {}
21unsafe impl Send for FXmacNic {}
22
23impl FXmacNic {
24    /// initialize fxmac driver
25    pub fn init(mapped_regs: usize) -> DevResult<Self> {
26        info!("FXmacNic init @ {mapped_regs:#x}");
27        let rx_buffer_queue = VecDeque::with_capacity(QS);
28
29        let mut hwaddr: [u8; 6] = [0; 6];
30        FXmacGetMacAddress(&mut hwaddr, 0);
31        info!("Got FXmac HW address: {hwaddr:x?}");
32
33        let inner = xmac_init(&hwaddr);
34        let dev = Self {
35            inner,
36            hwaddr,
37            rx_buffer_queue,
38        };
39        Ok(dev)
40    }
41}
42
43impl BaseDriverOps for FXmacNic {
44    fn device_name(&self) -> &str {
45        "cdns,phytium-gem-1.0"
46    }
47
48    fn device_type(&self) -> DeviceType {
49        DeviceType::Net
50    }
51}
52
53impl NetDriverOps for FXmacNic {
54    fn mac_address(&self) -> EthernetAddress {
55        EthernetAddress(self.hwaddr)
56    }
57
58    fn rx_queue_size(&self) -> usize {
59        QS
60    }
61
62    fn tx_queue_size(&self) -> usize {
63        QS
64    }
65
66    fn can_receive(&self) -> bool {
67        !self.rx_buffer_queue.is_empty()
68    }
69
70    fn can_transmit(&self) -> bool {
71        true
72    }
73
74    fn recycle_rx_buffer(&mut self, rx_buf: NetBufPtr) -> DevResult {
75        unsafe {
76            drop(Box::from_raw(rx_buf.raw_ptr::<u8>()));
77        }
78        Ok(())
79    }
80
81    fn recycle_tx_buffers(&mut self) -> DevResult {
82        // drop tx_buf
83        Ok(())
84    }
85
86    fn receive(&mut self) -> DevResult<NetBufPtr> {
87        if !self.rx_buffer_queue.is_empty() {
88            // RX buffer have received packets.
89            Ok(self.rx_buffer_queue.pop_front().unwrap())
90        } else {
91            match FXmacRecvHandler(self.inner) {
92                None => Err(DevError::Again),
93                Some(packets) => {
94                    for packet in packets {
95                        debug!("received packet length {}", packet.len());
96                        let mut buf = Box::new(packet);
97                        let buf_ptr = buf.as_mut_ptr();
98                        let buf_len = buf.len();
99                        let rx_buf = NetBufPtr::new(
100                            NonNull::new(Box::into_raw(buf) as *mut u8).unwrap(),
101                            NonNull::new(buf_ptr).unwrap(),
102                            buf_len,
103                        );
104
105                        self.rx_buffer_queue.push_back(rx_buf);
106                    }
107
108                    Ok(self.rx_buffer_queue.pop_front().unwrap())
109                }
110            }
111        }
112    }
113
114    fn transmit(&mut self, tx_buf: NetBufPtr) -> DevResult {
115        let tx_vec = vec![tx_buf.packet().to_vec()];
116        let ret = FXmacLwipPortTx(self.inner, tx_vec);
117        unsafe {
118            drop(Box::from_raw(tx_buf.raw_ptr::<u8>()));
119        }
120        if ret < 0 {
121            Err(DevError::Again)
122        } else {
123            Ok(())
124        }
125    }
126
127    fn alloc_tx_buffer(&mut self, size: usize) -> DevResult<NetBufPtr> {
128        let mut tx_buf = Box::new(alloc::vec![0; size]);
129        let tx_buf_ptr = tx_buf.as_mut_ptr();
130
131        Ok(NetBufPtr::new(
132            NonNull::new(Box::into_raw(tx_buf) as *mut u8).unwrap(),
133            NonNull::new(tx_buf_ptr).unwrap(),
134            size,
135        ))
136    }
137}