Use jumbo frame in ixgbe

master
Jiajie Chen 6 years ago
parent fffc330f47
commit cf3b183311

@ -23,7 +23,7 @@ pub const KERNEL_SIZE: usize = PML4_SIZE;
pub const KERNEL_HEAP_OFFSET: usize = KERNEL_OFFSET - PML4_SIZE; pub const KERNEL_HEAP_OFFSET: usize = KERNEL_OFFSET - PML4_SIZE;
pub const KERNEL_HEAP_PML4: usize = (KERNEL_HEAP_OFFSET & PML4_MASK) / PML4_SIZE; pub const KERNEL_HEAP_PML4: usize = (KERNEL_HEAP_OFFSET & PML4_MASK) / PML4_SIZE;
/// Size of kernel heap /// Size of kernel heap
pub const KERNEL_HEAP_SIZE: usize = 8 * 1024 * 1024; // 8 MB pub const KERNEL_HEAP_SIZE: usize = 64 * 1024 * 1024; // 64 MB
pub const MEMORY_OFFSET: usize = 0; pub const MEMORY_OFFSET: usize = 0;

@ -48,6 +48,10 @@ pub struct IXGBE {
#[derive(Clone)] #[derive(Clone)]
pub struct IXGBEDriver(Arc<Mutex<IXGBE>>); pub struct IXGBEDriver(Arc<Mutex<IXGBE>>);
// On linux, use ip link set <dev> mtu <MTU - 18>
const IXGBE_MTU: usize = 8000;
const IXGBE_BUFFER_SIZE: usize = PAGE_SIZE * 2;
const IXGBE_CTRL: usize = 0x00000 / 4; const IXGBE_CTRL: usize = 0x00000 / 4;
const IXGBE_STATUS: usize = 0x00008 / 4; const IXGBE_STATUS: usize = 0x00008 / 4;
const IXGBE_CTRL_EXT: usize = 0x00018 / 4; const IXGBE_CTRL_EXT: usize = 0x00018 / 4;
@ -85,6 +89,7 @@ const IXGBE_RXPBSIZE: usize = 0x03C00 / 4;
const IXGBE_RXPBSIZE_END: usize = 0x03C20 / 4; const IXGBE_RXPBSIZE_END: usize = 0x03C20 / 4;
const IXGBE_FCCFG: usize = 0x03D00 / 4; const IXGBE_FCCFG: usize = 0x03D00 / 4;
const IXGBE_HLREG0: usize = 0x04240 / 4; const IXGBE_HLREG0: usize = 0x04240 / 4;
const IXGBE_MAXFRS: usize = 0x04268 / 4;
const IXGBE_MFLCN: usize = 0x04294 / 4; const IXGBE_MFLCN: usize = 0x04294 / 4;
const IXGBE_AUTOC: usize = 0x042A0 / 4; const IXGBE_AUTOC: usize = 0x042A0 / 4;
const IXGBE_LINKS: usize = 0x042A4 / 4; const IXGBE_LINKS: usize = 0x042A4 / 4;
@ -354,7 +359,7 @@ impl<'a> phy::Device<'a> for IXGBEDriver {
fn capabilities(&self) -> DeviceCapabilities { fn capabilities(&self) -> DeviceCapabilities {
let mut caps = DeviceCapabilities::default(); let mut caps = DeviceCapabilities::default();
caps.max_transmission_unit = 1536; caps.max_transmission_unit = IXGBE_MTU; // max MTU
caps.max_burst_size = Some(64); caps.max_burst_size = Some(64);
// IP Rx checksum is offloaded with RXCSUM // IP Rx checksum is offloaded with RXCSUM
caps.checksum.ipv4 = Checksum::Tx; caps.checksum.ipv4 = Checksum::Tx;
@ -376,7 +381,7 @@ impl phy::TxToken for IXGBETxToken {
where where
F: FnOnce(&mut [u8]) -> Result<R>, F: FnOnce(&mut [u8]) -> Result<R>,
{ {
let mut buffer = [0u8; PAGE_SIZE]; let mut buffer = [0u8; IXGBE_BUFFER_SIZE];
let result = f(&mut buffer[..len]); let result = f(&mut buffer[..len]);
let mut driver = (self.0).0.lock(); let mut driver = (self.0).0.lock();
@ -660,7 +665,7 @@ pub fn ixgbe_init(name: String, irq: Option<u32>, header: usize, size: usize) {
// 2. Receive buffers of appropriate size should be allocated and pointers to these buffers should be stored in the descriptor ring. // 2. Receive buffers of appropriate size should be allocated and pointers to these buffers should be stored in the descriptor ring.
for i in 0..recv_queue_size { for i in 0..recv_queue_size {
let buffer_page = unsafe { let buffer_page = unsafe {
HEAP_ALLOCATOR.alloc_zeroed(Layout::from_size_align(PAGE_SIZE, PAGE_SIZE).unwrap()) HEAP_ALLOCATOR.alloc_zeroed(Layout::from_size_align(IXGBE_BUFFER_SIZE, PAGE_SIZE).unwrap())
} as usize; } as usize;
let buffer_page_pa = active_table().get_entry(buffer_page).unwrap().target(); let buffer_page_pa = active_table().get_entry(buffer_page).unwrap().target();
recv_queue[i].addr = buffer_page_pa as u64; recv_queue[i].addr = buffer_page_pa as u64;
@ -675,8 +680,8 @@ pub fn ixgbe_init(name: String, irq: Option<u32>, header: usize, size: usize) {
ixgbe[IXGBE_RDLEN].write(PAGE_SIZE as u32); // RDLEN ixgbe[IXGBE_RDLEN].write(PAGE_SIZE as u32); // RDLEN
// 5. Program SRRCTL associated with this queue according to the size of the buffers and the required header control. // 5. Program SRRCTL associated with this queue according to the size of the buffers and the required header control.
// Legacy descriptor, 4K buffer size // Legacy descriptor, 8K buffer size
ixgbe[IXGBE_SRRCTL].write((ixgbe[IXGBE_SRRCTL].read() & !0xf) | (4 << 0)); ixgbe[IXGBE_SRRCTL].write((ixgbe[IXGBE_SRRCTL].read() & !0xf) | (8 << 0));
ixgbe[IXGBE_RDH].write(0); // RDH ixgbe[IXGBE_RDH].write(0); // RDH
@ -709,16 +714,17 @@ pub fn ixgbe_init(name: String, irq: Option<u32>, header: usize, size: usize) {
// 4.6.8 Transmit Initialization // 4.6.8 Transmit Initialization
// Program the HLREG0 register according to the required MAC behavior. // Program the HLREG0 register according to the required MAC behavior.
// TXCRCEN | RXCRCSTRP | TXPADEN | RXLNGTHERREN // TXCRCEN | RXCRCSTRP | JUMBOEN | TXPADEN | RXLNGTHERREN
// ixgbe[IXGBE_HLREG0].write(ixgbe[IXGBE_HLREG0].read() & !(1 << 0) & !(1 << 1));
ixgbe[IXGBE_HLREG0] ixgbe[IXGBE_HLREG0]
.write(ixgbe[IXGBE_HLREG0].read() | (1 << 0) | (1 << 1) | (1 << 10) | (1 << 27)); .write(ixgbe[IXGBE_HLREG0].read() | (1 << 0) | (1 << 1) | (1 << 2) | (1 << 10) | (1 << 27));
// Set max MTU
ixgbe[IXGBE_MAXFRS].write((IXGBE_MTU as u32) << 16);
// The following steps should be done once per transmit queue: // The following steps should be done once per transmit queue:
// 1. Allocate a region of memory for the transmit descriptor list. // 1. Allocate a region of memory for the transmit descriptor list.
for i in 0..send_queue_size { for i in 0..send_queue_size {
let buffer_page = unsafe { let buffer_page = unsafe {
HEAP_ALLOCATOR.alloc_zeroed(Layout::from_size_align(PAGE_SIZE, PAGE_SIZE).unwrap()) HEAP_ALLOCATOR.alloc_zeroed(Layout::from_size_align(IXGBE_BUFFER_SIZE, PAGE_SIZE).unwrap())
} as usize; } as usize;
let buffer_page_pa = active_table().get_entry(buffer_page).unwrap().target(); let buffer_page_pa = active_table().get_entry(buffer_page).unwrap().target();
send_queue[i].addr = buffer_page_pa as u64; send_queue[i].addr = buffer_page_pa as u64;

Loading…
Cancel
Save