e1000_driver/e1000/
e1000.rs

1// e1000 Driver for Intel 82540EP/EM
2use super::e1000_const::*;
3use super::super::Ext;
4use super::super::Volatile;
5use alloc::vec::Vec;
6use core::{cmp::min, mem::size_of, slice::from_raw_parts_mut};
7use crate::utils::*;
8
9const TX_RING_SIZE: usize = 256;
10const RX_RING_SIZE: usize = 256;
11const MBUF_SIZE: usize = 2048;
12
13/// Kernel functions that drivers must use
14pub trait KernelFunc {
15    /// Page size (usually 4K)
16    const PAGE_SIZE: usize = 4096;
17
18    /// 或请求分配irq
19
20    /// Allocate consequent physical memory for DMA;
21    /// Return (cpu virtual address, dma physical address) which is page aligned.
22    //fn dma_alloc_coherent(pages: usize) -> usize;
23    fn dma_alloc_coherent(&mut self, pages: usize) -> (usize, usize);
24
25    /// Deallocate DMA memory by virtual address
26    fn dma_free_coherent(&mut self, vaddr: usize, pages: usize);
27}
28
29/// E1000Device 网卡驱动的主要结构体
30pub struct E1000Device<'a, K: KernelFunc> {
31    regs: &'static mut [Volatile<u32>],
32    rx_ring_dma: usize,
33    tx_ring_dma: usize,
34    rx_ring: &'a mut [RxDesc], //可以只为ring buffer加锁
35    tx_ring: &'a mut [TxDesc],
36    rx_mbufs: Vec<usize>,
37    tx_mbufs: Vec<usize>,
38    mbuf_size: usize,
39    //phy_interface: PhyInterfaceMode,
40    kfn: K,
41}
42
43// struct spinlock e1000_lock;
44
45/// [E1000 3.3.3]
46#[derive(Debug, Clone)]
47#[repr(C, align(16))]
48pub struct TxDesc {
49    addr: u64,
50    length: u16,
51    cso: u8,
52    cmd: u8,
53    status: u8,
54    css: u8,
55    special: u16,
56}
57
58/// [E1000 3.2.3]
59#[derive(Debug, Clone)]
60#[repr(C, align(16))]
61pub struct RxDesc {
62    addr: u64,   /* Address of the descriptor's data buffer */
63    length: u16, /* Length of data DMAed into data buffer */
64    csum: u16,   /* Packet checksum */
65    status: u8,  /* Descriptor status */
66    errors: u8,  /* Descriptor Errors */
67    special: u16,
68}
69
70impl<'a, K: KernelFunc> E1000Device<'a, K> {
71    /// New an e1000 device by Allocating memory
72    pub fn new(mut kfn: K, mapped_regs: usize) -> Result<Self, i32> {
73        info!("New E1000 device @ {:#x}", mapped_regs);
74        // 分配的ring内存空间需要16字节对齐
75        let alloc_tx_ring_pages =
76            ((TX_RING_SIZE * size_of::<TxDesc>()) + (K::PAGE_SIZE - 1)) / K::PAGE_SIZE;
77        let alloc_rx_ring_pages =
78            ((RX_RING_SIZE * size_of::<RxDesc>()) + (K::PAGE_SIZE - 1)) / K::PAGE_SIZE;
79        let (tx_ring_vaddr, tx_ring_dma) = kfn.dma_alloc_coherent(alloc_tx_ring_pages);
80        let (rx_ring_vaddr, rx_ring_dma) = kfn.dma_alloc_coherent(alloc_rx_ring_pages);
81
82        let tx_ring = unsafe { from_raw_parts_mut(tx_ring_vaddr as *mut TxDesc, TX_RING_SIZE) };
83        let rx_ring = unsafe { from_raw_parts_mut(rx_ring_vaddr as *mut RxDesc, RX_RING_SIZE) };
84
85        tx_ring.fill(TxDesc {
86            addr: 0,
87            length: 0,
88            cso: 0,
89            cmd: 0,
90            status: 0,
91            css: 0,
92            special: 0,
93        });
94        rx_ring.fill(RxDesc {
95            addr: 0,
96            length: 0,
97            csum: 0,
98            status: 0,
99            errors: 0,
100            special: 0,
101        });
102
103        let mut tx_mbufs = Vec::with_capacity(tx_ring.len());
104        let mut rx_mbufs = Vec::with_capacity(rx_ring.len());
105
106        // 一起申请所有TX内存
107        let alloc_tx_buffer_pages =
108            ((TX_RING_SIZE * MBUF_SIZE) + (K::PAGE_SIZE - 1)) / K::PAGE_SIZE;
109        let (mut tx_mbufs_vaddr, mut tx_mbufs_dma) = kfn.dma_alloc_coherent(alloc_tx_buffer_pages);
110
111        for i in 0..TX_RING_SIZE {
112            tx_ring[i].status = E1000_TXD_STAT_DD as u8;
113            tx_ring[i].addr = tx_mbufs_dma as u64;
114            tx_mbufs.push(tx_mbufs_vaddr);
115            tx_mbufs_dma += MBUF_SIZE;
116            tx_mbufs_vaddr += MBUF_SIZE;
117        }
118
119        // 一起申请所有RX内存
120        let alloc_rx_buffer_pages =
121            ((RX_RING_SIZE * MBUF_SIZE) + (K::PAGE_SIZE - 1)) / K::PAGE_SIZE;
122        //let mut rx_mbufs_dma: usize = K::dma_alloc_coherent(alloc_rx_buffer_pages);
123        let (mut rx_mbufs_vaddr, mut rx_mbufs_dma) = kfn.dma_alloc_coherent(alloc_rx_buffer_pages);
124        if rx_mbufs_vaddr == 0 {
125            panic!("e1000, alloc dma rx buffer failed");
126        }
127
128        for i in 0..RX_RING_SIZE {
129            rx_ring[i].addr = rx_mbufs_dma as u64;
130            rx_mbufs.push(rx_mbufs_vaddr);
131            rx_mbufs_dma += MBUF_SIZE;
132            rx_mbufs_vaddr += MBUF_SIZE;
133        }
134
135        // Slice切片,内存連續的動態大小的序列;
136        // array, 数组
137        // Vec, 内存連續的可增長數組類型
138
139        // 寄存器读写。写自己存器时,先写一遍,再读一遍,确保值写成功。
140        // ptr::write_volatile
141        // ptr::read_volatile
142
143        // 处理网络包的部分头字段
144        // impl<T: AsRef<[u8]> + AsMut<[u8]>> Packet<T>
145        // 或? vcell::VolatileCell
146
147        /* volatile = "0.4.5"
148        let regs = unsafe{ from_raw_parts_mut(mapped_regs as *mut u32, len) };
149        let regs = Volatile::new(regs);
150        regs.index_mut(E1000_IMS).write(0);
151
152        #[repr(transparent)]
153        只能用于只有单个非零大小字段(可能还有其他零大小字段,如PhantomData<T>)的
154        struct或enum 中。使得整个结构的内存布局和ABI被保证与该非零字段相同。
155        */
156        // 0x00000 ~ 0x1FFFF, I/O-Mapped Internal Registers and Memories
157        let len = 0x1FFFF / size_of::<u32>();
158        // 处理网卡寄存器配置: 由一个指针和一个长度len形成一个slice切片。len是元素的个数,而非字节数。
159        let regs = unsafe { from_raw_parts_mut(mapped_regs as *mut Volatile<u32>, len) };
160
161        let mut e1000dev = E1000Device {
162            regs,
163            rx_ring_dma,
164            tx_ring_dma,
165            rx_ring,
166            tx_ring,
167            rx_mbufs,
168            tx_mbufs,
169            mbuf_size: MBUF_SIZE,
170            kfn,
171        };
172        e1000dev.e1000_init();
173
174        Ok(e1000dev)
175    }
176
177    /// Initialize e1000 driver  
178    /// mapped_regs is the memory address at which the e1000's registers are mapped.
179    pub fn e1000_init(&mut self) {
180        let stat = self.regs[E1000_STAT].read();
181        let ctl = self.regs[E1000_CTL].read();
182        info!("e1000 CTL: {:#x}, Status: {:#x}", ctl, stat);
183
184        // Reset the device
185        self.regs[E1000_IMS].write(0); // disable interrupts
186        self.regs[E1000_CTL].write(ctl | E1000_CTL_RST);
187        self.regs[E1000_IMS].write(0); // redisable interrupts
188
189        // 内存壁垒 fence
190        //__sync_synchronize();
191        fence_w();
192
193        // [E1000 14.5] Transmit initialization
194        if (self.tx_ring.len() * size_of::<TxDesc>()) % 128 != 0 {
195            //panic("e1000");
196            error!("e1000, size of tx_ring is invalid");
197        }
198        self.regs[E1000_TDBAL].write(self.tx_ring_dma as u32);
199
200        self.regs[E1000_TDLEN].write((self.tx_ring.len() * size_of::<TxDesc>()) as u32);
201        self.regs[E1000_TDT].write(0);
202        self.regs[E1000_TDH].write(0);
203
204        // [E1000 14.4] Receive initialization
205        if (self.rx_ring.len() * size_of::<RxDesc>()) % 128 != 0 {
206            error!("e1000, size of rx_ring is invalid");
207        }
208        self.regs[E1000_RDBAL].write(self.rx_ring_dma as u32);
209
210        self.regs[E1000_RDH].write(0);
211        self.regs[E1000_RDT].write((RX_RING_SIZE - 1) as u32);
212        self.regs[E1000_RDLEN].write((self.rx_ring.len() * size_of::<RxDesc>()) as u32);
213
214        // filter by qemu's MAC address, 52:54:00:12:34:56
215        self.regs[E1000_RA].write(0x12005452);
216        self.regs[E1000_RA + 1].write(0x5534 | (1 << 31));
217        // multicast table
218        for i in 0..(4096 / 32) {
219            self.regs[E1000_MTA + i].write(0);
220        }
221        // transmitter control bits.
222        self.regs[E1000_TCTL].write(
223            E1000_TCTL_EN |  // enable
224            E1000_TCTL_PSP |                  // pad short packets
225            (0x10 << E1000_TCTL_CT_SHIFT) |   // collision stuff
226            (0x40 << E1000_TCTL_COLD_SHIFT),
227        );
228        self.regs[E1000_TIPG].write(10 | (8 << 10) | (6 << 20)); // inter-pkt gap
229
230        // receiver control bits.
231        self.regs[E1000_RCTL].write(
232            E1000_RCTL_EN | // enable receiver
233            E1000_RCTL_BAM |                 // enable broadcast
234            E1000_RCTL_SZ_2048 |             // 2048-byte rx buffers
235            E1000_RCTL_SECRC,
236        ); // strip CRC
237
238        self.regs[E1000_TIDV].write(0);
239        self.regs[E1000_TADV].write(0);
240        // ask e1000 for receive interrupts.
241        self.regs[E1000_RDTR].write(0); // interrupt after every received packet (no timer)
242        self.regs[E1000_RADV].write(0); // interrupt after every packet (no timer)
243        self.regs[E1000_IMS].write(1 << 7); // RXT0 - Receiver Timer Interrupt , RXDW -- Receiver Descriptor Write Back
244
245        self.regs[E1000_ICR].read(); // clear ints
246        self.e1000_write_flush();
247        info!("e1000_init has been completed");
248    }
249
250    /// Transmitting network packets
251    pub fn e1000_transmit(&mut self, packet: &[u8]) -> i32 {
252        let tindex = self.regs[E1000_TDT].read() as usize;
253        info!("Read E1000_TDT = {:#x}", tindex);
254        if (self.tx_ring[tindex].status & E1000_TXD_STAT_DD as u8) == 0 {
255            error!("E1000 hasn't finished the corresponding previous transmission request");
256            return -1;
257        }
258
259        let mut length = packet.len();
260        if length > self.mbuf_size {
261            error!("The packet: {} to be send is TOO LARGE", length);
262            length = min(length, self.mbuf_size);
263        }
264
265        let mbuf = unsafe { from_raw_parts_mut(self.tx_mbufs[tindex] as *mut u8, length) };
266        mbuf.copy_from_slice(packet);
267
268        info!(">>>>>>>>> TX PKT {}", length);
269        info!("\n\r");
270        //print_hex_dump(tx_mbuf, 64);
271
272        self.tx_ring[tindex].length = length as u16;
273        self.tx_ring[tindex].status = 0;
274        self.tx_ring[tindex].cmd = (E1000_TXD_CMD_RS | E1000_TXD_CMD_EOP) as u8;
275
276        self.regs[E1000_TDT].write(((tindex + 1) % TX_RING_SIZE) as u32);
277
278        self.e1000_write_flush();
279        // sync
280        fence_w();
281
282        length as i32
283    }
284
285    // Todo: send and recv lock
286    /// Receiving network packets
287    pub fn e1000_recv(&mut self) -> Option<Vec<Vec<u8>>> {
288        // Check for packets that have arrived from the e1000
289        // Create and deliver an mbuf for each packet (using net_rx()).
290        //let mut recv_packets = VecDeque::new();
291        let mut recv_packets = Vec::new();
292        let mut rindex = (self.regs[E1000_RDT].read() as usize + 1) % RX_RING_SIZE;
293        // DD设为1时,内存中的接收包是完整的
294        while (self.rx_ring[rindex].status & E1000_RXD_STAT_DD as u8) != 0 {
295            info!("Read E1000_RDT + 1 = {:#x}", rindex);
296            let len = self.rx_ring[rindex].length as usize;
297            let mbuf = unsafe { from_raw_parts_mut(self.rx_mbufs[rindex] as *mut u8, len) };
298            info!("RX PKT {} <<<<<<<<<", len);
299            //recv_packets.push_back(mbuf.to_vec());
300            recv_packets.push(mbuf.to_vec());
301
302            // Deliver the mbuf to the network stack
303            net_rx(mbuf);
304
305            fence();
306            // Just need to clear 64 bits header
307            mbuf[..min(64, len)].fill(0);
308
309            self.rx_ring[rindex].status = 0;
310            self.regs[E1000_RDT].write(rindex as u32);
311
312            self.e1000_write_flush();
313            // sync
314            fence_w();
315
316            rindex = (rindex + 1) % RX_RING_SIZE;
317        }
318        info!("e1000_recv\n\r");
319
320        if recv_packets.len() > 0 {
321            Some(recv_packets)
322        } else {
323            None
324        }
325    }
326    
327    // 参考
328    // xv6_for_internet_os
329    // https://xiayingp.gitbook.io/build_a_os/labs/lab-10-networking-part-1
330    // https://blog.mky.moe/mit6828/10-lab10/
331
332    /// Clear Interrupt
333    pub fn e1000_irq_disable(&mut self) {
334        self.regs[E1000_IMC].write(!0);
335        self.e1000_write_flush();
336    }
337
338    /// Enable Interrupts
339    pub fn e1000_irq_enable(&mut self) {
340        self.regs[E1000_IMS].write(IMS_ENABLE_MASK);
341        self.e1000_write_flush();
342    }
343
344    /// flush e1000 status
345    pub fn e1000_write_flush(&mut self) {
346        self.regs[E1000_STAT].read();
347    }
348
349    /// Cause a link status change interrupt
350    pub fn e1000_cause_lsc_int(&mut self) {
351        self.regs[E1000_ICS].write(E1000_ICR_LSC);
352    }
353
354    /// To handle e1000 interrupt
355    pub fn e1000_intr(&mut self) -> u32 {
356        //self.e1000_recv();
357
358        // tell the e1000 we've seen this interrupt;
359        // without this the e1000 won't raise any
360        // further interrupts.
361        self.regs[E1000_ICR].read()
362    }
363}
364
365/// called by e1000 driver's interrupt handler to deliver a packet to the
366/// networking stack
367pub fn net_rx(packet: &mut [u8]) {
368    /*
369    struct eth *ethhdr;
370    uint16 type;
371
372    ethhdr = mbufpullhdr(m, *ethhdr);
373    if (!ethhdr) {
374      mbuffree(m);
375      return;
376    }
377
378    type = ntohs(ethhdr->type);
379    if (type == ETHTYPE_IP)
380      net_rx_ip(m);
381    else if (type == ETHTYPE_ARP)
382      net_rx_arp(m);
383    else
384      mbuffree(m);
385
386      */
387}