diff --git a/drivers/net/ixgbed/src/device.rs b/drivers/net/ixgbed/src/device.rs index fc7c009f1c..5f48d363a7 100644 --- a/drivers/net/ixgbed/src/device.rs +++ b/drivers/net/ixgbed/src/device.rs @@ -41,6 +41,9 @@ impl NetworkAdapter for Intel8259x { &mut *(self.receive_ring.as_ptr().add(self.receive_index) as *mut ixgbe_adv_rx_desc) }; + // Acquire fence pairs the device's write of status / + // length with our subsequent reads. + core::sync::atomic::fence(core::sync::atomic::Ordering::Acquire); let status = unsafe { desc.wb.upper.status_error }; if (status & IXGBE_RXDADV_STAT_DD) != 0 { @@ -63,6 +66,10 @@ impl NetworkAdapter for Intel8259x { desc.read.pkt_addr = self.receive_buffer[self.receive_index].physical() as u64; desc.read.hdr_addr = 0; + // Release fence ensures the buffer reads above are + // visible to the device before the RDT doorbell is + // observed. + core::sync::atomic::fence(core::sync::atomic::Ordering::Release); self.write_reg(IXGBE_RDT(0), self.receive_index as u32); self.receive_index = wrap_ring(self.receive_index, self.receive_ring.len()); @@ -120,6 +127,9 @@ impl NetworkAdapter for Intel8259x { self.transmit_index = wrap_ring(self.transmit_index, self.transmit_ring.len()); self.transmit_ring_free -= 1; + // Release fence ensures the buffer writes above are visible + // to the device before the TDT doorbell is observed. + core::sync::atomic::fence(core::sync::atomic::Ordering::Release); self.write_reg(IXGBE_TDT(0), self.transmit_index as u32); Ok(i)