aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bts-trx/l1_if.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/osmo-bts-trx/l1_if.c')
-rw-r--r--src/osmo-bts-trx/l1_if.c232
1 files changed, 14 insertions, 218 deletions
diff --git a/src/osmo-bts-trx/l1_if.c b/src/osmo-bts-trx/l1_if.c
index a3bdf012..d65900fe 100644
--- a/src/osmo-bts-trx/l1_if.c
+++ b/src/osmo-bts-trx/l1_if.c
@@ -29,6 +29,7 @@
#include <osmocom/core/talloc.h>
#include <osmocom/core/bits.h>
+#include <osmocom/core/fsm.h>
#include <osmocom/codec/ecu.h>
#include <osmocom/gsm/abis_nm.h>
@@ -45,6 +46,7 @@
#include "l1_if.h"
#include "trx_if.h"
+#include "trx_provision_fsm.h"
#define RF_DISABLED_mdB to_mdB(-10)
@@ -62,7 +64,7 @@ static const uint8_t transceiver_chan_types[_GSM_PCHAN_MAX] = {
[GSM_PCHAN_UNKNOWN] = 0,
};
-static enum gsm_phys_chan_config transceiver_chan_type_2_pchan(uint8_t type)
+enum gsm_phys_chan_config transceiver_chan_type_2_pchan(uint8_t type)
{
int i;
for (i = 0; i < _GSM_PCHAN_MAX; i++) {
@@ -77,6 +79,8 @@ struct trx_l1h *trx_l1h_alloc(void *tall_ctx, struct phy_instance *pinst)
struct trx_l1h *l1h;
l1h = talloc_zero(tall_ctx, struct trx_l1h);
l1h->phy_inst = pinst;
+ l1h->provision_fi = osmo_fsm_inst_alloc(&trx_prov_fsm, l1h, l1h, LOGL_INFO, NULL);
+ OSMO_ASSERT(osmo_fsm_inst_update_id_f_sanitize(l1h->provision_fi, '-', phy_instance_name(pinst)) == 0);
trx_if_init(l1h);
return l1h;
}
@@ -140,7 +144,7 @@ int bts_model_lchan_deactivate_sacch(struct gsm_lchan *lchan)
return trx_sched_set_lchan(&l1h->l1s, gsm_lchan2chan_nr(lchan), LID_SACCH, false);
}
-static int l1if_trx_start_power_ramp(struct gsm_bts_trx *trx, ramp_compl_cb_t ramp_compl_cb)
+int l1if_trx_start_power_ramp(struct gsm_bts_trx *trx, ramp_compl_cb_t ramp_compl_cb)
{
struct phy_instance *pinst = trx_phy_instance(trx);
struct trx_l1h *l1h = pinst->u.osmotrx.hdl;
@@ -174,78 +178,6 @@ void l1if_trx_set_nominal_power(struct gsm_bts_trx *trx, int nominal_power)
l1if_trx_start_power_ramp(trx, NULL);
}
-static void l1if_getnompower_cb(struct trx_l1h *l1h, int nominal_power, int rc)
-{
- struct phy_instance *pinst = l1h->phy_inst;
- struct gsm_bts_trx *trx = pinst->trx;
-
- LOGPPHI(pinst, DL1C, LOGL_DEBUG, "l1if_getnompower_cb(nominal_power=%d, rc=%d)\n", nominal_power, rc);
-
- l1if_trx_set_nominal_power(trx, nominal_power);
-}
-
-static void l1if_setslot_cb(struct trx_l1h *l1h, uint8_t tn, uint8_t type, int rc)
-{
- struct phy_instance *pinst = l1h->phy_inst;
- struct gsm_bts_trx *trx = pinst->trx;
- struct gsm_bts_trx_ts *ts;
- enum gsm_phys_chan_config pchan;
-
- if (tn >= TRX_NR_TS) {
- LOGPPHI(pinst, DL1C, LOGL_ERROR, "transceiver SETSLOT invalid param TN (%" PRIu8 ")\n",
- tn);
- return;
- }
-
- pchan = transceiver_chan_type_2_pchan(type);
- if (pchan == GSM_PCHAN_UNKNOWN) {
- LOGPPHI(pinst, DL1C, LOGL_ERROR, "transceiver SETSLOT invalid param TS_TYPE (%" PRIu8 ")\n",
- type);
- return;
- }
-
- ts = &trx->ts[tn];
- LOGPPHI(pinst, DL1C, LOGL_DEBUG, "%s l1if_setslot_cb(as_pchan=%s),"
- " calling cb_ts_connected(rc=%d)\n",
- gsm_ts_name(ts), gsm_pchan_name(pchan), rc);
- cb_ts_connected(ts, rc);
-}
-
-static void l1if_poweronoff_cb(struct trx_l1h *l1h, bool poweronoff, int rc)
-{
- struct phy_instance *pinst = l1h->phy_inst;
- struct phy_link *plink = pinst->phy_link;
-
- plink->u.osmotrx.powered = poweronoff;
- plink->u.osmotrx.poweronoff_sent = false;
-
- if (poweronoff) {
- if (rc == 0 && plink->state != PHY_LINK_CONNECTED) {
- trx_sched_clock_started(pinst->trx->bts);
- phy_link_state_set(plink, PHY_LINK_CONNECTED);
-
- /* Begin to ramp up the power on all TRX associated with this phy */
- llist_for_each_entry(pinst, &plink->instances, list) {
- if (pinst->trx->mo.nm_state.administrative == NM_STATE_UNLOCKED)
- l1if_trx_start_power_ramp(pinst->trx, NULL);
- }
- } else if (rc != 0 && plink->state != PHY_LINK_SHUTDOWN) {
- trx_sched_clock_stopped(pinst->trx->bts);
- phy_link_state_set(plink, PHY_LINK_SHUTDOWN);
- }
- } else {
- if (plink->state != PHY_LINK_SHUTDOWN) {
- trx_sched_clock_stopped(pinst->trx->bts);
- phy_link_state_set(plink, PHY_LINK_SHUTDOWN);
-
- /* Notify TRX close on all TRX associated with this phy */
- llist_for_each_entry(pinst, &plink->instances, list) {
- bts_model_trx_close_cb(pinst->trx, rc);
- }
- }
- }
-}
-
static void l1if_setpower_att_cb(struct trx_l1h *l1h, int power_att_db, int rc)
{
struct phy_instance *pinst = l1h->phy_inst;
@@ -257,113 +189,6 @@ static void l1if_setpower_att_cb(struct trx_l1h *l1h, int power_att_db, int rc)
}
/*
- * transceiver provisioning
- */
-int l1if_provision_transceiver_trx(struct trx_l1h *l1h)
-{
- uint8_t tn;
- struct phy_instance *pinst = l1h->phy_inst;
- struct phy_link *plink = pinst->phy_link;
-
- /* During setup, pinst may still not be associated to a TRX nr */
- if (!pinst->trx) {
- LOGPPHI(pinst, DL1C, LOGL_INFO,
- "Delaying provision, TRX not yet assigned to phy instance\n");
- return -EIO;
- }
-
- if (phy_link_state_get(plink) == PHY_LINK_SHUTDOWN) {
- LOGPPHI(pinst, DL1C, LOGL_INFO,
- "Delaying provision, TRX not yet available\n");
- return -EIO;
- }
-
- if (l1h->config.enabled
- && l1h->config.tsc_valid
- && l1h->config.bsic_valid
- && l1h->config.arfcn_valid) {
- /* before power on */
- if (!l1h->config.arfcn_sent) {
- trx_if_cmd_rxtune(l1h, l1h->config.arfcn);
- trx_if_cmd_txtune(l1h, l1h->config.arfcn);
- /* After TXTUNE is sent to TRX, get the tx nominal power
- * (which may vary precisly on band/arfcn. Avoid sending
- * it if we are forced by VTY to use a specific nominal
- * power (because TRX may not support the command or
- * provide broken values) */
- if (!l1h->config.nominal_power_set_by_vty)
- trx_if_cmd_getnompower(l1h, l1if_getnompower_cb);
- l1h->config.arfcn_sent = 1;
- }
- if (!l1h->config.tsc_sent) {
- trx_if_cmd_settsc(l1h, l1h->config.tsc);
- l1h->config.tsc_sent = 1;
- }
- if (!l1h->config.bsic_sent) {
- trx_if_cmd_setbsic(l1h, l1h->config.bsic);
- l1h->config.bsic_sent = 1;
- }
-
- /* Ask transceiver to use the newest TRXD header version if not using it yet */
- if (!l1h->config.setformat_sent) {
- if (l1h->config.trxd_hdr_ver_use != plink->u.osmotrx.trxd_hdr_ver_max) {
- trx_if_cmd_setformat(l1h, plink->u.osmotrx.trxd_hdr_ver_max);
- l1h->config.trxd_hdr_ver_req = plink->u.osmotrx.trxd_hdr_ver_max;
- } else {
- LOGPPHI(pinst, DL1C, LOGL_INFO,
- "No need to negotiate TRXD version, "
- "already using maximum configured one: %" PRIu8 "\n",
- l1h->config.trxd_hdr_ver_use);
- }
- l1h->config.setformat_sent = 1;
- }
-
- if (pinst->num == 0 && !plink->u.osmotrx.powered && !plink->u.osmotrx.poweronoff_sent) {
- trx_if_cmd_poweron(l1h, l1if_poweronoff_cb);
- plink->u.osmotrx.poweronoff_sent = true;
- }
-
- /* after power on */
- if (l1h->config.rxgain_valid && !l1h->config.rxgain_sent) {
- trx_if_cmd_setrxgain(l1h, l1h->config.rxgain);
- l1h->config.rxgain_sent = 1;
- }
- if (l1h->config.maxdly_valid && !l1h->config.maxdly_sent) {
- trx_if_cmd_setmaxdly(l1h, l1h->config.maxdly);
- l1h->config.maxdly_sent = 1;
- }
- if (l1h->config.maxdlynb_valid && !l1h->config.maxdlynb_sent) {
- trx_if_cmd_setmaxdlynb(l1h, l1h->config.maxdlynb);
- l1h->config.maxdlynb_sent = 1;
- }
-
- 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] = 1;
- }
- }
- return 0;
- }
-
- if (!l1h->config.enabled) {
- if (pinst->num == 0 && plink->u.osmotrx.powered && !plink->u.osmotrx.poweronoff_sent) {
- trx_if_cmd_poweroff(l1h, l1if_poweronoff_cb);
- plink->u.osmotrx.poweronoff_sent = true;
- }
- l1h->config.rxgain_sent = 0;
- l1h->config.maxdly_sent = 0;
- l1h->config.maxdlynb_sent = 0;
- for (tn = 0; tn < TRX_NR_TS; tn++)
- l1h->config.slottype_sent[tn] = 0;
- }
-
- return 0;
-}
-
-/*
* activation/configuration/deactivation of transceiver's TRX
*/
@@ -373,11 +198,7 @@ static int trx_init(struct gsm_bts_trx *trx)
struct phy_instance *pinst = trx_phy_instance(trx);
struct trx_l1h *l1h = pinst->u.osmotrx.hdl;
- /* power on transceiver, if not already */
- if (!l1h->config.enabled) {
- l1h->config.enabled = true;
- l1if_provision_transceiver_trx(l1h);
- }
+ osmo_fsm_inst_dispatch(l1h->provision_fi, TRX_PROV_EV_CFG_ENABLE, (void*)(intptr_t)true);
if (trx == trx->bts->c0)
lchan_init_lapdm(&trx->ts[0].lchan[CCCH_LCHAN]);
@@ -411,13 +232,7 @@ void bts_model_trx_close(struct gsm_bts_trx *trx)
struct phy_instance *pinst = trx_phy_instance(trx);
struct trx_l1h *l1h = pinst->u.osmotrx.hdl;
- /* power off transceiver, if not already */
- if (l1h->config.enabled) {
- l1h->config.enabled = false;
- l1if_provision_transceiver_trx(l1h);
- } else if (!pinst->phy_link->u.osmotrx.poweronoff_sent) {
- bts_model_trx_close_cb(trx, 0);
- } /* else: poweroff in progress, cb will be called upon TRXC RSP */
+ osmo_fsm_inst_dispatch(l1h->provision_fi, TRX_PROV_EV_POWEROFF, NULL);
/* Set to Operational State: Disabled */
check_transceiver_availability_trx(l1h, 0);
@@ -446,12 +261,7 @@ static uint8_t trx_set_bts(struct gsm_bts *bts, struct tlv_parsed *new_attr)
struct phy_instance *pinst = trx_phy_instance(trx);
struct phy_link *plink = pinst->phy_link;
struct trx_l1h *l1h = pinst->u.osmotrx.hdl;
- if (l1h->config.bsic != bsic || !l1h->config.bsic_valid) {
- l1h->config.bsic = bsic;
- l1h->config.bsic_valid = 1;
- l1h->config.bsic_sent = 0;
- l1if_provision_transceiver_trx(l1h);
- }
+ osmo_fsm_inst_dispatch(l1h->provision_fi, TRX_PROV_EV_CFG_BSIC, (void*)(intptr_t)bsic);
check_transceiver_availability_trx(l1h, phy_link_state_get(plink) != PHY_LINK_SHUTDOWN);
}
@@ -466,12 +276,7 @@ static uint8_t trx_set_trx(struct gsm_bts_trx *trx)
struct phy_link *plink = pinst->phy_link;
uint16_t arfcn = trx->arfcn;
- if (l1h->config.arfcn != arfcn || !l1h->config.arfcn_valid) {
- l1h->config.arfcn = arfcn;
- l1h->config.arfcn_valid = 1;
- l1h->config.arfcn_sent = 0;
- l1if_provision_transceiver_trx(l1h);
- }
+ osmo_fsm_inst_dispatch(l1h->provision_fi, TRX_PROV_EV_CFG_ARFCN, (void*)(intptr_t)arfcn);
/* Begin to ramp up the power if power reduction is set by OML and TRX
is already running. Otherwise skip, power ramping will be started
@@ -497,12 +302,7 @@ static uint8_t trx_set_ts_as_pchan(struct gsm_bts_trx_ts *ts,
/* all TSC of all timeslots must be equal, because transceiver only
* supports one TSC per TRX */
- if (l1h->config.tsc != tsc || !l1h->config.tsc_valid) {
- l1h->config.tsc = tsc;
- l1h->config.tsc_valid = 1;
- l1h->config.tsc_sent = 0;
- l1if_provision_transceiver_trx(l1h);
- }
+ 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)))
@@ -525,13 +325,9 @@ static uint8_t trx_set_ts_as_pchan(struct gsm_bts_trx_ts *ts,
slottype = transceiver_chan_types[pchan];
- if (l1h->config.slottype[tn] != slottype
- || !l1h->config.slottype_valid[tn]) {
- l1h->config.slottype[tn] = slottype;
- l1h->config.slottype_valid[tn] = 1;
- l1h->config.slottype_sent[tn] = 0;
- l1if_provision_transceiver_trx(l1h);
- }
+
+ struct trx_prov_ev_cfg_ts_data data = { .tn = tn, .slottype = slottype };
+ osmo_fsm_inst_dispatch(l1h->provision_fi, TRX_PROV_EV_CFG_TS, &data);
return 0;
}