aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bts-sysmo
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2014-08-22 02:46:15 +0200
committerHarald Welte <laforge@gnumonks.org>2014-08-24 10:46:21 +0200
commite43feaf231e08f108aafa26a7829820fad3447cb (patch)
tree06b0fe4d89e8c2c4194dcb7e1ae0378b48dae1fc /src/osmo-bts-sysmo
parentfcca2e82184f8ece6a31db48abd77d560065b31f (diff)
New generic transmit power handling
In order to support transmit power reduction by thermal management as well as the variety of new internal / external PA configurations of BTSs, we need a slightly more complex system. Also, as at high power a single dB can be quite a big difference, we are now doing all computations in milli-dB(m), i.e. 1/10000 bel. Ramping is now used both for up and down ramping, as that is useful in cases where you want to gracefully shut down a cell by shrinking its radius, gradually handing over subscribers to neighboring cells. Furthermore, this code is becoming part of the 'common' codebase, as it is not really specific to how sysmobts is working. The user can specify a single aggregate value for external system gain/attenuation. Let's say you have 1dB loss of antenna cable, so you can put that as 'user-gain -1' into the config, which means that a 'transmit power of 20dBm' will be compensatet for that and the TRX is instructed to output 21dBm to compensate the cable loss. Similarly, external PAs can be described by a positive user-gain. One of the next steps will be to communicate those values and the nominal power capability of the specific BTS to the BSC, so the BSC will automatically show correct signal levels in the VTY and log files. The code includes provisions for future extensions regarding * an external and an internal PA with calibration tables * a thermal attenuation setting to be controlled by the site manager
Diffstat (limited to 'src/osmo-bts-sysmo')
-rw-r--r--src/osmo-bts-sysmo/main.c6
-rw-r--r--src/osmo-bts-sysmo/oml.c21
-rw-r--r--src/osmo-bts-sysmo/sysmobts_vty.c48
-rw-r--r--src/osmo-bts-sysmo/utils.c84
4 files changed, 11 insertions, 148 deletions
diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c
index 5a864074..d12421df 100644
--- a/src/osmo-bts-sysmo/main.c
+++ b/src/osmo-bts-sysmo/main.c
@@ -84,11 +84,7 @@ int bts_model_init(struct gsm_bts *bts)
rc = 23;
}
bts->c0->nominal_power = rc;
-
- /* Initial values for the power adjustments */
- bts->c0->pa.max_initial_power = 23;
- bts->c0->pa.step_size = 2;
- bts->c0->pa.step_interval = 1;
+ bts->c0->power_params.trx_p_max_out_mdBm = to_mdB(rc);
bts_model_vty_init(bts);
diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c
index e5f9260b..207cae89 100644
--- a/src/osmo-bts-sysmo/oml.c
+++ b/src/osmo-bts-sysmo/oml.c
@@ -272,7 +272,7 @@ static int trx_init_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg)
#endif
/* Begin to ramp up the power */
- sysmobts_pa_maybe_step(trx);
+ power_ramp_start(trx, get_p_target_mdBm(trx, 0), 0);
return opstart_compl(&trx->mo, l1_msg);
}
@@ -327,9 +327,7 @@ static int trx_init(struct gsm_bts_trx *trx)
dev_par->u8NbTsc = trx->bts->bsic & 7;
dev_par->fRxPowerLevel = fl1h->ul_power_target;
- /* initialize the power */
- sysmobts_pa_pwr_init(trx);
- dev_par->fTxPowerLevel = trx->pa.current_power;
+ dev_par->fTxPowerLevel = 0.0;
LOGP(DL1C, LOGL_NOTICE, "Init TRX (ARFCN %u, TSC %u, RxPower % 2f dBm, "
"TxPower % 2.2f dBm\n", dev_par->u16Arfcn, dev_par->u8NbTsc,
dev_par->fRxPowerLevel, dev_par->fTxPowerLevel);
@@ -1074,12 +1072,8 @@ static int chmod_txpower_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg)
LOGPC(DL1C, LOGL_INFO, "setTxPower %f dBm\n",
cc->cfgParams.setTxPowerLevel.fTxPowerLevel);
- trx->pa.current_power = cc->cfgParams.setTxPowerLevel.fTxPowerLevel;
msgb_free(l1_msg);
- /* Schedule the next step up */
- sysmobts_pa_maybe_step(trx);
-
return 0;
}
@@ -1553,10 +1547,8 @@ int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg,
struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx);
/* Did we go through MphInit yet? If yes fire and forget */
- if (fl1h->hLayer1) {
- sysmobts_pa_pwr_init(trx);
- l1if_set_txpower(fl1h, (float) trx->pa.current_power);
- }
+ if (fl1h->hLayer1)
+ power_ramp_start(trx, get_p_target_mdBm(trx, 0), 0);
}
/* FIXME: we actaully need to send a ACK or NACK for the OML message */
@@ -1722,3 +1714,8 @@ int bts_model_trx_deact_rf(struct gsm_bts_trx *trx)
return l1if_activate_rf(fl1, 0);
}
+
+int bts_model_change_power(struct gsm_bts_trx *trx, int p_trxout_mdBm)
+{
+ return l1if_set_txpower(trx_femtol1_hdl(trx), ((float) p_trxout_mdBm)/1000.0);
+}
diff --git a/src/osmo-bts-sysmo/sysmobts_vty.c b/src/osmo-bts-sysmo/sysmobts_vty.c
index ed90a234..8b617d78 100644
--- a/src/osmo-bts-sysmo/sysmobts_vty.c
+++ b/src/osmo-bts-sysmo/sysmobts_vty.c
@@ -254,40 +254,6 @@ DEFUN(cfg_trx_nominal_power, cfg_trx_nominal_power_cmd,
return CMD_SUCCESS;
}
-#define PA_STR "Power-Amplifier settings"
-DEFUN(cfg_trx_pa_max_initial, cfg_trx_pa_max_initial_cmd,
- "power-amplifier max-initial <0-100>",
- PA_STR "Maximum initial power\n"
- "Value in dBm\n")
-{
- struct gsm_bts_trx *trx = vty->index;
-
- trx->pa.max_initial_power = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_trx_pa_step_size, cfg_trx_pa_step_size_cmd,
- "power-amplifier step-size <1-100>",
- PA_STR "Power increase by step\n"
- "Step size in dB\n")
-{
- struct gsm_bts_trx *trx = vty->index;
-
- trx->pa.step_size = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_trx_pa_step_interval, cfg_trx_pa_step_interval_cmd,
- "power-amplifier step-interval <1-100>",
- PA_STR "Power increase by step\n"
- "Step time in seconds\n")
-{
- struct gsm_bts_trx *trx = vty->index;
-
- trx->pa.step_interval = atoi(argv[0]);
- return CMD_SUCCESS;
-}
-
/* runtime */
DEFUN(show_trx_clksrc, show_trx_clksrc_cmd,
@@ -452,11 +418,8 @@ DEFUN(set_tx_power, set_tx_power_cmd,
int trx_nr = atoi(argv[0]);
int power = atoi(argv[1]);
struct gsm_bts_trx *trx = gsm_bts_trx_num(vty_bts, trx_nr);
- struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx);
- trx->pa.current_power = power;
- osmo_timer_del(&trx->pa.step_timer);
- l1if_set_txpower(fl1h, (float) trx->pa.current_power);
+ power_ramp_start(trx, to_mdB(power), 1);
return CMD_SUCCESS;
}
@@ -586,12 +549,6 @@ void bts_model_config_write_trx(struct vty *vty, struct gsm_bts_trx *trx)
if (trx->nominal_power != sysmobts_get_nominal_power(trx))
vty_out(vty, " nominal-tx-power %d%s", trx->nominal_power,
VTY_NEWLINE);
- vty_out(vty, " power-amplifier max-initial %d%s",
- trx->pa.max_initial_power, VTY_NEWLINE);
- vty_out(vty, " power-amplifier step-size %d%s",
- trx->pa.step_size, VTY_NEWLINE);
- vty_out(vty, " power-amplifier step-interval %d%s",
- trx->pa.step_interval, VTY_NEWLINE);
for (i = 0; i < 32; i++) {
if (fl1h->gsmtap_sapi_mask & (1 << i)) {
@@ -663,9 +620,6 @@ int bts_model_vty_init(struct gsm_bts *bts)
install_element(TRX_NODE, &cfg_trx_min_qual_rach_cmd);
install_element(TRX_NODE, &cfg_trx_min_qual_norm_cmd);
install_element(TRX_NODE, &cfg_trx_nominal_power_cmd);
- install_element(TRX_NODE, &cfg_trx_pa_max_initial_cmd);
- install_element(TRX_NODE, &cfg_trx_pa_step_size_cmd);
- install_element(TRX_NODE, &cfg_trx_pa_step_interval_cmd);
return 0;
}
diff --git a/src/osmo-bts-sysmo/utils.c b/src/osmo-bts-sysmo/utils.c
index afca7730..a636ae15 100644
--- a/src/osmo-bts-sysmo/utils.c
+++ b/src/osmo-bts-sysmo/utils.c
@@ -137,88 +137,4 @@ int sysmobts_get_nominal_power(struct gsm_bts_trx *trx)
return -1;
}
-int sysmobts_get_target_power(struct gsm_bts_trx *trx)
-{
- int target_power = trx->nominal_power - trx->max_power_red;
- target_power -= trx->power_reduce;
-
- if (target_power < 0)
- target_power = 0;
-
- return target_power;
-}
-
-void sysmobts_pa_pwr_init(struct gsm_bts_trx *trx)
-{
- int target_power = sysmobts_get_target_power(trx);
-
- /* Cancel any pending request */
- osmo_timer_del(&trx->pa.step_timer);
-
- /* is this below our initial target */
- if (target_power <= trx->pa.max_initial_power) {
- LOGP(DL1C, LOGL_NOTICE,
- "PA target_power(%d) is below initial power.\n",
- target_power);
- trx->pa.current_power = target_power;
- return;
- }
-
- /* is this below our current value? */
- if (target_power <= trx->pa.current_power) {
- LOGP(DL1C, LOGL_NOTICE,
- "PA target_power(%d) is below current_power.\n",
- target_power);
- trx->pa.current_power = target_power;
- return;
- }
- if (trx->pa.current_power > trx->pa.max_initial_power) {
- LOGP(DL1C, LOGL_NOTICE,
- "PA target_power(%d) starting from current_power.\n",
- target_power);
- return;
- }
-
- /* We need to step it up. Start from the initial value */
- trx->pa.current_power = trx->pa.max_initial_power;
- LOGP(DL1C, LOGL_NOTICE,
- "PA target_power(%d) starting with %d dBm.\n",
- target_power, trx->pa.current_power);
-}
-
-static void pa_trx_cb(void *_trx)
-{
- struct gsm_bts_trx *trx = _trx;
-
- LOGP(DL1C, LOGL_NOTICE,
- "PA raising power to %d dBm.\n", trx->pa.current_power);
- l1if_set_txpower(trx_femtol1_hdl(trx), (float) trx->pa.current_power);
-}
-
-void sysmobts_pa_maybe_step(struct gsm_bts_trx *trx)
-{
- /* it can not have changed */
- int target_power = sysmobts_get_target_power(trx);
-
- /* We are done */
- if (trx->pa.current_power >= target_power) {
- LOGP(DL1C, LOGL_NOTICE,
- "PA have reached target power: %d dBm.\n",
- target_power);
- return;
- }
-
- /* Step up the current power but clamp it */
- trx->pa.current_power += trx->pa.step_size;
- if (trx->pa.current_power > target_power)
- trx->pa.current_power = target_power;
-
- LOGP(DL1C, LOGL_NOTICE,
- "PA scheduling to step to %d dBm.\n",
- trx->pa.current_power);
-
- trx->pa.step_timer.data = trx;
- trx->pa.step_timer.cb = pa_trx_cb;
- osmo_timer_schedule(&trx->pa.step_timer, trx->pa.step_interval, 0);
-}