aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2013-02-07 14:09:06 +0100
committerHarald Welte <laforge@gnumonks.org>2015-09-06 14:47:29 +0200
commit3ef34a9672ab78a656ebdb3a6e60b09c6bb87a12 (patch)
treee8705557e4657852518154be251134b72e67179a
parent86d5390ceeae05a56052d5e8882f8d8c4d88f74c (diff)
TRX: Use received TRX clocks to determine availablility of tranceiver
Only if transceiver becomes available, control commands are sent. If tranceiver is gone, reset scheduler. The current availability state is sent to BSC via OML state change commands.
-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;