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