fixeria has uploaded this change for review. (
https://gerrit.osmocom.org/c/osmocom-bb/+/30239 )
Change subject: trxcon: rework l1sched_trigger(), split l1sched_trigger_all()
......................................................................
trxcon: rework l1sched_trigger(), split l1sched_trigger_all()
The key idea is to allow triggering the scheduler only for a specific
timeslot of a frame, while keeping the API for triggering all together.
Change-Id: Ibb7f9d7de26733f21b0753a2c655a250286bf1f0
Related: OS#5599
---
M src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h
M src/host/trxcon/src/sched_clck.c
M src/host/trxcon/src/sched_trx.c
3 files changed, 86 insertions(+), 84 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/39/30239/1
diff --git a/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h
b/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h
index eb95c85..e73bab4 100644
--- a/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h
+++ b/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h
@@ -490,7 +490,9 @@
/* Clock and Downlink scheduling trigger */
int l1sched_clck_handle(struct l1sched_state *sched, uint32_t fn);
void l1sched_clck_reset(struct l1sched_state *sched);
-void l1sched_trigger(struct l1sched_state *sched, uint32_t fn);
+
+void l1sched_trigger(struct l1sched_state *sched, struct l1sched_burst_req *br);
+void l1sched_trigger_all(struct l1sched_state *sched, uint32_t fn);
/* External L1 API, must be implemented by the API user */
int l1sched_handle_config_req(struct l1sched_state *sched,
diff --git a/src/host/trxcon/src/sched_clck.c b/src/host/trxcon/src/sched_clck.c
index 5862d0a..6cc0898 100644
--- a/src/host/trxcon/src/sched_clck.c
+++ b/src/host/trxcon/src/sched_clck.c
@@ -44,9 +44,9 @@
/* Advance TDMA frame number in order to give the transceiver
* more time to handle the burst before the actual transmission. */
-#define l1sched_trigger_advance(sched) \
- l1sched_trigger((sched), GSM_TDMA_FN_SUM((sched)->fn_counter_proc, \
- (sched)->fn_counter_advance))
+#define l1sched_trigger_all_advance(sched) \
+ l1sched_trigger_all((sched), GSM_TDMA_FN_SUM((sched)->fn_counter_proc, \
+ (sched)->fn_counter_advance))
static void l1sched_clck_tick(void *data)
{
@@ -88,7 +88,7 @@
GSM_TDMA_FN_INC(sched->fn_counter_proc);
/* Trigger the scheduler */
- l1sched_trigger_advance(sched);
+ l1sched_trigger_all_advance(sched);
}
osmo_timer_schedule(&sched->clock_timer, 0,
@@ -101,7 +101,7 @@
sched->fn_counter_proc = fn;
/* Trigger the scheduler */
- l1sched_trigger_advance(sched);
+ l1sched_trigger_all_advance(sched);
/* Schedule first FN clock */
sched->clock = *tv_now;
@@ -182,7 +182,7 @@
GSM_TDMA_FN_INC(sched->fn_counter_proc);
/* Trigger the scheduler */
- l1sched_trigger_advance(sched);
+ l1sched_trigger_all_advance(sched);
}
/* Schedule next FN to be transmitted */
diff --git a/src/host/trxcon/src/sched_trx.c b/src/host/trxcon/src/sched_trx.c
index bef8cc2..abab0db 100644
--- a/src/host/trxcon/src/sched_trx.c
+++ b/src/host/trxcon/src/sched_trx.c
@@ -85,97 +85,97 @@
static void l1sched_a5_burst_enc(struct l1sched_lchan_state *lchan,
struct l1sched_burst_req *br);
-void l1sched_trigger(struct l1sched_state *sched, uint32_t fn)
+/* Trigger the scheduler for a single TDMA timeslot indicated in the given br */
+void l1sched_trigger(struct l1sched_state *sched, struct l1sched_burst_req *br)
{
- struct l1sched_burst_req br[TRX_TS_COUNT];
+ struct l1sched_ts *ts = sched->ts[br->tn];
const struct l1sched_tdma_frame *frame;
struct l1sched_lchan_state *lchan;
l1sched_lchan_tx_func *handler;
enum l1sched_lchan_type chan;
uint8_t offset;
- struct l1sched_ts *ts;
- unsigned int tn;
+ /* Timeslot is not allocated */
+ if (ts == NULL)
+ return;
+
+ /* Timeslot is not configured */
+ if (ts->mf_layout == NULL)
+ return;
+
+ /* Get frame from multiframe */
+ offset = br->fn % ts->mf_layout->period;
+ frame = ts->mf_layout->frames + offset;
+
+ /* Get required info from frame */
+ br->bid = frame->ul_bid;
+ chan = frame->ul_chan;
+ handler = l1sched_lchan_desc[chan].tx_fn;
+
+ /* Omit lchans without handler */
+ if (!handler)
+ return;
+
+ /* Make sure that lchan was allocated and activated */
+ lchan = l1sched_find_lchan(ts, chan);
+ if (lchan == NULL)
+ return;
+
+ /* Omit inactive lchans */
+ if (!lchan->active)
+ return;
+
+ /**
+ * If we aren't processing any primitive yet,
+ * attempt to obtain a new one from queue
+ */
+ if (lchan->prim == NULL)
+ lchan->prim = l1sched_prim_dequeue(&ts->tx_prims, br->fn, lchan);
+
+ /* TODO: report TX buffers health to the higher layers */
+
+ /* If CBTX (Continuous Burst Transmission) is assumed */
+ if (l1sched_lchan_desc[chan].flags & L1SCHED_CH_FLAG_CBTX) {
+ /**
+ * Probably, a TX buffer is empty. Nevertheless,
+ * we shall continuously transmit anything on
+ * CBTX channels.
+ */
+ if (lchan->prim == NULL)
+ l1sched_prim_dummy(lchan);
+ }
+
+ /* If there is no primitive, do nothing */
+ if (lchan->prim == NULL)
+ return;
+
+ /* Handover RACH needs to be handled regardless of the
+ * current channel type and the associated handler. */
+ if (L1SCHED_PRIM_IS_RACH(lchan->prim) && lchan->prim->chan !=
L1SCHED_RACH)
+ handler = l1sched_lchan_desc[L1SCHED_RACH].tx_fn;
+
+ /* Poke lchan handler */
+ handler(lchan, br);
+
+ /* Perform A5/X burst encryption if required */
+ if (lchan->a5.algo)
+ l1sched_a5_burst_enc(lchan, br);
+}
+
+/* Trigger the scheduler for all timeslots of the given TDMA Fn */
+void l1sched_trigger_all(struct l1sched_state *sched, uint32_t fn)
+{
/* Iterate over timeslot list */
- for (tn = 0; tn < ARRAY_SIZE(br); tn++) {
- /* Initialize the buffer for this timeslot */
- br[tn] = (struct l1sched_burst_req) {
+ for (unsigned int tn = 0; tn < ARRAY_SIZE(sched->ts); tn++) {
+ struct l1sched_burst_req br = {
.fn = fn,
.tn = tn,
.burst_len = 0, /* NOPE.ind */
};
- /* Timeslot is not allocated */
- ts = sched->ts[tn];
- if (ts == NULL)
- continue;
-
- /* Timeslot is not configured */
- if (ts->mf_layout == NULL)
- continue;
-
- /* Get frame from multiframe */
- offset = fn % ts->mf_layout->period;
- frame = ts->mf_layout->frames + offset;
-
- /* Get required info from frame */
- br[tn].bid = frame->ul_bid;
- chan = frame->ul_chan;
- handler = l1sched_lchan_desc[chan].tx_fn;
-
- /* Omit lchans without handler */
- if (!handler)
- continue;
-
- /* Make sure that lchan was allocated and activated */
- lchan = l1sched_find_lchan(ts, chan);
- if (lchan == NULL)
- continue;
-
- /* Omit inactive lchans */
- if (!lchan->active)
- continue;
-
- /**
- * If we aren't processing any primitive yet,
- * attempt to obtain a new one from queue
- */
- if (lchan->prim == NULL)
- lchan->prim = l1sched_prim_dequeue(&ts->tx_prims, fn, lchan);
-
- /* TODO: report TX buffers health to the higher layers */
-
- /* If CBTX (Continuous Burst Transmission) is assumed */
- if (l1sched_lchan_desc[chan].flags & L1SCHED_CH_FLAG_CBTX) {
- /**
- * Probably, a TX buffer is empty. Nevertheless,
- * we shall continuously transmit anything on
- * CBTX channels.
- */
- if (lchan->prim == NULL)
- l1sched_prim_dummy(lchan);
- }
-
- /* If there is no primitive, do nothing */
- if (lchan->prim == NULL)
- continue;
-
- /* Handover RACH needs to be handled regardless of the
- * current channel type and the associated handler. */
- if (L1SCHED_PRIM_IS_RACH(lchan->prim) && lchan->prim->chan !=
L1SCHED_RACH)
- handler = l1sched_lchan_desc[L1SCHED_RACH].tx_fn;
-
- /* Poke lchan handler */
- handler(lchan, &br[tn]);
-
- /* Perform A5/X burst encryption if required */
- if (lchan->a5.algo)
- l1sched_a5_burst_enc(lchan, &br[tn]);
+ l1sched_trigger(sched, &br);
+ l1sched_handle_burst_req(sched, &br);
}
-
- /* Send all bursts for this TDMA frame */
- for (tn = 0; tn < ARRAY_SIZE(br); tn++)
- l1sched_handle_burst_req(sched, &br[tn]);
}
void l1sched_logging_init(int log_cat_common, int log_cat_data)
--
To view, visit
https://gerrit.osmocom.org/c/osmocom-bb/+/30239
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-Change-Id: Ibb7f9d7de26733f21b0753a2c655a250286bf1f0
Gerrit-Change-Number: 30239
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-MessageType: newchange