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