fixeria has submitted this change. (
https://gerrit.osmocom.org/c/osmocom-bb/+/30239 )
Change subject: trxcon: rework l1sched_trigger(), split l1sched_pull_burst()
......................................................................
trxcon: rework l1sched_trigger(), split l1sched_pull_burst()
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.
Split off the main part from l1sched_trigger() to l1sched_pull_burst().
While at it, rename l1sched_trigger() to l1sched_pull_send_frame().
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, 85 insertions(+), 81 deletions(-)
Approvals:
laforge: Looks good to me, but someone else must approve
fixeria: Looks good to me, approved
pespin: Looks good to me, but someone else must approve
Jenkins Builder: Verified
diff --git a/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h
b/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h
index 3dfafb3..31d4b64 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);
+
+void l1sched_pull_burst(struct l1sched_state *sched, struct l1sched_burst_req *br);
+void l1sched_pull_send_frame(struct l1sched_state *sched);
/* 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 ccafd7b..f9eadaf 100644
--- a/src/host/trxcon/src/sched_clck.c
+++ b/src/host/trxcon/src/sched_clck.c
@@ -82,7 +82,7 @@
GSM_TDMA_FN_INC(sched->fn_counter_proc);
/* Trigger the scheduler */
- l1sched_trigger(sched);
+ l1sched_pull_send_frame(sched);
}
osmo_timer_schedule(&sched->clock_timer, 0,
@@ -95,7 +95,7 @@
sched->fn_counter_proc = fn;
/* Trigger the scheduler */
- l1sched_trigger(sched);
+ l1sched_pull_send_frame(sched);
/* Schedule first FN clock */
sched->clock = *tv_now;
@@ -176,7 +176,7 @@
GSM_TDMA_FN_INC(sched->fn_counter_proc);
/* Trigger the scheduler */
- l1sched_trigger(sched);
+ l1sched_pull_send_frame(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 c36b7de..2ac6904 100644
--- a/src/host/trxcon/src/sched_trx.c
+++ b/src/host/trxcon/src/sched_trx.c
@@ -85,102 +85,104 @@
static void l1sched_a5_burst_enc(struct l1sched_lchan_state *lchan,
struct l1sched_burst_req *br);
-void l1sched_trigger(struct l1sched_state *sched)
+/* Pull an Uplink burst from the scheduler and store it to br->burst[].
+ * The TDMA Fn advance must be applied by the caller (if needed).
+ * The given *br must be initialized by the caller. */
+void l1sched_pull_burst(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);
+}
+
+/* Pull *and send* Uplink bursts for all timeslots and the current TDMA Fn. */
+void l1sched_pull_send_frame(struct l1sched_state *sched)
+{
/* Advance TDMA frame number in order to give the transceiver
* more time to handle the burst before the actual transmission. */
const uint32_t fn = GSM_TDMA_FN_SUM(sched->fn_counter_proc,
sched->fn_counter_advance);
/* 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_pull_burst(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: 5
Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>
Gerrit-CC: msuraev <msuraev(a)sysmocom.de>
Gerrit-MessageType: merged