laforge has submitted this change. ( https://gerrit.osmocom.org/c/osmo-bts/+/24388 )
Change subject: [VAMOS] osmo-bts-trx: properly handle per-timeslot TSC values ...................................................................... [VAMOS] osmo-bts-trx: properly handle per-timeslot TSC values Each timeslot can have its own Training Sequence Code value, which may optionally be included in the NM_MT_SET_CHAN_ATTR message sent over the A-bis/OML. If it's not present, then the TSC value for a timeslot is derived from the BCC part of BSIC, which is always included in the NM_MT_SET_BTS_ATTR message. On the TRXC interface, the BTS global TSC value is indicated to the transceiver using either of the 'SETTSC' or 'SETBSIC' commands. The transceiver then applies this value for all timeslots by default, however it can be redefined for each timeslot individually using additional arguments of the 'SETSLOT' command (see section 25.2.4.1 in the user manual [1] for more details). Currently, trx_set_ts_as_pchan() sends TRX_PROV_EV_CFG_TSC to the transceiver provisioning FSM, together with the per-timeslot TSC value. This event causes the FSM to modify the global TSC value, that is going to be or has already been sent to the transceiver. This is wrong, the global TSC value shall not be overwritten. Remove the TRX_PROV_EV_CFG_TSC, and include per-timeslot Training Sequence Code and Set in the data structure that gets passed together with the TRX_PROV_EV_CFG_TS instead. Implement handling of the optional per-timeslot TSC in trx_if_cmd_setslot(). [1] https://downloads.osmocom.org/docs/latest/osmobts-usermanual.pdf Change-Id: Idc5796151e3e83f42d60c2d4cb7c35890d76a7f5 Related: SYS#4895, OS#4941 --- M src/osmo-bts-trx/l1_if.c M src/osmo-bts-trx/l1_if.h M src/osmo-bts-trx/main.c M src/osmo-bts-trx/trx_if.c M src/osmo-bts-trx/trx_if.h M src/osmo-bts-trx/trx_provision_fsm.c M src/osmo-bts-trx/trx_provision_fsm.h M src/osmo-bts-trx/trx_vty.c 8 files changed, 84 insertions(+), 58 deletions(-) Approvals: laforge: Looks good to me, approved pespin: Looks good to me, but someone else must approve Jenkins Builder: Verified diff --git a/src/osmo-bts-trx/l1_if.c b/src/osmo-bts-trx/l1_if.c index 3f95a69..3be5179 100644 --- a/src/osmo-bts-trx/l1_if.c +++ b/src/osmo-bts-trx/l1_if.c @@ -271,15 +271,9 @@ struct phy_instance *pinst = trx_phy_instance(ts->trx); struct trx_l1h *l1h = pinst->u.osmotrx.hdl; uint8_t tn = ts->nr; - uint16_t tsc = ts->tsc; uint8_t slottype; int rc; - /* all TSC of all timeslots must be equal, because transceiver only - * supports one TSC per TRX */ - - osmo_fsm_inst_dispatch(l1h->provision_fi, TRX_PROV_EV_CFG_TSC, (void*)(intptr_t)tsc); - /* ignore disabled slots */ if (!(l1h->config.slotmask & (1 << tn))) return NM_NACK_RES_NOTAVAIL; @@ -303,6 +297,13 @@ struct trx_prov_ev_cfg_ts_data data = { .tn = tn, .slottype = slottype }; + if (ts->tsc_set != 0 || ts->tsc != BTS_TSC(ts->trx->bts)) { + /* On TRXC we use 3GPP compliant numbering, so +1 */ + data.tsc_set = ts->tsc_set + 1; + data.tsc_val = ts->tsc; + data.tsc_valid = true; + } + osmo_fsm_inst_dispatch(l1h->provision_fi, TRX_PROV_EV_CFG_TS, &data); return 0; diff --git a/src/osmo-bts-trx/l1_if.h b/src/osmo-bts-trx/l1_if.h index 864bb69..50369d9 100644 --- a/src/osmo-bts-trx/l1_if.h +++ b/src/osmo-bts-trx/l1_if.h @@ -105,9 +105,14 @@ uint8_t slotmask; - bool slottype_valid[TRX_NR_TS]; - uint8_t slottype[TRX_NR_TS]; - bool slottype_sent[TRX_NR_TS]; + bool setslot_valid[TRX_NR_TS]; + struct { + uint8_t slottype; + uint8_t tsc_set; + uint8_t tsc_val; + bool tsc_valid; + } setslot[TRX_NR_TS]; + bool setslot_sent[TRX_NR_TS]; }; struct trx_l1h { diff --git a/src/osmo-bts-trx/main.c b/src/osmo-bts-trx/main.c index e0a99a5..6ec8dfc 100644 --- a/src/osmo-bts-trx/main.c +++ b/src/osmo-bts-trx/main.c @@ -145,6 +145,7 @@ osmo_bts_set_feature(bts->features, BTS_FEAT_CBCH); osmo_bts_set_feature(bts->features, BTS_FEAT_HOPPING); osmo_bts_set_feature(bts->features, BTS_FEAT_ACCH_REP); + osmo_bts_set_feature(bts->features, BTS_FEAT_MULTI_TSC); bts_internal_flag_set(bts, BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB); diff --git a/src/osmo-bts-trx/trx_if.c b/src/osmo-bts-trx/trx_if.c index af1deef..c10a15f 100644 --- a/src/osmo-bts-trx/trx_if.c +++ b/src/osmo-bts-trx/trx_if.c @@ -8,6 +8,7 @@ * Copyright (C) 2013 Andreas Eversberg <jo...@eversberg.eu> * Copyright (C) 2016-2017 Harald Welte <lafo...@gnumonks.org> * Copyright (C) 2019 Vadim Yanitskiy <axilira...@gmail.com> + * Copyright (C) 2021 sysmocom - s.m.f.c. GmbH <i...@sysmocom.de> * * All Rights Reserved * @@ -326,10 +327,21 @@ return trx_ctrl_cmd(l1h, 0, "SETMAXDLYNB", "%d", dly); } -/*! Send "SETSLOT" command to TRX: Configure Channel Combination for TS */ -int trx_if_cmd_setslot(struct trx_l1h *l1h, uint8_t tn, uint8_t type, trx_if_cmd_setslot_cb *cb) +/*! Send "SETSLOT" command to TRX: Configure Channel Combination and TSC for TS */ +int trx_if_cmd_setslot(struct trx_l1h *l1h, uint8_t tn, + trx_if_cmd_setslot_cb *cb) { - return trx_ctrl_cmd_cb(l1h, 1, cb, "SETSLOT", "%d %d", tn, type); + const struct trx_config *cfg = &l1h->config; + + if (cfg->setslot[tn].tsc_valid) { /* PHY is instructed to use a custom TSC */ + return trx_ctrl_cmd_cb(l1h, 1, cb, "SETSLOT", "%u %u C%u/S%u", + tn, cfg->setslot[tn].slottype, + cfg->setslot[tn].tsc_val, + cfg->setslot[tn].tsc_set); + } else { /* PHY is instructed to use the default TSC from 'SETTSC' */ + return trx_ctrl_cmd_cb(l1h, 1, cb, "SETSLOT", "%u %u", + tn, cfg->setslot[tn].slottype); + } } /*! Send "RXTUNE" command to TRX: Tune Receiver to given ARFCN */ diff --git a/src/osmo-bts-trx/trx_if.h b/src/osmo-bts-trx/trx_if.h index e131d56..b838b76 100644 --- a/src/osmo-bts-trx/trx_if.h +++ b/src/osmo-bts-trx/trx_if.h @@ -34,7 +34,7 @@ int trx_if_cmd_setpower_att(struct trx_l1h *l1h, int power_att_db, trx_if_cmd_setpower_att_cb *cb); int trx_if_cmd_setmaxdly(struct trx_l1h *l1h, int dly); int trx_if_cmd_setmaxdlynb(struct trx_l1h *l1h, int dly); -int trx_if_cmd_setslot(struct trx_l1h *l1h, uint8_t tn, uint8_t type, trx_if_cmd_setslot_cb *cb); +int trx_if_cmd_setslot(struct trx_l1h *l1h, uint8_t tn, trx_if_cmd_setslot_cb *cb); int trx_if_cmd_rxtune(struct trx_l1h *l1h, uint16_t arfcn, trx_if_cmd_generic_cb *cb); int trx_if_cmd_txtune(struct trx_l1h *l1h, uint16_t arfcn, trx_if_cmd_generic_cb *cb); int trx_if_cmd_handover(struct trx_l1h *l1h, uint8_t tn, uint8_t ss); diff --git a/src/osmo-bts-trx/trx_provision_fsm.c b/src/osmo-bts-trx/trx_provision_fsm.c index 070037d..5beca2a 100644 --- a/src/osmo-bts-trx/trx_provision_fsm.c +++ b/src/osmo-bts-trx/trx_provision_fsm.c @@ -191,17 +191,15 @@ cb_ts_connected(ts, rc); } -/* Returns true if any TS changed, false otherwise */ -static bool update_ts_data(struct trx_l1h *l1h, struct trx_prov_ev_cfg_ts_data* ts_data) { +static void update_ts_data(struct trx_l1h *l1h, struct trx_prov_ev_cfg_ts_data *data) +{ + l1h->config.setslot[data->tn].slottype = data->slottype; + l1h->config.setslot[data->tn].tsc_set = data->tsc_set; + l1h->config.setslot[data->tn].tsc_val = data->tsc_val; + l1h->config.setslot[data->tn].tsc_valid = data->tsc_valid; - if (l1h->config.slottype[ts_data->tn] != ts_data->slottype || - !l1h->config.slottype_valid[ts_data->tn]) { - l1h->config.slottype[ts_data->tn] = ts_data->slottype; - l1h->config.slottype_valid[ts_data->tn] = true; - l1h->config.slottype_sent[ts_data->tn] = false; - return true; - } - return false; + l1h->config.setslot_valid[data->tn] = true; + l1h->config.setslot_sent[data->tn] = false; } /* Whether a given TRX is fully configured and can be powered on */ @@ -290,9 +288,7 @@ struct trx_l1h *l1h = (struct trx_l1h *)fi->priv; struct phy_instance *pinst = l1h->phy_inst; struct gsm_bts_trx *trx = pinst->trx; - uint8_t bsic; uint16_t arfcn; - uint16_t tsc; int nominal_power; int status; bool others_ready; @@ -302,11 +298,21 @@ l1h->config.enabled =(bool)data; break; case TRX_PROV_EV_CFG_BSIC: - bsic = (uint8_t)(intptr_t)data; - if (l1h->config.bsic != bsic || !l1h->config.bsic_valid) { - l1h->config.bsic = bsic; - l1h->config.bsic_valid = true; - l1h->config.bsic_sent = false; + /* We always get BSIC from the BSC, TSC can be derived from the BCC */ + if (!pinst->phy_link->u.osmotrx.use_legacy_setbsic) { + const uint8_t tsc = BSIC2BCC((uint8_t)(intptr_t)data); + if (l1h->config.tsc != tsc || !l1h->config.tsc_valid) { + l1h->config.tsc = tsc; + l1h->config.tsc_valid = true; + l1h->config.tsc_sent = false; + } + } else { + const uint8_t bsic = (uint8_t)(intptr_t)data; + if (l1h->config.bsic != bsic || !l1h->config.bsic_valid) { + l1h->config.bsic = bsic; + l1h->config.bsic_valid = true; + l1h->config.bsic_sent = false; + } } break; case TRX_PROV_EV_CFG_ARFCN: @@ -319,14 +325,6 @@ l1h->config.nomtxpower_sent = false; } break; - case TRX_PROV_EV_CFG_TSC: - tsc = (uint16_t)(intptr_t)data; - if (l1h->config.tsc != tsc || !l1h->config.tsc_valid) { - l1h->config.tsc = tsc; - l1h->config.tsc_valid = true; - l1h->config.tsc_sent = false; - } - break; case TRX_PROV_EV_CFG_TS: update_ts_data(l1h, (struct trx_prov_ev_cfg_ts_data*)data); break; @@ -478,11 +476,10 @@ } for (tn = 0; tn < TRX_NR_TS; tn++) { - if (l1h->config.slottype_valid[tn] - && !l1h->config.slottype_sent[tn]) { - trx_if_cmd_setslot(l1h, tn, - l1h->config.slottype[tn], l1if_setslot_cb); - l1h->config.slottype_sent[tn] = true; + if (l1h->config.setslot_valid[tn] + && !l1h->config.setslot_sent[tn]) { + trx_if_cmd_setslot(l1h, tn, l1if_setslot_cb); + l1h->config.setslot_sent[tn] = true; } } } @@ -507,7 +504,7 @@ l1h->config.maxdly_sent = false; l1h->config.maxdlynb_sent = false; for (tn = 0; tn < TRX_NR_TS; tn++) - l1h->config.slottype_sent[tn] = false; + l1h->config.setslot_sent[tn] = false; } else if (!pinst->phy_link->u.osmotrx.poweronoff_sent) { bts_model_trx_close_cb(pinst->trx, 0); } /* else: poweroff in progress, cb will be called upon TRXC RSP */ @@ -519,12 +516,10 @@ break; case TRX_PROV_EV_CFG_TS: ts_data = (struct trx_prov_ev_cfg_ts_data*)data; - if (update_ts_data(l1h, ts_data)) { - trx_if_cmd_setslot(l1h, ts_data->tn, - l1h->config.slottype[ ts_data->tn], l1if_setslot_cb); - l1h->config.slottype_sent[ts_data->tn] = true; - } - + update_ts_data(l1h, ts_data); + /* While in this state we can send SETSLOT immediately */ + trx_if_cmd_setslot(l1h, ts_data->tn, l1if_setslot_cb); + l1h->config.setslot_sent[ts_data->tn] = true; break; default: OSMO_ASSERT(0); @@ -571,7 +566,6 @@ X(TRX_PROV_EV_CFG_ENABLE) | X(TRX_PROV_EV_CFG_BSIC) | X(TRX_PROV_EV_CFG_ARFCN) | - X(TRX_PROV_EV_CFG_TSC) | X(TRX_PROV_EV_CFG_TS) | X(TRX_PROV_EV_RXTUNE_CNF) | X(TRX_PROV_EV_TXTUNE_CNF) | @@ -623,7 +617,6 @@ OSMO_VALUE_STRING(TRX_PROV_EV_CFG_ENABLE), OSMO_VALUE_STRING(TRX_PROV_EV_CFG_BSIC), OSMO_VALUE_STRING(TRX_PROV_EV_CFG_ARFCN), - OSMO_VALUE_STRING(TRX_PROV_EV_CFG_TSC), OSMO_VALUE_STRING(TRX_PROV_EV_CFG_TS), OSMO_VALUE_STRING(TRX_PROV_EV_CFG_RXGAIN), OSMO_VALUE_STRING(TRX_PROV_EV_CFG_SETMAXDLY), diff --git a/src/osmo-bts-trx/trx_provision_fsm.h b/src/osmo-bts-trx/trx_provision_fsm.h index 0f80088..8e6b97b 100644 --- a/src/osmo-bts-trx/trx_provision_fsm.h +++ b/src/osmo-bts-trx/trx_provision_fsm.h @@ -22,6 +22,8 @@ #pragma once +#include <stdbool.h> + #include <osmocom/core/fsm.h> enum trx_provision_fsm_states { @@ -35,6 +37,11 @@ struct trx_prov_ev_cfg_ts_data { uint8_t tn; uint8_t slottype; + + /* Training Sequence Code and Set */ + uint8_t tsc_set; + uint8_t tsc_val; + bool tsc_valid; }; enum trx_provision_fsm_events { diff --git a/src/osmo-bts-trx/trx_vty.c b/src/osmo-bts-trx/trx_vty.c index 2b0913f..d9d17d0 100644 --- a/src/osmo-bts-trx/trx_vty.c +++ b/src/osmo-bts-trx/trx_vty.c @@ -127,16 +127,23 @@ else vty_out(vty, " maxdlynb : undefined%s", VTY_NEWLINE); for (tn = 0; tn < TRX_NR_TS; tn++) { - if (!((1 << tn) & l1h->config.slotmask)) + if (!((1 << tn) & l1h->config.slotmask)) { vty_out(vty, " slot #%d: unsupported%s", tn, VTY_NEWLINE); - else if (l1h->config.slottype_valid[tn]) - vty_out(vty, " slot #%d: type %d%s", tn, - l1h->config.slottype[tn], - VTY_NEWLINE); - else + continue; + } else if (!l1h->config.setslot_valid[tn]) { vty_out(vty, " slot #%d: undefined%s", tn, VTY_NEWLINE); + continue; + } + + vty_out(vty, " slot #%d: type %d", tn, + l1h->config.setslot[tn].slottype); + if (l1h->config.setslot[tn].tsc_valid) + vty_out(vty, " TSC-s%dc%d", + l1h->config.setslot[tn].tsc_set, + l1h->config.setslot[tn].tsc_val); + vty_out(vty, "%s", VTY_NEWLINE); } } -- To view, visit https://gerrit.osmocom.org/c/osmo-bts/+/24388 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Change-Id: Idc5796151e3e83f42d60c2d4cb7c35890d76a7f5 Gerrit-Change-Number: 24388 Gerrit-PatchSet: 7 Gerrit-Owner: fixeria <vyanits...@sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: laforge <lafo...@osmocom.org> Gerrit-Reviewer: pespin <pes...@sysmocom.de> Gerrit-MessageType: merged