xref: /DragonOS/kernel/src/driver/net/e1000e/e1000e.rs (revision 77799ccaaca276fe127448d169f0e035837cce44)
1*77799ccaSWu Mianzhi // 参考手册: PCIe* GbE Controllers Open Source Software Developer’s Manual
2*77799ccaSWu Mianzhi // Refernce: PCIe* GbE Controllers Open Source Software Developer’s Manual
3*77799ccaSWu Mianzhi 
4*77799ccaSWu Mianzhi use alloc::vec::Vec;
5*77799ccaSWu Mianzhi use core::intrinsics::unlikely;
6*77799ccaSWu Mianzhi use core::mem::size_of;
7*77799ccaSWu Mianzhi use core::ptr::NonNull;
8*77799ccaSWu Mianzhi use core::slice::{from_raw_parts, from_raw_parts_mut};
9*77799ccaSWu Mianzhi use core::sync::atomic::{compiler_fence, Ordering};
10*77799ccaSWu Mianzhi 
11*77799ccaSWu Mianzhi use super::e1000e_driver::e1000e_driver_init;
12*77799ccaSWu Mianzhi use crate::driver::net::dma::{dma_alloc, dma_dealloc};
13*77799ccaSWu Mianzhi use crate::driver::pci::pci::{
14*77799ccaSWu Mianzhi     get_pci_device_structure_mut, PciDeviceStructure, PciDeviceStructureGeneralDevice, PciError,
15*77799ccaSWu Mianzhi     PCI_DEVICE_LINKEDLIST,
16*77799ccaSWu Mianzhi };
17*77799ccaSWu Mianzhi use crate::driver::pci::pci_irq::{IrqCommonMsg, IrqMsg, IrqSpecificMsg, PciInterrupt, IRQ};
18*77799ccaSWu Mianzhi use crate::include::bindings::bindings::pt_regs;
19*77799ccaSWu Mianzhi use crate::libs::volatile::{ReadOnly, Volatile, VolatileReadable, VolatileWritable, WriteOnly};
20*77799ccaSWu Mianzhi use crate::net::net_core::poll_ifaces_try_lock_onetime;
21*77799ccaSWu Mianzhi use crate::{kdebug, kinfo};
22*77799ccaSWu Mianzhi 
23*77799ccaSWu Mianzhi const PAGE_SIZE: usize = 4096;
24*77799ccaSWu Mianzhi const NETWORK_CLASS: u8 = 0x2;
25*77799ccaSWu Mianzhi const ETHERNET_SUBCLASS: u8 = 0x0;
26*77799ccaSWu Mianzhi // e1000e系列网卡的device id列表,来源:https://admin.pci-ids.ucw.cz/read/PC/8086
27*77799ccaSWu Mianzhi const E1000E_DEVICE_ID: [u16; 14] = [
28*77799ccaSWu Mianzhi     0x10d3, // 8574L, qemu default
29*77799ccaSWu Mianzhi     0x10cc, // 82567LM-2
30*77799ccaSWu Mianzhi     0x10cd, // 82567LF-2
31*77799ccaSWu Mianzhi     0x105f, // 82571EB
32*77799ccaSWu Mianzhi     0x1060, // 82571EB
33*77799ccaSWu Mianzhi     0x107f, // 82572EI
34*77799ccaSWu Mianzhi     0x109a, // 82573L
35*77799ccaSWu Mianzhi     0x10ea, // 82577LM
36*77799ccaSWu Mianzhi     0x10eb, // 82577LC
37*77799ccaSWu Mianzhi     0x10ef, // 82578DM
38*77799ccaSWu Mianzhi     0x10f0, // 82578DC
39*77799ccaSWu Mianzhi     0x1502, // 82579LM
40*77799ccaSWu Mianzhi     0x1503, // 82579V
41*77799ccaSWu Mianzhi     0x150c, // 82583V
42*77799ccaSWu Mianzhi ];
43*77799ccaSWu Mianzhi 
44*77799ccaSWu Mianzhi // e1000e网卡与BAR有关的常量
45*77799ccaSWu Mianzhi // BAR0空间大小(128KB)
46*77799ccaSWu Mianzhi const E1000E_BAR_REG_SIZE: u32 = 128 * 1024;
47*77799ccaSWu Mianzhi // BAR0空间对齐(64bit)
48*77799ccaSWu Mianzhi const E1000E_BAR_REG_ALIGN: u8 = 64;
49*77799ccaSWu Mianzhi // 单个寄存器大小(32bit, 4字节)
50*77799ccaSWu Mianzhi const E1000E_REG_SIZE: u8 = 4;
51*77799ccaSWu Mianzhi 
52*77799ccaSWu Mianzhi // TxBuffer和RxBuffer的大小(DMA页)
53*77799ccaSWu Mianzhi const E1000E_DMA_PAGES: usize = 1;
54*77799ccaSWu Mianzhi 
55*77799ccaSWu Mianzhi // 中断相关
56*77799ccaSWu Mianzhi const E1000E_RECV_VECTOR: u16 = 57;
57*77799ccaSWu Mianzhi 
58*77799ccaSWu Mianzhi // napi队列中暂时存储的buffer个数
59*77799ccaSWu Mianzhi const E1000E_RECV_NAPI: usize = 1024;
60*77799ccaSWu Mianzhi 
61*77799ccaSWu Mianzhi // 收/发包的描述符结构 pp.24 Table 3-1
62*77799ccaSWu Mianzhi #[repr(C)]
63*77799ccaSWu Mianzhi #[derive(Copy, Clone, Debug)]
64*77799ccaSWu Mianzhi struct E1000ETransDesc {
65*77799ccaSWu Mianzhi     addr: u64,
66*77799ccaSWu Mianzhi     len: u16,
67*77799ccaSWu Mianzhi     cso: u8,
68*77799ccaSWu Mianzhi     cmd: u8,
69*77799ccaSWu Mianzhi     status: u8,
70*77799ccaSWu Mianzhi     css: u8,
71*77799ccaSWu Mianzhi     special: u8,
72*77799ccaSWu Mianzhi }
73*77799ccaSWu Mianzhi // pp.54 Table 3-12
74*77799ccaSWu Mianzhi #[repr(C)]
75*77799ccaSWu Mianzhi #[derive(Copy, Clone, Debug)]
76*77799ccaSWu Mianzhi struct E1000ERecvDesc {
77*77799ccaSWu Mianzhi     addr: u64,
78*77799ccaSWu Mianzhi     len: u16,
79*77799ccaSWu Mianzhi     chksum: u16,
80*77799ccaSWu Mianzhi     status: u16,
81*77799ccaSWu Mianzhi     error: u8,
82*77799ccaSWu Mianzhi     special: u8,
83*77799ccaSWu Mianzhi }
84*77799ccaSWu Mianzhi #[derive(Copy, Clone)]
85*77799ccaSWu Mianzhi // Buffer的Copy只是指针操作,不涉及实际数据的复制,因此要小心使用,确保不同的buffer不会使用同一块内存
86*77799ccaSWu Mianzhi pub struct E1000EBuffer {
87*77799ccaSWu Mianzhi     buffer: NonNull<u8>,
88*77799ccaSWu Mianzhi     paddr: usize,
89*77799ccaSWu Mianzhi     // length字段为0则表示这个buffer是一个占位符,不指向实际内存
90*77799ccaSWu Mianzhi     // the buffer is empty and no page is allocated if length field is set 0
91*77799ccaSWu Mianzhi     length: usize,
92*77799ccaSWu Mianzhi }
93*77799ccaSWu Mianzhi 
94*77799ccaSWu Mianzhi impl E1000EBuffer {
95*77799ccaSWu Mianzhi     pub fn new(length: usize) -> Self {
96*77799ccaSWu Mianzhi         assert!(length <= PAGE_SIZE);
97*77799ccaSWu Mianzhi         if unlikely(length == 0) {
98*77799ccaSWu Mianzhi             // 在某些情况下,我们并不需要实际分配buffer,只需要提供一个占位符即可
99*77799ccaSWu Mianzhi             // we dont need to allocate dma pages for buffer in some cases
100*77799ccaSWu Mianzhi             E1000EBuffer {
101*77799ccaSWu Mianzhi                 buffer: NonNull::dangling(),
102*77799ccaSWu Mianzhi                 paddr: 0,
103*77799ccaSWu Mianzhi                 length: 0,
104*77799ccaSWu Mianzhi             }
105*77799ccaSWu Mianzhi         } else {
106*77799ccaSWu Mianzhi             let (paddr, vaddr) = dma_alloc(E1000E_DMA_PAGES);
107*77799ccaSWu Mianzhi             E1000EBuffer {
108*77799ccaSWu Mianzhi                 buffer: vaddr,
109*77799ccaSWu Mianzhi                 paddr,
110*77799ccaSWu Mianzhi                 length,
111*77799ccaSWu Mianzhi             }
112*77799ccaSWu Mianzhi         }
113*77799ccaSWu Mianzhi     }
114*77799ccaSWu Mianzhi 
115*77799ccaSWu Mianzhi     pub fn as_addr(&self) -> NonNull<u8> {
116*77799ccaSWu Mianzhi         assert!(self.length != 0);
117*77799ccaSWu Mianzhi         return self.buffer;
118*77799ccaSWu Mianzhi     }
119*77799ccaSWu Mianzhi 
120*77799ccaSWu Mianzhi     pub fn as_addr_u64(&self) -> u64 {
121*77799ccaSWu Mianzhi         assert!(self.length != 0);
122*77799ccaSWu Mianzhi         return self.buffer.as_ptr() as u64;
123*77799ccaSWu Mianzhi     }
124*77799ccaSWu Mianzhi 
125*77799ccaSWu Mianzhi     pub fn as_paddr(&self) -> usize {
126*77799ccaSWu Mianzhi         assert!(self.length != 0);
127*77799ccaSWu Mianzhi         return self.paddr;
128*77799ccaSWu Mianzhi     }
129*77799ccaSWu Mianzhi 
130*77799ccaSWu Mianzhi     pub fn as_slice(&self) -> &[u8] {
131*77799ccaSWu Mianzhi         assert!(self.length != 0);
132*77799ccaSWu Mianzhi         return unsafe { from_raw_parts(self.buffer.as_ptr(), self.length) };
133*77799ccaSWu Mianzhi     }
134*77799ccaSWu Mianzhi 
135*77799ccaSWu Mianzhi     pub fn as_mut_slice(&mut self) -> &mut [u8] {
136*77799ccaSWu Mianzhi         assert!(self.length != 0);
137*77799ccaSWu Mianzhi         return unsafe { from_raw_parts_mut(self.buffer.as_ptr(), self.length) };
138*77799ccaSWu Mianzhi     }
139*77799ccaSWu Mianzhi 
140*77799ccaSWu Mianzhi     pub fn set_length(&mut self, length: usize) {
141*77799ccaSWu Mianzhi         self.length = length;
142*77799ccaSWu Mianzhi     }
143*77799ccaSWu Mianzhi 
144*77799ccaSWu Mianzhi     pub fn len(&self) -> usize {
145*77799ccaSWu Mianzhi         return self.length;
146*77799ccaSWu Mianzhi     }
147*77799ccaSWu Mianzhi     // 释放buffer内部的dma_pages,需要小心使用
148*77799ccaSWu Mianzhi     pub fn free_buffer(self) -> () {
149*77799ccaSWu Mianzhi         if self.length != 0 {
150*77799ccaSWu Mianzhi             unsafe { dma_dealloc(self.paddr, self.buffer, E1000E_DMA_PAGES) };
151*77799ccaSWu Mianzhi         }
152*77799ccaSWu Mianzhi     }
153*77799ccaSWu Mianzhi }
154*77799ccaSWu Mianzhi 
155*77799ccaSWu Mianzhi // 中断处理函数, 调用协议栈的poll函数,未来可能会用napi来替换这里
156*77799ccaSWu Mianzhi // Interrupt handler
157*77799ccaSWu Mianzhi unsafe extern "C" fn e1000e_irq_handler(irq_num: u64, irq_paramer: u64, regs: *mut pt_regs) {
158*77799ccaSWu Mianzhi     poll_ifaces_try_lock_onetime().ok();
159*77799ccaSWu Mianzhi }
160*77799ccaSWu Mianzhi 
161*77799ccaSWu Mianzhi pub struct E1000EDevice {
162*77799ccaSWu Mianzhi     // 设备寄存器
163*77799ccaSWu Mianzhi     // device registers
164*77799ccaSWu Mianzhi     general_regs: NonNull<GeneralRegs>,
165*77799ccaSWu Mianzhi     interrupt_regs: NonNull<InterruptRegs>,
166*77799ccaSWu Mianzhi     rctl_regs: NonNull<ReceiveCtrlRegs>,
167*77799ccaSWu Mianzhi     receive_regs: NonNull<ReceiveRegs>,
168*77799ccaSWu Mianzhi     tctl_regs: NonNull<TransmitCtrlRegs>,
169*77799ccaSWu Mianzhi     transimit_regs: NonNull<TransimitRegs>,
170*77799ccaSWu Mianzhi     pcie_regs: NonNull<PCIeRegs>,
171*77799ccaSWu Mianzhi 
172*77799ccaSWu Mianzhi     // descriptor环形队列,在操作系统与设备之间共享
173*77799ccaSWu Mianzhi     // descriptor rings are shared between os and device
174*77799ccaSWu Mianzhi     recv_desc_ring: &'static mut [E1000ERecvDesc],
175*77799ccaSWu Mianzhi     trans_desc_ring: &'static mut [E1000ETransDesc],
176*77799ccaSWu Mianzhi     recv_ring_pa: usize,
177*77799ccaSWu Mianzhi     trans_ring_pa: usize,
178*77799ccaSWu Mianzhi 
179*77799ccaSWu Mianzhi     // 设备收/发包缓冲区数组
180*77799ccaSWu Mianzhi     // buffers of receive/transmit packets
181*77799ccaSWu Mianzhi     recv_buffers: Vec<E1000EBuffer>,
182*77799ccaSWu Mianzhi     trans_buffers: Vec<E1000EBuffer>,
183*77799ccaSWu Mianzhi     mac: [u8; 6],
184*77799ccaSWu Mianzhi     first_trans: bool,
185*77799ccaSWu Mianzhi     // napi队列,用于存放在中断关闭期间通过轮询收取的buffer
186*77799ccaSWu Mianzhi     // the napi queue is designed to save buffer/packet when the interrupt is close
187*77799ccaSWu Mianzhi     // NOTE: this feature is not completely implemented and not used in the current version
188*77799ccaSWu Mianzhi     napi_buffers: Vec<E1000EBuffer>,
189*77799ccaSWu Mianzhi     napi_buffer_head: usize,
190*77799ccaSWu Mianzhi     napi_buffer_tail: usize,
191*77799ccaSWu Mianzhi     napi_buffer_empty: bool,
192*77799ccaSWu Mianzhi }
193*77799ccaSWu Mianzhi 
194*77799ccaSWu Mianzhi impl E1000EDevice {
195*77799ccaSWu Mianzhi     // 从PCI标准设备进行驱动初始化
196*77799ccaSWu Mianzhi     // init the device for PCI standard device struct
197*77799ccaSWu Mianzhi     pub fn new(device: &mut PciDeviceStructureGeneralDevice) -> Result<Self, E1000EPciError> {
198*77799ccaSWu Mianzhi         // 从BAR0获取我们需要的寄存器
199*77799ccaSWu Mianzhi         // Build registers sturcts from BAR0
200*77799ccaSWu Mianzhi         device.bar_ioremap().unwrap()?;
201*77799ccaSWu Mianzhi         device.enable_master();
202*77799ccaSWu Mianzhi         let bar = device.bar().ok_or(E1000EPciError::BarGetFailed)?;
203*77799ccaSWu Mianzhi         let bar0 = bar.get_bar(0)?;
204*77799ccaSWu Mianzhi         let (address, size) = bar0
205*77799ccaSWu Mianzhi             .memory_address_size()
206*77799ccaSWu Mianzhi             .ok_or(E1000EPciError::UnexpectedBarType)?;
207*77799ccaSWu Mianzhi         if address == 0 {
208*77799ccaSWu Mianzhi             return Err(E1000EPciError::BarNotAllocated);
209*77799ccaSWu Mianzhi         }
210*77799ccaSWu Mianzhi         if size != E1000E_BAR_REG_SIZE {
211*77799ccaSWu Mianzhi             return Err(E1000EPciError::UnexpectedBarSize);
212*77799ccaSWu Mianzhi         }
213*77799ccaSWu Mianzhi         let vaddress = bar0
214*77799ccaSWu Mianzhi             .virtual_address()
215*77799ccaSWu Mianzhi             .ok_or(E1000EPciError::BarGetVaddrFailed)?
216*77799ccaSWu Mianzhi             .data() as u64;
217*77799ccaSWu Mianzhi 
218*77799ccaSWu Mianzhi         // 初始化msi中断
219*77799ccaSWu Mianzhi         // initialize msi interupt
220*77799ccaSWu Mianzhi         let irq_vector = device.irq_vector_mut().unwrap();
221*77799ccaSWu Mianzhi         irq_vector.push(E1000E_RECV_VECTOR);
222*77799ccaSWu Mianzhi         device.irq_init(IRQ::PCI_IRQ_MSI).expect("IRQ Init Failed");
223*77799ccaSWu Mianzhi         let msg = IrqMsg {
224*77799ccaSWu Mianzhi             irq_common_message: IrqCommonMsg::init_from(
225*77799ccaSWu Mianzhi                 0,
226*77799ccaSWu Mianzhi                 "E1000E_RECV_IRQ",
227*77799ccaSWu Mianzhi                 0,
228*77799ccaSWu Mianzhi                 e1000e_irq_handler,
229*77799ccaSWu Mianzhi                 None,
230*77799ccaSWu Mianzhi             ),
231*77799ccaSWu Mianzhi             irq_specific_message: IrqSpecificMsg::msi_default(),
232*77799ccaSWu Mianzhi         };
233*77799ccaSWu Mianzhi         device.irq_install(msg)?;
234*77799ccaSWu Mianzhi         device.irq_enable(true)?;
235*77799ccaSWu Mianzhi 
236*77799ccaSWu Mianzhi         let general_regs: NonNull<GeneralRegs> =
237*77799ccaSWu Mianzhi             get_register_ptr(vaddress, E1000E_GENERAL_REGS_OFFSET);
238*77799ccaSWu Mianzhi         let interrupt_regs: NonNull<InterruptRegs> =
239*77799ccaSWu Mianzhi             get_register_ptr(vaddress, E1000E_INTERRRUPT_REGS_OFFSET);
240*77799ccaSWu Mianzhi         let rctl_regs: NonNull<ReceiveCtrlRegs> =
241*77799ccaSWu Mianzhi             get_register_ptr(vaddress, E1000E_RECEIVE_CTRL_REG_OFFSET);
242*77799ccaSWu Mianzhi         let receive_regs: NonNull<ReceiveRegs> =
243*77799ccaSWu Mianzhi             get_register_ptr(vaddress, E1000E_RECEIVE_REGS_OFFSET);
244*77799ccaSWu Mianzhi         let tctl_regs: NonNull<TransmitCtrlRegs> =
245*77799ccaSWu Mianzhi             get_register_ptr(vaddress, E1000E_TRANSMIT_CTRL_REG_OFFSET);
246*77799ccaSWu Mianzhi         let transimit_regs: NonNull<TransimitRegs> =
247*77799ccaSWu Mianzhi             get_register_ptr(vaddress, E1000E_TRANSMIT_REGS_OFFSET);
248*77799ccaSWu Mianzhi         let pcie_regs: NonNull<PCIeRegs> = get_register_ptr(vaddress, E1000E_PCIE_REGS_OFFSET);
249*77799ccaSWu Mianzhi         let ra_regs: NonNull<ReceiveAddressRegs> =
250*77799ccaSWu Mianzhi             get_register_ptr(vaddress, E1000E_RECEIVE_ADDRESS_REGS_OFFSET);
251*77799ccaSWu Mianzhi         // 开始设备初始化 14.3
252*77799ccaSWu Mianzhi         // Initialization Sequence
253*77799ccaSWu Mianzhi         unsafe {
254*77799ccaSWu Mianzhi             let mut ctrl = volread!(general_regs, ctrl);
255*77799ccaSWu Mianzhi             // 关闭中断
256*77799ccaSWu Mianzhi             // close the interrupt
257*77799ccaSWu Mianzhi             volwrite!(interrupt_regs, imc, E1000E_IMC_CLEAR);
258*77799ccaSWu Mianzhi             //SW RESET
259*77799ccaSWu Mianzhi             volwrite!(general_regs, ctrl, ctrl | E1000E_CTRL_RST);
260*77799ccaSWu Mianzhi             compiler_fence(Ordering::AcqRel);
261*77799ccaSWu Mianzhi             // PHY RESET
262*77799ccaSWu Mianzhi             ctrl = volread!(general_regs, ctrl);
263*77799ccaSWu Mianzhi             volwrite!(general_regs, ctrl, ctrl | E1000E_CTRL_PHY_RST);
264*77799ccaSWu Mianzhi             volwrite!(general_regs, ctrl, ctrl);
265*77799ccaSWu Mianzhi             // 关闭中断
266*77799ccaSWu Mianzhi             // close the interrupt
267*77799ccaSWu Mianzhi             volwrite!(interrupt_regs, imc, E1000E_IMC_CLEAR);
268*77799ccaSWu Mianzhi             let mut gcr = volread!(pcie_regs, gcr);
269*77799ccaSWu Mianzhi             gcr = gcr | (1 << 22);
270*77799ccaSWu Mianzhi             volwrite!(pcie_regs, gcr, gcr);
271*77799ccaSWu Mianzhi             compiler_fence(Ordering::AcqRel);
272*77799ccaSWu Mianzhi             // PHY Initialization 14.8.1
273*77799ccaSWu Mianzhi             // MAC/PHY Link Setup 14.8.2
274*77799ccaSWu Mianzhi             ctrl = volread!(general_regs, ctrl);
275*77799ccaSWu Mianzhi             ctrl &= !(E1000E_CTRL_FRCSPD | E1000E_CTRL_FRCDPLX);
276*77799ccaSWu Mianzhi             volwrite!(general_regs, ctrl, ctrl | E1000E_CTRL_SLU);
277*77799ccaSWu Mianzhi         }
278*77799ccaSWu Mianzhi         let status = unsafe { volread!(general_regs, status) };
279*77799ccaSWu Mianzhi         kdebug!("Status: {status:#X}");
280*77799ccaSWu Mianzhi 
281*77799ccaSWu Mianzhi         // 读取设备的mac地址
282*77799ccaSWu Mianzhi         // Read mac address
283*77799ccaSWu Mianzhi         let ral = unsafe { volread!(ra_regs, ral0) };
284*77799ccaSWu Mianzhi         let rah = unsafe { volread!(ra_regs, rah0) };
285*77799ccaSWu Mianzhi         let mac: [u8; 6] = [
286*77799ccaSWu Mianzhi             ((ral >> 0) & 0xFF) as u8,
287*77799ccaSWu Mianzhi             ((ral >> 8) & 0xFF) as u8,
288*77799ccaSWu Mianzhi             ((ral >> 16) & 0xFF) as u8,
289*77799ccaSWu Mianzhi             ((ral >> 24) & 0xFF) as u8,
290*77799ccaSWu Mianzhi             ((rah >> 0) & 0xFF) as u8,
291*77799ccaSWu Mianzhi             ((rah >> 8) & 0xFF) as u8,
292*77799ccaSWu Mianzhi         ];
293*77799ccaSWu Mianzhi         // 初始化receive和transimit descriptor环形队列
294*77799ccaSWu Mianzhi         // initialize receive and transimit desciptor ring
295*77799ccaSWu Mianzhi         let (recv_ring_pa, recv_ring_va) = dma_alloc(E1000E_DMA_PAGES);
296*77799ccaSWu Mianzhi         let (trans_ring_pa, trans_ring_va) = dma_alloc(E1000E_DMA_PAGES);
297*77799ccaSWu Mianzhi         let recv_ring_length = PAGE_SIZE / size_of::<E1000ERecvDesc>();
298*77799ccaSWu Mianzhi         let trans_ring_length = PAGE_SIZE / size_of::<E1000ETransDesc>();
299*77799ccaSWu Mianzhi 
300*77799ccaSWu Mianzhi         let recv_desc_ring = unsafe {
301*77799ccaSWu Mianzhi             from_raw_parts_mut::<E1000ERecvDesc>(recv_ring_va.as_ptr().cast(), recv_ring_length)
302*77799ccaSWu Mianzhi         };
303*77799ccaSWu Mianzhi         let trans_desc_ring = unsafe {
304*77799ccaSWu Mianzhi             from_raw_parts_mut::<E1000ETransDesc>(trans_ring_va.as_ptr().cast(), trans_ring_length)
305*77799ccaSWu Mianzhi         };
306*77799ccaSWu Mianzhi 
307*77799ccaSWu Mianzhi         // 初始化receive和transmit packet的缓冲区
308*77799ccaSWu Mianzhi         // initialzie receive and transmit buffers
309*77799ccaSWu Mianzhi         let mut recv_buffers: Vec<E1000EBuffer> = Vec::with_capacity(recv_ring_length);
310*77799ccaSWu Mianzhi         let mut trans_buffers: Vec<E1000EBuffer> = Vec::with_capacity(trans_ring_length);
311*77799ccaSWu Mianzhi 
312*77799ccaSWu Mianzhi         // 初始化缓冲区与descriptor,descriptor 中的addr字典应当指向buffer的物理地址
313*77799ccaSWu Mianzhi         // Receive buffers of appropriate size should be allocated and pointers to these buffers should be stored in the descriptor ring.
314*77799ccaSWu Mianzhi         for i in 0..recv_ring_length {
315*77799ccaSWu Mianzhi             let buffer = E1000EBuffer::new(PAGE_SIZE);
316*77799ccaSWu Mianzhi             recv_desc_ring[i].addr = buffer.as_paddr() as u64;
317*77799ccaSWu Mianzhi             recv_desc_ring[i].status = 0;
318*77799ccaSWu Mianzhi             recv_buffers.push(buffer);
319*77799ccaSWu Mianzhi         }
320*77799ccaSWu Mianzhi         // Same as receive buffers
321*77799ccaSWu Mianzhi         for i in 0..trans_ring_length {
322*77799ccaSWu Mianzhi             let buffer = E1000EBuffer::new(PAGE_SIZE);
323*77799ccaSWu Mianzhi             trans_desc_ring[i].addr = buffer.as_paddr() as u64;
324*77799ccaSWu Mianzhi             trans_desc_ring[i].status = 1;
325*77799ccaSWu Mianzhi             trans_buffers.push(buffer);
326*77799ccaSWu Mianzhi         }
327*77799ccaSWu Mianzhi 
328*77799ccaSWu Mianzhi         // Receive Initialization 14.6
329*77799ccaSWu Mianzhi         // Initialzie mutlicast table array to 0b
330*77799ccaSWu Mianzhi         // 初始化MTA,遍历0x05200-0x053FC中每个寄存器,写入0b,一共128个寄存器
331*77799ccaSWu Mianzhi         let mut mta_adress = vaddress + E1000E_MTA_REGS_START_OFFSET;
332*77799ccaSWu Mianzhi         while mta_adress != vaddress + E1000E_MTA_REGS_END_OFFSET {
333*77799ccaSWu Mianzhi             let mta: NonNull<MTARegs> = get_register_ptr(mta_adress, 0);
334*77799ccaSWu Mianzhi             unsafe { volwrite!(mta, mta, 0) };
335*77799ccaSWu Mianzhi             mta_adress = mta_adress + 4;
336*77799ccaSWu Mianzhi         }
337*77799ccaSWu Mianzhi         // 连续的寄存器读-写操作,放在同一个unsafe块中
338*77799ccaSWu Mianzhi         unsafe {
339*77799ccaSWu Mianzhi             // 设置descriptor环形队列的基地址
340*77799ccaSWu Mianzhi             // Program the descriptor base address with the address of the region.
341*77799ccaSWu Mianzhi             volwrite!(receive_regs, rdbal0, (recv_ring_pa) as u32);
342*77799ccaSWu Mianzhi             volwrite!(receive_regs, rdbah0, (recv_ring_pa >> 32) as u32);
343*77799ccaSWu Mianzhi             // 设置descriptor环形队列的长度
344*77799ccaSWu Mianzhi             // Set the length register to the size of the descriptor ring.
345*77799ccaSWu Mianzhi             volwrite!(receive_regs, rdlen0, PAGE_SIZE as u32);
346*77799ccaSWu Mianzhi             // 设置队列的首尾指针
347*77799ccaSWu Mianzhi             // Program the head and tail registers
348*77799ccaSWu Mianzhi             volwrite!(receive_regs, rdh0, 0);
349*77799ccaSWu Mianzhi             volwrite!(receive_regs, rdt0, (recv_ring_length - 1) as u32);
350*77799ccaSWu Mianzhi             // 设置控制寄存器的相关功能 14.6.1
351*77799ccaSWu Mianzhi             // Set the receive control register
352*77799ccaSWu Mianzhi             volwrite!(
353*77799ccaSWu Mianzhi                 rctl_regs,
354*77799ccaSWu Mianzhi                 rctl,
355*77799ccaSWu Mianzhi                 E1000E_RCTL_EN
356*77799ccaSWu Mianzhi                     | E1000E_RCTL_BAM
357*77799ccaSWu Mianzhi                     | E1000E_RCTL_BSIZE_4K
358*77799ccaSWu Mianzhi                     | E1000E_RCTL_BSEX
359*77799ccaSWu Mianzhi                     | E1000E_RCTL_SECRC
360*77799ccaSWu Mianzhi             );
361*77799ccaSWu Mianzhi 
362*77799ccaSWu Mianzhi             // Transmit Initialization 14.7
363*77799ccaSWu Mianzhi             // 开启发包descriptor的回写功能
364*77799ccaSWu Mianzhi             // Program the TXDCTL register with the desired TX descriptor write-back policy
365*77799ccaSWu Mianzhi             volwrite!(
366*77799ccaSWu Mianzhi                 transimit_regs,
367*77799ccaSWu Mianzhi                 txdctl,
368*77799ccaSWu Mianzhi                 E1000E_TXDCTL_WTHRESH | E1000E_TXDCTL_GRAN
369*77799ccaSWu Mianzhi             );
370*77799ccaSWu Mianzhi             // 设置descriptor环形队列的基地址,长度与首尾指针
371*77799ccaSWu Mianzhi             // Program the descriptor base address with the address of the region
372*77799ccaSWu Mianzhi             volwrite!(transimit_regs, tdbal0, trans_ring_pa as u32);
373*77799ccaSWu Mianzhi             volwrite!(transimit_regs, tdbah0, (trans_ring_pa >> 32) as u32);
374*77799ccaSWu Mianzhi             // Set the length register to the size of the descriptor ring.
375*77799ccaSWu Mianzhi             volwrite!(transimit_regs, tdlen0, PAGE_SIZE as u32);
376*77799ccaSWu Mianzhi             // Program the head and tail registerss
377*77799ccaSWu Mianzhi             volwrite!(transimit_regs, tdh0, 0);
378*77799ccaSWu Mianzhi             volwrite!(transimit_regs, tdt0, 0);
379*77799ccaSWu Mianzhi             // Program the TIPG register
380*77799ccaSWu Mianzhi             volwrite!(
381*77799ccaSWu Mianzhi                 tctl_regs,
382*77799ccaSWu Mianzhi                 tipg,
383*77799ccaSWu Mianzhi                 E1000E_TIPG_IPGT | E1000E_TIPG_IPGR1 | E1000E_TIPG_IPGR2
384*77799ccaSWu Mianzhi             );
385*77799ccaSWu Mianzhi             // Program the TCTL register.
386*77799ccaSWu Mianzhi             volwrite!(
387*77799ccaSWu Mianzhi                 tctl_regs,
388*77799ccaSWu Mianzhi                 tctl,
389*77799ccaSWu Mianzhi                 E1000E_TCTL_EN | E1000E_TCTL_PSP | E1000E_TCTL_CT_VAL | E1000E_TCTL_COLD_VAL
390*77799ccaSWu Mianzhi             );
391*77799ccaSWu Mianzhi 
392*77799ccaSWu Mianzhi             let icr = volread!(interrupt_regs, icr);
393*77799ccaSWu Mianzhi             volwrite!(interrupt_regs, icr, icr);
394*77799ccaSWu Mianzhi             // 开启收包相关的中断
395*77799ccaSWu Mianzhi             // Enable receive interrupts
396*77799ccaSWu Mianzhi             let mut ims = volread!(interrupt_regs, ims);
397*77799ccaSWu Mianzhi             ims = E1000E_IMS_LSC | E1000E_IMS_RXT0 | E1000E_IMS_RXDMT0 | E1000E_IMS_OTHER;
398*77799ccaSWu Mianzhi             volwrite!(interrupt_regs, ims, ims);
399*77799ccaSWu Mianzhi         }
400*77799ccaSWu Mianzhi         return Ok(E1000EDevice {
401*77799ccaSWu Mianzhi             general_regs,
402*77799ccaSWu Mianzhi             interrupt_regs,
403*77799ccaSWu Mianzhi             rctl_regs,
404*77799ccaSWu Mianzhi             receive_regs,
405*77799ccaSWu Mianzhi             tctl_regs,
406*77799ccaSWu Mianzhi             transimit_regs,
407*77799ccaSWu Mianzhi             pcie_regs,
408*77799ccaSWu Mianzhi             recv_desc_ring,
409*77799ccaSWu Mianzhi             trans_desc_ring,
410*77799ccaSWu Mianzhi             recv_ring_pa,
411*77799ccaSWu Mianzhi             trans_ring_pa,
412*77799ccaSWu Mianzhi             recv_buffers,
413*77799ccaSWu Mianzhi             trans_buffers,
414*77799ccaSWu Mianzhi             mac,
415*77799ccaSWu Mianzhi             first_trans: true,
416*77799ccaSWu Mianzhi             napi_buffers: vec![E1000EBuffer::new(0); E1000E_RECV_NAPI],
417*77799ccaSWu Mianzhi             napi_buffer_head: 0,
418*77799ccaSWu Mianzhi             napi_buffer_tail: 0,
419*77799ccaSWu Mianzhi             napi_buffer_empty: true,
420*77799ccaSWu Mianzhi         });
421*77799ccaSWu Mianzhi     }
422*77799ccaSWu Mianzhi     pub fn e1000e_receive(&mut self) -> Option<E1000EBuffer> {
423*77799ccaSWu Mianzhi         self.e1000e_intr();
424*77799ccaSWu Mianzhi         let mut rdt = unsafe { volread!(self.receive_regs, rdt0) } as usize;
425*77799ccaSWu Mianzhi         let index = (rdt + 1) % self.recv_desc_ring.len();
426*77799ccaSWu Mianzhi         let desc = &mut self.recv_desc_ring[index];
427*77799ccaSWu Mianzhi         if (desc.status & E1000E_RXD_STATUS_DD) == 0 {
428*77799ccaSWu Mianzhi             return None;
429*77799ccaSWu Mianzhi         }
430*77799ccaSWu Mianzhi         let mut buffer = self.recv_buffers[index];
431*77799ccaSWu Mianzhi         let new_buffer = E1000EBuffer::new(PAGE_SIZE);
432*77799ccaSWu Mianzhi         self.recv_buffers[index] = new_buffer;
433*77799ccaSWu Mianzhi         desc.addr = new_buffer.as_paddr() as u64;
434*77799ccaSWu Mianzhi         buffer.set_length(desc.len as usize);
435*77799ccaSWu Mianzhi         rdt = index;
436*77799ccaSWu Mianzhi         unsafe { volwrite!(self.receive_regs, rdt0, rdt as u32) };
437*77799ccaSWu Mianzhi         // kdebug!("e1000e: receive packet");
438*77799ccaSWu Mianzhi         return Some(buffer);
439*77799ccaSWu Mianzhi     }
440*77799ccaSWu Mianzhi 
441*77799ccaSWu Mianzhi     pub fn e1000e_can_transmit(&self) -> bool {
442*77799ccaSWu Mianzhi         let tdt = unsafe { volread!(self.transimit_regs, tdt0) } as usize;
443*77799ccaSWu Mianzhi         let index = tdt % self.trans_desc_ring.len();
444*77799ccaSWu Mianzhi         let desc = &self.trans_desc_ring[index];
445*77799ccaSWu Mianzhi         if (desc.status & E1000E_TXD_STATUS_DD) == 0 {
446*77799ccaSWu Mianzhi             return false;
447*77799ccaSWu Mianzhi         }
448*77799ccaSWu Mianzhi         true
449*77799ccaSWu Mianzhi     }
450*77799ccaSWu Mianzhi 
451*77799ccaSWu Mianzhi     pub fn e1000e_transmit(&mut self, packet: E1000EBuffer) {
452*77799ccaSWu Mianzhi         let mut tdt = unsafe { volread!(self.transimit_regs, tdt0) } as usize;
453*77799ccaSWu Mianzhi         let index = tdt % self.trans_desc_ring.len();
454*77799ccaSWu Mianzhi         let desc = &mut self.trans_desc_ring[index];
455*77799ccaSWu Mianzhi         let buffer = self.trans_buffers[index];
456*77799ccaSWu Mianzhi         self.trans_buffers[index] = packet;
457*77799ccaSWu Mianzhi         // recycle unused transmit buffer
458*77799ccaSWu Mianzhi         buffer.free_buffer();
459*77799ccaSWu Mianzhi         // Set the transmit descriptor
460*77799ccaSWu Mianzhi         desc.addr = packet.as_paddr() as u64;
461*77799ccaSWu Mianzhi         desc.len = packet.len() as u16;
462*77799ccaSWu Mianzhi         desc.status = 0;
463*77799ccaSWu Mianzhi         desc.cmd = E1000E_TXD_CMD_EOP | E1000E_TXD_CMD_RS | E1000E_TXD_CMD_IFCS;
464*77799ccaSWu Mianzhi         tdt = (tdt + 1) % self.trans_desc_ring.len();
465*77799ccaSWu Mianzhi         unsafe { volwrite!(self.transimit_regs, tdt0, tdt as u32) };
466*77799ccaSWu Mianzhi         self.first_trans = false;
467*77799ccaSWu Mianzhi     }
468*77799ccaSWu Mianzhi     pub fn mac_address(&self) -> [u8; 6] {
469*77799ccaSWu Mianzhi         return self.mac;
470*77799ccaSWu Mianzhi     }
471*77799ccaSWu Mianzhi     // 向ICR寄存器中的某一bit写入1b表示该中断已经被接收,同时会清空该位
472*77799ccaSWu Mianzhi     // we need to clear ICR to tell e1000e we have read the interrupt
473*77799ccaSWu Mianzhi     pub fn e1000e_intr(&mut self) {
474*77799ccaSWu Mianzhi         let icr = unsafe { volread!(self.interrupt_regs, icr) };
475*77799ccaSWu Mianzhi         // write 1b to any bit in ICR will clear the bit
476*77799ccaSWu Mianzhi         unsafe { volwrite!(self.interrupt_regs, icr, icr) };
477*77799ccaSWu Mianzhi     }
478*77799ccaSWu Mianzhi 
479*77799ccaSWu Mianzhi     // 切换是否接受分组到达的中断
480*77799ccaSWu Mianzhi     // change whether the receive timer interrupt is enabled
481*77799ccaSWu Mianzhi     // Note: this method is not completely implemented and not used in the current version
482*77799ccaSWu Mianzhi     pub fn e1000e_intr_set(&mut self, state: bool) {
483*77799ccaSWu Mianzhi         let mut ims = unsafe { volread!(self.interrupt_regs, ims) };
484*77799ccaSWu Mianzhi         match state {
485*77799ccaSWu Mianzhi             true => ims = ims | E1000E_IMS_RXT0,
486*77799ccaSWu Mianzhi             false => ims = ims & !E1000E_IMS_RXT0,
487*77799ccaSWu Mianzhi         }
488*77799ccaSWu Mianzhi         unsafe { volwrite!(self.interrupt_regs, ims, ims) };
489*77799ccaSWu Mianzhi     }
490*77799ccaSWu Mianzhi 
491*77799ccaSWu Mianzhi     // 实现了一部分napi机制的收包函数, 现在还没有投入使用
492*77799ccaSWu Mianzhi     // This method is a partial implementation of napi (New API) techniques
493*77799ccaSWu Mianzhi     // Note: this method is not completely implemented and not used in the current version
494*77799ccaSWu Mianzhi     pub fn e1000e_receive2(&mut self) -> Option<E1000EBuffer> {
495*77799ccaSWu Mianzhi         // 向设备表明我们已经接受到了之前的中断
496*77799ccaSWu Mianzhi         // Tell e1000e we have received the interrupt
497*77799ccaSWu Mianzhi         self.e1000e_intr();
498*77799ccaSWu Mianzhi         // 如果napi队列不存在已经收到的分组...
499*77799ccaSWu Mianzhi         // if napi queue is empty...
500*77799ccaSWu Mianzhi         if self.napi_buffer_empty {
501*77799ccaSWu Mianzhi             // 暂时关闭设备中断
502*77799ccaSWu Mianzhi             // close interrupt
503*77799ccaSWu Mianzhi             self.e1000e_intr_set(false);
504*77799ccaSWu Mianzhi             loop {
505*77799ccaSWu Mianzhi                 if self.napi_buffer_tail == self.napi_buffer_head && self.napi_buffer_empty == false
506*77799ccaSWu Mianzhi                 {
507*77799ccaSWu Mianzhi                     // napi缓冲队列已满,停止收包
508*77799ccaSWu Mianzhi                     // napi queue is full, stop
509*77799ccaSWu Mianzhi                     break;
510*77799ccaSWu Mianzhi                 }
511*77799ccaSWu Mianzhi                 match self.e1000e_receive() {
512*77799ccaSWu Mianzhi                     Some(buffer) => {
513*77799ccaSWu Mianzhi                         self.napi_buffers[self.napi_buffer_tail] = buffer;
514*77799ccaSWu Mianzhi                         self.napi_buffer_tail = (self.napi_buffer_tail + 1) % E1000E_RECV_NAPI;
515*77799ccaSWu Mianzhi                         self.napi_buffer_empty = false;
516*77799ccaSWu Mianzhi                     }
517*77799ccaSWu Mianzhi                     None => {
518*77799ccaSWu Mianzhi                         // 设备队列中没有剩余的已到达的数据包
519*77799ccaSWu Mianzhi                         // no packet remains in the device buffer
520*77799ccaSWu Mianzhi                         break;
521*77799ccaSWu Mianzhi                     }
522*77799ccaSWu Mianzhi                 };
523*77799ccaSWu Mianzhi             }
524*77799ccaSWu Mianzhi             // 重新打开设备中断
525*77799ccaSWu Mianzhi             // open the interrupt
526*77799ccaSWu Mianzhi             self.e1000e_intr_set(true);
527*77799ccaSWu Mianzhi         }
528*77799ccaSWu Mianzhi 
529*77799ccaSWu Mianzhi         let result = self.napi_buffers[self.napi_buffer_head];
530*77799ccaSWu Mianzhi         match result.len() {
531*77799ccaSWu Mianzhi             0 => {
532*77799ccaSWu Mianzhi                 // napi队列和网卡队列中都不存在数据包
533*77799ccaSWu Mianzhi                 // both napi queue and device buffer is empty, no packet will receive
534*77799ccaSWu Mianzhi                 return None;
535*77799ccaSWu Mianzhi             }
536*77799ccaSWu Mianzhi             _ => {
537*77799ccaSWu Mianzhi                 // 有剩余的已到达的数据包
538*77799ccaSWu Mianzhi                 // there is packet in napi queue
539*77799ccaSWu Mianzhi                 self.napi_buffer_head = (self.napi_buffer_head + 1) % E1000E_RECV_NAPI;
540*77799ccaSWu Mianzhi                 if self.napi_buffer_head == self.napi_buffer_tail {
541*77799ccaSWu Mianzhi                     self.napi_buffer_empty = true;
542*77799ccaSWu Mianzhi                 }
543*77799ccaSWu Mianzhi                 return Some(result);
544*77799ccaSWu Mianzhi             }
545*77799ccaSWu Mianzhi         }
546*77799ccaSWu Mianzhi     }
547*77799ccaSWu Mianzhi }
548*77799ccaSWu Mianzhi 
549*77799ccaSWu Mianzhi impl Drop for E1000EDevice {
550*77799ccaSWu Mianzhi     fn drop(&mut self) {
551*77799ccaSWu Mianzhi         // 释放已分配的所有dma页
552*77799ccaSWu Mianzhi         // free all dma pages we have allocated
553*77799ccaSWu Mianzhi         kdebug!("droping...");
554*77799ccaSWu Mianzhi         let recv_ring_length = PAGE_SIZE / size_of::<E1000ERecvDesc>();
555*77799ccaSWu Mianzhi         let trans_ring_length = PAGE_SIZE / size_of::<E1000ETransDesc>();
556*77799ccaSWu Mianzhi         unsafe {
557*77799ccaSWu Mianzhi             // 释放所有buffer中的dma页
558*77799ccaSWu Mianzhi             // free all dma pages in buffers
559*77799ccaSWu Mianzhi             for i in 0..recv_ring_length {
560*77799ccaSWu Mianzhi                 self.recv_buffers[i].free_buffer();
561*77799ccaSWu Mianzhi             }
562*77799ccaSWu Mianzhi             for i in 0..trans_ring_length {
563*77799ccaSWu Mianzhi                 self.trans_buffers[i].free_buffer();
564*77799ccaSWu Mianzhi             }
565*77799ccaSWu Mianzhi             // 释放descriptor ring
566*77799ccaSWu Mianzhi             // free descriptor ring
567*77799ccaSWu Mianzhi             dma_dealloc(
568*77799ccaSWu Mianzhi                 self.recv_ring_pa,
569*77799ccaSWu Mianzhi                 NonNull::new(self.recv_desc_ring).unwrap().cast(),
570*77799ccaSWu Mianzhi                 E1000E_DMA_PAGES,
571*77799ccaSWu Mianzhi             );
572*77799ccaSWu Mianzhi             dma_dealloc(
573*77799ccaSWu Mianzhi                 self.trans_ring_pa,
574*77799ccaSWu Mianzhi                 NonNull::new(self.trans_desc_ring).unwrap().cast(),
575*77799ccaSWu Mianzhi                 E1000E_DMA_PAGES,
576*77799ccaSWu Mianzhi             );
577*77799ccaSWu Mianzhi         }
578*77799ccaSWu Mianzhi     }
579*77799ccaSWu Mianzhi }
580*77799ccaSWu Mianzhi 
581*77799ccaSWu Mianzhi #[no_mangle]
582*77799ccaSWu Mianzhi pub extern "C" fn rs_e1000e_init() {
583*77799ccaSWu Mianzhi     e1000e_init();
584*77799ccaSWu Mianzhi }
585*77799ccaSWu Mianzhi 
586*77799ccaSWu Mianzhi pub fn e1000e_init() -> () {
587*77799ccaSWu Mianzhi     match e1000e_probe() {
588*77799ccaSWu Mianzhi         Ok(code) => kinfo!("Successfully init e1000e device!"),
589*77799ccaSWu Mianzhi         Err(error) => kinfo!("Error occurred!"),
590*77799ccaSWu Mianzhi     }
591*77799ccaSWu Mianzhi }
592*77799ccaSWu Mianzhi 
593*77799ccaSWu Mianzhi pub fn e1000e_probe() -> Result<u64, E1000EPciError> {
594*77799ccaSWu Mianzhi     let mut list = PCI_DEVICE_LINKEDLIST.write();
595*77799ccaSWu Mianzhi     let result = get_pci_device_structure_mut(&mut list, NETWORK_CLASS, ETHERNET_SUBCLASS);
596*77799ccaSWu Mianzhi     if result.is_empty() {
597*77799ccaSWu Mianzhi         return Ok(0);
598*77799ccaSWu Mianzhi     }
599*77799ccaSWu Mianzhi     for device in result {
600*77799ccaSWu Mianzhi         let standard_device = device.as_standard_device_mut().unwrap();
601*77799ccaSWu Mianzhi         let header = &standard_device.common_header;
602*77799ccaSWu Mianzhi         if header.vendor_id == 0x8086 {
603*77799ccaSWu Mianzhi             // intel
604*77799ccaSWu Mianzhi             if E1000E_DEVICE_ID.contains(&header.device_id) {
605*77799ccaSWu Mianzhi                 kdebug!(
606*77799ccaSWu Mianzhi                     "Detected e1000e PCI device with device id {:#x}",
607*77799ccaSWu Mianzhi                     header.device_id
608*77799ccaSWu Mianzhi                 );
609*77799ccaSWu Mianzhi                 let e1000e = E1000EDevice::new(standard_device)?;
610*77799ccaSWu Mianzhi                 e1000e_driver_init(e1000e);
611*77799ccaSWu Mianzhi             }
612*77799ccaSWu Mianzhi         }
613*77799ccaSWu Mianzhi     }
614*77799ccaSWu Mianzhi 
615*77799ccaSWu Mianzhi     return Ok(1);
616*77799ccaSWu Mianzhi }
617*77799ccaSWu Mianzhi 
618*77799ccaSWu Mianzhi // 用到的e1000e寄存器结构体
619*77799ccaSWu Mianzhi // pp.275, Table 13-3
620*77799ccaSWu Mianzhi // 设备通用寄存器
621*77799ccaSWu Mianzhi struct GeneralRegs {
622*77799ccaSWu Mianzhi     ctrl: Volatile<u32>,         //0x00000
623*77799ccaSWu Mianzhi     ctrl_alias: Volatile<u32>,   //0x00004
624*77799ccaSWu Mianzhi     status: ReadOnly<u32>,       //0x00008
625*77799ccaSWu Mianzhi     status_align: ReadOnly<u32>, //0x0000c
626*77799ccaSWu Mianzhi     eec: Volatile<u32>,          //0x00010
627*77799ccaSWu Mianzhi     eerd: Volatile<u32>,         //0x00014
628*77799ccaSWu Mianzhi     ctrl_ext: Volatile<u32>,     //0x00018
629*77799ccaSWu Mianzhi     fla: Volatile<u32>,          //0x0001c
630*77799ccaSWu Mianzhi     mdic: Volatile<u32>,         //0x00020
631*77799ccaSWu Mianzhi }
632*77799ccaSWu Mianzhi // 中断控制
633*77799ccaSWu Mianzhi struct InterruptRegs {
634*77799ccaSWu Mianzhi     icr: Volatile<u32>, //0x000c0 ICR寄存器应当为只读寄存器,但我们需要向其中写入来清除对应位
635*77799ccaSWu Mianzhi     itr: Volatile<u32>, //0x000c4
636*77799ccaSWu Mianzhi     ics: WriteOnly<u32>, //0x000c8
637*77799ccaSWu Mianzhi     ics_align: ReadOnly<u32>, //0x000cc
638*77799ccaSWu Mianzhi     ims: Volatile<u32>, //0x000d0
639*77799ccaSWu Mianzhi     ims_align: ReadOnly<u32>, //0x000d4
640*77799ccaSWu Mianzhi     imc: WriteOnly<u32>, //0x000d8
641*77799ccaSWu Mianzhi }
642*77799ccaSWu Mianzhi // 收包功能控制
643*77799ccaSWu Mianzhi struct ReceiveCtrlRegs {
644*77799ccaSWu Mianzhi     rctl: Volatile<u32>, //0x00100
645*77799ccaSWu Mianzhi }
646*77799ccaSWu Mianzhi // 发包功能控制
647*77799ccaSWu Mianzhi struct TransmitCtrlRegs {
648*77799ccaSWu Mianzhi     tctl: Volatile<u32>,     //0x00400
649*77799ccaSWu Mianzhi     tctl_ext: Volatile<u32>, //0x00404
650*77799ccaSWu Mianzhi     unused_1: ReadOnly<u32>, //0x00408
651*77799ccaSWu Mianzhi     unused_2: ReadOnly<u32>, //0x0040c
652*77799ccaSWu Mianzhi     tipg: Volatile<u32>,     //0x00410
653*77799ccaSWu Mianzhi }
654*77799ccaSWu Mianzhi // 收包功能相关
655*77799ccaSWu Mianzhi struct ReceiveRegs {
656*77799ccaSWu Mianzhi     rdbal0: Volatile<u32>,     //0x02800
657*77799ccaSWu Mianzhi     rdbah0: Volatile<u32>,     //0x02804
658*77799ccaSWu Mianzhi     rdlen0: Volatile<u32>,     //0x02808
659*77799ccaSWu Mianzhi     rdl_align: ReadOnly<u32>,  //0x0280c
660*77799ccaSWu Mianzhi     rdh0: Volatile<u32>,       //0x02810
661*77799ccaSWu Mianzhi     rdh_align: ReadOnly<u32>,  //0x02814
662*77799ccaSWu Mianzhi     rdt0: Volatile<u32>,       //0x02818
663*77799ccaSWu Mianzhi     rdt_align: ReadOnly<u32>,  //0x281c
664*77799ccaSWu Mianzhi     rdtr: Volatile<u32>,       //0x2820
665*77799ccaSWu Mianzhi     rdtr_align: ReadOnly<u32>, //0x2824
666*77799ccaSWu Mianzhi     rxdctl: Volatile<u32>,     //0x2828
667*77799ccaSWu Mianzhi }
668*77799ccaSWu Mianzhi // 发包功能相关
669*77799ccaSWu Mianzhi struct TransimitRegs {
670*77799ccaSWu Mianzhi     tdbal0: Volatile<u32>,      //0x03800
671*77799ccaSWu Mianzhi     tdbah0: Volatile<u32>,      //0x03804
672*77799ccaSWu Mianzhi     tdlen0: Volatile<u32>,      //0x03808
673*77799ccaSWu Mianzhi     tdlen_algin: ReadOnly<u32>, //0x0380c
674*77799ccaSWu Mianzhi     tdh0: Volatile<u32>,        //0x03810
675*77799ccaSWu Mianzhi     tdh_align: ReadOnly<u32>,   //0x03814
676*77799ccaSWu Mianzhi     tdt0: Volatile<u32>,        //0x03818
677*77799ccaSWu Mianzhi     tdt_align: ReadOnly<u32>,   //0x0381c
678*77799ccaSWu Mianzhi     tidv: Volatile<u32>,        //0x03820
679*77799ccaSWu Mianzhi     tidv_align: ReadOnly<u32>,  //0x03824
680*77799ccaSWu Mianzhi     txdctl: Volatile<u32>,      //0x03828
681*77799ccaSWu Mianzhi     tadv: Volatile<u32>,        //0x0382c
682*77799ccaSWu Mianzhi }
683*77799ccaSWu Mianzhi // mac地址
684*77799ccaSWu Mianzhi struct ReceiveAddressRegs {
685*77799ccaSWu Mianzhi     ral0: Volatile<u32>, //0x05400
686*77799ccaSWu Mianzhi     rah0: Volatile<u32>, //0x05404
687*77799ccaSWu Mianzhi }
688*77799ccaSWu Mianzhi // PCIe 通用控制
689*77799ccaSWu Mianzhi struct PCIeRegs {
690*77799ccaSWu Mianzhi     gcr: Volatile<u32>, //0x05b00
691*77799ccaSWu Mianzhi }
692*77799ccaSWu Mianzhi struct StatisticsRegs {}
693*77799ccaSWu Mianzhi 
694*77799ccaSWu Mianzhi // 0x05200-0x053fc
695*77799ccaSWu Mianzhi // 在Receive Initialization 中按照每次一个32bit寄存器的方式来遍历
696*77799ccaSWu Mianzhi // Multicast Table Array Registers will be written per 32bit
697*77799ccaSWu Mianzhi struct MTARegs {
698*77799ccaSWu Mianzhi     mta: Volatile<u32>,
699*77799ccaSWu Mianzhi }
700*77799ccaSWu Mianzhi 
701*77799ccaSWu Mianzhi const E1000E_GENERAL_REGS_OFFSET: u64 = 0x00000;
702*77799ccaSWu Mianzhi const E1000E_INTERRRUPT_REGS_OFFSET: u64 = 0x000c0;
703*77799ccaSWu Mianzhi const E1000E_RECEIVE_CTRL_REG_OFFSET: u64 = 0x00100;
704*77799ccaSWu Mianzhi const E1000E_RECEIVE_REGS_OFFSET: u64 = 0x02800;
705*77799ccaSWu Mianzhi const E1000E_TRANSMIT_CTRL_REG_OFFSET: u64 = 0x00400;
706*77799ccaSWu Mianzhi const E1000E_TRANSMIT_REGS_OFFSET: u64 = 0x03800;
707*77799ccaSWu Mianzhi const E1000E_RECEIVE_ADDRESS_REGS_OFFSET: u64 = 0x05400;
708*77799ccaSWu Mianzhi const E1000E_PCIE_REGS_OFFSET: u64 = 0x05b00;
709*77799ccaSWu Mianzhi const E1000E_MTA_REGS_START_OFFSET: u64 = 0x05200;
710*77799ccaSWu Mianzhi const E1000E_MTA_REGS_END_OFFSET: u64 = 0x053fc;
711*77799ccaSWu Mianzhi // 寄存器的特定位
712*77799ccaSWu Mianzhi //CTRL
713*77799ccaSWu Mianzhi const E1000E_CTRL_SLU: u32 = 1 << 6;
714*77799ccaSWu Mianzhi const E1000E_CTRL_FRCSPD: u32 = 1 << 11;
715*77799ccaSWu Mianzhi const E1000E_CTRL_FRCDPLX: u32 = 1 << 12;
716*77799ccaSWu Mianzhi const E1000E_CTRL_RST: u32 = 1 << 26;
717*77799ccaSWu Mianzhi const E1000E_CTRL_RFCE: u32 = 1 << 27;
718*77799ccaSWu Mianzhi const E1000E_CTRL_TFCE: u32 = 1 << 28;
719*77799ccaSWu Mianzhi const E1000E_CTRL_PHY_RST: u32 = 1 << 31;
720*77799ccaSWu Mianzhi 
721*77799ccaSWu Mianzhi // IMS
722*77799ccaSWu Mianzhi const E1000E_IMS_LSC: u32 = 1 << 2;
723*77799ccaSWu Mianzhi const E1000E_IMS_RXDMT0: u32 = 1 << 4;
724*77799ccaSWu Mianzhi const E1000E_IMS_RXO: u32 = 1 << 6;
725*77799ccaSWu Mianzhi const E1000E_IMS_RXT0: u32 = 1 << 7;
726*77799ccaSWu Mianzhi const E1000E_IMS_RXQ0: u32 = 1 << 20;
727*77799ccaSWu Mianzhi const E1000E_IMS_OTHER: u32 = 1 << 24; // qemu use this bit to set msi-x interrupt
728*77799ccaSWu Mianzhi 
729*77799ccaSWu Mianzhi // IMC
730*77799ccaSWu Mianzhi const E1000E_IMC_CLEAR: u32 = 0xffffffff;
731*77799ccaSWu Mianzhi 
732*77799ccaSWu Mianzhi // RCTL
733*77799ccaSWu Mianzhi const E1000E_RCTL_EN: u32 = 1 << 1;
734*77799ccaSWu Mianzhi const E1000E_RCTL_BAM: u32 = 1 << 15;
735*77799ccaSWu Mianzhi const E1000E_RCTL_BSIZE_4K: u32 = 3 << 16;
736*77799ccaSWu Mianzhi const E1000E_RCTL_BSEX: u32 = 1 << 25;
737*77799ccaSWu Mianzhi const E1000E_RCTL_SECRC: u32 = 1 << 26;
738*77799ccaSWu Mianzhi 
739*77799ccaSWu Mianzhi // TCTL
740*77799ccaSWu Mianzhi const E1000E_TCTL_EN: u32 = 1 << 1;
741*77799ccaSWu Mianzhi const E1000E_TCTL_PSP: u32 = 1 << 3;
742*77799ccaSWu Mianzhi const E1000E_TCTL_CT_VAL: u32 = 0x0f << 4; // suggested 16d collision, 手册建议值:16d
743*77799ccaSWu Mianzhi const E1000E_TCTL_COLD_VAL: u32 = 0x03f << 12; // suggested 64 byte time for Full-Duplex, 手册建议值:64
744*77799ccaSWu Mianzhi                                                // TXDCTL
745*77799ccaSWu Mianzhi const E1000E_TXDCTL_WTHRESH: u32 = 1 << 16;
746*77799ccaSWu Mianzhi const E1000E_TXDCTL_GRAN: u32 = 1 << 24;
747*77799ccaSWu Mianzhi // TIPG
748*77799ccaSWu Mianzhi const E1000E_TIPG_IPGT: u32 = 8;
749*77799ccaSWu Mianzhi const E1000E_TIPG_IPGR1: u32 = 2 << 10;
750*77799ccaSWu Mianzhi const E1000E_TIPG_IPGR2: u32 = 10 << 20;
751*77799ccaSWu Mianzhi 
752*77799ccaSWu Mianzhi // RxDescriptorStatus
753*77799ccaSWu Mianzhi const E1000E_RXD_STATUS_DD: u16 = 1 << 0;
754*77799ccaSWu Mianzhi 
755*77799ccaSWu Mianzhi // TxDescriptorStatus
756*77799ccaSWu Mianzhi const E1000E_TXD_STATUS_DD: u8 = 1 << 0;
757*77799ccaSWu Mianzhi const E1000E_TXD_CMD_EOP: u8 = 1 << 0;
758*77799ccaSWu Mianzhi const E1000E_TXD_CMD_IFCS: u8 = 1 << 1;
759*77799ccaSWu Mianzhi const E1000E_TXD_CMD_RS: u8 = 1 << 3;
760*77799ccaSWu Mianzhi 
761*77799ccaSWu Mianzhi // E1000E驱动初始化过程中可能的错误
762*77799ccaSWu Mianzhi pub enum E1000EPciError {
763*77799ccaSWu Mianzhi     // 获取到错误类型的BAR(IO BAR)
764*77799ccaSWu Mianzhi     // An IO BAR was provided rather than a memory BAR.
765*77799ccaSWu Mianzhi     UnexpectedBarType,
766*77799ccaSWu Mianzhi     // 获取的BAR没有被分配到某个地址(address == 0)
767*77799ccaSWu Mianzhi     // A BAR which we need was not allocated an address(address == 0).
768*77799ccaSWu Mianzhi     BarNotAllocated,
769*77799ccaSWu Mianzhi     //获取虚拟地址失败
770*77799ccaSWu Mianzhi     BarGetVaddrFailed,
771*77799ccaSWu Mianzhi     // 没有对应的BAR或者获取BAR失败
772*77799ccaSWu Mianzhi     BarGetFailed,
773*77799ccaSWu Mianzhi     // BAR的大小与预期不符(128KB)
774*77799ccaSWu Mianzhi     // Size of BAR is not 128KB
775*77799ccaSWu Mianzhi     UnexpectedBarSize,
776*77799ccaSWu Mianzhi     Pci(PciError),
777*77799ccaSWu Mianzhi }
778*77799ccaSWu Mianzhi 
779*77799ccaSWu Mianzhi /// PCI error到VirtioPciError的转换,层层上报
780*77799ccaSWu Mianzhi impl From<PciError> for E1000EPciError {
781*77799ccaSWu Mianzhi     fn from(error: PciError) -> Self {
782*77799ccaSWu Mianzhi         Self::Pci(error)
783*77799ccaSWu Mianzhi     }
784*77799ccaSWu Mianzhi }
785*77799ccaSWu Mianzhi 
786*77799ccaSWu Mianzhi /**
787*77799ccaSWu Mianzhi  * @brief 获取基地址的某个偏移量的指针,用于在mmio bar中构造寄存器结构体
788*77799ccaSWu Mianzhi  * @brief used for build register struct in mmio bar
789*77799ccaSWu Mianzhi  * @param vaddr: base address (in virtual memory)
790*77799ccaSWu Mianzhi  * @param offset: offset
791*77799ccaSWu Mianzhi  */
792*77799ccaSWu Mianzhi fn get_register_ptr<T>(vaddr: u64, offset: u64) -> NonNull<T> {
793*77799ccaSWu Mianzhi     NonNull::new((vaddr + offset) as *mut T).unwrap()
794*77799ccaSWu Mianzhi }
795