// 参考手册: PCIe* GbE Controllers Open Source Software Developer’s Manual // Refernce: PCIe* GbE Controllers Open Source Software Developer’s Manual use alloc::string::ToString; use alloc::sync::Arc; use alloc::vec::Vec; use core::intrinsics::unlikely; use core::mem::size_of; use core::ptr::NonNull; use core::slice::{from_raw_parts, from_raw_parts_mut}; use core::sync::atomic::{compiler_fence, Ordering}; use log::{debug, info}; use super::e1000e_driver::e1000e_driver_init; use crate::driver::base::device::DeviceId; use crate::driver::net::dma::{dma_alloc, dma_dealloc}; use crate::driver::net::irq_handle::DefaultNetIrqHandler; use crate::driver::pci::pci::{ get_pci_device_structure_mut, PciDeviceStructure, PciDeviceStructureGeneralDevice, PciError, PCI_DEVICE_LINKEDLIST, }; use crate::driver::pci::pci_irq::{IrqCommonMsg, IrqSpecificMsg, PciInterrupt, PciIrqMsg, IRQ}; use crate::exception::IrqNumber; use crate::libs::volatile::{ReadOnly, Volatile, WriteOnly}; const PAGE_SIZE: usize = 4096; const NETWORK_CLASS: u8 = 0x2; const ETHERNET_SUBCLASS: u8 = 0x0; // e1000e系列网卡的device id列表,来源:https://admin.pci-ids.ucw.cz/read/PC/8086 const E1000E_DEVICE_ID: [u16; 14] = [ 0x10d3, // 8574L, qemu default 0x10cc, // 82567LM-2 0x10cd, // 82567LF-2 0x105f, // 82571EB 0x1060, // 82571EB 0x107f, // 82572EI 0x109a, // 82573L 0x10ea, // 82577LM 0x10eb, // 82577LC 0x10ef, // 82578DM 0x10f0, // 82578DC 0x1502, // 82579LM 0x1503, // 82579V 0x150c, // 82583V ]; // e1000e网卡与BAR有关的常量 // BAR0空间大小(128KB) const E1000E_BAR_REG_SIZE: u32 = 128 * 1024; // BAR0空间对齐(64bit) #[allow(dead_code)] const E1000E_BAR_REG_ALIGN: u8 = 64; // 单个寄存器大小(32bit, 4字节) #[allow(dead_code)] const E1000E_REG_SIZE: u8 = 4; // TxBuffer和RxBuffer的大小(DMA页) const E1000E_DMA_PAGES: usize = 1; // 中断相关 const E1000E_RECV_VECTOR: IrqNumber = IrqNumber::new(57); // napi队列中暂时存储的buffer个数 const E1000E_RECV_NAPI: usize = 1024; // 收/发包的描述符结构 pp.24 Table 3-1 #[repr(C)] #[derive(Copy, Clone, Debug)] struct E1000ETransDesc { addr: u64, len: u16, cso: u8, cmd: u8, status: u8, css: u8, special: u8, } // pp.54 Table 3-12 #[repr(C)] #[derive(Copy, Clone, Debug)] struct E1000ERecvDesc { addr: u64, len: u16, chksum: u16, status: u16, error: u8, special: u8, } #[derive(Copy, Clone)] // Buffer的Copy只是指针操作,不涉及实际数据的复制,因此要小心使用,确保不同的buffer不会使用同一块内存 pub struct E1000EBuffer { buffer: NonNull, paddr: usize, // length字段为0则表示这个buffer是一个占位符,不指向实际内存 // the buffer is empty and no page is allocated if length field is set 0 length: usize, } impl E1000EBuffer { pub fn new(length: usize) -> Self { assert!(length <= PAGE_SIZE); if unlikely(length == 0) { // 在某些情况下,我们并不需要实际分配buffer,只需要提供一个占位符即可 // we dont need to allocate dma pages for buffer in some cases E1000EBuffer { buffer: NonNull::dangling(), paddr: 0, length: 0, } } else { let (paddr, vaddr) = dma_alloc(E1000E_DMA_PAGES); E1000EBuffer { buffer: vaddr, paddr, length, } } } #[allow(dead_code)] pub fn as_addr(&self) -> NonNull { assert!(self.length != 0); return self.buffer; } #[allow(dead_code)] pub fn as_addr_u64(&self) -> u64 { assert!(self.length != 0); return self.buffer.as_ptr() as u64; } pub fn as_paddr(&self) -> usize { assert!(self.length != 0); return self.paddr; } #[allow(dead_code)] pub fn as_slice(&self) -> &[u8] { assert!(self.length != 0); return unsafe { from_raw_parts(self.buffer.as_ptr(), self.length) }; } pub fn as_mut_slice(&mut self) -> &mut [u8] { assert!(self.length != 0); return unsafe { from_raw_parts_mut(self.buffer.as_ptr(), self.length) }; } pub fn set_length(&mut self, length: usize) { self.length = length; } pub fn len(&self) -> usize { return self.length; } // 释放buffer内部的dma_pages,需要小心使用 pub fn free_buffer(self) { if self.length != 0 { unsafe { dma_dealloc(self.paddr, self.buffer, E1000E_DMA_PAGES) }; } } } #[allow(dead_code)] pub struct E1000EDevice { // 设备寄存器 // device registers general_regs: NonNull, interrupt_regs: NonNull, rctl_regs: NonNull, receive_regs: NonNull, tctl_regs: NonNull, transimit_regs: NonNull, pcie_regs: NonNull, // descriptor环形队列,在操作系统与设备之间共享 // descriptor rings are shared between os and device recv_desc_ring: &'static mut [E1000ERecvDesc], trans_desc_ring: &'static mut [E1000ETransDesc], recv_ring_pa: usize, trans_ring_pa: usize, // 设备收/发包缓冲区数组 // buffers of receive/transmit packets recv_buffers: Vec, trans_buffers: Vec, mac: [u8; 6], first_trans: bool, // napi队列,用于存放在中断关闭期间通过轮询收取的buffer // the napi queue is designed to save buffer/packet when the interrupt is close // NOTE: this feature is not completely implemented and not used in the current version napi_buffers: Vec, napi_buffer_head: usize, napi_buffer_tail: usize, napi_buffer_empty: bool, } impl E1000EDevice { // 从PCI标准设备进行驱动初始化 // init the device for PCI standard device struct #[allow(unused_assignments)] pub fn new( device: &mut PciDeviceStructureGeneralDevice, device_id: Arc, ) -> Result { // 从BAR0获取我们需要的寄存器 // Build registers sturcts from BAR0 device.bar_ioremap().unwrap()?; device.enable_master(); let bar = device.bar().ok_or(E1000EPciError::BarGetFailed)?; let bar0 = bar.get_bar(0)?; let (address, size) = bar0 .memory_address_size() .ok_or(E1000EPciError::UnexpectedBarType)?; if address == 0 { return Err(E1000EPciError::BarNotAllocated); } if size != E1000E_BAR_REG_SIZE { return Err(E1000EPciError::UnexpectedBarSize); } let vaddress = bar0 .virtual_address() .ok_or(E1000EPciError::BarGetVaddrFailed)? .data() as u64; // 初始化msi中断 // initialize msi interupt let irq_vector = device.irq_vector_mut().unwrap(); irq_vector.push(E1000E_RECV_VECTOR); device.irq_init(IRQ::PCI_IRQ_MSI).expect("IRQ Init Failed"); let msg = PciIrqMsg { irq_common_message: IrqCommonMsg::init_from( 0, "E1000E_RECV_IRQ".to_string(), &DefaultNetIrqHandler, device_id, ), irq_specific_message: IrqSpecificMsg::msi_default(), }; device.irq_install(msg)?; device.irq_enable(true)?; let general_regs: NonNull = get_register_ptr(vaddress, E1000E_GENERAL_REGS_OFFSET); let interrupt_regs: NonNull = get_register_ptr(vaddress, E1000E_INTERRRUPT_REGS_OFFSET); let rctl_regs: NonNull = get_register_ptr(vaddress, E1000E_RECEIVE_CTRL_REG_OFFSET); let receive_regs: NonNull = get_register_ptr(vaddress, E1000E_RECEIVE_REGS_OFFSET); let tctl_regs: NonNull = get_register_ptr(vaddress, E1000E_TRANSMIT_CTRL_REG_OFFSET); let transimit_regs: NonNull = get_register_ptr(vaddress, E1000E_TRANSMIT_REGS_OFFSET); let pcie_regs: NonNull = get_register_ptr(vaddress, E1000E_PCIE_REGS_OFFSET); let ra_regs: NonNull = get_register_ptr(vaddress, E1000E_RECEIVE_ADDRESS_REGS_OFFSET); // 开始设备初始化 14.3 // Initialization Sequence unsafe { let mut ctrl = volread!(general_regs, ctrl); // 关闭中断 // close the interrupt volwrite!(interrupt_regs, imc, E1000E_IMC_CLEAR); //SW RESET volwrite!(general_regs, ctrl, ctrl | E1000E_CTRL_RST); compiler_fence(Ordering::AcqRel); // PHY RESET ctrl = volread!(general_regs, ctrl); volwrite!(general_regs, ctrl, ctrl | E1000E_CTRL_PHY_RST); volwrite!(general_regs, ctrl, ctrl); // 关闭中断 // close the interrupt volwrite!(interrupt_regs, imc, E1000E_IMC_CLEAR); let mut gcr = volread!(pcie_regs, gcr); gcr |= 1 << 22; volwrite!(pcie_regs, gcr, gcr); compiler_fence(Ordering::AcqRel); // PHY Initialization 14.8.1 // MAC/PHY Link Setup 14.8.2 ctrl = volread!(general_regs, ctrl); ctrl &= !(E1000E_CTRL_FRCSPD | E1000E_CTRL_FRCDPLX); volwrite!(general_regs, ctrl, ctrl | E1000E_CTRL_SLU); } let status = unsafe { volread!(general_regs, status) }; debug!("Status: {status:#X}"); // 读取设备的mac地址 // Read mac address let ral = unsafe { volread!(ra_regs, ral0) }; let rah = unsafe { volread!(ra_regs, rah0) }; let mac: [u8; 6] = [ (ral & 0xFF) as u8, ((ral >> 8) & 0xFF) as u8, ((ral >> 16) & 0xFF) as u8, ((ral >> 24) & 0xFF) as u8, (rah & 0xFF) as u8, ((rah >> 8) & 0xFF) as u8, ]; // 初始化receive和transimit descriptor环形队列 // initialize receive and transimit desciptor ring let (recv_ring_pa, recv_ring_va) = dma_alloc(E1000E_DMA_PAGES); let (trans_ring_pa, trans_ring_va) = dma_alloc(E1000E_DMA_PAGES); let recv_ring_length = PAGE_SIZE / size_of::(); let trans_ring_length = PAGE_SIZE / size_of::(); let recv_desc_ring = unsafe { from_raw_parts_mut::(recv_ring_va.as_ptr().cast(), recv_ring_length) }; let trans_desc_ring = unsafe { from_raw_parts_mut::(trans_ring_va.as_ptr().cast(), trans_ring_length) }; // 初始化receive和transmit packet的缓冲区 // initialzie receive and transmit buffers let mut recv_buffers: Vec = Vec::with_capacity(recv_ring_length); let mut trans_buffers: Vec = Vec::with_capacity(trans_ring_length); // 初始化缓冲区与descriptor,descriptor 中的addr字典应当指向buffer的物理地址 // Receive buffers of appropriate size should be allocated and pointers to these buffers should be stored in the descriptor ring. for ring in recv_desc_ring.iter_mut().take(recv_ring_length) { let buffer = E1000EBuffer::new(PAGE_SIZE); ring.addr = buffer.as_paddr() as u64; ring.status = 0; recv_buffers.push(buffer); } // Same as receive buffers for ring in trans_desc_ring.iter_mut().take(recv_ring_length) { let buffer = E1000EBuffer::new(PAGE_SIZE); ring.addr = buffer.as_paddr() as u64; ring.status = 1; trans_buffers.push(buffer); } // Receive Initialization 14.6 // Initialzie mutlicast table array to 0b // 初始化MTA,遍历0x05200-0x053FC中每个寄存器,写入0b,一共128个寄存器 let mut mta_adress = vaddress + E1000E_MTA_REGS_START_OFFSET; while mta_adress != vaddress + E1000E_MTA_REGS_END_OFFSET { let mta: NonNull = get_register_ptr(mta_adress, 0); unsafe { volwrite!(mta, mta, 0) }; mta_adress += 4; } // 连续的寄存器读-写操作,放在同一个unsafe块中 unsafe { // 设置descriptor环形队列的基地址 // Program the descriptor base address with the address of the region. volwrite!(receive_regs, rdbal0, (recv_ring_pa) as u32); volwrite!(receive_regs, rdbah0, (recv_ring_pa >> 32) as u32); // 设置descriptor环形队列的长度 // Set the length register to the size of the descriptor ring. volwrite!(receive_regs, rdlen0, PAGE_SIZE as u32); // 设置队列的首尾指针 // Program the head and tail registers volwrite!(receive_regs, rdh0, 0); volwrite!(receive_regs, rdt0, (recv_ring_length - 1) as u32); // 设置控制寄存器的相关功能 14.6.1 // Set the receive control register volwrite!( rctl_regs, rctl, E1000E_RCTL_EN | E1000E_RCTL_BAM | E1000E_RCTL_BSIZE_4K | E1000E_RCTL_BSEX | E1000E_RCTL_SECRC ); // Transmit Initialization 14.7 // 开启发包descriptor的回写功能 // Program the TXDCTL register with the desired TX descriptor write-back policy volwrite!( transimit_regs, txdctl, E1000E_TXDCTL_WTHRESH | E1000E_TXDCTL_GRAN ); // 设置descriptor环形队列的基地址,长度与首尾指针 // Program the descriptor base address with the address of the region volwrite!(transimit_regs, tdbal0, trans_ring_pa as u32); volwrite!(transimit_regs, tdbah0, (trans_ring_pa >> 32) as u32); // Set the length register to the size of the descriptor ring. volwrite!(transimit_regs, tdlen0, PAGE_SIZE as u32); // Program the head and tail registerss volwrite!(transimit_regs, tdh0, 0); volwrite!(transimit_regs, tdt0, 0); // Program the TIPG register volwrite!( tctl_regs, tipg, E1000E_TIPG_IPGT | E1000E_TIPG_IPGR1 | E1000E_TIPG_IPGR2 ); // Program the TCTL register. volwrite!( tctl_regs, tctl, E1000E_TCTL_EN | E1000E_TCTL_PSP | E1000E_TCTL_CT_VAL | E1000E_TCTL_COLD_VAL ); let icr = volread!(interrupt_regs, icr); volwrite!(interrupt_regs, icr, icr); // 开启收包相关的中断 // Enable receive interrupts let mut ims = volread!(interrupt_regs, ims); ims = E1000E_IMS_LSC | E1000E_IMS_RXT0 | E1000E_IMS_RXDMT0 | E1000E_IMS_OTHER; volwrite!(interrupt_regs, ims, ims); } return Ok(E1000EDevice { general_regs, interrupt_regs, rctl_regs, receive_regs, tctl_regs, transimit_regs, pcie_regs, recv_desc_ring, trans_desc_ring, recv_ring_pa, trans_ring_pa, recv_buffers, trans_buffers, mac, first_trans: true, napi_buffers: vec![E1000EBuffer::new(0); E1000E_RECV_NAPI], napi_buffer_head: 0, napi_buffer_tail: 0, napi_buffer_empty: true, }); } pub fn e1000e_receive(&mut self) -> Option { self.e1000e_intr(); let mut rdt = unsafe { volread!(self.receive_regs, rdt0) } as usize; let index = (rdt + 1) % self.recv_desc_ring.len(); let desc = &mut self.recv_desc_ring[index]; if (desc.status & E1000E_RXD_STATUS_DD) == 0 { return None; } let mut buffer = self.recv_buffers[index]; let new_buffer = E1000EBuffer::new(PAGE_SIZE); self.recv_buffers[index] = new_buffer; desc.addr = new_buffer.as_paddr() as u64; buffer.set_length(desc.len as usize); rdt = index; unsafe { volwrite!(self.receive_regs, rdt0, rdt as u32) }; // debug!("e1000e: receive packet"); return Some(buffer); } pub fn e1000e_can_transmit(&self) -> bool { let tdt = unsafe { volread!(self.transimit_regs, tdt0) } as usize; let index = tdt % self.trans_desc_ring.len(); let desc = &self.trans_desc_ring[index]; if (desc.status & E1000E_TXD_STATUS_DD) == 0 { return false; } true } pub fn e1000e_transmit(&mut self, packet: E1000EBuffer) { let mut tdt = unsafe { volread!(self.transimit_regs, tdt0) } as usize; let index = tdt % self.trans_desc_ring.len(); let desc = &mut self.trans_desc_ring[index]; let buffer = self.trans_buffers[index]; self.trans_buffers[index] = packet; // recycle unused transmit buffer buffer.free_buffer(); // Set the transmit descriptor desc.addr = packet.as_paddr() as u64; desc.len = packet.len() as u16; desc.status = 0; desc.cmd = E1000E_TXD_CMD_EOP | E1000E_TXD_CMD_RS | E1000E_TXD_CMD_IFCS; tdt = (tdt + 1) % self.trans_desc_ring.len(); unsafe { volwrite!(self.transimit_regs, tdt0, tdt as u32) }; self.first_trans = false; } pub fn mac_address(&self) -> [u8; 6] { return self.mac; } // 向ICR寄存器中的某一bit写入1b表示该中断已经被接收,同时会清空该位 // we need to clear ICR to tell e1000e we have read the interrupt pub fn e1000e_intr(&mut self) { let icr = unsafe { volread!(self.interrupt_regs, icr) }; // write 1b to any bit in ICR will clear the bit unsafe { volwrite!(self.interrupt_regs, icr, icr) }; } // 切换是否接受分组到达的中断 // change whether the receive timer interrupt is enabled // Note: this method is not completely implemented and not used in the current version #[allow(dead_code)] pub fn e1000e_intr_set(&mut self, state: bool) { let mut ims = unsafe { volread!(self.interrupt_regs, ims) }; match state { true => ims |= E1000E_IMS_RXT0, false => ims &= !E1000E_IMS_RXT0, } unsafe { volwrite!(self.interrupt_regs, ims, ims) }; } // 实现了一部分napi机制的收包函数, 现在还没有投入使用 // This method is a partial implementation of napi (New API) techniques // Note: this method is not completely implemented and not used in the current version #[allow(dead_code)] pub fn e1000e_receive2(&mut self) -> Option { // 向设备表明我们已经接受到了之前的中断 // Tell e1000e we have received the interrupt self.e1000e_intr(); // 如果napi队列不存在已经收到的分组... // if napi queue is empty... if self.napi_buffer_empty { // 暂时关闭设备中断 // close interrupt self.e1000e_intr_set(false); loop { if self.napi_buffer_tail == self.napi_buffer_head && !self.napi_buffer_empty { // napi缓冲队列已满,停止收包 // napi queue is full, stop break; } match self.e1000e_receive() { Some(buffer) => { self.napi_buffers[self.napi_buffer_tail] = buffer; self.napi_buffer_tail = (self.napi_buffer_tail + 1) % E1000E_RECV_NAPI; self.napi_buffer_empty = false; } None => { // 设备队列中没有剩余的已到达的数据包 // no packet remains in the device buffer break; } }; } // 重新打开设备中断 // open the interrupt self.e1000e_intr_set(true); } let result = self.napi_buffers[self.napi_buffer_head]; match result.len() { 0 => { // napi队列和网卡队列中都不存在数据包 // both napi queue and device buffer is empty, no packet will receive return None; } _ => { // 有剩余的已到达的数据包 // there is packet in napi queue self.napi_buffer_head = (self.napi_buffer_head + 1) % E1000E_RECV_NAPI; if self.napi_buffer_head == self.napi_buffer_tail { self.napi_buffer_empty = true; } return Some(result); } } } } impl Drop for E1000EDevice { fn drop(&mut self) { // 释放已分配的所有dma页 // free all dma pages we have allocated debug!("droping..."); let recv_ring_length = PAGE_SIZE / size_of::(); let trans_ring_length = PAGE_SIZE / size_of::(); unsafe { // 释放所有buffer中的dma页 // free all dma pages in buffers for i in 0..recv_ring_length { self.recv_buffers[i].free_buffer(); } for i in 0..trans_ring_length { self.trans_buffers[i].free_buffer(); } // 释放descriptor ring // free descriptor ring dma_dealloc( self.recv_ring_pa, NonNull::new(self.recv_desc_ring).unwrap().cast(), E1000E_DMA_PAGES, ); dma_dealloc( self.trans_ring_pa, NonNull::new(self.trans_desc_ring).unwrap().cast(), E1000E_DMA_PAGES, ); } } } pub fn e1000e_init() { match e1000e_probe() { Ok(_code) => { info!("Successfully init e1000e device!"); } Err(_error) => { info!("Error occurred!"); } } } pub fn e1000e_probe() -> Result { let mut list = PCI_DEVICE_LINKEDLIST.write(); let result = get_pci_device_structure_mut(&mut list, NETWORK_CLASS, ETHERNET_SUBCLASS); if result.is_empty() { return Ok(0); } for device in result { let standard_device = device.as_standard_device_mut().unwrap(); let header = &standard_device.common_header; if header.vendor_id == 0x8086 { // intel if E1000E_DEVICE_ID.contains(&header.device_id) { debug!( "Detected e1000e PCI device with device id {:#x}", header.device_id ); // todo: 根据pci的path来生成device id let e1000e = E1000EDevice::new( standard_device, DeviceId::new(None, Some(format!("e1000e_{}", header.device_id))).unwrap(), )?; e1000e_driver_init(e1000e); } } } return Ok(1); } // 用到的e1000e寄存器结构体 // pp.275, Table 13-3 // 设备通用寄存器 #[allow(dead_code)] struct GeneralRegs { ctrl: Volatile, //0x00000 ctrl_alias: Volatile, //0x00004 status: ReadOnly, //0x00008 status_align: ReadOnly, //0x0000c eec: Volatile, //0x00010 eerd: Volatile, //0x00014 ctrl_ext: Volatile, //0x00018 fla: Volatile, //0x0001c mdic: Volatile, //0x00020 } // 中断控制 #[allow(dead_code)] struct InterruptRegs { icr: Volatile, //0x000c0 ICR寄存器应当为只读寄存器,但我们需要向其中写入来清除对应位 itr: Volatile, //0x000c4 ics: WriteOnly, //0x000c8 ics_align: ReadOnly, //0x000cc ims: Volatile, //0x000d0 ims_align: ReadOnly, //0x000d4 imc: WriteOnly, //0x000d8 } // 收包功能控制 struct ReceiveCtrlRegs { rctl: Volatile, //0x00100 } // 发包功能控制 #[allow(dead_code)] struct TransmitCtrlRegs { tctl: Volatile, //0x00400 tctl_ext: Volatile, //0x00404 unused_1: ReadOnly, //0x00408 unused_2: ReadOnly, //0x0040c tipg: Volatile, //0x00410 } // 收包功能相关 #[allow(dead_code)] struct ReceiveRegs { rdbal0: Volatile, //0x02800 rdbah0: Volatile, //0x02804 rdlen0: Volatile, //0x02808 rdl_align: ReadOnly, //0x0280c rdh0: Volatile, //0x02810 rdh_align: ReadOnly, //0x02814 rdt0: Volatile, //0x02818 rdt_align: ReadOnly, //0x281c rdtr: Volatile, //0x2820 rdtr_align: ReadOnly, //0x2824 rxdctl: Volatile, //0x2828 } // 发包功能相关 #[allow(dead_code)] struct TransimitRegs { tdbal0: Volatile, //0x03800 tdbah0: Volatile, //0x03804 tdlen0: Volatile, //0x03808 tdlen_algin: ReadOnly, //0x0380c tdh0: Volatile, //0x03810 tdh_align: ReadOnly, //0x03814 tdt0: Volatile, //0x03818 tdt_align: ReadOnly, //0x0381c tidv: Volatile, //0x03820 tidv_align: ReadOnly, //0x03824 txdctl: Volatile, //0x03828 tadv: Volatile, //0x0382c } // mac地址 struct ReceiveAddressRegs { ral0: Volatile, //0x05400 rah0: Volatile, //0x05404 } // PCIe 通用控制 struct PCIeRegs { gcr: Volatile, //0x05b00 } #[allow(dead_code)] struct StatisticsRegs {} // 0x05200-0x053fc // 在Receive Initialization 中按照每次一个32bit寄存器的方式来遍历 // Multicast Table Array Registers will be written per 32bit struct MTARegs { mta: Volatile, } const E1000E_GENERAL_REGS_OFFSET: u64 = 0x00000; const E1000E_INTERRRUPT_REGS_OFFSET: u64 = 0x000c0; const E1000E_RECEIVE_CTRL_REG_OFFSET: u64 = 0x00100; const E1000E_RECEIVE_REGS_OFFSET: u64 = 0x02800; const E1000E_TRANSMIT_CTRL_REG_OFFSET: u64 = 0x00400; const E1000E_TRANSMIT_REGS_OFFSET: u64 = 0x03800; const E1000E_RECEIVE_ADDRESS_REGS_OFFSET: u64 = 0x05400; const E1000E_PCIE_REGS_OFFSET: u64 = 0x05b00; const E1000E_MTA_REGS_START_OFFSET: u64 = 0x05200; const E1000E_MTA_REGS_END_OFFSET: u64 = 0x053fc; // 寄存器的特定位 //CTRL const E1000E_CTRL_SLU: u32 = 1 << 6; const E1000E_CTRL_FRCSPD: u32 = 1 << 11; const E1000E_CTRL_FRCDPLX: u32 = 1 << 12; const E1000E_CTRL_RST: u32 = 1 << 26; #[allow(dead_code)] const E1000E_CTRL_RFCE: u32 = 1 << 27; #[allow(dead_code)] const E1000E_CTRL_TFCE: u32 = 1 << 28; const E1000E_CTRL_PHY_RST: u32 = 1 << 31; // IMS const E1000E_IMS_LSC: u32 = 1 << 2; const E1000E_IMS_RXDMT0: u32 = 1 << 4; #[allow(dead_code)] const E1000E_IMS_RXO: u32 = 1 << 6; const E1000E_IMS_RXT0: u32 = 1 << 7; #[allow(dead_code)] const E1000E_IMS_RXQ0: u32 = 1 << 20; const E1000E_IMS_OTHER: u32 = 1 << 24; // qemu use this bit to set msi-x interrupt // IMC const E1000E_IMC_CLEAR: u32 = 0xffffffff; // RCTL const E1000E_RCTL_EN: u32 = 1 << 1; const E1000E_RCTL_BAM: u32 = 1 << 15; const E1000E_RCTL_BSIZE_4K: u32 = 3 << 16; const E1000E_RCTL_BSEX: u32 = 1 << 25; const E1000E_RCTL_SECRC: u32 = 1 << 26; // TCTL const E1000E_TCTL_EN: u32 = 1 << 1; const E1000E_TCTL_PSP: u32 = 1 << 3; const E1000E_TCTL_CT_VAL: u32 = 0x0f << 4; // suggested 16d collision, 手册建议值:16d const E1000E_TCTL_COLD_VAL: u32 = 0x03f << 12; // suggested 64 byte time for Full-Duplex, 手册建议值:64 // TXDCTL const E1000E_TXDCTL_WTHRESH: u32 = 1 << 16; const E1000E_TXDCTL_GRAN: u32 = 1 << 24; // TIPG const E1000E_TIPG_IPGT: u32 = 8; const E1000E_TIPG_IPGR1: u32 = 2 << 10; const E1000E_TIPG_IPGR2: u32 = 10 << 20; // RxDescriptorStatus const E1000E_RXD_STATUS_DD: u16 = 1 << 0; // TxDescriptorStatus const E1000E_TXD_STATUS_DD: u8 = 1 << 0; const E1000E_TXD_CMD_EOP: u8 = 1 << 0; const E1000E_TXD_CMD_IFCS: u8 = 1 << 1; const E1000E_TXD_CMD_RS: u8 = 1 << 3; /// E1000E驱动初始化过程中可能的错误 #[allow(dead_code)] pub enum E1000EPciError { // 获取到错误类型的BAR(IO BAR) // An IO BAR was provided rather than a memory BAR. UnexpectedBarType, // 获取的BAR没有被分配到某个地址(address == 0) // A BAR which we need was not allocated an address(address == 0). BarNotAllocated, //获取虚拟地址失败 BarGetVaddrFailed, // 没有对应的BAR或者获取BAR失败 BarGetFailed, // BAR的大小与预期不符(128KB) // Size of BAR is not 128KB UnexpectedBarSize, Pci(PciError), } /// PCI error到VirtioPciError的转换,层层上报 impl From for E1000EPciError { fn from(error: PciError) -> Self { Self::Pci(error) } } /** * @brief 获取基地址的某个偏移量的指针,用于在mmio bar中构造寄存器结构体 * @brief used for build register struct in mmio bar * @param vaddr: base address (in virtual memory) * @param offset: offset */ fn get_register_ptr(vaddr: u64, offset: u64) -> NonNull { NonNull::new((vaddr + offset) as *mut T).unwrap() }