Skip to content

Commit 324e81d

Browse files
Merge pull request #48 from dsgruss/master
Add checksum insertion and offloading
2 parents ae3a846 + 32a7ffd commit 324e81d

File tree

4 files changed

+33
-7
lines changed

4 files changed

+33
-7
lines changed

src/desc.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,15 @@ use core::ops::{Deref, DerefMut};
33
use aligned::{Aligned, A8};
44
use volatile_register::{RO, RW};
55

6+
#[cfg(not(feature = "stm32f107"))]
7+
const DESC_SIZE: usize = 8;
8+
9+
#[cfg(feature = "stm32f107")]
10+
const DESC_SIZE: usize = 4;
11+
612
#[repr(C)]
713
pub struct Descriptor {
8-
desc: Aligned<A8, [u32; 4]>,
14+
desc: Aligned<A8, [u32; DESC_SIZE]>,
915
}
1016

1117
impl Clone for Descriptor {
@@ -25,7 +31,7 @@ impl Default for Descriptor {
2531
impl Descriptor {
2632
pub const fn new() -> Self {
2733
Self {
28-
desc: Aligned([0; 4]),
34+
desc: Aligned([0; DESC_SIZE]),
2935
}
3036
}
3137

src/lib.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,9 @@ pub unsafe fn new_unchecked<'rx, 'tx>(
175175
// Duplex mode
176176
.dm()
177177
.set_bit()
178+
// IPv4 checksum offload
179+
.ipco()
180+
.set_bit()
178181
// Automatic pad/CRC stripping
179182
.apcs()
180183
.set_bit()
@@ -237,7 +240,12 @@ pub unsafe fn new_unchecked<'rx, 'tx>(
237240
eth_mmc.mmctimr.modify(|r, w| w.bits(r.bits() | (1 << 21)));
238241

239242
// bus mode register
240-
eth_dma.dmabmr.modify(|_, w|
243+
eth_dma.dmabmr.modify(|_, w| {
244+
// For any non-f107 chips, we must use enhanced descriptor format to support checksum
245+
// offloading and/or timestamps.
246+
#[cfg(not(feature = "stm32f107"))]
247+
let w = w.edfe().set_bit();
248+
241249
// Address-aligned beats
242250
w.aab()
243251
.set_bit()
@@ -255,7 +263,8 @@ pub unsafe fn new_unchecked<'rx, 'tx>(
255263
.bits(0b01)
256264
// Use separate PBL
257265
.usp()
258-
.set_bit());
266+
.set_bit()
267+
});
259268

260269
let mut dma = EthernetDMA {
261270
eth_dma,

src/smoltcp_phy.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{rx::RxPacket, tx::TxError, EthernetDMA};
22
use core::intrinsics::transmute;
3-
use smoltcp::phy::{Device, DeviceCapabilities, RxToken, TxToken};
3+
use smoltcp::phy::{ChecksumCapabilities, Device, DeviceCapabilities, RxToken, TxToken};
44
use smoltcp::time::Instant;
55
use smoltcp::Error;
66

@@ -13,6 +13,7 @@ impl<'a, 'rx, 'tx, 'b> Device<'a> for &'b mut EthernetDMA<'rx, 'tx> {
1313
let mut caps = DeviceCapabilities::default();
1414
caps.max_transmission_unit = super::MTU;
1515
caps.max_burst_size = Some(1);
16+
caps.checksum = ChecksumCapabilities::ignored();
1617
caps
1718
}
1819

src/tx.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ const TXDESC_0_IC: u32 = 1 << 30;
1818
const TXDESC_0_FS: u32 = 1 << 28;
1919
/// Last segment of frame
2020
const TXDESC_0_LS: u32 = 1 << 29;
21+
/// Checksum insertion control
22+
const TXDESC_0_CIC0: u32 = 1 << 23;
23+
const TXDESC_0_CIC1: u32 = 1 << 22;
2124
/// Transmit end of ring
2225
const TXDESC_0_TER: u32 = 1 << 21;
2326
/// Second address chained
@@ -115,8 +118,15 @@ impl RingDescriptor for TxDescriptor {
115118
fn setup(&mut self, buffer: *const u8, _len: usize, next: Option<&Self>) {
116119
// Defer this initialization to this function, so we can have `RingEntry` on bss.
117120
unsafe {
118-
self.desc
119-
.write(0, TXDESC_0_TCH | TXDESC_0_IC | TXDESC_0_FS | TXDESC_0_LS);
121+
self.desc.write(
122+
0,
123+
TXDESC_0_TCH
124+
| TXDESC_0_IC
125+
| TXDESC_0_FS
126+
| TXDESC_0_LS
127+
| TXDESC_0_CIC0
128+
| TXDESC_0_CIC1,
129+
);
120130
}
121131
self.set_buffer1(buffer);
122132
match next {

0 commit comments

Comments
 (0)