aboutsummaryrefslogtreecommitdiff
path: root/src/bd/rxbd.rs
diff options
context:
space:
mode:
authorIan McIntyre <ianpmcintyre@gmail.com>2023-10-22 18:23:56 -0400
committerIan McIntyre <ianpmcintyre@gmail.com>2023-11-26 15:11:27 -0500
commitc7e5123f6604fbb9ca510f01af9b60e777bf57b4 (patch)
tree3eea4d033a5b091d6d52da6d45f754b3be0de132 /src/bd/rxbd.rs
First commit
A prototype of an i.MX RT ENET driver. There's design decisions I'm thinking of changing. Nevertheless, the smoltcp support seems to be working; an 1170EVK can act as a DHCP client and a TCP loopback server.
Diffstat (limited to 'src/bd/rxbd.rs')
-rw-r--r--src/bd/rxbd.rs95
1 files changed, 95 insertions, 0 deletions
diff --git a/src/bd/rxbd.rs b/src/bd/rxbd.rs
new file mode 100644
index 0000000..8523d6e
--- /dev/null
+++ b/src/bd/rxbd.rs
@@ -0,0 +1,95 @@
+//! Enhanced receive buffer descriptor layout and fields.
+
+use ral_registers::{RORegister, RWRegister};
+
+#[repr(C)]
+pub struct RxBD {
+ pub data_length: RORegister<u16>,
+ pub flags: RWRegister<u16>,
+ pub data_buffer_pointer: RWRegister<u32>,
+ pub status: RWRegister<u16>,
+ pub control: RWRegister<u16>,
+ pub checksum: RORegister<u16>,
+ pub header: RORegister<u16>,
+ _reserved0: [u16; 1],
+ pub last_bdu: RWRegister<u16>,
+ pub timestamp_1588: RORegister<u32>,
+ _reserved1: [u16; 4],
+}
+
+bdfields!(flags, u16,
+ empty [ offset = 15, bits = 1, ],
+ ro1 [ offset = 14, bits = 1, ],
+ wrap [ offset = 13, bits = 1, ],
+ ro2 [ offset = 12, bits = 1, ],
+ last [ offset = 11, bits = 1, ],
+
+ miss [ offset = 8, bits = 1, ],
+ broadcast [ offset = 7, bits = 1, ],
+ multicast [ offset = 6, bits = 1, ],
+ length_violation [ offset = 5, bits = 1, ],
+ non_octet_violation [ offset = 4, bits = 1, ],
+
+ crc_error [ offset = 2, bits = 1, ],
+ overrun [ offset = 1, bits = 1, ],
+ truncated [ offset = 0, bits = 1, ],
+);
+
+bdfields!(status, u16,
+ vlan_priority [ offset = 13, bits = 3, ],
+ ip_checksum_error [ offset = 5, bits = 1, ],
+ protocol_checksum_error [ offset = 4, bits = 1, ],
+ vlan [ offset = 2, bits = 1, ],
+ ipv6 [ offset = 1, bits = 1, ],
+ frag [ offset = 0, bits = 1, ],
+);
+
+bdfields!(control, u16,
+ mac_error [ offset = 15, bits = 1, ],
+ phy_error [ offset = 10, bits = 1, ],
+ collision [ offset = 9, bits = 1, ],
+ unicast [ offset = 8, bits = 1, ],
+ interrupt [ offset = 7, bits = 1, ],
+);
+
+bdfields!(header, u16,
+ length [ offset = 11, bits = 5, ],
+ protocol [ offset = 0, bits = 8, ],
+);
+
+bdfields!(last_bdu, u16,
+ last_bdu [ offset = 15, bits = 1, ],
+);
+
+#[cfg(test)]
+mod tests {
+ use core::ptr::addr_of;
+
+ use super::RxBD;
+
+ fn zeroed() -> RxBD {
+ // Safety: zero bitpattern is fine for primitive fields.
+ unsafe { core::mem::MaybeUninit::zeroed().assume_init() }
+ }
+
+ #[test]
+ fn field_offsets() {
+ let rxbd = zeroed();
+ let start = &rxbd as *const _ as *const u8;
+ assert_eq!(unsafe { start.add(0x0) }, addr_of!(rxbd.data_length).cast());
+ assert_eq!(unsafe { start.add(0x2) }, addr_of!(rxbd.flags).cast());
+ assert_eq!(
+ unsafe { start.add(0x4) },
+ addr_of!(rxbd.data_buffer_pointer).cast()
+ );
+ assert_eq!(unsafe { start.add(0x8) }, addr_of!(rxbd.status).cast());
+ assert_eq!(unsafe { start.add(0xA) }, addr_of!(rxbd.control).cast());
+ assert_eq!(unsafe { start.add(0xC) }, addr_of!(rxbd.checksum).cast());
+ assert_eq!(unsafe { start.add(0xE) }, addr_of!(rxbd.header).cast());
+ assert_eq!(unsafe { start.add(0x12) }, addr_of!(rxbd.last_bdu).cast());
+ assert_eq!(
+ unsafe { start.add(0x14) },
+ addr_of!(rxbd.timestamp_1588).cast()
+ );
+ }
+}