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 {
new(length: usize) -> Self102 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)]
as_addr(&self) -> NonNull<u8>123 pub fn as_addr(&self) -> NonNull<u8> {
124 assert!(self.length != 0);
125 return self.buffer;
126 }
127
128 #[allow(dead_code)]
as_addr_u64(&self) -> u64129 pub fn as_addr_u64(&self) -> u64 {
130 assert!(self.length != 0);
131 return self.buffer.as_ptr() as u64;
132 }
133
as_paddr(&self) -> usize134 pub fn as_paddr(&self) -> usize {
135 assert!(self.length != 0);
136 return self.paddr;
137 }
138
139 #[allow(dead_code)]
as_slice(&self) -> &[u8]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
as_mut_slice(&mut self) -> &mut [u8]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
set_length(&mut self, length: usize)150 pub fn set_length(&mut self, length: usize) {
151 self.length = length;
152 }
153
len(&self) -> usize154 pub fn len(&self) -> usize {
155 return self.length;
156 }
157 // 释放buffer内部的dma_pages,需要小心使用
free_buffer(self) -> ()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)]
new( device: &mut PciDeviceStructureGeneralDevice, device_id: Arc<DeviceId>, ) -> Result<Self, E1000EPciError>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 = 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 >> 0) & 0xFF) as u8,
295 ((ral >> 8) & 0xFF) as u8,
296 ((ral >> 16) & 0xFF) as u8,
297 ((ral >> 24) & 0xFF) as u8,
298 ((rah >> 0) & 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 i in 0..recv_ring_length {
323 let buffer = E1000EBuffer::new(PAGE_SIZE);
324 recv_desc_ring[i].addr = buffer.as_paddr() as u64;
325 recv_desc_ring[i].status = 0;
326 recv_buffers.push(buffer);
327 }
328 // Same as receive buffers
329 for i in 0..trans_ring_length {
330 let buffer = E1000EBuffer::new(PAGE_SIZE);
331 trans_desc_ring[i].addr = buffer.as_paddr() as u64;
332 trans_desc_ring[i].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 = 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 }
e1000e_receive(&mut self) -> Option<E1000EBuffer>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
e1000e_can_transmit(&self) -> bool449 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
e1000e_transmit(&mut self, packet: E1000EBuffer)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 }
mac_address(&self) -> [u8; 6]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
e1000e_intr(&mut self)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)]
e1000e_intr_set(&mut self, state: bool)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 = ims | E1000E_IMS_RXT0,
495 false => ims = 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)]
e1000e_receive2(&mut self) -> Option<E1000EBuffer>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 == false
516 {
517 // napi缓冲队列已满,停止收包
518 // napi queue is full, stop
519 break;
520 }
521 match self.e1000e_receive() {
522 Some(buffer) => {
523 self.napi_buffers[self.napi_buffer_tail] = buffer;
524 self.napi_buffer_tail = (self.napi_buffer_tail + 1) % E1000E_RECV_NAPI;
525 self.napi_buffer_empty = false;
526 }
527 None => {
528 // 设备队列中没有剩余的已到达的数据包
529 // no packet remains in the device buffer
530 break;
531 }
532 };
533 }
534 // 重新打开设备中断
535 // open the interrupt
536 self.e1000e_intr_set(true);
537 }
538
539 let result = self.napi_buffers[self.napi_buffer_head];
540 match result.len() {
541 0 => {
542 // napi队列和网卡队列中都不存在数据包
543 // both napi queue and device buffer is empty, no packet will receive
544 return None;
545 }
546 _ => {
547 // 有剩余的已到达的数据包
548 // there is packet in napi queue
549 self.napi_buffer_head = (self.napi_buffer_head + 1) % E1000E_RECV_NAPI;
550 if self.napi_buffer_head == self.napi_buffer_tail {
551 self.napi_buffer_empty = true;
552 }
553 return Some(result);
554 }
555 }
556 }
557 }
558
559 impl Drop for E1000EDevice {
drop(&mut self)560 fn drop(&mut self) {
561 // 释放已分配的所有dma页
562 // free all dma pages we have allocated
563 kdebug!("droping...");
564 let recv_ring_length = PAGE_SIZE / size_of::<E1000ERecvDesc>();
565 let trans_ring_length = PAGE_SIZE / size_of::<E1000ETransDesc>();
566 unsafe {
567 // 释放所有buffer中的dma页
568 // free all dma pages in buffers
569 for i in 0..recv_ring_length {
570 self.recv_buffers[i].free_buffer();
571 }
572 for i in 0..trans_ring_length {
573 self.trans_buffers[i].free_buffer();
574 }
575 // 释放descriptor ring
576 // free descriptor ring
577 dma_dealloc(
578 self.recv_ring_pa,
579 NonNull::new(self.recv_desc_ring).unwrap().cast(),
580 E1000E_DMA_PAGES,
581 );
582 dma_dealloc(
583 self.trans_ring_pa,
584 NonNull::new(self.trans_desc_ring).unwrap().cast(),
585 E1000E_DMA_PAGES,
586 );
587 }
588 }
589 }
590
591 #[no_mangle]
rs_e1000e_init()592 pub extern "C" fn rs_e1000e_init() {
593 e1000e_init();
594 }
595
e1000e_init() -> ()596 pub fn e1000e_init() -> () {
597 match e1000e_probe() {
598 Ok(_code) => {
599 kinfo!("Successfully init e1000e device!");
600 }
601 Err(_error) => {
602 kinfo!("Error occurred!");
603 }
604 }
605 }
606
e1000e_probe() -> Result<u64, E1000EPciError>607 pub fn e1000e_probe() -> Result<u64, E1000EPciError> {
608 let mut list = PCI_DEVICE_LINKEDLIST.write();
609 let result = get_pci_device_structure_mut(&mut list, NETWORK_CLASS, ETHERNET_SUBCLASS);
610 if result.is_empty() {
611 return Ok(0);
612 }
613 for device in result {
614 let standard_device = device.as_standard_device_mut().unwrap();
615 let header = &standard_device.common_header;
616 if header.vendor_id == 0x8086 {
617 // intel
618 if E1000E_DEVICE_ID.contains(&header.device_id) {
619 kdebug!(
620 "Detected e1000e PCI device with device id {:#x}",
621 header.device_id
622 );
623
624 // todo: 根据pci的path来生成device id
625 let e1000e = E1000EDevice::new(
626 standard_device,
627 DeviceId::new(None, Some(format!("e1000e_{}", header.device_id))).unwrap(),
628 )?;
629 e1000e_driver_init(e1000e);
630 }
631 }
632 }
633
634 return Ok(1);
635 }
636
637 // 用到的e1000e寄存器结构体
638 // pp.275, Table 13-3
639 // 设备通用寄存器
640 #[allow(dead_code)]
641 struct GeneralRegs {
642 ctrl: Volatile<u32>, //0x00000
643 ctrl_alias: Volatile<u32>, //0x00004
644 status: ReadOnly<u32>, //0x00008
645 status_align: ReadOnly<u32>, //0x0000c
646 eec: Volatile<u32>, //0x00010
647 eerd: Volatile<u32>, //0x00014
648 ctrl_ext: Volatile<u32>, //0x00018
649 fla: Volatile<u32>, //0x0001c
650 mdic: Volatile<u32>, //0x00020
651 }
652 // 中断控制
653 #[allow(dead_code)]
654 struct InterruptRegs {
655 icr: Volatile<u32>, //0x000c0 ICR寄存器应当为只读寄存器,但我们需要向其中写入来清除对应位
656 itr: Volatile<u32>, //0x000c4
657 ics: WriteOnly<u32>, //0x000c8
658 ics_align: ReadOnly<u32>, //0x000cc
659 ims: Volatile<u32>, //0x000d0
660 ims_align: ReadOnly<u32>, //0x000d4
661 imc: WriteOnly<u32>, //0x000d8
662 }
663 // 收包功能控制
664 struct ReceiveCtrlRegs {
665 rctl: Volatile<u32>, //0x00100
666 }
667 // 发包功能控制
668 #[allow(dead_code)]
669 struct TransmitCtrlRegs {
670 tctl: Volatile<u32>, //0x00400
671 tctl_ext: Volatile<u32>, //0x00404
672 unused_1: ReadOnly<u32>, //0x00408
673 unused_2: ReadOnly<u32>, //0x0040c
674 tipg: Volatile<u32>, //0x00410
675 }
676 // 收包功能相关
677 #[allow(dead_code)]
678 struct ReceiveRegs {
679 rdbal0: Volatile<u32>, //0x02800
680 rdbah0: Volatile<u32>, //0x02804
681 rdlen0: Volatile<u32>, //0x02808
682 rdl_align: ReadOnly<u32>, //0x0280c
683 rdh0: Volatile<u32>, //0x02810
684 rdh_align: ReadOnly<u32>, //0x02814
685 rdt0: Volatile<u32>, //0x02818
686 rdt_align: ReadOnly<u32>, //0x281c
687 rdtr: Volatile<u32>, //0x2820
688 rdtr_align: ReadOnly<u32>, //0x2824
689 rxdctl: Volatile<u32>, //0x2828
690 }
691 // 发包功能相关
692 #[allow(dead_code)]
693 struct TransimitRegs {
694 tdbal0: Volatile<u32>, //0x03800
695 tdbah0: Volatile<u32>, //0x03804
696 tdlen0: Volatile<u32>, //0x03808
697 tdlen_algin: ReadOnly<u32>, //0x0380c
698 tdh0: Volatile<u32>, //0x03810
699 tdh_align: ReadOnly<u32>, //0x03814
700 tdt0: Volatile<u32>, //0x03818
701 tdt_align: ReadOnly<u32>, //0x0381c
702 tidv: Volatile<u32>, //0x03820
703 tidv_align: ReadOnly<u32>, //0x03824
704 txdctl: Volatile<u32>, //0x03828
705 tadv: Volatile<u32>, //0x0382c
706 }
707 // mac地址
708 struct ReceiveAddressRegs {
709 ral0: Volatile<u32>, //0x05400
710 rah0: Volatile<u32>, //0x05404
711 }
712 // PCIe 通用控制
713 struct PCIeRegs {
714 gcr: Volatile<u32>, //0x05b00
715 }
716 #[allow(dead_code)]
717 struct StatisticsRegs {}
718
719 // 0x05200-0x053fc
720 // 在Receive Initialization 中按照每次一个32bit寄存器的方式来遍历
721 // Multicast Table Array Registers will be written per 32bit
722 struct MTARegs {
723 mta: Volatile<u32>,
724 }
725
726 const E1000E_GENERAL_REGS_OFFSET: u64 = 0x00000;
727 const E1000E_INTERRRUPT_REGS_OFFSET: u64 = 0x000c0;
728 const E1000E_RECEIVE_CTRL_REG_OFFSET: u64 = 0x00100;
729 const E1000E_RECEIVE_REGS_OFFSET: u64 = 0x02800;
730 const E1000E_TRANSMIT_CTRL_REG_OFFSET: u64 = 0x00400;
731 const E1000E_TRANSMIT_REGS_OFFSET: u64 = 0x03800;
732 const E1000E_RECEIVE_ADDRESS_REGS_OFFSET: u64 = 0x05400;
733 const E1000E_PCIE_REGS_OFFSET: u64 = 0x05b00;
734 const E1000E_MTA_REGS_START_OFFSET: u64 = 0x05200;
735 const E1000E_MTA_REGS_END_OFFSET: u64 = 0x053fc;
736 // 寄存器的特定位
737 //CTRL
738 const E1000E_CTRL_SLU: u32 = 1 << 6;
739 const E1000E_CTRL_FRCSPD: u32 = 1 << 11;
740 const E1000E_CTRL_FRCDPLX: u32 = 1 << 12;
741 const E1000E_CTRL_RST: u32 = 1 << 26;
742 #[allow(dead_code)]
743 const E1000E_CTRL_RFCE: u32 = 1 << 27;
744 #[allow(dead_code)]
745 const E1000E_CTRL_TFCE: u32 = 1 << 28;
746 const E1000E_CTRL_PHY_RST: u32 = 1 << 31;
747
748 // IMS
749 const E1000E_IMS_LSC: u32 = 1 << 2;
750 const E1000E_IMS_RXDMT0: u32 = 1 << 4;
751 #[allow(dead_code)]
752 const E1000E_IMS_RXO: u32 = 1 << 6;
753 const E1000E_IMS_RXT0: u32 = 1 << 7;
754 #[allow(dead_code)]
755 const E1000E_IMS_RXQ0: u32 = 1 << 20;
756 const E1000E_IMS_OTHER: u32 = 1 << 24; // qemu use this bit to set msi-x interrupt
757
758 // IMC
759 const E1000E_IMC_CLEAR: u32 = 0xffffffff;
760
761 // RCTL
762 const E1000E_RCTL_EN: u32 = 1 << 1;
763 const E1000E_RCTL_BAM: u32 = 1 << 15;
764 const E1000E_RCTL_BSIZE_4K: u32 = 3 << 16;
765 const E1000E_RCTL_BSEX: u32 = 1 << 25;
766 const E1000E_RCTL_SECRC: u32 = 1 << 26;
767
768 // TCTL
769 const E1000E_TCTL_EN: u32 = 1 << 1;
770 const E1000E_TCTL_PSP: u32 = 1 << 3;
771 const E1000E_TCTL_CT_VAL: u32 = 0x0f << 4; // suggested 16d collision, 手册建议值:16d
772 const E1000E_TCTL_COLD_VAL: u32 = 0x03f << 12; // suggested 64 byte time for Full-Duplex, 手册建议值:64
773 // TXDCTL
774 const E1000E_TXDCTL_WTHRESH: u32 = 1 << 16;
775 const E1000E_TXDCTL_GRAN: u32 = 1 << 24;
776 // TIPG
777 const E1000E_TIPG_IPGT: u32 = 8;
778 const E1000E_TIPG_IPGR1: u32 = 2 << 10;
779 const E1000E_TIPG_IPGR2: u32 = 10 << 20;
780
781 // RxDescriptorStatus
782 const E1000E_RXD_STATUS_DD: u16 = 1 << 0;
783
784 // TxDescriptorStatus
785 const E1000E_TXD_STATUS_DD: u8 = 1 << 0;
786 const E1000E_TXD_CMD_EOP: u8 = 1 << 0;
787 const E1000E_TXD_CMD_IFCS: u8 = 1 << 1;
788 const E1000E_TXD_CMD_RS: u8 = 1 << 3;
789
790 // E1000E驱动初始化过程中可能的错误
791 pub enum E1000EPciError {
792 // 获取到错误类型的BAR(IO BAR)
793 // An IO BAR was provided rather than a memory BAR.
794 UnexpectedBarType,
795 // 获取的BAR没有被分配到某个地址(address == 0)
796 // A BAR which we need was not allocated an address(address == 0).
797 BarNotAllocated,
798 //获取虚拟地址失败
799 BarGetVaddrFailed,
800 // 没有对应的BAR或者获取BAR失败
801 BarGetFailed,
802 // BAR的大小与预期不符(128KB)
803 // Size of BAR is not 128KB
804 UnexpectedBarSize,
805 Pci(PciError),
806 }
807
808 /// PCI error到VirtioPciError的转换,层层上报
809 impl From<PciError> for E1000EPciError {
from(error: PciError) -> Self810 fn from(error: PciError) -> Self {
811 Self::Pci(error)
812 }
813 }
814
815 /**
816 * @brief 获取基地址的某个偏移量的指针,用于在mmio bar中构造寄存器结构体
817 * @brief used for build register struct in mmio bar
818 * @param vaddr: base address (in virtual memory)
819 * @param offset: offset
820 */
get_register_ptr<T>(vaddr: u64, offset: u64) -> NonNull<T>821 fn get_register_ptr<T>(vaddr: u64, offset: u64) -> NonNull<T> {
822 NonNull::new((vaddr + offset) as *mut T).unwrap()
823 }
824