#include <debug.h>
#include <arm.h>
+#include <asm/system.h>
#include <osmocore/msgb.h>
#include <layer1/sync.h>
+#include <layer1/async.h>
#include <layer1/mframe_sched.h>
#include <layer1/sched_gsmtime.h>
#include <layer1/l23_api.h>
extern const struct tdma_sched_item rach_sched_set_ul[];
-/* When altering data structures used by L1 Sync part, we need to
- * make sure to temporarily disable IRQ/FIQ to keep data consistent */
-static inline void l1a_lock_sync(void)
-{
- arm_disable_interrupts();
-}
-
-static inline void l1a_unlock_sync(void)
-{
- arm_enable_interrupts();
-}
-
/* safely enable a message into the L1S TX queue */
void l1a_txq_msgb_enq(struct llist_head *queue, struct msgb *msg)
{
- l1a_lock_sync();
- msgb_enqueue(queue, msg);
- l1a_unlock_sync();
-}
-
-/* request a RACH request at the next multiframe T3 = fn51 */
-void l1a_rach_req(uint8_t fn51, uint8_t ra)
-{
- uint32_t fn_sched;
+ unsigned long flags;
- l1a_lock_sync();
- l1s.rach.ra = ra;
- /* TODO: can we wrap here? I don't think so */
- fn_sched = l1s.current_time.fn - l1s.current_time.t3;
- fn_sched += fn51;
- sched_gsmtime(rach_sched_set_ul, fn_sched, 0);
- l1a_unlock_sync();
+ local_firq_save(flags);
+ msgb_enqueue(queue, msg);
+ local_irq_restore(flags);
}
/* Enable a repeating multiframe task */
void l1a_mftask_enable(enum mframe_task task)
{
- /* we don't need locking here as L1S only reads mf_tasks */
- l1s.mf_tasks |= (1 << task);
+ /* we don't need locking here as L1S only reads mframe.tasks */
+ mframe_enable(task);
}
/* Disable a repeating multiframe task */
void l1a_mftask_disable(enum mframe_task task)
{
- /* we don't need locking here as L1S only reads mf_tasks */
- l1s.mf_tasks &= ~(1 << task);
+ /* we don't need locking here as L1S only reads mframe.tasks */
+ mframe_disable(task);
+}
+
+/* Set the mask for repeating multiframe tasks */
+void l1a_mftask_set(uint32_t tasks)
+{
+ /* we don't need locking here as L1S only reads mframe.tasks */
+ mframe_set(tasks);
}
/* Initialize asynchronous part of Layer1 */
{
l1a_l23api_init();
}
+
+/* Execute pending L1A completions */
+void l1a_compl_execute(void)
+{
+ unsigned long flags;
+ unsigned int scheduled;
+ unsigned int i;
+
+ /* get and reset the currently scheduled tasks */
+ local_firq_save(flags);
+ scheduled = l1s.scheduled_compl;
+ l1s.scheduled_compl = 0;
+ local_irq_restore(flags);
+
+ /* Iterate over list of scheduled completions, call their
+ * respective completion handler */
+ for (i = 0; i < 32; i++) {
+ if (!(scheduled & (1 << i)))
+ continue;
+ /* call completion function */
+ l1s.completion[i](i);
+ }
+}