aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2020-07-22 18:48:48 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2020-07-22 19:01:35 +0200
commit5c22fa33f7d2b61a56df7c063c05c479668a815d (patch)
tree45fd05f5f3cd1bfbc59d4c4f3a268b264b1c0a3e
parent3f4588273d94b8e752172fe8e3e2889cf200c498 (diff)
bts-trx: Integrate TRX provisioning logic more tightly into the FSM
The state of each config required is now tracked through the "acked" variables, this way the FSM can know when all configs are confirmed by the TRX and can proceed to submit POWERON command. With this version each TRX is still totally independent (there's an FSM per TRX), which means POWERON can be sent on TRX0 before TRX!=0 are fully configured. As a result, powe ramping may start before we know the NOMTXPOWER of a TRX. This kind of issue will be fixed in next commit. Related: SYS#4920 Change-Id: I1b736a4be5ce52a854f5767d8609153e1f4c08d9
-rw-r--r--src/osmo-bts-trx/l1_if.h10
-rw-r--r--src/osmo-bts-trx/trx_if.c59
-rw-r--r--src/osmo-bts-trx/trx_if.h11
-rw-r--r--src/osmo-bts-trx/trx_provision_fsm.c229
-rw-r--r--src/osmo-bts-trx/trx_provision_fsm.h6
5 files changed, 228 insertions, 87 deletions
diff --git a/src/osmo-bts-trx/l1_if.h b/src/osmo-bts-trx/l1_if.h
index f35936e1..fb988a65 100644
--- a/src/osmo-bts-trx/l1_if.h
+++ b/src/osmo-bts-trx/l1_if.h
@@ -61,21 +61,27 @@ struct trx_config {
uint8_t trxd_hdr_ver_req; /* requested TRXD header version */
uint8_t trxd_hdr_ver_use; /* actual TRXD header version in use */
bool setformat_sent;
+ bool setformat_acked;
bool enabled;
bool arfcn_valid;
uint16_t arfcn;
- bool arfcn_sent;
+ bool rxtune_sent;
+ bool rxtune_acked;
+ bool txtune_sent;
+ bool txtune_acked;
bool tsc_valid;
uint8_t tsc;
bool tsc_sent;
+ bool tsc_acked;
bool bsic_valid;
uint8_t bsic;
bool bsic_sent;
+ bool bsic_acked;
bool rxgain_valid;
uint8_t rxgain;
@@ -84,6 +90,8 @@ struct trx_config {
int forced_max_power_red; /* -1 if not forced by VTY config (default) */
bool nominal_power_set_by_vty; /* whether nominal trx power was enforced/retreived from VTY config "nominal-tx-power" */
+ bool nomtxpower_sent;
+ bool nomtxpower_acked;
bool maxdly_valid;
int maxdly;
diff --git a/src/osmo-bts-trx/trx_if.c b/src/osmo-bts-trx/trx_if.c
index e650d794..ad6faad9 100644
--- a/src/osmo-bts-trx/trx_if.c
+++ b/src/osmo-bts-trx/trx_if.c
@@ -270,32 +270,24 @@ int trx_if_cmd_poweron(struct trx_l1h *l1h, trx_if_cmd_poweronoff_cb *cb)
}
/*! Send "SETFORMAT" command to TRX: change TRXD header format version */
-int trx_if_cmd_setformat(struct trx_l1h *l1h, uint8_t ver)
+int trx_if_cmd_setformat(struct trx_l1h *l1h, uint8_t ver, trx_if_cmd_generic_cb *cb)
{
LOGPPHI(l1h->phy_inst, DTRX, LOGL_INFO,
"Requesting TRXD header format version %u\n", ver);
- return trx_ctrl_cmd(l1h, 0, "SETFORMAT", "%u", ver);
+ return trx_ctrl_cmd_cb(l1h, 0, cb, "SETFORMAT", "%u", ver);
}
/*! Send "SETTSC" command to TRX */
-int trx_if_cmd_settsc(struct trx_l1h *l1h, uint8_t tsc)
+int trx_if_cmd_settsc(struct trx_l1h *l1h, uint8_t tsc, trx_if_cmd_generic_cb *cb)
{
- struct phy_instance *pinst = l1h->phy_inst;
- if (pinst->phy_link->u.osmotrx.use_legacy_setbsic)
- return 0;
-
- return trx_ctrl_cmd(l1h, 1, "SETTSC", "%d", tsc);
+ return trx_ctrl_cmd_cb(l1h, 1, cb, "SETTSC", "%d", tsc);
}
/*! Send "SETBSIC" command to TRX */
-int trx_if_cmd_setbsic(struct trx_l1h *l1h, uint8_t bsic)
+int trx_if_cmd_setbsic(struct trx_l1h *l1h, uint8_t bsic, trx_if_cmd_generic_cb *cb)
{
- struct phy_instance *pinst = l1h->phy_inst;
- if (!pinst->phy_link->u.osmotrx.use_legacy_setbsic)
- return 0;
-
- return trx_ctrl_cmd(l1h, 1, "SETBSIC", "%d", bsic);
+ return trx_ctrl_cmd_cb(l1h, 1, cb, "SETBSIC", "%d", bsic);
}
/*! Send "SETRXGAIN" command to TRX */
@@ -335,7 +327,7 @@ int trx_if_cmd_setslot(struct trx_l1h *l1h, uint8_t tn, uint8_t type, trx_if_cmd
}
/*! Send "RXTUNE" command to TRX: Tune Receiver to given ARFCN */
-int trx_if_cmd_rxtune(struct trx_l1h *l1h, uint16_t arfcn)
+int trx_if_cmd_rxtune(struct trx_l1h *l1h, uint16_t arfcn, trx_if_cmd_generic_cb *cb)
{
struct phy_instance *pinst = l1h->phy_inst;
uint16_t freq10;
@@ -350,11 +342,11 @@ int trx_if_cmd_rxtune(struct trx_l1h *l1h, uint16_t arfcn)
return -ENOTSUP;
}
- return trx_ctrl_cmd(l1h, 1, "RXTUNE", "%d", freq10 * 100);
+ return trx_ctrl_cmd_cb(l1h, 1, cb, "RXTUNE", "%d", freq10 * 100);
}
/*! Send "TXTUNE" command to TRX: Tune Transmitter to given ARFCN */
-int trx_if_cmd_txtune(struct trx_l1h *l1h, uint16_t arfcn)
+int trx_if_cmd_txtune(struct trx_l1h *l1h, uint16_t arfcn, trx_if_cmd_generic_cb *cb)
{
struct phy_instance *pinst = l1h->phy_inst;
uint16_t freq10;
@@ -369,7 +361,7 @@ int trx_if_cmd_txtune(struct trx_l1h *l1h, uint16_t arfcn)
return -ENOTSUP;
}
- return trx_ctrl_cmd(l1h, 1, "TXTUNE", "%d", freq10 * 100);
+ return trx_ctrl_cmd_cb(l1h, 1, cb, "TXTUNE", "%d", freq10 * 100);
}
/*! Send "HANDOVER" command to TRX: Enable handover RACH Detection on timeslot/sub-slot */
@@ -516,12 +508,17 @@ static int trx_ctrl_rx_rsp_setslot(struct trx_l1h *l1h, struct trx_ctrl_rsp *rsp
static int trx_ctrl_rx_rsp_setformat(struct trx_l1h *l1h,
struct trx_ctrl_rsp *rsp)
{
+ trx_if_cmd_generic_cb *cb;
+
/* Old transceivers reject 'SETFORMAT' with 'RSP ERR 1' */
if (strcmp(rsp->cmd, "SETFORMAT") != 0) {
LOGPPHI(l1h->phy_inst, DTRX, LOGL_NOTICE,
"Transceiver rejected the format negotiation command, "
"using legacy TRXD header format version (0)\n");
- l1h->config.trxd_hdr_ver_use = 0;
+ if (rsp->cb) {
+ cb = (trx_if_cmd_generic_cb*) rsp->cb;
+ cb(l1h, 0);
+ }
return 0;
}
@@ -534,19 +531,9 @@ static int trx_ctrl_rx_rsp_setformat(struct trx_l1h *l1h,
return -EINVAL;
}
- /* Transceiver may suggest a lower version (than requested) */
- if (rsp->status == l1h->config.trxd_hdr_ver_req) {
- l1h->config.trxd_hdr_ver_use = rsp->status;
- LOGPPHI(l1h->phy_inst, DTRX, LOGL_INFO,
- "Using TRXD header format version %u\n",
- l1h->config.trxd_hdr_ver_use);
- } else {
- LOGPPHI(l1h->phy_inst, DTRX, LOGL_DEBUG,
- "Transceiver suggests TRXD header version %u (requested %u)\n",
- rsp->status, l1h->config.trxd_hdr_ver_req);
- /* Send another SETFORMAT with suggested version */
- l1h->config.trxd_hdr_ver_req = rsp->status;
- trx_if_cmd_setformat(l1h, rsp->status);
+ if (rsp->cb) {
+ cb = (trx_if_cmd_generic_cb*) rsp->cb;
+ cb(l1h, rsp->status);
}
return 0;
@@ -595,6 +582,8 @@ static int trx_ctrl_rx_rsp(struct trx_l1h *l1h,
struct trx_ctrl_rsp *rsp,
struct trx_ctrl_msg *tcm)
{
+ trx_if_cmd_generic_cb *cb;
+
if (strcmp(rsp->cmd, "POWERON") == 0) {
return trx_ctrl_rx_rsp_poweron(l1h, rsp);
} else if (strcmp(rsp->cmd, "POWEROFF") == 0) {
@@ -611,6 +600,12 @@ static int trx_ctrl_rx_rsp(struct trx_l1h *l1h,
return trx_ctrl_rx_rsp_setpower(l1h, rsp);
}
+ /* Generic callback if available */
+ if (rsp->cb) {
+ cb = (trx_if_cmd_generic_cb*) rsp->cb;
+ cb(l1h, rsp->status);
+ }
+
if (rsp->status) {
LOGPPHI(l1h->phy_inst, DTRX, tcm->critical ? LOGL_FATAL : LOGL_NOTICE,
"transceiver rejected TRX command with response: '%s%s%s %d'\n",
diff --git a/src/osmo-bts-trx/trx_if.h b/src/osmo-bts-trx/trx_if.h
index b2fc326c..6b417cff 100644
--- a/src/osmo-bts-trx/trx_if.h
+++ b/src/osmo-bts-trx/trx_if.h
@@ -14,6 +14,7 @@ struct trx_ctrl_msg {
void *cb;
};
+typedef void trx_if_cmd_generic_cb(struct trx_l1h *l1h, int rc);
typedef void trx_if_cmd_poweronoff_cb(struct trx_l1h *l1h, bool poweronoff, int rc);
typedef void trx_if_cmd_setslot_cb(struct trx_l1h *l1h, uint8_t tn, uint8_t type, int rc);
typedef void trx_if_cmd_getnompower_cb(struct trx_l1h *l1h, int nominal_power, int rc);
@@ -22,16 +23,16 @@ typedef void trx_if_cmd_setpower_att_cb(struct trx_l1h *l1h, int power_att_db, i
void trx_if_init(struct trx_l1h *l1h);
int trx_if_cmd_poweroff(struct trx_l1h *l1h, trx_if_cmd_poweronoff_cb *cb);
int trx_if_cmd_poweron(struct trx_l1h *l1h, trx_if_cmd_poweronoff_cb *cb);
-int trx_if_cmd_settsc(struct trx_l1h *l1h, uint8_t tsc);
-int trx_if_cmd_setbsic(struct trx_l1h *l1h, uint8_t bsic);
+int trx_if_cmd_settsc(struct trx_l1h *l1h, uint8_t tsc, trx_if_cmd_generic_cb *cb);
+int trx_if_cmd_setbsic(struct trx_l1h *l1h, uint8_t bsic, trx_if_cmd_generic_cb *cb);
int trx_if_cmd_setrxgain(struct trx_l1h *l1h, int db);
int trx_if_cmd_getnompower(struct trx_l1h *l1h, trx_if_cmd_getnompower_cb *cb);
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_rxtune(struct trx_l1h *l1h, uint16_t arfcn);
-int trx_if_cmd_txtune(struct trx_l1h *l1h, uint16_t arfcn);
+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);
int trx_if_cmd_nohandover(struct trx_l1h *l1h, uint8_t tn, uint8_t ss);
int trx_if_send_burst(struct trx_l1h *l1h, const struct trx_dl_burst_req *br);
@@ -41,6 +42,6 @@ int trx_if_powered(struct trx_l1h *l1h);
#define TRX_DATA_FORMAT_VER 1
/* Format negotiation command */
-int trx_if_cmd_setformat(struct trx_l1h *l1h, uint8_t ver);
+int trx_if_cmd_setformat(struct trx_l1h *l1h, uint8_t ver, trx_if_cmd_generic_cb *cb);
#endif /* TRX_IF_H */
diff --git a/src/osmo-bts-trx/trx_provision_fsm.c b/src/osmo-bts-trx/trx_provision_fsm.c
index fbeee371..611ec69b 100644
--- a/src/osmo-bts-trx/trx_provision_fsm.c
+++ b/src/osmo-bts-trx/trx_provision_fsm.c
@@ -56,14 +56,37 @@ static void l1if_poweronoff_cb(struct trx_l1h *l1h, bool poweronoff, int rc)
osmo_fsm_inst_dispatch(l1h->provision_fi, TRX_PROV_EV_POWEROFF_CNF, (void*)(intptr_t)rc);
}
+
+void l1if_rxtune_cb(struct trx_l1h *l1h, int rc)
+{
+ osmo_fsm_inst_dispatch(l1h->provision_fi, TRX_PROV_EV_RXTUNE_CNF, (void*)(intptr_t)rc);
+}
+
+void l1if_txtune_cb(struct trx_l1h *l1h, int rc)
+{
+ osmo_fsm_inst_dispatch(l1h->provision_fi, TRX_PROV_EV_TXTUNE_CNF, (void*)(intptr_t)rc);
+}
+
+void l1if_settsc_cb(struct trx_l1h *l1h, int rc)
+{
+ osmo_fsm_inst_dispatch(l1h->provision_fi, TRX_PROV_EV_SETTSC_CNF, (void*)(intptr_t)rc);
+}
+
+void l1if_setbsic_cb(struct trx_l1h *l1h, int rc)
+{
+ osmo_fsm_inst_dispatch(l1h->provision_fi, TRX_PROV_EV_SETBSIC_CNF, (void*)(intptr_t)rc);
+}
+
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);
+ osmo_fsm_inst_dispatch(l1h->provision_fi, TRX_PROV_EV_NOMTXPOWER_CNF, (void*)(intptr_t)nominal_power);
+}
- l1if_trx_set_nominal_power(trx, nominal_power);
+void l1if_setformat_cb(struct trx_l1h *l1h, int rc)
+{
+ osmo_fsm_inst_dispatch(l1h->provision_fi, TRX_PROV_EV_SETFORMAT_CNF, (void*)(intptr_t)rc);
}
/*
@@ -87,59 +110,58 @@ int l1if_provision_transceiver_trx(struct trx_l1h *l1h)
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);
+ /* before power on */
+ if (l1h->config.arfcn_valid) {
+ if (!l1h->config.rxtune_sent) {
+ trx_if_cmd_rxtune(l1h, l1h->config.arfcn, l1if_rxtune_cb);
+ l1h->config.rxtune_sent = true;
+ l1h->config.rxtune_acked = false;
+ }
+ if (!l1h->config.txtune_sent) {
+ trx_if_cmd_txtune(l1h, l1h->config.arfcn, l1if_txtune_cb);
+ l1h->config.txtune_sent = true;
+ l1h->config.txtune_acked = false;
+ }
+ if (l1h->config.txtune_acked) {
/* 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)
+ if (!l1h->config.nominal_power_set_by_vty && !l1h->config.nomtxpower_sent) {
trx_if_cmd_getnompower(l1h, l1if_getnompower_cb);
- l1h->config.arfcn_sent = true;
- }
- if (!l1h->config.tsc_sent) {
- trx_if_cmd_settsc(l1h, l1h->config.tsc);
- l1h->config.tsc_sent = true;
- }
- if (!l1h->config.bsic_sent) {
- trx_if_cmd_setbsic(l1h, l1h->config.bsic);
- l1h->config.bsic_sent = true;
- }
-
- /* 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.nomtxpower_sent = true;
+ l1h->config.nomtxpower_acked = false;
}
- l1h->config.setformat_sent = true;
}
+ }
+ if (!pinst->phy_link->u.osmotrx.use_legacy_setbsic &&
+ l1h->config.tsc_valid && !l1h->config.tsc_sent) {
+ trx_if_cmd_settsc(l1h, l1h->config.tsc, l1if_settsc_cb);
+ l1h->config.tsc_sent = true;
+ l1h->config.tsc_acked = false;
+ }
+ if (pinst->phy_link->u.osmotrx.use_legacy_setbsic &&
+ l1h->config.bsic_valid && !l1h->config.bsic_sent) {
+ trx_if_cmd_setbsic(l1h, l1h->config.bsic, l1if_setbsic_cb);
+ l1h->config.bsic_sent = true;
+ l1h->config.bsic_acked = false;
+ }
- 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;
+ /* Ask transceiver to use the newest TRXD header version if not using it yet */
+ if (!l1h->config.setformat_sent) {
+ l1h->config.setformat_sent = true;
+ if (plink->u.osmotrx.trxd_hdr_ver_max == 0) {
+ LOGPPHI(pinst, DL1C, LOGL_INFO,
+ "No need to negotiate max TRXD version 0");
+ l1h->config.trxd_hdr_ver_use = 0;
+ l1h->config.setformat_acked = true;
+ } else {
+ trx_if_cmd_setformat(l1h, l1h->config.trxd_hdr_ver_req, l1if_setformat_cb);
+ l1h->config.setformat_acked = false;
}
-
- return 0;
}
- LOGPPHI(pinst, DL1C, LOGL_INFO, "Delaying provision, TRX attributes not yet received from BSC:%s%s%s%s\n",
- l1h->config.enabled ? "" :" enable",
- l1h->config.tsc_valid ? "" : " tsc",
- l1h->config.bsic_valid ? "" : " bsic",
- l1h->config.arfcn_valid ? "" : " arfcn");
- return 1;
+ return 0;
}
static void l1if_setslot_cb(struct trx_l1h *l1h, uint8_t tn, uint8_t type, int rc)
@@ -182,6 +204,20 @@ static bool update_ts_data(struct trx_l1h *l1h, struct trx_prov_ev_cfg_ts_data*
return false;
}
+/* Whether a given TRX is fully configured and can be powered on */
+static bool trx_can_be_powered_on(struct trx_l1h *l1h)
+{
+ struct phy_instance *pinst = l1h->phy_inst;
+ if (l1h->config.enabled && l1h->config.rxtune_acked && l1h->config.txtune_acked &&
+ (l1h->config.bsic_acked || !pinst->phy_link->u.osmotrx.use_legacy_setbsic) &&
+ (l1h->config.tsc_acked || pinst->phy_link->u.osmotrx.use_legacy_setbsic) &&
+ (l1h->config.nomtxpower_acked || l1h->config.nominal_power_set_by_vty) &&
+ (l1h->config.setformat_acked)) {
+ return true;
+ }
+ return false;
+}
+
//////////////////////////
// FSM STATE ACTIONS
@@ -202,12 +238,24 @@ static void st_closed(struct osmo_fsm_inst *fi, uint32_t event, void *data)
}
}
+static void st_open_poweroff_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+ struct trx_l1h *l1h = (struct trx_l1h *)fi->priv;
+ struct phy_instance *pinst = l1h->phy_inst;
+
+ l1h->config.trxd_hdr_ver_req = pinst->phy_link->u.osmotrx.trxd_hdr_ver_max;
+}
+
static void st_open_poweroff(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
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;
switch(event) {
case TRX_PROV_EV_CFG_ENABLE:
@@ -226,7 +274,9 @@ static void st_open_poweroff(struct osmo_fsm_inst *fi, uint32_t event, void *dat
if (l1h->config.arfcn != arfcn || !l1h->config.arfcn_valid) {
l1h->config.arfcn = arfcn;
l1h->config.arfcn_valid = true;
- l1h->config.arfcn_sent = false;
+ l1h->config.txtune_sent = false;
+ l1h->config.rxtune_sent = false;
+ l1h->config.nomtxpower_sent = false;
}
break;
case TRX_PROV_EV_CFG_TSC:
@@ -240,17 +290,84 @@ static void st_open_poweroff(struct osmo_fsm_inst *fi, uint32_t event, void *dat
case TRX_PROV_EV_CFG_TS:
update_ts_data(l1h, (struct trx_prov_ev_cfg_ts_data*)data);
break;
+
+ /* CONFIRMATIONS FROM TRXC */
+ case TRX_PROV_EV_RXTUNE_CNF:
+ if (l1h->config.rxtune_sent)
+ l1h->config.rxtune_acked = true;
+ break;
+ case TRX_PROV_EV_TXTUNE_CNF:
+ if (l1h->config.txtune_sent)
+ l1h->config.txtune_acked = true;
+ break;
+ case TRX_PROV_EV_NOMTXPOWER_CNF:
+ nominal_power = (int)(intptr_t)data;
+ if (l1h->config.nomtxpower_sent)
+ l1h->config.nomtxpower_acked = true;
+ l1if_trx_set_nominal_power(trx, nominal_power);
+ break;
+ case TRX_PROV_EV_SETBSIC_CNF:
+ if (l1h->config.bsic_sent)
+ l1h->config.bsic_acked = true;
+ break;
+ case TRX_PROV_EV_SETTSC_CNF:
+ if (l1h->config.tsc_sent)
+ l1h->config.tsc_acked = true;
+ break;
+ case TRX_PROV_EV_SETFORMAT_CNF:
+ status = (int)(intptr_t)data;
+ /* Transceiver may suggest a lower version (than requested) */
+ if (status == l1h->config.trxd_hdr_ver_req) {
+ l1h->config.trxd_hdr_ver_use = status;
+ l1h->config.setformat_acked = true;
+ LOGPPHI(l1h->phy_inst, DTRX, LOGL_INFO,
+ "Using TRXD header format version %u\n",
+ l1h->config.trxd_hdr_ver_use);
+ } else {
+ LOGPPHI(l1h->phy_inst, DTRX, LOGL_DEBUG,
+ "Transceiver suggests TRXD header version %u (requested %u)\n",
+ status, l1h->config.trxd_hdr_ver_req);
+ /* Send another SETFORMAT with suggested version */
+ l1h->config.trxd_hdr_ver_req = status;
+ l1h->config.setformat_sent = false;
+ }
+ break;
+ default:
+ OSMO_ASSERT(0);
}
- /* 0 = if we gathered all date and could go forward :*/
- if (l1if_provision_transceiver_trx(l1h) == 0) {
+ l1if_provision_transceiver_trx(l1h);
+
+ /* if we gathered all data and could go forward :*/
+ if (trx_can_be_powered_on(l1h)) {
if (l1h->phy_inst->num == 0)
trx_prov_fsm_state_chg(fi, TRX_PROV_ST_OPEN_WAIT_POWERON_CNF);
else
trx_prov_fsm_state_chg(fi, TRX_PROV_ST_OPEN_POWERON);
+ } else {
+ LOGPPHI(pinst, DL1C, LOGL_INFO, "Delaying poweron, TRX attributes not yet configured:%s%s%s%s%s%s\n",
+ l1h->config.enabled ? "" :" enable",
+ pinst->phy_link->u.osmotrx.use_legacy_setbsic ?
+ (l1h->config.bsic_valid ? (l1h->config.bsic_acked ? "" : " bsic-ack") : " bsic") :
+ (l1h->config.tsc_valid ? (l1h->config.tsc_acked ? "" : " tsc-ack") : " tsc"),
+ l1h->config.arfcn_valid ? "" : " arfcn",
+ l1h->config.rxtune_acked ? "" : " rxtune-ack",
+ l1h->config.nominal_power_set_by_vty ? "" : (l1h->config.nomtxpower_acked ? "" : " nomtxpower-ack"),
+ l1h->config.setformat_acked ? "" : " setformat-ack"
+ );
}
}
+
+static void st_open_wait_power_cnf_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+ struct trx_l1h *l1h = (struct trx_l1h *)fi->priv;
+ struct phy_instance *pinst = l1h->phy_inst;
+
+ trx_if_cmd_poweron(l1h, l1if_poweronoff_cb);
+ pinst->phy_link->u.osmotrx.poweronoff_sent = true;
+}
+
static void st_open_wait_power_cnf(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
struct trx_l1h *l1h = (struct trx_l1h *)fi->priv;
@@ -392,11 +509,18 @@ static struct osmo_fsm_state trx_prov_fsm_states[] = {
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_CFG_TS) |
+ X(TRX_PROV_EV_RXTUNE_CNF) |
+ X(TRX_PROV_EV_TXTUNE_CNF) |
+ X(TRX_PROV_EV_NOMTXPOWER_CNF) |
+ X(TRX_PROV_EV_SETBSIC_CNF) |
+ X(TRX_PROV_EV_SETTSC_CNF) |
+ X(TRX_PROV_EV_SETFORMAT_CNF),
.out_state_mask =
X(TRX_PROV_ST_OPEN_WAIT_POWERON_CNF) |
X(TRX_PROV_ST_OPEN_POWERON),
.name = "OPEN_POWEROFF",
+ .onenter = st_open_poweroff_on_enter,
.action = st_open_poweroff,
},
[TRX_PROV_ST_OPEN_WAIT_POWERON_CNF] = {
@@ -406,6 +530,7 @@ static struct osmo_fsm_state trx_prov_fsm_states[] = {
.out_state_mask =
X(TRX_PROV_ST_OPEN_POWERON),
.name = "OPEN_WAIT_POWERON_CNF",
+ .onenter = st_open_wait_power_cnf_on_enter,
.action = st_open_wait_power_cnf,
},
[TRX_PROV_ST_OPEN_POWERON] = {
@@ -438,6 +563,12 @@ const struct value_string trx_prov_fsm_event_names[] = {
OSMO_VALUE_STRING(TRX_PROV_EV_CFG_TS),
OSMO_VALUE_STRING(TRX_PROV_EV_CFG_RXGAIN),
OSMO_VALUE_STRING(TRX_PROV_EV_CFG_SETMAXDLY),
+ OSMO_VALUE_STRING(TRX_PROV_EV_RXTUNE_CNF),
+ OSMO_VALUE_STRING(TRX_PROV_EV_TXTUNE_CNF),
+ OSMO_VALUE_STRING(TRX_PROV_EV_NOMTXPOWER_CNF),
+ OSMO_VALUE_STRING(TRX_PROV_EV_SETBSIC_CNF),
+ OSMO_VALUE_STRING(TRX_PROV_EV_SETTSC_CNF),
+ OSMO_VALUE_STRING(TRX_PROV_EV_SETFORMAT_CNF),
OSMO_VALUE_STRING(TRX_PROV_EV_POWERON_CNF),
OSMO_VALUE_STRING(TRX_PROV_EV_POWEROFF),
OSMO_VALUE_STRING(TRX_PROV_EV_POWEROFF_CNF),
diff --git a/src/osmo-bts-trx/trx_provision_fsm.h b/src/osmo-bts-trx/trx_provision_fsm.h
index 7fede35c..24eb2687 100644
--- a/src/osmo-bts-trx/trx_provision_fsm.h
+++ b/src/osmo-bts-trx/trx_provision_fsm.h
@@ -46,6 +46,12 @@ enum trx_provision_fsm_events {
TRX_PROV_EV_CFG_TS,
TRX_PROV_EV_CFG_RXGAIN,
TRX_PROV_EV_CFG_SETMAXDLY,
+ TRX_PROV_EV_RXTUNE_CNF,
+ TRX_PROV_EV_TXTUNE_CNF,
+ TRX_PROV_EV_NOMTXPOWER_CNF,
+ TRX_PROV_EV_SETBSIC_CNF,
+ TRX_PROV_EV_SETTSC_CNF,
+ TRX_PROV_EV_SETFORMAT_CNF,
TRX_PROV_EV_POWERON_CNF,
TRX_PROV_EV_POWEROFF,
TRX_PROV_EV_POWEROFF_CNF,