- __critical while (!ao_radio_dma_done)
- ao_sleep(&ao_radio_dma_done);
- ao_mutex_put(&ao_radio_mutex);
- return (ao_radio_dma_done & AO_DMA_DONE);
+
+ /* Wait for DMA to be done, for the radio receive process to
+ * get aborted or for a receive timeout to fire
+ */
+ __critical while (!ao_radio_dma_done && !ao_radio_abort)
+ if (ao_sleep(&ao_radio_dma_done))
+ break;
+
+ /* If recv was aborted, clean up by stopping the DMA engine
+ * and idling the radio
+ */
+ if (!ao_radio_dma_done) {
+ ao_dma_abort(ao_radio_dma);
+ ao_radio_idle();
+ }
+ ao_radio_put();
+ return ao_radio_dma_done;
+}
+
+/*
+ * Wake up a task waiting to receive a radio packet
+ * and tell them to abort the transfer
+ */
+
+void
+ao_radio_recv_abort(void)
+{
+ ao_radio_abort = 1;
+ ao_wakeup(&ao_radio_dma_done);