@@ -121,15 +121,11 @@ impl Device for RingbufferDevice {
121121 let mut header_buf: [ [ u8 ; 8 ] ; 1 ] = [ [ 0u8 ; 8 ] ; 1 ] ;
122122 self . rx_buffer . read_slice ( & mut header_buf, 0 ) ;
123123
124- // Extract CRC, sequence number, and length from header
125- let _stored_crc = u32:: from_le_bytes ( [
126- header_buf[ 0 ] [ 0 ] ,
127- header_buf[ 0 ] [ 1 ] ,
128- header_buf[ 0 ] [ 2 ] ,
129- header_buf[ 0 ] [ 3 ] ,
130- ] ) ;
131- let seq_num = u16:: from_le_bytes ( [ header_buf[ 0 ] [ 4 ] , header_buf[ 0 ] [ 5 ] ] ) ;
132- let packet_len = u16:: from_le_bytes ( [ header_buf[ 0 ] [ 6 ] , header_buf[ 0 ] [ 7 ] ] ) as usize ;
124+ // Extract CRC, sequence number, and length from header using direct pointer reads
125+ let header_ptr = header_buf[ 0 ] . as_ptr ( ) ;
126+ let _stored_crc = unsafe { ( header_ptr as * const u32 ) . read_unaligned ( ) } ;
127+ let seq_num = unsafe { ( header_ptr. add ( 4 ) as * const u16 ) . read_unaligned ( ) } ;
128+ let packet_len = unsafe { ( header_ptr. add ( 6 ) as * const u16 ) . read_unaligned ( ) } as usize ;
133129
134130 // Check if this is the same packet we saw before (based on sequence number)
135131 if seq_num == self . last_rx_seq {
@@ -151,29 +147,19 @@ impl Device for RingbufferDevice {
151147 // Calculate total packet size: header + payload
152148 let total_len = PACKET_HEADER_SIZE + packet_len;
153149 let num_words = total_len. div_ceil ( 8 ) ;
154- let mut buffer = [ [ 0u8 ; 8 ] ; ScatterUnit :: SCATTER_MEMORY_LEN ] ;
155- let words = & mut buffer[ ..num_words] ;
156150
157- // Copy entire packet from ringbuffer (header + payload)
158- self . rx_buffer . read_slice ( words, 0 ) ;
159-
160- // Convert to contiguous byte buffer
151+ // Allocate aligned buffer for reading from ringbuffer
152+ // Use a flat byte buffer and cast it to [[u8; 8]] for the API
161153 let mut packet_buffer = [ 0u8 ; ScatterUnit :: SCATTER_MEMORY_LEN * 8 ] ;
162- let mut idx = 0 ;
163- for word in words. iter ( ) {
164- for & byte in word. iter ( ) {
165- packet_buffer[ idx] = byte;
166- idx += 1 ;
167- if idx >= total_len {
168- break ;
169- }
170- }
171- if idx >= total_len {
172- break ;
173- }
174- }
175154
176- // Validate CRC
155+ let word_slice = unsafe {
156+ core:: slice:: from_raw_parts_mut ( packet_buffer. as_mut_ptr ( ) as * mut [ u8 ; 8 ] , num_words)
157+ } ;
158+
159+ // Copy entire packet from ringbuffer (header + payload)
160+ self . rx_buffer . read_slice ( word_slice, 0 ) ;
161+
162+ // Validate CRC (packet_buffer is already in the right format)
177163 if !is_valid ( & packet_buffer[ ..total_len] ) {
178164 trace ! ( "CRC validation failed for packet seq {}" , seq_num) ;
179165 return None ;
@@ -253,36 +239,33 @@ impl phy::TxToken for TxToken<'_> {
253239 // Prepare buffer: header + payload
254240 let mut buffer = [ 0u8 ; GatherUnit :: GATHER_MEMORY_LEN * 8 ] ;
255241
242+ // Write header fields using direct pointer writes
256243 // Header format: CRC32 (4 bytes) + sequence (2 bytes) + length (2 bytes)
257- // Checksum added later
258- buffer[ 4 ..6 ] . copy_from_slice ( & ( self . seq_num . to_le_bytes ( ) ) ) ;
259- buffer[ 6 ..8 ] . copy_from_slice ( & ( len as u16 ) . to_le_bytes ( ) ) ;
244+ let header_ptr = buffer. as_mut_ptr ( ) ;
245+ unsafe {
246+ // Write sequence and length (CRC written later after payload)
247+ ( header_ptr. add ( 4 ) as * mut u16 ) . write_unaligned ( self . seq_num . to_le ( ) ) ;
248+ ( header_ptr. add ( 6 ) as * mut u16 ) . write_unaligned ( ( len as u16 ) . to_le ( ) ) ;
249+ }
260250
261251 // Let smoltcp fill the packet data
262252 let result = f ( & mut buffer[ PACKET_HEADER_SIZE ..PACKET_HEADER_SIZE + len] ) ;
253+
263254 // Calculate total length and seal packet with CRC in header
264255 let total_len = PACKET_HEADER_SIZE + len;
265-
266256 let crc = CRC . checksum ( & buffer[ 4 ..total_len] ) ;
267- buffer[ 0 ..4 ] . copy_from_slice ( & ( crc. to_le_bytes ( ) ) ) ;
257+ unsafe {
258+ ( header_ptr as * mut u32 ) . write_unaligned ( crc. to_le ( ) ) ;
259+ }
268260
269- // Convert to word array for ringbuffer
261+ // Convert to word array for ringbuffer using pointer cast
270262 let num_words = total_len. div_ceil ( 8 ) ;
271- let max_words = GatherUnit :: GATHER_MEMORY_LEN ;
272- let mut word_buffer = [ [ 0u8 ; 8 ] ; GatherUnit :: GATHER_MEMORY_LEN ] ;
273-
274- for ( i, chunk) in buffer[ ..total_len] . chunks ( 8 ) . enumerate ( ) {
275- if i >= max_words {
276- break ;
277- }
278- for ( j, & byte) in chunk. iter ( ) . enumerate ( ) {
279- word_buffer[ i] [ j] = byte;
280- }
281- }
263+ // The buffer is correctly sized and alignment is maintained.
264+ let word_slice =
265+ unsafe { core:: slice:: from_raw_parts ( buffer. as_ptr ( ) as * const [ u8 ; 8 ] , num_words) } ;
282266
283267 // Write to ringbuffer starting at offset 0
284- let words = & word_buffer[ ..num_words. min ( max_words) ] ;
285- self . tx_buffer . write_slice ( words, 0 ) ;
268+ self . tx_buffer . write_slice ( word_slice, 0 ) ;
286269
287270 trace ! (
288271 "Transmitted packet: checksum {}, seq {}, total length {}" ,
0 commit comments