From 6f1953b9773d66cf7ab831c345a44e89036751c1 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Tue, 26 Feb 2019 23:03:04 +0800 Subject: [PATCH] Add document for e1000 driver --- kernel/src/drivers/net/e1000.rs | 149 +++++++++++++++++++------------- 1 file changed, 90 insertions(+), 59 deletions(-) diff --git a/kernel/src/drivers/net/e1000.rs b/kernel/src/drivers/net/e1000.rs index a00c65c..d570f3d 100644 --- a/kernel/src/drivers/net/e1000.rs +++ b/kernel/src/drivers/net/e1000.rs @@ -34,9 +34,28 @@ pub struct E1000 { send_buffers: Vec, recv_page: usize, recv_buffers: Vec, - first_trans: bool + first_trans: bool, } +const E1000_STATUS: usize = 0x0008 / 4; +const E1000_IMS: usize = 0x00D0 / 4; +const E1000_RCTL: usize = 0x0100 / 4; +const E1000_TCTL: usize = 0x0400 / 4; +const E1000_TIPG: usize = 0x0410 / 4; +const E1000_RDBAL: usize = 0x2800 / 4; +const E1000_RDBAH: usize = 0x2804 / 4; +const E1000_RDLEN: usize = 0x2808 / 4; +const E1000_RDH: usize = 0x2810 / 4; +const E1000_RDT: usize = 0x2818 / 4; +const E1000_TDBAL: usize = 0x3800 / 4; +const E1000_TDBAH: usize = 0x3804 / 4; +const E1000_TDLEN: usize = 0x3808 / 4; +const E1000_TDH: usize = 0x3810 / 4; +const E1000_TDT: usize = 0x3818 / 4; +const E1000_MTA: usize = 0x5200 / 4; +const E1000_RAL: usize = 0x5400 / 4; +const E1000_RAH: usize = 0x5404 / 4; + #[derive(Clone)] pub struct E1000Driver(Arc>); @@ -64,11 +83,13 @@ impl E1000 { current_addr = current_addr + PAGE_SIZE; } - let e1000 = unsafe { slice::from_raw_parts_mut(self.header as *mut Volatile, self.size / 4) }; + let e1000 = + unsafe { slice::from_raw_parts_mut(self.header as *mut Volatile, self.size / 4) }; let send_queue_size = PAGE_SIZE / size_of::(); - let mut send_queue = - unsafe { slice::from_raw_parts_mut(self.send_page as *mut E1000RecvDesc, send_queue_size) }; - let mut tdt = e1000[0x3818 / 4].read(); + let mut send_queue = unsafe { + slice::from_raw_parts_mut(self.send_page as *mut E1000RecvDesc, send_queue_size) + }; + let mut tdt = e1000[E1000_TDT].read(); let index = (tdt as usize + 1) % send_queue_size; let send_desc = &mut send_queue[index]; @@ -84,11 +105,13 @@ impl E1000 { current_addr = current_addr + PAGE_SIZE; } - let e1000 = unsafe { slice::from_raw_parts_mut(self.header as *mut Volatile, self.size / 4) }; + let e1000 = + unsafe { slice::from_raw_parts_mut(self.header as *mut Volatile, self.size / 4) }; let recv_queue_size = PAGE_SIZE / size_of::(); - let mut recv_queue = - unsafe { slice::from_raw_parts_mut(self.recv_page as *mut E1000RecvDesc, recv_queue_size) }; - let mut rdt = e1000[0x2818 / 4].read(); + let mut recv_queue = unsafe { + slice::from_raw_parts_mut(self.recv_page as *mut E1000RecvDesc, recv_queue_size) + }; + let mut rdt = e1000[E1000_RDT].read(); let index = (rdt as usize + 1) % recv_queue_size; let recv_desc = &mut recv_queue[index]; return (*recv_desc).status & 1 != 0; @@ -169,26 +192,28 @@ impl phy::RxToken for E1000RxToken { { let data = { let mut driver = (self.0).0.lock(); - let e1000 = unsafe { slice::from_raw_parts_mut(driver.header as *mut Volatile, driver.size / 4) }; + let e1000 = unsafe { + slice::from_raw_parts_mut(driver.header as *mut Volatile, driver.size / 4) + }; let recv_queue_size = PAGE_SIZE / size_of::(); - let mut recv_queue = - unsafe { slice::from_raw_parts_mut(driver.recv_page as *mut E1000RecvDesc, recv_queue_size) }; - let mut rdt = e1000[0x2818 / 4].read(); + let mut recv_queue = unsafe { + slice::from_raw_parts_mut(driver.recv_page as *mut E1000RecvDesc, recv_queue_size) + }; + let mut rdt = e1000[E1000_RDT].read(); let index = (rdt as usize + 1) % recv_queue_size; let recv_desc = &mut recv_queue[index]; assert!(recv_desc.status & 1 != 0); - let buffer = unsafe { slice::from_raw_parts(driver.recv_buffers[index] as *const u8, recv_desc.len as usize) }; - - println!("{:?}", recv_desc); - for i in 0..recv_desc.len { - print!("{:#X} ", buffer[i as usize]); - } - println!(""); + let buffer = unsafe { + slice::from_raw_parts( + driver.recv_buffers[index] as *const u8, + recv_desc.len as usize, + ) + }; recv_desc.status = recv_desc.status & !1; rdt = (rdt + 1) % recv_queue_size as u32; - e1000[0x2818 / 4].write(rdt); + e1000[E1000_RDT].write(rdt); buffer }; @@ -208,11 +233,14 @@ impl phy::TxToken for E1000TxToken { let mut driver = (self.0).0.lock(); - let e1000 = unsafe { slice::from_raw_parts_mut(driver.header as *mut Volatile, driver.size / 4) }; + let e1000 = unsafe { + slice::from_raw_parts_mut(driver.header as *mut Volatile, driver.size / 4) + }; let send_queue_size = PAGE_SIZE / size_of::(); - let mut send_queue = - unsafe { slice::from_raw_parts_mut(driver.send_page as *mut E1000SendDesc, send_queue_size) }; - let mut tdt = e1000[0x3818 / 4].read(); + let mut send_queue = unsafe { + slice::from_raw_parts_mut(driver.send_page as *mut E1000SendDesc, send_queue_size) + }; + let mut tdt = e1000[E1000_TDT].read(); let index_next = (tdt as usize + 1) % send_queue_size; let send_desc = &mut send_queue[index_next]; @@ -220,26 +248,24 @@ impl phy::TxToken for E1000TxToken { let index = (tdt as usize) % send_queue_size; let send_desc = &mut send_queue[index]; - let target = unsafe { slice::from_raw_parts_mut(driver.send_buffers[index] as *mut u8, len) }; + let target = + unsafe { slice::from_raw_parts_mut(driver.send_buffers[index] as *mut u8, len) }; target.copy_from_slice(&buffer[..len]); - println!("len {:?}", len); - let buffer_page_pa = active_table().get_entry(driver.send_buffers[index]).unwrap().target(); + let buffer_page_pa = active_table() + .get_entry(driver.send_buffers[index]) + .unwrap() + .target(); assert_eq!(buffer_page_pa, send_desc.addr as usize); send_desc.len = len as u16 + 4; + // RS | EOP send_desc.cmd = (1 << 3) | (1 << 0); send_desc.status = 0; - println!("{:?}", &send_queue[index]); - for i in 0..len { - print!("{:#X} ", target[i]); - } - println!("tdh {} tdt {}", e1000[0x3810 / 4].read(), e1000[0x3818 / 4].read()); - fence(Ordering::SeqCst); tdt = (tdt + 1) % send_queue_size as u32; - e1000[0x3818 / 4].write(tdt); + e1000[E1000_TDT].write(tdt); fence(Ordering::SeqCst); @@ -247,7 +273,7 @@ impl phy::TxToken for E1000TxToken { if tdt == 0 { driver.first_trans = false; } - + result } } @@ -313,14 +339,14 @@ pub fn e1000_init(header: usize, size: usize) { let e1000 = unsafe { slice::from_raw_parts_mut(header as *mut Volatile, size / 4) }; debug!( "status before setup: {:#?}", - E1000Status::from_bits_truncate(e1000[0x8 / 4].read()) + E1000Status::from_bits_truncate(e1000[E1000_STATUS].read()) ); - e1000[0x3800 / 4].write(send_page_pa as u32); // TDBAL - e1000[0x3804 / 4].write((send_page_pa >> 32) as u32); // TDBAH - e1000[0x3808 / 4].write(PAGE_SIZE as u32); // TDLEN - e1000[0x3810 / 4].write(0); // TDH - e1000[0x3818 / 4].write(0); // TDT + e1000[E1000_TDBAL].write(send_page_pa as u32); // TDBAL + e1000[E1000_TDBAH].write((send_page_pa >> 32) as u32); // TDBAH + e1000[E1000_TDLEN].write(PAGE_SIZE as u32); // TDLEN + e1000[E1000_TDH].write(0); // TDH + e1000[E1000_TDT].write(0); // TDT for i in 0..send_queue_size { let buffer_page = unsafe { @@ -331,32 +357,35 @@ pub fn e1000_init(header: usize, size: usize) { driver.send_buffers.push(buffer_page); } - e1000[0x400 / 4].write((1 << 1) | (1 << 3) | (0x10 << 4) | (0x40 << 12)); // TCTL - e1000[0x410 / 4].write(0xa | (0x8 << 10) | (0xc << 20)); // TIPG + // EN | PSP | CT=0x10 | COLD=0x40 + e1000[E1000_TCTL].write((1 << 1) | (1 << 3) | (0x10 << 4) | (0x40 << 12)); // TCTL + // IPGT=0xa | IPGR1=0x8 | IPGR2=0xc + e1000[E1000_TIPG].write(0xa | (0x8 << 10) | (0xc << 20)); // TIPG - let mut RAL: u32 = 0; - let mut RAH: u32 = 0; + let mut ral: u32 = 0; + let mut rah: u32 = 0; for i in 0..4 { - RAL = RAL | (mac[i] as u32) << (i * 8); + ral = ral | (mac[i] as u32) << (i * 8); } for i in 0..2 { - RAH = RAH | (mac[i + 4] as u32) << (i * 8); + rah = rah | (mac[i + 4] as u32) << (i * 8); } - e1000[0x5400 / 4].write(RAL); // RAL - e1000[0x5404 / 4].write(RAH | (1 << 31)); // RAH + e1000[E1000_RAL].write(ral); // RAL + // AV | AS=DA + e1000[E1000_RAH].write(rah | (1 << 31)); // RAH // MTA - for i in (0x5200 / 4)..(0x5400 / 4) { + for i in E1000_MTA..E1000_RAL { e1000[i].write(0); } - e1000[0xd0 / 4].write(0); // IMS + e1000[E1000_IMS].write(0); // IMS - e1000[0x2800 / 4].write(recv_page_pa as u32); // RDBAL - e1000[0x2804 / 4].write((recv_page_pa >> 32) as u32); // RDBAH - e1000[0x2808 / 4].write(PAGE_SIZE as u32); // RDLEN - e1000[0x2810 / 4].write(0); // RDH - e1000[0x2818 / 4].write((recv_queue_size - 1) as u32); // RDT + e1000[E1000_RDBAL].write(recv_page_pa as u32); // RDBAL + e1000[E1000_RDBAH].write((recv_page_pa >> 32) as u32); // RDBAH + e1000[E1000_RDLEN].write(PAGE_SIZE as u32); // RDLEN + e1000[E1000_RDH].write(0); // RDH + e1000[E1000_RDT].write((recv_queue_size - 1) as u32); // RDT for i in 0..recv_queue_size { let buffer_page = unsafe { @@ -367,11 +396,13 @@ pub fn e1000_init(header: usize, size: usize) { driver.recv_buffers.push(buffer_page); } - e1000[0x100 / 4].write((1 << 1) | (1 << 15) | (3 << 16) | (1 << 25) | (1 << 26)); // RCTL + // EN | BAM | BSIZE=3 | BSEX | SECRC + // BSIZE=3 | BSEX means buffer size = 4096 + e1000[E1000_RCTL].write((1 << 1) | (1 << 15) | (3 << 16) | (1 << 25) | (1 << 26)); // RCTL debug!( "status after setup: {:#?}", - E1000Status::from_bits_truncate(e1000[0x8 / 4].read()) + E1000Status::from_bits_truncate(e1000[E1000_STATUS].read()) ); let net_driver = E1000Driver(Arc::new(Mutex::new(driver)));