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