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