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 <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <[email protected]>
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: pespin <[email protected]>
Gerrit-CC: msuraev <[email protected]>
Gerrit-MessageType: merged

Reply via email to