Add document for e1000 driver

master
Jiajie Chen 6 years ago
parent af9a978a9d
commit 6f1953b977

@ -34,9 +34,28 @@ pub struct E1000 {
send_buffers: Vec<usize>,
recv_page: usize,
recv_buffers: Vec<usize>,
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<Mutex<E1000>>);
@ -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<u32>, self.size / 4) };
let e1000 =
unsafe { slice::from_raw_parts_mut(self.header as *mut Volatile<u32>, self.size / 4) };
let send_queue_size = PAGE_SIZE / size_of::<E1000SendDesc>();
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<u32>, self.size / 4) };
let e1000 =
unsafe { slice::from_raw_parts_mut(self.header as *mut Volatile<u32>, self.size / 4) };
let recv_queue_size = PAGE_SIZE / size_of::<E1000RecvDesc>();
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<u32>, driver.size / 4) };
let e1000 = unsafe {
slice::from_raw_parts_mut(driver.header as *mut Volatile<u32>, driver.size / 4)
};
let recv_queue_size = PAGE_SIZE / size_of::<E1000RecvDesc>();
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<u32>, driver.size / 4) };
let e1000 = unsafe {
slice::from_raw_parts_mut(driver.header as *mut Volatile<u32>, driver.size / 4)
};
let send_queue_size = PAGE_SIZE / size_of::<E1000SendDesc>();
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<u32>, 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)));

Loading…
Cancel
Save