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
This commit is contained in:
Jacob Erlbeck 2015-06-04 19:04:30 +02:00
parent 8158ea7288
commit b33e675e5a
4 changed files with 62 additions and 6 deletions

View File

@ -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;

View File

@ -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",

View File

@ -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);

View File

@ -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);