aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2015-06-04 19:04:30 +0200
committerJacob Erlbeck <jerlbeck@sysmocom.de>2015-06-08 09:41:07 +0200
commitb33e675e5a9f80be81ffef87ba3a9ed05d6945c5 (patch)
tree901f5466605c64b68b1333f44b3bf5c5eb7be7e9
parent8158ea7288f57d7bc66d8ccd1c278999fd656076 (diff)
ms: Add support for maximum CS values
Currently the CS values can be increased to CS4 even when the "cs" configuration command has been used with a lower value. The "cs" command just sets the initial coding scheme, so other means are needed to limit the selection. One approach is to use the CS flags passed in SI, but these are currently ignored. To make it possible to limit the CS selection by configuring the PCU, this commit adds the following VTY commands to config-pcu: - cs max <1-4> Limit DL and UL CS to the given value - cs max <1-4> <1-4> Limit DL and UL CS separately (DL first) - no cs max Don't limit Ticket: #1674 Sponsored-by: On-Waves ehf
-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 b31db5f..e52875e 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 c8d598e..adb6ff5 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 2e4a970..cecf786 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 df1e5a4..6dba18c 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);