diff options
-rw-r--r-- | src/osmo-bts-trx/l1_if.c | 30 | ||||
-rw-r--r-- | src/osmo-bts-trx/l1_if.h | 1 | ||||
-rw-r--r-- | src/osmo-bts-trx/scheduler.c | 22 | ||||
-rw-r--r-- | src/osmo-bts-trx/trx_if.c | 6 |
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; |