---
 include/osmo-bts/phy_link.h       |   1 +
 src/osmo-bts-sysmo/l1_if.c        |  59 ++++++++++++---
 src/osmo-bts-sysmo/l1_if.h        |  22 +++++-
 src/osmo-bts-sysmo/main.c         |  42 ++++-------
 src/osmo-bts-sysmo/oml.c          |   1 +
 src/osmo-bts-sysmo/sysmobts_vty.c | 146 +++++++++++++++++++++++---------------
 tests/sysmobts/sysmobts_test.c    |   4 ++
 7 files changed, 178 insertions(+), 97 deletions(-)

diff --git a/include/osmo-bts/phy_link.h b/include/osmo-bts/phy_link.h
index b9fc412..ec3a915 100644
--- a/include/osmo-bts/phy_link.h
+++ b/include/osmo-bts/phy_link.h
@@ -82,6 +82,7 @@ struct phy_instance {

        union {
                struct {
+                       struct femtol1_hdl *hdl;
                } sysmobts;
                struct {
                        struct trx_l1h *hdl;
diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c
index 8457a74..b64136b 100644
--- a/src/osmo-bts-sysmo/l1_if.c
+++ b/src/osmo-bts-sysmo/l1_if.c
@@ -1,6 +1,6 @@
 /* Interface handler for Sysmocom L1 */

-/* (C) 2011-2014 by Harald Welte <[email protected]>
+/* (C) 2011-2016 by Harald Welte <[email protected]>
  * (C) 2014 by Holger Hans Peter Freyther
  *
  * All Rights Reserved
@@ -41,6 +41,7 @@
 #include <osmo-bts/oml.h>
 #include <osmo-bts/rsl.h>
 #include <osmo-bts/gsm_data.h>
+#include <osmo-bts/phy_link.h>
 #include <osmo-bts/paging.h>
 #include <osmo-bts/measurement.h>
 #include <osmo-bts/pcu_if.h>
@@ -579,7 +580,7 @@ static int handle_mph_time_ind(struct femtol1_hdl *fl1,
                                GsmL1_MphTimeInd_t *time_ind,
                                struct msgb *msg)
 {
-       struct gsm_bts_trx *trx = fl1->priv;
+       struct gsm_bts_trx *trx = femtol1_hdl_trx(fl1);
        struct gsm_bts *bts = trx->bts;
        struct osmo_phsap_prim l1sap;
        uint32_t fn;
@@ -705,7 +706,7 @@ static int handle_ph_readytosend_ind(struct femtol1_hdl 
*fl1,
                                     GsmL1_PhReadyToSendInd_t *rts_ind,
                                     struct msgb *l1p_msg)
 {
-       struct gsm_bts_trx *trx = fl1->priv;
+       struct gsm_bts_trx *trx = femtol1_hdl_trx(fl1);
        struct gsm_bts *bts = trx->bts;
        struct msgb *resp_msg;
        GsmL1_PhDataReq_t *data_req;
@@ -834,7 +835,7 @@ static int process_meas_res(struct gsm_bts_trx *trx, 
uint8_t chan_nr,
 static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t 
*data_ind,
                              struct msgb *l1p_msg)
 {
-       struct gsm_bts_trx *trx = fl1->priv;
+       struct gsm_bts_trx *trx = femtol1_hdl_trx(fl1);
        uint8_t chan_nr, link_id;
        struct msgb *sap_msg;
        struct osmo_phsap_prim *l1sap;
@@ -900,7 +901,7 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, 
GsmL1_PhDataInd_t *data_i
 static int handle_ph_ra_ind(struct femtol1_hdl *fl1, GsmL1_PhRaInd_t *ra_ind,
                            struct msgb *l1p_msg)
 {
-       struct gsm_bts_trx *trx = fl1->priv;
+       struct gsm_bts_trx *trx = femtol1_hdl_trx(fl1);
        struct gsm_bts *bts = trx->bts;
        struct gsm_bts_role_bts *btsb = bts->role;
        struct gsm_lchan *lchan;
@@ -1021,7 +1022,8 @@ int l1if_handle_l1prim(int wq, struct femtol1_hdl *fl1h, 
struct msgb *msg)
                        if (wlc->cb) {
                                /* call-back function must take
                                 * ownership of msgb */
-                               rc = wlc->cb(fl1h->priv, msg, wlc->cb_data);
+                               rc = wlc->cb(femtol1_hdl_trx(fl1h), msg,
+                                            wlc->cb_data);
                        } else {
                                rc = 0;
                                msgb_free(msg);
@@ -1053,7 +1055,8 @@ int l1if_handle_sysprim(struct femtol1_hdl *fl1h, struct 
msgb *msg)
                        if (wlc->cb) {
                                /* call-back function must take
                                 * ownership of msgb */
-                               rc = wlc->cb(fl1h->priv, msg, wlc->cb_data);
+                               rc = wlc->cb(femtol1_hdl_trx(fl1h), msg,
+                                            wlc->cb_data);
                        } else {
                                rc = 0;
                                msgb_free(msg);
@@ -1166,7 +1169,7 @@ int l1if_activate_rf(struct femtol1_hdl *hdl, int on)
 {
        struct msgb *msg = sysp_msgb_alloc();
        SuperFemto_Prim_t *sysp = msgb_sysprim(msg);
-       struct gsm_bts_trx *trx = hdl->priv;
+       struct gsm_bts_trx *trx = hdl->phy_inst->trx;

        if (on) {
                sysp->id = SuperFemto_PrimId_ActivateRfReq;
@@ -1478,7 +1481,7 @@ static int get_hwinfo_eeprom(struct femtol1_hdl *fl1h)
        return 0;
 }

-struct femtol1_hdl *l1if_open(void *priv)
+struct femtol1_hdl *l1if_open(struct phy_instance *pinst)
 {
        struct femtol1_hdl *fl1h;
        int rc;
@@ -1495,12 +1498,12 @@ struct femtol1_hdl *l1if_open(void *priv)
                         FEMTOBTS_API_VERSION & 0xff);
 #endif

-       fl1h = talloc_zero(priv, struct femtol1_hdl);
+       fl1h = talloc_zero(pinst, struct femtol1_hdl);
        if (!fl1h)
                return NULL;
        INIT_LLIST_HEAD(&fl1h->wlc_list);

-       fl1h->priv = priv;
+       fl1h->phy_inst = pinst;
        fl1h->clk_cal = 0;
        fl1h->clk_use_eeprom = 1;
        fl1h->min_qual_rach = MIN_QUAL_RACH;
@@ -1535,6 +1538,8 @@ struct femtol1_hdl *l1if_open(void *priv)
                return NULL;
        }

+       l1if_reset(fl1h);
+
        return fl1h;
 }

@@ -1662,3 +1667,35 @@ int l1if_rf_clock_info_correct(struct femtol1_hdl *fl1h)
 }

 #endif
+
+int bts_model_phy_link_open(struct phy_link *plink)
+{
+       struct phy_instance *pinst = phy_instance_by_num(plink, 0);
+       struct gsm_bts *bts;
+
+       OSMO_ASSERT(pinst);
+
+       phy_link_state_set(plink, PHY_LINK_CONNECTING);
+
+       pinst->u.sysmobts.hdl = l1if_open(pinst);
+       if (!pinst->u.sysmobts.hdl) {
+               LOGP(DL1C, LOGL_FATAL, "Cannot open L1 interface\n");
+               return -EIO;
+       }
+
+       bts = pinst->trx->bts;
+       if (pinst->trx == bts->c0) {
+               int rc;
+               rc = sysmobts_get_nominal_power(bts->c0);
+               if (rc < 0) {
+                       LOGP(DL1C, LOGL_NOTICE, "Cannot determine nominal "
+                            "transmit power. Assuming 23dBm.\n");
+               }
+               bts->c0->nominal_power = rc;
+               bts->c0->power_params.trx_p_max_out_mdBm = to_mdB(rc);
+       }
+
+       phy_link_state_set(plink, PHY_LINK_CONNECTED);
+
+       return 0;
+}
diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h
index 3f2938f..de4f2a3 100644
--- a/src/osmo-bts-sysmo/l1_if.h
+++ b/src/osmo-bts-sysmo/l1_if.h
@@ -7,6 +7,8 @@
 #include <osmocom/core/timer.h>
 #include <osmocom/gsm/gsm_utils.h>

+#include <osmo-bts/phy_link.h>
+
 #include <sysmocom/femtobts/gsml1prim.h>

 enum {
@@ -52,7 +54,7 @@ struct femtol1_hdl {
        char *calib_path;
        struct llist_head wlc_list;

-       void *priv;                     /* user reference */
+       struct phy_instance *phy_inst;          /* Reference to PHY instance */

        struct osmo_timer_list alive_timer;
        unsigned int alive_prim_cnt;
@@ -78,6 +80,9 @@ struct femtol1_hdl {
        struct calib_send_state st;

        uint8_t last_rf_mute[8];
+
+       /* for l1_fwd */
+       void *priv;
 };

 #define msgb_l1prim(msg)       ((GsmL1_Prim_t *)(msg)->l1h)
@@ -91,7 +96,7 @@ int l1if_req_compl(struct femtol1_hdl *fl1h, struct msgb *msg,
 int l1if_gsm_req_compl(struct femtol1_hdl *fl1h, struct msgb *msg,
                l1if_compl_cb *cb, void *cb_data);

-struct femtol1_hdl *l1if_open(void *priv);
+struct femtol1_hdl *l1if_open(struct phy_instance *pinst);
 int l1if_close(struct femtol1_hdl *hdl);
 int l1if_reset(struct femtol1_hdl *hdl);
 int l1if_activate_rf(struct femtol1_hdl *hdl, int on);
@@ -134,4 +139,17 @@ int l1if_rf_clock_info_correct(struct femtol1_hdl *fl1h);
 /* public helpers for test */
 int bts_check_for_ciph_cmd(struct femtol1_hdl *fl1h,
                              struct msgb *msg, struct gsm_lchan *lchan);
+
+static inline struct femtol1_hdl *trx_femtol1_hdl(struct gsm_bts_trx *trx)
+{
+       struct phy_instance *pinst = trx_phy_instance(trx);
+       OSMO_ASSERT(pinst);
+       return pinst->u.sysmobts.hdl;
+}
+
+static inline struct gsm_bts_trx *femtol1_hdl_trx(struct femtol1_hdl *fl1h)
+{
+       OSMO_ASSERT(fl1h->phy_inst);
+       return fl1h->phy_inst->trx;
+}
 #endif /* _FEMTO_L1_H */
diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c
index d468a71..68a4be8 100644
--- a/src/osmo-bts-sysmo/main.c
+++ b/src/osmo-bts-sysmo/main.c
@@ -86,21 +86,13 @@ void clk_cal_use_eeprom(struct gsm_bts *bts)
 int bts_model_init(struct gsm_bts *bts)
 {
        struct gsm_bts_role_bts *btsb;
-       struct femtol1_hdl *fl1h;
        struct stat st;
-       struct osmo_fd accept_fd, read_fd;
+       static struct osmo_fd accept_fd, read_fd;
        int rc;

        btsb = bts_role_bts(bts);
        btsb->support.ciphers = CIPHER_A5(1) | CIPHER_A5(2) | CIPHER_A5(3);

-       clk_cal_use_eeprom(bts);
-
-       if (stat(SYSMOBTS_RF_LOCK_PATH, &st) == 0) {
-               LOGP(DL1C, LOGL_NOTICE, "Not starting BTS due to RF_LOCK file 
present\n");
-               exit(23);
-       }
-
        rc = oml_router_init(bts, OML_ROUTER_PATH, &accept_fd, &read_fd);
        if (rc < 0) {
                fprintf(stderr, "Error creating the OML router: %s rc=%d\n",
@@ -108,23 +100,12 @@ int bts_model_init(struct gsm_bts *bts)
                exit(1);
        }

-       fl1h = l1if_open(bts->c0);
-       if (!fl1h) {
-               LOGP(DL1C, LOGL_FATAL, "Cannot open L1 Interface\n");
-               return -EIO;
-       }
-       fl1h->dsp_trace_f = dsp_trace;
-
-       bts->c0->role_bts.l1h = fl1h;
+       clk_cal_use_eeprom(bts);

-       rc = sysmobts_get_nominal_power(bts->c0);
-       if (rc < 0) {
-               LOGP(DL1C, LOGL_NOTICE, "Cannot determine nominal "
-                    "transmit power. Assuming 23dBm.\n");
-               rc = 23;
+       if (stat(SYSMOBTS_RF_LOCK_PATH, &st) == 0) {
+               LOGP(DL1C, LOGL_NOTICE, "Not starting BTS due to RF_LOCK file 
present\n");
+               exit(23);
        }
-       bts->c0->nominal_power = rc;
-       bts->c0->power_params.trx_p_max_out_mdBm = to_mdB(rc);

        bts_model_vty_init(bts);

@@ -133,10 +114,6 @@ int bts_model_init(struct gsm_bts *bts)

 int bts_model_oml_estab(struct gsm_bts *bts)
 {
-       struct femtol1_hdl *fl1h = bts->c0->role_bts.l1h;
-
-       l1if_reset(fl1h);
-
        return 0;
 }

@@ -205,6 +182,7 @@ int bts_model_handle_options(int argc, char **argv)
                switch (c) {
                case 'p':
                        dsp_trace = strtoul(optarg, NULL, 16);
+#warning use dsp_trace!!!
                        break;
                case 'M':
                        pcu_direct = 1;
@@ -222,6 +200,14 @@ int bts_model_handle_options(int argc, char **argv)
        return num_errors;
 }

+void bts_model_phy_link_set_defaults(struct phy_link *plink)
+{
+}
+
+void bts_model_phy_instance_set_defaults(struct phy_instance *pinst)
+{
+}
+
 void bts_model_abis_close(struct gsm_bts *bts)
 {
        /* for now, we simply terminate the program and re-spawn */
diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c
index adc0241..cd03b22 100644
--- a/src/osmo-bts-sysmo/oml.c
+++ b/src/osmo-bts-sysmo/oml.c
@@ -36,6 +36,7 @@
 #include <osmo-bts/amr.h>
 #include <osmo-bts/bts.h>
 #include <osmo-bts/bts_model.h>
+#include <osmo-bts/phy_link.h>
 #include <osmo-bts/handover.h>
 #include <osmo-bts/l1sap.h>

diff --git a/src/osmo-bts-sysmo/sysmobts_vty.c 
b/src/osmo-bts-sysmo/sysmobts_vty.c
index 4a37b5d..19122dc 100644
--- a/src/osmo-bts-sysmo/sysmobts_vty.c
+++ b/src/osmo-bts-sysmo/sysmobts_vty.c
@@ -40,6 +40,7 @@
 #include <osmocom/vty/misc.h>

 #include <osmo-bts/gsm_data.h>
+#include <osmo-bts/phy_link.h>
 #include <osmo-bts/logging.h>
 #include <osmo-bts/vty.h>

@@ -84,24 +85,24 @@ DEFUN(cfg_bts_no_auto_band, cfg_bts_no_auto_band_cmd,
        return CMD_SUCCESS;
 }

-DEFUN(cfg_trx_clkcal_eeprom, cfg_trx_clkcal_eeprom_cmd,
+DEFUN(cfg_phy_clkcal_eeprom, cfg_phy_clkcal_eeprom_cmd,
        "clock-calibration eeprom",
        "Use the eeprom clock calibration value\n")
 {
-       struct gsm_bts_trx *trx = vty->index;
-       struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx);
+       struct phy_instance *pinst = vty->index;
+       struct femtol1_hdl *fl1h = pinst->u.sysmobts.hdl;

        fl1h->clk_use_eeprom = 1;

        return CMD_SUCCESS;
 }

-DEFUN(cfg_trx_clkcal_def, cfg_trx_clkcal_def_cmd,
+DEFUN(cfg_phy_clkcal_def, cfg_phy_clkcal_def_cmd,
        "clock-calibration default",
        "Set the clock calibration value\n" "Default Clock DAC value\n")
 {
-       struct gsm_bts_trx *trx = vty->index;
-       struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx);
+       struct phy_instance *pinst = vty->index;
+       struct femtol1_hdl *fl1h = pinst->u.sysmobts.hdl;

        fl1h->clk_use_eeprom = 0;
        fl1h->clk_cal = 0xffff;
@@ -110,13 +111,13 @@ DEFUN(cfg_trx_clkcal_def, cfg_trx_clkcal_def_cmd,
 }

 #ifdef HW_SYSMOBTS_V1
-DEFUN(cfg_trx_clkcal, cfg_trx_clkcal_cmd,
+DEFUN(cfg_phy_clkcal, cfg_phy_clkcal_cmd,
        "clock-calibration <0-4095>",
        "Set the clock calibration value\n" "Clock DAC value\n")
 {
        unsigned int clkcal = atoi(argv[0]);
-       struct gsm_bts_trx *trx = vty->index;
-       struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx);
+       struct phy_instance *pinst = vty->index;
+       struct femtol1_hdl *fl1h = pinst->u.sysmobts.hdl;

        fl1h->clk_use_eeprom = 0;
        fl1h->clk_cal = clkcal & 0xfff;
@@ -124,13 +125,13 @@ DEFUN(cfg_trx_clkcal, cfg_trx_clkcal_cmd,
        return CMD_SUCCESS;
 }
 #else
-DEFUN(cfg_trx_clkcal, cfg_trx_clkcal_cmd,
+DEFUN(cfg_phy_clkcal, cfg_phy_clkcal_cmd,
        "clock-calibration <-4095-4095>",
        "Set the clock calibration value\n" "Offset in PPB\n")
 {
        int clkcal = atoi(argv[0]);
-       struct gsm_bts_trx *trx = vty->index;
-       struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx);
+       struct phy_instance *pinst = vty->index;
+       struct femtol1_hdl *fl1h = pinst->u.sysmobts.hdl;

        fl1h->clk_use_eeprom = 0;
        fl1h->clk_cal = clkcal;
@@ -139,7 +140,7 @@ DEFUN(cfg_trx_clkcal, cfg_trx_clkcal_cmd,
 }
 #endif

-DEFUN(cfg_trx_clksrc, cfg_trx_clksrc_cmd,
+DEFUN(cfg_phy_clksrc, cfg_phy_clksrc_cmd,
        "clock-source (tcxo|ocxo|ext|gps)",
        "Set the clock source value\n"
        "Use the TCXO\n"
@@ -147,8 +148,8 @@ DEFUN(cfg_trx_clksrc, cfg_trx_clksrc_cmd,
        "Use an external clock\n"
        "Use the GPS pps\n")
 {
-       struct gsm_bts_trx *trx = vty->index;
-       struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx);
+       struct phy_instance *pinst = vty->index;
+       struct femtol1_hdl *fl1h = pinst->u.sysmobts.hdl;
        int rc;

        rc = get_string_value(femtobts_clksrc_names, argv[0]);
@@ -160,12 +161,12 @@ DEFUN(cfg_trx_clksrc, cfg_trx_clksrc_cmd,
        return CMD_SUCCESS;
 }

-DEFUN(cfg_trx_cal_path, cfg_trx_cal_path_cmd,
+DEFUN(cfg_phy_cal_path, cfg_phy_cal_path_cmd,
        "trx-calibration-path PATH",
        "Set the path name to TRX calibration data\n" "Path name\n")
 {
-       struct gsm_bts_trx *trx = vty->index;
-       struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx);
+       struct phy_instance *pinst = vty->index;
+       struct femtol1_hdl *fl1h = pinst->u.sysmobts.hdl;

        if (fl1h->calib_path)
                talloc_free(fl1h->calib_path);
@@ -188,26 +189,26 @@ DEFUN_DEPRECATED(cfg_trx_ul_power_target, 
cfg_trx_ul_power_target_cmd,
        return CMD_SUCCESS;
 }

-DEFUN(cfg_trx_min_qual_rach, cfg_trx_min_qual_rach_cmd,
+DEFUN(cfg_phy_min_qual_rach, cfg_phy_min_qual_rach_cmd,
        "min-qual-rach <-100-100>",
        "Set the minimum quality level of RACH burst to be accpeted\n"
        "C/I level in tenth of dB\n")
 {
-       struct gsm_bts_trx *trx = vty->index;
-       struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx);
+       struct phy_instance *pinst = vty->index;
+       struct femtol1_hdl *fl1h = pinst->u.sysmobts.hdl;

        fl1h->min_qual_rach = strtof(argv[0], NULL) / 10.0f;

        return CMD_SUCCESS;
 }

-DEFUN(cfg_trx_min_qual_norm, cfg_trx_min_qual_norm_cmd,
+DEFUN(cfg_phy_min_qual_norm, cfg_phy_min_qual_norm_cmd,
        "min-qual-norm <-100-100>",
        "Set the minimum quality level of normal burst to be accpeted\n"
        "C/I level in tenth of dB\n")
 {
-       struct gsm_bts_trx *trx = vty->index;
-       struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx);
+       struct phy_instance *pinst = vty->index;
+       struct femtol1_hdl *fl1h = pinst->u.sysmobts.hdl;

        fl1h->min_qual_norm = strtof(argv[0], NULL) / 10.0f;

@@ -286,18 +287,24 @@ DEFUN(show_dsp_trace_f, show_dsp_trace_f_cmd,

 DEFUN(dsp_trace_f, dsp_trace_f_cmd, "HIDDEN", TRX_STR)
 {
-       int trx_nr = atoi(argv[0]);
-       struct gsm_bts_trx *trx = gsm_bts_trx_num(vty_bts, trx_nr);
+       int phy_nr = atoi(argv[0]);
+       struct phy_link *plink = phy_link_by_num(phy_nr);
+       struct phy_instance *pinst;
        struct femtol1_hdl *fl1h;
        unsigned int flag ;

-       if (!trx) {
-               vty_out(vty, "Cannot find TRX number %u%s",
-                       trx_nr, VTY_NEWLINE);
+       if (!plink) {
+               vty_out(vty, "Cannot find PHY link number %u%s",
+                       phy_nr, VTY_NEWLINE);
                return CMD_WARNING;
        }
-
-       fl1h = trx_femtol1_hdl(trx);
+       pinst = phy_instance_by_num(plink, 0);
+       if (!pinst) {
+               vty_out(vty, "Cannot find PHY instance number 0%s",
+                       VTY_NEWLINE);
+               return CMD_WARNING;
+       }
+       fl1h = pinst->u.sysmobts.hdl;
        flag = get_string_value(femtobts_tracef_names, argv[1]);
        l1if_set_trace_flags(fl1h, fl1h->dsp_trace_f | flag);

@@ -306,18 +313,24 @@ DEFUN(dsp_trace_f, dsp_trace_f_cmd, "HIDDEN", TRX_STR)

 DEFUN(no_dsp_trace_f, no_dsp_trace_f_cmd, "HIDDEN", NO_STR TRX_STR)
 {
-       int trx_nr = atoi(argv[0]);
-       struct gsm_bts_trx *trx = gsm_bts_trx_num(vty_bts, trx_nr);
+       int phy_nr = atoi(argv[0]);
+       struct phy_link *plink = phy_link_by_num(phy_nr);
+       struct phy_instance *pinst;
        struct femtol1_hdl *fl1h;
        unsigned int flag ;

-       if (!trx) {
-               vty_out(vty, "Cannot find TRX number %u%s",
-                       trx_nr, VTY_NEWLINE);
+       if (!plink) {
+               vty_out(vty, "Cannot find PHY link number %u%s",
+                       phy_nr, VTY_NEWLINE);
                return CMD_WARNING;
        }
-
-       fl1h = trx_femtol1_hdl(trx);
+       pinst = phy_instance_by_num(plink, 0);
+       if (!pinst) {
+               vty_out(vty, "Cannot find PHY instance number 0%s",
+                       VTY_NEWLINE);
+               return CMD_WARNING;
+       }
+       fl1h = pinst->u.sysmobts.hdl;
        flag = get_string_value(femtobts_tracef_names, argv[1]);
        l1if_set_trace_flags(fl1h, fl1h->dsp_trace_f & ~flag);

@@ -325,20 +338,28 @@ DEFUN(no_dsp_trace_f, no_dsp_trace_f_cmd, "HIDDEN", 
NO_STR TRX_STR)
 }

 DEFUN(show_sys_info, show_sys_info_cmd,
-       "show trx <0-0> system-information",
+       "show phy <0-255> instance <0-255> system-information",
        SHOW_TRX_STR "Display information about system\n")
 {
-       int trx_nr = atoi(argv[0]);
-       struct gsm_bts_trx *trx = gsm_bts_trx_num(vty_bts, trx_nr);
+       int phy_nr = atoi(argv[0]);
+       int inst_nr = atoi(argv[1]);
+       struct phy_link *plink = phy_link_by_num(phy_nr);
+       struct phy_instance *pinst;
        struct femtol1_hdl *fl1h;
        int i;

-       if (!trx) {
-               vty_out(vty, "Cannot find TRX number %u%s",
-                       trx_nr, VTY_NEWLINE);
+       if (!plink) {
+               vty_out(vty, "Cannot find PHY link %u%s",
+                       phy_nr, VTY_NEWLINE);
                return CMD_WARNING;
        }
-       fl1h = trx_femtol1_hdl(trx);
+       pinst = phy_instance_by_num(plink, inst_nr);
+       if (!plink) {
+               vty_out(vty, "Cannot find PHY instance %u%s",
+                       phy_nr, VTY_NEWLINE);
+               return CMD_WARNING;
+       }
+       fl1h = pinst->u.sysmobts.hdl;

        vty_out(vty, "DSP Version: %u.%u.%u, FPGA Version: %u.%u.%u%s",
                fl1h->hw_info.dsp_version[0],
@@ -471,7 +492,14 @@ void bts_model_config_write_bts(struct vty *vty, struct 
gsm_bts *bts)

 void bts_model_config_write_trx(struct vty *vty, struct gsm_bts_trx *trx)
 {
-       struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx);
+       if (trx->nominal_power != sysmobts_get_nominal_power(trx))
+               vty_out(vty, "  nominal-tx-power %d%s", trx->nominal_power,
+                       VTY_NEWLINE);
+}
+
+static void write_phy_inst(struct vty *vty, struct phy_instance *pinst)
+{
+       struct femtol1_hdl *fl1h = pinst->u.sysmobts.hdl;

        if (fl1h->clk_use_eeprom)
                vty_out(vty, "  clock-calibration eeprom%s", VTY_NEWLINE);
@@ -488,9 +516,14 @@ void bts_model_config_write_trx(struct vty *vty, struct 
gsm_bts_trx *trx)
                VTY_NEWLINE);
        vty_out(vty, "  min-qual-norm %.0f%s", fl1h->min_qual_norm * 10.0f,
                VTY_NEWLINE);
-       if (trx->nominal_power != sysmobts_get_nominal_power(trx))
-               vty_out(vty, "  nominal-tx-power %d%s", trx->nominal_power,
-                       VTY_NEWLINE);
+}
+
+void bts_model_config_write_phy(struct vty *vty, struct phy_link *plink)
+{
+       struct phy_instance *pinst;
+
+       llist_for_each_entry(pinst, &plink->instances, list)
+               write_phy_inst(vty, pinst);
 }

 int bts_model_vty_init(struct gsm_bts *bts)
@@ -529,15 +562,16 @@ int bts_model_vty_init(struct gsm_bts *bts)
        install_element(BTS_NODE, &cfg_bts_auto_band_cmd);
        install_element(BTS_NODE, &cfg_bts_no_auto_band_cmd);

-       install_element(TRX_NODE, &cfg_trx_clkcal_cmd);
-       install_element(TRX_NODE, &cfg_trx_clkcal_eeprom_cmd);
-       install_element(TRX_NODE, &cfg_trx_clkcal_def_cmd);
-       install_element(TRX_NODE, &cfg_trx_clksrc_cmd);
-       install_element(TRX_NODE, &cfg_trx_cal_path_cmd);
        install_element(TRX_NODE, &cfg_trx_ul_power_target_cmd);
-       install_element(TRX_NODE, &cfg_trx_min_qual_rach_cmd);
-       install_element(TRX_NODE, &cfg_trx_min_qual_norm_cmd);
        install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);

+       install_element(PHY_INST_NODE, &cfg_phy_clkcal_cmd);
+       install_element(PHY_INST_NODE, &cfg_phy_clkcal_eeprom_cmd);
+       install_element(PHY_INST_NODE, &cfg_phy_clkcal_def_cmd);
+       install_element(PHY_INST_NODE, &cfg_phy_clksrc_cmd);
+       install_element(PHY_INST_NODE, &cfg_phy_cal_path_cmd);
+       install_element(PHY_INST_NODE, &cfg_phy_min_qual_rach_cmd);
+       install_element(PHY_INST_NODE, &cfg_phy_min_qual_norm_cmd);
+
        return 0;
 }
diff --git a/tests/sysmobts/sysmobts_test.c b/tests/sysmobts/sysmobts_test.c
index b835dc2..6ae7623 100644
--- a/tests/sysmobts/sysmobts_test.c
+++ b/tests/sysmobts/sysmobts_test.c
@@ -265,3 +265,7 @@ int bts_model_oml_estab(struct gsm_bts *bts)
 { return 0; }
 void bts_model_abis_close(struct gsm_bts *bts)
 { }
+void bts_model_phy_link_set_defaults(struct phy_link *plink)
+{ }
+void bts_model_phy_instance_set_defaults(struct phy_instance *pinst)
+{ }
-- 
2.7.0

Reply via email to