diff options
Diffstat (limited to 'src/osmo-bts-trx/l1_if.c')
-rw-r--r-- | src/osmo-bts-trx/l1_if.c | 232 |
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; } |