From 2f60aee6d93c509926fc017a80352fff62149992 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 28 Feb 2010 22:58:30 +0100 Subject: extend TDMA scheduler functions to use third parameter (p3) The idea of the third parameter is that it can be specified on a tdma_schedule_set() level. The multi-frame scheduler can thus use it to pass some context information into the l1s_{cmd,resp}_*() functions, such as the MF TASK and whether or not it is SDCCH or SACCH. --- src/target/firmware/include/layer1/sched_gsmtime.h | 3 +- src/target/firmware/include/layer1/tdma_sched.h | 13 ++-- src/target/firmware/layer1/async.c | 2 +- src/target/firmware/layer1/mframe_sched.c | 5 +- src/target/firmware/layer1/sched_gsmtime.c | 6 +- src/target/firmware/layer1/sync.c | 72 +++++++++++----------- src/target/firmware/layer1/tdma_sched.c | 13 ++-- 7 files changed, 61 insertions(+), 53 deletions(-) (limited to 'src/target') diff --git a/src/target/firmware/include/layer1/sched_gsmtime.h b/src/target/firmware/include/layer1/sched_gsmtime.h index d241fe05..5e9ec133 100644 --- a/src/target/firmware/include/layer1/sched_gsmtime.h +++ b/src/target/firmware/include/layer1/sched_gsmtime.h @@ -8,13 +8,14 @@ struct sched_gsmtime_event { struct llist_head list; struct tdma_sched_item *si; uint32_t fn; + uint16_t p3; /* parameter for TDMA scheduler */ }; /* initialize the GSMTIME scheduler */ void sched_gsmtime_init(void); /* Scheduling of a single event at a givnen GSM time */ -int sched_gsmtime(struct tdma_sched_item *si, uint32_t fn); +int sched_gsmtime(struct tdma_sched_item *si, uint32_t fn, uint16_t p3); /* execute all GSMTIME one-shot events pending for 'current_fn' */ int sched_gsmtime_execute(uint32_t current_fn); diff --git a/src/target/firmware/include/layer1/tdma_sched.h b/src/target/firmware/include/layer1/tdma_sched.h index 2f32a18a..40fcb479 100644 --- a/src/target/firmware/include/layer1/tdma_sched.h +++ b/src/target/firmware/include/layer1/tdma_sched.h @@ -13,13 +13,14 @@ #define TDMASCHED_NUM_FRAMES 25 #define TDMASCHED_NUM_CB 5 -typedef int tdma_sched_cb(uint16_t p1, uint16_t p2); +typedef int tdma_sched_cb(uint8_t p1, uint8_t p2, uint16_t p3); /* A single item in a TDMA scheduler bucket */ struct tdma_sched_item { tdma_sched_cb *cb; - uint16_t p1; - uint16_t p2; + uint8_t p1; + uint8_t p2; + uint16_t p3; }; /* A bucket inside the TDMA scheduler */ @@ -35,10 +36,10 @@ struct tdma_scheduler { }; /* Schedule an item at 'frame_offset' TDMA frames in the future */ -int tdma_schedule(uint8_t frame_offset, tdma_sched_cb *cb, uint16_t p1, uint16_t p2); +int tdma_schedule(uint8_t frame_offset, tdma_sched_cb *cb, uint8_t p1, uint8_t p2, uint16_t p3); /* Schedule a set of items starting from 'frame_offset' TDMA frames in the future */ -int tdma_schedule_set(uint8_t frame_offset, const struct tdma_sched_item *item_set); +int tdma_schedule_set(uint8_t frame_offset, const struct tdma_sched_item *item_set, uint16_t p3); /* Execute pre-scheduled events for current frame */ int tdma_sched_execute(void); @@ -53,7 +54,7 @@ void tdma_sched_reset(void); void tdma_sched_dump(void); -extern void tdma_end_set(uint16_t p1, uint16_t p2); +extern void tdma_end_set(uint8_t p1, uint8_t p2, uint16_t p3); #define SCHED_ITEM(x, y, z) { .cb = x, .p1 = y, .p2 = z } #define SCHED_END_FRAME() { .cb = NULL, .p1 = 0, .p2 = 0 } #define SCHED_END_SET() { .cb = &tdma_end_set, .p1 = 0, .p2 = 0 } diff --git a/src/target/firmware/layer1/async.c b/src/target/firmware/layer1/async.c index c1a457e4..d351709a 100644 --- a/src/target/firmware/layer1/async.c +++ b/src/target/firmware/layer1/async.c @@ -64,7 +64,7 @@ void l1a_rach_req(uint8_t fn51, uint8_t 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); + sched_gsmtime(rach_sched_set_ul, fn_sched, 0); l1a_unlock_sync(); } diff --git a/src/target/firmware/layer1/mframe_sched.c b/src/target/firmware/layer1/mframe_sched.c index 7bae6cad..502d102f 100644 --- a/src/target/firmware/layer1/mframe_sched.c +++ b/src/target/firmware/layer1/mframe_sched.c @@ -45,7 +45,7 @@ struct mframe_sched_item { /* At which number inside the modulo shall we be scheduled */ uint16_t frame_nr; /* bit-mask of flags */ - uint32_t flags; + uint16_t flags; }; /* FIXME: properly clean this up */ @@ -246,7 +246,8 @@ static void mframe_schedule_set(const struct mframe_sched_item *set) unsigned int current = (l1s.current_time.fn + SCHEDULE_AHEAD) % si->modulo; if (current == trigger) { /* FIXME: what to do with SACCH Flag etc? */ - tdma_schedule_set(SCHEDULE_AHEAD-SCHEDULE_LATENCY, si->sched_set); + tdma_schedule_set(SCHEDULE_AHEAD-SCHEDULE_LATENCY, + si->sched_set, si->flags); } } } diff --git a/src/target/firmware/layer1/sched_gsmtime.c b/src/target/firmware/layer1/sched_gsmtime.c index 86b51039..dabe15f8 100644 --- a/src/target/firmware/layer1/sched_gsmtime.c +++ b/src/target/firmware/layer1/sched_gsmtime.c @@ -34,7 +34,7 @@ static LLIST_HEAD(active_evts); static LLIST_HEAD(inactive_evts); /* Scheduling of a tdma_sched_item list one-shot at a givnen GSM time */ -int sched_gsmtime(struct tdma_sched_item *si, uint32_t fn) +int sched_gsmtime(struct tdma_sched_item *si, uint32_t fn, uint16_t p3) { struct llist_head *lh; struct sched_gsmtime_event *evt, *cur; @@ -50,6 +50,7 @@ int sched_gsmtime(struct tdma_sched_item *si, uint32_t fn) evt->fn = fn; evt->si = si; + evt->p3 = p3; /* do a sorted insert into the list, i.e. insert the new * event _before_ the first entry that has a higher fn */ @@ -82,7 +83,8 @@ int sched_gsmtime_execute(uint32_t fn) llist_for_each_entry_safe(evt, evt2, &active_evts, list) { if (evt->fn == fn + SCHEDULE_AHEAD) { printd("sched_gsmtime_execute(time=%u): fn=%u si=%p\n", fn, evt->fn, evt->si); - tdma_schedule_set(SCHEDULE_AHEAD-SCHEDULE_LATENCY, evt->si); + tdma_schedule_set(SCHEDULE_AHEAD-SCHEDULE_LATENCY, + evt->si, evt->p3); llist_del(&evt->list); /* put event back in list of inactive (free) events */ llist_add(&evt->list, &inactive_evts); diff --git a/src/target/firmware/layer1/sync.c b/src/target/firmware/layer1/sync.c index 8ad6d96b..1f01158d 100644 --- a/src/target/firmware/layer1/sync.c +++ b/src/target/firmware/layer1/sync.c @@ -400,7 +400,7 @@ static void l1_sync(void) /* ABORT command ********************************************************/ -static int l1s_abort_cmd(uint16_t p1, uint16_t p2) +static int l1s_abort_cmd(uint8_t p1, uint8_t p2, uint16_t p3) { putchart('A'); @@ -427,13 +427,13 @@ static int l1s_abort_cmd(uint16_t p1, uint16_t p2) void l1s_dsp_abort(void) { /* abort right now */ - tdma_schedule(0, &l1s_abort_cmd, 0, 0); + tdma_schedule(0, &l1s_abort_cmd, 0, 0, 0); } /* FCCH Burst *****************************************************************/ /* scheduler callback to issue a FB detection task to the DSP */ -static int l1s_fbdet_cmd(uint16_t p1, uint16_t fb_mode) +static int l1s_fbdet_cmd(uint8_t p1, uint8_t fb_mode, uint16_t p3) { if (fb_mode == 0) { putchart('F'); @@ -456,7 +456,7 @@ static int l1s_fbdet_cmd(uint16_t p1, uint16_t fb_mode) /* scheduler callback to check for a FB detection response */ -static int l1s_fbdet_resp(uint16_t p1, uint16_t attempt) +static int l1s_fbdet_resp(uint8_t p1, uint8_t attempt, uint16_t p3) { int ntdma, qbits, fn_offset; @@ -575,17 +575,17 @@ void l1s_fb_test(uint8_t base_fn, uint8_t fb_mode) #if 1 int i; /* schedule the FB detection command */ - tdma_schedule(base_fn, &l1s_fbdet_cmd, 0, fb_mode); + tdma_schedule(base_fn, &l1s_fbdet_cmd, 0, fb_mode, 0); /* schedule 12 attempts to read the result */ for (i = 1; i <= 12; i++) { uint8_t fn = base_fn + 1 + i; - tdma_schedule(fn, &l1s_fbdet_resp, 0, i); + tdma_schedule(fn, &l1s_fbdet_resp, 0, i, 0); } #else /* use the new scheduler 'set' and simply schedule the whole set */ /* WARNING: we cannot set FB_MODE_1 this way !!! */ - tdma_schedule_set(base_fn, fb_sched_set); + tdma_schedule_set(base_fn, fb_sched_set, 0); #endif } @@ -601,7 +601,7 @@ static uint8_t sb_cnt; extern const struct tdma_sched_item rach_sched_set_ul[]; -static int l1s_sbdet_resp(uint16_t p1, uint16_t attempt) +static int l1s_sbdet_resp(uint8_t p1, uint8_t attempt, uint16_t p3) { uint32_t sb; uint8_t bsic; @@ -713,7 +713,7 @@ static int l1s_sbdet_resp(uint16_t p1, uint16_t attempt) return 0; } -static int l1s_sbdet_cmd(uint16_t p1, uint16_t p2) +static int l1s_sbdet_cmd(uint8_t p1, uint8_t p2, uint16_t p3) { putchart('S'); @@ -734,21 +734,21 @@ void l1s_sb_test(uint8_t base_fn) { #if 1 /* This is how it is done by the TSM30 */ - tdma_schedule(base_fn, &l1s_sbdet_cmd, 0, 1); - tdma_schedule(base_fn + 1, &l1s_sbdet_cmd, 0, 2); - tdma_schedule(base_fn + 3, &l1s_sbdet_resp, 0, 1); - tdma_schedule(base_fn + 4, &l1s_sbdet_resp, 0, 2); + tdma_schedule(base_fn, &l1s_sbdet_cmd, 0, 1, 0); + tdma_schedule(base_fn + 1, &l1s_sbdet_cmd, 0, 2, 0); + tdma_schedule(base_fn + 3, &l1s_sbdet_resp, 0, 1, 0); + tdma_schedule(base_fn + 4, &l1s_sbdet_resp, 0, 2, 0); #else - tdma_schedule(base_fn, &l1s_sbdet_cmd, 0, 1); - tdma_schedule(base_fn + 1, &l1s_sbdet_resp, 0, 1); - tdma_schedule(base_fn + 2, &l1s_sbdet_resp, 0, 2); + tdma_schedule(base_fn, &l1s_sbdet_cmd, 0, 1, 0); + tdma_schedule(base_fn + 1, &l1s_sbdet_resp, 0, 1, 0); + tdma_schedule(base_fn + 2, &l1s_sbdet_resp, 0, 2, 0); #endif } /* Power Measurement **********************************************************/ /* scheduler callback to issue a power measurement task to the DSP */ -static int l1s_pm_cmd(uint16_t p1, uint16_t arfcn) +static int l1s_pm_cmd(uint8_t p1, uint8_t p2, uint16_t arfcn) { putchart('P'); @@ -766,7 +766,7 @@ static int l1s_pm_cmd(uint16_t p1, uint16_t arfcn) } /* scheduler callback to read power measurement resposnse from the DSP */ -static int l1s_pm_resp(uint16_t p1, uint16_t p2) +static int l1s_pm_resp(uint8_t p1, uint8_t p2, uint16_t p3) { uint16_t pm_level[2]; struct l1_signal sig; @@ -793,13 +793,13 @@ static int l1s_pm_resp(uint16_t p1, uint16_t p2) void l1s_pm_test(uint8_t base_fn, uint16_t arfcn) { - tdma_schedule(base_fn, &l1s_pm_cmd, 0, arfcn); - tdma_schedule(base_fn + 2, &l1s_pm_resp, 0, 0); + tdma_schedule(base_fn, &l1s_pm_cmd, 0, 0, arfcn); + tdma_schedule(base_fn + 2, &l1s_pm_resp, 0, 0, 0); } /* Normal Burst ***************************************************************/ -static int l1s_nb_resp(uint16_t p1, uint16_t burst_id) +static int l1s_nb_resp(uint8_t p1, uint8_t burst_id, uint16_t p3) { static struct l1_signal _nb_sig, *sig = &_nb_sig; struct msgb *msg; @@ -872,7 +872,7 @@ static int l1s_nb_resp(uint16_t p1, uint16_t burst_id) return 0; } -static int l1s_nb_cmd(uint16_t p1, uint16_t burst_id) +static int l1s_nb_cmd(uint8_t p1, uint8_t burst_id, uint16_t p3) { uint8_t tsc = l1s.serving_cell.bsic & 0x7; @@ -902,7 +902,7 @@ const struct tdma_sched_item nb_sched_set[] = { const uint8_t ubUui[23] = { 0x01, 0x03, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b }; /* p1: type of operation (0: one NB, 1: one RACH burst, 2: four NB */ -static int l1s_tx_resp(uint16_t p1, uint16_t burst_id) +static int l1s_tx_resp(uint8_t p1, uint8_t burst_id, uint16_t p3) { putchart('t'); @@ -933,7 +933,7 @@ static int l1s_tx_resp(uint16_t p1, uint16_t burst_id) static uint8_t loc_cnt = 0; /* p1: type of operation (0: one NB, 1: one RACH burst, 2: four NB */ -static int l1s_tx_cmd(uint16_t p1, uint16_t burst_id) +static int l1s_tx_cmd(uint8_t p1, uint8_t burst_id, uint16_t p3) { int i; uint8_t tsc; @@ -1035,20 +1035,20 @@ void l1s_tx_test(uint8_t base_fn, uint8_t type) printf("Starting TX %d\n", type); if (type == 0) {// one normal burst - tdma_schedule(base_fn, &l1s_tx_cmd, 0, 0); - tdma_schedule(base_fn + 2, &l1s_tx_resp, 0, 0); + tdma_schedule(base_fn, &l1s_tx_cmd, 0, 0, 0); + tdma_schedule(base_fn + 2, &l1s_tx_resp, 0, 0, 0); } else if (type == 1) { // one RACH burst - tdma_schedule(base_fn, &l1s_tx_cmd, 1, 0); - tdma_schedule(base_fn + 2, &l1s_tx_resp, 1, 0); + tdma_schedule(base_fn, &l1s_tx_cmd, 1, 0, 0); + tdma_schedule(base_fn + 2, &l1s_tx_resp, 1, 0, 0); } else if (type == 2) { // four normal burst - tdma_schedule(base_fn, &l1s_tx_cmd, 2, 0); - tdma_schedule(base_fn + 1, &l1s_tx_cmd, 2, 1); - tdma_schedule(base_fn + 2, &l1s_tx_resp, 2, 0); - tdma_schedule(base_fn + 2, &l1s_tx_cmd, 2, 2); - tdma_schedule(base_fn + 3, &l1s_tx_resp, 2, 1); - tdma_schedule(base_fn + 3, &l1s_tx_cmd, 2, 3); - tdma_schedule(base_fn + 4, &l1s_tx_resp, 2, 2); - tdma_schedule(base_fn + 5, &l1s_tx_resp, 2, 3); + tdma_schedule(base_fn, &l1s_tx_cmd, 2, 0, 0); + tdma_schedule(base_fn + 1, &l1s_tx_cmd, 2, 1, 0); + tdma_schedule(base_fn + 2, &l1s_tx_resp, 2, 0, 0); + tdma_schedule(base_fn + 2, &l1s_tx_cmd, 2, 2, 0); + tdma_schedule(base_fn + 3, &l1s_tx_resp, 2, 1, 0); + tdma_schedule(base_fn + 3, &l1s_tx_cmd, 2, 3, 0); + tdma_schedule(base_fn + 4, &l1s_tx_resp, 2, 2, 0); + tdma_schedule(base_fn + 5, &l1s_tx_resp, 2, 3, 0); } } diff --git a/src/target/firmware/layer1/tdma_sched.c b/src/target/firmware/layer1/tdma_sched.c index 0ed1a758..12296d78 100644 --- a/src/target/firmware/layer1/tdma_sched.c +++ b/src/target/firmware/layer1/tdma_sched.c @@ -33,7 +33,7 @@ #include /* dummy function to mark end of set */ -void tdma_end_set(uint16_t p1, uint16_t p2) +void tdma_end_set(uint8_t p1, uint8_t p2, uint16_t p3) { } @@ -49,7 +49,7 @@ static uint8_t wrap_bucket(uint8_t offset) } /* Schedule an item at 'frame_offset' TDMA frames in the future */ -int tdma_schedule(uint8_t frame_offset, tdma_sched_cb *cb, uint16_t p1, uint16_t p2) +int tdma_schedule(uint8_t frame_offset, tdma_sched_cb *cb, uint8_t p1, uint8_t p2, uint16_t p3) { struct tdma_scheduler *sched = &l1s.tdma_sched; uint8_t bucket_nr = wrap_bucket(frame_offset); @@ -66,12 +66,13 @@ int tdma_schedule(uint8_t frame_offset, tdma_sched_cb *cb, uint16_t p1, uint16_t sched_item->cb = cb; sched_item->p1 = p1; sched_item->p2 = p2; + sched_item->p3 = p3; return 0; } /* Schedule a set of items starting from 'frame_offset' TDMA frames in the future */ -int tdma_schedule_set(uint8_t frame_offset, const struct tdma_sched_item *item_set) +int tdma_schedule_set(uint8_t frame_offset, const struct tdma_sched_item *item_set, uint16_t p3) { struct tdma_scheduler *sched = &l1s.tdma_sched; uint8_t bucket_nr = wrap_bucket(frame_offset); @@ -97,7 +98,9 @@ int tdma_schedule_set(uint8_t frame_offset, const struct tdma_sched_item *item_s return -1; } /* copy the item from the set into the current bucket item position */ - memcpy(&bucket->item[bucket->num_items++], sched_item, sizeof(*sched_item)); + memcpy(&bucket->item[bucket->num_items], sched_item, sizeof(*sched_item)); + bucket->item[bucket->num_items].p3 = p3; + bucket->num_items++; } return i; @@ -131,7 +134,7 @@ int tdma_sched_execute(void) num_events++; - rc = item->cb(item->p1, item->p2); + rc = item->cb(item->p1, item->p2, item->p3); if (rc < 0) { printf("Error %d during processing of item %u of bucket %u\n", rc, i, sched->cur_bucket); -- cgit v1.2.3