osmo-bts/src/osmo-bts-trx/l1_if.h

144 lines
3.8 KiB
C
Raw Normal View History

#ifndef L1_IF_H_TRX
#define L1_IF_H_TRX
#include <osmocom/core/rate_ctr.h>
#include <osmo-bts/scheduler.h>
#include <osmo-bts/phy_link.h>
bts-trx: Detect duplicated responses for retransmitted commands It was detected that under some conditions, osmo-trx (with limesdr) may take a long time to answer to CMDs, which means trx_ctrl_timer will trigger re-transmitting the last sent but yet unacked CMD. Due to the high latency in osmo-trx, the original AND the rentrasnmited CMD are handled after a while and RSP messages are sent for both. When osmo-bts-trx receives the first RSP, it was marking the CMD as acked and carried on with next one. Then, when the RSP from the retransmited CMD arrives, it already lost state and doesn't know where does that come from. As a result, osmo-bts-trx shutdowns. The issue can be seen in the following truncated log from osmo-bts-trx with TRX category enabled: 20180117135228175 Enqueuing TRX control command 'CMD RXTUNE 1782000' 20180117135228175 Enqueuing TRX control command 'CMD TXTUNE 1877000' 20180117135228175 Enqueuing TRX control command 'CMD SETTSC 7' 20180117135228175 Enqueuing TRX control command 'CMD POWERON' 20180117135228175 Enqueuing TRX control command 'CMD SETRXGAIN 1' 20180117135228175 Enqueuing TRX control command 'CMD SETPOWER 20' 20180117135228175 Enqueuing TRX control command 'CMD SETSLOT 0 5' ... 20180117135249829 Response message: 'RSP POWEROFF 0' 20180117135249855 Response message: 'RSP RXTUNE 0 1782000' 20180117135249876 Response message: 'RSP TXTUNE 0 1877000' 20180117135249876 Response message: 'RSP SETTSC 0 7' 20180117135250648 Response message: 'RSP POWERON 0' 20180117135251150 Response message: 'RSP SETRXGAIN 0 0' 20180117135253151 No response from transceiver for phy0.0 (CMD SETPOWER 20) 20180117135253777 Response message: 'RSP SETPOWER 0 20' 20180117135254535 Clock indication: fn=2018878 20180117135255777 No response from transceiver for phy0.0 (CMD SETSLOT 0 5) ... 20180117135256858 Response message: 'RSP SETPOWER 0 20' 20180117135256858 Discarding duplicated RSP from old CMD 'RSP SETPOWER 0 20' 20180117135256858 Response message: 'RSP SETSLOT 0 0 5' 20180117135256858 Response message: 'RSP SETSLOT 0 0 5' 20180117135256858 Discarding duplicated RSP from old CMD 'RSP SETSLOT 0 0 5' Change-Id: I3633cba212edde878f83ed36aef922aaca6f503a
2018-01-17 12:45:40 +00:00
#include "trx_if.h"
/*
* TRX frame clock handling
*
* In a "normal" synchronous PHY layer, we would be polled every time
* the PHY needs data for a given frame number. However, the
* OpenBTS-inherited TRX protocol works differently: We (L1) must
* autonomously send burst data based on our own clock, and every so
* often (currently every ~ 216 frames), we get a clock indication from
* the TRX.
*
* We're using a MONOTONIC timerfd interval timer for the 4.615ms frame
* intervals, and then compute + send the 8 bursts for that frame.
*
* Upon receiving a clock indication from the TRX, we compensate
* accordingly: If we were transmitting too fast, we're delaying the
* next interval timer accordingly. If we were too slow, we immediately
* send burst data for the missing frame numbers.
*/
/* bts-trx specific rate counters */
enum {
BTSTRX_CTR_SCHED_DL_MISS_FN,
osmo-bts-trx/scheduler: implement baseband frequency hopping The idea behind the baseband frequency hopping is quite simple: we have several RF carriers (transceivers) transmitting and receiving on fixed frequencies (just like in a regular multi-trx setup), and an additional burst routing layer between the schedulear and the transceiver interface (TRXD over UDP). Speaking in terms of the proposed implementation: - on Downlink, dlfh_route_br() calculates the ARFCN corresponding to the current TDMA frame number according to the hopping sequence parametets, and picks the transceiver with matching ARFCN; - on Uplink, ulfh_route_bi() iterates over the transceiver list of of the BTS, calculating hopping ARFCNs for equivalent timeslots, and picks the one with ARFCN matching the received burst. In order to avoid frequent transceiver lookups on the Downlink path, dlfh_route_br() maintains a "cache" in the timeslot state structure. Unfortunately, this "cache" seems to be useless on the Uplink path, so ulfh_route_bi() always needs to lookup the matching transceiver for each burst received over the TRXD interface. It may also happen that the scheduler will be unable to route an Uplink or Downlink burst, e.g. due to inconsistent / incorrect hopping sequence parameters received from the BSC, or in case if a transceiver gets RF-locked by the BTS operator. Such events are logged as "FATAL" and aditionally signalled by the following osmo-bts-trx specific rate counters: - trx_sched:dl_fh_no_carrier (Downlink), and - trx_sched:ul_fh_no_carrier (Uplink). Change-Id: I68f4ae09fd0789ad0d8f1c1e17e17dfc4de8e462 Related: SYS#4868, OS#4546
2020-06-15 10:22:39 +00:00
BTSTRX_CTR_SCHED_DL_FH_NO_CARRIER,
BTSTRX_CTR_SCHED_DL_FH_CACHE_MISS,
osmo-bts-trx/scheduler: implement baseband frequency hopping The idea behind the baseband frequency hopping is quite simple: we have several RF carriers (transceivers) transmitting and receiving on fixed frequencies (just like in a regular multi-trx setup), and an additional burst routing layer between the schedulear and the transceiver interface (TRXD over UDP). Speaking in terms of the proposed implementation: - on Downlink, dlfh_route_br() calculates the ARFCN corresponding to the current TDMA frame number according to the hopping sequence parametets, and picks the transceiver with matching ARFCN; - on Uplink, ulfh_route_bi() iterates over the transceiver list of of the BTS, calculating hopping ARFCNs for equivalent timeslots, and picks the one with ARFCN matching the received burst. In order to avoid frequent transceiver lookups on the Downlink path, dlfh_route_br() maintains a "cache" in the timeslot state structure. Unfortunately, this "cache" seems to be useless on the Uplink path, so ulfh_route_bi() always needs to lookup the matching transceiver for each burst received over the TRXD interface. It may also happen that the scheduler will be unable to route an Uplink or Downlink burst, e.g. due to inconsistent / incorrect hopping sequence parameters received from the BSC, or in case if a transceiver gets RF-locked by the BTS operator. Such events are logged as "FATAL" and aditionally signalled by the following osmo-bts-trx specific rate counters: - trx_sched:dl_fh_no_carrier (Downlink), and - trx_sched:ul_fh_no_carrier (Uplink). Change-Id: I68f4ae09fd0789ad0d8f1c1e17e17dfc4de8e462 Related: SYS#4868, OS#4546
2020-06-15 10:22:39 +00:00
BTSTRX_CTR_SCHED_UL_FH_NO_CARRIER,
};
/*! clock state of a given TRX */
struct osmo_trx_clock_state {
/*! number of FN periods without TRX clock indication */
uint32_t fn_without_clock_ind;
struct {
/*! last FN we processed based on FN period timer */
uint32_t fn;
/*! time at which we last processed FN */
struct timespec tv;
} last_fn_timer;
struct {
/*! last FN we received a clock indication for */
uint32_t fn;
/*! time at which we received the last clock indication */
struct timespec tv;
} last_clk_ind;
/*! Osmocom FD wrapper for timerfd */
struct osmo_fd fn_timer_ofd;
};
/* gsm_bts->model_priv, specific to osmo-bts-trx */
struct bts_trx_priv {
struct osmo_trx_clock_state clk_s;
struct rate_ctr_group *ctrs; /* bts-trx specific rate counters */
};
struct trx_config {
uint8_t trxd_pdu_ver_req; /* requested TRXD PDU version */
uint8_t trxd_pdu_ver_use; /* actual TRXD PDU version in use */
bool setformat_sent;
bool setformat_acked;
bool enabled;
bool arfcn_valid;
uint16_t arfcn;
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;
bool rxgain_sent;
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;
bool maxdly_sent;
bool maxdlynb_valid;
int maxdlynb;
bool maxdlynb_sent;
uint8_t slotmask;
bool setslot_valid[TRX_NR_TS];
struct {
uint8_t slottype;
uint8_t tsc_set;
uint8_t tsc_val;
bool tsc_valid;
} setslot[TRX_NR_TS];
bool setslot_sent[TRX_NR_TS];
};
struct trx_l1h {
struct llist_head trx_ctrl_list;
bts-trx: Detect duplicated responses for retransmitted commands It was detected that under some conditions, osmo-trx (with limesdr) may take a long time to answer to CMDs, which means trx_ctrl_timer will trigger re-transmitting the last sent but yet unacked CMD. Due to the high latency in osmo-trx, the original AND the rentrasnmited CMD are handled after a while and RSP messages are sent for both. When osmo-bts-trx receives the first RSP, it was marking the CMD as acked and carried on with next one. Then, when the RSP from the retransmited CMD arrives, it already lost state and doesn't know where does that come from. As a result, osmo-bts-trx shutdowns. The issue can be seen in the following truncated log from osmo-bts-trx with TRX category enabled: 20180117135228175 Enqueuing TRX control command 'CMD RXTUNE 1782000' 20180117135228175 Enqueuing TRX control command 'CMD TXTUNE 1877000' 20180117135228175 Enqueuing TRX control command 'CMD SETTSC 7' 20180117135228175 Enqueuing TRX control command 'CMD POWERON' 20180117135228175 Enqueuing TRX control command 'CMD SETRXGAIN 1' 20180117135228175 Enqueuing TRX control command 'CMD SETPOWER 20' 20180117135228175 Enqueuing TRX control command 'CMD SETSLOT 0 5' ... 20180117135249829 Response message: 'RSP POWEROFF 0' 20180117135249855 Response message: 'RSP RXTUNE 0 1782000' 20180117135249876 Response message: 'RSP TXTUNE 0 1877000' 20180117135249876 Response message: 'RSP SETTSC 0 7' 20180117135250648 Response message: 'RSP POWERON 0' 20180117135251150 Response message: 'RSP SETRXGAIN 0 0' 20180117135253151 No response from transceiver for phy0.0 (CMD SETPOWER 20) 20180117135253777 Response message: 'RSP SETPOWER 0 20' 20180117135254535 Clock indication: fn=2018878 20180117135255777 No response from transceiver for phy0.0 (CMD SETSLOT 0 5) ... 20180117135256858 Response message: 'RSP SETPOWER 0 20' 20180117135256858 Discarding duplicated RSP from old CMD 'RSP SETPOWER 0 20' 20180117135256858 Response message: 'RSP SETSLOT 0 0 5' 20180117135256858 Response message: 'RSP SETSLOT 0 0 5' 20180117135256858 Discarding duplicated RSP from old CMD 'RSP SETSLOT 0 0 5' Change-Id: I3633cba212edde878f83ed36aef922aaca6f503a
2018-01-17 12:45:40 +00:00
/* Latest RSPed cmd, used to catch duplicate RSPs from sent retransmissions */
struct trx_ctrl_msg *last_acked;
//struct gsm_bts_trx *trx;
struct phy_instance *phy_inst;
struct osmo_fd trx_ofd_ctrl;
struct osmo_timer_list trx_ctrl_timer;
struct osmo_fd trx_ofd_data;
/* transceiver config */
struct trx_config config;
struct osmo_fsm_inst *provision_fi;
};
struct trx_l1h *trx_l1h_alloc(void *tall_ctx, struct phy_instance *pinst);
int l1if_provision_transceiver_trx(struct trx_l1h *l1h);
int l1if_mph_time_ind(struct gsm_bts *bts, uint32_t fn);
void l1if_trx_set_nominal_power(struct gsm_bts_trx *trx, int nominal_power);
int l1if_trx_start_power_ramp(struct gsm_bts_trx *trx, ramp_compl_cb_t ramp_compl_cb);
enum gsm_phys_chan_config transceiver_chan_type_2_pchan(uint8_t type);
#endif /* L1_IF_H_TRX */