fixeria has uploaded this change for review. (
https://gerrit.osmocom.org/c/osmo-bts/+/31716 )
Change subject: osmo-bts-trx: properly activate [CBCH/]BCCH/CCCH
......................................................................
osmo-bts-trx: properly activate [CBCH/]BCCH/CCCH
The timeslot carrying BCCH/CCCH on C0 is a bit special in a way that
it's being activated implicitly - there is no explicit RSL CHANnel
ACTIVation for that. This is why we have TRX_CHAN_FLAG_AUTO_ACTIVE,
which marks sub-channels of BCCH/CCCH in the trx_chan_desc[].
The upcoming patch changes the burst buffer allocation strategy, so
that the memory is allocated on channel activation and then free()d
on channel release. This patch facilitates that by making the
activation/deactivation logic consistent for all sub-channels.
Change-Id: Id0c70d6a2b777a5117c85149bfa1b3a997299d1d
Related: OS#1572
---
M include/osmo-bts/scheduler.h
M src/common/scheduler.c
M src/osmo-bts-trx/l1_if.c
3 files changed, 113 insertions(+), 58 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/16/31716/1
diff --git a/include/osmo-bts/scheduler.h b/include/osmo-bts/scheduler.h
index 40b4293..01e8e2b 100644
--- a/include/osmo-bts/scheduler.h
+++ b/include/osmo-bts/scheduler.h
@@ -5,13 +5,6 @@
#include <osmo-bts/gsm_data.h>
-/* Whether a logical channel must be activated automatically */
-#define TRX_CHAN_FLAG_AUTO_ACTIVE (1 << 0)
-
-/* FIXME: we should actually activate 'auto-active' channels */
-#define TRX_CHAN_IS_ACTIVE(state, chan) \
- (trx_chan_desc[chan].flags & TRX_CHAN_FLAG_AUTO_ACTIVE || (state)->active)
-
#define TRX_GMSK_NB_TSC(br) \
_sched_train_seq_gmsk_nb[(br)->tsc_set][(br)->tsc]
@@ -192,6 +185,9 @@
/*! \brief set all matching logical channels active/inactive */
int trx_sched_set_lchan(struct gsm_lchan *lchan, uint8_t chan_nr, uint8_t link_id, bool
active);
+/*! \brief set all logical channels of BCCH/CCCH active/inactive */
+int trx_sched_set_bcch_ccch(struct gsm_lchan *lchan, bool active);
+
/*! \brief set mode of all matching logical channels to given mode(s) */
int trx_sched_set_mode(struct gsm_bts_trx_ts *ts, uint8_t chan_nr, uint8_t rsl_cmode,
uint8_t tch_mode, int codecs, uint8_t codec0, uint8_t codec1,
diff --git a/src/common/scheduler.c b/src/common/scheduler.c
index 14aff34..3189f07 100644
--- a/src/common/scheduler.c
+++ b/src/common/scheduler.c
@@ -150,7 +150,6 @@
.desc = "Frequency correction channel",
/* Tx only, frequency correction bursts */
- .flags = TRX_CHAN_FLAG_AUTO_ACTIVE,
.dl_fn = tx_fcch_fn,
},
[TRXC_SCH] = {
@@ -158,7 +157,6 @@
.desc = "Synchronization channel",
/* Tx only, synchronization bursts */
- .flags = TRX_CHAN_FLAG_AUTO_ACTIVE,
.dl_fn = tx_sch_fn,
},
[TRXC_BCCH] = {
@@ -169,7 +167,6 @@
/* Tx only, xCCH convolutional coding (3GPP TS 05.03, section 4.4),
* regular interleaving (3GPP TS 05.02, clause 7, table 3):
* a L2 frame is interleaved over 4 consecutive bursts. */
- .flags = TRX_CHAN_FLAG_AUTO_ACTIVE,
.rts_fn = rts_data_fn,
.dl_fn = tx_data_fn,
},
@@ -179,7 +176,6 @@
.chan_nr = RSL_CHAN_RACH,
/* Rx only, RACH convolutional coding (3GPP TS 05.03, section 4.6). */
- .flags = TRX_CHAN_FLAG_AUTO_ACTIVE,
.ul_fn = rx_rach_fn,
},
[TRXC_CCCH] = {
@@ -190,7 +186,6 @@
/* Tx only, xCCH convolutional coding (3GPP TS 05.03, section 4.4),
* regular interleaving (3GPP TS 05.02, clause 7, table 3):
* a L2 frame is interleaved over 4 consecutive bursts. */
- .flags = TRX_CHAN_FLAG_AUTO_ACTIVE,
.rts_fn = rts_data_fn,
.dl_fn = tx_data_fn,
},
@@ -575,7 +570,6 @@
.chan_nr = RSL_CHAN_OSMO_CBCH4,
/* Tx only, same as for TRXC_BCCH (xCCH), see above. */
- .flags = TRX_CHAN_FLAG_AUTO_ACTIVE,
.rts_fn = rts_data_fn,
.dl_fn = tx_data_fn,
},
@@ -1062,6 +1056,52 @@
}
}
+static void _trx_sched_set_lchan(struct gsm_lchan *lchan,
+ enum trx_chan_type chan,
+ bool active)
+{
+ struct l1sched_ts *l1ts = lchan->ts->priv;
+ struct l1sched_chan_state *chan_state;
+
+ OSMO_ASSERT(l1ts != NULL);
+ chan_state = &l1ts->chan_state[chan];
+
+ LOGPLCHAN(lchan, DL1C, LOGL_INFO, "%s %s\n",
+ (active) ? "Activating" : "Deactivating",
+ trx_chan_desc[chan].name);
+
+ /* free burst memory, to cleanly start with burst 0 */
+ if (chan_state->dl_bursts) {
+ talloc_free(chan_state->dl_bursts);
+ chan_state->dl_bursts = NULL;
+ }
+ if (chan_state->ul_bursts) {
+ talloc_free(chan_state->ul_bursts);
+ chan_state->ul_bursts = NULL;
+ }
+ if (chan_state->ul_bursts_prev) {
+ talloc_free(chan_state->ul_bursts_prev);
+ chan_state->ul_bursts_prev = NULL;
+ }
+
+ if (active) {
+ /* Clean up everything */
+ memset(chan_state, 0, sizeof(*chan_state));
+
+ /* Bind to generic 'struct gsm_lchan' */
+ chan_state->lchan = lchan;
+ } else {
+ chan_state->ho_rach_detect = 0;
+
+ /* Remove pending Tx prims belonging to this lchan */
+ trx_sched_queue_filter(&l1ts->dl_prims,
+ trx_chan_desc[chan].chan_nr,
+ trx_chan_desc[chan].link_id);
+ }
+
+ chan_state->active = active;
+}
+
/* setting all logical channels given attributes to active/inactive */
int trx_sched_set_lchan(struct gsm_lchan *lchan, uint8_t chan_nr, uint8_t link_id, bool
active)
{
@@ -1069,7 +1109,6 @@
uint8_t tn = L1SAP_CHAN2TS(chan_nr);
uint8_t ss = l1sap_chan2ss(chan_nr);
bool found = false;
- int i;
if (!l1ts) {
LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "%s lchan with uninitialized scheduler
structure\n",
@@ -1083,48 +1122,15 @@
chan_nr &= ~RSL_CHAN_OSMO_VAMOS_MASK;
/* look for all matching chan_nr/link_id */
- for (i = 0; i < _TRX_CHAN_MAX; i++) {
- struct l1sched_chan_state *chan_state = &l1ts->chan_state[i];
-
- if (trx_chan_desc[i].chan_nr != (chan_nr & RSL_CHAN_NR_MASK))
+ for (enum trx_chan_type chan = 0; chan < _TRX_CHAN_MAX; chan++) {
+ if (trx_chan_desc[chan].chan_nr != (chan_nr & RSL_CHAN_NR_MASK))
continue;
- if (trx_chan_desc[i].link_id != link_id)
+ if (trx_chan_desc[chan].link_id != link_id)
continue;
- if (chan_state->active == active)
+ if (l1ts->chan_state[chan].active == active)
continue;
found = true;
-
- LOGPLCHAN(lchan, DL1C, LOGL_INFO, "%s %s\n",
- (active) ? "Activating" : "Deactivating",
- trx_chan_desc[i].name);
- /* free burst memory, to cleanly start with burst 0 */
- if (chan_state->dl_bursts) {
- talloc_free(chan_state->dl_bursts);
- chan_state->dl_bursts = NULL;
- }
- if (chan_state->ul_bursts) {
- talloc_free(chan_state->ul_bursts);
- chan_state->ul_bursts = NULL;
- }
- if (chan_state->ul_bursts_prev) {
- talloc_free(chan_state->ul_bursts_prev);
- chan_state->ul_bursts_prev = NULL;
- }
-
- if (active) {
- /* Clean up everything */
- memset(chan_state, 0, sizeof(*chan_state));
-
- /* Bind to generic 'struct gsm_lchan' */
- chan_state->lchan = lchan;
- } else {
- chan_state->ho_rach_detect = 0;
-
- /* Remove pending Tx prims belonging to this lchan */
- trx_sched_queue_filter(&l1ts->dl_prims, chan_nr, link_id);
- }
-
- chan_state->active = active;
+ _trx_sched_set_lchan(lchan, chan, active);
}
/* disable handover detection (on deactivation) */
@@ -1134,6 +1140,31 @@
return found ? 0 : -EINVAL;
}
+int trx_sched_set_bcch_ccch(struct gsm_lchan *lchan, bool active)
+{
+ struct l1sched_ts *l1ts = lchan->ts->priv;
+ static const enum trx_chan_type chans[] = {
+ TRXC_FCCH,
+ TRXC_SCH,
+ TRXC_BCCH,
+ TRXC_RACH,
+ TRXC_CCCH,
+ };
+
+ if (!l1ts)
+ return -EINVAL;
+
+ for (unsigned int i = 0; i < ARRAY_SIZE(chans); i++) {
+ enum trx_chan_type chan = chans[i];
+
+ if (l1ts->chan_state[chan].active == active)
+ continue;
+ _trx_sched_set_lchan(lchan, chan, active);
+ }
+
+ return 0;
+}
+
/* setting all logical channels given attributes to active/inactive */
int trx_sched_set_mode(struct gsm_bts_trx_ts *ts, uint8_t chan_nr, uint8_t rsl_cmode,
uint8_t tch_mode, int codecs, uint8_t codec0, uint8_t codec1,
@@ -1277,7 +1308,7 @@
return 0;
/* check if channel is active */
- if (!TRX_CHAN_IS_ACTIVE(&l1ts->chan_state[chan], chan))
+ if (!l1ts->chan_state[chan].active)
return -EINVAL;
/* There is no burst, just for logging */
@@ -1334,7 +1365,7 @@
l1cs = &l1ts->chan_state[br->chan];
/* check if channel is active */
- if (!TRX_CHAN_IS_ACTIVE(l1cs, br->chan))
+ if (!l1cs->active)
return;
/* Training Sequence Code and Set */
@@ -1523,7 +1554,7 @@
func = trx_chan_desc[bi->chan].ul_fn;
/* check if channel is active */
- if (!TRX_CHAN_IS_ACTIVE(l1cs, bi->chan)) {
+ if (!l1cs->active) {
/* handle noise measurements on dedicated and idle channels */
if (TRX_CHAN_IS_DEDIC(bi->chan) || bi->chan == TRXC_IDLE)
trx_sched_noise_meas(l1cs, bi);
diff --git a/src/osmo-bts-trx/l1_if.c b/src/osmo-bts-trx/l1_if.c
index 2b0c723..5df3238 100644
--- a/src/osmo-bts-trx/l1_if.c
+++ b/src/osmo-bts-trx/l1_if.c
@@ -270,11 +270,19 @@
if (rc)
return NM_NACK_RES_NOTAVAIL;
- /* activate lchan for CCCH */
- if (pchan == GSM_PCHAN_CCCH || pchan == GSM_PCHAN_CCCH_SDCCH4 ||
- pchan == GSM_PCHAN_CCCH_SDCCH4_CBCH) {
+ /* activate lchans for [CBCH/]BCCH/CCCH */
+ switch (pchan) {
+ case GSM_PCHAN_CCCH_SDCCH4_CBCH:
+ trx_sched_set_lchan(&ts->lchan[CCCH_LCHAN], RSL_CHAN_OSMO_CBCH4, LID_DEDIC,
true);
+ /* fall-through */
+ case GSM_PCHAN_CCCH_SDCCH4:
+ case GSM_PCHAN_CCCH:
+ trx_sched_set_bcch_ccch(&ts->lchan[CCCH_LCHAN], true);
ts->lchan[CCCH_LCHAN].rel_act_kind = LCHAN_REL_ACT_OML;
lchan_set_state(&ts->lchan[CCCH_LCHAN], LCHAN_S_ACTIVE);
+ break;
+ default:
+ break;
}
slottype = transceiver_chan_types[pchan];
--
To view, visit
https://gerrit.osmocom.org/c/osmo-bts/+/31716
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Change-Id: Id0c70d6a2b777a5117c85149bfa1b3a997299d1d
Gerrit-Change-Number: 31716
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-MessageType: newchange