summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVadim Yanitskiy <vyanitskiy@sysmocom.de>2023-07-10 02:04:48 +0700
committerVadim Yanitskiy <vyanitskiy@sysmocom.de>2023-07-12 03:52:34 +0700
commit21aacfe7096ef27fe40c22d20a86d2303f9cba91 (patch)
treeed76fb72d394e2ace84cfecaf0fcc686348e8714 /src
parenta22acea3a9db44d891080caaed8619114386afff (diff)
trxcon/l1sched: peoperly prioritize FACCH/H over TCH
Unlike FACCH/F, which steals one TCH frame, FACCH/H steals two TCH frames. This is what prim_dequeue_tchh() aims to implement, but the current implementation is not 100% correct. The problem is that we're attempting to dequeue and drop two TCH frames in one go, whenever we get a FACCH/H frame. Most likely, there will be no 2nd TCH frame in the Tx queue at that time, so it will never be dropped and will clog the queue. Let's replicate what osmo-bts-trx does: * dequeue and drop the 1st TCH frame when sending 1st/6 burst of FACCH, * dequeue and drop the 2nd TCH frame when sending 3rd/6 burst of FACCH. Change-Id: I513d6805ddf97783c002be285fb3ca7893e42377 Related: OS#4396, OS#1572
Diffstat (limited to 'src')
-rw-r--r--src/host/trxcon/src/sched_lchan_tchh.c48
1 files changed, 19 insertions, 29 deletions
diff --git a/src/host/trxcon/src/sched_lchan_tchh.c b/src/host/trxcon/src/sched_lchan_tchh.c
index 6affbc5d..67e21320 100644
--- a/src/host/trxcon/src/sched_lchan_tchh.c
+++ b/src/host/trxcon/src/sched_lchan_tchh.c
@@ -414,36 +414,23 @@ bfi:
static struct msgb *prim_dequeue_tchh(struct l1sched_lchan_state *lchan, uint32_t fn)
{
- struct msgb *facch;
- struct msgb *tch;
- bool facch_now;
-
- /* Can we initiate an UL FACCH/H frame transmission at this Fn? */
- facch_now = l1sched_tchh_facch_start(lchan->type, fn, true);
- if (!facch_now)
- goto no_facch;
-
- /* If there are no FACCH/H prims in the queue */
- facch = l1sched_lchan_prim_dequeue_tch(lchan, true);
- if (!facch) /* Just dequeue a TCH/H prim */
- goto no_facch;
-
- /* FACCH/H prim replaces two TCH/F prims */
- tch = l1sched_lchan_prim_dequeue_tch(lchan, false);
- if (tch) {
- /* At least one TCH/H prim is dropped */
- msgb_free(tch);
-
- /* Attempt to find another */
- tch = l1sched_lchan_prim_dequeue_tch(lchan, false);
- if (tch) /* Drop the second TCH/H prim */
- msgb_free(tch);
+ struct msgb *msg_facch;
+ struct msgb *msg_tch;
+
+ /* dequeue a pair of TCH and FACCH frames */
+ msg_tch = l1sched_lchan_prim_dequeue_tch(lchan, false);
+ if (l1sched_tchh_facch_start(lchan->type, fn, true))
+ msg_facch = l1sched_lchan_prim_dequeue_tch(lchan, true);
+ else
+ msg_facch = NULL;
+
+ /* prioritize FACCH over TCH */
+ if (msg_facch != NULL) {
+ msgb_free(msg_tch); /* drop 1st TCH/HS block */
+ return msg_facch;
}
- return facch;
-
-no_facch:
- return l1sched_lchan_prim_dequeue_tch(lchan, false);
+ return msg_tch;
}
int tx_tchh_fn(struct l1sched_lchan_state *lchan,
@@ -478,8 +465,11 @@ int tx_tchh_fn(struct l1sched_lchan_state *lchan,
*mask = *mask << 2;
/* If FACCH/H blocks are still pending */
- if (lchan->ul_facch_blocks > 2)
+ if (lchan->ul_facch_blocks > 2) {
+ struct msgb *msg = l1sched_lchan_prim_dequeue_tch(lchan, false);
+ msgb_free(msg); /* drop 2nd TCH/HS block */
goto send_burst;
+ }
lchan->prim = prim_dequeue_tchh(lchan, br->fn);
if (lchan->prim == NULL) {