Skip to content

Commit ddcb6b6

Browse files
committed
Make EthernetDMA actually drop safe
1 parent 76f2da4 commit ddcb6b6

File tree

3 files changed

+29
-0
lines changed

3 files changed

+29
-0
lines changed

src/dma/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,15 @@ impl<'rx, 'tx> EthernetDMA<'rx, 'tx> {
281281
}
282282
}
283283

284+
impl Drop for EthernetDMA<'_, '_> {
285+
// On drop, stop all DMA actions.
286+
fn drop(&mut self) {
287+
self.tx_ring.stop(&self.eth_dma);
288+
289+
self.rx_ring.stop(&self.eth_dma);
290+
}
291+
}
292+
284293
#[cfg(feature = "ptp")]
285294
impl EthernetDMA<'_, '_> {
286295
/// Try to get the timestamp for the given packet ID.

src/dma/rx/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,16 @@ impl<'a> RxRing<'a> {
8181
self.demand_poll();
8282
}
8383

84+
/// Stop the RX DMA
85+
pub(crate) fn stop(&self, eth_dma: &ETHERNET_DMA) {
86+
eth_dma.dmaomr.modify(|_, w| w.sr().clear_bit());
87+
88+
// DMA accesses do not stop before the running state
89+
// of the DMA has changed to something other than
90+
// running.
91+
while self.running_state().is_running() {}
92+
}
93+
8494
/// Demand that the DMA engine polls the current `RxDescriptor`
8595
/// (when in [`RunningState::Stopped`].)
8696
fn demand_poll(&self) {

src/dma/tx/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,16 @@ impl<'ring> TxRing<'ring> {
6868
eth_dma.dmaomr.modify(|_, w| w.st().set_bit());
6969
}
7070

71+
/// Stop the TX DMA
72+
pub(crate) fn stop(&self, eth_dma: &ETHERNET_DMA) {
73+
eth_dma.dmaomr.modify(|_, w| w.st().clear_bit());
74+
75+
// DMA accesses do not stop before the running state
76+
// of the DMA has changed to something other than
77+
// running.
78+
while self.is_running() {}
79+
}
80+
7181
/// If this returns `true`, the next `send` will succeed.
7282
pub fn next_entry_available(&self) -> bool {
7383
!self.entries[self.next_entry].is_available()

0 commit comments

Comments
 (0)