aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVadim Yanitskiy <vyanitskiy@sysmocom.de>2023-03-07 08:52:25 +0700
committerfixeria <vyanitskiy@sysmocom.de>2023-03-22 12:14:25 +0000
commit8e04613e4f0bf5093e15a6027ac53e3934555708 (patch)
tree66eb4d365b59d99c27c55b89e244a080dd024817
parente7085d16998cc1ba98ee1e12ea260552dc6cac76 (diff)
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
-rw-r--r--include/osmo-bts/gsm_data.h1
-rw-r--r--include/osmo-bts/scheduler.h10
-rw-r--r--src/common/scheduler.c127
-rw-r--r--src/osmo-bts-trx/l1_if.c21
4 files changed, 101 insertions, 58 deletions
diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h
index dcb357f1..69e3b00a 100644
--- a/include/osmo-bts/gsm_data.h
+++ b/include/osmo-bts/gsm_data.h
@@ -58,6 +58,7 @@ struct gsm_network {
/* lchans 0..3 are SDCCH in combined channel configuration,
use 4 as magic number for BCCH hack - see osmo-bts-../oml.c:opstart_compl() */
#define CCCH_LCHAN 4
+#define CBCH_LCHAN 2
#define TRX_NR_TS 8
#define TS_MAX_LCHAN 8
diff --git a/include/osmo-bts/scheduler.h b/include/osmo-bts/scheduler.h
index 40b42939..01e8e2bb 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 @@ int trx_sched_set_pchan(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config pch
/*! \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 f19257eb..25aefe84 100644
--- a/src/common/scheduler.c
+++ b/src/common/scheduler.c
@@ -150,7 +150,6 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
.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 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
.desc = "Synchronization channel",
/* Tx only, synchronization bursts */
- .flags = TRX_CHAN_FLAG_AUTO_ACTIVE,
.dl_fn = tx_sch_fn,
},
[TRXC_BCCH] = {
@@ -169,7 +167,6 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
/* 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 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
.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 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
/* 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 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
.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_queue_filter(struct llist_head *q, uint8_t chan_nr, uint8_
}
}
+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 @@ int trx_sched_set_lchan(struct gsm_lchan *lchan, uint8_t chan_nr, uint8_t link_i
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 @@ int trx_sched_set_lchan(struct gsm_lchan *lchan, uint8_t chan_nr, uint8_t link_i
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 @@ int trx_sched_set_lchan(struct gsm_lchan *lchan, uint8_t chan_nr, uint8_t link_i
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 @@ int _sched_rts(const struct l1sched_ts *l1ts, uint32_t fn)
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 @@ void _sched_dl_burst(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br)
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 @@ int trx_sched_ul_burst(struct l1sched_ts *l1ts, struct trx_ul_burst_ind *bi)
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 2b0c723b..2ed18681 100644
--- a/src/osmo-bts-trx/l1_if.c
+++ b/src/osmo-bts-trx/l1_if.c
@@ -270,11 +270,26 @@ static uint8_t trx_set_ts_as_pchan(struct gsm_bts_trx_ts *ts,
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_SDCCH8_SACCH8C_CBCH:
+ /* using RSL_CHAN_OSMO_CBCH4 is correct here, because the scheduler
+ * does not distinguish between SDCCH/4+CBCH abd SDCCH/8+CBCH. */
+ trx_sched_set_lchan(&ts->lchan[CBCH_LCHAN],
+ RSL_CHAN_OSMO_CBCH4, LID_DEDIC, true);
+ break;
+ case GSM_PCHAN_CCCH_SDCCH4_CBCH:
+ trx_sched_set_lchan(&ts->lchan[CBCH_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];