aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bts.h1
-rw-r--r--src/gprs_ms.cpp13
-rw-r--r--src/pcu_main.cpp2
-rw-r--r--src/pcu_vty.c52
4 files changed, 62 insertions, 6 deletions
diff --git a/src/bts.h b/src/bts.h
index b31db5fc..e52875eb 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -121,6 +121,7 @@ struct gprs_rlcmac_bts {
uint8_t cs3;
uint8_t cs4;
uint8_t initial_cs_dl, initial_cs_ul;
+ uint8_t max_cs_dl, max_cs_ul;
uint8_t force_cs; /* 0=use from BTS 1=use from VTY */
uint16_t force_llc_lifetime; /* overrides lifetime from SGSN */
uint32_t llc_discard_csec;
diff --git a/src/gprs_ms.cpp b/src/gprs_ms.cpp
index c8d598ee..adb6ff52 100644
--- a/src/gprs_ms.cpp
+++ b/src/gprs_ms.cpp
@@ -366,6 +366,7 @@ void GprsMs::update_error_rate(gprs_rlcmac_tbf *tbf, int error_rate)
{
struct gprs_rlcmac_bts *bts_data;
int64_t now;
+ uint8_t max_cs_ul = 4, max_cs_dl = 4;
OSMO_ASSERT(m_bts != NULL);
bts_data = m_bts->bts_data();
@@ -375,6 +376,12 @@ void GprsMs::update_error_rate(gprs_rlcmac_tbf *tbf, int error_rate)
now = now_msec();
+ if (bts_data->max_cs_ul)
+ max_cs_ul = bts_data->max_cs_ul;
+
+ if (bts_data->max_cs_dl)
+ max_cs_dl = bts_data->max_cs_dl;
+
/* TODO: Support different CS values for UL and DL */
if (error_rate > bts_data->cs_adj_upper_limit) {
@@ -388,10 +395,12 @@ void GprsMs::update_error_rate(gprs_rlcmac_tbf *tbf, int error_rate)
m_last_cs_not_low = now;
}
} else if (error_rate < bts_data->cs_adj_lower_limit) {
- if (m_current_cs_dl < 4) {
+ if (m_current_cs_dl < max_cs_dl) {
if (now - m_last_cs_not_low > 1000) {
m_current_cs_dl += 1;
- m_current_cs_ul = m_current_cs_dl;
+ if (m_current_cs_dl <= max_cs_ul)
+ m_current_cs_ul = m_current_cs_dl;
+
LOGP(DRLCMACDL, LOGL_INFO,
"MS (IMSI %s): Low error rate %d%%, "
"increasing CS level to %d\n",
diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp
index 2e4a970f..cecf786e 100644
--- a/src/pcu_main.cpp
+++ b/src/pcu_main.cpp
@@ -176,6 +176,8 @@ int main(int argc, char *argv[])
bts->cs_adj_enabled = 1;
bts->cs_adj_upper_limit = 33; /* Decrease CS if the error rate is above */
bts->cs_adj_lower_limit = 10; /* Increase CS if the error rate is below */
+ bts->max_cs_ul = 4;
+ bts->max_cs_dl = 4;
msgb_set_talloc_ctx(tall_pcu_ctx);
diff --git a/src/pcu_vty.c b/src/pcu_vty.c
index df1e5a41..6dba18cd 100644
--- a/src/pcu_vty.c
+++ b/src/pcu_vty.c
@@ -75,6 +75,14 @@ static int config_write_pcu(struct vty *vty)
vty_out(vty, " cs %d %d%s", bts->initial_cs_dl,
bts->initial_cs_ul, VTY_NEWLINE);
}
+ if (bts->max_cs_dl && bts->max_cs_ul) {
+ if (bts->max_cs_ul == bts->max_cs_dl)
+ vty_out(vty, " cs max %d%s", bts->max_cs_dl,
+ VTY_NEWLINE);
+ else
+ vty_out(vty, " cs max %d %d%s", bts->max_cs_dl,
+ bts->max_cs_ul, VTY_NEWLINE);
+ }
if (bts->cs_adj_enabled)
vty_out(vty, " cs threshold %d %d%s",
bts->cs_adj_lower_limit, bts->cs_adj_upper_limit,
@@ -281,7 +289,7 @@ DEFUN(cfg_pcu_cs,
DEFUN(cfg_pcu_no_cs,
cfg_pcu_no_cs_cmd,
"no cs",
- NO_STR "Don't force given Coding Scheme, (use BTS config)\n")
+ NO_STR CS_STR)
{
struct gprs_rlcmac_bts *bts = bts_main_data();
@@ -290,6 +298,40 @@ DEFUN(cfg_pcu_no_cs,
return CMD_SUCCESS;
}
+DEFUN(cfg_pcu_cs_max,
+ cfg_pcu_cs_max_cmd,
+ "cs max <1-4> [<1-4>]",
+ CS_STR
+ "Set maximum values for adaptive CS selection (overrides BTS config)\n"
+ "Maximum CS value to be used\n"
+ "Use a different maximum CS value for the uplink")
+{
+ struct gprs_rlcmac_bts *bts = bts_main_data();
+ uint8_t cs = atoi(argv[0]);
+
+ bts->max_cs_dl = cs;
+ if (argc > 1)
+ bts->max_cs_ul = atoi(argv[1]);
+ else
+ bts->max_cs_ul = cs;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_pcu_no_cs_max,
+ cfg_pcu_no_cs_max_cmd,
+ "no cs max",
+ NO_STR CS_STR
+ "Set maximum values for adaptive CS selection (overrides BTS config)\n")
+{
+ struct gprs_rlcmac_bts *bts = bts_main_data();
+
+ bts->max_cs_dl = 0;
+ bts->max_cs_ul = 0;
+
+ return CMD_SUCCESS;
+}
+
#define QUEUE_STR "Packet queue options\n"
#define LIFETIME_STR "Set lifetime limit of LLC frame in centi-seconds " \
"(overrides the value given by SGSN)\n"
@@ -519,10 +561,10 @@ DEFUN(cfg_pcu_no_ms_idle_time,
return CMD_SUCCESS;
}
-#define CS_ERR_LIMITS_STR "set limits for error rate based CS adjustment\n"
+#define CS_ERR_LIMITS_STR "set thresholds for error rate based CS adjustment\n"
DEFUN(cfg_pcu_cs_err_limits,
cfg_pcu_cs_err_limits_cmd,
- "cs limits <0-100> <0-100>",
+ "cs threshold <0-100> <0-100>",
CS_STR CS_ERR_LIMITS_STR "lower limit in %\n" "upper limit in %\n")
{
struct gprs_rlcmac_bts *bts = bts_main_data();
@@ -546,7 +588,7 @@ DEFUN(cfg_pcu_cs_err_limits,
DEFUN(cfg_pcu_no_cs_err_limits,
cfg_pcu_no_cs_err_limits_cmd,
- "no cs limits",
+ "no cs threshold",
NO_STR CS_STR CS_ERR_LIMITS_STR)
{
struct gprs_rlcmac_bts *bts = bts_main_data();
@@ -615,6 +657,8 @@ int pcu_vty_init(const struct log_info *cat)
install_element(PCU_NODE, &cfg_pcu_no_two_phase_cmd);
install_element(PCU_NODE, &cfg_pcu_cs_cmd);
install_element(PCU_NODE, &cfg_pcu_no_cs_cmd);
+ install_element(PCU_NODE, &cfg_pcu_cs_max_cmd);
+ install_element(PCU_NODE, &cfg_pcu_no_cs_max_cmd);
install_element(PCU_NODE, &cfg_pcu_cs_err_limits_cmd);
install_element(PCU_NODE, &cfg_pcu_no_cs_err_limits_cmd);
install_element(PCU_NODE, &cfg_pcu_queue_lifetime_cmd);