aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/osmo-bts-trx/l1_if.c30
-rw-r--r--src/osmo-bts-trx/l1_if.h1
-rw-r--r--src/osmo-bts-trx/scheduler.c22
-rw-r--r--src/osmo-bts-trx/trx_if.c6
4 files changed, 49 insertions, 10 deletions
diff --git a/src/osmo-bts-trx/l1_if.c b/src/osmo-bts-trx/l1_if.c
index 25aa0f98..8040f4e0 100644
--- a/src/osmo-bts-trx/l1_if.c
+++ b/src/osmo-bts-trx/l1_if.c
@@ -93,14 +93,14 @@ void l1if_reset(struct trx_l1h *l1h)
{
}
-void check_tranceiver_availability(struct trx_l1h *l1h)
+static void check_tranceiver_availability_trx(struct trx_l1h *l1h, int avail)
{
struct gsm_bts_trx *trx = l1h->trx;
uint8_t tn;
/* HACK, we should change state when we receive first clock from
* tranceiver */
- if (1) {
+ if (avail) {
/* signal availability */
oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OK);
oml_mo_tx_sw_act_rep(&trx->mo);
@@ -117,7 +117,23 @@ void check_tranceiver_availability(struct trx_l1h *l1h)
NM_AVSTATE_OFF_LINE);
oml_mo_state_chg(&trx->bb_transc.mo, NM_OPSTATE_DISABLED,
NM_AVSTATE_OFF_LINE);
+
+ for (tn = 0; tn < 8; tn++)
+ oml_mo_state_chg(&trx->ts[tn].mo, NM_OPSTATE_DISABLED,
+ NM_AVSTATE_OFF_LINE);
+ }
+}
+
+int check_tranceiver_availability(struct gsm_bts *bts, int avail)
+{
+ struct gsm_bts_trx *trx;
+ struct trx_l1h *l1h;
+
+ llist_for_each_entry(trx, &bts->trx_list, list) {
+ l1h = trx_l1h_hdl(trx);
+ check_tranceiver_availability_trx(l1h, avail);
}
+ return 0;
}
@@ -128,6 +144,9 @@ int l1if_provision_tranceiver_trx(struct trx_l1h *l1h)
{
uint8_t tn;
+ if (!tranceiver_available)
+ return -EIO;
+
if (l1h->config.poweron
&& l1h->config.tsc_valid
&& l1h->config.bsic_valid
@@ -250,7 +269,7 @@ static int trx_close(struct gsm_bts_trx *trx)
}
/* Set to Operational State: Disabled */
- oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
+ check_tranceiver_availability_trx(l1h, 0);
return 0;
}
@@ -268,9 +287,10 @@ static uint8_t trx_set_bts(struct gsm_bts *bts)
l1h->config.bsic = bsic;
l1h->config.bsic_valid = 1;
l1h->config.bsic_sent = 0;
+ l1if_provision_tranceiver_trx(l1h);
}
- check_tranceiver_availability(l1h);
}
+ check_tranceiver_availability(bts, tranceiver_available);
return 0;
@@ -286,6 +306,7 @@ static uint8_t trx_set_trx(struct gsm_bts_trx *trx)
l1h->config.arfcn = arfcn;
l1h->config.arfcn_valid = 1;
l1h->config.arfcn_sent = 0;
+ l1if_provision_tranceiver_trx(l1h);
}
return 0;
@@ -308,6 +329,7 @@ static uint8_t trx_set_ts(struct gsm_bts_trx_ts *ts)
l1h->config.tsc = tsc;
l1h->config.tsc_valid = 1;
l1h->config.tsc_sent = 0;
+ l1if_provision_tranceiver_trx(l1h);
}
/* set physical channel */
diff --git a/src/osmo-bts-trx/l1_if.h b/src/osmo-bts-trx/l1_if.h
index bb8407fb..7a6afb28 100644
--- a/src/osmo-bts-trx/l1_if.h
+++ b/src/osmo-bts-trx/l1_if.h
@@ -116,6 +116,7 @@ struct trx_l1h {
struct trx_l1h *l1if_open(struct gsm_bts_trx *trx);
void l1if_close(struct trx_l1h *l1h);
void l1if_reset(struct trx_l1h *l1h);
+int check_tranceiver_availability(struct gsm_bts *bts, int avail);
int l1if_provision_tranceiver_trx(struct trx_l1h *l1h);
int l1if_provision_tranceiver(struct gsm_bts *bts);
int l1if_mph_time_ind(struct gsm_bts *bts, uint32_t fn);
diff --git a/src/osmo-bts-trx/scheduler.c b/src/osmo-bts-trx/scheduler.c
index 3224296f..917cbdaf 100644
--- a/src/osmo-bts-trx/scheduler.c
+++ b/src/osmo-bts-trx/scheduler.c
@@ -1937,14 +1937,18 @@ static void trx_ctrl_timer_cb(void *data)
LOGP(DL1C, LOGL_NOTICE, "No more clock from traneiver\n");
+no_clock:
tranceiver_available = 0;
/* flush pending messages of transceiver */
- llist_for_each_entry(trx, &bts->trx_list, list)
+ /* close all logical channels and reset timeslots */
+ llist_for_each_entry(trx, &bts->trx_list, list) {
trx_if_flush(trx_l1h_hdl(trx));
+ trx_sched_reset(trx_l1h_hdl(trx));
+ }
- /* start over provisioning tranceiver */
- l1if_provision_tranceiver(bts);
+ /* tell BSC */
+ check_tranceiver_availability(bts, 0);
return;
}
@@ -1958,10 +1962,10 @@ static void trx_ctrl_timer_cb(void *data)
if (elapsed > FRAME_DURATION_uS * MAX_FN_SKEW || elapsed < 0) {
LOGP(DL1C, LOGL_NOTICE, "PC clock skew: elapsed uS %d\n",
elapsed);
- tranceiver_available = 0;
- return;
+ goto no_clock;
}
+ /* schedule next FN clock */
while (elapsed > FRAME_DURATION_uS / 2) {
tv_clock->tv_usec += FRAME_DURATION_uS;
if (tv_clock->tv_usec >= 1000000) {
@@ -1996,7 +2000,7 @@ new_clock:
tranceiver_last_fn = fn;
trx_sched_fn(tranceiver_last_fn);
- /* schedule first FN to be transmitted */
+ /* schedule first FN clock */
memcpy(tv_clock, &tv_now, sizeof(struct timeval));
tranceiver_available = 1;
memset(&tranceiver_clock_timer, 0,
@@ -2006,6 +2010,12 @@ new_clock:
osmo_timer_schedule(&tranceiver_clock_timer, 0,
FRAME_DURATION_uS);
+ /* start provisioning tranceiver */
+ l1if_provision_tranceiver(bts);
+
+ /* tell BSC */
+ check_tranceiver_availability(bts, 1);
+
return 0;
}
diff --git a/src/osmo-bts-trx/trx_if.c b/src/osmo-bts-trx/trx_if.c
index e35b7cd4..7d1be857 100644
--- a/src/osmo-bts-trx/trx_if.c
+++ b/src/osmo-bts-trx/trx_if.c
@@ -183,6 +183,12 @@ static int trx_ctrl_cmd(struct trx_l1h *l1h, int critical, const char *cmd,
va_list ap;
int l, pending = 0;
+ if (!tranceiver_available) {
+ LOGP(DTRX, LOGL_ERROR, "CTRL ignored: No clock from "
+ "tranceiver, please fix!\n");
+ return -EIO;
+ }
+
if (!llist_empty(&l1h->trx_ctrl_list))
pending = 1;