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 477799ccaSWu Mianzhi use alloc::vec::Vec; 577799ccaSWu Mianzhi use core::intrinsics::unlikely; 677799ccaSWu Mianzhi use core::mem::size_of; 777799ccaSWu Mianzhi use core::ptr::NonNull; 877799ccaSWu Mianzhi use core::slice::{from_raw_parts, from_raw_parts_mut}; 977799ccaSWu Mianzhi use core::sync::atomic::{compiler_fence, Ordering}; 1077799ccaSWu Mianzhi 1177799ccaSWu Mianzhi use super::e1000e_driver::e1000e_driver_init; 1277799ccaSWu Mianzhi use crate::driver::net::dma::{dma_alloc, dma_dealloc}; 1377799ccaSWu Mianzhi use crate::driver::pci::pci::{ 1477799ccaSWu Mianzhi get_pci_device_structure_mut, PciDeviceStructure, PciDeviceStructureGeneralDevice, PciError, 1577799ccaSWu Mianzhi PCI_DEVICE_LINKEDLIST, 1677799ccaSWu Mianzhi }; 1777799ccaSWu Mianzhi use crate::driver::pci::pci_irq::{IrqCommonMsg, IrqMsg, IrqSpecificMsg, PciInterrupt, IRQ}; 1877799ccaSWu Mianzhi use crate::include::bindings::bindings::pt_regs; 19971462beSGnoCiYeH use crate::libs::volatile::{ReadOnly, Volatile, WriteOnly}; 2077799ccaSWu Mianzhi use crate::net::net_core::poll_ifaces_try_lock_onetime; 2177799ccaSWu Mianzhi use crate::{kdebug, kinfo}; 2277799ccaSWu Mianzhi 2377799ccaSWu Mianzhi const PAGE_SIZE: usize = 4096; 2477799ccaSWu Mianzhi const NETWORK_CLASS: u8 = 0x2; 2577799ccaSWu Mianzhi const ETHERNET_SUBCLASS: u8 = 0x0; 2677799ccaSWu Mianzhi // e1000e系列网卡的device id列表,来源:https://admin.pci-ids.ucw.cz/read/PC/8086 2777799ccaSWu Mianzhi const E1000E_DEVICE_ID: [u16; 14] = [ 2877799ccaSWu Mianzhi 0x10d3, // 8574L, qemu default 2977799ccaSWu Mianzhi 0x10cc, // 82567LM-2 3077799ccaSWu Mianzhi 0x10cd, // 82567LF-2 3177799ccaSWu Mianzhi 0x105f, // 82571EB 3277799ccaSWu Mianzhi 0x1060, // 82571EB 3377799ccaSWu Mianzhi 0x107f, // 82572EI 3477799ccaSWu Mianzhi 0x109a, // 82573L 3577799ccaSWu Mianzhi 0x10ea, // 82577LM 3677799ccaSWu Mianzhi 0x10eb, // 82577LC 3777799ccaSWu Mianzhi 0x10ef, // 82578DM 3877799ccaSWu Mianzhi 0x10f0, // 82578DC 3977799ccaSWu Mianzhi 0x1502, // 82579LM 4077799ccaSWu Mianzhi 0x1503, // 82579V 4177799ccaSWu Mianzhi 0x150c, // 82583V 4277799ccaSWu Mianzhi ]; 4377799ccaSWu Mianzhi 4477799ccaSWu Mianzhi // e1000e网卡与BAR有关的常量 4577799ccaSWu Mianzhi // BAR0空间大小(128KB) 4677799ccaSWu Mianzhi const E1000E_BAR_REG_SIZE: u32 = 128 * 1024; 4777799ccaSWu Mianzhi // BAR0空间对齐(64bit) 48971462beSGnoCiYeH #[allow(dead_code)] 4977799ccaSWu Mianzhi const E1000E_BAR_REG_ALIGN: u8 = 64; 5077799ccaSWu Mianzhi // 单个寄存器大小(32bit, 4字节) 51971462beSGnoCiYeH #[allow(dead_code)] 5277799ccaSWu Mianzhi const E1000E_REG_SIZE: u8 = 4; 5377799ccaSWu Mianzhi 5477799ccaSWu Mianzhi // TxBuffer和RxBuffer的大小(DMA页) 5577799ccaSWu Mianzhi const E1000E_DMA_PAGES: usize = 1; 5677799ccaSWu Mianzhi 5777799ccaSWu Mianzhi // 中断相关 5877799ccaSWu Mianzhi const E1000E_RECV_VECTOR: u16 = 57; 5977799ccaSWu Mianzhi 6077799ccaSWu Mianzhi // napi队列中暂时存储的buffer个数 6177799ccaSWu Mianzhi const E1000E_RECV_NAPI: usize = 1024; 6277799ccaSWu Mianzhi 6377799ccaSWu Mianzhi // 收/发包的描述符结构 pp.24 Table 3-1 6477799ccaSWu Mianzhi #[repr(C)] 6577799ccaSWu Mianzhi #[derive(Copy, Clone, Debug)] 6677799ccaSWu Mianzhi struct E1000ETransDesc { 6777799ccaSWu Mianzhi addr: u64, 6877799ccaSWu Mianzhi len: u16, 6977799ccaSWu Mianzhi cso: u8, 7077799ccaSWu Mianzhi cmd: u8, 7177799ccaSWu Mianzhi status: u8, 7277799ccaSWu Mianzhi css: u8, 7377799ccaSWu Mianzhi special: u8, 7477799ccaSWu Mianzhi } 7577799ccaSWu Mianzhi // pp.54 Table 3-12 7677799ccaSWu Mianzhi #[repr(C)] 7777799ccaSWu Mianzhi #[derive(Copy, Clone, Debug)] 7877799ccaSWu Mianzhi struct E1000ERecvDesc { 7977799ccaSWu Mianzhi addr: u64, 8077799ccaSWu Mianzhi len: u16, 8177799ccaSWu Mianzhi chksum: u16, 8277799ccaSWu Mianzhi status: u16, 8377799ccaSWu Mianzhi error: u8, 8477799ccaSWu Mianzhi special: u8, 8577799ccaSWu Mianzhi } 8677799ccaSWu Mianzhi #[derive(Copy, Clone)] 8777799ccaSWu Mianzhi // Buffer的Copy只是指针操作,不涉及实际数据的复制,因此要小心使用,确保不同的buffer不会使用同一块内存 8877799ccaSWu Mianzhi pub struct E1000EBuffer { 8977799ccaSWu Mianzhi buffer: NonNull<u8>, 9077799ccaSWu Mianzhi paddr: usize, 9177799ccaSWu Mianzhi // length字段为0则表示这个buffer是一个占位符,不指向实际内存 9277799ccaSWu Mianzhi // the buffer is empty and no page is allocated if length field is set 0 9377799ccaSWu Mianzhi length: usize, 9477799ccaSWu Mianzhi } 9577799ccaSWu Mianzhi 9677799ccaSWu Mianzhi impl E1000EBuffer { 9777799ccaSWu Mianzhi pub fn new(length: usize) -> Self { 9877799ccaSWu Mianzhi assert!(length <= PAGE_SIZE); 9977799ccaSWu Mianzhi if unlikely(length == 0) { 10077799ccaSWu Mianzhi // 在某些情况下,我们并不需要实际分配buffer,只需要提供一个占位符即可 10177799ccaSWu Mianzhi // we dont need to allocate dma pages for buffer in some cases 10277799ccaSWu Mianzhi E1000EBuffer { 10377799ccaSWu Mianzhi buffer: NonNull::dangling(), 10477799ccaSWu Mianzhi paddr: 0, 10577799ccaSWu Mianzhi length: 0, 10677799ccaSWu Mianzhi } 10777799ccaSWu Mianzhi } else { 10877799ccaSWu Mianzhi let (paddr, vaddr) = dma_alloc(E1000E_DMA_PAGES); 10977799ccaSWu Mianzhi E1000EBuffer { 11077799ccaSWu Mianzhi buffer: vaddr, 11177799ccaSWu Mianzhi paddr, 11277799ccaSWu Mianzhi length, 11377799ccaSWu Mianzhi } 11477799ccaSWu Mianzhi } 11577799ccaSWu Mianzhi } 11677799ccaSWu Mianzhi 117971462beSGnoCiYeH #[allow(dead_code)] 11877799ccaSWu Mianzhi pub fn as_addr(&self) -> NonNull<u8> { 11977799ccaSWu Mianzhi assert!(self.length != 0); 12077799ccaSWu Mianzhi return self.buffer; 12177799ccaSWu Mianzhi } 12277799ccaSWu Mianzhi 123971462beSGnoCiYeH #[allow(dead_code)] 12477799ccaSWu Mianzhi pub fn as_addr_u64(&self) -> u64 { 12577799ccaSWu Mianzhi assert!(self.length != 0); 12677799ccaSWu Mianzhi return self.buffer.as_ptr() as u64; 12777799ccaSWu Mianzhi } 12877799ccaSWu Mianzhi 12977799ccaSWu Mianzhi pub fn as_paddr(&self) -> usize { 13077799ccaSWu Mianzhi assert!(self.length != 0); 13177799ccaSWu Mianzhi return self.paddr; 13277799ccaSWu Mianzhi } 13377799ccaSWu Mianzhi 134971462beSGnoCiYeH #[allow(dead_code)] 13577799ccaSWu Mianzhi pub fn as_slice(&self) -> &[u8] { 13677799ccaSWu Mianzhi assert!(self.length != 0); 13777799ccaSWu Mianzhi return unsafe { from_raw_parts(self.buffer.as_ptr(), self.length) }; 13877799ccaSWu Mianzhi } 13977799ccaSWu Mianzhi 14077799ccaSWu Mianzhi pub fn as_mut_slice(&mut self) -> &mut [u8] { 14177799ccaSWu Mianzhi assert!(self.length != 0); 14277799ccaSWu Mianzhi return unsafe { from_raw_parts_mut(self.buffer.as_ptr(), self.length) }; 14377799ccaSWu Mianzhi } 14477799ccaSWu Mianzhi 14577799ccaSWu Mianzhi pub fn set_length(&mut self, length: usize) { 14677799ccaSWu Mianzhi self.length = length; 14777799ccaSWu Mianzhi } 14877799ccaSWu Mianzhi 14977799ccaSWu Mianzhi pub fn len(&self) -> usize { 15077799ccaSWu Mianzhi return self.length; 15177799ccaSWu Mianzhi } 15277799ccaSWu Mianzhi // 释放buffer内部的dma_pages,需要小心使用 15377799ccaSWu Mianzhi pub fn free_buffer(self) -> () { 15477799ccaSWu Mianzhi if self.length != 0 { 15577799ccaSWu Mianzhi unsafe { dma_dealloc(self.paddr, self.buffer, E1000E_DMA_PAGES) }; 15677799ccaSWu Mianzhi } 15777799ccaSWu Mianzhi } 15877799ccaSWu Mianzhi } 15977799ccaSWu Mianzhi 16077799ccaSWu Mianzhi // 中断处理函数, 调用协议栈的poll函数,未来可能会用napi来替换这里 16177799ccaSWu Mianzhi // Interrupt handler 162971462beSGnoCiYeH unsafe extern "C" fn e1000e_irq_handler(_irq_num: u64, _irq_paramer: u64, _regs: *mut pt_regs) { 16377799ccaSWu Mianzhi poll_ifaces_try_lock_onetime().ok(); 16477799ccaSWu Mianzhi } 16577799ccaSWu Mianzhi 166971462beSGnoCiYeH #[allow(dead_code)] 16777799ccaSWu Mianzhi pub struct E1000EDevice { 16877799ccaSWu Mianzhi // 设备寄存器 16977799ccaSWu Mianzhi // device registers 17077799ccaSWu Mianzhi general_regs: NonNull<GeneralRegs>, 17177799ccaSWu Mianzhi interrupt_regs: NonNull<InterruptRegs>, 17277799ccaSWu Mianzhi rctl_regs: NonNull<ReceiveCtrlRegs>, 17377799ccaSWu Mianzhi receive_regs: NonNull<ReceiveRegs>, 17477799ccaSWu Mianzhi tctl_regs: NonNull<TransmitCtrlRegs>, 17577799ccaSWu Mianzhi transimit_regs: NonNull<TransimitRegs>, 17677799ccaSWu Mianzhi pcie_regs: NonNull<PCIeRegs>, 17777799ccaSWu Mianzhi 17877799ccaSWu Mianzhi // descriptor环形队列,在操作系统与设备之间共享 17977799ccaSWu Mianzhi // descriptor rings are shared between os and device 18077799ccaSWu Mianzhi recv_desc_ring: &'static mut [E1000ERecvDesc], 18177799ccaSWu Mianzhi trans_desc_ring: &'static mut [E1000ETransDesc], 18277799ccaSWu Mianzhi recv_ring_pa: usize, 18377799ccaSWu Mianzhi trans_ring_pa: usize, 18477799ccaSWu Mianzhi 18577799ccaSWu Mianzhi // 设备收/发包缓冲区数组 18677799ccaSWu Mianzhi // buffers of receive/transmit packets 18777799ccaSWu Mianzhi recv_buffers: Vec<E1000EBuffer>, 18877799ccaSWu Mianzhi trans_buffers: Vec<E1000EBuffer>, 18977799ccaSWu Mianzhi mac: [u8; 6], 19077799ccaSWu Mianzhi first_trans: bool, 19177799ccaSWu Mianzhi // napi队列,用于存放在中断关闭期间通过轮询收取的buffer 19277799ccaSWu Mianzhi // the napi queue is designed to save buffer/packet when the interrupt is close 19377799ccaSWu Mianzhi // NOTE: this feature is not completely implemented and not used in the current version 19477799ccaSWu Mianzhi napi_buffers: Vec<E1000EBuffer>, 19577799ccaSWu Mianzhi napi_buffer_head: usize, 19677799ccaSWu Mianzhi napi_buffer_tail: usize, 19777799ccaSWu Mianzhi napi_buffer_empty: bool, 19877799ccaSWu Mianzhi } 19977799ccaSWu Mianzhi 20077799ccaSWu Mianzhi impl E1000EDevice { 20177799ccaSWu Mianzhi // 从PCI标准设备进行驱动初始化 20277799ccaSWu Mianzhi // init the device for PCI standard device struct 203971462beSGnoCiYeH #[allow(unused_assignments)] 20477799ccaSWu Mianzhi pub fn new(device: &mut PciDeviceStructureGeneralDevice) -> Result<Self, E1000EPciError> { 20577799ccaSWu Mianzhi // 从BAR0获取我们需要的寄存器 20677799ccaSWu Mianzhi // Build registers sturcts from BAR0 20777799ccaSWu Mianzhi device.bar_ioremap().unwrap()?; 20877799ccaSWu Mianzhi device.enable_master(); 20977799ccaSWu Mianzhi let bar = device.bar().ok_or(E1000EPciError::BarGetFailed)?; 21077799ccaSWu Mianzhi let bar0 = bar.get_bar(0)?; 21177799ccaSWu Mianzhi let (address, size) = bar0 21277799ccaSWu Mianzhi .memory_address_size() 21377799ccaSWu Mianzhi .ok_or(E1000EPciError::UnexpectedBarType)?; 21477799ccaSWu Mianzhi if address == 0 { 21577799ccaSWu Mianzhi return Err(E1000EPciError::BarNotAllocated); 21677799ccaSWu Mianzhi } 21777799ccaSWu Mianzhi if size != E1000E_BAR_REG_SIZE { 21877799ccaSWu Mianzhi return Err(E1000EPciError::UnexpectedBarSize); 21977799ccaSWu Mianzhi } 22077799ccaSWu Mianzhi let vaddress = bar0 22177799ccaSWu Mianzhi .virtual_address() 22277799ccaSWu Mianzhi .ok_or(E1000EPciError::BarGetVaddrFailed)? 22377799ccaSWu Mianzhi .data() as u64; 22477799ccaSWu Mianzhi 22577799ccaSWu Mianzhi // 初始化msi中断 22677799ccaSWu Mianzhi // initialize msi interupt 22777799ccaSWu Mianzhi let irq_vector = device.irq_vector_mut().unwrap(); 22877799ccaSWu Mianzhi irq_vector.push(E1000E_RECV_VECTOR); 22977799ccaSWu Mianzhi device.irq_init(IRQ::PCI_IRQ_MSI).expect("IRQ Init Failed"); 23077799ccaSWu Mianzhi let msg = IrqMsg { 23177799ccaSWu Mianzhi irq_common_message: IrqCommonMsg::init_from( 23277799ccaSWu Mianzhi 0, 23377799ccaSWu Mianzhi "E1000E_RECV_IRQ", 23477799ccaSWu Mianzhi 0, 23577799ccaSWu Mianzhi e1000e_irq_handler, 23677799ccaSWu Mianzhi None, 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); 27677799ccaSWu Mianzhi gcr = 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) }; 28677799ccaSWu Mianzhi kdebug!("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] = [ 29377799ccaSWu Mianzhi ((ral >> 0) & 0xFF) as u8, 29477799ccaSWu Mianzhi ((ral >> 8) & 0xFF) as u8, 29577799ccaSWu Mianzhi ((ral >> 16) & 0xFF) as u8, 29677799ccaSWu Mianzhi ((ral >> 24) & 0xFF) as u8, 29777799ccaSWu Mianzhi ((rah >> 0) & 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. 32177799ccaSWu Mianzhi for i in 0..recv_ring_length { 32277799ccaSWu Mianzhi let buffer = E1000EBuffer::new(PAGE_SIZE); 32377799ccaSWu Mianzhi recv_desc_ring[i].addr = buffer.as_paddr() as u64; 32477799ccaSWu Mianzhi recv_desc_ring[i].status = 0; 32577799ccaSWu Mianzhi recv_buffers.push(buffer); 32677799ccaSWu Mianzhi } 32777799ccaSWu Mianzhi // Same as receive buffers 32877799ccaSWu Mianzhi for i in 0..trans_ring_length { 32977799ccaSWu Mianzhi let buffer = E1000EBuffer::new(PAGE_SIZE); 33077799ccaSWu Mianzhi trans_desc_ring[i].addr = buffer.as_paddr() as u64; 33177799ccaSWu Mianzhi trans_desc_ring[i].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) }; 34277799ccaSWu Mianzhi mta_adress = 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 } 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) }; 44477799ccaSWu Mianzhi // kdebug!("e1000e: receive packet"); 44577799ccaSWu Mianzhi return Some(buffer); 44677799ccaSWu Mianzhi } 44777799ccaSWu Mianzhi 44877799ccaSWu 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 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 } 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 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)] 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 { 49377799ccaSWu Mianzhi true => ims = ims | E1000E_IMS_RXT0, 49477799ccaSWu Mianzhi false => ims = 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)] 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 { 51477799ccaSWu Mianzhi if self.napi_buffer_tail == self.napi_buffer_head && self.napi_buffer_empty == false 51577799ccaSWu Mianzhi { 51677799ccaSWu Mianzhi // napi缓冲队列已满,停止收包 51777799ccaSWu Mianzhi // napi queue is full, stop 51877799ccaSWu Mianzhi break; 51977799ccaSWu Mianzhi } 52077799ccaSWu Mianzhi match self.e1000e_receive() { 52177799ccaSWu Mianzhi Some(buffer) => { 52277799ccaSWu Mianzhi self.napi_buffers[self.napi_buffer_tail] = buffer; 52377799ccaSWu Mianzhi self.napi_buffer_tail = (self.napi_buffer_tail + 1) % E1000E_RECV_NAPI; 52477799ccaSWu Mianzhi self.napi_buffer_empty = false; 52577799ccaSWu Mianzhi } 52677799ccaSWu Mianzhi None => { 52777799ccaSWu Mianzhi // 设备队列中没有剩余的已到达的数据包 52877799ccaSWu Mianzhi // no packet remains in the device buffer 52977799ccaSWu Mianzhi break; 53077799ccaSWu Mianzhi } 53177799ccaSWu Mianzhi }; 53277799ccaSWu Mianzhi } 53377799ccaSWu Mianzhi // 重新打开设备中断 53477799ccaSWu Mianzhi // open the interrupt 53577799ccaSWu Mianzhi self.e1000e_intr_set(true); 53677799ccaSWu Mianzhi } 53777799ccaSWu Mianzhi 53877799ccaSWu Mianzhi let result = self.napi_buffers[self.napi_buffer_head]; 53977799ccaSWu Mianzhi match result.len() { 54077799ccaSWu Mianzhi 0 => { 54177799ccaSWu Mianzhi // napi队列和网卡队列中都不存在数据包 54277799ccaSWu Mianzhi // both napi queue and device buffer is empty, no packet will receive 54377799ccaSWu Mianzhi return None; 54477799ccaSWu Mianzhi } 54577799ccaSWu Mianzhi _ => { 54677799ccaSWu Mianzhi // 有剩余的已到达的数据包 54777799ccaSWu Mianzhi // there is packet in napi queue 54877799ccaSWu Mianzhi self.napi_buffer_head = (self.napi_buffer_head + 1) % E1000E_RECV_NAPI; 54977799ccaSWu Mianzhi if self.napi_buffer_head == self.napi_buffer_tail { 55077799ccaSWu Mianzhi self.napi_buffer_empty = true; 55177799ccaSWu Mianzhi } 55277799ccaSWu Mianzhi return Some(result); 55377799ccaSWu Mianzhi } 55477799ccaSWu Mianzhi } 55577799ccaSWu Mianzhi } 55677799ccaSWu Mianzhi } 55777799ccaSWu Mianzhi 55877799ccaSWu Mianzhi impl Drop for E1000EDevice { 55977799ccaSWu Mianzhi fn drop(&mut self) { 56077799ccaSWu Mianzhi // 释放已分配的所有dma页 56177799ccaSWu Mianzhi // free all dma pages we have allocated 56277799ccaSWu Mianzhi kdebug!("droping..."); 56377799ccaSWu Mianzhi let recv_ring_length = PAGE_SIZE / size_of::<E1000ERecvDesc>(); 56477799ccaSWu Mianzhi let trans_ring_length = PAGE_SIZE / size_of::<E1000ETransDesc>(); 56577799ccaSWu Mianzhi unsafe { 56677799ccaSWu Mianzhi // 释放所有buffer中的dma页 56777799ccaSWu Mianzhi // free all dma pages in buffers 56877799ccaSWu Mianzhi for i in 0..recv_ring_length { 56977799ccaSWu Mianzhi self.recv_buffers[i].free_buffer(); 57077799ccaSWu Mianzhi } 57177799ccaSWu Mianzhi for i in 0..trans_ring_length { 57277799ccaSWu Mianzhi self.trans_buffers[i].free_buffer(); 57377799ccaSWu Mianzhi } 57477799ccaSWu Mianzhi // 释放descriptor ring 57577799ccaSWu Mianzhi // free descriptor ring 57677799ccaSWu Mianzhi dma_dealloc( 57777799ccaSWu Mianzhi self.recv_ring_pa, 57877799ccaSWu Mianzhi NonNull::new(self.recv_desc_ring).unwrap().cast(), 57977799ccaSWu Mianzhi E1000E_DMA_PAGES, 58077799ccaSWu Mianzhi ); 58177799ccaSWu Mianzhi dma_dealloc( 58277799ccaSWu Mianzhi self.trans_ring_pa, 58377799ccaSWu Mianzhi NonNull::new(self.trans_desc_ring).unwrap().cast(), 58477799ccaSWu Mianzhi E1000E_DMA_PAGES, 58577799ccaSWu Mianzhi ); 58677799ccaSWu Mianzhi } 58777799ccaSWu Mianzhi } 58877799ccaSWu Mianzhi } 58977799ccaSWu Mianzhi 59077799ccaSWu Mianzhi #[no_mangle] 59177799ccaSWu Mianzhi pub extern "C" fn rs_e1000e_init() { 59277799ccaSWu Mianzhi e1000e_init(); 59377799ccaSWu Mianzhi } 59477799ccaSWu Mianzhi 59577799ccaSWu Mianzhi pub fn e1000e_init() -> () { 59677799ccaSWu Mianzhi match e1000e_probe() { 597*8d72b68dSJomo Ok(_code) => { 598*8d72b68dSJomo kinfo!("Successfully init e1000e device!"); 599*8d72b68dSJomo } 600*8d72b68dSJomo Err(_error) => { 601*8d72b68dSJomo kinfo!("Error occurred!"); 602*8d72b68dSJomo } 60377799ccaSWu Mianzhi } 60477799ccaSWu Mianzhi } 60577799ccaSWu Mianzhi 60677799ccaSWu Mianzhi pub fn e1000e_probe() -> Result<u64, E1000EPciError> { 60777799ccaSWu Mianzhi let mut list = PCI_DEVICE_LINKEDLIST.write(); 60877799ccaSWu Mianzhi let result = get_pci_device_structure_mut(&mut list, NETWORK_CLASS, ETHERNET_SUBCLASS); 60977799ccaSWu Mianzhi if result.is_empty() { 61077799ccaSWu Mianzhi return Ok(0); 61177799ccaSWu Mianzhi } 61277799ccaSWu Mianzhi for device in result { 61377799ccaSWu Mianzhi let standard_device = device.as_standard_device_mut().unwrap(); 61477799ccaSWu Mianzhi let header = &standard_device.common_header; 61577799ccaSWu Mianzhi if header.vendor_id == 0x8086 { 61677799ccaSWu Mianzhi // intel 61777799ccaSWu Mianzhi if E1000E_DEVICE_ID.contains(&header.device_id) { 61877799ccaSWu Mianzhi kdebug!( 61977799ccaSWu Mianzhi "Detected e1000e PCI device with device id {:#x}", 62077799ccaSWu Mianzhi header.device_id 62177799ccaSWu Mianzhi ); 62277799ccaSWu Mianzhi let e1000e = E1000EDevice::new(standard_device)?; 62377799ccaSWu Mianzhi e1000e_driver_init(e1000e); 62477799ccaSWu Mianzhi } 62577799ccaSWu Mianzhi } 62677799ccaSWu Mianzhi } 62777799ccaSWu Mianzhi 62877799ccaSWu Mianzhi return Ok(1); 62977799ccaSWu Mianzhi } 63077799ccaSWu Mianzhi 63177799ccaSWu Mianzhi // 用到的e1000e寄存器结构体 63277799ccaSWu Mianzhi // pp.275, Table 13-3 63377799ccaSWu Mianzhi // 设备通用寄存器 634971462beSGnoCiYeH #[allow(dead_code)] 63577799ccaSWu Mianzhi struct GeneralRegs { 63677799ccaSWu Mianzhi ctrl: Volatile<u32>, //0x00000 63777799ccaSWu Mianzhi ctrl_alias: Volatile<u32>, //0x00004 63877799ccaSWu Mianzhi status: ReadOnly<u32>, //0x00008 63977799ccaSWu Mianzhi status_align: ReadOnly<u32>, //0x0000c 64077799ccaSWu Mianzhi eec: Volatile<u32>, //0x00010 64177799ccaSWu Mianzhi eerd: Volatile<u32>, //0x00014 64277799ccaSWu Mianzhi ctrl_ext: Volatile<u32>, //0x00018 64377799ccaSWu Mianzhi fla: Volatile<u32>, //0x0001c 64477799ccaSWu Mianzhi mdic: Volatile<u32>, //0x00020 64577799ccaSWu Mianzhi } 64677799ccaSWu Mianzhi // 中断控制 647971462beSGnoCiYeH #[allow(dead_code)] 64877799ccaSWu Mianzhi struct InterruptRegs { 64977799ccaSWu Mianzhi icr: Volatile<u32>, //0x000c0 ICR寄存器应当为只读寄存器,但我们需要向其中写入来清除对应位 65077799ccaSWu Mianzhi itr: Volatile<u32>, //0x000c4 65177799ccaSWu Mianzhi ics: WriteOnly<u32>, //0x000c8 65277799ccaSWu Mianzhi ics_align: ReadOnly<u32>, //0x000cc 65377799ccaSWu Mianzhi ims: Volatile<u32>, //0x000d0 65477799ccaSWu Mianzhi ims_align: ReadOnly<u32>, //0x000d4 65577799ccaSWu Mianzhi imc: WriteOnly<u32>, //0x000d8 65677799ccaSWu Mianzhi } 65777799ccaSWu Mianzhi // 收包功能控制 65877799ccaSWu Mianzhi struct ReceiveCtrlRegs { 65977799ccaSWu Mianzhi rctl: Volatile<u32>, //0x00100 66077799ccaSWu Mianzhi } 66177799ccaSWu Mianzhi // 发包功能控制 662971462beSGnoCiYeH #[allow(dead_code)] 66377799ccaSWu Mianzhi struct TransmitCtrlRegs { 66477799ccaSWu Mianzhi tctl: Volatile<u32>, //0x00400 66577799ccaSWu Mianzhi tctl_ext: Volatile<u32>, //0x00404 66677799ccaSWu Mianzhi unused_1: ReadOnly<u32>, //0x00408 66777799ccaSWu Mianzhi unused_2: ReadOnly<u32>, //0x0040c 66877799ccaSWu Mianzhi tipg: Volatile<u32>, //0x00410 66977799ccaSWu Mianzhi } 67077799ccaSWu Mianzhi // 收包功能相关 671971462beSGnoCiYeH #[allow(dead_code)] 67277799ccaSWu Mianzhi struct ReceiveRegs { 67377799ccaSWu Mianzhi rdbal0: Volatile<u32>, //0x02800 67477799ccaSWu Mianzhi rdbah0: Volatile<u32>, //0x02804 67577799ccaSWu Mianzhi rdlen0: Volatile<u32>, //0x02808 67677799ccaSWu Mianzhi rdl_align: ReadOnly<u32>, //0x0280c 67777799ccaSWu Mianzhi rdh0: Volatile<u32>, //0x02810 67877799ccaSWu Mianzhi rdh_align: ReadOnly<u32>, //0x02814 67977799ccaSWu Mianzhi rdt0: Volatile<u32>, //0x02818 68077799ccaSWu Mianzhi rdt_align: ReadOnly<u32>, //0x281c 68177799ccaSWu Mianzhi rdtr: Volatile<u32>, //0x2820 68277799ccaSWu Mianzhi rdtr_align: ReadOnly<u32>, //0x2824 68377799ccaSWu Mianzhi rxdctl: Volatile<u32>, //0x2828 68477799ccaSWu Mianzhi } 68577799ccaSWu Mianzhi // 发包功能相关 686971462beSGnoCiYeH #[allow(dead_code)] 68777799ccaSWu Mianzhi struct TransimitRegs { 68877799ccaSWu Mianzhi tdbal0: Volatile<u32>, //0x03800 68977799ccaSWu Mianzhi tdbah0: Volatile<u32>, //0x03804 69077799ccaSWu Mianzhi tdlen0: Volatile<u32>, //0x03808 69177799ccaSWu Mianzhi tdlen_algin: ReadOnly<u32>, //0x0380c 69277799ccaSWu Mianzhi tdh0: Volatile<u32>, //0x03810 69377799ccaSWu Mianzhi tdh_align: ReadOnly<u32>, //0x03814 69477799ccaSWu Mianzhi tdt0: Volatile<u32>, //0x03818 69577799ccaSWu Mianzhi tdt_align: ReadOnly<u32>, //0x0381c 69677799ccaSWu Mianzhi tidv: Volatile<u32>, //0x03820 69777799ccaSWu Mianzhi tidv_align: ReadOnly<u32>, //0x03824 69877799ccaSWu Mianzhi txdctl: Volatile<u32>, //0x03828 69977799ccaSWu Mianzhi tadv: Volatile<u32>, //0x0382c 70077799ccaSWu Mianzhi } 70177799ccaSWu Mianzhi // mac地址 70277799ccaSWu Mianzhi struct ReceiveAddressRegs { 70377799ccaSWu Mianzhi ral0: Volatile<u32>, //0x05400 70477799ccaSWu Mianzhi rah0: Volatile<u32>, //0x05404 70577799ccaSWu Mianzhi } 70677799ccaSWu Mianzhi // PCIe 通用控制 70777799ccaSWu Mianzhi struct PCIeRegs { 70877799ccaSWu Mianzhi gcr: Volatile<u32>, //0x05b00 70977799ccaSWu Mianzhi } 710971462beSGnoCiYeH #[allow(dead_code)] 71177799ccaSWu Mianzhi struct StatisticsRegs {} 71277799ccaSWu Mianzhi 71377799ccaSWu Mianzhi // 0x05200-0x053fc 71477799ccaSWu Mianzhi // 在Receive Initialization 中按照每次一个32bit寄存器的方式来遍历 71577799ccaSWu Mianzhi // Multicast Table Array Registers will be written per 32bit 71677799ccaSWu Mianzhi struct MTARegs { 71777799ccaSWu Mianzhi mta: Volatile<u32>, 71877799ccaSWu Mianzhi } 71977799ccaSWu Mianzhi 72077799ccaSWu Mianzhi const E1000E_GENERAL_REGS_OFFSET: u64 = 0x00000; 72177799ccaSWu Mianzhi const E1000E_INTERRRUPT_REGS_OFFSET: u64 = 0x000c0; 72277799ccaSWu Mianzhi const E1000E_RECEIVE_CTRL_REG_OFFSET: u64 = 0x00100; 72377799ccaSWu Mianzhi const E1000E_RECEIVE_REGS_OFFSET: u64 = 0x02800; 72477799ccaSWu Mianzhi const E1000E_TRANSMIT_CTRL_REG_OFFSET: u64 = 0x00400; 72577799ccaSWu Mianzhi const E1000E_TRANSMIT_REGS_OFFSET: u64 = 0x03800; 72677799ccaSWu Mianzhi const E1000E_RECEIVE_ADDRESS_REGS_OFFSET: u64 = 0x05400; 72777799ccaSWu Mianzhi const E1000E_PCIE_REGS_OFFSET: u64 = 0x05b00; 72877799ccaSWu Mianzhi const E1000E_MTA_REGS_START_OFFSET: u64 = 0x05200; 72977799ccaSWu Mianzhi const E1000E_MTA_REGS_END_OFFSET: u64 = 0x053fc; 73077799ccaSWu Mianzhi // 寄存器的特定位 73177799ccaSWu Mianzhi //CTRL 73277799ccaSWu Mianzhi const E1000E_CTRL_SLU: u32 = 1 << 6; 73377799ccaSWu Mianzhi const E1000E_CTRL_FRCSPD: u32 = 1 << 11; 73477799ccaSWu Mianzhi const E1000E_CTRL_FRCDPLX: u32 = 1 << 12; 73577799ccaSWu Mianzhi const E1000E_CTRL_RST: u32 = 1 << 26; 736971462beSGnoCiYeH #[allow(dead_code)] 73777799ccaSWu Mianzhi const E1000E_CTRL_RFCE: u32 = 1 << 27; 738971462beSGnoCiYeH #[allow(dead_code)] 73977799ccaSWu Mianzhi const E1000E_CTRL_TFCE: u32 = 1 << 28; 74077799ccaSWu Mianzhi const E1000E_CTRL_PHY_RST: u32 = 1 << 31; 74177799ccaSWu Mianzhi 74277799ccaSWu Mianzhi // IMS 74377799ccaSWu Mianzhi const E1000E_IMS_LSC: u32 = 1 << 2; 74477799ccaSWu Mianzhi const E1000E_IMS_RXDMT0: u32 = 1 << 4; 745971462beSGnoCiYeH #[allow(dead_code)] 74677799ccaSWu Mianzhi const E1000E_IMS_RXO: u32 = 1 << 6; 74777799ccaSWu Mianzhi const E1000E_IMS_RXT0: u32 = 1 << 7; 748971462beSGnoCiYeH #[allow(dead_code)] 74977799ccaSWu Mianzhi const E1000E_IMS_RXQ0: u32 = 1 << 20; 75077799ccaSWu Mianzhi const E1000E_IMS_OTHER: u32 = 1 << 24; // qemu use this bit to set msi-x interrupt 75177799ccaSWu Mianzhi 75277799ccaSWu Mianzhi // IMC 75377799ccaSWu Mianzhi const E1000E_IMC_CLEAR: u32 = 0xffffffff; 75477799ccaSWu Mianzhi 75577799ccaSWu Mianzhi // RCTL 75677799ccaSWu Mianzhi const E1000E_RCTL_EN: u32 = 1 << 1; 75777799ccaSWu Mianzhi const E1000E_RCTL_BAM: u32 = 1 << 15; 75877799ccaSWu Mianzhi const E1000E_RCTL_BSIZE_4K: u32 = 3 << 16; 75977799ccaSWu Mianzhi const E1000E_RCTL_BSEX: u32 = 1 << 25; 76077799ccaSWu Mianzhi const E1000E_RCTL_SECRC: u32 = 1 << 26; 76177799ccaSWu Mianzhi 76277799ccaSWu Mianzhi // TCTL 76377799ccaSWu Mianzhi const E1000E_TCTL_EN: u32 = 1 << 1; 76477799ccaSWu Mianzhi const E1000E_TCTL_PSP: u32 = 1 << 3; 76577799ccaSWu Mianzhi const E1000E_TCTL_CT_VAL: u32 = 0x0f << 4; // suggested 16d collision, 手册建议值:16d 76677799ccaSWu Mianzhi const E1000E_TCTL_COLD_VAL: u32 = 0x03f << 12; // suggested 64 byte time for Full-Duplex, 手册建议值:64 76777799ccaSWu Mianzhi // TXDCTL 76877799ccaSWu Mianzhi const E1000E_TXDCTL_WTHRESH: u32 = 1 << 16; 76977799ccaSWu Mianzhi const E1000E_TXDCTL_GRAN: u32 = 1 << 24; 77077799ccaSWu Mianzhi // TIPG 77177799ccaSWu Mianzhi const E1000E_TIPG_IPGT: u32 = 8; 77277799ccaSWu Mianzhi const E1000E_TIPG_IPGR1: u32 = 2 << 10; 77377799ccaSWu Mianzhi const E1000E_TIPG_IPGR2: u32 = 10 << 20; 77477799ccaSWu Mianzhi 77577799ccaSWu Mianzhi // RxDescriptorStatus 77677799ccaSWu Mianzhi const E1000E_RXD_STATUS_DD: u16 = 1 << 0; 77777799ccaSWu Mianzhi 77877799ccaSWu Mianzhi // TxDescriptorStatus 77977799ccaSWu Mianzhi const E1000E_TXD_STATUS_DD: u8 = 1 << 0; 78077799ccaSWu Mianzhi const E1000E_TXD_CMD_EOP: u8 = 1 << 0; 78177799ccaSWu Mianzhi const E1000E_TXD_CMD_IFCS: u8 = 1 << 1; 78277799ccaSWu Mianzhi const E1000E_TXD_CMD_RS: u8 = 1 << 3; 78377799ccaSWu Mianzhi 78477799ccaSWu Mianzhi // E1000E驱动初始化过程中可能的错误 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 { 80477799ccaSWu 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 */ 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