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