<p>rafael2k has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bts/+/17808">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">osmo-bts-litecell15: Implement missing features.<br><br>Many hardware parameters of the LC 1.5 were not exposed to the user.<br>This patchset introduces most of the features, being very similar<br>to osmo-bts-oc2g code.<br><br>Change-Id: Id41bba798440b00a3b11441b64b2e8094a946bf2<br>---<br>M include/osmo-bts/phy_link.h<br>M src/osmo-bts-litecell15/l1_if.c<br>M src/osmo-bts-litecell15/l1_if.h<br>M src/osmo-bts-litecell15/lc15bts.c<br>M src/osmo-bts-litecell15/lc15bts.h<br>M src/osmo-bts-litecell15/lc15bts_vty.c<br>M src/osmo-bts-litecell15/main.c<br>M src/osmo-bts-litecell15/oml.c<br>8 files changed, 530 insertions(+), 10 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/08/17808/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmo-bts/phy_link.h b/include/osmo-bts/phy_link.h</span><br><span>index 116297b..cf877bd 100644</span><br><span>--- a/include/osmo-bts/phy_link.h</span><br><span>+++ b/include/osmo-bts/phy_link.h</span><br><span>@@ -135,6 +135,7 @@</span><br><span>                  uint8_t dsp_alive_period;       /* DSP alive timer period  */</span><br><span>                        uint8_t tx_pwr_adj_mode;        /* 0: no auto adjust power, 1: auto adjust power using RMS detector */</span><br><span>                       uint8_t tx_pwr_red_8psk;        /* 8-PSK maximum Tx power reduction level in dB */</span><br><span style="color: hsl(120, 100%, 40%);">+                    uint8_t tx_c0_idle_pwr_red;     /* C0 idle slot Tx power reduction level in dB */</span><br><span>            } lc15;</span><br><span>                 struct {</span><br><span>                         /* configuration */</span><br><span>diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c</span><br><span>index abf48bc..0b289fc 100644</span><br><span>--- a/src/osmo-bts-litecell15/l1_if.c</span><br><span>+++ b/src/osmo-bts-litecell15/l1_if.c</span><br><span>@@ -1263,8 +1263,10 @@</span><br><span>                         LOGP(DL1C, LOGL_FATAL, "RF-ACT.conf with status %s\n",</span><br><span>                             get_value_string(lc15bts_l1status_names, status));</span><br><span>                   bts_shutdown(trx->bts, "RF-ACT failure");</span><br><span style="color: hsl(0, 100%, 40%);">-          } else</span><br><span style="color: hsl(0, 100%, 40%);">-                  bts_update_status(BTS_STATUS_RF_ACTIVE, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+           } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      if(trx->bts->lc15.led_ctrl_mode == LC15_LED_CONTROL_BTS)</span><br><span style="color: hsl(120, 100%, 40%);">+                                bts_update_status(BTS_STATUS_RF_ACTIVE, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span> </span><br><span>            /* signal availability */</span><br><span>            oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OK);</span><br><span>@@ -1275,7 +1277,8 @@</span><br><span>               for (i = 0; i < ARRAY_SIZE(trx->ts); i++)</span><br><span>                      oml_mo_state_chg(&trx->ts[i].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY);</span><br><span>         } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                bts_update_status(BTS_STATUS_RF_ACTIVE, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+           if(trx->bts->lc15.led_ctrl_mode == LC15_LED_CONTROL_BTS)</span><br><span style="color: hsl(120, 100%, 40%);">+                        bts_update_status(BTS_STATUS_RF_ACTIVE, 0);</span><br><span>          oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);</span><br><span>                 oml_mo_state_chg(&trx->bb_transc.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);</span><br><span>       }</span><br><span>@@ -1290,17 +1293,26 @@</span><br><span> {</span><br><span>     struct msgb *msg = sysp_msgb_alloc();</span><br><span>        Litecell15_Prim_t *sysp = msgb_sysprim(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+  struct phy_instance *pinst = hdl->phy_inst;</span><br><span> </span><br><span>   if (on) {</span><br><span>            sysp->id = Litecell15_PrimId_ActivateRfReq;</span><br><span>               sysp->u.activateRfReq.msgq.u8UseTchMsgq = 0;</span><br><span>              sysp->u.activateRfReq.msgq.u8UsePdtchMsgq = pcu_direct;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-          sysp->u.activateRfReq.u8UnusedTsMode = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+          sysp->u.activateRfReq.u8UnusedTsMode = pinst->u.lc15.pedestal_mode;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>          sysp->u.activateRfReq.u8McCorrMode = 0;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+                /* diversity mode: 0: SISO-A, 1: SISO-B, 2: MRC */</span><br><span style="color: hsl(120, 100%, 40%);">+            sysp->u.activateRfReq.u8DiversityMode = pinst->u.lc15.diversity_mode;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>                /* maximum cell size in quarter-bits, 90 == 12.456 km */</span><br><span style="color: hsl(0, 100%, 40%);">-                sysp->u.activateRfReq.u8MaxCellSize = 90;</span><br><span style="color: hsl(120, 100%, 40%);">+          sysp->u.activateRfReq.u8MaxCellSize = pinst->u.lc15.max_cell_size;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            /* auto tx power adjustment mode 0:none, 1: automatic*/</span><br><span style="color: hsl(120, 100%, 40%);">+               sysp->u.activateRfReq.u8EnAutoPowerAdjust = pinst->u.lc15.tx_pwr_adj_mode;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   } else {</span><br><span>             sysp->id = Litecell15_PrimId_DeactivateRfReq;</span><br><span>     }</span><br><span>@@ -1589,6 +1601,54 @@</span><br><span>   return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void dsp_alive_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void *data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ Litecell15_Prim_t *sysp = msgb_sysprim(resp);</span><br><span style="color: hsl(120, 100%, 40%);">+ Litecell15_IsAliveCnf_t *sac = &sysp->u.isAliveCnf;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(trx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      fl1h->hw_alive.dsp_alive_cnt++;</span><br><span style="color: hsl(120, 100%, 40%);">+    LOGP(DL1C, LOGL_DEBUG, "Rx SYS prim %s, status=%d (%d)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                  get_value_string(lc15bts_sysprim_names, sysp->id), sac->status, trx->nr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  msgb_free(resp);</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%);">+static int dsp_alive_timer_cb(void *data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct lc15l1_hdl *fl1h = data;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gsm_bts_trx *trx = fl1h->phy_inst->trx;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct msgb *msg = sysp_msgb_alloc();</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     Litecell15_Prim_t *sys_prim =  msgb_sysprim(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+     sys_prim->id = Litecell15_PrimId_IsAliveReq;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (fl1h->hw_alive.dsp_alive_cnt == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGP(DL1C, LOGL_ERROR, "Timeout waiting for SYS prim %s primitive (%d)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                          get_value_string(lc15bts_sysprim_names, sys_prim->id + 1), trx->nr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          if( fl1h->phy_inst->trx ){</span><br><span style="color: hsl(120, 100%, 40%);">+                      fl1h->phy_inst->trx->mo.obj_inst.trx_nr = fl1h->phy_inst->trx->nr;</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   LOGP(DL1C, LOGL_DEBUG, "Tx SYS prim %s (%d)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                     get_value_string(lc15bts_sysprim_names, sys_prim->id), trx->nr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      rc = l1if_req_compl(fl1h, msg, dsp_alive_compl_cb, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DL1C, LOGL_FATAL, "Failed to send %s primitive\n", get_value_string(lc15bts_sysprim_names, sys_prim->id));</span><br><span style="color: hsl(120, 100%, 40%);">+          return -EIO;</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%);">+   /* restart timer */</span><br><span style="color: hsl(120, 100%, 40%);">+   fl1h->hw_alive.dsp_alive_cnt = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_timer_schedule(&fl1h->hw_alive.dsp_alive_timer, fl1h->hw_alive.dsp_alive_period, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int bts_model_phy_link_open(struct phy_link *plink)</span><br><span> {</span><br><span>   struct phy_instance *pinst = phy_instance_by_num(plink, 0);</span><br><span>@@ -1608,6 +1668,27 @@</span><br><span>                 return -EIO;</span><br><span>         }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* Set default PHY parameters */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!pinst->u.lc15.max_cell_size)</span><br><span style="color: hsl(120, 100%, 40%);">+          pinst->u.lc15.max_cell_size = LC15_BTS_MAX_CELL_SIZE_DEFAULT;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!pinst->u.lc15.diversity_mode)</span><br><span style="color: hsl(120, 100%, 40%);">+         pinst->u.lc15.diversity_mode = LC15_BTS_DIVERSITY_MODE_DEFAULT;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!pinst->u.lc15.pedestal_mode)</span><br><span style="color: hsl(120, 100%, 40%);">+          pinst->u.lc15.pedestal_mode = LC15_BTS_PEDESTAL_MODE_DEFAULT;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!pinst->u.lc15.dsp_alive_period)</span><br><span style="color: hsl(120, 100%, 40%);">+               pinst->u.lc15.dsp_alive_period = LC15_BTS_DSP_ALIVE_TMR_DEFAULT;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!pinst->u.lc15.tx_pwr_adj_mode)</span><br><span style="color: hsl(120, 100%, 40%);">+                pinst->u.lc15.tx_pwr_adj_mode = LC15_BTS_TX_PWR_ADJ_DEFAULT;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!pinst->u.lc15.tx_pwr_red_8psk)</span><br><span style="color: hsl(120, 100%, 40%);">+                pinst->u.lc15.tx_pwr_red_8psk = LC15_BTS_TX_RED_PWR_8PSK_DEFAULT;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!pinst->u.lc15.tx_c0_idle_pwr_red)</span><br><span style="color: hsl(120, 100%, 40%);">+             pinst->u.lc15.tx_c0_idle_pwr_red = LC15_BTS_TX_C0_IDLE_RED_PWR_DEFAULT;</span><br><span> </span><br><span>       struct lc15l1_hdl *fl1h = pinst->u.lc15.hdl;</span><br><span>      fl1h->dsp_trace_f = dsp_trace;</span><br><span>@@ -1616,5 +1697,25 @@</span><br><span> </span><br><span>       phy_link_state_set(plink, PHY_LINK_CONNECTED);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+    /* Send first IS_ALIVE primitive */</span><br><span style="color: hsl(120, 100%, 40%);">+   struct msgb *msg = sysp_msgb_alloc();</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     Litecell15_Prim_t *sys_prim =  msgb_sysprim(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+     sys_prim->id = Litecell15_PrimId_IsAliveReq;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = l1if_req_compl(fl1h, msg, dsp_alive_compl_cb, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DL1C, LOGL_FATAL, "Failed to send %s primitive\n", get_value_string(lc15bts_sysprim_names, sys_prim->id));</span><br><span style="color: hsl(120, 100%, 40%);">+          return -EIO;</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%);">+   /* initialize DSP heart beat alive timer */</span><br><span style="color: hsl(120, 100%, 40%);">+   fl1h->hw_alive.dsp_alive_timer.cb = dsp_alive_timer_cb;</span><br><span style="color: hsl(120, 100%, 40%);">+    fl1h->hw_alive.dsp_alive_timer.data = fl1h;</span><br><span style="color: hsl(120, 100%, 40%);">+        fl1h->hw_alive.dsp_alive_cnt = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  fl1h->hw_alive.dsp_alive_period = pinst->u.lc15.dsp_alive_period;</span><br><span style="color: hsl(120, 100%, 40%);">+       osmo_timer_schedule(&fl1h->hw_alive.dsp_alive_timer, fl1h->hw_alive.dsp_alive_period, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>        return 0;</span><br><span> }</span><br><span>diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h</span><br><span>index aac2607..45f0ddd 100644</span><br><span>--- a/src/osmo-bts-litecell15/l1_if.h</span><br><span>+++ b/src/osmo-bts-litecell15/l1_if.h</span><br><span>@@ -30,6 +30,12 @@</span><br><span>         _NUM_MQ_WRITE</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* gsm_bts->model_priv, specific to Litecell 1.5 BTS */</span><br><span style="color: hsl(120, 100%, 40%);">+struct bts_lc15_priv {</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t led_ctrl_mode;                  /* 0: control by BTS, 1: not control by BTS */</span><br><span style="color: hsl(120, 100%, 40%);">+        unsigned int rtp_drift_thres_ms;        /* RTP timestamp drift detection threshold */</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> struct calib_send_state {</span><br><span>     FILE *fp;</span><br><span>    const char *path;</span><br><span>@@ -62,6 +68,12 @@</span><br><span>       struct calib_send_state st;</span><br><span> </span><br><span>      uint8_t last_rf_mute[8];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    struct {</span><br><span style="color: hsl(120, 100%, 40%);">+              struct osmo_timer_list dsp_alive_timer;</span><br><span style="color: hsl(120, 100%, 40%);">+               unsigned int dsp_alive_cnt;</span><br><span style="color: hsl(120, 100%, 40%);">+           uint8_t dsp_alive_period;</span><br><span style="color: hsl(120, 100%, 40%);">+     } hw_alive;</span><br><span> };</span><br><span> </span><br><span> #define msgb_l1prim(msg)       ((GsmL1_Prim_t *)(msg)->l1h)</span><br><span>diff --git a/src/osmo-bts-litecell15/lc15bts.c b/src/osmo-bts-litecell15/lc15bts.c</span><br><span>index 172a7e4..8ebc3a2 100644</span><br><span>--- a/src/osmo-bts-litecell15/lc15bts.c</span><br><span>+++ b/src/osmo-bts-litecell15/lc15bts.c</span><br><span>@@ -121,6 +121,12 @@</span><br><span>      case Litecell15_PrimId_MuteRfCnf:        return L1P_T_CONF;</span><br><span>  case Litecell15_PrimId_SetRxAttenReq:    return L1P_T_REQ;</span><br><span>   case Litecell15_PrimId_SetRxAttenCnf:    return L1P_T_CONF;</span><br><span style="color: hsl(120, 100%, 40%);">+   case Litecell15_PrimId_IsAliveReq:       return L1P_T_REQ;</span><br><span style="color: hsl(120, 100%, 40%);">+    case Litecell15_PrimId_IsAliveCnf:       return L1P_T_CONF;</span><br><span style="color: hsl(120, 100%, 40%);">+   case Litecell15_PrimId_SetMaxCellSizeReq:       return L1P_T_REQ;</span><br><span style="color: hsl(120, 100%, 40%);">+     case Litecell15_PrimId_SetMaxCellSizeCnf:       return L1P_T_CONF;</span><br><span style="color: hsl(120, 100%, 40%);">+    case Litecell15_PrimId_SetC0IdleSlotPowerReductionReq:       return L1P_T_REQ;</span><br><span style="color: hsl(120, 100%, 40%);">+        case Litecell15_PrimId_SetC0IdleSlotPowerReductionCnf:       return L1P_T_CONF;</span><br><span>      default:                                 return L1P_T_INVALID;</span><br><span>       }</span><br><span> }</span><br><span>@@ -142,6 +148,12 @@</span><br><span>        { Litecell15_PrimId_MuteRfCnf,          "MUTE-RF.cnf" },</span><br><span>   { Litecell15_PrimId_SetRxAttenReq,      "SET-RX-ATTEN.req" },</span><br><span>      { Litecell15_PrimId_SetRxAttenCnf,      "SET-RX-ATTEN-CNF.cnf" },</span><br><span style="color: hsl(120, 100%, 40%);">+   { Litecell15_PrimId_IsAliveReq,         "IS-ALIVE.req" },</span><br><span style="color: hsl(120, 100%, 40%);">+   { Litecell15_PrimId_IsAliveCnf,         "IS-ALIVE-CNF.cnf" },</span><br><span style="color: hsl(120, 100%, 40%);">+       { Litecell15_PrimId_SetMaxCellSizeReq,         "SET-MAX-CELL-SIZE.req" },</span><br><span style="color: hsl(120, 100%, 40%);">+   { Litecell15_PrimId_SetMaxCellSizeCnf,         "SET-MAX-CELL-SIZE.cnf" },</span><br><span style="color: hsl(120, 100%, 40%);">+   { Litecell15_PrimId_SetC0IdleSlotPowerReductionReq,         "SET-C0-IDLE-PWR-RED.req" },</span><br><span style="color: hsl(120, 100%, 40%);">+    { Litecell15_PrimId_SetC0IdleSlotPowerReductionCnf,         "SET-C0-IDLE-PWR-RED.cnf" },</span><br><span>   { 0, NULL }</span><br><span> };</span><br><span> </span><br><span>@@ -155,6 +167,9 @@</span><br><span>  case Litecell15_PrimId_SetCalibTblReq:   return Litecell15_PrimId_SetCalibTblCnf;</span><br><span>    case Litecell15_PrimId_MuteRfReq:        return Litecell15_PrimId_MuteRfCnf;</span><br><span>         case Litecell15_PrimId_SetRxAttenReq:    return Litecell15_PrimId_SetRxAttenCnf;</span><br><span style="color: hsl(120, 100%, 40%);">+      case Litecell15_PrimId_IsAliveReq:       return Litecell15_PrimId_IsAliveCnf;</span><br><span style="color: hsl(120, 100%, 40%);">+ case Litecell15_PrimId_SetMaxCellSizeReq:       return Litecell15_PrimId_SetMaxCellSizeCnf;</span><br><span style="color: hsl(120, 100%, 40%);">+   case Litecell15_PrimId_SetC0IdleSlotPowerReductionReq:       return Litecell15_PrimId_SetC0IdleSlotPowerReductionCnf;</span><br><span>         default:                                 return -1;    // Weak</span><br><span>         }</span><br><span> }</span><br><span>diff --git a/src/osmo-bts-litecell15/lc15bts.h b/src/osmo-bts-litecell15/lc15bts.h</span><br><span>index 4c40db0..6360826 100644</span><br><span>--- a/src/osmo-bts-litecell15/lc15bts.h</span><br><span>+++ b/src/osmo-bts-litecell15/lc15bts.h</span><br><span>@@ -22,6 +22,28 @@</span><br><span>      L1P_T_IND,</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum lc15_diversity_mode{</span><br><span style="color: hsl(120, 100%, 40%);">+     LC15_DIVERSITY_SISO_A = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+    LC15_DIVERSITY_SISO_B,</span><br><span style="color: hsl(120, 100%, 40%);">+        LC15_DIVERSITY_MRC,</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%);">+enum lc15_pedestal_mode{</span><br><span style="color: hsl(120, 100%, 40%);">+   LC15_PEDESTAL_OFF = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+        LC15_PEDESTAL_ON,</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%);">+enum lc15_led_control_mode{</span><br><span style="color: hsl(120, 100%, 40%);">+  LC15_LED_CONTROL_BTS = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+     LC15_LED_CONTROL_EXT,</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%);">+enum lc15_auto_pwr_adjust_mode{</span><br><span style="color: hsl(120, 100%, 40%);">+  LC15_TX_PWR_ADJ_NONE = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+     LC15_TX_PWR_ADJ_AUTO,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> enum l1prim_type lc15bts_get_l1prim_type(GsmL1_PrimId_t id);</span><br><span> const struct value_string lc15bts_l1prim_names[GsmL1_PrimId_NUM+1];</span><br><span> GsmL1_PrimId_t lc15bts_get_l1prim_conf(GsmL1_PrimId_t id);</span><br><span>@@ -61,4 +83,15 @@</span><br><span> </span><br><span> const uint8_t pdch_msu_size[_NUM_PDCH_CS];</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* LC15 default parameters */</span><br><span style="color: hsl(120, 100%, 40%);">+#define LC15_BTS_MAX_CELL_SIZE_DEFAULT      166     /* 166 qbits is default  value */</span><br><span style="color: hsl(120, 100%, 40%);">+#define LC15_BTS_DIVERSITY_MODE_DEFAULT      0       /* SISO-A is default mode */</span><br><span style="color: hsl(120, 100%, 40%);">+#define LC15_BTS_PEDESTAL_MODE_DEFAULT    0       /* Unused TS is off by default */</span><br><span style="color: hsl(120, 100%, 40%);">+#define LC15_BTS_LED_CTRL_MODE_DEFAULT       0       /* LED is controlled by BTS by default */</span><br><span style="color: hsl(120, 100%, 40%);">+#define LC15_BTS_DSP_ALIVE_TMR_DEFAULT       5       /* Default DSP alive timer is 5 seconds  */</span><br><span style="color: hsl(120, 100%, 40%);">+#define LC15_BTS_TX_PWR_ADJ_DEFAULT        0       /* Default Tx power auto adjustment is none */</span><br><span style="color: hsl(120, 100%, 40%);">+#define LC15_BTS_TX_RED_PWR_8PSK_DEFAULT        0       /* Default 8-PSK maximum power level is 0 dB */</span><br><span style="color: hsl(120, 100%, 40%);">+#define LC15_BTS_RTP_DRIFT_THRES_DEFAULT       0       /* Default RTP drift threshold is 0 ms (disabled) */</span><br><span style="color: hsl(120, 100%, 40%);">+#define LC15_BTS_TX_C0_IDLE_RED_PWR_DEFAULT       0       /* Default C0 idle slot reduction power level is 0 dB */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #endif /* LC15BTS_H */</span><br><span>diff --git a/src/osmo-bts-litecell15/lc15bts_vty.c b/src/osmo-bts-litecell15/lc15bts_vty.c</span><br><span>index d27ec28..e895ab8 100644</span><br><span>--- a/src/osmo-bts-litecell15/lc15bts_vty.c</span><br><span>+++ b/src/osmo-bts-litecell15/lc15bts_vty.c</span><br><span>@@ -43,6 +43,11 @@</span><br><span> #include <osmocom/vty/command.h></span><br><span> #include <osmocom/vty/misc.h></span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/ctrl/control_cmd.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmo-bts/signal.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmo-bts/oml.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmo-bts/bts.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #include <osmo-bts/gsm_data.h></span><br><span> #include <osmo-bts/phy_link.h></span><br><span> #include <osmo-bts/logging.h></span><br><span>@@ -55,6 +60,7 @@</span><br><span> #include "utils.h"</span><br><span> </span><br><span> extern int lchan_activate(struct gsm_lchan *lchan);</span><br><span style="color: hsl(120, 100%, 40%);">+extern int rsl_tx_preproc_meas_res(struct gsm_lchan *lchan);</span><br><span> </span><br><span> #define TRX_STR "Transceiver related commands\n" "TRX number\n"</span><br><span> </span><br><span>@@ -65,6 +71,31 @@</span><br><span> </span><br><span> static struct gsm_bts *vty_bts;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static const struct value_string lc15_diversity_mode_strs[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+      { LC15_DIVERSITY_SISO_A, "siso-a" },</span><br><span style="color: hsl(120, 100%, 40%);">+        { LC15_DIVERSITY_SISO_B, "siso-b" },</span><br><span style="color: hsl(120, 100%, 40%);">+        { LC15_DIVERSITY_MRC, "mrc" },</span><br><span style="color: hsl(120, 100%, 40%);">+      { 0, NULL }</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%);">+static const struct value_string lc15_pedestal_mode_strs[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+     { LC15_PEDESTAL_OFF, "off" },</span><br><span style="color: hsl(120, 100%, 40%);">+       { LC15_PEDESTAL_ON, "on" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0, NULL }</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%);">+static const struct value_string lc15_led_mode_strs[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+  { LC15_LED_CONTROL_BTS, "bts" },</span><br><span style="color: hsl(120, 100%, 40%);">+    { LC15_LED_CONTROL_EXT, "external" },</span><br><span style="color: hsl(120, 100%, 40%);">+       { 0, NULL }</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%);">+static const struct value_string lc15_auto_adj_pwr_strs[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+      { LC15_TX_PWR_ADJ_NONE, "none" },</span><br><span style="color: hsl(120, 100%, 40%);">+   { LC15_TX_PWR_ADJ_AUTO, "auto" },</span><br><span style="color: hsl(120, 100%, 40%);">+   { 0, NULL }</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* configuration */</span><br><span> </span><br><span> DEFUN(cfg_phy_cal_path, cfg_phy_cal_path_cmd,</span><br><span>@@ -321,8 +352,164 @@</span><br><span>        return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(cfg_phy_max_cell_size, cfg_phy_max_cell_size_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+       "max-cell-size <0-166>",</span><br><span style="color: hsl(120, 100%, 40%);">+       "Set the maximum cell size  in qbits\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  struct phy_instance *pinst = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+   int cell_size = (uint8_t)atoi(argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (( cell_size >  166 ) || ( cell_size < 0 )) {</span><br><span style="color: hsl(120, 100%, 40%);">+                vty_out(vty, "Max cell size must be between 0 and 166 qbits (%d) %s",</span><br><span style="color: hsl(120, 100%, 40%);">+                               cell_size, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+              return CMD_WARNING;</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%);">+      pinst->u.lc15.max_cell_size = (uint8_t)cell_size;</span><br><span style="color: hsl(120, 100%, 40%);">+  return CMD_SUCCESS;</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%);">+DEFUN(cfg_phy_diversity_mode, cfg_phy_diversity_mode_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+           "diversity-mode (siso-a|siso-b|mrc)",</span><br><span style="color: hsl(120, 100%, 40%);">+               "Set reception diversity mode \n"</span><br><span style="color: hsl(120, 100%, 40%);">+           "Reception diversity mode can be (siso-a, siso-b, mrc)\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct phy_instance *pinst = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+   int val = get_string_value(lc15_diversity_mode_strs, argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if((val < LC15_DIVERSITY_SISO_A) || (val > LC15_DIVERSITY_MRC)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       vty_out(vty, "Invalid reception diversity mode %d%s", val, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+                    return CMD_WARNING;</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%);">+   pinst->u.lc15.diversity_mode = (uint8_t)val;</span><br><span style="color: hsl(120, 100%, 40%);">+       return CMD_SUCCESS;</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%);">+DEFUN(cfg_phy_pedestal_mode, cfg_phy_pedestal_mode_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+             "pedestal-mode (on|off)",</span><br><span style="color: hsl(120, 100%, 40%);">+           "Set unused time-slot transmission in pedestal mode\n"</span><br><span style="color: hsl(120, 100%, 40%);">+              "Transmission pedestal mode can be (off, on)\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct phy_instance *pinst = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+   int val = get_string_value(lc15_pedestal_mode_strs, argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if((val < LC15_PEDESTAL_OFF)  || (val > LC15_PEDESTAL_ON)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    vty_out(vty, "Invalid unused time-slot transmission mode %d%s", val, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+                  return CMD_WARNING;</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%);">+   pinst->u.lc15.pedestal_mode = (uint8_t)val;</span><br><span style="color: hsl(120, 100%, 40%);">+        return CMD_SUCCESS;</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%);">+DEFUN(cfg_bts_led_mode, cfg_bts_led_mode_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+               "led-control-mode (bts|external)",</span><br><span style="color: hsl(120, 100%, 40%);">+          "Set LED controlled by BTS or external software\n"</span><br><span style="color: hsl(120, 100%, 40%);">+          "LED can be controlled by (bts, external)\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gsm_bts *bts = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+  int val = get_string_value(lc15_led_mode_strs, argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if((val < LC15_LED_CONTROL_BTS)  || (val > LC15_LED_CONTROL_EXT)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     vty_out(vty, "Invalid LED control mode %d%s", val, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+                    return CMD_WARNING;</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%);">+        struct bts_lc15_priv *bts_lc15 = bts->model_priv;</span><br><span style="color: hsl(120, 100%, 40%);">+     bts_lc15->led_ctrl_mode = (uint8_t)val;</span><br><span style="color: hsl(120, 100%, 40%);">+    return CMD_SUCCESS;</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%);">+DEFUN(cfg_phy_dsp_alive_timer, cfg_phy_dsp_alive_timer_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "dsp-alive-period <0-60>",</span><br><span style="color: hsl(120, 100%, 40%);">+    "Set DSP alive timer period in second\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct phy_instance *pinst = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t period = (uint8_t)atoi(argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (( period >  60 ) || ( period < 0 )) {</span><br><span style="color: hsl(120, 100%, 40%);">+               vty_out(vty, "DSP heart beat alive timer period must be between 0 and 60 seconds (%d) %s",</span><br><span style="color: hsl(120, 100%, 40%);">+                          period, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+         return CMD_WARNING;</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%);">+   pinst->u.lc15.dsp_alive_period = period;</span><br><span style="color: hsl(120, 100%, 40%);">+   return CMD_SUCCESS;</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%);">+DEFUN(cfg_phy_auto_tx_pwr_adj, cfg_phy_auto_tx_pwr_adj_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "pwr-adj-mode (none|auto)",</span><br><span style="color: hsl(120, 100%, 40%);">+ "Set output power adjustment mode\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    struct phy_instance *pinst = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+   int val = get_string_value(lc15_auto_adj_pwr_strs, argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if((val < LC15_TX_PWR_ADJ_NONE) || (val > LC15_TX_PWR_ADJ_AUTO)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              vty_out(vty, "Invalid output power adjustment mode %d%s", val, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+        return CMD_WARNING;</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%);">+   pinst->u.lc15.tx_pwr_adj_mode = (uint8_t)val;</span><br><span style="color: hsl(120, 100%, 40%);">+      return CMD_SUCCESS;</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%);">+DEFUN(cfg_phy_tx_red_pwr_8psk, cfg_phy_tx_red_pwr_8psk_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "tx-red-pwr-8psk <0-40>",</span><br><span style="color: hsl(120, 100%, 40%);">+     "Set reduction output power for 8-PSK scheme in dB unit\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct phy_instance *pinst = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+   int val = atoi(argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if ((val > 40) || (val < 0)) {</span><br><span style="color: hsl(120, 100%, 40%);">+          vty_out(vty, "Reduction Tx power level must be between 0 and 40 dB (%d) %s",</span><br><span style="color: hsl(120, 100%, 40%);">+                val, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+            return CMD_WARNING;</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%);">+   pinst->u.lc15.tx_pwr_red_8psk = (uint8_t)val;</span><br><span style="color: hsl(120, 100%, 40%);">+      return CMD_SUCCESS;</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%);">+DEFUN(cfg_phy_c0_idle_red_pwr, cfg_phy_c0_idle_red_pwr_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "c0-idle-red-pwr <0-40>",</span><br><span style="color: hsl(120, 100%, 40%);">+     "Set reduction output power for C0 idle slot in dB unit\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct phy_instance *pinst = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+   int val = atoi(argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if ((val > 40) || (val < 0)) {</span><br><span style="color: hsl(120, 100%, 40%);">+          vty_out(vty, "Reduction Tx power level must be between 0 and 40 dB (%d) %s",</span><br><span style="color: hsl(120, 100%, 40%);">+                val, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+            return CMD_WARNING;</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%);">+   pinst->u.lc15.tx_c0_idle_pwr_red = (uint8_t)val;</span><br><span style="color: hsl(120, 100%, 40%);">+   return CMD_SUCCESS;</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%);">+DEFUN(cfg_bts_rtp_drift_threshold, cfg_bts_rtp_drift_threshold_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "rtp-drift-threshold <0-10000>",</span><br><span style="color: hsl(120, 100%, 40%);">+      "RTP parameters\n"</span><br><span style="color: hsl(120, 100%, 40%);">+  "RTP timestamp drift threshold in ms\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_bts *bts = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        struct bts_lc15_priv *bts_lc15 = bts->model_priv;</span><br><span style="color: hsl(120, 100%, 40%);">+  bts_lc15->rtp_drift_thres_ms = (unsigned int) atoi(argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> void bts_model_config_write_bts(struct vty *vty, struct gsm_bts *bts)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+        struct bts_lc15_priv *bts_lc15 = bts->model_priv;</span><br><span style="color: hsl(120, 100%, 40%);">+  vty_out(vty, " led-control-mode %s%s",</span><br><span style="color: hsl(120, 100%, 40%);">+                      get_value_string(lc15_led_mode_strs, bts_lc15->led_ctrl_mode), VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     vty_out(vty, " rtp-drift-threshold %d%s",</span><br><span style="color: hsl(120, 100%, 40%);">+                   bts_lc15->rtp_drift_thres_ms, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> }</span><br><span> </span><br><span> void bts_model_config_write_trx(struct vty *vty, struct gsm_bts_trx *trx)</span><br><span>@@ -349,6 +536,28 @@</span><br><span>        if (pinst->u.lc15.calib_path)</span><br><span>             vty_out(vty, "  trx-calibration-path %s%s",</span><br><span>                        pinst->u.lc15.calib_path, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  vty_out(vty, "  max-cell-size %d%s",</span><br><span style="color: hsl(120, 100%, 40%);">+                        pinst->u.lc15.max_cell_size, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       vty_out(vty, "  diversity-mode %s%s",</span><br><span style="color: hsl(120, 100%, 40%);">+                       get_value_string(lc15_diversity_mode_strs, pinst->u.lc15.diversity_mode), VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  vty_out(vty, "  pedestal-mode %s%s",</span><br><span style="color: hsl(120, 100%, 40%);">+                        get_value_string(lc15_pedestal_mode_strs, pinst->u.lc15.pedestal_mode) , VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   vty_out(vty, "  dsp-alive-period %d%s",</span><br><span style="color: hsl(120, 100%, 40%);">+                     pinst->u.lc15.dsp_alive_period, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    vty_out(vty, "  pwr-adj-mode %s%s",</span><br><span style="color: hsl(120, 100%, 40%);">+                 get_value_string(lc15_auto_adj_pwr_strs, pinst->u.lc15.tx_pwr_adj_mode), VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   vty_out(vty, "  tx-red-pwr-8psk %d%s",</span><br><span style="color: hsl(120, 100%, 40%);">+                      pinst->u.lc15.tx_pwr_red_8psk, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     vty_out(vty, "  c0-idle-red-pwr %d%s",</span><br><span style="color: hsl(120, 100%, 40%);">+                      pinst->u.lc15.tx_c0_idle_pwr_red, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> }</span><br><span> </span><br><span> int bts_model_vty_init(struct gsm_bts *bts)</span><br><span>@@ -401,6 +610,8 @@</span><br><span> </span><br><span>       install_element(BTS_NODE, &cfg_bts_auto_band_cmd);</span><br><span>       install_element(BTS_NODE, &cfg_bts_no_auto_band_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+     install_element(BTS_NODE, &cfg_bts_led_mode_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ install_element(BTS_NODE, &cfg_bts_rtp_drift_threshold_cmd);</span><br><span> </span><br><span>         install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);</span><br><span> </span><br><span>@@ -408,6 +619,14 @@</span><br><span>        install_element(PHY_INST_NODE, &cfg_phy_no_dsp_trace_f_cmd);</span><br><span>     install_element(PHY_INST_NODE, &cfg_phy_cal_path_cmd);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+        install_element(PHY_INST_NODE, &cfg_phy_diversity_mode_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+      install_element(PHY_INST_NODE, &cfg_phy_pedestal_mode_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+       install_element(PHY_INST_NODE, &cfg_phy_max_cell_size_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+       install_element(PHY_INST_NODE, &cfg_phy_dsp_alive_timer_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+     install_element(PHY_INST_NODE, &cfg_phy_auto_tx_pwr_adj_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+     install_element(PHY_INST_NODE, &cfg_phy_tx_red_pwr_8psk_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+     install_element(PHY_INST_NODE, &cfg_phy_c0_idle_red_pwr_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  return 0;</span><br><span> }</span><br><span> </span><br><span>diff --git a/src/osmo-bts-litecell15/main.c b/src/osmo-bts-litecell15/main.c</span><br><span>index 6f3fc00..ef02135 100644</span><br><span>--- a/src/osmo-bts-litecell15/main.c</span><br><span>+++ b/src/osmo-bts-litecell15/main.c</span><br><span>@@ -83,14 +83,21 @@</span><br><span> </span><br><span> int bts_model_init(struct gsm_bts *bts)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gsm_bts_trx *trx;</span><br><span>     struct stat st;</span><br><span>      static struct osmo_fd accept_fd, read_fd;</span><br><span>    int rc;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   struct bts_lc15_priv *bts_lc15 = talloc(bts, struct bts_lc15_priv);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ bts->model_priv = bts_lc15;</span><br><span>       bts->variant = BTS_OSMO_LITECELL15;</span><br><span>       bts->support.ciphers = CIPHER_A5(1) | CIPHER_A5(2) | CIPHER_A5(3);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+     /* specific default values for LC15 platform */</span><br><span style="color: hsl(120, 100%, 40%);">+       bts_lc15->led_ctrl_mode = LC15_BTS_LED_CTRL_MODE_DEFAULT;</span><br><span style="color: hsl(120, 100%, 40%);">+  /* RTP drift threshold default */</span><br><span style="color: hsl(120, 100%, 40%);">+     bts_lc15->rtp_drift_thres_ms = LC15_BTS_RTP_DRIFT_THRES_DEFAULT;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>        rc = oml_router_init(bts, OML_ROUTER_PATH, &accept_fd, &read_fd);</span><br><span>    if (rc < 0) {</span><br><span>             fprintf(stderr, "Error creating the OML router: %s rc=%d\n",</span><br><span>diff --git a/src/osmo-bts-litecell15/oml.c b/src/osmo-bts-litecell15/oml.c</span><br><span>index edc49ec..a519b38 100644</span><br><span>--- a/src/osmo-bts-litecell15/oml.c</span><br><span>+++ b/src/osmo-bts-litecell15/oml.c</span><br><span>@@ -384,7 +384,7 @@</span><br><span>        struct msgb *msg;</span><br><span>    GsmL1_MphInitReq_t *mi_req;</span><br><span>  GsmL1_DeviceParam_t *dev_par;</span><br><span style="color: hsl(0, 100%, 40%);">-   int lc15_band;</span><br><span style="color: hsl(120, 100%, 40%);">+        int rc, lc15_band;</span><br><span> </span><br><span>       if (!gsm_abis_mo_check_attr(&trx->mo, trx_rqd_attr,</span><br><span>                               ARRAY_SIZE(trx_rqd_attr))) {</span><br><span>@@ -394,6 +394,15 @@</span><br><span>              //return oml_mo_opstart_nack(&trx->mo, NM_NACK_CANT_PERFORM);</span><br><span>         }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* Update TRX band */</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = gsm_arfcn2band_rc(trx->arfcn, &trx->bts->band);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">+             /* FIXME: abort initialization? */</span><br><span style="color: hsl(120, 100%, 40%);">+            LOGP(DL1C, LOGL_ERROR, "Could not pick GSM band "</span><br><span style="color: hsl(120, 100%, 40%);">+                   "for ARFCN %u\n", trx->arfcn);</span><br><span style="color: hsl(120, 100%, 40%);">+           trx->bts->band = 0x00;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  lc15_band = lc15bts_select_lc15_band(trx, trx->arfcn);</span><br><span>    if (lc15_band < 0) {</span><br><span>              LOGP(DL1C, LOGL_ERROR, "Unsupported GSM band %s\n",</span><br><span>@@ -1170,6 +1179,7 @@</span><br><span>        { GsmL1_ConfigParamId_SetTxPowerLevel,  "Set Tx power level" },</span><br><span>    { GsmL1_ConfigParamId_SetLogChParams,   "Set logical channel params" },</span><br><span>    { GsmL1_ConfigParamId_SetCipheringParams,"Configure ciphering params" },</span><br><span style="color: hsl(120, 100%, 40%);">+    { GsmL1_ConfigParamId_Set8pskPowerReduction,    "Set 8PSK Tx power reduction" },</span><br><span>   { 0, NULL }</span><br><span> };</span><br><span> </span><br><span>@@ -1227,6 +1237,56 @@</span><br><span>       return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int chmod_txpower_backoff_8psk_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg,</span><br><span style="color: hsl(120, 100%, 40%);">+                                void *data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      GsmL1_Prim_t *l1p = msgb_l1prim(l1_msg);</span><br><span style="color: hsl(120, 100%, 40%);">+      GsmL1_MphConfigCnf_t *cc = &l1p->u.mphConfigCnf;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     LOGP(DL1C, LOGL_INFO, "%s MPH-CONFIG.conf (%s) ",</span><br><span style="color: hsl(120, 100%, 40%);">+           gsm_trx_name(trx),</span><br><span style="color: hsl(120, 100%, 40%);">+            get_value_string(lc15bts_l1cfgt_names, cc->cfgParamId));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPC(DL1C, LOGL_INFO, "Backoff %u dB\n",</span><br><span style="color: hsl(120, 100%, 40%);">+           cc->cfgParams.set8pskPowerReduction.u8PowerReduction);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   msgb_free(l1_msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return 0;</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%);">+static int chmod_max_cell_size_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp,</span><br><span style="color: hsl(120, 100%, 40%);">+                             void *data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      Litecell15_Prim_t *sysp = msgb_sysprim(resp);</span><br><span style="color: hsl(120, 100%, 40%);">+ Litecell15_SetMaxCellSizeCnf_t *sac = &sysp->u.setMaxCellSizeCnf;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    LOGP(DL1C, LOGL_INFO, "%s Rx SYS prim %s -> %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                       gsm_trx_name(trx),</span><br><span style="color: hsl(120, 100%, 40%);">+                    get_value_string(lc15bts_sysprim_names, sysp->id),</span><br><span style="color: hsl(120, 100%, 40%);">+                 get_value_string(lc15bts_l1status_names, sac->status));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  msgb_free(resp);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return 0;</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%);">+static int chmod_c0_idle_pwr_red_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp,</span><br><span style="color: hsl(120, 100%, 40%);">+                           void *data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      Litecell15_Prim_t *sysp = msgb_sysprim(resp);</span><br><span style="color: hsl(120, 100%, 40%);">+ Litecell15_SetC0IdleSlotPowerReductionCnf_t *sac = &sysp->u.setC0IdleSlotPowerReductionCnf;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  LOGP(DL1C, LOGL_INFO, "%s Rx SYS prim %s -> %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                       gsm_trx_name(trx),</span><br><span style="color: hsl(120, 100%, 40%);">+                    get_value_string(lc15bts_sysprim_names, sysp->id),</span><br><span style="color: hsl(120, 100%, 40%);">+                 get_value_string(lc15bts_l1status_names, sac->status));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  msgb_free(resp);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static int chmod_modif_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg,</span><br><span>                              void *data)</span><br><span> {</span><br><span>@@ -1368,6 +1428,47 @@</span><br><span>    return l1if_gsm_req_compl(fl1h, msg, chmod_txpower_compl_cb, NULL);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+int l1if_set_txpower_backoff_8psk(struct lc15l1_hdl *fl1h, uint8_t backoff)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  struct msgb *msg = l1p_msgb_alloc();</span><br><span style="color: hsl(120, 100%, 40%);">+  GsmL1_MphConfigReq_t *conf_req;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     conf_req = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphConfigReq, fl1h, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+   conf_req->cfgParamId = GsmL1_ConfigParamId_Set8pskPowerReduction;</span><br><span style="color: hsl(120, 100%, 40%);">+  conf_req->cfgParams.set8pskPowerReduction.u8PowerReduction = backoff;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return l1if_gsm_req_compl(fl1h, msg, chmod_txpower_backoff_8psk_compl_cb, NULL);</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%);">+int l1if_set_max_cell_size(struct lc15l1_hdl *fl1h, uint8_t cell_size)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct msgb *msg =  sysp_msgb_alloc();</span><br><span style="color: hsl(120, 100%, 40%);">+        Litecell15_Prim_t *sys_prim =  msgb_sysprim(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+     sys_prim->id = Litecell15_PrimId_SetMaxCellSizeReq;</span><br><span style="color: hsl(120, 100%, 40%);">+        sys_prim->u.setMaxCellSizeReq.u8MaxCellSize = cell_size;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DL1C, LOGL_INFO, "%s Set max cell size = %d qbits\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                  gsm_trx_name(fl1h->phy_inst->trx),</span><br><span style="color: hsl(120, 100%, 40%);">+                      cell_size);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return l1if_req_compl(fl1h, msg, chmod_max_cell_size_compl_cb, NULL);</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int l1if_set_txpower_c0_idle_pwr_red(struct lc15l1_hdl *fl1h, uint8_t red)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct msgb *msg =  sysp_msgb_alloc();</span><br><span style="color: hsl(120, 100%, 40%);">+        Litecell15_Prim_t *sys_prim =  msgb_sysprim(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+     sys_prim->id = Litecell15_PrimId_SetC0IdleSlotPowerReductionReq;</span><br><span style="color: hsl(120, 100%, 40%);">+   sys_prim->u.setC0IdleSlotPowerReductionReq.u8PowerReduction = red;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       LOGP(DL1C, LOGL_INFO, "%s Set C0 idle slot power reduction = %d dB\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                      gsm_trx_name(fl1h->phy_inst->trx),</span><br><span style="color: hsl(120, 100%, 40%);">+                      red);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       return l1if_req_compl(fl1h, msg, chmod_c0_idle_pwr_red_compl_cb, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> const enum GsmL1_CipherId_t rsl2l1_ciph[] = {</span><br><span>        [0]     = GsmL1_CipherId_A50,</span><br><span>        [1]     = GsmL1_CipherId_A50,</span><br><span>@@ -1700,7 +1801,8 @@</span><br><span>                /* our L1 only supports one global TSC for all channels</span><br><span>               * one one TRX, so we need to make sure not to activate</span><br><span>               * channels with a different TSC!! */</span><br><span style="color: hsl(0, 100%, 40%);">-           if (TLVP_PRES_LEN(new_attr, NM_ATT_TSC, 1) &&</span><br><span style="color: hsl(120, 100%, 40%);">+         if (TLVP_PRESENT(new_attr, NM_ATT_TSC) &&</span><br><span style="color: hsl(120, 100%, 40%);">+                 TLVP_LEN(new_attr, NM_ATT_TSC) >= 1 &&</span><br><span>                    *TLVP_VAL(new_attr, NM_ATT_TSC) != (bts->bsic & 7)) {</span><br><span>                     LOGP(DOML, LOGL_ERROR, "Channel TSC %u != BSIC-TSC %u\n",</span><br><span>                          *TLVP_VAL(new_attr, NM_ATT_TSC), bts->bsic & 7);</span><br><span>@@ -1718,12 +1820,38 @@</span><br><span>    if (kind == NM_OC_RADIO_CARRIER) {</span><br><span>           struct gsm_bts_trx *trx = obj;</span><br><span>               struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(trx);</span><br><span style="color: hsl(120, 100%, 40%);">+                /* convert max TA to max cell size in qbits */</span><br><span style="color: hsl(120, 100%, 40%);">+                uint8_t cell_size = bts->max_ta << 2;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+              /* We do not need to check for L1 handle</span><br><span style="color: hsl(120, 100%, 40%);">+               * because the max cell size parameter can receive before MphInit */</span><br><span style="color: hsl(120, 100%, 40%);">+          if (fl1h->phy_inst->u.lc15.max_cell_size != cell_size) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        /* instruct L1 to apply max cell size */</span><br><span style="color: hsl(120, 100%, 40%);">+                      l1if_set_max_cell_size(fl1h, cell_size);</span><br><span style="color: hsl(120, 100%, 40%);">+                      /* update current max cell size */</span><br><span style="color: hsl(120, 100%, 40%);">+                    fl1h->phy_inst->u.lc15.max_cell_size = cell_size;</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> </span><br><span>              /* Did we go through MphInit yet? If yes fire and forget */</span><br><span style="color: hsl(0, 100%, 40%);">-             if (fl1h->hLayer1)</span><br><span style="color: hsl(120, 100%, 40%);">+         if (fl1h->hLayer1) {</span><br><span>                      power_ramp_start(trx, get_p_target_mdBm(trx, 0), 0);</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+                 if (fl1h->phy_inst->u.lc15.tx_pwr_red_8psk != trx->max_power_backoff_8psk) {</span><br><span style="color: hsl(120, 100%, 40%);">+                         /* update current Tx power backoff for 8-PSK */</span><br><span style="color: hsl(120, 100%, 40%);">+                               fl1h->phy_inst->u.lc15.tx_pwr_red_8psk = trx->max_power_backoff_8psk;</span><br><span style="color: hsl(120, 100%, 40%);">+                                /* instruct L1 to apply Tx power backoff for 8 PSK */</span><br><span style="color: hsl(120, 100%, 40%);">+                         l1if_set_txpower_backoff_8psk(fl1h, fl1h->phy_inst->u.lc15.tx_pwr_red_8psk);</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%);">+                   if (fl1h->phy_inst->u.lc15.tx_c0_idle_pwr_red != trx->c0_idle_power_red) {</span><br><span style="color: hsl(120, 100%, 40%);">+                           /* update current C0 idle slot Tx power reduction */</span><br><span style="color: hsl(120, 100%, 40%);">+                          fl1h->phy_inst->u.lc15.tx_c0_idle_pwr_red = trx->c0_idle_power_red;</span><br><span style="color: hsl(120, 100%, 40%);">+                          /* instruct L1 to apply C0 idle slot power reduction */</span><br><span style="color: hsl(120, 100%, 40%);">+                               l1if_set_txpower_c0_idle_pwr_red(fl1h, fl1h->phy_inst->u.lc15.tx_c0_idle_pwr_red);</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%);">+     }</span><br><span>    /* FIXME: we actually need to send a ACK or NACK for the OML message */</span><br><span>      return oml_fom_ack_nack(msg, 0);</span><br><span> }</span><br><span>@@ -1893,6 +2021,8 @@</span><br><span> </span><br><span>    cb_ts_disconnected(ts);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   msgb_free(l1_msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         return 0;</span><br><span> }</span><br><span> </span><br><span>@@ -1927,6 +2057,8 @@</span><br><span> </span><br><span>       cb_ts_connected(ts, 0);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   msgb_free(l1_msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         return 0;</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/+/17808">change 17808</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/+/17808"/><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: Id41bba798440b00a3b11441b64b2e8094a946bf2 </div>
<div style="display:none"> Gerrit-Change-Number: 17808 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: rafael2k <rafael@rhizomatica.org> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>