@@ -39,8 +39,6 @@ use crate::ethernet::StationManagement;
39
39
// 6 DMAC, 6 SMAC, 4 q tag, 2 ethernet type II, 1500 ip MTU, 4 CRC, 2
40
40
// padding
41
41
const ETH_BUF_SIZE : usize = 1536 ;
42
- const ETH_NUM_TD : usize = 4 ;
43
- const ETH_NUM_RD : usize = 4 ;
44
42
45
43
/// Transmit and Receive Descriptor fields
46
44
#[ allow( dead_code) ]
@@ -95,22 +93,22 @@ impl TDes {
95
93
96
94
/// Store a ring of TDes and associated buffers
97
95
#[ repr( C , packed) ]
98
- struct TDesRing {
99
- td : [ TDes ; ETH_NUM_TD ] ,
100
- tbuf : [ [ u32 ; ETH_BUF_SIZE / 4 ] ; ETH_NUM_TD ] ,
96
+ struct TDesRing < const TD : usize > {
97
+ td : [ TDes ; TD ] ,
98
+ tbuf : [ [ u32 ; ETH_BUF_SIZE / 4 ] ; TD ] ,
101
99
tdidx : usize ,
102
100
}
103
101
104
- impl TDesRing {
102
+ impl < const TD : usize > TDesRing < TD > {
105
103
const fn new ( ) -> Self {
106
104
Self {
107
105
td : [ TDes {
108
106
tdes0 : 0 ,
109
107
tdes1 : 0 ,
110
108
tdes2 : 0 ,
111
109
tdes3 : 0 ,
112
- } ; ETH_NUM_TD ] ,
113
- tbuf : [ [ 0 ; ETH_BUF_SIZE / 4 ] ; ETH_NUM_TD ] ,
110
+ } ; TD ] ,
111
+ tbuf : [ [ 0 ; ETH_BUF_SIZE / 4 ] ; TD ] ,
114
112
tdidx : 0 ,
115
113
}
116
114
}
@@ -121,8 +119,8 @@ impl TDesRing {
121
119
/// will be stored in the descriptors, so ensure the TDesRing is
122
120
/// not moved after initialisation.
123
121
pub fn init ( & mut self ) {
124
- for td in self . td . iter_mut ( ) {
125
- td . init ( ) ;
122
+ for x in 0 .. TD {
123
+ self . td [ x ] . init ( ) ;
126
124
}
127
125
self . tdidx = 0 ;
128
126
@@ -131,9 +129,8 @@ impl TDesRing {
131
129
unsafe {
132
130
let dma = & * stm32:: ETHERNET_DMA :: ptr ( ) ;
133
131
dma. dmactx_dlar
134
- . write ( |w| w. bits ( & self . td as * const _ as u32 ) ) ;
135
- dma. dmactx_rlr
136
- . write ( |w| w. tdrl ( ) . bits ( self . td . len ( ) as u16 - 1 ) ) ;
132
+ . write ( |w| w. bits ( & self . td [ 0 ] as * const _ as u32 ) ) ;
133
+ dma. dmactx_rlr . write ( |w| w. tdrl ( ) . bits ( TD as u16 - 1 ) ) ;
137
134
dma. dmactx_dtpr
138
135
. write ( |w| w. bits ( & self . td [ 0 ] as * const _ as u32 ) ) ;
139
136
}
@@ -166,7 +163,7 @@ impl TDesRing {
166
163
cortex_m:: asm:: dsb ( ) ;
167
164
168
165
// Move the tail pointer (TPR) to the next descriptor
169
- let x = ( x + 1 ) % ETH_NUM_TD ;
166
+ let x = ( x + 1 ) % TD ;
170
167
unsafe {
171
168
let dma = & * stm32:: ETHERNET_DMA :: ptr ( ) ;
172
169
dma. dmactx_dtpr
@@ -241,22 +238,22 @@ impl RDes {
241
238
242
239
/// Store a ring of RDes and associated buffers
243
240
#[ repr( C , packed) ]
244
- struct RDesRing {
245
- rd : [ RDes ; ETH_NUM_RD ] ,
246
- rbuf : [ [ u32 ; ETH_BUF_SIZE / 4 ] ; ETH_NUM_RD ] ,
241
+ struct RDesRing < const RD : usize > {
242
+ rd : [ RDes ; RD ] ,
243
+ rbuf : [ [ u32 ; ETH_BUF_SIZE / 4 ] ; RD ] ,
247
244
rdidx : usize ,
248
245
}
249
246
250
- impl RDesRing {
247
+ impl < const RD : usize > RDesRing < RD > {
251
248
const fn new ( ) -> Self {
252
249
Self {
253
250
rd : [ RDes {
254
251
rdes0 : 0 ,
255
252
rdes1 : 0 ,
256
253
rdes2 : 0 ,
257
254
rdes3 : 0 ,
258
- } ; ETH_NUM_RD ] ,
259
- rbuf : [ [ 0 ; ETH_BUF_SIZE / 4 ] ; ETH_NUM_RD ] ,
255
+ } ; RD ] ,
256
+ rbuf : [ [ 0 ; ETH_BUF_SIZE / 4 ] ; RD ] ,
260
257
rdidx : 0 ,
261
258
}
262
259
}
@@ -267,18 +264,17 @@ impl RDesRing {
267
264
/// will be stored in the descriptors, so ensure the RDesRing is
268
265
/// not moved after initialisation.
269
266
pub fn init ( & mut self ) {
270
- for rd in self . rd . iter_mut ( ) {
271
- rd . init ( ) ;
267
+ for x in 0 .. RD {
268
+ self . rd [ x ] . init ( ) ;
272
269
}
273
270
self . rdidx = 0 ;
274
271
275
272
// Initialise pointers in the DMA engine
276
273
unsafe {
277
274
let dma = & * stm32:: ETHERNET_DMA :: ptr ( ) ;
278
275
dma. dmacrx_dlar
279
- . write ( |w| w. bits ( & self . rd as * const _ as u32 ) ) ;
280
- dma. dmacrx_rlr
281
- . write ( |w| w. rdrl ( ) . bits ( self . rd . len ( ) as u16 - 1 ) ) ;
276
+ . write ( |w| w. bits ( & self . rd [ 0 ] as * const _ as u32 ) ) ;
277
+ dma. dmacrx_rlr . write ( |w| w. rdrl ( ) . bits ( RD as u16 - 1 ) ) ;
282
278
}
283
279
284
280
// Release descriptors to the DMA engine
@@ -325,7 +321,7 @@ impl RDesRing {
325
321
}
326
322
327
323
// Update active descriptor
328
- self . rdidx = ( x + 1 ) % ETH_NUM_RD ;
324
+ self . rdidx = ( x + 1 ) % RD ;
329
325
}
330
326
331
327
/// Access the buffer pointed to by the next RDes
@@ -347,24 +343,29 @@ impl RDesRing {
347
343
}
348
344
}
349
345
350
- pub struct DesRing {
351
- tx : TDesRing ,
352
- rx : RDesRing ,
346
+ pub struct DesRing < const TD : usize , const RD : usize > {
347
+ tx : TDesRing < TD > ,
348
+ rx : RDesRing < RD > ,
353
349
}
354
- impl DesRing {
355
- pub const fn new ( ) -> DesRing {
350
+ impl < const TD : usize , const RD : usize > DesRing < TD , RD > {
351
+ pub const fn new ( ) -> Self {
356
352
DesRing {
357
353
tx : TDesRing :: new ( ) ,
358
354
rx : RDesRing :: new ( ) ,
359
355
}
360
356
}
361
357
}
358
+ impl < const TD : usize , const RD : usize > Default for DesRing < TD , RD > {
359
+ fn default ( ) -> Self {
360
+ Self :: new ( )
361
+ }
362
+ }
362
363
363
364
///
364
365
/// Ethernet DMA
365
366
///
366
- pub struct EthernetDMA < ' a > {
367
- ring : & ' a mut DesRing ,
367
+ pub struct EthernetDMA < ' a , const TD : usize , const RD : usize > {
368
+ ring : & ' a mut DesRing < TD , RD > ,
368
369
eth_dma : stm32:: ETHERNET_DMA ,
369
370
}
370
371
@@ -393,15 +394,15 @@ pub struct EthernetMAC {
393
394
/// # Safety
394
395
///
395
396
/// `EthernetDMA` shall not be moved as it is initialised here
396
- pub unsafe fn new_unchecked < ' a > (
397
+ pub unsafe fn new_unchecked < ' a , const TD : usize , const RD : usize > (
397
398
eth_mac : stm32:: ETHERNET_MAC ,
398
399
eth_mtl : stm32:: ETHERNET_MTL ,
399
400
eth_dma : stm32:: ETHERNET_DMA ,
400
- ring : & ' a mut DesRing ,
401
+ ring : & ' a mut DesRing < TD , RD > ,
401
402
mac_addr : EthernetAddress ,
402
403
prec : rec:: Eth1Mac ,
403
404
clocks : & CoreClocks ,
404
- ) -> ( EthernetDMA < ' a > , EthernetMAC ) {
405
+ ) -> ( EthernetDMA < ' a , TD , RD > , EthernetMAC ) {
405
406
// RCC
406
407
{
407
408
let rcc = & * stm32:: RCC :: ptr ( ) ;
@@ -713,9 +714,9 @@ impl StationManagement for EthernetMAC {
713
714
}
714
715
715
716
/// Define TxToken type and implement consume method
716
- pub struct TxToken < ' a > ( & ' a mut TDesRing ) ;
717
+ pub struct TxToken < ' a , const TD : usize > ( & ' a mut TDesRing < TD > ) ;
717
718
718
- impl < ' a > phy:: TxToken for TxToken < ' a > {
719
+ impl < ' a , const TD : usize > phy:: TxToken for TxToken < ' a , TD > {
719
720
fn consume < R , F > (
720
721
self ,
721
722
_timestamp : Instant ,
@@ -734,9 +735,9 @@ impl<'a> phy::TxToken for TxToken<'a> {
734
735
}
735
736
736
737
/// Define RxToken type and implement consume method
737
- pub struct RxToken < ' a > ( & ' a mut RDesRing ) ;
738
+ pub struct RxToken < ' a , const RD : usize > ( & ' a mut RDesRing < RD > ) ;
738
739
739
- impl < ' a > phy:: RxToken for RxToken < ' a > {
740
+ impl < ' a , const RD : usize > phy:: RxToken for RxToken < ' a , RD > {
740
741
fn consume < R , F > ( self , _timestamp : Instant , f : F ) -> smoltcp:: Result < R >
741
742
where
742
743
F : FnOnce ( & mut [ u8 ] ) -> smoltcp:: Result < R > ,
@@ -748,9 +749,11 @@ impl<'a> phy::RxToken for RxToken<'a> {
748
749
}
749
750
750
751
/// Implement the smoltcp Device interface
751
- impl < ' a > phy:: Device < ' a > for EthernetDMA < ' _ > {
752
- type RxToken = RxToken < ' a > ;
753
- type TxToken = TxToken < ' a > ;
752
+ impl < ' a , const TD : usize , const RD : usize > phy:: Device < ' a >
753
+ for EthernetDMA < ' _ , TD , RD >
754
+ {
755
+ type RxToken = RxToken < ' a , RD > ;
756
+ type TxToken = TxToken < ' a , TD > ;
754
757
755
758
// Clippy false positive because DeviceCapabilities is non-exhaustive
756
759
#[ allow( clippy:: field_reassign_with_default) ]
@@ -759,11 +762,11 @@ impl<'a> phy::Device<'a> for EthernetDMA<'_> {
759
762
// ethernet frame type II (6 smac, 6 dmac, 2 ethertype),
760
763
// sans CRC (4), 1500 IP MTU
761
764
caps. max_transmission_unit = 1514 ;
762
- caps. max_burst_size = Some ( core:: cmp:: min ( ETH_NUM_TD , ETH_NUM_RD ) ) ;
765
+ caps. max_burst_size = Some ( core:: cmp:: min ( TD , RD ) ) ;
763
766
caps
764
767
}
765
768
766
- fn receive ( & mut self ) -> Option < ( RxToken , TxToken ) > {
769
+ fn receive ( & mut self ) -> Option < ( RxToken < RD > , TxToken < TD > ) > {
767
770
// Skip all queued packets with errors.
768
771
while self . ring . rx . available ( ) && !self . ring . rx . valid ( ) {
769
772
self . ring . rx . release ( )
@@ -776,7 +779,7 @@ impl<'a> phy::Device<'a> for EthernetDMA<'_> {
776
779
}
777
780
}
778
781
779
- fn transmit ( & mut self ) -> Option < TxToken > {
782
+ fn transmit ( & mut self ) -> Option < TxToken < TD > > {
780
783
if self . ring . tx . available ( ) {
781
784
Some ( TxToken ( & mut self . ring . tx ) )
782
785
} else {
@@ -785,7 +788,7 @@ impl<'a> phy::Device<'a> for EthernetDMA<'_> {
785
788
}
786
789
}
787
790
788
- impl EthernetDMA < ' _ > {
791
+ impl < const TD : usize , const RD : usize > EthernetDMA < ' _ , TD , RD > {
789
792
/// Return the number of packets dropped since this method was
790
793
/// last called
791
794
pub fn number_packets_dropped ( & self ) -> u32 {
0 commit comments