<p>fixeria has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bts/+/24179">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">[VAMOS] Re-organize osmo-bts-trx specific structures<br><br>Change-Id: I7c4379e43a25e9d858d582a99bf6c4b65c9af481<br>---<br>M include/osmo-bts/gsm_data.h<br>M include/osmo-bts/phy_link.h<br>M include/osmo-bts/scheduler.h<br>M include/osmo-bts/scheduler_backend.h<br>M src/common/scheduler.c<br>M src/osmo-bts-trx/l1_if.c<br>M src/osmo-bts-trx/l1_if.h<br>M src/osmo-bts-trx/loops.c<br>M src/osmo-bts-trx/loops.h<br>M src/osmo-bts-trx/sched_lchan_fcch_sch.c<br>M src/osmo-bts-trx/sched_lchan_pdtch.c<br>M src/osmo-bts-trx/sched_lchan_rach.c<br>M src/osmo-bts-trx/sched_lchan_tchf.c<br>M src/osmo-bts-trx/sched_lchan_tchh.c<br>M src/osmo-bts-trx/sched_lchan_xcch.c<br>M src/osmo-bts-trx/scheduler_trx.c<br>M src/osmo-bts-trx/trx_if.c<br>M src/osmo-bts-virtual/bts_model.c<br>M src/osmo-bts-virtual/l1_if.c<br>M src/osmo-bts-virtual/l1_if.h<br>M src/osmo-bts-virtual/scheduler_virtbts.c<br>21 files changed, 400 insertions(+), 509 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/79/24179/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h</span><br><span>index ff0c89c..5b441be 100644</span><br><span>--- a/include/osmo-bts/gsm_data.h</span><br><span>+++ b/include/osmo-bts/gsm_data.h</span><br><span>@@ -455,6 +455,9 @@</span><br><span>   /* Transceiver "cache" for frequency hopping */</span><br><span>    const struct gsm_bts_trx *fh_trx_list[64];</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+        /* Implementation specific structure(s) */</span><br><span style="color: hsl(120, 100%, 40%);">+    void *impl;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>        struct gsm_lchan lchan[TS_MAX_LCHAN];</span><br><span> };</span><br><span> </span><br><span>diff --git a/include/osmo-bts/phy_link.h b/include/osmo-bts/phy_link.h</span><br><span>index 467ad52..c4b60f3 100644</span><br><span>--- a/include/osmo-bts/phy_link.h</span><br><span>+++ b/include/osmo-bts/phy_link.h</span><br><span>@@ -115,9 +115,6 @@</span><br><span>                       bool sw_act_reported;</span><br><span>                } osmotrx;</span><br><span>           struct {</span><br><span style="color: hsl(0, 100%, 40%);">-                        struct l1sched_trx sched;</span><br><span style="color: hsl(0, 100%, 40%);">-               } virt;</span><br><span style="color: hsl(0, 100%, 40%);">-         struct {</span><br><span>                     /* logical transceiver number within one PHY */</span><br><span>                      uint32_t trx_id;</span><br><span>                     /* trx lock state variable */</span><br><span>diff --git a/include/osmo-bts/scheduler.h b/include/osmo-bts/scheduler.h</span><br><span>index 2d613e7..e5bd1a1 100644</span><br><span>--- a/include/osmo-bts/scheduler.h</span><br><span>+++ b/include/osmo-bts/scheduler.h</span><br><span>@@ -137,6 +137,8 @@</span><br><span> };</span><br><span> </span><br><span> struct l1sched_ts {</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gsm_bts_trx_ts   *ts;            /* timeslot we belong to */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>        uint8_t                 mf_index;       /* selected multiframe index */</span><br><span>      uint8_t                 mf_period;      /* period of multiframe */</span><br><span>   const struct trx_sched_frame *mf_frames; /* pointer to frame layout */</span><br><span>@@ -149,25 +151,18 @@</span><br><span>       struct l1sched_chan_state chan_state[_TRX_CHAN_MAX];</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct l1sched_trx {</span><br><span style="color: hsl(0, 100%, 40%);">-      struct gsm_bts_trx      *trx;</span><br><span style="color: hsl(0, 100%, 40%);">-   struct l1sched_ts       ts[TRX_NR_TS];</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct l1sched_ts *l1sched_trx_get_ts(struct l1sched_trx *l1t, uint8_t tn);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> </span><br><span> /*! \brief Initialize the scheduler data structures */</span><br><span style="color: hsl(0, 100%, 40%);">-int trx_sched_init(struct l1sched_trx *l1t, struct gsm_bts_trx *trx);</span><br><span style="color: hsl(120, 100%, 40%);">+void trx_sched_init(struct gsm_bts_trx *trx);</span><br><span> </span><br><span> /*! \brief De-initialize the scheduler data structures */</span><br><span style="color: hsl(0, 100%, 40%);">-void trx_sched_exit(struct l1sched_trx *l1t);</span><br><span style="color: hsl(120, 100%, 40%);">+void trx_sched_clean(struct gsm_bts_trx *trx);</span><br><span> </span><br><span> /*! \brief Handle a PH-DATA.req from L2 down to L1 */</span><br><span style="color: hsl(0, 100%, 40%);">-int trx_sched_ph_data_req(struct l1sched_trx *l1t, struct osmo_phsap_prim *l1sap);</span><br><span style="color: hsl(120, 100%, 40%);">+int trx_sched_ph_data_req(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap);</span><br><span> </span><br><span> /*! \brief Handle a PH-TCH.req from L2 down to L1 */</span><br><span style="color: hsl(0, 100%, 40%);">-int trx_sched_tch_req(struct l1sched_trx *l1t, struct osmo_phsap_prim *l1sap);</span><br><span style="color: hsl(120, 100%, 40%);">+int trx_sched_tch_req(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap);</span><br><span> </span><br><span> /*! \brief PHY informs us of new (current) GSM frame number */</span><br><span> int trx_sched_clock(struct gsm_bts *bts, uint32_t fn);</span><br><span>@@ -179,21 +174,19 @@</span><br><span> int trx_sched_clock_stopped(struct gsm_bts *bts);</span><br><span> </span><br><span> /*! \brief set multiframe scheduler to given physical channel config */</span><br><span style="color: hsl(0, 100%, 40%);">-int trx_sched_set_pchan(struct l1sched_trx *l1t, uint8_t tn,</span><br><span style="color: hsl(0, 100%, 40%);">-        enum gsm_phys_chan_config pchan);</span><br><span style="color: hsl(120, 100%, 40%);">+int trx_sched_set_pchan(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config pchan);</span><br><span> </span><br><span> /*! \brief set all matching logical channels active/inactive */</span><br><span style="color: hsl(0, 100%, 40%);">-int trx_sched_set_lchan(struct l1sched_trx *l1t, uint8_t chan_nr, uint8_t link_id, bool active);</span><br><span style="color: hsl(120, 100%, 40%);">+int trx_sched_set_lchan(struct gsm_lchan *lchan, uint8_t chan_nr, uint8_t link_id, bool active);</span><br><span> </span><br><span> /*! \brief set mode of all matching logical channels to given mode(s) */</span><br><span style="color: hsl(0, 100%, 40%);">-int trx_sched_set_mode(struct l1sched_trx *l1t, uint8_t chan_nr, uint8_t rsl_cmode,</span><br><span style="color: hsl(120, 100%, 40%);">+int trx_sched_set_mode(struct gsm_bts_trx_ts *ts, uint8_t chan_nr, uint8_t rsl_cmode,</span><br><span>   uint8_t tch_mode, int codecs, uint8_t codec0, uint8_t codec1,</span><br><span>        uint8_t codec2, uint8_t codec3, uint8_t initial_codec,</span><br><span>       uint8_t handover);</span><br><span> </span><br><span> /*! \brief set ciphering on given logical channels */</span><br><span style="color: hsl(0, 100%, 40%);">-int trx_sched_set_cipher(struct l1sched_trx *l1t, uint8_t chan_nr, int downlink,</span><br><span style="color: hsl(0, 100%, 40%);">-        int algo, uint8_t *key, int key_len);</span><br><span style="color: hsl(120, 100%, 40%);">+int trx_sched_set_cipher(struct gsm_lchan *lchan, uint8_t chan_nr, bool downlink);</span><br><span> </span><br><span> /* frame structures */</span><br><span> struct trx_sched_frame {</span><br><span>@@ -274,8 +267,8 @@</span><br><span> };</span><br><span> </span><br><span> /*! Handle an UL burst received by PHY */</span><br><span style="color: hsl(0, 100%, 40%);">-int trx_sched_route_burst_ind(struct trx_ul_burst_ind *bi, struct l1sched_trx *l1t);</span><br><span style="color: hsl(0, 100%, 40%);">-int trx_sched_ul_burst(struct l1sched_trx *l1t, struct trx_ul_burst_ind *bi);</span><br><span style="color: hsl(120, 100%, 40%);">+int trx_sched_route_burst_ind(const struct gsm_bts_trx *trx, struct trx_ul_burst_ind *bi);</span><br><span style="color: hsl(120, 100%, 40%);">+int trx_sched_ul_burst(struct l1sched_ts *l1ts, struct trx_ul_burst_ind *bi);</span><br><span> </span><br><span> /* Averaging mode for trx_sched_meas_avg() */</span><br><span> enum sched_meas_avg_mode {</span><br><span>diff --git a/include/osmo-bts/scheduler_backend.h b/include/osmo-bts/scheduler_backend.h</span><br><span>index 13ca71b..2a0dd11 100644</span><br><span>--- a/include/osmo-bts/scheduler_backend.h</span><br><span>+++ b/include/osmo-bts/scheduler_backend.h</span><br><span>@@ -1,21 +1,18 @@</span><br><span> #pragma once</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#define LOGL1S(subsys, level, l1t, tn, chan, fn, fmt, args ...)      \</span><br><span style="color: hsl(120, 100%, 40%);">+#define LOGL1S(subsys, level, l1ts, chan, fn, fmt, args ...) \</span><br><span>            LOGP(subsys, level, "%s %s %s: " fmt,         \</span><br><span>                    gsm_fn_as_gsmtime_str(fn),              \</span><br><span style="color: hsl(0, 100%, 40%);">-                       gsm_ts_name(&(l1t)->trx->ts[tn]),     \</span><br><span style="color: hsl(120, 100%, 40%);">+                     gsm_ts_name((l1ts)->ts),             \</span><br><span>                    chan >=0 ? trx_chan_desc[chan].name : "", ## args)</span><br><span> </span><br><span> /* Logging helper adding context from trx_{ul,dl}_burst_{ind,req} */</span><br><span style="color: hsl(0, 100%, 40%);">-#define LOGL1SB(subsys, level, l1t, b, fmt, args ...) \</span><br><span style="color: hsl(0, 100%, 40%);">-      LOGL1S(subsys, level, l1t, (b)->tn, (b)->chan, (b)->fn, fmt, ## args)</span><br><span style="color: hsl(120, 100%, 40%);">+#define LOGL1SB(subsys, level, l1ts, b, fmt, args ...) \</span><br><span style="color: hsl(120, 100%, 40%);">+      LOGL1S(subsys, level, l1ts, (b)->chan, (b)->fn, fmt, ## args)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-typedef int trx_sched_rts_func(struct l1sched_trx *l1t, uint8_t tn,</span><br><span style="color: hsl(0, 100%, 40%);">-                             uint32_t fn, enum trx_chan_type chan);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-typedef int trx_sched_dl_func(struct l1sched_trx *l1t, struct trx_dl_burst_req *br);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-typedef int trx_sched_ul_func(struct l1sched_trx *l1t, const struct trx_ul_burst_ind *bi);</span><br><span style="color: hsl(120, 100%, 40%);">+typedef int trx_sched_rts_func(const struct l1sched_ts *l1ts, const struct trx_dl_burst_req *br);</span><br><span style="color: hsl(120, 100%, 40%);">+typedef int trx_sched_dl_func(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);</span><br><span style="color: hsl(120, 100%, 40%);">+typedef int trx_sched_ul_func(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi);</span><br><span> </span><br><span> struct trx_chan_desc {</span><br><span>       /*! \brief Human-readable name */</span><br><span>@@ -42,35 +39,34 @@</span><br><span> extern const ubit_t _sched_egprs_tsc[8][78];</span><br><span> extern const ubit_t _sched_sch_train[64];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct msgb *_sched_dequeue_prim(struct l1sched_trx *l1t,</span><br><span style="color: hsl(0, 100%, 40%);">-                                const struct trx_dl_burst_req *br);</span><br><span style="color: hsl(120, 100%, 40%);">+struct msgb *_sched_dequeue_prim(struct l1sched_ts *l1ts, const struct trx_dl_burst_req *br);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int _sched_compose_ph_data_ind(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,</span><br><span style="color: hsl(120, 100%, 40%);">+int _sched_compose_ph_data_ind(struct l1sched_ts *l1ts, uint32_t fn,</span><br><span>                               enum trx_chan_type chan, uint8_t *l2,</span><br><span>                                uint8_t l2_len, float rssi,</span><br><span>                          int16_t ta_offs_256bits, int16_t link_qual_cb,</span><br><span>                               uint16_t ber10k,</span><br><span>                             enum osmo_ph_pres_info_type presence_info);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int _sched_compose_tch_ind(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,</span><br><span style="color: hsl(120, 100%, 40%);">+int _sched_compose_tch_ind(struct l1sched_ts *l1ts, uint32_t fn,</span><br><span>                            enum trx_chan_type chan, uint8_t *tch, uint8_t tch_len,</span><br><span>                      int16_t ta_offs_256bits, uint16_t ber10k, float rssi,</span><br><span>                        uint8_t is_sub);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int tx_idle_fn(struct l1sched_trx *l1t, struct trx_dl_burst_req *br);</span><br><span style="color: hsl(0, 100%, 40%);">-int tx_fcch_fn(struct l1sched_trx *l1t, struct trx_dl_burst_req *br);</span><br><span style="color: hsl(0, 100%, 40%);">-int tx_sch_fn(struct l1sched_trx *l1t, struct trx_dl_burst_req *br);</span><br><span style="color: hsl(0, 100%, 40%);">-int tx_data_fn(struct l1sched_trx *l1t, struct trx_dl_burst_req *br);</span><br><span style="color: hsl(0, 100%, 40%);">-int tx_pdtch_fn(struct l1sched_trx *l1t, struct trx_dl_burst_req *br);</span><br><span style="color: hsl(0, 100%, 40%);">-int tx_tchf_fn(struct l1sched_trx *l1t, struct trx_dl_burst_req *br);</span><br><span style="color: hsl(0, 100%, 40%);">-int tx_tchh_fn(struct l1sched_trx *l1t, struct trx_dl_burst_req *br);</span><br><span style="color: hsl(120, 100%, 40%);">+int tx_idle_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);</span><br><span style="color: hsl(120, 100%, 40%);">+int tx_fcch_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);</span><br><span style="color: hsl(120, 100%, 40%);">+int tx_sch_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);</span><br><span style="color: hsl(120, 100%, 40%);">+int tx_data_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);</span><br><span style="color: hsl(120, 100%, 40%);">+int tx_pdtch_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);</span><br><span style="color: hsl(120, 100%, 40%);">+int tx_tchf_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);</span><br><span style="color: hsl(120, 100%, 40%);">+int tx_tchh_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int rx_rach_fn(struct l1sched_trx *l1t, const struct trx_ul_burst_ind *bi);</span><br><span style="color: hsl(0, 100%, 40%);">-int rx_data_fn(struct l1sched_trx *l1t, const struct trx_ul_burst_ind *bi);</span><br><span style="color: hsl(0, 100%, 40%);">-int rx_pdtch_fn(struct l1sched_trx *l1t, const struct trx_ul_burst_ind *bi);</span><br><span style="color: hsl(0, 100%, 40%);">-int rx_tchf_fn(struct l1sched_trx *l1t, const struct trx_ul_burst_ind *bi);</span><br><span style="color: hsl(0, 100%, 40%);">-int rx_tchh_fn(struct l1sched_trx *l1t, const struct trx_ul_burst_ind *bi);</span><br><span style="color: hsl(120, 100%, 40%);">+int rx_rach_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi);</span><br><span style="color: hsl(120, 100%, 40%);">+int rx_data_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi);</span><br><span style="color: hsl(120, 100%, 40%);">+int rx_pdtch_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi);</span><br><span style="color: hsl(120, 100%, 40%);">+int rx_tchf_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi);</span><br><span style="color: hsl(120, 100%, 40%);">+int rx_tchh_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void _sched_dl_burst(struct l1sched_trx *l1t, struct trx_dl_burst_req *br);</span><br><span style="color: hsl(0, 100%, 40%);">-int _sched_rts(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn);</span><br><span style="color: hsl(0, 100%, 40%);">-void _sched_act_rach_det(struct l1sched_trx *l1t, uint8_t tn, uint8_t ss, int activate);</span><br><span style="color: hsl(120, 100%, 40%);">+void _sched_dl_burst(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);</span><br><span style="color: hsl(120, 100%, 40%);">+int _sched_rts(const struct l1sched_ts *l1ts, uint32_t fn);</span><br><span style="color: hsl(120, 100%, 40%);">+void _sched_act_rach_det(struct gsm_bts_trx *trx, uint8_t tn, uint8_t ss, int activate);</span><br><span>diff --git a/src/common/scheduler.c b/src/common/scheduler.c</span><br><span>index 87a1f60..3e7ae58 100644</span><br><span>--- a/src/common/scheduler.c</span><br><span>+++ b/src/common/scheduler.c</span><br><span>@@ -3,6 +3,7 @@</span><br><span> /* (C) 2013 by Andreas Eversberg <jolly@eversberg.eu></span><br><span>  * (C) 2015 by Alexander Chemeris <Alexander.Chemeris@fairwaves.co></span><br><span>  * (C) 2015 by Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(120, 100%, 40%);">+ * Contributions by sysmocom - s.f.m.c. GmbH</span><br><span>  *</span><br><span>  * All Rights Reserved</span><br><span>  *</span><br><span>@@ -46,12 +47,9 @@</span><br><span> </span><br><span> extern void *tall_bts_ctx;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int rts_data_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,</span><br><span style="color: hsl(0, 100%, 40%);">-     enum trx_chan_type chan);</span><br><span style="color: hsl(0, 100%, 40%);">-static int rts_tchf_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,</span><br><span style="color: hsl(0, 100%, 40%);">-       enum trx_chan_type chan);</span><br><span style="color: hsl(0, 100%, 40%);">-static int rts_tchh_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,</span><br><span style="color: hsl(0, 100%, 40%);">-       enum trx_chan_type chan);</span><br><span style="color: hsl(120, 100%, 40%);">+static int rts_data_fn(const struct l1sched_ts *l1ts, const struct trx_dl_burst_req *br);</span><br><span style="color: hsl(120, 100%, 40%);">+static int rts_tchf_fn(const struct l1sched_ts *l1ts, const struct trx_dl_burst_req *br);</span><br><span style="color: hsl(120, 100%, 40%);">+static int rts_tchh_fn(const struct l1sched_ts *l1ts, const struct trx_dl_burst_req *br);</span><br><span> </span><br><span> /*! \brief Dummy Burst (TS 05.02 Chapter 5.2.6) */</span><br><span> const ubit_t _sched_dummy_burst[GSM_BURST_LEN] = {</span><br><span>@@ -576,20 +574,20 @@</span><br><span>  * init / exit</span><br><span>  */</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int trx_sched_init(struct l1sched_trx *l1t, struct gsm_bts_trx *trx)</span><br><span style="color: hsl(120, 100%, 40%);">+void trx_sched_init(struct gsm_bts_trx *trx)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  uint8_t tn;</span><br><span style="color: hsl(0, 100%, 40%);">-     unsigned int i;</span><br><span style="color: hsl(120, 100%, 40%);">+       unsigned int tn, i;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (!trx)</span><br><span style="color: hsl(0, 100%, 40%);">-               return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       LOGPTRX(trx, DL1C, LOGL_DEBUG, "Init scheduler structures\n");</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    l1t->trx = trx;</span><br><span style="color: hsl(120, 100%, 40%);">+    for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) {</span><br><span style="color: hsl(120, 100%, 40%);">+          struct l1sched_ts *l1ts;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    LOGP(DL1C, LOGL_NOTICE, "Init scheduler for trx=%u\n", l1t->trx->nr);</span><br><span style="color: hsl(120, 100%, 40%);">+         l1ts = talloc_zero(trx, struct l1sched_ts);</span><br><span style="color: hsl(120, 100%, 40%);">+           OSMO_ASSERT(l1ts != NULL);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  for (tn = 0; tn < ARRAY_SIZE(l1t->ts); tn++) {</span><br><span style="color: hsl(0, 100%, 40%);">-            struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, tn);</span><br><span style="color: hsl(120, 100%, 40%);">+                trx->ts[tn].impl = l1ts;</span><br><span style="color: hsl(120, 100%, 40%);">+           l1ts->ts = &trx->ts[tn];</span><br><span> </span><br><span>               l1ts->mf_index = 0;</span><br><span>               l1ts->ctrs = rate_ctr_group_alloc(trx, &l1sched_ts_ctrg_desc, (trx->nr + 1) * 10 + tn);</span><br><span>@@ -601,20 +599,18 @@</span><br><span>                    chan_state->active = false;</span><br><span>               }</span><br><span>    }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void trx_sched_exit(struct l1sched_trx *l1t)</span><br><span style="color: hsl(120, 100%, 40%);">+void trx_sched_clean(struct gsm_bts_trx *trx)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      struct gsm_bts_trx_ts *ts;</span><br><span style="color: hsl(0, 100%, 40%);">-      uint8_t tn;</span><br><span style="color: hsl(0, 100%, 40%);">-     int i;</span><br><span style="color: hsl(120, 100%, 40%);">+        unsigned int tn, i;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DL1C, LOGL_NOTICE, "Exit scheduler for trx=%u\n", l1t->trx->nr);</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPTRX(trx, DL1C, LOGL_DEBUG, "Clean scheduler structures\n");</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   for (tn = 0; tn < ARRAY_SIZE(l1t->ts); tn++) {</span><br><span style="color: hsl(0, 100%, 40%);">-            struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, tn);</span><br><span style="color: hsl(120, 100%, 40%);">+        for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) {</span><br><span style="color: hsl(120, 100%, 40%);">+          struct gsm_bts_trx_ts *ts = &trx->ts[tn];</span><br><span style="color: hsl(120, 100%, 40%);">+              struct l1sched_ts *l1ts = ts->impl;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>             msgb_queue_flush(&l1ts->dl_prims);</span><br><span>            rate_ctr_group_free(l1ts->ctrs);</span><br><span>          l1ts->ctrs = NULL;</span><br><span>@@ -631,19 +627,16 @@</span><br><span>                        }</span><br><span>            }</span><br><span>            /* clear lchan channel states */</span><br><span style="color: hsl(0, 100%, 40%);">-                ts = &l1t->trx->ts[tn];</span><br><span>            for (i = 0; i < ARRAY_SIZE(ts->lchan); i++)</span><br><span>                    lchan_set_state(&ts->lchan[i], LCHAN_S_NONE);</span><br><span>         }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct msgb *_sched_dequeue_prim(struct l1sched_trx *l1t,</span><br><span style="color: hsl(0, 100%, 40%);">-                              const struct trx_dl_burst_req *br)</span><br><span style="color: hsl(120, 100%, 40%);">+struct msgb *_sched_dequeue_prim(struct l1sched_ts *l1ts, const struct trx_dl_burst_req *br)</span><br><span> {</span><br><span>       struct msgb *msg, *msg2;</span><br><span>     uint32_t prim_fn, l1sap_fn;</span><br><span>  uint8_t chan_nr, link_id;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, br->tn);</span><br><span> </span><br><span>    /* get prim of current fn from queue */</span><br><span>      llist_for_each_entry_safe(msg, msg2, &l1ts->dl_prims, list) {</span><br><span>@@ -660,17 +653,17 @@</span><br><span>                         l1sap_fn = l1sap->u.tch.fn;</span><br><span>                       break;</span><br><span>               default:</span><br><span style="color: hsl(0, 100%, 40%);">-                        LOGL1SB(DL1P, LOGL_ERROR, l1t, br, "Prim has wrong type.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                       LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, "Prim has wrong type.\n");</span><br><span>                     goto free_msg;</span><br><span>               }</span><br><span>            prim_fn = GSM_TDMA_FN_SUB(l1sap_fn, br->fn);</span><br><span>              if (prim_fn > 100) { /* l1sap_fn < fn */</span><br><span style="color: hsl(0, 100%, 40%);">-                  LOGL1SB(DL1P, LOGL_NOTICE, l1t, br,</span><br><span style="color: hsl(120, 100%, 40%);">+                   LOGL1SB(DL1P, LOGL_NOTICE, l1ts, br,</span><br><span>                              "Prim %u is out of range (%u vs exp %u), or channel %s with "</span><br><span>                              "type %s is already disabled. If this happens in "</span><br><span>                         "conjunction with PCU, increase 'rts-advance' by 5.\n",</span><br><span>                            prim_fn, l1sap_fn, br->fn,</span><br><span style="color: hsl(0, 100%, 40%);">-                           get_lchan_by_chan_nr(l1t->trx, chan_nr)->name,</span><br><span style="color: hsl(120, 100%, 40%);">+                          get_lchan_by_chan_nr(l1ts->ts->trx, chan_nr)->name,</span><br><span>                         trx_chan_desc[br->chan].name);</span><br><span>                       rate_ctr_inc2(l1ts->ctrs, L1SCHED_TS_CTR_DL_LATE);</span><br><span>                        /* unlink and free message */</span><br><span>@@ -684,7 +677,7 @@</span><br><span>          /* l1sap_fn == fn */</span><br><span>                 if ((chan_nr ^ (trx_chan_desc[br->chan].chan_nr | br->tn))</span><br><span>              || ((link_id & 0xc0) ^ trx_chan_desc[br->chan].link_id)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                      LOGL1SB(DL1P, LOGL_ERROR, l1t, br, "Prim has wrong chan_nr=0x%02x link_id=%02x, "</span><br><span style="color: hsl(120, 100%, 40%);">+                   LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, "Prim has wrong chan_nr=0x%02x link_id=%02x, "</span><br><span>                                 "expecting chan_nr=0x%02x link_id=%02x.\n", chan_nr, link_id,</span><br><span>                              trx_chan_desc[br->chan].chan_nr | br->tn, trx_chan_desc[br->chan].link_id);</span><br><span>                         goto free_msg;</span><br><span>@@ -706,7 +699,7 @@</span><br><span>         return NULL;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int _sched_compose_ph_data_ind(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,</span><br><span style="color: hsl(120, 100%, 40%);">+int _sched_compose_ph_data_ind(struct l1sched_ts *l1ts, uint32_t fn,</span><br><span>                         enum trx_chan_type chan, uint8_t *l2,</span><br><span>                                uint8_t l2_len, float rssi,</span><br><span>                          int16_t ta_offs_256bits, int16_t link_qual_cb,</span><br><span>@@ -715,8 +708,7 @@</span><br><span> {</span><br><span>     struct msgb *msg;</span><br><span>    struct osmo_phsap_prim *l1sap;</span><br><span style="color: hsl(0, 100%, 40%);">-  uint8_t chan_nr = trx_chan_desc[chan].chan_nr | tn;</span><br><span style="color: hsl(0, 100%, 40%);">-     struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, tn);</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t chan_nr = trx_chan_desc[chan].chan_nr | l1ts->ts->nr;</span><br><span> </span><br><span>      /* compose primitive */</span><br><span>      msg = l1sap_msgb_alloc(l2_len);</span><br><span>@@ -739,22 +731,20 @@</span><br><span>              l1ts->chan_state[chan].lost_frames = 0;</span><br><span> </span><br><span>       /* forward primitive */</span><br><span style="color: hsl(0, 100%, 40%);">- l1sap_up(l1t->trx, l1sap);</span><br><span style="color: hsl(120, 100%, 40%);">+ l1sap_up(l1ts->ts->trx, l1sap);</span><br><span> </span><br><span>    return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int _sched_compose_tch_ind(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,</span><br><span style="color: hsl(120, 100%, 40%);">+int _sched_compose_tch_ind(struct l1sched_ts *l1ts, uint32_t fn,</span><br><span>                        enum trx_chan_type chan, uint8_t *tch, uint8_t tch_len,</span><br><span>                      int16_t ta_offs_256bits, uint16_t ber10k, float rssi,</span><br><span>                        uint8_t is_sub)</span><br><span> {</span><br><span>      struct msgb *msg;</span><br><span>    struct osmo_phsap_prim *l1sap;</span><br><span style="color: hsl(0, 100%, 40%);">-  struct gsm_bts_trx *trx = l1t->trx;</span><br><span style="color: hsl(0, 100%, 40%);">-  struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, tn);</span><br><span style="color: hsl(0, 100%, 40%);">-  uint8_t chan_nr = trx_chan_desc[chan].chan_nr | tn;</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gsm_lchan *lchan = &trx->ts[L1SAP_CHAN2TS(chan_nr)].lchan[l1sap_chan2ss(chan_nr)];</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t chan_nr = trx_chan_desc[chan].chan_nr | l1ts->ts->nr;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct gsm_lchan *lchan = &l1ts->ts->lchan[l1sap_chan2ss(chan_nr)];</span><br><span> </span><br><span>    /* compose primitive */</span><br><span>      msg = l1sap_msgb_alloc(tch_len);</span><br><span>@@ -775,11 +765,10 @@</span><br><span>     if (l1ts->chan_state[chan].lost_frames)</span><br><span>           l1ts->chan_state[chan].lost_frames--;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    LOGL1S(DL1P, LOGL_DEBUG, l1t, tn, -1, l1sap->u.data.fn,</span><br><span style="color: hsl(0, 100%, 40%);">-             "%s Rx -> RTP: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+     LOGL1S(DL1P, LOGL_DEBUG, l1ts, chan, l1sap->u.data.fn, "%s Rx -> RTP: %s\n",</span><br><span>                gsm_lchan_name(lchan), osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));</span><br><span>  /* forward primitive */</span><br><span style="color: hsl(0, 100%, 40%);">- l1sap_up(l1t->trx, l1sap);</span><br><span style="color: hsl(120, 100%, 40%);">+ l1sap_up(l1ts->ts->trx, l1sap);</span><br><span> </span><br><span>    return 0;</span><br><span> }</span><br><span>@@ -790,12 +779,12 @@</span><br><span>  * data request (from upper layer)</span><br><span>  */</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int trx_sched_ph_data_req(struct l1sched_trx *l1t, struct osmo_phsap_prim *l1sap)</span><br><span style="color: hsl(120, 100%, 40%);">+int trx_sched_ph_data_req(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        uint8_t tn = l1sap->u.data.chan_nr & 7;</span><br><span style="color: hsl(0, 100%, 40%);">-  struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, tn);</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t tn = L1SAP_CHAN2TS(l1sap->u.data.chan_nr);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct l1sched_ts *l1ts = trx->ts[tn].impl;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      LOGL1S(DL1P, LOGL_DEBUG, l1t, tn, -1, l1sap->u.data.fn,</span><br><span style="color: hsl(120, 100%, 40%);">+    LOGL1S(DL1P, LOGL_DEBUG, l1ts, -1, l1sap->u.data.fn,</span><br><span>              "PH-DATA.req: chan_nr=0x%02x link_id=0x%02x\n",</span><br><span>            l1sap->u.data.chan_nr, l1sap->u.data.link_id);</span><br><span> </span><br><span>@@ -813,13 +802,13 @@</span><br><span>     return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int trx_sched_tch_req(struct l1sched_trx *l1t, struct osmo_phsap_prim *l1sap)</span><br><span style="color: hsl(120, 100%, 40%);">+int trx_sched_tch_req(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-     uint8_t tn = l1sap->u.tch.chan_nr & 7;</span><br><span style="color: hsl(0, 100%, 40%);">-   struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, tn);</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t tn = L1SAP_CHAN2TS(l1sap->u.data.chan_nr);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct l1sched_ts *l1ts = trx->ts[tn].impl;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      LOGL1S(DL1P, LOGL_DEBUG, l1t, tn, -1, l1sap->u.tch.fn, "TCH.req: chan_nr=0x%02x\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                l1sap->u.tch.chan_nr);</span><br><span style="color: hsl(120, 100%, 40%);">+     LOGL1S(DL1P, LOGL_DEBUG, l1ts, -1, l1sap->u.tch.fn,</span><br><span style="color: hsl(120, 100%, 40%);">+               "TCH.req: chan_nr=0x%02x\n", l1sap->u.tch.chan_nr);</span><br><span> </span><br><span>  OSMO_ASSERT(l1sap->oph.operation == PRIM_OP_REQUEST);</span><br><span>     OSMO_ASSERT(l1sap->oph.msg);</span><br><span>@@ -841,31 +830,28 @@</span><br><span>  */</span><br><span> </span><br><span> /* RTS for data frame */</span><br><span style="color: hsl(0, 100%, 40%);">-static int rts_data_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,</span><br><span style="color: hsl(0, 100%, 40%);">-  enum trx_chan_type chan)</span><br><span style="color: hsl(120, 100%, 40%);">+static int rts_data_fn(const struct l1sched_ts *l1ts, const struct trx_dl_burst_req *br)</span><br><span> {</span><br><span>      uint8_t chan_nr, link_id;</span><br><span>    struct msgb *msg;</span><br><span>    struct osmo_phsap_prim *l1sap;</span><br><span> </span><br><span>   /* get data for RTS indication */</span><br><span style="color: hsl(0, 100%, 40%);">-       chan_nr = trx_chan_desc[chan].chan_nr | tn;</span><br><span style="color: hsl(0, 100%, 40%);">-     link_id = trx_chan_desc[chan].link_id;</span><br><span style="color: hsl(120, 100%, 40%);">+        chan_nr = trx_chan_desc[br->chan].chan_nr | br->tn;</span><br><span style="color: hsl(120, 100%, 40%);">+     link_id = trx_chan_desc[br->chan].link_id;</span><br><span> </span><br><span>    if (!chan_nr) {</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGL1S(DL1P, LOGL_FATAL, l1t, tn, chan, fn,</span><br><span style="color: hsl(0, 100%, 40%);">-                     "RTS func with non-existing chan_nr %d\n", chan_nr);</span><br><span style="color: hsl(120, 100%, 40%);">+                LOGL1SB(DL1P, LOGL_FATAL, l1ts, br, "RTS func with non-existing chan_nr 0x%02x\n", chan_nr);</span><br><span>               return -ENODEV;</span><br><span>      }</span><br><span> </span><br><span>        /* For handover detection, there are cases where the SACCH should remain inactive until the first RACH</span><br><span>        * indicating the TA is received. */</span><br><span>         if (L1SAP_IS_LINK_SACCH(link_id)</span><br><span style="color: hsl(0, 100%, 40%);">-            && !l1t->ts[tn].chan_state[chan].lchan->want_dl_sacch_active)</span><br><span style="color: hsl(120, 100%, 40%);">+           && !l1ts->chan_state[br->chan].lchan->want_dl_sacch_active)</span><br><span>             return 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   LOGL1S(DL1P, LOGL_DEBUG, l1t, tn, chan, fn,</span><br><span style="color: hsl(0, 100%, 40%);">-             "PH-RTS.ind: chan_nr=0x%02x link_id=0x%02x\n", chan_nr, link_id);</span><br><span style="color: hsl(120, 100%, 40%);">+   LOGL1SB(DL1P, LOGL_DEBUG, l1ts, br, "PH-RTS.ind: chan_nr=0x%02x link_id=0x%02x\n", chan_nr, link_id);</span><br><span> </span><br><span>  /* generate prim */</span><br><span>  msg = l1sap_msgb_alloc(200);</span><br><span>@@ -876,31 +862,30 @@</span><br><span>                                         PRIM_OP_INDICATION, msg);</span><br><span>    l1sap->u.data.chan_nr = chan_nr;</span><br><span>  l1sap->u.data.link_id = link_id;</span><br><span style="color: hsl(0, 100%, 40%);">-     l1sap->u.data.fn = fn;</span><br><span style="color: hsl(120, 100%, 40%);">+     l1sap->u.data.fn = br->fn;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    return l1sap_up(l1t->trx, l1sap);</span><br><span style="color: hsl(120, 100%, 40%);">+  return l1sap_up(l1ts->ts->trx, l1sap);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int rts_tch_common(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,</span><br><span style="color: hsl(0, 100%, 40%);">-        enum trx_chan_type chan, int facch)</span><br><span style="color: hsl(120, 100%, 40%);">+static int rts_tch_common(const struct l1sched_ts *l1ts,</span><br><span style="color: hsl(120, 100%, 40%);">+                   const struct trx_dl_burst_req *br,</span><br><span style="color: hsl(120, 100%, 40%);">+                    bool facch)</span><br><span> {</span><br><span>   uint8_t chan_nr, link_id;</span><br><span>    struct msgb *msg;</span><br><span>    struct osmo_phsap_prim *l1sap;</span><br><span style="color: hsl(0, 100%, 40%);">-  struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, tn);</span><br><span>       int rc = 0;</span><br><span> </span><br><span>      /* get data for RTS indication */</span><br><span style="color: hsl(0, 100%, 40%);">-       chan_nr = trx_chan_desc[chan].chan_nr | tn;</span><br><span style="color: hsl(0, 100%, 40%);">-     link_id = trx_chan_desc[chan].link_id;</span><br><span style="color: hsl(120, 100%, 40%);">+        chan_nr = trx_chan_desc[br->chan].chan_nr | br->tn;</span><br><span style="color: hsl(120, 100%, 40%);">+     link_id = trx_chan_desc[br->chan].link_id;</span><br><span> </span><br><span>    if (!chan_nr) {</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGL1S(DL1P, LOGL_FATAL, l1t, tn, chan, fn,</span><br><span style="color: hsl(0, 100%, 40%);">-                     "RTS func with non-existing chan_nr %d\n", chan_nr);</span><br><span style="color: hsl(120, 100%, 40%);">+                LOGL1SB(DL1P, LOGL_FATAL, l1ts, br, "RTS func with non-existing chan_nr 0x%02x\n", chan_nr);</span><br><span>               return -ENODEV;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   LOGL1S(DL1P, LOGL_DEBUG, l1t, tn, chan, fn, "TCH RTS.ind: chan_nr=0x%02x\n", chan_nr);</span><br><span style="color: hsl(120, 100%, 40%);">+      LOGL1SB(DL1P, LOGL_DEBUG, l1ts, br, "TCH RTS.ind: chan_nr=0x%02x\n", chan_nr);</span><br><span> </span><br><span>         /* only send, if FACCH is selected */</span><br><span>        if (facch) {</span><br><span>@@ -913,13 +898,13 @@</span><br><span>                                                 PRIM_OP_INDICATION, msg);</span><br><span>            l1sap->u.data.chan_nr = chan_nr;</span><br><span>          l1sap->u.data.link_id = link_id;</span><br><span style="color: hsl(0, 100%, 40%);">-             l1sap->u.data.fn = fn;</span><br><span style="color: hsl(120, 100%, 40%);">+             l1sap->u.data.fn = br->fn;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-            rc = l1sap_up(l1t->trx, l1sap);</span><br><span style="color: hsl(120, 100%, 40%);">+            rc = l1sap_up(l1ts->ts->trx, l1sap);</span><br><span>   }</span><br><span> </span><br><span>        /* don't send, if TCH is in signalling only mode */</span><br><span style="color: hsl(0, 100%, 40%);">- if (l1ts->chan_state[chan].rsl_cmode != RSL_CMOD_SPD_SIGN) {</span><br><span style="color: hsl(120, 100%, 40%);">+       if (l1ts->chan_state[br->chan].rsl_cmode != RSL_CMOD_SPD_SIGN) {</span><br><span>               /* generate prim */</span><br><span>          msg = l1sap_msgb_alloc(200);</span><br><span>                 if (!msg)</span><br><span>@@ -928,49 +913,44 @@</span><br><span>            osmo_prim_init(&l1sap->oph, SAP_GSM_PH, PRIM_TCH_RTS,</span><br><span>                                                 PRIM_OP_INDICATION, msg);</span><br><span>            l1sap->u.tch.chan_nr = chan_nr;</span><br><span style="color: hsl(0, 100%, 40%);">-              l1sap->u.tch.fn = fn;</span><br><span style="color: hsl(120, 100%, 40%);">+              l1sap->u.tch.fn = br->fn;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-             return l1sap_up(l1t->trx, l1sap);</span><br><span style="color: hsl(120, 100%, 40%);">+          return l1sap_up(l1ts->ts->trx, l1sap);</span><br><span>         }</span><br><span> </span><br><span>        return rc;</span><br><span> }</span><br><span> </span><br><span> /* RTS for full rate traffic frame */</span><br><span style="color: hsl(0, 100%, 40%);">-static int rts_tchf_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,</span><br><span style="color: hsl(0, 100%, 40%);">-    enum trx_chan_type chan)</span><br><span style="color: hsl(120, 100%, 40%);">+static int rts_tchf_fn(const struct l1sched_ts *l1ts, const struct trx_dl_burst_req *br)</span><br><span> {</span><br><span>      /* TCH/F may include FACCH on every 4th burst */</span><br><span style="color: hsl(0, 100%, 40%);">-        return rts_tch_common(l1t, tn, fn, chan, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+  return rts_tch_common(l1ts, br, true);</span><br><span> }</span><br><span> </span><br><span> </span><br><span> /* RTS for half rate traffic frame */</span><br><span style="color: hsl(0, 100%, 40%);">-static int rts_tchh_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,</span><br><span style="color: hsl(0, 100%, 40%);">-    enum trx_chan_type chan)</span><br><span style="color: hsl(120, 100%, 40%);">+static int rts_tchh_fn(const struct l1sched_ts *l1ts, const struct trx_dl_burst_req *br)</span><br><span> {</span><br><span>      /* the FN 4/5, 13/14, 21/22 defines that FACCH may be included. */</span><br><span style="color: hsl(0, 100%, 40%);">-      return rts_tch_common(l1t, tn, fn, chan, ((fn % 26) >> 2) & 1);</span><br><span style="color: hsl(120, 100%, 40%);">+     return rts_tch_common(l1ts, br, ((br->fn % 26) >> 2) & 1);</span><br><span> }</span><br><span> </span><br><span> /* set multiframe scheduler to given pchan */</span><br><span style="color: hsl(0, 100%, 40%);">-int trx_sched_set_pchan(struct l1sched_trx *l1t, uint8_t tn,</span><br><span style="color: hsl(0, 100%, 40%);">-   enum gsm_phys_chan_config pchan)</span><br><span style="color: hsl(120, 100%, 40%);">+int trx_sched_set_pchan(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config pchan)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, tn);</span><br><span style="color: hsl(0, 100%, 40%);">-  int i;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  i = find_sched_mframe_idx(pchan, tn);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct l1sched_ts *l1ts = ts->impl;</span><br><span style="color: hsl(120, 100%, 40%);">+        int i = find_sched_mframe_idx(pchan, ts->nr);</span><br><span>     if (i < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGP(DL1C, LOGL_NOTICE, "Failed to configure multiframe "</span><br><span style="color: hsl(0, 100%, 40%);">-                     "trx=%d ts=%d\n", l1t->trx->nr, tn);</span><br><span style="color: hsl(120, 100%, 40%);">+          LOGP(DL1C, LOGL_NOTICE, "%s Failed to configure multiframe\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                   gsm_ts_name(ts));</span><br><span>               return -ENOTSUP;</span><br><span>     }</span><br><span>    l1ts->mf_index = i;</span><br><span>       l1ts->mf_period = trx_sched_multiframes[i].period;</span><br><span>        l1ts->mf_frames = trx_sched_multiframes[i].frames;</span><br><span style="color: hsl(0, 100%, 40%);">-   LOGP(DL1C, LOGL_NOTICE, "Configuring multiframe with %s trx=%d ts=%d\n",</span><br><span style="color: hsl(0, 100%, 40%);">-              trx_sched_multiframes[i].name, l1t->trx->nr, tn);</span><br><span style="color: hsl(120, 100%, 40%);">+       LOGP(DL1C, LOGL_NOTICE, "%s Configured multiframe with '%s'\n",</span><br><span style="color: hsl(120, 100%, 40%);">+          gsm_ts_name(ts), trx_sched_multiframes[i].name);</span><br><span>        return 0;</span><br><span> }</span><br><span> </span><br><span>@@ -1006,10 +986,10 @@</span><br><span> }</span><br><span> </span><br><span> /* setting all logical channels given attributes to active/inactive */</span><br><span style="color: hsl(0, 100%, 40%);">-int trx_sched_set_lchan(struct l1sched_trx *l1t, uint8_t chan_nr, uint8_t link_id, bool active)</span><br><span style="color: hsl(120, 100%, 40%);">+int trx_sched_set_lchan(struct gsm_lchan *lchan, uint8_t chan_nr, uint8_t link_id, bool active)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+   struct l1sched_ts *l1ts = lchan->ts->impl;</span><br><span>     uint8_t tn = L1SAP_CHAN2TS(chan_nr);</span><br><span style="color: hsl(0, 100%, 40%);">-    struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, tn);</span><br><span>       uint8_t ss = l1sap_chan2ss(chan_nr);</span><br><span>         bool found = false;</span><br><span>  int i;</span><br><span>@@ -1026,9 +1006,9 @@</span><br><span>                       continue;</span><br><span>            found = true;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-               LOGP(DL1C, LOGL_NOTICE, "%s %s on trx=%d ts=%d\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                    (active) ? "Activating" : "Deactivating",</span><br><span style="color: hsl(0, 100%, 40%);">-                   trx_chan_desc[i].name, l1t->trx->nr, tn);</span><br><span style="color: hsl(120, 100%, 40%);">+               LOGPLCHAN(lchan, DL1C, LOGL_NOTICE, "%s %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                        (active) ? "Activating" : "Deactivating",</span><br><span style="color: hsl(120, 100%, 40%);">+                         trx_chan_desc[i].name);</span><br><span>            /* free burst memory, to cleanly start with burst 0 */</span><br><span>               if (chan_state->dl_bursts) {</span><br><span>                      talloc_free(chan_state->dl_bursts);</span><br><span>@@ -1044,8 +1024,7 @@</span><br><span>                       memset(chan_state, 0, sizeof(*chan_state));</span><br><span> </span><br><span>                      /* Bind to generic 'struct gsm_lchan' */</span><br><span style="color: hsl(0, 100%, 40%);">-                        chan_state->lchan = get_lchan_by_chan_nr(l1t->trx, chan_nr);</span><br><span style="color: hsl(0, 100%, 40%);">-                      OSMO_ASSERT(chan_state->lchan != NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+                    chan_state->lchan = lchan;</span><br><span>                } else {</span><br><span>                     chan_state->ho_rach_detect = 0;</span><br><span> </span><br><span>@@ -1058,36 +1037,37 @@</span><br><span> </span><br><span>         /* disable handover detection (on deactivation) */</span><br><span>   if (!active)</span><br><span style="color: hsl(0, 100%, 40%);">-            _sched_act_rach_det(l1t, tn, ss, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+          _sched_act_rach_det(lchan->ts->trx, tn, ss, 0);</span><br><span> </span><br><span>    return found ? 0 : -EINVAL;</span><br><span> }</span><br><span> </span><br><span> /* setting all logical channels given attributes to active/inactive */</span><br><span style="color: hsl(0, 100%, 40%);">-int trx_sched_set_mode(struct l1sched_trx *l1t, uint8_t chan_nr, uint8_t rsl_cmode,</span><br><span style="color: hsl(120, 100%, 40%);">+int trx_sched_set_mode(struct gsm_bts_trx_ts *ts, uint8_t chan_nr, uint8_t rsl_cmode,</span><br><span>     uint8_t tch_mode, int codecs, uint8_t codec0, uint8_t codec1,</span><br><span>        uint8_t codec2, uint8_t codec3, uint8_t initial_id, uint8_t handover)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+    struct l1sched_ts *l1ts = ts->impl;</span><br><span>       uint8_t tn = L1SAP_CHAN2TS(chan_nr);</span><br><span style="color: hsl(0, 100%, 40%);">-    struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, tn);</span><br><span>       uint8_t ss = l1sap_chan2ss(chan_nr);</span><br><span>         int i;</span><br><span>       int rc = -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct l1sched_chan_state *chan_state;</span><br><span> </span><br><span>   /* no mode for PDCH */</span><br><span style="color: hsl(0, 100%, 40%);">-  if (trx_sched_multiframes[l1ts->mf_index].pchan == GSM_PCHAN_PDCH)</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ts->pchan == GSM_PCHAN_PDCH)</span><br><span>          return 0;</span><br><span> </span><br><span>        /* look for all matching chan_nr/link_id */</span><br><span>  for (i = 0; i < _TRX_CHAN_MAX; i++) {</span><br><span>             if (trx_chan_desc[i].chan_nr == (chan_nr & 0xf8)</span><br><span>                  && trx_chan_desc[i].link_id == 0x00) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 chan_state = &l1ts->chan_state[i];</span><br><span style="color: hsl(0, 100%, 40%);">-                       LOGP(DL1C, LOGL_NOTICE, "Set mode %u, %u, handover %u "</span><br><span style="color: hsl(0, 100%, 40%);">-                               "on %s of trx=%d ts=%d\n", rsl_cmode, tch_mode,</span><br><span style="color: hsl(0, 100%, 40%);">-                               handover, trx_chan_desc[i].name, l1t->trx->nr,</span><br><span style="color: hsl(0, 100%, 40%);">-                            tn);</span><br><span style="color: hsl(120, 100%, 40%);">+                  struct l1sched_chan_state *chan_state = &l1ts->chan_state[i];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                        LOGP(DL1C, LOGL_NOTICE,</span><br><span style="color: hsl(120, 100%, 40%);">+                            "%s Set mode for %s (rsl_cmode=%u, tch_mode=%u, handover=%u)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                            gsm_ts_name(ts), trx_chan_desc[i].name,</span><br><span style="color: hsl(120, 100%, 40%);">+                       rsl_cmode, tch_mode, handover);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>                       chan_state->rsl_cmode = rsl_cmode;</span><br><span>                        chan_state->tch_mode = tch_mode;</span><br><span>                  chan_state->ho_rach_detect = handover;</span><br><span>@@ -1114,50 +1094,49 @@</span><br><span>   * of transceiver link).</span><br><span>      * disable handover, if state is still set, since we might not know</span><br><span>   * the actual state of transceiver (due to loss of link) */</span><br><span style="color: hsl(0, 100%, 40%);">-     _sched_act_rach_det(l1t, tn, ss, handover);</span><br><span style="color: hsl(120, 100%, 40%);">+   _sched_act_rach_det(ts->trx, tn, ss, handover);</span><br><span> </span><br><span>       return rc;</span><br><span> }</span><br><span> </span><br><span> /* setting cipher on logical channels */</span><br><span style="color: hsl(0, 100%, 40%);">-int trx_sched_set_cipher(struct l1sched_trx *l1t, uint8_t chan_nr, int downlink,</span><br><span style="color: hsl(0, 100%, 40%);">- int algo, uint8_t *key, int key_len)</span><br><span style="color: hsl(120, 100%, 40%);">+int trx_sched_set_cipher(struct gsm_lchan *lchan, uint8_t chan_nr, bool downlink)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-    uint8_t tn = L1SAP_CHAN2TS(chan_nr);</span><br><span style="color: hsl(0, 100%, 40%);">-    struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, tn);</span><br><span style="color: hsl(0, 100%, 40%);">-  int i;</span><br><span style="color: hsl(0, 100%, 40%);">-  int rc = -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct l1sched_chan_state *chan_state;</span><br><span style="color: hsl(120, 100%, 40%);">+        int algo = lchan->encr.alg_id - 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ int i, rc = -EINVAL;</span><br><span> </span><br><span>     /* no cipher for PDCH */</span><br><span style="color: hsl(0, 100%, 40%);">-        if (trx_sched_multiframes[l1ts->mf_index].pchan == GSM_PCHAN_PDCH)</span><br><span style="color: hsl(120, 100%, 40%);">+ if (lchan->ts->pchan == GSM_PCHAN_PDCH)</span><br><span>                return 0;</span><br><span> </span><br><span>        /* no algorithm given means a5/0 */</span><br><span>  if (algo <= 0)</span><br><span>            algo = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       else if (key_len != 8) {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DL1C, LOGL_ERROR, "Algo A5/%d not supported with given "</span><br><span style="color: hsl(0, 100%, 40%);">-                 "key len=%d\n", algo, key_len);</span><br><span style="color: hsl(120, 100%, 40%);">+     else if (lchan->encr.key_len != 8) {</span><br><span style="color: hsl(120, 100%, 40%);">+               LOGPLCHAN(lchan, DL1C, LOGL_ERROR,</span><br><span style="color: hsl(120, 100%, 40%);">+                      "Algo A5/%d not supported with given key_len=%u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                         algo, lchan->encr.key_len);</span><br><span>             return -ENOTSUP;</span><br><span>     }</span><br><span> </span><br><span>        /* look for all matching chan_nr */</span><br><span>  for (i = 0; i < _TRX_CHAN_MAX; i++) {</span><br><span>             if (trx_chan_desc[i].chan_nr == (chan_nr & RSL_CHAN_NR_MASK)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                     chan_state = &l1ts->chan_state[i];</span><br><span style="color: hsl(0, 100%, 40%);">-                       LOGP(DL1C, LOGL_NOTICE, "Set a5/%d %s for %s on trx=%d "</span><br><span style="color: hsl(0, 100%, 40%);">-                              "ts=%d\n", algo,</span><br><span style="color: hsl(0, 100%, 40%);">-                              (downlink) ? "downlink" : "uplink",</span><br><span style="color: hsl(0, 100%, 40%);">-                         trx_chan_desc[i].name, l1t->trx->nr, tn);</span><br><span style="color: hsl(120, 100%, 40%);">+                       struct l1sched_ts *l1ts = lchan->ts->impl;</span><br><span style="color: hsl(120, 100%, 40%);">+                      struct l1sched_chan_state *l1cs = &l1ts->chan_state[i];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                      LOGPLCHAN(lchan, DL1C, LOGL_NOTICE, "Set A5/%d %s for %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                  algo, (downlink) ? "downlink" : "uplink",</span><br><span style="color: hsl(120, 100%, 40%);">+                                 trx_chan_desc[i].name);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>                  if (downlink) {</span><br><span style="color: hsl(0, 100%, 40%);">-                         chan_state->dl_encr_algo = algo;</span><br><span style="color: hsl(0, 100%, 40%);">-                             memcpy(chan_state->dl_encr_key, key, key_len);</span><br><span style="color: hsl(0, 100%, 40%);">-                               chan_state->dl_encr_key_len = key_len;</span><br><span style="color: hsl(120, 100%, 40%);">+                             l1cs->dl_encr_algo = algo;</span><br><span style="color: hsl(120, 100%, 40%);">+                         memcpy(l1cs->dl_encr_key, lchan->encr.key, lchan->encr.key_len);</span><br><span style="color: hsl(120, 100%, 40%);">+                             l1cs->dl_encr_key_len = lchan->encr.key_len;</span><br><span>                   } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                                chan_state->ul_encr_algo = algo;</span><br><span style="color: hsl(0, 100%, 40%);">-                             memcpy(chan_state->ul_encr_key, key, key_len);</span><br><span style="color: hsl(0, 100%, 40%);">-                               chan_state->ul_encr_key_len = key_len;</span><br><span style="color: hsl(120, 100%, 40%);">+                             l1cs->ul_encr_algo = algo;</span><br><span style="color: hsl(120, 100%, 40%);">+                         memcpy(l1cs->ul_encr_key, lchan->encr.key, lchan->encr.key_len);</span><br><span style="color: hsl(120, 100%, 40%);">+                             l1cs->ul_encr_key_len = lchan->encr.key_len;</span><br><span>                   }</span><br><span>                    rc = 0;</span><br><span>              }</span><br><span>@@ -1167,9 +1146,8 @@</span><br><span> }</span><br><span> </span><br><span> /* process ready-to-send */</span><br><span style="color: hsl(0, 100%, 40%);">-int _sched_rts(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn)</span><br><span style="color: hsl(120, 100%, 40%);">+int _sched_rts(const struct l1sched_ts *l1ts, uint32_t fn)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, tn);</span><br><span>       const struct trx_sched_frame *frame;</span><br><span>         uint8_t offset, period, bid;</span><br><span>         trx_sched_rts_func *func;</span><br><span>@@ -1200,14 +1178,21 @@</span><br><span>  if (!TRX_CHAN_IS_ACTIVE(&l1ts->chan_state[chan], chan))</span><br><span>               return -EINVAL;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     return func(l1t, tn, fn, frame->dl_chan);</span><br><span style="color: hsl(120, 100%, 40%);">+  /* There is no burst, just for logging */</span><br><span style="color: hsl(120, 100%, 40%);">+     struct trx_dl_burst_req dbr = {</span><br><span style="color: hsl(120, 100%, 40%);">+               .fn = fn,</span><br><span style="color: hsl(120, 100%, 40%);">+             .tn = l1ts->ts->nr,</span><br><span style="color: hsl(120, 100%, 40%);">+             .bid = bid,</span><br><span style="color: hsl(120, 100%, 40%);">+           .chan = chan,</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return func(l1ts, &dbr);</span><br><span> }</span><br><span> </span><br><span> /* process downlink burst */</span><br><span style="color: hsl(0, 100%, 40%);">-void _sched_dl_burst(struct l1sched_trx *l1t, struct trx_dl_burst_req *br)</span><br><span style="color: hsl(120, 100%, 40%);">+void _sched_dl_burst(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, br->tn);</span><br><span style="color: hsl(0, 100%, 40%);">-   struct l1sched_chan_state *l1cs;</span><br><span style="color: hsl(120, 100%, 40%);">+      const struct l1sched_chan_state *l1cs;</span><br><span>       const struct trx_sched_frame *frame;</span><br><span>         uint8_t offset, period;</span><br><span>      trx_sched_dl_func *func;</span><br><span>@@ -1231,7 +1216,7 @@</span><br><span>             return;</span><br><span> </span><br><span>  /* get burst from function */</span><br><span style="color: hsl(0, 100%, 40%);">-   if (func(l1t, br) != 0)</span><br><span style="color: hsl(120, 100%, 40%);">+       if (func(l1ts, br) != 0)</span><br><span>             return;</span><br><span> </span><br><span>  /* BS Power reduction (in dB) per logical channel */</span><br><span>@@ -1251,12 +1236,11 @@</span><br><span>       }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int trx_sched_calc_frame_loss(struct l1sched_trx *l1t,</span><br><span style="color: hsl(120, 100%, 40%);">+static int trx_sched_calc_frame_loss(struct l1sched_ts *l1ts,</span><br><span>                                    struct l1sched_chan_state *l1cs,</span><br><span>                                     const struct trx_ul_burst_ind *bi)</span><br><span> {</span><br><span>         const struct trx_sched_frame *frame;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct l1sched_ts *l1ts;</span><br><span>     uint32_t elapsed_fs;</span><br><span>         uint8_t offset, i;</span><br><span>   uint32_t fn_i;</span><br><span>@@ -1269,9 +1253,6 @@</span><br><span>       if (l1cs->proc_tdma_fs == 0)</span><br><span>              return 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /* Get current TDMA frame info */</span><br><span style="color: hsl(0, 100%, 40%);">-       l1ts = l1sched_trx_get_ts(l1t, bi->tn);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>   /* Not applicable for some logical channels */</span><br><span>       switch (bi->chan) {</span><br><span>       case TRXC_IDLE:</span><br><span>@@ -1288,7 +1269,7 @@</span><br><span>      /* How many frames elapsed since the last one? */</span><br><span>    elapsed_fs = GSM_TDMA_FN_SUB(bi->fn, l1cs->last_tdma_fn);</span><br><span>      if (elapsed_fs > l1ts->mf_period) { /* Too many! */</span><br><span style="color: hsl(0, 100%, 40%);">-               LOGL1SB(DL1P, LOGL_ERROR, l1t, bi,</span><br><span style="color: hsl(120, 100%, 40%);">+            LOGL1SB(DL1P, LOGL_ERROR, l1ts, bi,</span><br><span>                  "Too many (>%u) contiguous TDMA frames=%u elapsed "</span><br><span>                     "since the last processed fn=%u\n", l1ts->mf_period,</span><br><span>                    elapsed_fs, l1cs->last_tdma_fn);</span><br><span>@@ -1314,7 +1295,7 @@</span><br><span>  }</span><br><span> </span><br><span>        if (l1cs->lost_tdma_fs > 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-             LOGL1SB(DL1P, LOGL_NOTICE, l1t, bi,</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGL1SB(DL1P, LOGL_NOTICE, l1ts, bi,</span><br><span>                         "At least %u TDMA frames were lost since the last "</span><br><span>                        "processed fn=%u\n", l1cs->lost_tdma_fs, l1cs->last_tdma_fn);</span><br><span> </span><br><span>@@ -1350,10 +1331,10 @@</span><br><span>                  dbi.bid = frame->ul_bid;</span><br><span>                  dbi.fn = fn_i;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                      LOGL1SB(DL1P, LOGL_NOTICE, l1t, &dbi,</span><br><span style="color: hsl(120, 100%, 40%);">+                     LOGL1SB(DL1P, LOGL_NOTICE, l1ts, &dbi,</span><br><span>                           "Substituting lost burst with NOPE.ind\n");</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                       func(l1t, &dbi);</span><br><span style="color: hsl(120, 100%, 40%);">+                  func(l1ts, &dbi);</span><br><span> </span><br><span>                    l1cs->lost_tdma_fs--;</span><br><span>             }</span><br><span>@@ -1363,9 +1344,8 @@</span><br><span> }</span><br><span> </span><br><span> /* Process an Uplink burst indication */</span><br><span style="color: hsl(0, 100%, 40%);">-int trx_sched_ul_burst(struct l1sched_trx *l1t, struct trx_ul_burst_ind *bi)</span><br><span style="color: hsl(120, 100%, 40%);">+int trx_sched_ul_burst(struct l1sched_ts *l1ts, struct trx_ul_burst_ind *bi)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, bi->tn);</span><br><span>        struct l1sched_chan_state *l1cs;</span><br><span>     const struct trx_sched_frame *frame;</span><br><span>         uint8_t offset, period;</span><br><span>@@ -1386,7 +1366,7 @@</span><br><span> </span><br><span>  /* TODO: handle noise measurements */</span><br><span>        if (bi->chan == TRXC_IDLE && bi->flags & TRX_BI_F_NOPE_IND) {</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGL1SB(DL1P, LOGL_DEBUG, l1t, bi, "Rx noise measurement (%d)\n", bi->rssi);</span><br><span style="color: hsl(120, 100%, 40%);">+             LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, "Rx noise measurement (%d)\n", bi->rssi);</span><br><span>           return -ENOTSUP;</span><br><span>     }</span><br><span> </span><br><span>@@ -1399,7 +1379,7 @@</span><br><span>                return -EINVAL;</span><br><span> </span><br><span>  /* calculate how many TDMA frames were potentially lost */</span><br><span style="color: hsl(0, 100%, 40%);">-      trx_sched_calc_frame_loss(l1t, l1cs, bi);</span><br><span style="color: hsl(120, 100%, 40%);">+     trx_sched_calc_frame_loss(l1ts, l1cs, bi);</span><br><span> </span><br><span>       /* update TDMA frame counters */</span><br><span>     l1cs->last_tdma_fn = bi->fn;</span><br><span>@@ -1415,7 +1395,7 @@</span><br><span>           default:</span><br><span>                     /* NOTE: Uplink burst handler must check bi->burst_len before</span><br><span>                      * accessing bi->burst to avoid uninitialized memory access. */</span><br><span style="color: hsl(0, 100%, 40%);">-                      return func(l1t, bi);</span><br><span style="color: hsl(120, 100%, 40%);">+                 return func(l1ts, bi);</span><br><span>               }</span><br><span>    }</span><br><span> </span><br><span>@@ -1434,13 +1414,7 @@</span><br><span>       }</span><br><span> </span><br><span>        /* Invoke the logical channel handler */</span><br><span style="color: hsl(0, 100%, 40%);">-        func(l1t, bi);</span><br><span style="color: hsl(120, 100%, 40%);">+        func(l1ts, bi);</span><br><span> </span><br><span>  return 0;</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct l1sched_ts *l1sched_trx_get_ts(struct l1sched_trx *l1t, uint8_t tn)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(tn < ARRAY_SIZE(l1t->ts));</span><br><span style="color: hsl(0, 100%, 40%);">-    return &l1t->ts[tn];</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span>diff --git a/src/osmo-bts-trx/l1_if.c b/src/osmo-bts-trx/l1_if.c</span><br><span>index fc8ef76..3f95a69 100644</span><br><span>--- a/src/osmo-bts-trx/l1_if.c</span><br><span>+++ b/src/osmo-bts-trx/l1_if.c</span><br><span>@@ -109,9 +109,6 @@</span><br><span> </span><br><span> int bts_model_lchan_deactivate(struct gsm_lchan *lchan)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-     struct phy_instance *pinst = trx_phy_instance(lchan->ts->trx);</span><br><span style="color: hsl(0, 100%, 40%);">-    struct trx_l1h *l1h = pinst->u.osmotrx.hdl;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>       if (lchan->rel_act_kind == LCHAN_REL_ACT_REACT) {</span><br><span>                 lchan->rel_act_kind = LCHAN_REL_ACT_RSL;</span><br><span>          /* FIXME: perform whatever is needed (if any) to set proper PCH/AGCH allocation according to</span><br><span>@@ -121,14 +118,12 @@</span><br><span>         /* set lchan inactive */</span><br><span>     lchan_set_state(lchan, LCHAN_S_NONE);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       return trx_sched_set_lchan(&l1h->l1s, gsm_lchan2chan_nr(lchan), LID_DEDIC, false);</span><br><span style="color: hsl(120, 100%, 40%);">+     return trx_sched_set_lchan(lchan, gsm_lchan2chan_nr(lchan), LID_DEDIC, false);</span><br><span> }</span><br><span> </span><br><span> int bts_model_lchan_deactivate_sacch(struct gsm_lchan *lchan)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   struct phy_instance *pinst = trx_phy_instance(lchan->ts->trx);</span><br><span style="color: hsl(0, 100%, 40%);">-    struct trx_l1h *l1h = pinst->u.osmotrx.hdl;</span><br><span style="color: hsl(0, 100%, 40%);">-  return trx_sched_set_lchan(&l1h->l1s, gsm_lchan2chan_nr(lchan), LID_SACCH, false);</span><br><span style="color: hsl(120, 100%, 40%);">+     return trx_sched_set_lchan(lchan, gsm_lchan2chan_nr(lchan), LID_SACCH, false);</span><br><span> }</span><br><span> </span><br><span> int l1if_trx_start_power_ramp(struct gsm_bts_trx *trx, ramp_compl_cb_t ramp_compl_cb)</span><br><span>@@ -293,7 +288,7 @@</span><br><span>        * decided on a more specific PCHAN type already. */</span><br><span>         OSMO_ASSERT(pchan != GSM_PCHAN_TCH_F_PDCH);</span><br><span>  OSMO_ASSERT(pchan != GSM_PCHAN_TCH_F_TCH_H_PDCH);</span><br><span style="color: hsl(0, 100%, 40%);">-       rc = trx_sched_set_pchan(&l1h->l1s, tn, pchan);</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = trx_sched_set_pchan(ts, pchan);</span><br><span>         if (rc)</span><br><span>              return NM_NACK_RES_NOTAVAIL;</span><br><span> </span><br><span>@@ -344,8 +339,7 @@</span><br><span>  */</span><br><span> </span><br><span> /* enable ciphering */</span><br><span style="color: hsl(0, 100%, 40%);">-static int l1if_set_ciphering(struct trx_l1h *l1h, struct gsm_lchan *lchan,</span><br><span style="color: hsl(0, 100%, 40%);">-  uint8_t chan_nr, int downlink)</span><br><span style="color: hsl(120, 100%, 40%);">+static int l1if_set_ciphering(struct gsm_lchan *lchan, uint8_t chan_nr, int downlink)</span><br><span> {</span><br><span>   /* ciphering already enabled in both directions */</span><br><span>   if (lchan->ciph_state == LCHAN_CIPH_RXTX_CONF)</span><br><span>@@ -353,28 +347,22 @@</span><br><span> </span><br><span>        if (!downlink) {</span><br><span>             /* set uplink */</span><br><span style="color: hsl(0, 100%, 40%);">-                trx_sched_set_cipher(&l1h->l1s, chan_nr, 0, lchan->encr.alg_id - 1,</span><br><span style="color: hsl(0, 100%, 40%);">-                   lchan->encr.key, lchan->encr.key_len);</span><br><span style="color: hsl(120, 100%, 40%);">+          trx_sched_set_cipher(lchan, chan_nr, false);</span><br><span>                 lchan->ciph_state = LCHAN_CIPH_RX_CONF;</span><br><span>   } else {</span><br><span>             /* set downlink and also set uplink, if not already */</span><br><span style="color: hsl(0, 100%, 40%);">-          if (lchan->ciph_state != LCHAN_CIPH_RX_CONF) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       trx_sched_set_cipher(&l1h->l1s, chan_nr, 0,</span><br><span style="color: hsl(0, 100%, 40%);">-                              lchan->encr.alg_id - 1, lchan->encr.key,</span><br><span style="color: hsl(0, 100%, 40%);">-                          lchan->encr.key_len);</span><br><span style="color: hsl(0, 100%, 40%);">-                }</span><br><span style="color: hsl(0, 100%, 40%);">-               trx_sched_set_cipher(&l1h->l1s, chan_nr, 1, lchan->encr.alg_id - 1,</span><br><span style="color: hsl(0, 100%, 40%);">-                   lchan->encr.key, lchan->encr.key_len);</span><br><span style="color: hsl(120, 100%, 40%);">+          if (lchan->ciph_state != LCHAN_CIPH_RX_CONF)</span><br><span style="color: hsl(120, 100%, 40%);">+                       trx_sched_set_cipher(lchan, chan_nr, false);</span><br><span style="color: hsl(120, 100%, 40%);">+          trx_sched_set_cipher(lchan, chan_nr, true);</span><br><span>          lchan->ciph_state = LCHAN_CIPH_RXTX_CONF;</span><br><span>         }</span><br><span> </span><br><span>        return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int mph_info_chan_confirm(struct trx_l1h *l1h, uint8_t chan_nr,</span><br><span style="color: hsl(0, 100%, 40%);">-        enum osmo_mph_info_type type, uint8_t cause)</span><br><span style="color: hsl(120, 100%, 40%);">+static int mph_info_chan_confirm(struct gsm_bts_trx *trx, uint8_t chan_nr,</span><br><span style="color: hsl(120, 100%, 40%);">+                               enum osmo_mph_info_type type, uint8_t cause)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      struct phy_instance *pinst = l1h->phy_inst;</span><br><span>       struct osmo_phsap_prim l1sap;</span><br><span> </span><br><span>    memset(&l1sap, 0, sizeof(l1sap));</span><br><span>@@ -384,7 +372,7 @@</span><br><span>  l1sap.u.info.u.act_cnf.chan_nr = chan_nr;</span><br><span>    l1sap.u.info.u.act_cnf.cause = cause;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       return l1sap_up(pinst->trx, &l1sap);</span><br><span style="color: hsl(120, 100%, 40%);">+   return l1sap_up(trx, &l1sap);</span><br><span> }</span><br><span> </span><br><span> int l1if_mph_time_ind(struct gsm_bts *bts, uint32_t fn)</span><br><span>@@ -406,8 +394,6 @@</span><br><span> /* primitive from common part */</span><br><span> int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        struct phy_instance *pinst = trx_phy_instance(trx);</span><br><span style="color: hsl(0, 100%, 40%);">-     struct trx_l1h *l1h = pinst->u.osmotrx.hdl;</span><br><span>       struct msgb *msg = l1sap->oph.msg;</span><br><span>        uint8_t chan_nr;</span><br><span>     int rc = 0;</span><br><span>@@ -418,21 +404,21 @@</span><br><span>          if (!msg)</span><br><span>                    break;</span><br><span>               /* put data into scheduler's queue */</span><br><span style="color: hsl(0, 100%, 40%);">-               return trx_sched_ph_data_req(&l1h->l1s, l1sap);</span><br><span style="color: hsl(120, 100%, 40%);">+                return trx_sched_ph_data_req(trx, l1sap);</span><br><span>    case OSMO_PRIM(PRIM_TCH, PRIM_OP_REQUEST):</span><br><span>           if (!msg)</span><br><span>                    break;</span><br><span>               /* put data into scheduler's queue */</span><br><span style="color: hsl(0, 100%, 40%);">-               return trx_sched_tch_req(&l1h->l1s, l1sap);</span><br><span style="color: hsl(120, 100%, 40%);">+            return trx_sched_tch_req(trx, l1sap);</span><br><span>        case OSMO_PRIM(PRIM_MPH_INFO, PRIM_OP_REQUEST):</span><br><span>              switch (l1sap->u.info.type) {</span><br><span>             case PRIM_INFO_ACT_CIPH:</span><br><span>                     chan_nr = l1sap->u.info.u.ciph_req.chan_nr;</span><br><span>                       lchan = get_lchan_by_chan_nr(trx, chan_nr);</span><br><span>                  if (l1sap->u.info.u.ciph_req.uplink)</span><br><span style="color: hsl(0, 100%, 40%);">-                         l1if_set_ciphering(l1h, lchan, chan_nr, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+                           l1if_set_ciphering(lchan, chan_nr, 0);</span><br><span>                       if (l1sap->u.info.u.ciph_req.downlink)</span><br><span style="color: hsl(0, 100%, 40%);">-                               l1if_set_ciphering(l1h, lchan, chan_nr, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+                           l1if_set_ciphering(lchan, chan_nr, 1);</span><br><span>                       break;</span><br><span>               case PRIM_INFO_ACTIVATE:</span><br><span>             case PRIM_INFO_DEACTIVATE:</span><br><span>@@ -463,11 +449,11 @@</span><br><span>                                   chan_nr = RSL_CHAN_OSMO_PDCH | (chan_nr & ~RSL_CHAN_NR_MASK);</span><br><span> </span><br><span>                                /* activate dedicated channel */</span><br><span style="color: hsl(0, 100%, 40%);">-                                trx_sched_set_lchan(&l1h->l1s, chan_nr, LID_DEDIC, true);</span><br><span style="color: hsl(120, 100%, 40%);">+                              trx_sched_set_lchan(lchan, chan_nr, LID_DEDIC, true);</span><br><span>                                /* activate associated channel */</span><br><span style="color: hsl(0, 100%, 40%);">-                               trx_sched_set_lchan(&l1h->l1s, chan_nr, LID_SACCH, true);</span><br><span style="color: hsl(120, 100%, 40%);">+                              trx_sched_set_lchan(lchan, chan_nr, LID_SACCH, true);</span><br><span>                                /* set mode */</span><br><span style="color: hsl(0, 100%, 40%);">-                          trx_sched_set_mode(&l1h->l1s, chan_nr,</span><br><span style="color: hsl(120, 100%, 40%);">+                         trx_sched_set_mode(lchan->ts, chan_nr,</span><br><span>                                    lchan->rsl_cmode, lchan->tch_mode,</span><br><span>                                     lchan->tch.amr_mr.num_modes,</span><br><span>                                      lchan->tch.amr_mr.bts_mode[0].mode,</span><br><span>@@ -481,16 +467,15 @@</span><br><span>                               /* set lchan active */</span><br><span>                               lchan_set_state(lchan, LCHAN_S_ACTIVE);</span><br><span>                              /* set initial ciphering */</span><br><span style="color: hsl(0, 100%, 40%);">-                             l1if_set_ciphering(l1h, lchan, chan_nr, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-                             l1if_set_ciphering(l1h, lchan, chan_nr, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+                           l1if_set_ciphering(lchan, chan_nr, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+                                l1if_set_ciphering(lchan, chan_nr, 1);</span><br><span>                               if (lchan->encr.alg_id)</span><br><span>                                   lchan->ciph_state = LCHAN_CIPH_RXTX_CONF;</span><br><span>                                 else</span><br><span>                                         lchan->ciph_state = LCHAN_CIPH_NONE;</span><br><span> </span><br><span>                          /* confirm */</span><br><span style="color: hsl(0, 100%, 40%);">-                           mph_info_chan_confirm(l1h, chan_nr,</span><br><span style="color: hsl(0, 100%, 40%);">-                                     PRIM_INFO_ACTIVATE, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+                               mph_info_chan_confirm(trx, chan_nr, PRIM_INFO_ACTIVATE, 0);</span><br><span>                          break;</span><br><span>                       }</span><br><span>                    if (l1sap->u.info.type == PRIM_INFO_MODIFY) {</span><br><span>@@ -499,7 +484,7 @@</span><br><span>                                       osmo_ecu_destroy(lchan->ecu_state);</span><br><span>                               lchan->ecu_state = osmo_ecu_init(trx, lchan2ecu_codec(lchan));</span><br><span>                            /* change mode */</span><br><span style="color: hsl(0, 100%, 40%);">-                               trx_sched_set_mode(&l1h->l1s, chan_nr,</span><br><span style="color: hsl(120, 100%, 40%);">+                         trx_sched_set_mode(lchan->ts, chan_nr,</span><br><span>                                    lchan->rsl_cmode, lchan->tch_mode,</span><br><span>                                     lchan->tch.amr_mr.num_modes,</span><br><span>                                      lchan->tch.amr_mr.bts_mode[0].mode,</span><br><span>@@ -527,8 +512,7 @@</span><br><span>                                 /* deactivate dedicated channel */</span><br><span>                           lchan_deactivate(lchan);</span><br><span>                             /* confirm only on dedicated channel */</span><br><span style="color: hsl(0, 100%, 40%);">-                         mph_info_chan_confirm(l1h, chan_nr,</span><br><span style="color: hsl(0, 100%, 40%);">-                                     PRIM_INFO_DEACTIVATE, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+                             mph_info_chan_confirm(trx, chan_nr, PRIM_INFO_DEACTIVATE, 0);</span><br><span>                        }</span><br><span>                    break;</span><br><span>               default:</span><br><span>diff --git a/src/osmo-bts-trx/l1_if.h b/src/osmo-bts-trx/l1_if.h</span><br><span>index 491f7cd..864bb69 100644</span><br><span>--- a/src/osmo-bts-trx/l1_if.h</span><br><span>+++ b/src/osmo-bts-trx/l1_if.h</span><br><span>@@ -125,8 +125,6 @@</span><br><span>  /* transceiver config */</span><br><span>     struct trx_config       config;</span><br><span>      struct osmo_fsm_inst    *provision_fi;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  struct l1sched_trx      l1s;</span><br><span> };</span><br><span> </span><br><span> struct trx_l1h *trx_l1h_alloc(void *tall_ctx, struct phy_instance *pinst);</span><br><span>@@ -136,10 +134,4 @@</span><br><span> int l1if_trx_start_power_ramp(struct gsm_bts_trx *trx, ramp_compl_cb_t ramp_compl_cb);</span><br><span> enum gsm_phys_chan_config transceiver_chan_type_2_pchan(uint8_t type);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static inline struct l1sched_trx *trx_l1sched_hdl(struct gsm_bts_trx *trx)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  struct trx_l1h *l1h = trx->pinst->u.osmotrx.hdl;</span><br><span style="color: hsl(0, 100%, 40%);">-  return &l1h->l1s;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> #endif /* L1_IF_H_TRX */</span><br><span>diff --git a/src/osmo-bts-trx/loops.c b/src/osmo-bts-trx/loops.c</span><br><span>index 823c2d7..4c70e8d 100644</span><br><span>--- a/src/osmo-bts-trx/loops.c</span><br><span>+++ b/src/osmo-bts-trx/loops.c</span><br><span>@@ -35,13 +35,10 @@</span><br><span> #include "l1_if.h"</span><br><span> #include "loops.h"</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void trx_loop_amr_input(struct l1sched_trx *l1t, uint8_t chan_nr,</span><br><span style="color: hsl(0, 100%, 40%);">-   struct l1sched_chan_state *chan_state,</span><br><span style="color: hsl(0, 100%, 40%);">-  int n_errors, int n_bits_total)</span><br><span style="color: hsl(120, 100%, 40%);">+void trx_loop_amr_input(struct l1sched_chan_state *chan_state,</span><br><span style="color: hsl(120, 100%, 40%);">+                       int n_errors, int n_bits_total)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gsm_bts_trx *trx = l1t->trx;</span><br><span style="color: hsl(0, 100%, 40%);">-  struct gsm_lchan *lchan = &trx->ts[L1SAP_CHAN2TS(chan_nr)]</span><br><span style="color: hsl(0, 100%, 40%);">-                                       .lchan[l1sap_chan2ss(chan_nr)];</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gsm_lchan *lchan = chan_state->lchan;</span><br><span>      float ber;</span><br><span> </span><br><span>       /* calculate BER (Bit Error Ratio) */</span><br><span>@@ -59,7 +56,7 @@</span><br><span>            return;</span><br><span> </span><br><span>  /* count bit errors */</span><br><span style="color: hsl(0, 100%, 40%);">-  if (L1SAP_IS_CHAN_TCHH(chan_nr)) {</span><br><span style="color: hsl(120, 100%, 40%);">+    if (lchan->type == GSM_LCHAN_TCH_H) {</span><br><span>             chan_state->ber_num += 2;</span><br><span>                 chan_state->ber_sum += (ber + ber);</span><br><span>       } else {</span><br><span>diff --git a/src/osmo-bts-trx/loops.h b/src/osmo-bts-trx/loops.h</span><br><span>index 1384960..4aa05c4 100644</span><br><span>--- a/src/osmo-bts-trx/loops.h</span><br><span>+++ b/src/osmo-bts-trx/loops.h</span><br><span>@@ -11,9 +11,8 @@</span><br><span>  * loops api</span><br><span>  */</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void trx_loop_amr_input(struct l1sched_trx *l1t, uint8_t chan_nr,</span><br><span style="color: hsl(0, 100%, 40%);">-   struct l1sched_chan_state *chan_state,</span><br><span style="color: hsl(0, 100%, 40%);">-  int n_errors, int n_bits_total);</span><br><span style="color: hsl(120, 100%, 40%);">+void trx_loop_amr_input(struct l1sched_chan_state *chan_state,</span><br><span style="color: hsl(120, 100%, 40%);">+                      int n_errors, int n_bits_total);</span><br><span> </span><br><span> void trx_loop_amr_set(struct l1sched_chan_state *chan_state, int loop);</span><br><span> </span><br><span>diff --git a/src/osmo-bts-trx/sched_lchan_fcch_sch.c b/src/osmo-bts-trx/sched_lchan_fcch_sch.c</span><br><span>index 4aac601..eaf140f 100644</span><br><span>--- a/src/osmo-bts-trx/sched_lchan_fcch_sch.c</span><br><span>+++ b/src/osmo-bts-trx/sched_lchan_fcch_sch.c</span><br><span>@@ -36,9 +36,9 @@</span><br><span> #include <sched_utils.h></span><br><span> </span><br><span> /* obtain a to-be-transmitted FCCH (frequency correction channel) burst */</span><br><span style="color: hsl(0, 100%, 40%);">-int tx_fcch_fn(struct l1sched_trx *l1t, struct trx_dl_burst_req *br)</span><br><span style="color: hsl(120, 100%, 40%);">+int tx_fcch_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-     LOGL1SB(DL1P, LOGL_DEBUG, l1t, br, "Transmitting FCCH\n");</span><br><span style="color: hsl(120, 100%, 40%);">+  LOGL1SB(DL1P, LOGL_DEBUG, l1ts, br, "Transmitting FCCH\n");</span><br><span> </span><br><span>    /* A frequency correction burst is basically a sequence of zeros.</span><br><span>     * Since br->burst is already zero-initialized, just set the length. */</span><br><span>@@ -48,21 +48,21 @@</span><br><span> }</span><br><span> </span><br><span> /* obtain a to-be-transmitted SCH (synchronization channel) burst */</span><br><span style="color: hsl(0, 100%, 40%);">-int tx_sch_fn(struct l1sched_trx *l1t, struct trx_dl_burst_req *br)</span><br><span style="color: hsl(120, 100%, 40%);">+int tx_sch_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br)</span><br><span> {</span><br><span>       ubit_t burst[78];</span><br><span>    uint8_t sb_info[4];</span><br><span>  struct  gsm_time t;</span><br><span>  uint8_t t3p, bsic;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  LOGL1SB(DL1P, LOGL_DEBUG, l1t, br, "Transmitting SCH\n");</span><br><span style="color: hsl(120, 100%, 40%);">+   LOGL1SB(DL1P, LOGL_DEBUG, l1ts, br, "Transmitting SCH\n");</span><br><span> </span><br><span>     /* BURST BYPASS */</span><br><span> </span><br><span>       /* create SB info from GSM time and BSIC */</span><br><span>  gsm_fn2gsmtime(&t, br->fn);</span><br><span>   t3p = t.t3 / 10;</span><br><span style="color: hsl(0, 100%, 40%);">-        bsic = l1t->trx->bts->bsic;</span><br><span style="color: hsl(120, 100%, 40%);">+  bsic = l1ts->ts->trx->bts->bsic;</span><br><span>         sb_info[0] =</span><br><span>                 ((bsic &  0x3f) << 2) |</span><br><span>            ((t.t1 & 0x600) >> 9);</span><br><span>diff --git a/src/osmo-bts-trx/sched_lchan_pdtch.c b/src/osmo-bts-trx/sched_lchan_pdtch.c</span><br><span>index 7ccc77a..8648cb8 100644</span><br><span>--- a/src/osmo-bts-trx/sched_lchan_pdtch.c</span><br><span>+++ b/src/osmo-bts-trx/sched_lchan_pdtch.c</span><br><span>@@ -39,9 +39,8 @@</span><br><span> #define EGPRS_0503_MAX_BYTES       155</span><br><span> </span><br><span> /*! \brief a single PDTCH burst was received by the PHY, process it */</span><br><span style="color: hsl(0, 100%, 40%);">-int rx_pdtch_fn(struct l1sched_trx *l1t, const struct trx_ul_burst_ind *bi)</span><br><span style="color: hsl(120, 100%, 40%);">+int rx_pdtch_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, bi->tn);</span><br><span>        struct l1sched_chan_state *chan_state = &l1ts->chan_state[bi->chan];</span><br><span>       sbit_t *burst, **bursts_p = &chan_state->ul_bursts;</span><br><span>   uint32_t first_fn;</span><br><span>@@ -55,7 +54,7 @@</span><br><span>       int rc;</span><br><span>      enum osmo_ph_pres_info_type presence_info;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  LOGL1SB(DL1P, LOGL_DEBUG, l1t, bi, "Received PDTCH bid=%u\n", bi->bid);</span><br><span style="color: hsl(120, 100%, 40%);">+  LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, "Received PDTCH bid=%u\n", bi->bid);</span><br><span> </span><br><span>    /* allocate burst memory, if not already */</span><br><span>  if (!*bursts_p) {</span><br><span>@@ -107,7 +106,7 @@</span><br><span> </span><br><span>  /* check for complete set of bursts */</span><br><span>       if ((*mask & 0xf) != 0xf) {</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGL1SB(DL1P, LOGL_DEBUG, l1t, bi, "Received incomplete frame (%u/%u)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, "Received incomplete frame (%u/%u)\n",</span><br><span>                         bi->fn % l1ts->mf_period, l1ts->mf_period);</span><br><span>         }</span><br><span>    *mask = 0x0;</span><br><span>@@ -129,7 +128,7 @@</span><br><span>   if (rc > 0) {</span><br><span>             presence_info = PRES_INFO_BOTH;</span><br><span>      } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGL1SB(DL1P, LOGL_DEBUG, l1t, bi, "Received bad PDTCH (%u/%u)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+          LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, "Received bad PDTCH (%u/%u)\n",</span><br><span>                        bi->fn % l1ts->mf_period, l1ts->mf_period);</span><br><span>                 rc = 0;</span><br><span>              presence_info = PRES_INFO_INVALID;</span><br><span>@@ -138,7 +137,7 @@</span><br><span>     ber10k = compute_ber10k(n_bits_total, n_errors);</span><br><span> </span><br><span>         first_fn = GSM_TDMA_FN_SUB(bi->fn, 3);</span><br><span style="color: hsl(0, 100%, 40%);">-       return _sched_compose_ph_data_ind(l1t, bi->tn,</span><br><span style="color: hsl(120, 100%, 40%);">+     return _sched_compose_ph_data_ind(l1ts,</span><br><span>                                        first_fn, bi->chan, l2, rc,</span><br><span>                                       meas_avg.rssi, meas_avg.toa256,</span><br><span>                                      meas_avg.ci_cb, ber10k,</span><br><span>@@ -146,10 +145,8 @@</span><br><span> }</span><br><span> </span><br><span> /* obtain a to-be-transmitted PDTCH (packet data) burst */</span><br><span style="color: hsl(0, 100%, 40%);">-int tx_pdtch_fn(struct l1sched_trx *l1t, struct trx_dl_burst_req *br)</span><br><span style="color: hsl(120, 100%, 40%);">+int tx_pdtch_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, br->tn);</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gsm_bts_trx_ts *ts = &l1t->trx->ts[br->tn];</span><br><span>      struct msgb *msg = NULL; /* make GCC happy */</span><br><span>        ubit_t *burst, **bursts_p = &l1ts->chan_state[br->chan].dl_bursts;</span><br><span>         enum trx_mod_type *mod = &l1ts->chan_state[br->chan].dl_mod_type;</span><br><span>@@ -163,11 +160,11 @@</span><br><span>  }</span><br><span> </span><br><span>        /* get mac block from queue */</span><br><span style="color: hsl(0, 100%, 40%);">-  msg = _sched_dequeue_prim(l1t, br);</span><br><span style="color: hsl(120, 100%, 40%);">+   msg = _sched_dequeue_prim(l1ts, br);</span><br><span>         if (msg)</span><br><span>             goto got_msg;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       LOGL1SB(DL1P, LOGL_INFO, l1t, br, "No prim for transmit.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+       LOGL1SB(DL1P, LOGL_INFO, l1ts, br, "No prim for transmit.\n");</span><br><span> </span><br><span> no_msg:</span><br><span>      /* free burst memory */</span><br><span>@@ -195,7 +192,7 @@</span><br><span> </span><br><span>    /* check validity of message */</span><br><span>      if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGL1SB(DL1P, LOGL_FATAL, l1t, br, "Prim invalid length, please FIX! "</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGL1SB(DL1P, LOGL_FATAL, l1ts, br, "Prim invalid length, please FIX! "</span><br><span>                    "(len=%ld)\n", (long)(msg->tail - msg->l2h));</span><br><span>                /* free message */</span><br><span>           msgb_free(msg);</span><br><span>@@ -215,7 +212,7 @@</span><br><span>                burst = *bursts_p + br->bid * 348;</span><br><span>                memset(br->burst, 1, 9);</span><br><span>          memcpy(br->burst + 9, burst, 174);</span><br><span style="color: hsl(0, 100%, 40%);">-           memcpy(br->burst + 183, _sched_egprs_tsc[gsm_ts_tsc(ts)], 78);</span><br><span style="color: hsl(120, 100%, 40%);">+             memcpy(br->burst + 183, _sched_egprs_tsc[gsm_ts_tsc(l1ts->ts)], 78);</span><br><span>           memcpy(br->burst + 261, burst + 174, 174);</span><br><span>                memset(br->burst + 435, 1, 9);</span><br><span> </span><br><span>@@ -223,13 +220,13 @@</span><br><span>        } else {</span><br><span>             burst = *bursts_p + br->bid * 116;</span><br><span>                memcpy(br->burst + 3, burst, 58);</span><br><span style="color: hsl(0, 100%, 40%);">-            memcpy(br->burst + 61, _sched_tsc[gsm_ts_tsc(ts)], 26);</span><br><span style="color: hsl(120, 100%, 40%);">+            memcpy(br->burst + 61, _sched_tsc[gsm_ts_tsc(l1ts->ts)], 26);</span><br><span>          memcpy(br->burst + 87, burst + 58, 58);</span><br><span> </span><br><span>               br->burst_len = GSM_BURST_LEN;</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   LOGL1SB(DL1P, LOGL_DEBUG, l1t, br, "Transmitting burst=%u.\n", br->bid);</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGL1SB(DL1P, LOGL_DEBUG, l1ts, br, "Transmitting burst=%u.\n", br->bid);</span><br><span> </span><br><span>   return 0;</span><br><span> }</span><br><span>diff --git a/src/osmo-bts-trx/sched_lchan_rach.c b/src/osmo-bts-trx/sched_lchan_rach.c</span><br><span>index ce9a46b..c3abf32 100644</span><br><span>--- a/src/osmo-bts-trx/sched_lchan_rach.c</span><br><span>+++ b/src/osmo-bts-trx/sched_lchan_rach.c</span><br><span>@@ -102,8 +102,9 @@</span><br><span>        return seq;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int rx_rach_fn(struct l1sched_trx *l1t, const struct trx_ul_burst_ind *bi)</span><br><span style="color: hsl(120, 100%, 40%);">+int rx_rach_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gsm_bts_trx *trx = l1ts->ts->trx;</span><br><span>       struct osmo_phsap_prim l1sap;</span><br><span>        int n_errors = 0;</span><br><span>    int n_bits_total = 0;</span><br><span>@@ -130,7 +131,7 @@</span><br><span>                  synch_seq = rach_get_synch_seq((sbit_t *) bi->burst, &best_score);</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   LOGL1SB(DL1P, LOGL_DEBUG, l1t, bi,</span><br><span style="color: hsl(120, 100%, 40%);">+    LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi,</span><br><span>         "Received%s RACH (%s): rssi=%d toa256=%d",</span><br><span>         (bi->chan != TRXC_RACH) ? " handover" : "",</span><br><span>           get_value_string(rach_synch_seq_names, synch_seq),</span><br><span>@@ -157,16 +158,16 @@</span><br><span>    if (bi->flags & TRX_BI_F_CI_CB)</span><br><span>               l1sap.u.rach_ind.lqual_cb = bi->ci_cb;</span><br><span>    else</span><br><span style="color: hsl(0, 100%, 40%);">-            l1sap.u.rach_ind.lqual_cb = l1t->trx->bts->min_qual_rach;</span><br><span style="color: hsl(120, 100%, 40%);">+            l1sap.u.rach_ind.lqual_cb = trx->bts->min_qual_rach;</span><br><span> </span><br><span>       /* Decode RACH depending on its synch. sequence */</span><br><span>   switch (synch_seq) {</span><br><span>         case RACH_SYNCH_SEQ_TS1:</span><br><span>     case RACH_SYNCH_SEQ_TS2:</span><br><span>             rc = gsm0503_rach_ext_decode_ber(&ra11, bi->burst + RACH_EXT_TAIL_LEN + RACH_SYNCH_SEQ_LEN,</span><br><span style="color: hsl(0, 100%, 40%);">-                                               l1t->trx->bts->bsic, &n_errors, &n_bits_total);</span><br><span style="color: hsl(120, 100%, 40%);">+                                              trx->bts->bsic, &n_errors, &n_bits_total);</span><br><span>            if (rc) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       LOGL1SB(DL1P, LOGL_DEBUG, l1t, bi, "Received bad Access Burst\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                  LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, "Received bad Access Burst\n");</span><br><span>                        return 0;</span><br><span>            }</span><br><span> </span><br><span>@@ -183,14 +184,14 @@</span><br><span>        default:</span><br><span>             /* Fall-back to the default TS0 if needed */</span><br><span>                 if (synch_seq != RACH_SYNCH_SEQ_TS0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                  LOGL1SB(DL1P, LOGL_DEBUG, l1t, bi, "Falling-back to the default TS0\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                    LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, "Falling-back to the default TS0\n");</span><br><span>                  synch_seq = RACH_SYNCH_SEQ_TS0;</span><br><span>              }</span><br><span> </span><br><span>                rc = gsm0503_rach_decode_ber(&ra, bi->burst + RACH_EXT_TAIL_LEN + RACH_SYNCH_SEQ_LEN,</span><br><span style="color: hsl(0, 100%, 40%);">-                                         l1t->trx->bts->bsic, &n_errors, &n_bits_total);</span><br><span style="color: hsl(120, 100%, 40%);">+                                      trx->bts->bsic, &n_errors, &n_bits_total);</span><br><span>                if (rc) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       LOGL1SB(DL1P, LOGL_DEBUG, l1t, bi, "Received bad Access Burst\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                  LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, "Received bad Access Burst\n");</span><br><span>                        return 0;</span><br><span>            }</span><br><span> </span><br><span>@@ -203,7 +204,7 @@</span><br><span>  l1sap.u.rach_ind.ber10k = compute_ber10k(n_bits_total, n_errors);</span><br><span> </span><br><span>        /* forward primitive */</span><br><span style="color: hsl(0, 100%, 40%);">- l1sap_up(l1t->trx, &l1sap);</span><br><span style="color: hsl(120, 100%, 40%);">+    l1sap_up(trx, &l1sap);</span><br><span> </span><br><span>       return 0;</span><br><span> }</span><br><span>diff --git a/src/osmo-bts-trx/sched_lchan_tchf.c b/src/osmo-bts-trx/sched_lchan_tchf.c</span><br><span>index 8ace49e..0961758 100644</span><br><span>--- a/src/osmo-bts-trx/sched_lchan_tchf.c</span><br><span>+++ b/src/osmo-bts-trx/sched_lchan_tchf.c</span><br><span>@@ -46,9 +46,8 @@</span><br><span> #include <loops.h></span><br><span> </span><br><span> /*! \brief a single TCH/F burst was received by the PHY, process it */</span><br><span style="color: hsl(0, 100%, 40%);">-int rx_tchf_fn(struct l1sched_trx *l1t, const struct trx_ul_burst_ind *bi)</span><br><span style="color: hsl(120, 100%, 40%);">+int rx_tchf_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, bi->tn);</span><br><span>        struct l1sched_chan_state *chan_state = &l1ts->chan_state[bi->chan];</span><br><span>       struct gsm_lchan *lchan = chan_state->lchan;</span><br><span>      sbit_t *burst, **bursts_p = &chan_state->ul_bursts;</span><br><span>@@ -70,9 +69,9 @@</span><br><span>       /* If handover RACH detection is turned on, treat this burst as an Access Burst.</span><br><span>      * Handle NOPE.ind as usually to ensure proper Uplink measurement reporting. */</span><br><span>      if (chan_state->ho_rach_detect == 1 && ~bi->flags & TRX_BI_F_NOPE_IND)</span><br><span style="color: hsl(0, 100%, 40%);">-                return rx_rach_fn(l1t, bi);</span><br><span style="color: hsl(120, 100%, 40%);">+           return rx_rach_fn(l1ts, bi);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        LOGL1SB(DL1P, LOGL_DEBUG, l1t, bi, "Received TCH/F, bid=%u\n", bi->bid);</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, "Received TCH/F, bid=%u\n", bi->bid);</span><br><span> </span><br><span>   /* allocate burst memory, if not already */</span><br><span>  if (!*bursts_p) {</span><br><span>@@ -107,7 +106,7 @@</span><br><span> </span><br><span>  /* check for complete set of bursts */</span><br><span>       if ((*mask & 0xf) != 0xf) {</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGL1SB(DL1P, LOGL_NOTICE, l1t, bi,</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGL1SB(DL1P, LOGL_NOTICE, l1ts, bi,</span><br><span>                         "Received incomplete frame (%u/%u)\n",</span><br><span>                     bi->fn % l1ts->mf_period, l1ts->mf_period);</span><br><span>         }</span><br><span>@@ -152,7 +151,7 @@</span><br><span>              /* Tag all frames that are not regular AMR voice frames as</span><br><span>            * SUB-Frames */</span><br><span>             if (chan_state->amr_last_dtx != AMR_OTHER) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 LOGL1SB(DL1P, LOGL_DEBUG, l1t, bi, "Received AMR SID frame: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                  LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, "Received AMR SID frame: %s\n",</span><br><span>                               gsm0503_amr_dtx_frame_name(chan_state->amr_last_dtx));</span><br><span>                     is_sub = 1;</span><br><span>          }</span><br><span>@@ -183,9 +182,7 @@</span><br><span>              }</span><br><span> </span><br><span>                if (rc)</span><br><span style="color: hsl(0, 100%, 40%);">-                 trx_loop_amr_input(l1t,</span><br><span style="color: hsl(0, 100%, 40%);">-                         trx_chan_desc[bi->chan].chan_nr | bi->tn, chan_state,</span><br><span style="color: hsl(0, 100%, 40%);">-                             n_errors, n_bits_total);</span><br><span style="color: hsl(120, 100%, 40%);">+                      trx_loop_amr_input(chan_state, n_errors, n_bits_total);</span><br><span>              /* only good speech frames get rtp header */</span><br><span>                 if (rc != GSM_MACBLOCK_LEN && rc >= 4) {</span><br><span>                  if (chan_state->amr_last_dtx == AMR_OTHER) {</span><br><span>@@ -201,7 +198,7 @@</span><br><span> </span><br><span>            break;</span><br><span>       default:</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGL1SB(DL1P, LOGL_ERROR, l1t, bi,</span><br><span style="color: hsl(120, 100%, 40%);">+            LOGL1SB(DL1P, LOGL_ERROR, l1ts, bi,</span><br><span>                  "TCH mode %u invalid, please fix!\n",</span><br><span>                      tch_mode);</span><br><span>           return -EINVAL;</span><br><span>@@ -213,11 +210,11 @@</span><br><span> </span><br><span>  /* Check if the frame is bad */</span><br><span>      if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGL1SB(DL1P, LOGL_NOTICE, l1t, bi, "Received bad data (%u/%u)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+          LOGL1SB(DL1P, LOGL_NOTICE, l1ts, bi, "Received bad data (%u/%u)\n",</span><br><span>                        bi->fn % l1ts->mf_period, l1ts->mf_period);</span><br><span>                 bfi_flag = true;</span><br><span>     } else if (rc < 4) {</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGL1SB(DL1P, LOGL_NOTICE, l1t, bi,</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGL1SB(DL1P, LOGL_NOTICE, l1ts, bi,</span><br><span>                         "Received bad data (%u/%u) with invalid codec mode %d\n",</span><br><span>                  bi->fn % l1ts->mf_period, l1ts->mf_period, rc);</span><br><span>             bfi_flag = true;</span><br><span>@@ -233,7 +230,7 @@</span><br><span>       /* FACCH */</span><br><span>  if (rc == GSM_MACBLOCK_LEN) {</span><br><span>                fn_begin = gsm0502_fn_remap(bi->fn, FN_REMAP_FACCH_F);</span><br><span style="color: hsl(0, 100%, 40%);">-               _sched_compose_ph_data_ind(l1t, bi->tn, fn_begin, bi->chan,</span><br><span style="color: hsl(120, 100%, 40%);">+             _sched_compose_ph_data_ind(l1ts, fn_begin, bi->chan,</span><br><span>                      tch_data + amr, GSM_MACBLOCK_LEN,</span><br><span>                    meas_avg.rssi, meas_avg.toa256,</span><br><span>                      meas_avg.ci_cb, ber10k,</span><br><span>@@ -281,7 +278,7 @@</span><br><span>                                        chan_state->codec[chan_state->dl_ft],</span><br><span>                                  AMR_BAD);</span><br><span>                            if (rc < 2) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                        LOGL1SB(DL1P, LOGL_ERROR, l1t, bi,</span><br><span style="color: hsl(120, 100%, 40%);">+                                    LOGL1SB(DL1P, LOGL_ERROR, l1ts, bi,</span><br><span>                                         "Failed to encode AMR_BAD frame (rc=%d), "</span><br><span>                                         "not sending BFI\n", rc);</span><br><span>                                   return -EINVAL;</span><br><span>@@ -289,7 +286,7 @@</span><br><span>                                memset(tch_data + 2, 0, rc - 2);</span><br><span>                             break;</span><br><span>                       default:</span><br><span style="color: hsl(0, 100%, 40%);">-                                LOGL1SB(DL1P, LOGL_ERROR, l1t, bi,</span><br><span style="color: hsl(120, 100%, 40%);">+                            LOGL1SB(DL1P, LOGL_ERROR, l1ts, bi,</span><br><span>                                  "TCH mode %u invalid, please fix!\n", tch_mode);</span><br><span>                           return -EINVAL;</span><br><span>                      }</span><br><span>@@ -302,7 +299,7 @@</span><br><span>      /* TCH or BFI */</span><br><span> compose_l1sap:</span><br><span>   fn_begin = gsm0502_fn_remap(bi->fn, FN_REMAP_TCH_F);</span><br><span style="color: hsl(0, 100%, 40%);">- return _sched_compose_tch_ind(l1t, bi->tn, fn_begin, bi->chan, tch_data, rc,</span><br><span style="color: hsl(120, 100%, 40%);">+    return _sched_compose_tch_ind(l1ts, fn_begin, bi->chan, tch_data, rc,</span><br><span>                                   /* FIXME: what should we use for BFI here? */</span><br><span>                                bfi_flag ? bi->toa256 : meas_avg.toa256, ber10k,</span><br><span>                                  bfi_flag ? bi->rssi : meas_avg.rssi, is_sub);</span><br><span>@@ -310,10 +307,9 @@</span><br><span> </span><br><span> /* common section for generation of TCH bursts (TCH/H and TCH/F).</span><br><span>  * FIXME: this function is over-complicated, refactor / get rid of it. */</span><br><span style="color: hsl(0, 100%, 40%);">-void tx_tch_common(struct l1sched_trx *l1t, struct trx_dl_burst_req *br,</span><br><span style="color: hsl(120, 100%, 40%);">+void tx_tch_common(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br,</span><br><span>                   struct msgb **_msg_tch, struct msgb **_msg_facch)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, br->tn);</span><br><span>        struct msgb *msg1, *msg2, *msg_tch = NULL, *msg_facch = NULL;</span><br><span>        struct l1sched_chan_state *chan_state = &l1ts->chan_state[br->chan];</span><br><span>       uint8_t rsl_cmode = chan_state->rsl_cmode;</span><br><span>@@ -326,7 +322,7 @@</span><br><span>          uint8_t tch_data[GSM_FR_BYTES];</span><br><span>              int len;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-            LOGL1SB(DL1P, LOGL_NOTICE, l1t, br, "Missing TCH bursts detected, sending BFI\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          LOGL1SB(DL1P, LOGL_NOTICE, l1ts, br, "Missing TCH bursts detected, sending BFI\n");</span><br><span> </span><br><span>            /* indicate bad frame */</span><br><span>             switch (tch_mode) {</span><br><span>@@ -351,7 +347,7 @@</span><br><span>                            chan_state->codec[chan_state->dl_cmr],</span><br><span>                                 chan_state->codec[chan_state->dl_ft], AMR_BAD);</span><br><span>                        if (len < 2) {</span><br><span style="color: hsl(0, 100%, 40%);">-                               LOGL1SB(DL1P, LOGL_ERROR, l1t, br,</span><br><span style="color: hsl(120, 100%, 40%);">+                            LOGL1SB(DL1P, LOGL_ERROR, l1ts, br,</span><br><span>                                  "Failed to encode AMR_BAD frame (rc=%d), "</span><br><span>                                         "not sending BFI\n", len);</span><br><span>                                 return;</span><br><span>@@ -360,21 +356,21 @@</span><br><span>                      break;</span><br><span>               default:</span><br><span> inval_mode1:</span><br><span style="color: hsl(0, 100%, 40%);">-                        LOGL1SB(DL1P, LOGL_ERROR, l1t, br, "TCH mode invalid, please fix!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                      LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, "TCH mode invalid, please fix!\n");</span><br><span>                    len = 0;</span><br><span>             }</span><br><span> </span><br><span>                if (len) {</span><br><span>                   /* Note: RSSI/ToA256 is set to 0 to indicate to the higher</span><br><span>                    * layers that this is a faked tch_ind */</span><br><span style="color: hsl(0, 100%, 40%);">-                       _sched_compose_tch_ind(l1t, br->tn, br->fn, br->chan,</span><br><span style="color: hsl(120, 100%, 40%);">+                        _sched_compose_tch_ind(l1ts, br->fn, br->chan,</span><br><span>                                                tch_data, len, 0, 10000, 0, 0);</span><br><span>               }</span><br><span>    }</span><br><span> </span><br><span>        /* get frame and unlink from queue */</span><br><span style="color: hsl(0, 100%, 40%);">-   msg1 = _sched_dequeue_prim(l1t, br);</span><br><span style="color: hsl(0, 100%, 40%);">-    msg2 = _sched_dequeue_prim(l1t, br);</span><br><span style="color: hsl(120, 100%, 40%);">+  msg1 = _sched_dequeue_prim(l1ts, br);</span><br><span style="color: hsl(120, 100%, 40%);">+ msg2 = _sched_dequeue_prim(l1ts, br);</span><br><span>        if (msg1) {</span><br><span>          l1sap = msgb_l1sap_prim(msg1);</span><br><span>               if (l1sap->oph.primitive == PRIM_TCH) {</span><br><span>@@ -382,7 +378,7 @@</span><br><span>                     if (msg2) {</span><br><span>                          l1sap = msgb_l1sap_prim(msg2);</span><br><span>                               if (l1sap->oph.primitive == PRIM_TCH) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                      LOGL1SB(DL1P, LOGL_FATAL, l1t, br, "TCH twice, please FIX!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                                     LOGL1SB(DL1P, LOGL_FATAL, l1ts, br, "TCH twice, please FIX!\n");</span><br><span>                                   msgb_free(msg2);</span><br><span>                             } else</span><br><span>                                       msg_facch = msg2;</span><br><span>@@ -392,7 +388,7 @@</span><br><span>                      if (msg2) {</span><br><span>                          l1sap = msgb_l1sap_prim(msg2);</span><br><span>                               if (l1sap->oph.primitive != PRIM_TCH) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                      LOGL1SB(DL1P, LOGL_FATAL, l1t, br, "FACCH twice, please FIX!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                                   LOGL1SB(DL1P, LOGL_FATAL, l1ts, br, "FACCH twice, please FIX!\n");</span><br><span>                                         msgb_free(msg2);</span><br><span>                             } else</span><br><span>                                       msg_tch = msg2;</span><br><span>@@ -408,7 +404,7 @@</span><br><span> </span><br><span>    /* check validity of message */</span><br><span>      if (msg_facch && msgb_l2len(msg_facch) != GSM_MACBLOCK_LEN) {</span><br><span style="color: hsl(0, 100%, 40%);">-           LOGL1SB(DL1P, LOGL_FATAL, l1t, br, "Prim has odd len=%u != %u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGL1SB(DL1P, LOGL_FATAL, l1ts, br, "Prim has odd len=%u != %u\n",</span><br><span>                         msgb_l2len(msg_facch), GSM_MACBLOCK_LEN);</span><br><span>            /* free message */</span><br><span>           msgb_free(msg_facch);</span><br><span>@@ -425,7 +421,7 @@</span><br><span>          int8_t sti, cmi;</span><br><span> </span><br><span>                 if (rsl_cmode != RSL_CMOD_SPD_SPEECH) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 LOGL1SB(DL1P, LOGL_NOTICE, l1t, br, "Dropping speech frame, "</span><br><span style="color: hsl(120, 100%, 40%);">+                       LOGL1SB(DL1P, LOGL_NOTICE, l1ts, br, "Dropping speech frame, "</span><br><span>                             "because we are not in speech mode\n");</span><br><span>                    goto free_bad_msg;</span><br><span>           }</span><br><span>@@ -463,32 +459,32 @@</span><br><span>                            trx_loop_amr_set(chan_state, 1);</span><br><span>                     }</span><br><span>                    if (ft < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                LOGL1SB(DL1P, LOGL_ERROR, l1t, br,</span><br><span style="color: hsl(120, 100%, 40%);">+                            LOGL1SB(DL1P, LOGL_ERROR, l1ts, br,</span><br><span>                                  "Codec (FT = %d) of RTP frame not in list\n", ft_codec);</span><br><span>                           goto free_bad_msg;</span><br><span>                   }</span><br><span>                    if (fn_is_codec_mode_request(br->fn) && chan_state->dl_ft != ft) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                LOGL1SB(DL1P, LOGL_NOTICE, l1t, br, "Codec (FT = %d) "</span><br><span style="color: hsl(120, 100%, 40%);">+                              LOGL1SB(DL1P, LOGL_NOTICE, l1ts, br, "Codec (FT = %d) "</span><br><span>                                    " of RTP cannot be changed now, but in next frame\n", ft_codec);</span><br><span>                           goto free_bad_msg;</span><br><span>                   }</span><br><span>                    chan_state->dl_ft = ft;</span><br><span>                   if (bfi == AMR_BAD) {</span><br><span style="color: hsl(0, 100%, 40%);">-                           LOGL1SB(DL1P, LOGL_NOTICE, l1t, br, "Transmitting 'bad AMR frame'\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                              LOGL1SB(DL1P, LOGL_NOTICE, l1ts, br, "Transmitting 'bad AMR frame'\n");</span><br><span>                            goto free_bad_msg;</span><br><span>                   }</span><br><span>                    break;</span><br><span>               default:</span><br><span> inval_mode2:</span><br><span style="color: hsl(0, 100%, 40%);">-                        LOGL1SB(DL1P, LOGL_ERROR, l1t, br, "TCH mode invalid, please fix!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                      LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, "TCH mode invalid, please fix!\n");</span><br><span>                    goto free_bad_msg;</span><br><span>           }</span><br><span>            if (len < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       LOGL1SB(DL1P, LOGL_ERROR, l1t, br, "Cannot send invalid AMR payload\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                    LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, "Cannot send invalid AMR payload\n");</span><br><span>                  goto free_bad_msg;</span><br><span>           }</span><br><span>            if (msgb_l2len(msg_tch) != len) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       LOGL1SB(DL1P, LOGL_ERROR, l1t, br, "Cannot send payload with "</span><br><span style="color: hsl(120, 100%, 40%);">+                      LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, "Cannot send payload with "</span><br><span>                            "invalid length! (expecting %d, received %d)\n",</span><br><span>                           len, msgb_l2len(msg_tch));</span><br><span> free_bad_msg:</span><br><span>@@ -505,11 +501,9 @@</span><br><span> }</span><br><span> </span><br><span> /* obtain a to-be-transmitted TCH/F (Full Traffic Channel) burst */</span><br><span style="color: hsl(0, 100%, 40%);">-int tx_tchf_fn(struct l1sched_trx *l1t, struct trx_dl_burst_req *br)</span><br><span style="color: hsl(120, 100%, 40%);">+int tx_tchf_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br)</span><br><span> {</span><br><span>    struct msgb *msg_tch = NULL, *msg_facch = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, br->tn);</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gsm_bts_trx_ts *ts = &l1t->trx->ts[br->tn];</span><br><span>      struct l1sched_chan_state *chan_state = &l1ts->chan_state[br->chan];</span><br><span>       uint8_t tch_mode = chan_state->tch_mode;</span><br><span>  ubit_t *burst, **bursts_p = &chan_state->dl_bursts;</span><br><span>@@ -521,7 +515,7 @@</span><br><span>             goto send_burst;</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   tx_tch_common(l1t, br, &msg_tch, &msg_facch);</span><br><span style="color: hsl(120, 100%, 40%);">+ tx_tch_common(l1ts, br, &msg_tch, &msg_facch);</span><br><span> </span><br><span>   /* BURST BYPASS */</span><br><span> </span><br><span>@@ -538,7 +532,7 @@</span><br><span> </span><br><span>     /* no message at all */</span><br><span>      if (!msg_tch && !msg_facch) {</span><br><span style="color: hsl(0, 100%, 40%);">-           LOGL1SB(DL1P, LOGL_INFO, l1t, br, "No TCH or FACCH prim for transmit.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          LOGL1SB(DL1P, LOGL_INFO, l1ts, br, "No TCH or FACCH prim for transmit.\n");</span><br><span>                goto send_burst;</span><br><span>     }</span><br><span> </span><br><span>@@ -568,12 +562,12 @@</span><br><span>        /* compose burst */</span><br><span>  burst = *bursts_p + br->bid * 116;</span><br><span>        memcpy(br->burst + 3, burst, 58);</span><br><span style="color: hsl(0, 100%, 40%);">-    memcpy(br->burst + 61, _sched_tsc[gsm_ts_tsc(ts)], 26);</span><br><span style="color: hsl(120, 100%, 40%);">+    memcpy(br->burst + 61, _sched_tsc[gsm_ts_tsc(l1ts->ts)], 26);</span><br><span>  memcpy(br->burst + 87, burst + 58, 58);</span><br><span> </span><br><span>       br->burst_len = GSM_BURST_LEN;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   LOGL1SB(DL1P, LOGL_DEBUG, l1t, br, "Transmitting burst=%u.\n", br->bid);</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGL1SB(DL1P, LOGL_DEBUG, l1ts, br, "Transmitting burst=%u.\n", br->bid);</span><br><span> </span><br><span>   return 0;</span><br><span> }</span><br><span>diff --git a/src/osmo-bts-trx/sched_lchan_tchh.c b/src/osmo-bts-trx/sched_lchan_tchh.c</span><br><span>index ca05844..e526e48 100644</span><br><span>--- a/src/osmo-bts-trx/sched_lchan_tchh.c</span><br><span>+++ b/src/osmo-bts-trx/sched_lchan_tchh.c</span><br><span>@@ -46,9 +46,8 @@</span><br><span> #include <loops.h></span><br><span> </span><br><span> /*! \brief a single TCH/H burst was received by the PHY, process it */</span><br><span style="color: hsl(0, 100%, 40%);">-int rx_tchh_fn(struct l1sched_trx *l1t, const struct trx_ul_burst_ind *bi)</span><br><span style="color: hsl(120, 100%, 40%);">+int rx_tchh_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, bi->tn);</span><br><span>        struct l1sched_chan_state *chan_state = &l1ts->chan_state[bi->chan];</span><br><span>       struct gsm_lchan *lchan = chan_state->lchan;</span><br><span>      sbit_t *burst, **bursts_p = &chan_state->ul_bursts;</span><br><span>@@ -77,9 +76,9 @@</span><br><span>       /* If handover RACH detection is turned on, treat this burst as an Access Burst.</span><br><span>      * Handle NOPE.ind as usually to ensure proper Uplink measurement reporting. */</span><br><span>      if (chan_state->ho_rach_detect == 1 && ~bi->flags & TRX_BI_F_NOPE_IND)</span><br><span style="color: hsl(0, 100%, 40%);">-                return rx_rach_fn(l1t, bi);</span><br><span style="color: hsl(120, 100%, 40%);">+           return rx_rach_fn(l1ts, bi);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        LOGL1SB(DL1P, LOGL_DEBUG, l1t, bi, "Received TCH/H, bid=%u\n", bi->bid);</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, "Received TCH/H, bid=%u\n", bi->bid);</span><br><span> </span><br><span>   /* allocate burst memory, if not already */</span><br><span>  if (!*bursts_p) {</span><br><span>@@ -114,7 +113,7 @@</span><br><span> </span><br><span>  /* check for complete set of bursts */</span><br><span>       if ((*mask & 0x3) != 0x3) {</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGL1SB(DL1P, LOGL_NOTICE, l1t, bi,</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGL1SB(DL1P, LOGL_NOTICE, l1ts, bi,</span><br><span>                         "Received incomplete frame (%u/%u)\n",</span><br><span>                     bi->fn % l1ts->mf_period, l1ts->mf_period);</span><br><span>         }</span><br><span>@@ -175,7 +174,7 @@</span><br><span>              /* Tag all frames that are not regular AMR voice frames</span><br><span>                 as SUB-Frames */</span><br><span>          if (chan_state->amr_last_dtx != AMR_OTHER) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 LOGL1SB(DL1P, LOGL_DEBUG, l1t, bi, "Received AMR SID frame: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                  LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, "Received AMR SID frame: %s\n",</span><br><span>                                gsm0503_amr_dtx_frame_name(chan_state->amr_last_dtx));</span><br><span>                    is_sub = 1;</span><br><span>          }</span><br><span>@@ -206,9 +205,7 @@</span><br><span>              }</span><br><span> </span><br><span>                if (rc)</span><br><span style="color: hsl(0, 100%, 40%);">-                 trx_loop_amr_input(l1t,</span><br><span style="color: hsl(0, 100%, 40%);">-                         trx_chan_desc[bi->chan].chan_nr | bi->tn, chan_state,</span><br><span style="color: hsl(0, 100%, 40%);">-                             n_errors, n_bits_total);</span><br><span style="color: hsl(120, 100%, 40%);">+                      trx_loop_amr_input(chan_state, n_errors, n_bits_total);</span><br><span> </span><br><span>          /* only good speech frames get rtp header */</span><br><span>                 if (rc != GSM_MACBLOCK_LEN && rc >= 4) {</span><br><span>@@ -225,7 +222,7 @@</span><br><span> </span><br><span>                break;</span><br><span>       default:</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGL1SB(DL1P, LOGL_ERROR, l1t, bi,</span><br><span style="color: hsl(120, 100%, 40%);">+            LOGL1SB(DL1P, LOGL_ERROR, l1ts, bi,</span><br><span>                  "TCH mode %u invalid, please fix!\n",</span><br><span>                      tch_mode);</span><br><span>           return -EINVAL;</span><br><span>@@ -241,11 +238,11 @@</span><br><span> </span><br><span>  /* Check if the frame is bad */</span><br><span>      if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGL1SB(DL1P, LOGL_NOTICE, l1t, bi, "Received bad data (%u/%u)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+          LOGL1SB(DL1P, LOGL_NOTICE, l1ts, bi, "Received bad data (%u/%u)\n",</span><br><span>                        bi->fn % l1ts->mf_period, l1ts->mf_period);</span><br><span>                 bfi_flag = true;</span><br><span>     } else if (rc < 4) {</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGL1SB(DL1P, LOGL_NOTICE, l1t, bi,</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGL1SB(DL1P, LOGL_NOTICE, l1ts, bi,</span><br><span>                         "Received bad data (%u/%u) with invalid codec mode %d\n",</span><br><span>                  bi->fn % l1ts->mf_period, l1ts->mf_period, rc);</span><br><span>             bfi_flag = true;</span><br><span>@@ -265,7 +262,7 @@</span><br><span>                       fn_begin = gsm0502_fn_remap(bi->fn, FN_REMAP_FACCH_H0);</span><br><span>           else</span><br><span>                         fn_begin = gsm0502_fn_remap(bi->fn, FN_REMAP_FACCH_H1);</span><br><span style="color: hsl(0, 100%, 40%);">-              _sched_compose_ph_data_ind(l1t, bi->tn, fn_begin, bi->chan,</span><br><span style="color: hsl(120, 100%, 40%);">+             _sched_compose_ph_data_ind(l1ts, fn_begin, bi->chan,</span><br><span>                      tch_data + amr, GSM_MACBLOCK_LEN,</span><br><span>                    meas_avg.rssi, meas_avg.toa256,</span><br><span>                      meas_avg.ci_cb, ber10k,</span><br><span>@@ -312,7 +309,7 @@</span><br><span>                                        chan_state->codec[chan_state->dl_ft],</span><br><span>                                  AMR_BAD);</span><br><span>                            if (rc < 2) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                        LOGL1SB(DL1P, LOGL_ERROR, l1t, bi,</span><br><span style="color: hsl(120, 100%, 40%);">+                                    LOGL1SB(DL1P, LOGL_ERROR, l1ts, bi,</span><br><span>                                         "Failed to encode AMR_BAD frame (rc=%d), "</span><br><span>                                         "not sending BFI\n", rc);</span><br><span>                                   return -EINVAL;</span><br><span>@@ -320,7 +317,7 @@</span><br><span>                                memset(tch_data + 2, 0, rc - 2);</span><br><span>                             break;</span><br><span>                       default:</span><br><span style="color: hsl(0, 100%, 40%);">-                                LOGL1SB(DL1P, LOGL_ERROR, l1t, bi,</span><br><span style="color: hsl(120, 100%, 40%);">+                            LOGL1SB(DL1P, LOGL_ERROR, l1ts, bi,</span><br><span>                                  "TCH mode %u invalid, please fix!\n", tch_mode);</span><br><span>                           return -EINVAL;</span><br><span>                      }</span><br><span>@@ -364,7 +361,7 @@</span><br><span>              chan_state->ber10k_facch = 0;</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   return _sched_compose_tch_ind(l1t, bi->tn, fn_begin, bi->chan, tch_data, rc,</span><br><span style="color: hsl(120, 100%, 40%);">+    return _sched_compose_tch_ind(l1ts, fn_begin, bi->chan, tch_data, rc,</span><br><span>                                   /* FIXME: what should we use for BFI here? */</span><br><span>                                bfi_flag ? bi->toa256 : meas_avg.toa256, ber10k,</span><br><span>                                  bfi_flag ? bi->rssi : meas_avg.rssi, is_sub);</span><br><span>@@ -372,16 +369,14 @@</span><br><span> </span><br><span> /* common section for generation of TCH bursts (TCH/H and TCH/F).</span><br><span>  * FIXME: this function is over-complicated, refactor / get rid of it. */</span><br><span style="color: hsl(0, 100%, 40%);">-extern void tx_tch_common(struct l1sched_trx *l1t,</span><br><span style="color: hsl(120, 100%, 40%);">+extern void tx_tch_common(struct l1sched_ts *l1ts,</span><br><span>                     const struct trx_dl_burst_req *br,</span><br><span>                           struct msgb **_msg_tch, struct msgb **_msg_facch);</span><br><span> </span><br><span> /* obtain a to-be-transmitted TCH/H (Half Traffic Channel) burst */</span><br><span style="color: hsl(0, 100%, 40%);">-int tx_tchh_fn(struct l1sched_trx *l1t, struct trx_dl_burst_req *br)</span><br><span style="color: hsl(120, 100%, 40%);">+int tx_tchh_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br)</span><br><span> {</span><br><span>       struct msgb *msg_tch = NULL, *msg_facch = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, br->tn);</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gsm_bts_trx_ts *ts = &l1t->trx->ts[br->tn];</span><br><span>      struct l1sched_chan_state *chan_state = &l1ts->chan_state[br->chan];</span><br><span>       uint8_t tch_mode = chan_state->tch_mode;</span><br><span>  ubit_t *burst, **bursts_p = &chan_state->dl_bursts;</span><br><span>@@ -394,11 +389,11 @@</span><br><span>   }</span><br><span> </span><br><span>        /* get TCH and/or FACCH */</span><br><span style="color: hsl(0, 100%, 40%);">-      tx_tch_common(l1t, br, &msg_tch, &msg_facch);</span><br><span style="color: hsl(120, 100%, 40%);">+ tx_tch_common(l1ts, br, &msg_tch, &msg_facch);</span><br><span> </span><br><span>   /* check for FACCH alignment */</span><br><span>      if (msg_facch && ((((br->fn + 4) % 26) >> 2) & 1)) {</span><br><span style="color: hsl(0, 100%, 40%);">-               LOGL1SB(DL1P, LOGL_ERROR, l1t, br,</span><br><span style="color: hsl(120, 100%, 40%);">+            LOGL1SB(DL1P, LOGL_ERROR, l1ts, br,</span><br><span>                  "Cannot transmit FACCH starting on even frames, please fix RTS!\n");</span><br><span>               msgb_free(msg_facch);</span><br><span>                msg_facch = NULL;</span><br><span>@@ -424,7 +419,7 @@</span><br><span> </span><br><span>  /* no message at all */</span><br><span>      if (!msg_tch && !msg_facch && !chan_state->dl_ongoing_facch) {</span><br><span style="color: hsl(0, 100%, 40%);">-               LOGL1SB(DL1P, LOGL_INFO, l1t, br, "No TCH or FACCH prim for transmit.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          LOGL1SB(DL1P, LOGL_INFO, l1ts, br, "No TCH or FACCH prim for transmit.\n");</span><br><span>                goto send_burst;</span><br><span>     }</span><br><span> </span><br><span>@@ -456,12 +451,12 @@</span><br><span>        /* compose burst */</span><br><span>  burst = *bursts_p + br->bid * 116;</span><br><span>        memcpy(br->burst + 3, burst, 58);</span><br><span style="color: hsl(0, 100%, 40%);">-    memcpy(br->burst + 61, _sched_tsc[gsm_ts_tsc(ts)], 26);</span><br><span style="color: hsl(120, 100%, 40%);">+    memcpy(br->burst + 61, _sched_tsc[gsm_ts_tsc(l1ts->ts)], 26);</span><br><span>  memcpy(br->burst + 87, burst + 58, 58);</span><br><span> </span><br><span>       br->burst_len = GSM_BURST_LEN;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   LOGL1SB(DL1P, LOGL_DEBUG, l1t, br, "Transmitting burst=%u.\n", br->bid);</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGL1SB(DL1P, LOGL_DEBUG, l1ts, br, "Transmitting burst=%u.\n", br->bid);</span><br><span> </span><br><span>   return 0;</span><br><span> }</span><br><span>diff --git a/src/osmo-bts-trx/sched_lchan_xcch.c b/src/osmo-bts-trx/sched_lchan_xcch.c</span><br><span>index ba0d612..62b511c 100644</span><br><span>--- a/src/osmo-bts-trx/sched_lchan_xcch.c</span><br><span>+++ b/src/osmo-bts-trx/sched_lchan_xcch.c</span><br><span>@@ -47,9 +47,8 @@</span><br><span> }</span><br><span> </span><br><span> /*! \brief a single (SDCCH/SACCH) burst was received by the PHY, process it */</span><br><span style="color: hsl(0, 100%, 40%);">-int rx_data_fn(struct l1sched_trx *l1t, const struct trx_ul_burst_ind *bi)</span><br><span style="color: hsl(120, 100%, 40%);">+int rx_data_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, bi->tn);</span><br><span>        struct l1sched_chan_state *chan_state = &l1ts->chan_state[bi->chan];</span><br><span>       sbit_t *burst, **bursts_p = &chan_state->ul_bursts;</span><br><span>   uint32_t *first_fn = &chan_state->ul_first_fn;</span><br><span>@@ -66,9 +65,9 @@</span><br><span>    /* If handover RACH detection is turned on, treat this burst as an Access Burst.</span><br><span>      * Handle NOPE.ind as usually to ensure proper Uplink measurement reporting. */</span><br><span>      if (chan_state->ho_rach_detect == 1 && ~bi->flags & TRX_BI_F_NOPE_IND)</span><br><span style="color: hsl(0, 100%, 40%);">-                return rx_rach_fn(l1t, bi);</span><br><span style="color: hsl(120, 100%, 40%);">+           return rx_rach_fn(l1ts, bi);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        LOGL1SB(DL1P, LOGL_DEBUG, l1t, bi, "Received Data, bid=%u\n", bi->bid);</span><br><span style="color: hsl(120, 100%, 40%);">+  LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, "Received Data, bid=%u\n", bi->bid);</span><br><span> </span><br><span>    /* allocate burst memory, if not already */</span><br><span>  if (!*bursts_p) {</span><br><span>@@ -116,7 +115,7 @@</span><br><span> </span><br><span>  /* check for complete set of bursts */</span><br><span>       if ((*mask & 0xf) != 0xf) {</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGL1SB(DL1P, LOGL_NOTICE, l1t, bi, "Received incomplete data (%u/%u)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGL1SB(DL1P, LOGL_NOTICE, l1ts, bi, "Received incomplete data (%u/%u)\n",</span><br><span>                         bi->fn % l1ts->mf_period, l1ts->mf_period);</span><br><span> </span><br><span>             /* we require first burst to have correct FN */</span><br><span>@@ -130,7 +129,7 @@</span><br><span>        /* decode */</span><br><span>         rc = gsm0503_xcch_decode(l2, *bursts_p, &n_errors, &n_bits_total);</span><br><span>   if (rc) {</span><br><span style="color: hsl(0, 100%, 40%);">-               LOGL1SB(DL1P, LOGL_NOTICE, l1t, bi, "Received bad data (%u/%u)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+          LOGL1SB(DL1P, LOGL_NOTICE, l1ts, bi, "Received bad data (%u/%u)\n",</span><br><span>                        bi->fn % l1ts->mf_period, l1ts->mf_period);</span><br><span>                 l2_len = 0;</span><br><span> </span><br><span>@@ -142,11 +141,11 @@</span><br><span>                      add_sbits(*bursts_p, chan_state->ul_bursts_prev);</span><br><span>                         rc = gsm0503_xcch_decode(l2, *bursts_p, &n_errors, &n_bits_total);</span><br><span>                   if (rc) {</span><br><span style="color: hsl(0, 100%, 40%);">-                               LOGL1SB(DL1P, LOGL_NOTICE, l1t, bi,</span><br><span style="color: hsl(120, 100%, 40%);">+                           LOGL1SB(DL1P, LOGL_NOTICE, l1ts, bi,</span><br><span>                                        "Combining current SACCH block with previous SACCH block also yields bad data (%u/%u)\n",</span><br><span>                                  bi->fn % l1ts->mf_period, l1ts->mf_period);</span><br><span>                  } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                                LOGL1SB(DL1P, LOGL_DEBUG, l1t, bi,</span><br><span style="color: hsl(120, 100%, 40%);">+                            LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi,</span><br><span>                                 "Combining current SACCH block with previous SACCH block yields good data (%u/%u)\n",</span><br><span>                                      bi->fn % l1ts->mf_period, l1ts->mf_period);</span><br><span>                          l2_len = GSM_MACBLOCK_LEN;</span><br><span>@@ -161,7 +160,7 @@</span><br><span>     if (rep_sacch)</span><br><span>               memcpy(chan_state->ul_bursts_prev, *bursts_p, 464);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      return _sched_compose_ph_data_ind(l1t, bi->tn, *first_fn,</span><br><span style="color: hsl(120, 100%, 40%);">+  return _sched_compose_ph_data_ind(l1ts, *first_fn,</span><br><span>                                     bi->chan, l2, l2_len,</span><br><span>                                     meas_avg.rssi, meas_avg.toa256,</span><br><span>                                      meas_avg.ci_cb, ber10k,</span><br><span>@@ -169,10 +168,8 @@</span><br><span> }</span><br><span> </span><br><span> /* obtain a to-be-transmitted xCCH (e.g SACCH or SDCCH) burst */</span><br><span style="color: hsl(0, 100%, 40%);">-int tx_data_fn(struct l1sched_trx *l1t, struct trx_dl_burst_req *br)</span><br><span style="color: hsl(120, 100%, 40%);">+int tx_data_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-    struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, br->tn);</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gsm_bts_trx_ts *ts = &l1t->trx->ts[br->tn];</span><br><span>      struct msgb *msg = NULL; /* make GCC happy */</span><br><span>        ubit_t *burst, **bursts_p = &l1ts->chan_state[br->chan].dl_bursts;</span><br><span> </span><br><span>@@ -184,11 +181,11 @@</span><br><span>     }</span><br><span> </span><br><span>        /* get mac block from queue */</span><br><span style="color: hsl(0, 100%, 40%);">-  msg = _sched_dequeue_prim(l1t, br);</span><br><span style="color: hsl(120, 100%, 40%);">+   msg = _sched_dequeue_prim(l1ts, br);</span><br><span>         if (msg)</span><br><span>             goto got_msg;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       LOGL1SB(DL1P, LOGL_INFO, l1t, br, "No prim for transmit.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+       LOGL1SB(DL1P, LOGL_INFO, l1ts, br, "No prim for transmit.\n");</span><br><span> </span><br><span> no_msg:</span><br><span>      /* free burst memory */</span><br><span>@@ -201,7 +198,7 @@</span><br><span> got_msg:</span><br><span>    /* check validity of message */</span><br><span>      if (msgb_l2len(msg) != GSM_MACBLOCK_LEN) {</span><br><span style="color: hsl(0, 100%, 40%);">-              LOGL1SB(DL1P, LOGL_FATAL, l1t, br, "Prim has odd len=%u != %u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGL1SB(DL1P, LOGL_FATAL, l1ts, br, "Prim has odd len=%u != %u\n",</span><br><span>                         msgb_l2len(msg), GSM_MACBLOCK_LEN);</span><br><span>          /* free message */</span><br><span>           msgb_free(msg);</span><br><span>@@ -219,7 +216,7 @@</span><br><span> </span><br><span>                    /* Note: RSSI is set to 0 to indicate to the higher</span><br><span>                   * layers that this is a faked ph_data_ind */</span><br><span style="color: hsl(0, 100%, 40%);">-                   _sched_compose_ph_data_ind(l1t, br->tn, 0, br->chan, NULL, 0,</span><br><span style="color: hsl(120, 100%, 40%);">+                   _sched_compose_ph_data_ind(l1ts, 0, br->chan, NULL, 0,</span><br><span>                                               0, 0, 0, 10000,</span><br><span>                                              PRES_INFO_INVALID);</span><br><span>               }</span><br><span>@@ -242,12 +239,12 @@</span><br><span>    /* compose burst */</span><br><span>  burst = *bursts_p + br->bid * 116;</span><br><span>        memcpy(br->burst + 3, burst, 58);</span><br><span style="color: hsl(0, 100%, 40%);">-    memcpy(br->burst + 61, _sched_tsc[gsm_ts_tsc(ts)], 26);</span><br><span style="color: hsl(120, 100%, 40%);">+    memcpy(br->burst + 61, _sched_tsc[gsm_ts_tsc(l1ts->ts)], 26);</span><br><span>  memcpy(br->burst + 87, burst + 58, 58);</span><br><span> </span><br><span>       br->burst_len = GSM_BURST_LEN;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   LOGL1SB(DL1P, LOGL_DEBUG, l1t, br, "Transmitting burst=%u.\n", br->bid);</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGL1SB(DL1P, LOGL_DEBUG, l1ts, br, "Transmitting burst=%u.\n", br->bid);</span><br><span> </span><br><span>   return 0;</span><br><span> }</span><br><span>diff --git a/src/osmo-bts-trx/scheduler_trx.c b/src/osmo-bts-trx/scheduler_trx.c</span><br><span>index bfe8d5c..3f55374 100644</span><br><span>--- a/src/osmo-bts-trx/scheduler_trx.c</span><br><span>+++ b/src/osmo-bts-trx/scheduler_trx.c</span><br><span>@@ -53,9 +53,9 @@</span><br><span>      (ts)->hopping.hsn, (ts)->hopping.maio, (ts)->hopping.arfcn_num</span><br><span> </span><br><span> /* an IDLE burst returns nothing. on C0 it is replaced by dummy burst */</span><br><span style="color: hsl(0, 100%, 40%);">-int tx_idle_fn(struct l1sched_trx *l1t, struct trx_dl_burst_req *br)</span><br><span style="color: hsl(120, 100%, 40%);">+int tx_idle_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  LOGL1SB(DL1P, LOGL_DEBUG, l1t, br, "Transmitting IDLE\n");</span><br><span style="color: hsl(120, 100%, 40%);">+  LOGL1SB(DL1P, LOGL_DEBUG, l1ts, br, "Transmitting IDLE\n");</span><br><span>        return 0;</span><br><span> }</span><br><span> </span><br><span>@@ -109,7 +109,6 @@</span><br><span>             struct phy_instance *pinst = trx_phy_instance(trx);</span><br><span>          struct phy_link *plink = pinst->phy_link;</span><br><span>                 struct trx_l1h *l1h = pinst->u.osmotrx.hdl;</span><br><span style="color: hsl(0, 100%, 40%);">-          struct l1sched_trx *l1t = &l1h->l1s;</span><br><span> </span><br><span>              /* we don't schedule, if power is off */</span><br><span>                 if (!trx_if_powered(l1h))</span><br><span>@@ -120,9 +119,11 @@</span><br><span>             sched_fn = GSM_TDMA_FN_SUM(fn, plink->u.osmotrx.clock_advance);</span><br><span> </span><br><span>               /* process every TS of TRX */</span><br><span style="color: hsl(0, 100%, 40%);">-           for (tn = 0; tn < ARRAY_SIZE(l1t->ts); tn++) {</span><br><span style="color: hsl(120, 100%, 40%);">+          for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  struct l1sched_ts *l1ts = trx->ts[tn].impl;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>                     /* ready-to-send */</span><br><span style="color: hsl(0, 100%, 40%);">-                     _sched_rts(l1t, tn, GSM_TDMA_FN_SUM(sched_fn, plink->u.osmotrx.rts_advance));</span><br><span style="color: hsl(120, 100%, 40%);">+                      _sched_rts(l1ts, GSM_TDMA_FN_SUM(sched_fn, plink->u.osmotrx.rts_advance));</span><br><span> </span><br><span>                    /* All other parameters to be set by _sched_dl_burst() */</span><br><span>                    br = (struct trx_dl_burst_req) {</span><br><span>@@ -131,7 +132,7 @@</span><br><span>                       };</span><br><span> </span><br><span>                       /* get burst for FN */</span><br><span style="color: hsl(0, 100%, 40%);">-                  _sched_dl_burst(l1t, &br);</span><br><span style="color: hsl(120, 100%, 40%);">+                        _sched_dl_burst(l1ts, &br);</span><br><span>                      if (br.burst_len == 0) {</span><br><span>                             /* if no bits, send no burst */</span><br><span>                              continue;</span><br><span>@@ -206,24 +207,17 @@</span><br><span> }</span><br><span> </span><br><span> /* Route a given Uplink burst indication to the scheduler depending on freq. hopping state */</span><br><span style="color: hsl(0, 100%, 40%);">-int trx_sched_route_burst_ind(struct trx_ul_burst_ind *bi, struct l1sched_trx *l1t)</span><br><span style="color: hsl(120, 100%, 40%);">+int trx_sched_route_burst_ind(const struct gsm_bts_trx *trx, struct trx_ul_burst_ind *bi)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  const struct phy_instance *pinst;</span><br><span style="color: hsl(0, 100%, 40%);">-       const struct gsm_bts_trx *trx;</span><br><span style="color: hsl(0, 100%, 40%);">-  struct trx_l1h *l1h;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>         /* no frequency hopping => nothing to do */</span><br><span style="color: hsl(0, 100%, 40%);">-  if (!l1t->trx->ts[bi->tn].hopping.enabled)</span><br><span style="color: hsl(0, 100%, 40%);">-             return trx_sched_ul_burst(l1t, bi);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!trx->ts[bi->tn].hopping.enabled)</span><br><span style="color: hsl(120, 100%, 40%);">+           return trx_sched_ul_burst(trx->ts[bi->tn].impl, bi);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  trx = ulfh_route_bi(bi, l1t->trx);</span><br><span style="color: hsl(120, 100%, 40%);">+ trx = ulfh_route_bi(bi, trx);</span><br><span>        if (trx == NULL)</span><br><span>             return -ENODEV;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     pinst = trx_phy_instance(trx);</span><br><span style="color: hsl(0, 100%, 40%);">-  l1h = pinst->u.osmotrx.hdl;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  return trx_sched_ul_burst(&l1h->l1s, bi);</span><br><span style="color: hsl(120, 100%, 40%);">+      return trx_sched_ul_burst(trx->ts[bi->tn].impl, bi);</span><br><span> }</span><br><span> </span><br><span> /*! maximum number of 'missed' frame periods we can tolerate of OS doesn't schedule us*/</span><br><span>@@ -462,9 +456,9 @@</span><br><span>    return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void _sched_act_rach_det(struct l1sched_trx *l1t, uint8_t tn, uint8_t ss, int activate)</span><br><span style="color: hsl(120, 100%, 40%);">+void _sched_act_rach_det(struct gsm_bts_trx *trx, uint8_t tn, uint8_t ss, int activate)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- struct phy_instance *pinst = trx_phy_instance(l1t->trx);</span><br><span style="color: hsl(120, 100%, 40%);">+   struct phy_instance *pinst = trx_phy_instance(trx);</span><br><span>  struct trx_l1h *l1h = pinst->u.osmotrx.hdl;</span><br><span> </span><br><span>   if (activate)</span><br><span>diff --git a/src/osmo-bts-trx/trx_if.c b/src/osmo-bts-trx/trx_if.c</span><br><span>index ff63187..78ba750 100644</span><br><span>--- a/src/osmo-bts-trx/trx_if.c</span><br><span>+++ b/src/osmo-bts-trx/trx_if.c</span><br><span>@@ -992,7 +992,7 @@</span><br><span>                 pdu_ver, trx_data_desc_msg(&bi));</span><br><span> </span><br><span>    /* feed received burst into scheduler code */</span><br><span style="color: hsl(0, 100%, 40%);">-   trx_sched_route_burst_ind(&bi, &l1h->l1s);</span><br><span style="color: hsl(120, 100%, 40%);">+ trx_sched_route_burst_ind(l1h->phy_inst->trx, &bi);</span><br><span> </span><br><span>    return 0;</span><br><span> }</span><br><span>@@ -1135,7 +1135,7 @@</span><br><span>       struct trx_l1h *l1h = pinst->u.osmotrx.hdl;</span><br><span> </span><br><span>   trx_if_close(l1h);</span><br><span style="color: hsl(0, 100%, 40%);">-      trx_sched_exit(&l1h->l1s);</span><br><span style="color: hsl(120, 100%, 40%);">+     trx_sched_clean(pinst->trx);</span><br><span> }</span><br><span> </span><br><span> /*! open the control + burst data sockets for one phy_instance */</span><br><span>@@ -1148,11 +1148,7 @@</span><br><span>       if (!l1h)</span><br><span>            return -EINVAL;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     rc = trx_sched_init(&l1h->l1s, pinst->trx);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGPPHI(l1h->phy_inst, DL1C, LOGL_FATAL, "Cannot initialize scheduler\n");</span><br><span style="color: hsl(0, 100%, 40%);">-         return -EIO;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(120, 100%, 40%);">+     trx_sched_init(pinst->trx);</span><br><span> </span><br><span>   rc = trx_if_open(l1h);</span><br><span>       if (rc < 0) {</span><br><span>diff --git a/src/osmo-bts-virtual/bts_model.c b/src/osmo-bts-virtual/bts_model.c</span><br><span>index e7b0f81..af8a6f2 100644</span><br><span>--- a/src/osmo-bts-virtual/bts_model.c</span><br><span>+++ b/src/osmo-bts-virtual/bts_model.c</span><br><span>@@ -100,11 +100,7 @@</span><br><span> </span><br><span> static uint8_t vbts_set_ts(struct gsm_bts_trx_ts *ts)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  struct phy_instance *pinst = trx_phy_instance(ts->trx);</span><br><span style="color: hsl(0, 100%, 40%);">-      int rc;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- rc = trx_sched_set_pchan(&pinst->u.virt.sched, ts->nr, ts->pchan);</span><br><span style="color: hsl(0, 100%, 40%);">- if (rc)</span><br><span style="color: hsl(120, 100%, 40%);">+       if (trx_sched_set_pchan(ts, ts->pchan) != 0)</span><br><span>              return NM_NACK_RES_NOTAVAIL;</span><br><span> </span><br><span>     return 0;</span><br><span>diff --git a/src/osmo-bts-virtual/l1_if.c b/src/osmo-bts-virtual/l1_if.c</span><br><span>index 78da639..5c04977 100644</span><br><span>--- a/src/osmo-bts-virtual/l1_if.c</span><br><span>+++ b/src/osmo-bts-virtual/l1_if.c</span><br><span>@@ -214,7 +214,7 @@</span><br><span> </span><br><span>     /* iterate over list of PHY instances and initialize the scheduler */</span><br><span>        llist_for_each_entry(pinst, &plink->instances, list) {</span><br><span style="color: hsl(0, 100%, 40%);">-           trx_sched_init(&pinst->u.virt.sched, pinst->trx);</span><br><span style="color: hsl(120, 100%, 40%);">+           trx_sched_init(pinst->trx);</span><br><span>               /* Only start the scheduler for the transceiver on C0.</span><br><span>                * If we have multiple transceivers, CCCH is always on C0</span><br><span>             * and has to be auto active */</span><br><span>@@ -244,28 +244,19 @@</span><br><span> /* enable ciphering */</span><br><span> static int l1if_set_ciphering(struct gsm_lchan *lchan, uint8_t chan_nr, int downlink)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- struct gsm_bts_trx *trx = lchan->ts->trx;</span><br><span style="color: hsl(0, 100%, 40%);">- struct phy_instance *pinst = trx_phy_instance(trx);</span><br><span style="color: hsl(0, 100%, 40%);">-     struct l1sched_trx *sched = &pinst->u.virt.sched;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>     /* ciphering already enabled in both directions */</span><br><span>   if (lchan->ciph_state == LCHAN_CIPH_RXTX_CONF)</span><br><span>            return -EINVAL;</span><br><span> </span><br><span>  if (!downlink) {</span><br><span>             /* set uplink */</span><br><span style="color: hsl(0, 100%, 40%);">-                trx_sched_set_cipher(sched, chan_nr, 0, lchan->encr.alg_id - 1,</span><br><span style="color: hsl(0, 100%, 40%);">-                      lchan->encr.key, lchan->encr.key_len);</span><br><span style="color: hsl(120, 100%, 40%);">+          trx_sched_set_cipher(lchan, chan_nr, false);</span><br><span>                 lchan->ciph_state = LCHAN_CIPH_RX_CONF;</span><br><span>   } else {</span><br><span>             /* set downlink and also set uplink, if not already */</span><br><span style="color: hsl(0, 100%, 40%);">-          if (lchan->ciph_state != LCHAN_CIPH_RX_CONF) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       trx_sched_set_cipher(sched, chan_nr, 0,</span><br><span style="color: hsl(0, 100%, 40%);">-                         lchan->encr.alg_id - 1, lchan->encr.key,</span><br><span style="color: hsl(0, 100%, 40%);">-                          lchan->encr.key_len);</span><br><span style="color: hsl(0, 100%, 40%);">-                }</span><br><span style="color: hsl(0, 100%, 40%);">-               trx_sched_set_cipher(sched, chan_nr, 1, lchan->encr.alg_id - 1,</span><br><span style="color: hsl(0, 100%, 40%);">-                      lchan->encr.key, lchan->encr.key_len);</span><br><span style="color: hsl(120, 100%, 40%);">+          if (lchan->ciph_state != LCHAN_CIPH_RX_CONF)</span><br><span style="color: hsl(120, 100%, 40%);">+                       trx_sched_set_cipher(lchan, chan_nr, false);</span><br><span style="color: hsl(120, 100%, 40%);">+          trx_sched_set_cipher(lchan, chan_nr, true);</span><br><span>          lchan->ciph_state = LCHAN_CIPH_RXTX_CONF;</span><br><span>         }</span><br><span> </span><br><span>@@ -342,7 +333,6 @@</span><br><span> int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap)</span><br><span> {</span><br><span>         struct phy_instance *pinst = trx_phy_instance(trx);</span><br><span style="color: hsl(0, 100%, 40%);">-     struct l1sched_trx *sched = &pinst->u.virt.sched;</span><br><span>     struct msgb *msg = l1sap->oph.msg;</span><br><span>        uint8_t chan_nr;</span><br><span>     uint8_t tn, ss;</span><br><span>@@ -354,12 +344,12 @@</span><br><span>              if (!msg)</span><br><span>                    break;</span><br><span>               /* put data into scheduler's queue */</span><br><span style="color: hsl(0, 100%, 40%);">-               return trx_sched_ph_data_req(sched, l1sap);</span><br><span style="color: hsl(120, 100%, 40%);">+           return trx_sched_ph_data_req(trx, l1sap);</span><br><span>    case OSMO_PRIM(PRIM_TCH, PRIM_OP_REQUEST):</span><br><span>           if (!msg)</span><br><span>                    break;</span><br><span>               /* put data into scheduler's queue */</span><br><span style="color: hsl(0, 100%, 40%);">-               return trx_sched_tch_req(sched, l1sap);</span><br><span style="color: hsl(120, 100%, 40%);">+               return trx_sched_tch_req(trx, l1sap);</span><br><span>        case OSMO_PRIM(PRIM_MPH_INFO, PRIM_OP_REQUEST):</span><br><span>              switch (l1sap->u.info.type) {</span><br><span>             case PRIM_INFO_ACT_CIPH:</span><br><span>@@ -388,11 +378,11 @@</span><br><span>                                     break;</span><br><span>                               }</span><br><span>                            /* activate dedicated channel */</span><br><span style="color: hsl(0, 100%, 40%);">-                                trx_sched_set_lchan(sched, chan_nr, LID_DEDIC, true);</span><br><span style="color: hsl(120, 100%, 40%);">+                         trx_sched_set_lchan(lchan, chan_nr, LID_DEDIC, true);</span><br><span>                                /* activate associated channel */</span><br><span style="color: hsl(0, 100%, 40%);">-                               trx_sched_set_lchan(sched, chan_nr, LID_SACCH, true);</span><br><span style="color: hsl(120, 100%, 40%);">+                         trx_sched_set_lchan(lchan, chan_nr, LID_SACCH, true);</span><br><span>                                /* set mode */</span><br><span style="color: hsl(0, 100%, 40%);">-                          trx_sched_set_mode(sched, chan_nr,</span><br><span style="color: hsl(120, 100%, 40%);">+                            trx_sched_set_mode(lchan->ts, chan_nr,</span><br><span>                                    lchan->rsl_cmode, lchan->tch_mode,</span><br><span>                                     lchan->tch.amr_mr.num_modes,</span><br><span>                                      lchan->tch.amr_mr.bts_mode[0].mode,</span><br><span>@@ -420,7 +410,7 @@</span><br><span>                         }</span><br><span>                    if (l1sap->u.info.type == PRIM_INFO_MODIFY) {</span><br><span>                             /* change mode */</span><br><span style="color: hsl(0, 100%, 40%);">-                               trx_sched_set_mode(sched, chan_nr,</span><br><span style="color: hsl(120, 100%, 40%);">+                            trx_sched_set_mode(lchan->ts, chan_nr,</span><br><span>                                    lchan->rsl_cmode, lchan->tch_mode,</span><br><span>                                     lchan->tch.amr_mr.num_modes,</span><br><span>                                      lchan->tch.amr_mr.bts_mode[0].mode,</span><br><span>@@ -437,12 +427,12 @@</span><br><span>                               break;</span><br><span>                       }</span><br><span>                    /* deactivate associated channel */</span><br><span style="color: hsl(0, 100%, 40%);">-                     trx_sched_set_lchan(sched, chan_nr, LID_SACCH, false);</span><br><span style="color: hsl(120, 100%, 40%);">+                        trx_sched_set_lchan(lchan, chan_nr, LID_SACCH, false);</span><br><span>                       if (!l1sap->u.info.u.act_req.sacch_only) {</span><br><span>                                /* set lchan inactive */</span><br><span>                             lchan_set_state(lchan, LCHAN_S_NONE);</span><br><span>                                /* deactivate dedicated channel */</span><br><span style="color: hsl(0, 100%, 40%);">-                              trx_sched_set_lchan(sched, chan_nr, LID_DEDIC, false);</span><br><span style="color: hsl(120, 100%, 40%);">+                                trx_sched_set_lchan(lchan, chan_nr, LID_DEDIC, false);</span><br><span>                               /* confirm only on dedicated channel */</span><br><span>                              mph_info_chan_confirm(trx, chan_nr,</span><br><span>                                  PRIM_INFO_DEACTIVATE, 0);</span><br><span>diff --git a/src/osmo-bts-virtual/l1_if.h b/src/osmo-bts-virtual/l1_if.h</span><br><span>index 075856f..c55e2d3 100644</span><br><span>--- a/src/osmo-bts-virtual/l1_if.h</span><br><span>+++ b/src/osmo-bts-virtual/l1_if.h</span><br><span>@@ -14,7 +14,6 @@</span><br><span> </span><br><span> struct vbts_l1h {</span><br><span>  struct gsm_bts_trx      *trx;</span><br><span style="color: hsl(0, 100%, 40%);">-   struct l1sched_trx      l1s;</span><br><span>         struct virt_um_inst     *virt_um;</span><br><span> };</span><br><span> </span><br><span>diff --git a/src/osmo-bts-virtual/scheduler_virtbts.c b/src/osmo-bts-virtual/scheduler_virtbts.c</span><br><span>index bbc2c4e..22fcff0 100644</span><br><span>--- a/src/osmo-bts-virtual/scheduler_virtbts.c</span><br><span>+++ b/src/osmo-bts-virtual/scheduler_virtbts.c</span><br><span>@@ -2,6 +2,7 @@</span><br><span> </span><br><span> /* (C) 2015-2017 by Harald Welte <laforge@gnumonks.org></span><br><span>  * (C) 2017 Sebastian Stumpf <sebastian.stumpf87@googlemail.com></span><br><span style="color: hsl(120, 100%, 40%);">+ * Contributions by sysmocom - s.f.m.c. GmbH</span><br><span>  *</span><br><span>  * All Rights Reserved</span><br><span>  *</span><br><span>@@ -51,13 +52,14 @@</span><br><span>  * Send a message over the virtual um interface.</span><br><span>  * This will at first wrap the msg with a GSMTAP header and then write it to the declared multicast socket.</span><br><span>  */</span><br><span style="color: hsl(0, 100%, 40%);">-static void _tx_to_virt_um(struct l1sched_trx *l1t,</span><br><span style="color: hsl(120, 100%, 40%);">+static void _tx_to_virt_um(struct l1sched_ts *l1ts,</span><br><span>                           struct trx_dl_burst_req *br,</span><br><span>                         struct msgb *msg, bool is_voice_frame)</span><br><span> {</span><br><span>       const struct trx_chan_desc *chdesc = &trx_chan_desc[br->chan];</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct gsm_bts_trx *trx = l1ts->ts->trx;</span><br><span>         struct msgb *outmsg;                    /* msg to send with gsmtap header prepended */</span><br><span style="color: hsl(0, 100%, 40%);">-  uint16_t arfcn = l1t->trx->arfcn; /* ARFCN of the transceiver the message is send with */</span><br><span style="color: hsl(120, 100%, 40%);">+       uint16_t arfcn = trx->arfcn;         /* ARFCN of the transceiver the message is send with */</span><br><span>      uint8_t signal_dbm = 63;                /* signal strength, 63 is best */</span><br><span>    uint8_t snr = 63;                       /* signal noise ratio, 63 is best */</span><br><span>         uint8_t *data = msgb_l2(msg);           /* data to transmit (whole message without l1 header) */</span><br><span>@@ -73,13 +75,13 @@</span><br><span>       /* in Osmocom, AGCH is only sent on ccch block 0. no idea why. this seems to cause false GSMTAP channel</span><br><span>       * types for agch and pch. */</span><br><span>        if (rsl_chantype == RSL_CHAN_PCH_AGCH &&</span><br><span style="color: hsl(0, 100%, 40%);">-            l1sap_fn2ccch_block(br->fn) >= num_agch(l1t->trx, "PH-DATA-REQ"))</span><br><span style="color: hsl(120, 100%, 40%);">+          l1sap_fn2ccch_block(br->fn) >= num_agch(trx, "PH-DATA-REQ"))</span><br><span>             gsmtap_chantype = GSMTAP_CHANNEL_PCH;</span><br><span>        else</span><br><span>                 gsmtap_chantype = chantype_rsl2gsmtap2(rsl_chantype, chdesc->link_id, is_voice_frame); /* the logical channel type */</span><br><span> </span><br><span>         if (gsmtap_chantype == GSMTAP_CHANNEL_UNKNOWN) {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGL1SB(DL1P, LOGL_ERROR, l1t, br, "Tx GSMTAP for RSL channel type 0x%02x: cannot send, this"</span><br><span style="color: hsl(120, 100%, 40%);">+               LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, "Tx GSMTAP for RSL channel type 0x%02x: cannot send, this"</span><br><span>                    " channel type is unknown in GSMTAP\n", rsl_chantype);</span><br><span>              msgb_free(msg);</span><br><span>              return;</span><br><span>@@ -93,44 +95,42 @@</span><br><span>        outmsg = gsmtap_makemsg(arfcn, timeslot, gsmtap_chantype, subslot, br->fn, signal_dbm, snr, data, data_len);</span><br><span> </span><br><span>  if (outmsg) {</span><br><span style="color: hsl(0, 100%, 40%);">-           struct phy_instance *pinst = trx_phy_instance(l1t->trx);</span><br><span style="color: hsl(120, 100%, 40%);">+           struct phy_instance *pinst = trx_phy_instance(trx);</span><br><span>          int rc;</span><br><span> </span><br><span>          rc = virt_um_write_msg(pinst->phy_link->u.virt.virt_um, outmsg);</span><br><span>               if (rc < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                  LOGL1SB(DL1P, LOGL_ERROR, l1t, br,</span><br><span style="color: hsl(120, 100%, 40%);">+                    LOGL1SB(DL1P, LOGL_ERROR, l1ts, br,</span><br><span>                         "GSMTAP msg could not send to virtual Um: %s\n", strerror(-rc));</span><br><span>            else if (rc == 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                       bts_shutdown(l1t->trx->bts, "VirtPHY write socket died\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                   bts_shutdown(trx->bts, "VirtPHY write socket died\n");</span><br><span>          else</span><br><span style="color: hsl(0, 100%, 40%);">-                    LOGL1SB(DL1P, LOGL_DEBUG, l1t, br,</span><br><span style="color: hsl(120, 100%, 40%);">+                    LOGL1SB(DL1P, LOGL_DEBUG, l1ts, br,</span><br><span>                         "Sending GSMTAP message to virtual Um\n");</span><br><span>  } else</span><br><span style="color: hsl(0, 100%, 40%);">-          LOGL1SB(DL1P, LOGL_ERROR, l1t, br, "GSMTAP msg could not be created!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, "GSMTAP msg could not be created!\n");</span><br><span> </span><br><span>     /* free incoming message */</span><br><span>  msgb_free(msg);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void tx_to_virt_um(struct l1sched_trx *l1t,</span><br><span style="color: hsl(120, 100%, 40%);">+static void tx_to_virt_um(struct l1sched_ts *l1ts,</span><br><span>                         struct trx_dl_burst_req *br,</span><br><span>                         struct msgb *msg)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        _tx_to_virt_um(l1t, br, msg, false);</span><br><span style="color: hsl(120, 100%, 40%);">+  _tx_to_virt_um(l1ts, br, msg, false);</span><br><span> }</span><br><span> </span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static struct gsm_lchan *lchan_from_l1t(struct l1sched_trx *l1t, uint8_t tn, enum trx_chan_type chan)</span><br><span style="color: hsl(120, 100%, 40%);">+static struct gsm_lchan *lchan_from_l1t(const struct l1sched_ts *l1ts,</span><br><span style="color: hsl(120, 100%, 40%);">+                                       const enum trx_chan_type chan)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gsm_bts_trx_ts *ts;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gsm_bts_trx_ts *ts = l1ts->ts;</span><br><span>     uint8_t subslot = 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        OSMO_ASSERT(l1t && l1t->trx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>     if (chan == TRXC_TCHH_1)</span><br><span>             subslot = 1;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        ts = &l1t->trx->ts[tn];</span><br><span>    return &ts->lchan[subslot];</span><br><span> }</span><br><span> </span><br><span>@@ -152,11 +152,11 @@</span><br><span>  }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void tx_to_virt_um_voice_frame(struct l1sched_trx *l1t,</span><br><span style="color: hsl(120, 100%, 40%);">+static void tx_to_virt_um_voice_frame(struct l1sched_ts *l1ts,</span><br><span>                                   struct trx_dl_burst_req *br,</span><br><span>                                 struct msgb *msg)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-    struct gsm_lchan *lchan = lchan_from_l1t(l1t, br->tn, br->chan);</span><br><span style="color: hsl(120, 100%, 40%);">+        struct gsm_lchan *lchan = lchan_from_l1t(l1ts, br->chan);</span><br><span>         int um_voice_type;</span><br><span> </span><br><span>       OSMO_ASSERT(lchan);</span><br><span>@@ -170,7 +170,7 @@</span><br><span>    msgb_pull_to_l2(msg);</span><br><span>        msgb_push_u8(msg, um_voice_type);</span><br><span>    msg->l2h = msg->data;</span><br><span style="color: hsl(0, 100%, 40%);">-     _tx_to_virt_um(l1t, br, msg, true);</span><br><span style="color: hsl(120, 100%, 40%);">+   _tx_to_virt_um(l1ts, br, msg, true);</span><br><span> }</span><br><span> </span><br><span> /*</span><br><span>@@ -178,22 +178,22 @@</span><br><span>  */</span><br><span> </span><br><span> /* an IDLE burst returns nothing. on C0 it is replaced by dummy burst */</span><br><span style="color: hsl(0, 100%, 40%);">-int tx_idle_fn(struct l1sched_trx *l1t, struct trx_dl_burst_req *br)</span><br><span style="color: hsl(120, 100%, 40%);">+int tx_idle_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br)</span><br><span> {</span><br><span>    return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int tx_fcch_fn(struct l1sched_trx *l1t, struct trx_dl_burst_req *br)</span><br><span style="color: hsl(120, 100%, 40%);">+int tx_fcch_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br)</span><br><span> {</span><br><span>    return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int tx_sch_fn(struct l1sched_trx *l1t, struct trx_dl_burst_req *br)</span><br><span style="color: hsl(120, 100%, 40%);">+int tx_sch_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br)</span><br><span> {</span><br><span>      return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int tx_data_fn(struct l1sched_trx *l1t, struct trx_dl_burst_req *br)</span><br><span style="color: hsl(120, 100%, 40%);">+int tx_data_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br)</span><br><span> {</span><br><span>    struct msgb *msg;</span><br><span> </span><br><span>@@ -201,15 +201,15 @@</span><br><span>                return 0;</span><br><span> </span><br><span>        /* get mac block from queue */</span><br><span style="color: hsl(0, 100%, 40%);">-  msg = _sched_dequeue_prim(l1t, br);</span><br><span style="color: hsl(120, 100%, 40%);">+   msg = _sched_dequeue_prim(l1ts, br);</span><br><span>         if (!msg) {</span><br><span style="color: hsl(0, 100%, 40%);">-             LOGL1SB(DL1P, LOGL_INFO, l1t, br, "has not been served !! No prim\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGL1SB(DL1P, LOGL_INFO, l1ts, br, "has not been served !! No prim\n");</span><br><span>            return -ENODEV;</span><br><span>      }</span><br><span> </span><br><span>        /* check validity of message */</span><br><span>      if (msgb_l2len(msg) != GSM_MACBLOCK_LEN) {</span><br><span style="color: hsl(0, 100%, 40%);">-              LOGL1SB(DL1P, LOGL_FATAL, l1t, br, "Prim not 23 bytes, please FIX! (len=%d)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+             LOGL1SB(DL1P, LOGL_FATAL, l1ts, br, "Prim not 23 bytes, please FIX! (len=%d)\n",</span><br><span>                   msgb_l2len(msg));</span><br><span>            /* free message */</span><br><span>           msgb_free(msg);</span><br><span>@@ -217,12 +217,12 @@</span><br><span>      }</span><br><span> </span><br><span>        /* transmit the msg received on dl from bsc to layer1 (virt Um) */</span><br><span style="color: hsl(0, 100%, 40%);">-      tx_to_virt_um(l1t, br, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+  tx_to_virt_um(l1ts, br, msg);</span><br><span> </span><br><span>    return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int tx_pdtch_fn(struct l1sched_trx *l1t, struct trx_dl_burst_req *br)</span><br><span style="color: hsl(120, 100%, 40%);">+int tx_pdtch_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br)</span><br><span> {</span><br><span>  struct msgb *msg = NULL; /* make GCC happy */</span><br><span> </span><br><span>@@ -230,23 +230,22 @@</span><br><span>            return 0;</span><br><span> </span><br><span>        /* get mac block from queue */</span><br><span style="color: hsl(0, 100%, 40%);">-  msg = _sched_dequeue_prim(l1t, br);</span><br><span style="color: hsl(120, 100%, 40%);">+   msg = _sched_dequeue_prim(l1ts, br);</span><br><span>         if (!msg) {</span><br><span style="color: hsl(0, 100%, 40%);">-             LOGL1SB(DL1P, LOGL_INFO, l1t, br, "has not been served !! No prim\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGL1SB(DL1P, LOGL_INFO, l1ts, br, "has not been served !! No prim\n");</span><br><span>            return -ENODEV;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   tx_to_virt_um(l1t, br, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+  tx_to_virt_um(l1ts, br, msg);</span><br><span> </span><br><span>    return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void tx_tch_common(struct l1sched_trx *l1t,</span><br><span style="color: hsl(120, 100%, 40%);">+static void tx_tch_common(struct l1sched_ts *l1ts,</span><br><span>                       const struct trx_dl_burst_req *br,</span><br><span>                           struct msgb **_msg_tch, struct msgb **_msg_facch,</span><br><span>                    int codec_mode_request)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, br->tn);</span><br><span>        struct msgb *msg1, *msg2, *msg_tch = NULL, *msg_facch = NULL;</span><br><span>        struct l1sched_chan_state *chan_state = &l1ts->chan_state[br->chan];</span><br><span>       uint8_t rsl_cmode = chan_state->rsl_cmode;</span><br><span>@@ -259,7 +258,7 @@</span><br><span>          uint8_t tch_data[GSM_FR_BYTES];</span><br><span>              int len;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-            LOGL1SB(DL1P, LOGL_NOTICE, l1t, br, "Missing TCH bursts detected, sending "</span><br><span style="color: hsl(120, 100%, 40%);">+         LOGL1SB(DL1P, LOGL_NOTICE, l1ts, br, "Missing TCH bursts detected, sending "</span><br><span>                       "BFI for %s\n", trx_chan_desc[br->chan].name);</span><br><span> </span><br><span>              /* indicate bad frame */</span><br><span>@@ -287,7 +286,7 @@</span><br><span>                       if (len < 2)</span><br><span>                              break;</span><br><span>                       memset(tch_data + 2, 0, len - 2);</span><br><span style="color: hsl(0, 100%, 40%);">-                       _sched_compose_tch_ind(l1t, br->tn, 0, br->chan, tch_data, len);</span><br><span style="color: hsl(120, 100%, 40%);">+                        _sched_compose_tch_ind(l1ts, 0, br->chan, tch_data, len);</span><br><span>                         break;</span><br><span>               default:</span><br><span> inval_mode1:</span><br><span>@@ -296,13 +295,13 @@</span><br><span>                     len = 0;</span><br><span>             }</span><br><span>            if (len)</span><br><span style="color: hsl(0, 100%, 40%);">-                        _sched_compose_tch_ind(l1t, br->tn, 0, br->chan, tch_data, len);</span><br><span style="color: hsl(120, 100%, 40%);">+                        _sched_compose_tch_ind(l1ts, 0, br->chan, tch_data, len);</span><br><span>         }</span><br><span> #endif</span><br><span> </span><br><span>      /* get frame and unlink from queue */</span><br><span style="color: hsl(0, 100%, 40%);">-   msg1 = _sched_dequeue_prim(l1t, br);</span><br><span style="color: hsl(0, 100%, 40%);">-    msg2 = _sched_dequeue_prim(l1t, br);</span><br><span style="color: hsl(120, 100%, 40%);">+  msg1 = _sched_dequeue_prim(l1ts, br);</span><br><span style="color: hsl(120, 100%, 40%);">+ msg2 = _sched_dequeue_prim(l1ts, br);</span><br><span>        if (msg1) {</span><br><span>          l1sap = msgb_l1sap_prim(msg1);</span><br><span>               if (l1sap->oph.primitive == PRIM_TCH) {</span><br><span>@@ -310,7 +309,7 @@</span><br><span>                     if (msg2) {</span><br><span>                          l1sap = msgb_l1sap_prim(msg2);</span><br><span>                               if (l1sap->oph.primitive == PRIM_TCH) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                      LOGL1SB(DL1P, LOGL_FATAL, l1t, br,</span><br><span style="color: hsl(120, 100%, 40%);">+                                    LOGL1SB(DL1P, LOGL_FATAL, l1ts, br,</span><br><span>                                          "TCH twice, please FIX!\n");</span><br><span>                                       msgb_free(msg2);</span><br><span>                             } else</span><br><span>@@ -321,7 +320,7 @@</span><br><span>                         if (msg2) {</span><br><span>                          l1sap = msgb_l1sap_prim(msg2);</span><br><span>                               if (l1sap->oph.primitive != PRIM_TCH) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                      LOGL1SB(DL1P, LOGL_FATAL, l1t, br,</span><br><span style="color: hsl(120, 100%, 40%);">+                                    LOGL1SB(DL1P, LOGL_FATAL, l1ts, br,</span><br><span>                                          "FACCH twice, please FIX!\n");</span><br><span>                                     msgb_free(msg2);</span><br><span>                             } else</span><br><span>@@ -338,7 +337,7 @@</span><br><span> </span><br><span>     /* check validity of message */</span><br><span>      if (msg_facch && msgb_l2len(msg_facch) != GSM_MACBLOCK_LEN) {</span><br><span style="color: hsl(0, 100%, 40%);">-           LOGL1SB(DL1P, LOGL_FATAL, l1t, br, "Prim has odd len=%u != %u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGL1SB(DL1P, LOGL_FATAL, l1ts, br, "Prim has odd len=%u != %u\n",</span><br><span>                         msgb_l2len(msg_facch), GSM_MACBLOCK_LEN);</span><br><span>            /* free message */</span><br><span>           msgb_free(msg_facch);</span><br><span>@@ -354,7 +353,7 @@</span><br><span> #endif</span><br><span> </span><br><span>            if (rsl_cmode != RSL_CMOD_SPD_SPEECH) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 LOGL1SB(DL1P, LOGL_NOTICE, l1t, br, "Dropping speech frame, "</span><br><span style="color: hsl(120, 100%, 40%);">+                       LOGL1SB(DL1P, LOGL_NOTICE, l1ts, br, "Dropping speech frame, "</span><br><span>                             "because we are not in speech mode\n");</span><br><span>                    goto free_bad_msg;</span><br><span>           }</span><br><span>@@ -365,7 +364,7 @@</span><br><span>                              len = 15;</span><br><span>                            if (msgb_l2len(msg_tch) >= 1</span><br><span>                               && (msg_tch->l2h[0] & 0xf0) != 0x00) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                  LOGL1SB(DL1P, LOGL_NOTICE, l1t, br,</span><br><span style="color: hsl(120, 100%, 40%);">+                                   LOGL1SB(DL1P, LOGL_NOTICE, l1ts, br,</span><br><span>                                                 "Transmitting 'bad HR frame'\n");</span><br><span>                                  goto free_bad_msg;</span><br><span>                           }</span><br><span>@@ -374,7 +373,7 @@</span><br><span>                      len = GSM_FR_BYTES;</span><br><span>                  if (msgb_l2len(msg_tch) >= 1</span><br><span>                       && (msg_tch->l2h[0] >> 4) != 0xd) {</span><br><span style="color: hsl(0, 100%, 40%);">-                           LOGL1SB(DL1P, LOGL_NOTICE, l1t, br,</span><br><span style="color: hsl(120, 100%, 40%);">+                           LOGL1SB(DL1P, LOGL_NOTICE, l1ts, br,</span><br><span>                                         "Transmitting 'bad FR frame'\n");</span><br><span>                          goto free_bad_msg;</span><br><span>                   }</span><br><span>@@ -385,7 +384,7 @@</span><br><span>                      len = GSM_EFR_BYTES;</span><br><span>                         if (msgb_l2len(msg_tch) >= 1</span><br><span>                       && (msg_tch->l2h[0] >> 4) != 0xc) {</span><br><span style="color: hsl(0, 100%, 40%);">-                           LOGL1SB(DL1P, LOGL_NOTICE, l1t, br,</span><br><span style="color: hsl(120, 100%, 40%);">+                           LOGL1SB(DL1P, LOGL_NOTICE, l1ts, br,</span><br><span>                                         "Transmitting 'bad EFR frame'\n");</span><br><span>                                 goto free_bad_msg;</span><br><span>                   }</span><br><span>@@ -396,15 +395,15 @@</span><br><span>                    break;</span><br><span>               default:</span><br><span> inval_mode2:</span><br><span style="color: hsl(0, 100%, 40%);">-                        LOGL1SB(DL1P, LOGL_ERROR, l1t, br, "TCH mode invalid, please fix!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                      LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, "TCH mode invalid, please fix!\n");</span><br><span>                    goto free_bad_msg;</span><br><span>           }</span><br><span>            if (len < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       LOGL1SB(DL1P, LOGL_ERROR, l1t, br, "Cannot send invalid AMR payload\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                    LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, "Cannot send invalid AMR payload\n");</span><br><span>                  goto free_bad_msg;</span><br><span>           }</span><br><span>            if (msgb_l2len(msg_tch) != len) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       LOGL1SB(DL1P, LOGL_ERROR, l1t, br, "Cannot send payload with "</span><br><span style="color: hsl(120, 100%, 40%);">+                      LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, "Cannot send payload with "</span><br><span>                            "invalid length! (expecing %d, received %d)\n", len, msgb_l2len(msg_tch));</span><br><span> free_bad_msg:</span><br><span>                        /* free message */</span><br><span>@@ -419,34 +418,33 @@</span><br><span>   *_msg_facch = msg_facch;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int tx_tchf_fn(struct l1sched_trx *l1t, struct trx_dl_burst_req *br)</span><br><span style="color: hsl(120, 100%, 40%);">+int tx_tchf_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br)</span><br><span> {</span><br><span>     struct msgb *msg_tch = NULL, *msg_facch = NULL;</span><br><span> </span><br><span>  if (br->bid > 0)</span><br><span>               return 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   tx_tch_common(l1t, br, &msg_tch, &msg_facch, (((br->fn + 4) % 26) >> 2) & 1);</span><br><span style="color: hsl(120, 100%, 40%);">+    tx_tch_common(l1ts, br, &msg_tch, &msg_facch, (((br->fn + 4) % 26) >> 2) & 1);</span><br><span> </span><br><span>      /* no message at all */</span><br><span>      if (!msg_tch && !msg_facch) {</span><br><span style="color: hsl(0, 100%, 40%);">-           LOGL1SB(DL1P, LOGL_INFO, l1t, br, "has not been served !! No prim\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGL1SB(DL1P, LOGL_INFO, l1ts, br, "has not been served !! No prim\n");</span><br><span>            return -ENODEV;</span><br><span>      }</span><br><span> </span><br><span>        if (msg_facch) {</span><br><span style="color: hsl(0, 100%, 40%);">-                tx_to_virt_um(l1t, br, msg_facch);</span><br><span style="color: hsl(120, 100%, 40%);">+            tx_to_virt_um(l1ts, br, msg_facch);</span><br><span>          msgb_free(msg_tch);</span><br><span>  } else if (msg_tch)</span><br><span style="color: hsl(0, 100%, 40%);">-             tx_to_virt_um_voice_frame(l1t, br, msg_tch);</span><br><span style="color: hsl(120, 100%, 40%);">+          tx_to_virt_um_voice_frame(l1ts, br, msg_tch);</span><br><span> </span><br><span>    return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int tx_tchh_fn(struct l1sched_trx *l1t, struct trx_dl_burst_req *br)</span><br><span style="color: hsl(120, 100%, 40%);">+int tx_tchh_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br)</span><br><span> {</span><br><span>    struct msgb *msg_tch = NULL, *msg_facch = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, br->tn);</span><br><span>        struct l1sched_chan_state *chan_state = &l1ts->chan_state[br->chan];</span><br><span>       //uint8_t tch_mode = chan_state->tch_mode;</span><br><span> </span><br><span>@@ -455,11 +453,11 @@</span><br><span>            return 0;</span><br><span> </span><br><span>        /* get TCH and/or FACCH */</span><br><span style="color: hsl(0, 100%, 40%);">-      tx_tch_common(l1t, br, &msg_tch, &msg_facch, (((br->fn + 4) % 26) >> 2) & 1);</span><br><span style="color: hsl(120, 100%, 40%);">+    tx_tch_common(l1ts, br, &msg_tch, &msg_facch, (((br->fn + 4) % 26) >> 2) & 1);</span><br><span> </span><br><span>      /* check for FACCH alignment */</span><br><span>      if (msg_facch && ((((br->fn + 4) % 26) >> 2) & 1)) {</span><br><span style="color: hsl(0, 100%, 40%);">-               LOGL1SB(DL1P, LOGL_ERROR, l1t, br, "Cannot transmit FACCH starting on "</span><br><span style="color: hsl(120, 100%, 40%);">+             LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, "Cannot transmit FACCH starting on "</span><br><span>                   "even frames, please fix RTS!\n");</span><br><span>                 msgb_free(msg_facch);</span><br><span>                msg_facch = NULL;</span><br><span>@@ -467,15 +465,15 @@</span><br><span> </span><br><span>        /* no message at all */</span><br><span>      if (!msg_tch && !msg_facch && !chan_state->dl_ongoing_facch) {</span><br><span style="color: hsl(0, 100%, 40%);">-               LOGL1SB(DL1P, LOGL_INFO, l1t, br, "has not been served !! No prim\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGL1SB(DL1P, LOGL_INFO, l1ts, br, "has not been served !! No prim\n");</span><br><span>            return -ENODEV;</span><br><span>      }</span><br><span> </span><br><span>        if (msg_facch) {</span><br><span style="color: hsl(0, 100%, 40%);">-                tx_to_virt_um(l1t, br, msg_facch);</span><br><span style="color: hsl(120, 100%, 40%);">+            tx_to_virt_um(l1ts, br, msg_facch);</span><br><span>          msgb_free(msg_tch);</span><br><span>  } else if (msg_tch)</span><br><span style="color: hsl(0, 100%, 40%);">-             tx_to_virt_um_voice_frame(l1t, br, msg_tch);</span><br><span style="color: hsl(120, 100%, 40%);">+          tx_to_virt_um_voice_frame(l1ts, br, msg_tch);</span><br><span> </span><br><span>    return 0;</span><br><span> }</span><br><span>@@ -489,33 +487,33 @@</span><br><span>  * directly into the L1SAP, bypassing the TDMA multiplex logic oriented</span><br><span>  * towards receiving bursts */</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int rx_rach_fn(struct l1sched_trx *l1t, const struct trx_ul_burst_ind *bi)</span><br><span style="color: hsl(120, 100%, 40%);">+int rx_rach_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi)</span><br><span> {</span><br><span>   return 0;</span><br><span> }</span><br><span> </span><br><span> /*! \brief a single burst was received by the PHY, process it */</span><br><span style="color: hsl(0, 100%, 40%);">-int rx_data_fn(struct l1sched_trx *l1t, const struct trx_ul_burst_ind *bi)</span><br><span style="color: hsl(120, 100%, 40%);">+int rx_data_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi)</span><br><span> {</span><br><span>    return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int rx_pdtch_fn(struct l1sched_trx *l1t, const struct trx_ul_burst_ind *bi)</span><br><span style="color: hsl(120, 100%, 40%);">+int rx_pdtch_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi)</span><br><span> {</span><br><span>      return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int rx_tchf_fn(struct l1sched_trx *l1t, const struct trx_ul_burst_ind *bi)</span><br><span style="color: hsl(120, 100%, 40%);">+int rx_tchf_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi)</span><br><span> {</span><br><span>        return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int rx_tchh_fn(struct l1sched_trx *l1t, const struct trx_ul_burst_ind *bi)</span><br><span style="color: hsl(120, 100%, 40%);">+int rx_tchh_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi)</span><br><span> {</span><br><span>        return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void _sched_act_rach_det(struct l1sched_trx *l1t, uint8_t tn, uint8_t ss, int activate)</span><br><span style="color: hsl(120, 100%, 40%);">+void _sched_act_rach_det(struct gsm_bts_trx *trx, uint8_t tn, uint8_t ss, int activate)</span><br><span> {</span><br><span> }</span><br><span> </span><br><span>@@ -536,12 +534,11 @@</span><br><span> </span><br><span>         /* advance the frame number? */</span><br><span>      llist_for_each_entry(trx, &bts->trx_list, list) {</span><br><span style="color: hsl(0, 100%, 40%);">-                struct phy_instance *pinst = trx_phy_instance(trx);</span><br><span style="color: hsl(0, 100%, 40%);">-             struct l1sched_trx *l1t = &pinst->u.virt.sched;</span><br><span>               struct trx_dl_burst_req br = { .fn = fn };</span><br><span> </span><br><span>               /* do for each of the 8 timeslots */</span><br><span style="color: hsl(0, 100%, 40%);">-            for (br.tn = 0; br.tn < ARRAY_SIZE(l1t->ts); br.tn++) {</span><br><span style="color: hsl(120, 100%, 40%);">+         for (br.tn = 0; br.tn < ARRAY_SIZE(trx->ts); br.tn++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 struct l1sched_ts *l1ts = trx->ts[br.tn].impl;</span><br><span>                    /* Generate RTS indication to higher layers */</span><br><span>                       /* This will basically do 2 things (check l1_if:bts_model_l1sap_down):</span><br><span>                        * 1) Get pending messages from layer 2 (from the lapdm queue)</span><br><span>@@ -549,13 +546,13 @@</span><br><span>                        *    --> Handle and process non-transparent RSL-Messages (activate channel, )</span><br><span>                     *    --> Forward transparent RSL-DATA-Messages to the ms by appending them to</span><br><span>                     *        the l1-dl-queue */</span><br><span style="color: hsl(0, 100%, 40%);">-                    _sched_rts(l1t, br.tn, GSM_TDMA_FN_SUM(fn, RTS_ADVANCE));</span><br><span style="color: hsl(120, 100%, 40%);">+                     _sched_rts(l1ts, GSM_TDMA_FN_SUM(fn, RTS_ADVANCE));</span><br><span>                  /* schedule transmit backend functions */</span><br><span>                    /* Process data in the l1-dlqueue and forward it</span><br><span>                      * to MS */</span><br><span>                  /* the returned bits are not used here, the routines called will directly forward their</span><br><span>                       * bits to the virt Um */</span><br><span style="color: hsl(0, 100%, 40%);">-                       _sched_dl_burst(l1t, &br);</span><br><span style="color: hsl(120, 100%, 40%);">+                        _sched_dl_burst(l1ts, &br);</span><br><span>              }</span><br><span>    }</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-bts/+/24179">change 24179</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-bts/+/24179"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-bts </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I7c4379e43a25e9d858d582a99bf6c4b65c9af481 </div>
<div style="display:none"> Gerrit-Change-Number: 24179 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: fixeria <vyanitskiy@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>