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
13pub 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 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 Ok(())
84 }
85
86 fn receive(&mut self) -> DevResult<NetBufPtr> {
87 if !self.rx_buffer_queue.is_empty() {
88 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}