xref: /DragonOS/kernel/src/driver/net/e1000e/e1000e.rs (revision bd70d2d1f490aabd570a5301b858bd5eb04149fa)
177799ccaSWu Mianzhi // 参考手册: PCIe* GbE Controllers Open Source Software Developer’s Manual
277799ccaSWu Mianzhi // Refernce: PCIe* GbE Controllers Open Source Software Developer’s Manual
377799ccaSWu Mianzhi 
4e2841179SLoGin use alloc::string::ToString;
5e2841179SLoGin use alloc::sync::Arc;
677799ccaSWu Mianzhi use alloc::vec::Vec;
777799ccaSWu Mianzhi use core::intrinsics::unlikely;
877799ccaSWu Mianzhi use core::mem::size_of;
977799ccaSWu Mianzhi use core::ptr::NonNull;
1077799ccaSWu Mianzhi use core::slice::{from_raw_parts, from_raw_parts_mut};
1177799ccaSWu Mianzhi use core::sync::atomic::{compiler_fence, Ordering};
122eab6dd7S曾俊 use log::{debug, info};
1377799ccaSWu Mianzhi 
1477799ccaSWu Mianzhi use super::e1000e_driver::e1000e_driver_init;
15e2841179SLoGin use crate::driver::base::device::DeviceId;
1677799ccaSWu Mianzhi use crate::driver::net::dma::{dma_alloc, dma_dealloc};
17e2841179SLoGin use crate::driver::net::irq_handle::DefaultNetIrqHandler;
1877799ccaSWu Mianzhi use crate::driver::pci::pci::{
1977799ccaSWu Mianzhi     get_pci_device_structure_mut, PciDeviceStructure, PciDeviceStructureGeneralDevice, PciError,
2077799ccaSWu Mianzhi     PCI_DEVICE_LINKEDLIST,
2177799ccaSWu Mianzhi };
22ce5850adSLoGin use crate::driver::pci::pci_irq::{IrqCommonMsg, IrqSpecificMsg, PciInterrupt, PciIrqMsg, IRQ};
23e2841179SLoGin use crate::exception::IrqNumber;
24e2841179SLoGin 
25971462beSGnoCiYeH use crate::libs::volatile::{ReadOnly, Volatile, WriteOnly};
26e2841179SLoGin 
2777799ccaSWu Mianzhi const PAGE_SIZE: usize = 4096;
2877799ccaSWu Mianzhi const NETWORK_CLASS: u8 = 0x2;
2977799ccaSWu Mianzhi const ETHERNET_SUBCLASS: u8 = 0x0;
3077799ccaSWu Mianzhi // e1000e系列网卡的device id列表,来源:https://admin.pci-ids.ucw.cz/read/PC/8086
3177799ccaSWu Mianzhi const E1000E_DEVICE_ID: [u16; 14] = [
3277799ccaSWu Mianzhi     0x10d3, // 8574L, qemu default
3377799ccaSWu Mianzhi     0x10cc, // 82567LM-2
3477799ccaSWu Mianzhi     0x10cd, // 82567LF-2
3577799ccaSWu Mianzhi     0x105f, // 82571EB
3677799ccaSWu Mianzhi     0x1060, // 82571EB
3777799ccaSWu Mianzhi     0x107f, // 82572EI
3877799ccaSWu Mianzhi     0x109a, // 82573L
3977799ccaSWu Mianzhi     0x10ea, // 82577LM
4077799ccaSWu Mianzhi     0x10eb, // 82577LC
4177799ccaSWu Mianzhi     0x10ef, // 82578DM
4277799ccaSWu Mianzhi     0x10f0, // 82578DC
4377799ccaSWu Mianzhi     0x1502, // 82579LM
4477799ccaSWu Mianzhi     0x1503, // 82579V
4577799ccaSWu Mianzhi     0x150c, // 82583V
4677799ccaSWu Mianzhi ];
4777799ccaSWu Mianzhi 
4877799ccaSWu Mianzhi // e1000e网卡与BAR有关的常量
4977799ccaSWu Mianzhi // BAR0空间大小(128KB)
5077799ccaSWu Mianzhi const E1000E_BAR_REG_SIZE: u32 = 128 * 1024;
5177799ccaSWu Mianzhi // BAR0空间对齐(64bit)
52971462beSGnoCiYeH #[allow(dead_code)]
5377799ccaSWu Mianzhi const E1000E_BAR_REG_ALIGN: u8 = 64;
5477799ccaSWu Mianzhi // 单个寄存器大小(32bit, 4字节)
55971462beSGnoCiYeH #[allow(dead_code)]
5677799ccaSWu Mianzhi const E1000E_REG_SIZE: u8 = 4;
5777799ccaSWu Mianzhi 
5877799ccaSWu Mianzhi // TxBuffer和RxBuffer的大小(DMA页)
5977799ccaSWu Mianzhi const E1000E_DMA_PAGES: usize = 1;
6077799ccaSWu Mianzhi 
6177799ccaSWu Mianzhi // 中断相关
62e2841179SLoGin const E1000E_RECV_VECTOR: IrqNumber = IrqNumber::new(57);
6377799ccaSWu Mianzhi 
6477799ccaSWu Mianzhi // napi队列中暂时存储的buffer个数
6577799ccaSWu Mianzhi const E1000E_RECV_NAPI: usize = 1024;
6677799ccaSWu Mianzhi 
6777799ccaSWu Mianzhi // 收/发包的描述符结构 pp.24 Table 3-1
6877799ccaSWu Mianzhi #[repr(C)]
6977799ccaSWu Mianzhi #[derive(Copy, Clone, Debug)]
7077799ccaSWu Mianzhi struct E1000ETransDesc {
7177799ccaSWu Mianzhi     addr: u64,
7277799ccaSWu Mianzhi     len: u16,
7377799ccaSWu Mianzhi     cso: u8,
7477799ccaSWu Mianzhi     cmd: u8,
7577799ccaSWu Mianzhi     status: u8,
7677799ccaSWu Mianzhi     css: u8,
7777799ccaSWu Mianzhi     special: u8,
7877799ccaSWu Mianzhi }
7977799ccaSWu Mianzhi // pp.54 Table 3-12
8077799ccaSWu Mianzhi #[repr(C)]
8177799ccaSWu Mianzhi #[derive(Copy, Clone, Debug)]
8277799ccaSWu Mianzhi struct E1000ERecvDesc {
8377799ccaSWu Mianzhi     addr: u64,
8477799ccaSWu Mianzhi     len: u16,
8577799ccaSWu Mianzhi     chksum: u16,
8677799ccaSWu Mianzhi     status: u16,
8777799ccaSWu Mianzhi     error: u8,
8877799ccaSWu Mianzhi     special: u8,
8977799ccaSWu Mianzhi }
9077799ccaSWu Mianzhi #[derive(Copy, Clone)]
9177799ccaSWu Mianzhi // Buffer的Copy只是指针操作,不涉及实际数据的复制,因此要小心使用,确保不同的buffer不会使用同一块内存
9277799ccaSWu Mianzhi pub struct E1000EBuffer {
9377799ccaSWu Mianzhi     buffer: NonNull<u8>,
9477799ccaSWu Mianzhi     paddr: usize,
9577799ccaSWu Mianzhi     // length字段为0则表示这个buffer是一个占位符,不指向实际内存
9677799ccaSWu Mianzhi     // the buffer is empty and no page is allocated if length field is set 0
9777799ccaSWu Mianzhi     length: usize,
9877799ccaSWu Mianzhi }
9977799ccaSWu Mianzhi 
10077799ccaSWu Mianzhi impl E1000EBuffer {
new(length: usize) -> Self10177799ccaSWu Mianzhi     pub fn new(length: usize) -> Self {
10277799ccaSWu Mianzhi         assert!(length <= PAGE_SIZE);
10377799ccaSWu Mianzhi         if unlikely(length == 0) {
10477799ccaSWu Mianzhi             // 在某些情况下,我们并不需要实际分配buffer,只需要提供一个占位符即可
10577799ccaSWu Mianzhi             // we dont need to allocate dma pages for buffer in some cases
10677799ccaSWu Mianzhi             E1000EBuffer {
10777799ccaSWu Mianzhi                 buffer: NonNull::dangling(),
10877799ccaSWu Mianzhi                 paddr: 0,
10977799ccaSWu Mianzhi                 length: 0,
11077799ccaSWu Mianzhi             }
11177799ccaSWu Mianzhi         } else {
11277799ccaSWu Mianzhi             let (paddr, vaddr) = dma_alloc(E1000E_DMA_PAGES);
11377799ccaSWu Mianzhi             E1000EBuffer {
11477799ccaSWu Mianzhi                 buffer: vaddr,
11577799ccaSWu Mianzhi                 paddr,
11677799ccaSWu Mianzhi                 length,
11777799ccaSWu Mianzhi             }
11877799ccaSWu Mianzhi         }
11977799ccaSWu Mianzhi     }
12077799ccaSWu Mianzhi 
121971462beSGnoCiYeH     #[allow(dead_code)]
as_addr(&self) -> NonNull<u8>12277799ccaSWu Mianzhi     pub fn as_addr(&self) -> NonNull<u8> {
12377799ccaSWu Mianzhi         assert!(self.length != 0);
12477799ccaSWu Mianzhi         return self.buffer;
12577799ccaSWu Mianzhi     }
12677799ccaSWu Mianzhi 
127971462beSGnoCiYeH     #[allow(dead_code)]
as_addr_u64(&self) -> u6412877799ccaSWu Mianzhi     pub fn as_addr_u64(&self) -> u64 {
12977799ccaSWu Mianzhi         assert!(self.length != 0);
13077799ccaSWu Mianzhi         return self.buffer.as_ptr() as u64;
13177799ccaSWu Mianzhi     }
13277799ccaSWu Mianzhi 
as_paddr(&self) -> usize13377799ccaSWu Mianzhi     pub fn as_paddr(&self) -> usize {
13477799ccaSWu Mianzhi         assert!(self.length != 0);
13577799ccaSWu Mianzhi         return self.paddr;
13677799ccaSWu Mianzhi     }
13777799ccaSWu Mianzhi 
138971462beSGnoCiYeH     #[allow(dead_code)]
as_slice(&self) -> &[u8]13977799ccaSWu Mianzhi     pub fn as_slice(&self) -> &[u8] {
14077799ccaSWu Mianzhi         assert!(self.length != 0);
14177799ccaSWu Mianzhi         return unsafe { from_raw_parts(self.buffer.as_ptr(), self.length) };
14277799ccaSWu Mianzhi     }
14377799ccaSWu Mianzhi 
as_mut_slice(&mut self) -> &mut [u8]14477799ccaSWu Mianzhi     pub fn as_mut_slice(&mut self) -> &mut [u8] {
14577799ccaSWu Mianzhi         assert!(self.length != 0);
14677799ccaSWu Mianzhi         return unsafe { from_raw_parts_mut(self.buffer.as_ptr(), self.length) };
14777799ccaSWu Mianzhi     }
14877799ccaSWu Mianzhi 
set_length(&mut self, length: usize)14977799ccaSWu Mianzhi     pub fn set_length(&mut self, length: usize) {
15077799ccaSWu Mianzhi         self.length = length;
15177799ccaSWu Mianzhi     }
15277799ccaSWu Mianzhi 
len(&self) -> usize15377799ccaSWu Mianzhi     pub fn len(&self) -> usize {
15477799ccaSWu Mianzhi         return self.length;
15577799ccaSWu Mianzhi     }
15677799ccaSWu Mianzhi     // 释放buffer内部的dma_pages,需要小心使用
free_buffer(self)157b5b571e0SLoGin     pub fn free_buffer(self) {
15877799ccaSWu Mianzhi         if self.length != 0 {
15977799ccaSWu Mianzhi             unsafe { dma_dealloc(self.paddr, self.buffer, E1000E_DMA_PAGES) };
16077799ccaSWu Mianzhi         }
16177799ccaSWu Mianzhi     }
16277799ccaSWu Mianzhi }
16377799ccaSWu Mianzhi 
164971462beSGnoCiYeH #[allow(dead_code)]
16577799ccaSWu Mianzhi pub struct E1000EDevice {
16677799ccaSWu Mianzhi     // 设备寄存器
16777799ccaSWu Mianzhi     // device registers
16877799ccaSWu Mianzhi     general_regs: NonNull<GeneralRegs>,
16977799ccaSWu Mianzhi     interrupt_regs: NonNull<InterruptRegs>,
17077799ccaSWu Mianzhi     rctl_regs: NonNull<ReceiveCtrlRegs>,
17177799ccaSWu Mianzhi     receive_regs: NonNull<ReceiveRegs>,
17277799ccaSWu Mianzhi     tctl_regs: NonNull<TransmitCtrlRegs>,
17377799ccaSWu Mianzhi     transimit_regs: NonNull<TransimitRegs>,
17477799ccaSWu Mianzhi     pcie_regs: NonNull<PCIeRegs>,
17577799ccaSWu Mianzhi 
17677799ccaSWu Mianzhi     // descriptor环形队列,在操作系统与设备之间共享
17777799ccaSWu Mianzhi     // descriptor rings are shared between os and device
17877799ccaSWu Mianzhi     recv_desc_ring: &'static mut [E1000ERecvDesc],
17977799ccaSWu Mianzhi     trans_desc_ring: &'static mut [E1000ETransDesc],
18077799ccaSWu Mianzhi     recv_ring_pa: usize,
18177799ccaSWu Mianzhi     trans_ring_pa: usize,
18277799ccaSWu Mianzhi 
18377799ccaSWu Mianzhi     // 设备收/发包缓冲区数组
18477799ccaSWu Mianzhi     // buffers of receive/transmit packets
18577799ccaSWu Mianzhi     recv_buffers: Vec<E1000EBuffer>,
18677799ccaSWu Mianzhi     trans_buffers: Vec<E1000EBuffer>,
18777799ccaSWu Mianzhi     mac: [u8; 6],
18877799ccaSWu Mianzhi     first_trans: bool,
18977799ccaSWu Mianzhi     // napi队列,用于存放在中断关闭期间通过轮询收取的buffer
19077799ccaSWu Mianzhi     // the napi queue is designed to save buffer/packet when the interrupt is close
19177799ccaSWu Mianzhi     // NOTE: this feature is not completely implemented and not used in the current version
19277799ccaSWu Mianzhi     napi_buffers: Vec<E1000EBuffer>,
19377799ccaSWu Mianzhi     napi_buffer_head: usize,
19477799ccaSWu Mianzhi     napi_buffer_tail: usize,
19577799ccaSWu Mianzhi     napi_buffer_empty: bool,
19677799ccaSWu Mianzhi }
19777799ccaSWu Mianzhi 
19877799ccaSWu Mianzhi impl E1000EDevice {
19977799ccaSWu Mianzhi     // 从PCI标准设备进行驱动初始化
20077799ccaSWu Mianzhi     // init the device for PCI standard device struct
201971462beSGnoCiYeH     #[allow(unused_assignments)]
new( device: &mut PciDeviceStructureGeneralDevice, device_id: Arc<DeviceId>, ) -> Result<Self, E1000EPciError>202e2841179SLoGin     pub fn new(
203e2841179SLoGin         device: &mut PciDeviceStructureGeneralDevice,
204e2841179SLoGin         device_id: Arc<DeviceId>,
205e2841179SLoGin     ) -> Result<Self, E1000EPciError> {
20677799ccaSWu Mianzhi         // 从BAR0获取我们需要的寄存器
20777799ccaSWu Mianzhi         // Build registers sturcts from BAR0
20877799ccaSWu Mianzhi         device.bar_ioremap().unwrap()?;
20977799ccaSWu Mianzhi         device.enable_master();
21077799ccaSWu Mianzhi         let bar = device.bar().ok_or(E1000EPciError::BarGetFailed)?;
21177799ccaSWu Mianzhi         let bar0 = bar.get_bar(0)?;
21277799ccaSWu Mianzhi         let (address, size) = bar0
21377799ccaSWu Mianzhi             .memory_address_size()
21477799ccaSWu Mianzhi             .ok_or(E1000EPciError::UnexpectedBarType)?;
21577799ccaSWu Mianzhi         if address == 0 {
21677799ccaSWu Mianzhi             return Err(E1000EPciError::BarNotAllocated);
21777799ccaSWu Mianzhi         }
21877799ccaSWu Mianzhi         if size != E1000E_BAR_REG_SIZE {
21977799ccaSWu Mianzhi             return Err(E1000EPciError::UnexpectedBarSize);
22077799ccaSWu Mianzhi         }
22177799ccaSWu Mianzhi         let vaddress = bar0
22277799ccaSWu Mianzhi             .virtual_address()
22377799ccaSWu Mianzhi             .ok_or(E1000EPciError::BarGetVaddrFailed)?
22477799ccaSWu Mianzhi             .data() as u64;
22577799ccaSWu Mianzhi 
22677799ccaSWu Mianzhi         // 初始化msi中断
22777799ccaSWu Mianzhi         // initialize msi interupt
22877799ccaSWu Mianzhi         let irq_vector = device.irq_vector_mut().unwrap();
22977799ccaSWu Mianzhi         irq_vector.push(E1000E_RECV_VECTOR);
23077799ccaSWu Mianzhi         device.irq_init(IRQ::PCI_IRQ_MSI).expect("IRQ Init Failed");
231ce5850adSLoGin         let msg = PciIrqMsg {
23277799ccaSWu Mianzhi             irq_common_message: IrqCommonMsg::init_from(
23377799ccaSWu Mianzhi                 0,
234e2841179SLoGin                 "E1000E_RECV_IRQ".to_string(),
235e2841179SLoGin                 &DefaultNetIrqHandler,
236e2841179SLoGin                 device_id,
23777799ccaSWu Mianzhi             ),
23877799ccaSWu Mianzhi             irq_specific_message: IrqSpecificMsg::msi_default(),
23977799ccaSWu Mianzhi         };
24077799ccaSWu Mianzhi         device.irq_install(msg)?;
24177799ccaSWu Mianzhi         device.irq_enable(true)?;
24277799ccaSWu Mianzhi 
24377799ccaSWu Mianzhi         let general_regs: NonNull<GeneralRegs> =
24477799ccaSWu Mianzhi             get_register_ptr(vaddress, E1000E_GENERAL_REGS_OFFSET);
24577799ccaSWu Mianzhi         let interrupt_regs: NonNull<InterruptRegs> =
24677799ccaSWu Mianzhi             get_register_ptr(vaddress, E1000E_INTERRRUPT_REGS_OFFSET);
24777799ccaSWu Mianzhi         let rctl_regs: NonNull<ReceiveCtrlRegs> =
24877799ccaSWu Mianzhi             get_register_ptr(vaddress, E1000E_RECEIVE_CTRL_REG_OFFSET);
24977799ccaSWu Mianzhi         let receive_regs: NonNull<ReceiveRegs> =
25077799ccaSWu Mianzhi             get_register_ptr(vaddress, E1000E_RECEIVE_REGS_OFFSET);
25177799ccaSWu Mianzhi         let tctl_regs: NonNull<TransmitCtrlRegs> =
25277799ccaSWu Mianzhi             get_register_ptr(vaddress, E1000E_TRANSMIT_CTRL_REG_OFFSET);
25377799ccaSWu Mianzhi         let transimit_regs: NonNull<TransimitRegs> =
25477799ccaSWu Mianzhi             get_register_ptr(vaddress, E1000E_TRANSMIT_REGS_OFFSET);
25577799ccaSWu Mianzhi         let pcie_regs: NonNull<PCIeRegs> = get_register_ptr(vaddress, E1000E_PCIE_REGS_OFFSET);
25677799ccaSWu Mianzhi         let ra_regs: NonNull<ReceiveAddressRegs> =
25777799ccaSWu Mianzhi             get_register_ptr(vaddress, E1000E_RECEIVE_ADDRESS_REGS_OFFSET);
25877799ccaSWu Mianzhi         // 开始设备初始化 14.3
25977799ccaSWu Mianzhi         // Initialization Sequence
26077799ccaSWu Mianzhi         unsafe {
26177799ccaSWu Mianzhi             let mut ctrl = volread!(general_regs, ctrl);
26277799ccaSWu Mianzhi             // 关闭中断
26377799ccaSWu Mianzhi             // close the interrupt
26477799ccaSWu Mianzhi             volwrite!(interrupt_regs, imc, E1000E_IMC_CLEAR);
26577799ccaSWu Mianzhi             //SW RESET
26677799ccaSWu Mianzhi             volwrite!(general_regs, ctrl, ctrl | E1000E_CTRL_RST);
26777799ccaSWu Mianzhi             compiler_fence(Ordering::AcqRel);
26877799ccaSWu Mianzhi             // PHY RESET
26977799ccaSWu Mianzhi             ctrl = volread!(general_regs, ctrl);
27077799ccaSWu Mianzhi             volwrite!(general_regs, ctrl, ctrl | E1000E_CTRL_PHY_RST);
27177799ccaSWu Mianzhi             volwrite!(general_regs, ctrl, ctrl);
27277799ccaSWu Mianzhi             // 关闭中断
27377799ccaSWu Mianzhi             // close the interrupt
27477799ccaSWu Mianzhi             volwrite!(interrupt_regs, imc, E1000E_IMC_CLEAR);
27577799ccaSWu Mianzhi             let mut gcr = volread!(pcie_regs, gcr);
276b5b571e0SLoGin             gcr |= 1 << 22;
27777799ccaSWu Mianzhi             volwrite!(pcie_regs, gcr, gcr);
27877799ccaSWu Mianzhi             compiler_fence(Ordering::AcqRel);
27977799ccaSWu Mianzhi             // PHY Initialization 14.8.1
28077799ccaSWu Mianzhi             // MAC/PHY Link Setup 14.8.2
28177799ccaSWu Mianzhi             ctrl = volread!(general_regs, ctrl);
28277799ccaSWu Mianzhi             ctrl &= !(E1000E_CTRL_FRCSPD | E1000E_CTRL_FRCDPLX);
28377799ccaSWu Mianzhi             volwrite!(general_regs, ctrl, ctrl | E1000E_CTRL_SLU);
28477799ccaSWu Mianzhi         }
28577799ccaSWu Mianzhi         let status = unsafe { volread!(general_regs, status) };
2862eab6dd7S曾俊         debug!("Status: {status:#X}");
28777799ccaSWu Mianzhi 
28877799ccaSWu Mianzhi         // 读取设备的mac地址
28977799ccaSWu Mianzhi         // Read mac address
29077799ccaSWu Mianzhi         let ral = unsafe { volread!(ra_regs, ral0) };
29177799ccaSWu Mianzhi         let rah = unsafe { volread!(ra_regs, rah0) };
29277799ccaSWu Mianzhi         let mac: [u8; 6] = [
293b5b571e0SLoGin             (ral & 0xFF) as u8,
29477799ccaSWu Mianzhi             ((ral >> 8) & 0xFF) as u8,
29577799ccaSWu Mianzhi             ((ral >> 16) & 0xFF) as u8,
29677799ccaSWu Mianzhi             ((ral >> 24) & 0xFF) as u8,
297b5b571e0SLoGin             (rah & 0xFF) as u8,
29877799ccaSWu Mianzhi             ((rah >> 8) & 0xFF) as u8,
29977799ccaSWu Mianzhi         ];
30077799ccaSWu Mianzhi         // 初始化receive和transimit descriptor环形队列
30177799ccaSWu Mianzhi         // initialize receive and transimit desciptor ring
30277799ccaSWu Mianzhi         let (recv_ring_pa, recv_ring_va) = dma_alloc(E1000E_DMA_PAGES);
30377799ccaSWu Mianzhi         let (trans_ring_pa, trans_ring_va) = dma_alloc(E1000E_DMA_PAGES);
30477799ccaSWu Mianzhi         let recv_ring_length = PAGE_SIZE / size_of::<E1000ERecvDesc>();
30577799ccaSWu Mianzhi         let trans_ring_length = PAGE_SIZE / size_of::<E1000ETransDesc>();
30677799ccaSWu Mianzhi 
30777799ccaSWu Mianzhi         let recv_desc_ring = unsafe {
30877799ccaSWu Mianzhi             from_raw_parts_mut::<E1000ERecvDesc>(recv_ring_va.as_ptr().cast(), recv_ring_length)
30977799ccaSWu Mianzhi         };
31077799ccaSWu Mianzhi         let trans_desc_ring = unsafe {
31177799ccaSWu Mianzhi             from_raw_parts_mut::<E1000ETransDesc>(trans_ring_va.as_ptr().cast(), trans_ring_length)
31277799ccaSWu Mianzhi         };
31377799ccaSWu Mianzhi 
31477799ccaSWu Mianzhi         // 初始化receive和transmit packet的缓冲区
31577799ccaSWu Mianzhi         // initialzie receive and transmit buffers
31677799ccaSWu Mianzhi         let mut recv_buffers: Vec<E1000EBuffer> = Vec::with_capacity(recv_ring_length);
31777799ccaSWu Mianzhi         let mut trans_buffers: Vec<E1000EBuffer> = Vec::with_capacity(trans_ring_length);
31877799ccaSWu Mianzhi 
31977799ccaSWu Mianzhi         // 初始化缓冲区与descriptor,descriptor 中的addr字典应当指向buffer的物理地址
32077799ccaSWu Mianzhi         // Receive buffers of appropriate size should be allocated and pointers to these buffers should be stored in the descriptor ring.
321b5b571e0SLoGin         for ring in recv_desc_ring.iter_mut().take(recv_ring_length) {
32277799ccaSWu Mianzhi             let buffer = E1000EBuffer::new(PAGE_SIZE);
323b5b571e0SLoGin             ring.addr = buffer.as_paddr() as u64;
324b5b571e0SLoGin             ring.status = 0;
32577799ccaSWu Mianzhi             recv_buffers.push(buffer);
32677799ccaSWu Mianzhi         }
32777799ccaSWu Mianzhi         // Same as receive buffers
328b5b571e0SLoGin         for ring in trans_desc_ring.iter_mut().take(recv_ring_length) {
32977799ccaSWu Mianzhi             let buffer = E1000EBuffer::new(PAGE_SIZE);
330b5b571e0SLoGin             ring.addr = buffer.as_paddr() as u64;
331b5b571e0SLoGin             ring.status = 1;
33277799ccaSWu Mianzhi             trans_buffers.push(buffer);
33377799ccaSWu Mianzhi         }
33477799ccaSWu Mianzhi 
33577799ccaSWu Mianzhi         // Receive Initialization 14.6
33677799ccaSWu Mianzhi         // Initialzie mutlicast table array to 0b
33777799ccaSWu Mianzhi         // 初始化MTA,遍历0x05200-0x053FC中每个寄存器,写入0b,一共128个寄存器
33877799ccaSWu Mianzhi         let mut mta_adress = vaddress + E1000E_MTA_REGS_START_OFFSET;
33977799ccaSWu Mianzhi         while mta_adress != vaddress + E1000E_MTA_REGS_END_OFFSET {
34077799ccaSWu Mianzhi             let mta: NonNull<MTARegs> = get_register_ptr(mta_adress, 0);
34177799ccaSWu Mianzhi             unsafe { volwrite!(mta, mta, 0) };
342b5b571e0SLoGin             mta_adress += 4;
34377799ccaSWu Mianzhi         }
34477799ccaSWu Mianzhi         // 连续的寄存器读-写操作,放在同一个unsafe块中
34577799ccaSWu Mianzhi         unsafe {
34677799ccaSWu Mianzhi             // 设置descriptor环形队列的基地址
34777799ccaSWu Mianzhi             // Program the descriptor base address with the address of the region.
34877799ccaSWu Mianzhi             volwrite!(receive_regs, rdbal0, (recv_ring_pa) as u32);
34977799ccaSWu Mianzhi             volwrite!(receive_regs, rdbah0, (recv_ring_pa >> 32) as u32);
35077799ccaSWu Mianzhi             // 设置descriptor环形队列的长度
35177799ccaSWu Mianzhi             // Set the length register to the size of the descriptor ring.
35277799ccaSWu Mianzhi             volwrite!(receive_regs, rdlen0, PAGE_SIZE as u32);
35377799ccaSWu Mianzhi             // 设置队列的首尾指针
35477799ccaSWu Mianzhi             // Program the head and tail registers
35577799ccaSWu Mianzhi             volwrite!(receive_regs, rdh0, 0);
35677799ccaSWu Mianzhi             volwrite!(receive_regs, rdt0, (recv_ring_length - 1) as u32);
35777799ccaSWu Mianzhi             // 设置控制寄存器的相关功能 14.6.1
35877799ccaSWu Mianzhi             // Set the receive control register
35977799ccaSWu Mianzhi             volwrite!(
36077799ccaSWu Mianzhi                 rctl_regs,
36177799ccaSWu Mianzhi                 rctl,
36277799ccaSWu Mianzhi                 E1000E_RCTL_EN
36377799ccaSWu Mianzhi                     | E1000E_RCTL_BAM
36477799ccaSWu Mianzhi                     | E1000E_RCTL_BSIZE_4K
36577799ccaSWu Mianzhi                     | E1000E_RCTL_BSEX
36677799ccaSWu Mianzhi                     | E1000E_RCTL_SECRC
36777799ccaSWu Mianzhi             );
36877799ccaSWu Mianzhi 
36977799ccaSWu Mianzhi             // Transmit Initialization 14.7
37077799ccaSWu Mianzhi             // 开启发包descriptor的回写功能
37177799ccaSWu Mianzhi             // Program the TXDCTL register with the desired TX descriptor write-back policy
37277799ccaSWu Mianzhi             volwrite!(
37377799ccaSWu Mianzhi                 transimit_regs,
37477799ccaSWu Mianzhi                 txdctl,
37577799ccaSWu Mianzhi                 E1000E_TXDCTL_WTHRESH | E1000E_TXDCTL_GRAN
37677799ccaSWu Mianzhi             );
37777799ccaSWu Mianzhi             // 设置descriptor环形队列的基地址,长度与首尾指针
37877799ccaSWu Mianzhi             // Program the descriptor base address with the address of the region
37977799ccaSWu Mianzhi             volwrite!(transimit_regs, tdbal0, trans_ring_pa as u32);
38077799ccaSWu Mianzhi             volwrite!(transimit_regs, tdbah0, (trans_ring_pa >> 32) as u32);
38177799ccaSWu Mianzhi             // Set the length register to the size of the descriptor ring.
38277799ccaSWu Mianzhi             volwrite!(transimit_regs, tdlen0, PAGE_SIZE as u32);
38377799ccaSWu Mianzhi             // Program the head and tail registerss
38477799ccaSWu Mianzhi             volwrite!(transimit_regs, tdh0, 0);
38577799ccaSWu Mianzhi             volwrite!(transimit_regs, tdt0, 0);
38677799ccaSWu Mianzhi             // Program the TIPG register
38777799ccaSWu Mianzhi             volwrite!(
38877799ccaSWu Mianzhi                 tctl_regs,
38977799ccaSWu Mianzhi                 tipg,
39077799ccaSWu Mianzhi                 E1000E_TIPG_IPGT | E1000E_TIPG_IPGR1 | E1000E_TIPG_IPGR2
39177799ccaSWu Mianzhi             );
39277799ccaSWu Mianzhi             // Program the TCTL register.
39377799ccaSWu Mianzhi             volwrite!(
39477799ccaSWu Mianzhi                 tctl_regs,
39577799ccaSWu Mianzhi                 tctl,
39677799ccaSWu Mianzhi                 E1000E_TCTL_EN | E1000E_TCTL_PSP | E1000E_TCTL_CT_VAL | E1000E_TCTL_COLD_VAL
39777799ccaSWu Mianzhi             );
39877799ccaSWu Mianzhi 
39977799ccaSWu Mianzhi             let icr = volread!(interrupt_regs, icr);
40077799ccaSWu Mianzhi             volwrite!(interrupt_regs, icr, icr);
40177799ccaSWu Mianzhi             // 开启收包相关的中断
40277799ccaSWu Mianzhi             // Enable receive interrupts
40377799ccaSWu Mianzhi             let mut ims = volread!(interrupt_regs, ims);
40477799ccaSWu Mianzhi             ims = E1000E_IMS_LSC | E1000E_IMS_RXT0 | E1000E_IMS_RXDMT0 | E1000E_IMS_OTHER;
40577799ccaSWu Mianzhi             volwrite!(interrupt_regs, ims, ims);
40677799ccaSWu Mianzhi         }
40777799ccaSWu Mianzhi         return Ok(E1000EDevice {
40877799ccaSWu Mianzhi             general_regs,
40977799ccaSWu Mianzhi             interrupt_regs,
41077799ccaSWu Mianzhi             rctl_regs,
41177799ccaSWu Mianzhi             receive_regs,
41277799ccaSWu Mianzhi             tctl_regs,
41377799ccaSWu Mianzhi             transimit_regs,
41477799ccaSWu Mianzhi             pcie_regs,
41577799ccaSWu Mianzhi             recv_desc_ring,
41677799ccaSWu Mianzhi             trans_desc_ring,
41777799ccaSWu Mianzhi             recv_ring_pa,
41877799ccaSWu Mianzhi             trans_ring_pa,
41977799ccaSWu Mianzhi             recv_buffers,
42077799ccaSWu Mianzhi             trans_buffers,
42177799ccaSWu Mianzhi             mac,
42277799ccaSWu Mianzhi             first_trans: true,
42377799ccaSWu Mianzhi             napi_buffers: vec![E1000EBuffer::new(0); E1000E_RECV_NAPI],
42477799ccaSWu Mianzhi             napi_buffer_head: 0,
42577799ccaSWu Mianzhi             napi_buffer_tail: 0,
42677799ccaSWu Mianzhi             napi_buffer_empty: true,
42777799ccaSWu Mianzhi         });
42877799ccaSWu Mianzhi     }
e1000e_receive(&mut self) -> Option<E1000EBuffer>42977799ccaSWu Mianzhi     pub fn e1000e_receive(&mut self) -> Option<E1000EBuffer> {
43077799ccaSWu Mianzhi         self.e1000e_intr();
43177799ccaSWu Mianzhi         let mut rdt = unsafe { volread!(self.receive_regs, rdt0) } as usize;
43277799ccaSWu Mianzhi         let index = (rdt + 1) % self.recv_desc_ring.len();
43377799ccaSWu Mianzhi         let desc = &mut self.recv_desc_ring[index];
43477799ccaSWu Mianzhi         if (desc.status & E1000E_RXD_STATUS_DD) == 0 {
43577799ccaSWu Mianzhi             return None;
43677799ccaSWu Mianzhi         }
43777799ccaSWu Mianzhi         let mut buffer = self.recv_buffers[index];
43877799ccaSWu Mianzhi         let new_buffer = E1000EBuffer::new(PAGE_SIZE);
43977799ccaSWu Mianzhi         self.recv_buffers[index] = new_buffer;
44077799ccaSWu Mianzhi         desc.addr = new_buffer.as_paddr() as u64;
44177799ccaSWu Mianzhi         buffer.set_length(desc.len as usize);
44277799ccaSWu Mianzhi         rdt = index;
44377799ccaSWu Mianzhi         unsafe { volwrite!(self.receive_regs, rdt0, rdt as u32) };
4442eab6dd7S曾俊         // debug!("e1000e: receive packet");
44577799ccaSWu Mianzhi         return Some(buffer);
44677799ccaSWu Mianzhi     }
44777799ccaSWu Mianzhi 
e1000e_can_transmit(&self) -> bool44877799ccaSWu Mianzhi     pub fn e1000e_can_transmit(&self) -> bool {
44977799ccaSWu Mianzhi         let tdt = unsafe { volread!(self.transimit_regs, tdt0) } as usize;
45077799ccaSWu Mianzhi         let index = tdt % self.trans_desc_ring.len();
45177799ccaSWu Mianzhi         let desc = &self.trans_desc_ring[index];
45277799ccaSWu Mianzhi         if (desc.status & E1000E_TXD_STATUS_DD) == 0 {
45377799ccaSWu Mianzhi             return false;
45477799ccaSWu Mianzhi         }
45577799ccaSWu Mianzhi         true
45677799ccaSWu Mianzhi     }
45777799ccaSWu Mianzhi 
e1000e_transmit(&mut self, packet: E1000EBuffer)45877799ccaSWu Mianzhi     pub fn e1000e_transmit(&mut self, packet: E1000EBuffer) {
45977799ccaSWu Mianzhi         let mut tdt = unsafe { volread!(self.transimit_regs, tdt0) } as usize;
46077799ccaSWu Mianzhi         let index = tdt % self.trans_desc_ring.len();
46177799ccaSWu Mianzhi         let desc = &mut self.trans_desc_ring[index];
46277799ccaSWu Mianzhi         let buffer = self.trans_buffers[index];
46377799ccaSWu Mianzhi         self.trans_buffers[index] = packet;
46477799ccaSWu Mianzhi         // recycle unused transmit buffer
46577799ccaSWu Mianzhi         buffer.free_buffer();
46677799ccaSWu Mianzhi         // Set the transmit descriptor
46777799ccaSWu Mianzhi         desc.addr = packet.as_paddr() as u64;
46877799ccaSWu Mianzhi         desc.len = packet.len() as u16;
46977799ccaSWu Mianzhi         desc.status = 0;
47077799ccaSWu Mianzhi         desc.cmd = E1000E_TXD_CMD_EOP | E1000E_TXD_CMD_RS | E1000E_TXD_CMD_IFCS;
47177799ccaSWu Mianzhi         tdt = (tdt + 1) % self.trans_desc_ring.len();
47277799ccaSWu Mianzhi         unsafe { volwrite!(self.transimit_regs, tdt0, tdt as u32) };
47377799ccaSWu Mianzhi         self.first_trans = false;
47477799ccaSWu Mianzhi     }
mac_address(&self) -> [u8; 6]47577799ccaSWu Mianzhi     pub fn mac_address(&self) -> [u8; 6] {
47677799ccaSWu Mianzhi         return self.mac;
47777799ccaSWu Mianzhi     }
47877799ccaSWu Mianzhi     // 向ICR寄存器中的某一bit写入1b表示该中断已经被接收,同时会清空该位
47977799ccaSWu Mianzhi     // we need to clear ICR to tell e1000e we have read the interrupt
e1000e_intr(&mut self)48077799ccaSWu Mianzhi     pub fn e1000e_intr(&mut self) {
48177799ccaSWu Mianzhi         let icr = unsafe { volread!(self.interrupt_regs, icr) };
48277799ccaSWu Mianzhi         // write 1b to any bit in ICR will clear the bit
48377799ccaSWu Mianzhi         unsafe { volwrite!(self.interrupt_regs, icr, icr) };
48477799ccaSWu Mianzhi     }
48577799ccaSWu Mianzhi 
48677799ccaSWu Mianzhi     // 切换是否接受分组到达的中断
48777799ccaSWu Mianzhi     // change whether the receive timer interrupt is enabled
48877799ccaSWu Mianzhi     // Note: this method is not completely implemented and not used in the current version
489971462beSGnoCiYeH     #[allow(dead_code)]
e1000e_intr_set(&mut self, state: bool)49077799ccaSWu Mianzhi     pub fn e1000e_intr_set(&mut self, state: bool) {
49177799ccaSWu Mianzhi         let mut ims = unsafe { volread!(self.interrupt_regs, ims) };
49277799ccaSWu Mianzhi         match state {
493b5b571e0SLoGin             true => ims |= E1000E_IMS_RXT0,
494b5b571e0SLoGin             false => ims &= !E1000E_IMS_RXT0,
49577799ccaSWu Mianzhi         }
49677799ccaSWu Mianzhi         unsafe { volwrite!(self.interrupt_regs, ims, ims) };
49777799ccaSWu Mianzhi     }
49877799ccaSWu Mianzhi 
49977799ccaSWu Mianzhi     // 实现了一部分napi机制的收包函数, 现在还没有投入使用
50077799ccaSWu Mianzhi     // This method is a partial implementation of napi (New API) techniques
50177799ccaSWu Mianzhi     // Note: this method is not completely implemented and not used in the current version
502971462beSGnoCiYeH     #[allow(dead_code)]
e1000e_receive2(&mut self) -> Option<E1000EBuffer>50377799ccaSWu Mianzhi     pub fn e1000e_receive2(&mut self) -> Option<E1000EBuffer> {
50477799ccaSWu Mianzhi         // 向设备表明我们已经接受到了之前的中断
50577799ccaSWu Mianzhi         // Tell e1000e we have received the interrupt
50677799ccaSWu Mianzhi         self.e1000e_intr();
50777799ccaSWu Mianzhi         // 如果napi队列不存在已经收到的分组...
50877799ccaSWu Mianzhi         // if napi queue is empty...
50977799ccaSWu Mianzhi         if self.napi_buffer_empty {
51077799ccaSWu Mianzhi             // 暂时关闭设备中断
51177799ccaSWu Mianzhi             // close interrupt
51277799ccaSWu Mianzhi             self.e1000e_intr_set(false);
51377799ccaSWu Mianzhi             loop {
514b5b571e0SLoGin                 if self.napi_buffer_tail == self.napi_buffer_head && !self.napi_buffer_empty {
51577799ccaSWu Mianzhi                     // napi缓冲队列已满,停止收包
51677799ccaSWu Mianzhi                     // napi queue is full, stop
51777799ccaSWu Mianzhi                     break;
51877799ccaSWu Mianzhi                 }
51977799ccaSWu Mianzhi                 match self.e1000e_receive() {
52077799ccaSWu Mianzhi                     Some(buffer) => {
52177799ccaSWu Mianzhi                         self.napi_buffers[self.napi_buffer_tail] = buffer;
52277799ccaSWu Mianzhi                         self.napi_buffer_tail = (self.napi_buffer_tail + 1) % E1000E_RECV_NAPI;
52377799ccaSWu Mianzhi                         self.napi_buffer_empty = false;
52477799ccaSWu Mianzhi                     }
52577799ccaSWu Mianzhi                     None => {
52677799ccaSWu Mianzhi                         // 设备队列中没有剩余的已到达的数据包
52777799ccaSWu Mianzhi                         // no packet remains in the device buffer
52877799ccaSWu Mianzhi                         break;
52977799ccaSWu Mianzhi                     }
53077799ccaSWu Mianzhi                 };
53177799ccaSWu Mianzhi             }
53277799ccaSWu Mianzhi             // 重新打开设备中断
53377799ccaSWu Mianzhi             // open the interrupt
53477799ccaSWu Mianzhi             self.e1000e_intr_set(true);
53577799ccaSWu Mianzhi         }
53677799ccaSWu Mianzhi 
53777799ccaSWu Mianzhi         let result = self.napi_buffers[self.napi_buffer_head];
53877799ccaSWu Mianzhi         match result.len() {
53977799ccaSWu Mianzhi             0 => {
54077799ccaSWu Mianzhi                 // napi队列和网卡队列中都不存在数据包
54177799ccaSWu Mianzhi                 // both napi queue and device buffer is empty, no packet will receive
54277799ccaSWu Mianzhi                 return None;
54377799ccaSWu Mianzhi             }
54477799ccaSWu Mianzhi             _ => {
54577799ccaSWu Mianzhi                 // 有剩余的已到达的数据包
54677799ccaSWu Mianzhi                 // there is packet in napi queue
54777799ccaSWu Mianzhi                 self.napi_buffer_head = (self.napi_buffer_head + 1) % E1000E_RECV_NAPI;
54877799ccaSWu Mianzhi                 if self.napi_buffer_head == self.napi_buffer_tail {
54977799ccaSWu Mianzhi                     self.napi_buffer_empty = true;
55077799ccaSWu Mianzhi                 }
55177799ccaSWu Mianzhi                 return Some(result);
55277799ccaSWu Mianzhi             }
55377799ccaSWu Mianzhi         }
55477799ccaSWu Mianzhi     }
55577799ccaSWu Mianzhi }
55677799ccaSWu Mianzhi 
55777799ccaSWu Mianzhi impl Drop for E1000EDevice {
drop(&mut self)55877799ccaSWu Mianzhi     fn drop(&mut self) {
55977799ccaSWu Mianzhi         // 释放已分配的所有dma页
56077799ccaSWu Mianzhi         // free all dma pages we have allocated
5612eab6dd7S曾俊         debug!("droping...");
56277799ccaSWu Mianzhi         let recv_ring_length = PAGE_SIZE / size_of::<E1000ERecvDesc>();
56377799ccaSWu Mianzhi         let trans_ring_length = PAGE_SIZE / size_of::<E1000ETransDesc>();
56477799ccaSWu Mianzhi         unsafe {
56577799ccaSWu Mianzhi             // 释放所有buffer中的dma页
56677799ccaSWu Mianzhi             // free all dma pages in buffers
56777799ccaSWu Mianzhi             for i in 0..recv_ring_length {
56877799ccaSWu Mianzhi                 self.recv_buffers[i].free_buffer();
56977799ccaSWu Mianzhi             }
57077799ccaSWu Mianzhi             for i in 0..trans_ring_length {
57177799ccaSWu Mianzhi                 self.trans_buffers[i].free_buffer();
57277799ccaSWu Mianzhi             }
57377799ccaSWu Mianzhi             // 释放descriptor ring
57477799ccaSWu Mianzhi             // free descriptor ring
57577799ccaSWu Mianzhi             dma_dealloc(
57677799ccaSWu Mianzhi                 self.recv_ring_pa,
57777799ccaSWu Mianzhi                 NonNull::new(self.recv_desc_ring).unwrap().cast(),
57877799ccaSWu Mianzhi                 E1000E_DMA_PAGES,
57977799ccaSWu Mianzhi             );
58077799ccaSWu Mianzhi             dma_dealloc(
58177799ccaSWu Mianzhi                 self.trans_ring_pa,
58277799ccaSWu Mianzhi                 NonNull::new(self.trans_desc_ring).unwrap().cast(),
58377799ccaSWu Mianzhi                 E1000E_DMA_PAGES,
58477799ccaSWu Mianzhi             );
58577799ccaSWu Mianzhi         }
58677799ccaSWu Mianzhi     }
58777799ccaSWu Mianzhi }
58877799ccaSWu Mianzhi 
e1000e_init()589b5b571e0SLoGin pub fn e1000e_init() {
59077799ccaSWu Mianzhi     match e1000e_probe() {
5918d72b68dSJomo         Ok(_code) => {
5922eab6dd7S曾俊             info!("Successfully init e1000e device!");
5938d72b68dSJomo         }
5948d72b68dSJomo         Err(_error) => {
5952eab6dd7S曾俊             info!("Error occurred!");
5968d72b68dSJomo         }
59777799ccaSWu Mianzhi     }
59877799ccaSWu Mianzhi }
59977799ccaSWu Mianzhi 
e1000e_probe() -> Result<u64, E1000EPciError>60077799ccaSWu Mianzhi pub fn e1000e_probe() -> Result<u64, E1000EPciError> {
60177799ccaSWu Mianzhi     let mut list = PCI_DEVICE_LINKEDLIST.write();
60277799ccaSWu Mianzhi     let result = get_pci_device_structure_mut(&mut list, NETWORK_CLASS, ETHERNET_SUBCLASS);
60377799ccaSWu Mianzhi     if result.is_empty() {
60477799ccaSWu Mianzhi         return Ok(0);
60577799ccaSWu Mianzhi     }
60677799ccaSWu Mianzhi     for device in result {
60777799ccaSWu Mianzhi         let standard_device = device.as_standard_device_mut().unwrap();
60877799ccaSWu Mianzhi         let header = &standard_device.common_header;
60977799ccaSWu Mianzhi         if header.vendor_id == 0x8086 {
61077799ccaSWu Mianzhi             // intel
61177799ccaSWu Mianzhi             if E1000E_DEVICE_ID.contains(&header.device_id) {
6122eab6dd7S曾俊                 debug!(
61377799ccaSWu Mianzhi                     "Detected e1000e PCI device with device id {:#x}",
61477799ccaSWu Mianzhi                     header.device_id
61577799ccaSWu Mianzhi                 );
616e2841179SLoGin 
617e2841179SLoGin                 // todo: 根据pci的path来生成device id
618e2841179SLoGin                 let e1000e = E1000EDevice::new(
619e2841179SLoGin                     standard_device,
620e2841179SLoGin                     DeviceId::new(None, Some(format!("e1000e_{}", header.device_id))).unwrap(),
621e2841179SLoGin                 )?;
62277799ccaSWu Mianzhi                 e1000e_driver_init(e1000e);
62377799ccaSWu Mianzhi             }
62477799ccaSWu Mianzhi         }
62577799ccaSWu Mianzhi     }
62677799ccaSWu Mianzhi 
62777799ccaSWu Mianzhi     return Ok(1);
62877799ccaSWu Mianzhi }
62977799ccaSWu Mianzhi 
63077799ccaSWu Mianzhi // 用到的e1000e寄存器结构体
63177799ccaSWu Mianzhi // pp.275, Table 13-3
63277799ccaSWu Mianzhi // 设备通用寄存器
633971462beSGnoCiYeH #[allow(dead_code)]
63477799ccaSWu Mianzhi struct GeneralRegs {
63577799ccaSWu Mianzhi     ctrl: Volatile<u32>,         //0x00000
63677799ccaSWu Mianzhi     ctrl_alias: Volatile<u32>,   //0x00004
63777799ccaSWu Mianzhi     status: ReadOnly<u32>,       //0x00008
63877799ccaSWu Mianzhi     status_align: ReadOnly<u32>, //0x0000c
63977799ccaSWu Mianzhi     eec: Volatile<u32>,          //0x00010
64077799ccaSWu Mianzhi     eerd: Volatile<u32>,         //0x00014
64177799ccaSWu Mianzhi     ctrl_ext: Volatile<u32>,     //0x00018
64277799ccaSWu Mianzhi     fla: Volatile<u32>,          //0x0001c
64377799ccaSWu Mianzhi     mdic: Volatile<u32>,         //0x00020
64477799ccaSWu Mianzhi }
64577799ccaSWu Mianzhi // 中断控制
646971462beSGnoCiYeH #[allow(dead_code)]
64777799ccaSWu Mianzhi struct InterruptRegs {
64877799ccaSWu Mianzhi     icr: Volatile<u32>, //0x000c0 ICR寄存器应当为只读寄存器,但我们需要向其中写入来清除对应位
64977799ccaSWu Mianzhi     itr: Volatile<u32>, //0x000c4
65077799ccaSWu Mianzhi     ics: WriteOnly<u32>, //0x000c8
65177799ccaSWu Mianzhi     ics_align: ReadOnly<u32>, //0x000cc
65277799ccaSWu Mianzhi     ims: Volatile<u32>, //0x000d0
65377799ccaSWu Mianzhi     ims_align: ReadOnly<u32>, //0x000d4
65477799ccaSWu Mianzhi     imc: WriteOnly<u32>, //0x000d8
65577799ccaSWu Mianzhi }
65677799ccaSWu Mianzhi // 收包功能控制
65777799ccaSWu Mianzhi struct ReceiveCtrlRegs {
65877799ccaSWu Mianzhi     rctl: Volatile<u32>, //0x00100
65977799ccaSWu Mianzhi }
66077799ccaSWu Mianzhi // 发包功能控制
661971462beSGnoCiYeH #[allow(dead_code)]
66277799ccaSWu Mianzhi struct TransmitCtrlRegs {
66377799ccaSWu Mianzhi     tctl: Volatile<u32>,     //0x00400
66477799ccaSWu Mianzhi     tctl_ext: Volatile<u32>, //0x00404
66577799ccaSWu Mianzhi     unused_1: ReadOnly<u32>, //0x00408
66677799ccaSWu Mianzhi     unused_2: ReadOnly<u32>, //0x0040c
66777799ccaSWu Mianzhi     tipg: Volatile<u32>,     //0x00410
66877799ccaSWu Mianzhi }
66977799ccaSWu Mianzhi // 收包功能相关
670971462beSGnoCiYeH #[allow(dead_code)]
67177799ccaSWu Mianzhi struct ReceiveRegs {
67277799ccaSWu Mianzhi     rdbal0: Volatile<u32>,     //0x02800
67377799ccaSWu Mianzhi     rdbah0: Volatile<u32>,     //0x02804
67477799ccaSWu Mianzhi     rdlen0: Volatile<u32>,     //0x02808
67577799ccaSWu Mianzhi     rdl_align: ReadOnly<u32>,  //0x0280c
67677799ccaSWu Mianzhi     rdh0: Volatile<u32>,       //0x02810
67777799ccaSWu Mianzhi     rdh_align: ReadOnly<u32>,  //0x02814
67877799ccaSWu Mianzhi     rdt0: Volatile<u32>,       //0x02818
67977799ccaSWu Mianzhi     rdt_align: ReadOnly<u32>,  //0x281c
68077799ccaSWu Mianzhi     rdtr: Volatile<u32>,       //0x2820
68177799ccaSWu Mianzhi     rdtr_align: ReadOnly<u32>, //0x2824
68277799ccaSWu Mianzhi     rxdctl: Volatile<u32>,     //0x2828
68377799ccaSWu Mianzhi }
68477799ccaSWu Mianzhi // 发包功能相关
685971462beSGnoCiYeH #[allow(dead_code)]
68677799ccaSWu Mianzhi struct TransimitRegs {
68777799ccaSWu Mianzhi     tdbal0: Volatile<u32>,      //0x03800
68877799ccaSWu Mianzhi     tdbah0: Volatile<u32>,      //0x03804
68977799ccaSWu Mianzhi     tdlen0: Volatile<u32>,      //0x03808
69077799ccaSWu Mianzhi     tdlen_algin: ReadOnly<u32>, //0x0380c
69177799ccaSWu Mianzhi     tdh0: Volatile<u32>,        //0x03810
69277799ccaSWu Mianzhi     tdh_align: ReadOnly<u32>,   //0x03814
69377799ccaSWu Mianzhi     tdt0: Volatile<u32>,        //0x03818
69477799ccaSWu Mianzhi     tdt_align: ReadOnly<u32>,   //0x0381c
69577799ccaSWu Mianzhi     tidv: Volatile<u32>,        //0x03820
69677799ccaSWu Mianzhi     tidv_align: ReadOnly<u32>,  //0x03824
69777799ccaSWu Mianzhi     txdctl: Volatile<u32>,      //0x03828
69877799ccaSWu Mianzhi     tadv: Volatile<u32>,        //0x0382c
69977799ccaSWu Mianzhi }
70077799ccaSWu Mianzhi // mac地址
70177799ccaSWu Mianzhi struct ReceiveAddressRegs {
70277799ccaSWu Mianzhi     ral0: Volatile<u32>, //0x05400
70377799ccaSWu Mianzhi     rah0: Volatile<u32>, //0x05404
70477799ccaSWu Mianzhi }
70577799ccaSWu Mianzhi // PCIe 通用控制
70677799ccaSWu Mianzhi struct PCIeRegs {
70777799ccaSWu Mianzhi     gcr: Volatile<u32>, //0x05b00
70877799ccaSWu Mianzhi }
709971462beSGnoCiYeH #[allow(dead_code)]
71077799ccaSWu Mianzhi struct StatisticsRegs {}
71177799ccaSWu Mianzhi 
71277799ccaSWu Mianzhi // 0x05200-0x053fc
71377799ccaSWu Mianzhi // 在Receive Initialization 中按照每次一个32bit寄存器的方式来遍历
71477799ccaSWu Mianzhi // Multicast Table Array Registers will be written per 32bit
71577799ccaSWu Mianzhi struct MTARegs {
71677799ccaSWu Mianzhi     mta: Volatile<u32>,
71777799ccaSWu Mianzhi }
71877799ccaSWu Mianzhi 
71977799ccaSWu Mianzhi const E1000E_GENERAL_REGS_OFFSET: u64 = 0x00000;
72077799ccaSWu Mianzhi const E1000E_INTERRRUPT_REGS_OFFSET: u64 = 0x000c0;
72177799ccaSWu Mianzhi const E1000E_RECEIVE_CTRL_REG_OFFSET: u64 = 0x00100;
72277799ccaSWu Mianzhi const E1000E_RECEIVE_REGS_OFFSET: u64 = 0x02800;
72377799ccaSWu Mianzhi const E1000E_TRANSMIT_CTRL_REG_OFFSET: u64 = 0x00400;
72477799ccaSWu Mianzhi const E1000E_TRANSMIT_REGS_OFFSET: u64 = 0x03800;
72577799ccaSWu Mianzhi const E1000E_RECEIVE_ADDRESS_REGS_OFFSET: u64 = 0x05400;
72677799ccaSWu Mianzhi const E1000E_PCIE_REGS_OFFSET: u64 = 0x05b00;
72777799ccaSWu Mianzhi const E1000E_MTA_REGS_START_OFFSET: u64 = 0x05200;
72877799ccaSWu Mianzhi const E1000E_MTA_REGS_END_OFFSET: u64 = 0x053fc;
72977799ccaSWu Mianzhi // 寄存器的特定位
73077799ccaSWu Mianzhi //CTRL
73177799ccaSWu Mianzhi const E1000E_CTRL_SLU: u32 = 1 << 6;
73277799ccaSWu Mianzhi const E1000E_CTRL_FRCSPD: u32 = 1 << 11;
73377799ccaSWu Mianzhi const E1000E_CTRL_FRCDPLX: u32 = 1 << 12;
73477799ccaSWu Mianzhi const E1000E_CTRL_RST: u32 = 1 << 26;
735971462beSGnoCiYeH #[allow(dead_code)]
73677799ccaSWu Mianzhi const E1000E_CTRL_RFCE: u32 = 1 << 27;
737971462beSGnoCiYeH #[allow(dead_code)]
73877799ccaSWu Mianzhi const E1000E_CTRL_TFCE: u32 = 1 << 28;
73977799ccaSWu Mianzhi const E1000E_CTRL_PHY_RST: u32 = 1 << 31;
74077799ccaSWu Mianzhi 
74177799ccaSWu Mianzhi // IMS
74277799ccaSWu Mianzhi const E1000E_IMS_LSC: u32 = 1 << 2;
74377799ccaSWu Mianzhi const E1000E_IMS_RXDMT0: u32 = 1 << 4;
744971462beSGnoCiYeH #[allow(dead_code)]
74577799ccaSWu Mianzhi const E1000E_IMS_RXO: u32 = 1 << 6;
74677799ccaSWu Mianzhi const E1000E_IMS_RXT0: u32 = 1 << 7;
747971462beSGnoCiYeH #[allow(dead_code)]
74877799ccaSWu Mianzhi const E1000E_IMS_RXQ0: u32 = 1 << 20;
74977799ccaSWu Mianzhi const E1000E_IMS_OTHER: u32 = 1 << 24; // qemu use this bit to set msi-x interrupt
75077799ccaSWu Mianzhi 
75177799ccaSWu Mianzhi // IMC
75277799ccaSWu Mianzhi const E1000E_IMC_CLEAR: u32 = 0xffffffff;
75377799ccaSWu Mianzhi 
75477799ccaSWu Mianzhi // RCTL
75577799ccaSWu Mianzhi const E1000E_RCTL_EN: u32 = 1 << 1;
75677799ccaSWu Mianzhi const E1000E_RCTL_BAM: u32 = 1 << 15;
75777799ccaSWu Mianzhi const E1000E_RCTL_BSIZE_4K: u32 = 3 << 16;
75877799ccaSWu Mianzhi const E1000E_RCTL_BSEX: u32 = 1 << 25;
75977799ccaSWu Mianzhi const E1000E_RCTL_SECRC: u32 = 1 << 26;
76077799ccaSWu Mianzhi 
76177799ccaSWu Mianzhi // TCTL
76277799ccaSWu Mianzhi const E1000E_TCTL_EN: u32 = 1 << 1;
76377799ccaSWu Mianzhi const E1000E_TCTL_PSP: u32 = 1 << 3;
76477799ccaSWu Mianzhi const E1000E_TCTL_CT_VAL: u32 = 0x0f << 4; // suggested 16d collision, 手册建议值:16d
76577799ccaSWu Mianzhi const E1000E_TCTL_COLD_VAL: u32 = 0x03f << 12; // suggested 64 byte time for Full-Duplex, 手册建议值:64
76677799ccaSWu Mianzhi                                                // TXDCTL
76777799ccaSWu Mianzhi const E1000E_TXDCTL_WTHRESH: u32 = 1 << 16;
76877799ccaSWu Mianzhi const E1000E_TXDCTL_GRAN: u32 = 1 << 24;
76977799ccaSWu Mianzhi // TIPG
77077799ccaSWu Mianzhi const E1000E_TIPG_IPGT: u32 = 8;
77177799ccaSWu Mianzhi const E1000E_TIPG_IPGR1: u32 = 2 << 10;
77277799ccaSWu Mianzhi const E1000E_TIPG_IPGR2: u32 = 10 << 20;
77377799ccaSWu Mianzhi 
77477799ccaSWu Mianzhi // RxDescriptorStatus
77577799ccaSWu Mianzhi const E1000E_RXD_STATUS_DD: u16 = 1 << 0;
77677799ccaSWu Mianzhi 
77777799ccaSWu Mianzhi // TxDescriptorStatus
77877799ccaSWu Mianzhi const E1000E_TXD_STATUS_DD: u8 = 1 << 0;
77977799ccaSWu Mianzhi const E1000E_TXD_CMD_EOP: u8 = 1 << 0;
78077799ccaSWu Mianzhi const E1000E_TXD_CMD_IFCS: u8 = 1 << 1;
78177799ccaSWu Mianzhi const E1000E_TXD_CMD_RS: u8 = 1 << 3;
78277799ccaSWu Mianzhi 
783*bd70d2d1SLoGin /// E1000E驱动初始化过程中可能的错误
784*bd70d2d1SLoGin #[allow(dead_code)]
78577799ccaSWu Mianzhi pub enum E1000EPciError {
78677799ccaSWu Mianzhi     // 获取到错误类型的BAR(IO BAR)
78777799ccaSWu Mianzhi     // An IO BAR was provided rather than a memory BAR.
78877799ccaSWu Mianzhi     UnexpectedBarType,
78977799ccaSWu Mianzhi     // 获取的BAR没有被分配到某个地址(address == 0)
79077799ccaSWu Mianzhi     // A BAR which we need was not allocated an address(address == 0).
79177799ccaSWu Mianzhi     BarNotAllocated,
79277799ccaSWu Mianzhi     //获取虚拟地址失败
79377799ccaSWu Mianzhi     BarGetVaddrFailed,
79477799ccaSWu Mianzhi     // 没有对应的BAR或者获取BAR失败
79577799ccaSWu Mianzhi     BarGetFailed,
79677799ccaSWu Mianzhi     // BAR的大小与预期不符(128KB)
79777799ccaSWu Mianzhi     // Size of BAR is not 128KB
79877799ccaSWu Mianzhi     UnexpectedBarSize,
79977799ccaSWu Mianzhi     Pci(PciError),
80077799ccaSWu Mianzhi }
80177799ccaSWu Mianzhi 
80277799ccaSWu Mianzhi /// PCI error到VirtioPciError的转换,层层上报
80377799ccaSWu Mianzhi impl From<PciError> for E1000EPciError {
from(error: PciError) -> Self80477799ccaSWu Mianzhi     fn from(error: PciError) -> Self {
80577799ccaSWu Mianzhi         Self::Pci(error)
80677799ccaSWu Mianzhi     }
80777799ccaSWu Mianzhi }
80877799ccaSWu Mianzhi 
80977799ccaSWu Mianzhi /**
81077799ccaSWu Mianzhi  * @brief 获取基地址的某个偏移量的指针,用于在mmio bar中构造寄存器结构体
81177799ccaSWu Mianzhi  * @brief used for build register struct in mmio bar
81277799ccaSWu Mianzhi  * @param vaddr: base address (in virtual memory)
81377799ccaSWu Mianzhi  * @param offset: offset
81477799ccaSWu Mianzhi  */
get_register_ptr<T>(vaddr: u64, offset: u64) -> NonNull<T>81577799ccaSWu Mianzhi fn get_register_ptr<T>(vaddr: u64, offset: u64) -> NonNull<T> {
81677799ccaSWu Mianzhi     NonNull::new((vaddr + offset) as *mut T).unwrap()
81777799ccaSWu Mianzhi }
818