eth: mtu clarification

This commit is contained in:
Robert Jördens 2019-04-29 17:29:02 +00:00
parent 9863ba3a33
commit cd284d2c07
1 changed files with 21 additions and 19 deletions

View File

@ -47,8 +47,6 @@ mod phy_consts {
}
use self::phy_consts::*;
pub const MTU: usize = 1536;
const EMAC_DES3_OWN: u32 = 0x8000_0000;
const EMAC_DES3_CTXT: u32 = 0x4000_0000;
const EMAC_DES3_FD: u32 = 0x2000_0000;
@ -61,11 +59,11 @@ const EMAC_RDES3_BUF1V: u32 = 0x0100_0000;
const EMAC_TDES2_B1L: u32 = 0x0000_3FFF;
const EMAC_DES0_BUF1AP: u32 = 0xFFFF_FFFF;
const ETH_DESC_U32_SIZE: usize = 4;
const ETH_TX_BUFFER_COUNT: usize = 4;
const ETH_TX_BUFFER_SIZE: usize = MTU;
const ETH_RX_BUFFER_COUNT: usize = 4;
const ETH_RX_BUFFER_SIZE: usize = MTU;
// 6 DMAC, 6 SMAC, 4 q tag, 2 ethernet type II, 1500 ip MTU, 4 CRC, 2 padding
const ETH_BUFFER_SIZE: usize = 1524;
const ETH_DESC_U32_SIZE: usize = 4;
const ETH_TX_BUFFER_COUNT: usize = 4;
const ETH_RX_BUFFER_COUNT: usize = 4;
#[allow(dead_code)]
mod cr_consts {
@ -171,7 +169,7 @@ fn phy_write(reg_addr: u8, reg_data: u16) {
w
.pa().bits(PHY_ADDR)
.rda().bits(reg_addr)
.goc().bits(0b01) // read
.goc().bits(0b01) // write
.cr().bits(CLOCK_RANGE)
.mb().set_bit()
});
@ -190,7 +188,7 @@ fn phy_write_ext(reg_addr: u16, reg_data: u16) {
#[repr(align(4))]
struct RxRing {
desc_buf: [[u32; ETH_DESC_U32_SIZE]; ETH_RX_BUFFER_COUNT],
pkt_buf: [[u8; ETH_RX_BUFFER_SIZE]; ETH_RX_BUFFER_COUNT],
pkt_buf: [[u8; ETH_BUFFER_SIZE]; ETH_RX_BUFFER_COUNT],
cur_desc: usize,
counter: u32,
}
@ -199,13 +197,16 @@ impl RxRing {
const fn new() -> Self {
Self {
desc_buf: [[0; ETH_DESC_U32_SIZE]; ETH_RX_BUFFER_COUNT],
pkt_buf: [[0; ETH_RX_BUFFER_SIZE]; ETH_RX_BUFFER_COUNT],
pkt_buf: [[0; ETH_BUFFER_SIZE]; ETH_RX_BUFFER_COUNT],
cur_desc: 0,
counter: 0,
}
}
fn init(&mut self) {
assert_eq!(self.desc_buf[0].len() % 4, 0);
assert_eq!(self.pkt_buf[0].len() % 4, 0);
for i in 0..self.desc_buf.len() {
for j in 0..self.desc_buf[0].len() {
self.desc_buf[i][j] = 0;
@ -231,7 +232,6 @@ impl RxRing {
for _ in 0..self.desc_buf.len() {
self.buf_release()
}
self.counter = 0;
}
fn next_desc(&self) -> usize {
@ -251,7 +251,7 @@ impl RxRing {
unsafe fn buf_as_slice<'a>(&self) -> &'a [u8] {
let len = (self.desc_buf[self.cur_desc][3] & EMAC_RDES3_PL) as usize;
let len = cmp::min(len, ETH_RX_BUFFER_SIZE);
let len = cmp::min(len, ETH_BUFFER_SIZE);
let addr = &self.pkt_buf[self.cur_desc] as *const u8;
slice::from_raw_parts(addr, len)
}
@ -268,14 +268,13 @@ impl RxRing {
});
self.cur_desc = self.next_desc();
self.counter += 1;
}
}
#[repr(align(4))]
struct TxRing {
desc_buf: [[u32; ETH_DESC_U32_SIZE]; ETH_TX_BUFFER_COUNT],
pkt_buf: [[u8; ETH_TX_BUFFER_SIZE]; ETH_TX_BUFFER_COUNT],
pkt_buf: [[u8; ETH_BUFFER_SIZE]; ETH_TX_BUFFER_COUNT],
cur_desc: usize,
counter: u32,
}
@ -284,13 +283,16 @@ impl TxRing {
const fn new() -> Self {
Self {
desc_buf: [[0; ETH_DESC_U32_SIZE]; ETH_TX_BUFFER_COUNT],
pkt_buf: [[0; ETH_TX_BUFFER_SIZE]; ETH_TX_BUFFER_COUNT],
pkt_buf: [[0; ETH_BUFFER_SIZE]; ETH_TX_BUFFER_COUNT],
cur_desc: 0,
counter: 0,
}
}
fn init(&mut self) {
assert_eq!(self.desc_buf[0].len() % 4, 0);
assert_eq!(self.pkt_buf[0].len() % 4, 0);
for i in 0..self.desc_buf.len() {
for j in 0..self.desc_buf[0].len() {
self.desc_buf[i][j] = 0;
@ -300,7 +302,6 @@ impl TxRing {
}
}
self.cur_desc = 0;
self.counter = 0;
cortex_m::interrupt::free(|_cs| unsafe {
let dma = &*stm32::ETHERNET_DMA::ptr();
@ -329,7 +330,7 @@ impl TxRing {
}
unsafe fn buf_as_slice_mut<'a>(&mut self, len: usize) -> &'a mut [u8] {
let len = cmp::min(len, ETH_TX_BUFFER_SIZE);
let len = cmp::min(len, ETH_BUFFER_SIZE);
self.desc_buf[self.cur_desc][2] = EMAC_TDES2_IOC | (len as u32 & EMAC_TDES2_B1L);
let addr = &self.pkt_buf[self.cur_desc] as *const _ as *mut u8;
self.desc_buf[self.cur_desc][0] = addr as u32 & EMAC_DES0_BUF1AP;
@ -339,7 +340,6 @@ impl TxRing {
fn buf_release(&mut self) {
self.desc_buf[self.cur_desc][3] = EMAC_DES3_OWN | EMAC_DES3_FD | EMAC_DES3_LD;
self.cur_desc = self.next_desc();
self.counter += 1;
let addr = &self.desc_buf[self.cur_desc] as *const _;
cortex_m::interrupt::free(|_cs| {
@ -508,7 +508,7 @@ impl Device {
eth_dma.dmacrx_cr.modify(|_, w| {
w
// receive buffer size
.rbsz().bits(MTU as u16)
.rbsz().bits(ETH_BUFFER_SIZE as u16)
// Rx DMA PBL
.rxpbl().bits(32)
// Disable flushing of received frames
@ -543,6 +543,8 @@ impl<'a, 'b> phy::Device<'a> for &'b mut Device {
fn capabilities(&self) -> phy::DeviceCapabilities {
let mut capabilities = phy::DeviceCapabilities::default();
// ethernet frame type II (6 smac, 6 dmac, 2 ethertype),
// sans CRC (4), 1500 IP MTU
capabilities.max_transmission_unit = 1514;
capabilities.max_burst_size = Some(self.tx.desc_buf.len());
capabilities