Change in osmo-bts[master]: osmo-bts-litecell15: Implement missing features.

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

rafael2k gerrit-no-reply at lists.osmocom.org
Tue Apr 14 06:52:04 UTC 2020


rafael2k has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bts/+/17808 )


Change subject: osmo-bts-litecell15: Implement missing features.
......................................................................

osmo-bts-litecell15: Implement missing features.

Many hardware parameters of the LC 1.5 were not exposed to the user.
This patchset introduces most of the features, being very similar
to osmo-bts-oc2g code.

Change-Id: Id41bba798440b00a3b11441b64b2e8094a946bf2
---
M include/osmo-bts/phy_link.h
M src/osmo-bts-litecell15/l1_if.c
M src/osmo-bts-litecell15/l1_if.h
M src/osmo-bts-litecell15/lc15bts.c
M src/osmo-bts-litecell15/lc15bts.h
M src/osmo-bts-litecell15/lc15bts_vty.c
M src/osmo-bts-litecell15/main.c
M src/osmo-bts-litecell15/oml.c
8 files changed, 530 insertions(+), 10 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/08/17808/1

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

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-bts/+/17808
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Change-Id: Id41bba798440b00a3b11441b64b2e8094a946bf2
Gerrit-Change-Number: 17808
Gerrit-PatchSet: 1
Gerrit-Owner: rafael2k <rafael at rhizomatica.org>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200414/868c963f/attachment.htm>


More information about the gerrit-log mailing list