summaryrefslogtreecommitdiffstats
path: root/src/target
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2010-02-28 22:58:30 +0100
committerHarald Welte <laforge@gnumonks.org>2010-03-01 23:48:45 +0100
commit2f60aee6d93c509926fc017a80352fff62149992 (patch)
tree7858300f45854b8a23bb9ad96328af1c0bd4785a /src/target
parentaa4225d2cb41c8d42fa91e464a27f8af23c38bd8 (diff)
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.
Diffstat (limited to 'src/target')
-rw-r--r--src/target/firmware/include/layer1/sched_gsmtime.h3
-rw-r--r--src/target/firmware/include/layer1/tdma_sched.h13
-rw-r--r--src/target/firmware/layer1/async.c2
-rw-r--r--src/target/firmware/layer1/mframe_sched.c5
-rw-r--r--src/target/firmware/layer1/sched_gsmtime.c6
-rw-r--r--src/target/firmware/layer1/sync.c72
-rw-r--r--src/target/firmware/layer1/tdma_sched.c13
7 files changed, 61 insertions, 53 deletions
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 <calypso/dsp.h>
/* 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);