Merge remote-tracking branch 'origin/NR_UE_rework_LC_config' into integration_2024_w06
This commit is contained in:
@@ -42,32 +42,6 @@
|
|||||||
#include "SCHED_NR/phy_frame_config_nr.h"
|
#include "SCHED_NR/phy_frame_config_nr.h"
|
||||||
#include "oai_asn1.h"
|
#include "oai_asn1.h"
|
||||||
|
|
||||||
const long logicalChannelGroup0_NR = 0;
|
|
||||||
typedef struct NR_LogicalChannelConfig__ul_SpecificParameters LcConfig_UlParamas_t;
|
|
||||||
|
|
||||||
const LcConfig_UlParamas_t NR_LCSRB1 = {
|
|
||||||
.priority = 1,
|
|
||||||
.prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity,
|
|
||||||
.logicalChannelGroup = (long *)&logicalChannelGroup0_NR};
|
|
||||||
|
|
||||||
const LcConfig_UlParamas_t NR_LCSRB2 = {
|
|
||||||
.priority = 3,
|
|
||||||
.prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity,
|
|
||||||
.logicalChannelGroup = (long *)&logicalChannelGroup0_NR};
|
|
||||||
|
|
||||||
const LcConfig_UlParamas_t NR_LCSRB3 = {
|
|
||||||
.priority = 1,
|
|
||||||
.prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity,
|
|
||||||
.logicalChannelGroup = (long *)&logicalChannelGroup0_NR};
|
|
||||||
|
|
||||||
// these are the default values for SRB configurations(SRB1 and SRB2) as mentioned in 36.331 pg 258-259
|
|
||||||
const NR_LogicalChannelConfig_t NR_SRB1_logicalChannelConfig_defaultValue = {.ul_SpecificParameters =
|
|
||||||
(LcConfig_UlParamas_t *)&NR_LCSRB1};
|
|
||||||
const NR_LogicalChannelConfig_t NR_SRB2_logicalChannelConfig_defaultValue = {.ul_SpecificParameters =
|
|
||||||
(LcConfig_UlParamas_t *)&NR_LCSRB2};
|
|
||||||
const NR_LogicalChannelConfig_t NR_SRB3_logicalChannelConfig_defaultValue = {.ul_SpecificParameters =
|
|
||||||
(LcConfig_UlParamas_t *)&NR_LCSRB3};
|
|
||||||
|
|
||||||
void set_tdd_config_nr_ue(fapi_nr_tdd_table_t *tdd_table,
|
void set_tdd_config_nr_ue(fapi_nr_tdd_table_t *tdd_table,
|
||||||
int mu,
|
int mu,
|
||||||
NR_TDD_UL_DL_Pattern_t *pattern)
|
NR_TDD_UL_DL_Pattern_t *pattern)
|
||||||
@@ -648,25 +622,13 @@ static void configure_ss_coreset(NR_BWP_PDCCH_t *pdcch, NR_PDCCH_Config_t *pdcch
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lcid_cmp(const void *lc1, const void *lc2, void *mac_inst)
|
static int lcid_cmp(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
uint8_t id1 = ((nr_lcordered_info_t *)lc1)->lcids_ordered;
|
long priority_a = (*((nr_lcordered_info_t**)a))->priority;
|
||||||
uint8_t id2 = ((nr_lcordered_info_t *)lc2)->lcids_ordered;
|
AssertFatal(priority_a > 0 && priority_a < 17, "Invalid priority value %ld\n", priority_a);
|
||||||
NR_UE_MAC_INST_t *mac = (NR_UE_MAC_INST_t *)mac_inst;
|
long priority_b = (*((nr_lcordered_info_t**)b))->priority;
|
||||||
|
AssertFatal(priority_b > 0 && priority_b < 17, "Invalid priority value %ld\n", priority_b);
|
||||||
NR_LogicalChannelConfig_t **lc_config = &mac->logicalChannelConfig[0];
|
return priority_a - priority_b;
|
||||||
|
|
||||||
AssertFatal(id1 > 0 && id2 > 0, "undefined logical channel identity\n");
|
|
||||||
AssertFatal(lc_config[id1 - 1] != NULL || lc_config[id2 - 1] != NULL, "logical channel configuration should be available\n");
|
|
||||||
|
|
||||||
return (lc_config[id1 - 1]->ul_SpecificParameters->priority - lc_config[id2 - 1]->ul_SpecificParameters->priority);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nr_release_mac_config_logicalChannelBearer(NR_UE_MAC_INST_t *mac, long channel_identity)
|
|
||||||
{
|
|
||||||
if (mac->logicalChannelConfig[channel_identity - 1] != NULL) {
|
|
||||||
asn1cFreeStruc(asn_DEF_NR_LogicalChannelConfig, mac->logicalChannelConfig[channel_identity - 1]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nr_get_ms_bucketsizeduration(long bucketsizeduration)
|
static int nr_get_ms_bucketsizeduration(long bucketsizeduration)
|
||||||
@@ -695,33 +657,46 @@ static int nr_get_ms_bucketsizeduration(long bucketsizeduration)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nr_configure_mac_config_logicalChannelBearer(module_id_t module_id,
|
static uint32_t get_lc_bucket_size(long prioritisedBitRate, long bucketSizeDuration)
|
||||||
long channel_identity,
|
|
||||||
NR_LogicalChannelConfig_t *lc_config)
|
|
||||||
{
|
{
|
||||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
int pbr = nr_get_pbr(prioritisedBitRate);
|
||||||
|
|
||||||
LOG_I(NR_MAC, "[MACLogicalChannelConfig]Applying RRC Logical Channel Config %d to lcid %li\n", module_id, channel_identity);
|
|
||||||
mac->logicalChannelConfig[channel_identity - 1] = lc_config;
|
|
||||||
|
|
||||||
// initialize the variable Bj for every LCID
|
|
||||||
mac->scheduling_info.lc_sched_info[channel_identity - 1].Bj = 0;
|
|
||||||
|
|
||||||
// store the bucket size
|
|
||||||
int pbr = nr_get_pbr(lc_config->ul_SpecificParameters->prioritisedBitRate);
|
|
||||||
int bsd = nr_get_ms_bucketsizeduration(lc_config->ul_SpecificParameters->bucketSizeDuration);
|
|
||||||
|
|
||||||
// in infinite pbr, the bucket is saturated by pbr
|
// in infinite pbr, the bucket is saturated by pbr
|
||||||
if (lc_config->ul_SpecificParameters->prioritisedBitRate
|
int bsd = 0;
|
||||||
== NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity) {
|
if (prioritisedBitRate == NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity)
|
||||||
bsd = 1;
|
bsd = 1;
|
||||||
}
|
|
||||||
mac->scheduling_info.lc_sched_info[channel_identity - 1].bucket_size = pbr * bsd;
|
|
||||||
|
|
||||||
if (lc_config->ul_SpecificParameters->logicalChannelGroup != NULL)
|
|
||||||
mac->scheduling_info.lc_sched_info[channel_identity - 1].LCGID = *lc_config->ul_SpecificParameters->logicalChannelGroup;
|
|
||||||
else
|
else
|
||||||
mac->scheduling_info.lc_sched_info[channel_identity - 1].LCGID = 0;
|
bsd = nr_get_ms_bucketsizeduration(bucketSizeDuration);
|
||||||
|
|
||||||
|
return pbr * bsd;
|
||||||
|
}
|
||||||
|
|
||||||
|
// default configuration as per 38.331 section 9.2.1
|
||||||
|
static void set_default_logicalchannelconfig(nr_lcordered_info_t *lc_info, NR_SRB_Identity_t srb_id)
|
||||||
|
{
|
||||||
|
lc_info->lcid = srb_id;
|
||||||
|
lc_info->priority = srb_id == 2 ? 3 : 1;
|
||||||
|
lc_info->prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
|
||||||
|
lc_info->bucket_size = get_lc_bucket_size(lc_info->prioritisedBitRate, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nr_configure_lc_config(NR_UE_MAC_INST_t *mac,
|
||||||
|
nr_lcordered_info_t *lc_info,
|
||||||
|
NR_LogicalChannelConfig_t *mac_lc_config,
|
||||||
|
NR_SRB_Identity_t srb_id)
|
||||||
|
{
|
||||||
|
if (srb_id > 0 && !mac_lc_config->ul_SpecificParameters) {
|
||||||
|
// release configuration and reset to default
|
||||||
|
set_default_logicalchannelconfig(lc_info, srb_id);
|
||||||
|
mac->scheduling_info.lc_sched_info[lc_info->lcid - 1].LCGID = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AssertFatal(mac_lc_config->ul_SpecificParameters, "UL parameters shouldn't be NULL for DRBs\n");
|
||||||
|
struct NR_LogicalChannelConfig__ul_SpecificParameters *ul_parm = mac_lc_config->ul_SpecificParameters;
|
||||||
|
lc_info->priority = ul_parm->priority;
|
||||||
|
lc_info->prioritisedBitRate = ul_parm->prioritisedBitRate;
|
||||||
|
// TODO Verify setting to 0 is ok, 331 just says need R (release if NULL)
|
||||||
|
mac->scheduling_info.lc_sched_info[lc_info->lcid - 1].LCGID = ul_parm->logicalChannelGroup ? *ul_parm->logicalChannelGroup : 0;
|
||||||
|
lc_info->bucket_size = get_lc_bucket_size(ul_parm->prioritisedBitRate, ul_parm->bucketSizeDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void configure_logicalChannelBearer(module_id_t module_id,
|
static void configure_logicalChannelBearer(module_id_t module_id,
|
||||||
@@ -729,59 +704,66 @@ static void configure_logicalChannelBearer(module_id_t module_id,
|
|||||||
struct NR_CellGroupConfig__rlc_BearerToReleaseList *rlc_torelease_list)
|
struct NR_CellGroupConfig__rlc_BearerToReleaseList *rlc_torelease_list)
|
||||||
{
|
{
|
||||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
||||||
|
|
||||||
if (rlc_torelease_list) {
|
if (rlc_torelease_list) {
|
||||||
for (int i = 0; i < rlc_torelease_list->list.count; i++) {
|
for (int i = 0; i < rlc_torelease_list->list.count; i++) {
|
||||||
if (rlc_torelease_list->list.array[i]) {
|
long id = *rlc_torelease_list->list.array[i];
|
||||||
int lc_identity = *rlc_torelease_list->list.array[i];
|
int j;
|
||||||
nr_release_mac_config_logicalChannelBearer(mac, lc_identity);
|
for (j = 0; j < mac->lc_ordered_list.count; j++) {
|
||||||
|
if (id == mac->lc_ordered_list.array[j]->lcid)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
if (j < mac->lc_ordered_list.count) {
|
||||||
|
nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[j];
|
||||||
|
asn_sequence_del(&mac->lc_ordered_list, j, 0);
|
||||||
|
free(lc_info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LOG_E(NR_MAC, "Element not present in the list, impossible to release\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rlc_toadd_list) {
|
if (rlc_toadd_list) {
|
||||||
for (int i = 0; i < rlc_toadd_list->list.count; i++) {
|
for (int i = 0; i < rlc_toadd_list->list.count; i++) {
|
||||||
NR_RLC_BearerConfig_t *rlc_bearer = rlc_toadd_list->list.array[i];
|
NR_RLC_BearerConfig_t *rlc_bearer = rlc_toadd_list->list.array[i];
|
||||||
int lc_identity = rlc_bearer->logicalChannelIdentity;
|
int lc_identity = rlc_bearer->logicalChannelIdentity;
|
||||||
mac->lc_ordered_info[i].lcids_ordered = lc_identity;
|
NR_LogicalChannelConfig_t *mac_lc_config = rlc_bearer->mac_LogicalChannelConfig;
|
||||||
NR_LogicalChannelConfig_t *mac_lc_config = NULL;
|
int j;
|
||||||
if (mac->logicalChannelConfig[lc_identity - 1] == NULL) {
|
for (j = 0; j < mac->lc_ordered_list.count; j++) {
|
||||||
|
if (lc_identity == mac->lc_ordered_list.array[j]->lcid)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (j < mac->lc_ordered_list.count) {
|
||||||
|
LOG_D(NR_MAC, "Logical channel %d is already established, Reconfiguring now\n", lc_identity);
|
||||||
|
if (mac_lc_config != NULL) {
|
||||||
|
NR_SRB_Identity_t srb_id = 0;
|
||||||
|
if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity)
|
||||||
|
srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity;
|
||||||
|
nr_configure_lc_config(mac, mac->lc_ordered_list.array[j], mac_lc_config, srb_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
/* setup of new LCID*/
|
/* setup of new LCID*/
|
||||||
|
nr_lcordered_info_t *lc_info = calloc(1, sizeof(*lc_info));
|
||||||
|
lc_info->lcid = lc_identity;
|
||||||
LOG_D(NR_MAC, "Establishing the logical channel %d\n", lc_identity);
|
LOG_D(NR_MAC, "Establishing the logical channel %d\n", lc_identity);
|
||||||
AssertFatal(rlc_bearer->servedRadioBearer, "servedRadioBearer should be present for LCID establishment\n");
|
AssertFatal(rlc_bearer->servedRadioBearer, "servedRadioBearer should be present for LCID establishment\n");
|
||||||
if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) { /* SRB */
|
if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) { /* SRB */
|
||||||
NR_SRB_Identity_t srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity;
|
NR_SRB_Identity_t srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity;
|
||||||
if (rlc_bearer->mac_LogicalChannelConfig != NULL) {
|
if (mac_lc_config != NULL)
|
||||||
UPDATE_MAC_IE(mac_lc_config, rlc_bearer->mac_LogicalChannelConfig, NR_LogicalChannelConfig_t);
|
nr_configure_lc_config(mac, lc_info, mac_lc_config, srb_id);
|
||||||
} else {
|
|
||||||
LOG_I(NR_RRC, "Applying the default logicalChannelConfig for SRB\n");
|
|
||||||
if (srb_id == 1)
|
|
||||||
mac_lc_config = (NR_LogicalChannelConfig_t *)&NR_SRB1_logicalChannelConfig_defaultValue;
|
|
||||||
else if (srb_id == 2)
|
|
||||||
mac_lc_config = (NR_LogicalChannelConfig_t *)&NR_SRB2_logicalChannelConfig_defaultValue;
|
|
||||||
else if (srb_id == 3)
|
|
||||||
mac_lc_config = (NR_LogicalChannelConfig_t *)&NR_SRB3_logicalChannelConfig_defaultValue;
|
|
||||||
else
|
else
|
||||||
AssertFatal(1 == 0, "The logical id %d is not a valid SRB id %li\n", lc_identity, srb_id);
|
set_default_logicalchannelconfig(lc_info, srb_id);
|
||||||
}
|
|
||||||
} else { /* DRB */
|
} else { /* DRB */
|
||||||
AssertFatal(rlc_bearer->mac_LogicalChannelConfig,
|
AssertFatal(mac_lc_config, "When establishing a DRB, LogicalChannelConfig should be mandatorily present\n");
|
||||||
"When establishing a DRB, LogicalChannelConfig should be mandatorily present\n");
|
nr_configure_lc_config(mac, lc_info, mac_lc_config, 0);
|
||||||
UPDATE_MAC_IE(mac_lc_config, rlc_bearer->mac_LogicalChannelConfig, NR_LogicalChannelConfig_t);
|
|
||||||
}
|
}
|
||||||
} else {
|
ASN_SEQUENCE_ADD(&mac->lc_ordered_list, lc_info);
|
||||||
/* LC is already established, reconfiguring the LC */
|
|
||||||
LOG_D(NR_MAC, "Logical channel %d is already established, Reconfiguring now\n", lc_identity);
|
|
||||||
if (rlc_bearer->mac_LogicalChannelConfig != NULL) {
|
|
||||||
UPDATE_MAC_IE(mac_lc_config, rlc_bearer->mac_LogicalChannelConfig, NR_LogicalChannelConfig_t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mac_lc_config) {
|
|
||||||
mac->lc_ordered_info[i].logicalChannelConfig_ordered = mac_lc_config;
|
|
||||||
nr_configure_mac_config_logicalChannelBearer(module_id, lc_identity, mac_lc_config);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// reorder the logical channels as per its priority
|
// reorder the logical channels as per its priority
|
||||||
qsort_r(mac->lc_ordered_info, rlc_toadd_list->list.count, sizeof(nr_lcordered_info_t), lcid_cmp, mac);
|
qsort(mac->lc_ordered_list.array, mac->lc_ordered_list.count, sizeof(nr_lcordered_info_t*), lcid_cmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -181,12 +181,10 @@ typedef struct {
|
|||||||
int32_t LCID_buffer_remain;
|
int32_t LCID_buffer_remain;
|
||||||
// buffer status for each lcid
|
// buffer status for each lcid
|
||||||
uint8_t LCID_status;
|
uint8_t LCID_status;
|
||||||
|
// logical channel group id of this LCID
|
||||||
|
long LCGID;
|
||||||
// Bj bucket usage per lcid
|
// Bj bucket usage per lcid
|
||||||
int32_t Bj;
|
int32_t Bj;
|
||||||
// Bucket size per lcid
|
|
||||||
int32_t bucket_size;
|
|
||||||
// logical channel group id for each LCID
|
|
||||||
uint8_t LCGID;
|
|
||||||
} NR_LC_SCHEDULING_INFO;
|
} NR_LC_SCHEDULING_INFO;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -434,10 +432,11 @@ typedef struct ssb_list_info {
|
|||||||
|
|
||||||
typedef struct nr_lcordered_info_s {
|
typedef struct nr_lcordered_info_s {
|
||||||
// logical channels ids ordered as per priority
|
// logical channels ids ordered as per priority
|
||||||
int lcids_ordered;
|
NR_LogicalChannelIdentity_t lcid;
|
||||||
|
long priority;
|
||||||
// logical channel configurations reordered as per priority
|
long prioritisedBitRate;
|
||||||
NR_LogicalChannelConfig_t *logicalChannelConfig_ordered;
|
// Bucket size per lcid
|
||||||
|
uint32_t bucket_size;
|
||||||
} nr_lcordered_info_t;
|
} nr_lcordered_info_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -513,11 +512,9 @@ typedef struct NR_UE_MAC_INST_s {
|
|||||||
/// BSR report flag management
|
/// BSR report flag management
|
||||||
uint8_t BSR_reporting_active;
|
uint8_t BSR_reporting_active;
|
||||||
|
|
||||||
// Pointers to LogicalChannelConfig indexed by LogicalChannelIdentity. Note NULL means LCHAN is inactive.
|
|
||||||
NR_LogicalChannelConfig_t *logicalChannelConfig[NR_MAX_NUM_LCID];
|
|
||||||
|
|
||||||
// order lc info
|
// order lc info
|
||||||
nr_lcordered_info_t lc_ordered_info[NR_MAX_NUM_LCID];
|
A_SEQUENCE_OF(nr_lcordered_info_t) lc_ordered_list;
|
||||||
|
|
||||||
NR_UE_SCHEDULING_INFO scheduling_info;
|
NR_UE_SCHEDULING_INFO scheduling_info;
|
||||||
|
|
||||||
/// PHR
|
/// PHR
|
||||||
|
|||||||
@@ -239,12 +239,12 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t
|
|||||||
uint8_t nr_locate_BsrIndexByBufferSize(const uint32_t *table, int size,
|
uint8_t nr_locate_BsrIndexByBufferSize(const uint32_t *table, int size,
|
||||||
int value);
|
int value);
|
||||||
|
|
||||||
/*! \fn int nr_get_pbr(uint8_t prioritizedbitrate)
|
/*! \fn int nr_get_pbr(long prioritizedbitrate)
|
||||||
\brief get the rate in kbps from the rate configured by the higher layer
|
\brief get the rate in kbps from the rate configured by the higher layer
|
||||||
\param[in] prioritizedbitrate
|
\param[in] prioritizedbitrate
|
||||||
\return the rate in kbps
|
\return the rate in kbps
|
||||||
*/
|
*/
|
||||||
uint32_t nr_get_pbr(uint8_t prioritizedbitrate);
|
uint32_t nr_get_pbr(long prioritizedbitrate);
|
||||||
|
|
||||||
/*! \fn int nr_get_sf_periodicBSRTimer(uint8_t periodicBSR_Timer)
|
/*! \fn int nr_get_sf_periodicBSRTimer(uint8_t periodicBSR_Timer)
|
||||||
\brief get the number of subframe from the periodic BSR timer configured by the higher layers
|
\brief get the number of subframe from the periodic BSR timer configured by the higher layers
|
||||||
|
|||||||
@@ -99,11 +99,9 @@ void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac)
|
|||||||
|
|
||||||
for (int i = 0; i < NR_MAX_NUM_LCID; i++) {
|
for (int i = 0; i < NR_MAX_NUM_LCID; i++) {
|
||||||
LOG_D(NR_MAC, "Applying default logical channel config for LCGID %d\n", i);
|
LOG_D(NR_MAC, "Applying default logical channel config for LCGID %d\n", i);
|
||||||
mac->scheduling_info.lc_sched_info[i].Bj = -1;
|
|
||||||
mac->scheduling_info.lc_sched_info[i].bucket_size = -1;
|
|
||||||
mac->scheduling_info.lc_sched_info[i].LCGID = 0; // defaults to 0 irrespective of SRB or DRB
|
|
||||||
mac->scheduling_info.lc_sched_info[i].LCID_status = LCID_EMPTY;
|
mac->scheduling_info.lc_sched_info[i].LCID_status = LCID_EMPTY;
|
||||||
mac->scheduling_info.lc_sched_info[i].LCID_buffer_remain = 0;
|
mac->scheduling_info.lc_sched_info[i].LCID_buffer_remain = 0;
|
||||||
|
mac->scheduling_info.lc_sched_info[i].Bj = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +144,8 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac)
|
|||||||
nr_ue_mac_default_configs(nr_mac);
|
nr_ue_mac_default_configs(nr_mac);
|
||||||
|
|
||||||
// initialize Bj for each logical channel to zero
|
// initialize Bj for each logical channel to zero
|
||||||
// Done in default config but to -1 (is that correct?)
|
for (int i = 0; i < NR_MAX_NUM_LCID; i++)
|
||||||
|
nr_mac->scheduling_info.lc_sched_info[i].Bj = 0;
|
||||||
|
|
||||||
// stop all running timers
|
// stop all running timers
|
||||||
// TODO
|
// TODO
|
||||||
@@ -221,9 +220,10 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac)
|
|||||||
for (int i = 0; i < mac->ul_BWPs.count; i++)
|
for (int i = 0; i < mac->ul_BWPs.count; i++)
|
||||||
release_ul_BWP(mac, i);
|
release_ul_BWP(mac, i);
|
||||||
|
|
||||||
for (int i = 0; i < NR_MAX_NUM_LCID; i++) {
|
for (int i = 0; i < mac->lc_ordered_list.count; i++) {
|
||||||
nr_release_mac_config_logicalChannelBearer(mac, i + 1);
|
nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i];
|
||||||
memset(&mac->lc_ordered_info[i], 0, sizeof(nr_lcordered_info_t));
|
asn_sequence_del(&mac->lc_ordered_list, i, 0);
|
||||||
|
free(lc_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&mac->ssb_measurements, 0, sizeof(mac->ssb_measurements));
|
memset(&mac->ssb_measurements, 0, sizeof(mac->ssb_measurements));
|
||||||
|
|||||||
@@ -1109,12 +1109,11 @@ void nr_ue_ul_scheduler(nr_uplink_indication_t *ul_info)
|
|||||||
|
|
||||||
// update Bj for all active lcids before LCP procedure
|
// update Bj for all active lcids before LCP procedure
|
||||||
LOG_D(NR_MAC, "====================[Frame %d][Slot %d]Logical Channel Prioritization===========\n", frame_tx, slot_tx);
|
LOG_D(NR_MAC, "====================[Frame %d][Slot %d]Logical Channel Prioritization===========\n", frame_tx, slot_tx);
|
||||||
for (nr_lcordered_info_t *lc_bearer = mac->lc_ordered_info; lc_bearer->logicalChannelConfig_ordered != NULL; lc_bearer++) {
|
for (int i = 0; i < mac->lc_ordered_list.count; i++) {
|
||||||
int lcid = lc_bearer->lcids_ordered;
|
nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i];
|
||||||
NR_LogicalChannelConfig_t *lcconfig = mac->logicalChannelConfig[lcid - 1];
|
int lcid = lc_info->lcid;
|
||||||
NR_LC_SCHEDULING_INFO *sched_lc = &mac->scheduling_info.lc_sched_info[lcid - 1];
|
|
||||||
// max amount of data that can be buffered/accumulated in a logical channel buffer
|
// max amount of data that can be buffered/accumulated in a logical channel buffer
|
||||||
int32_t bucketSize_max = sched_lc->bucket_size;
|
int32_t bucketSize_max = lc_info->bucket_size;
|
||||||
AssertFatal(bucketSize_max >= 0, "negative bucketSize_max %d, will never schedule UE: lcid %d\n",bucketSize_max, lcid);
|
AssertFatal(bucketSize_max >= 0, "negative bucketSize_max %d, will never schedule UE: lcid %d\n",bucketSize_max, lcid);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1122,15 +1121,13 @@ void nr_ue_ul_scheduler(nr_uplink_indication_t *ul_info)
|
|||||||
increment the value of Bj by product PBR * T
|
increment the value of Bj by product PBR * T
|
||||||
*/
|
*/
|
||||||
int T = 1; // time elapsed since Bj was last incremented
|
int T = 1; // time elapsed since Bj was last incremented
|
||||||
int32_t bj = sched_lc->Bj;
|
int32_t bj = mac->scheduling_info.lc_sched_info[lcid - 1].Bj;
|
||||||
bj += nr_get_pbr(lcconfig->ul_SpecificParameters->prioritisedBitRate) * T;
|
bj += nr_get_pbr(lc_info->prioritisedBitRate) * T;
|
||||||
if (lcconfig->ul_SpecificParameters->prioritisedBitRate
|
if (lc_info->prioritisedBitRate == NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity)
|
||||||
== NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity) {
|
bj = nr_get_pbr(lc_info->prioritisedBitRate);
|
||||||
bj = nr_get_pbr(lcconfig->ul_SpecificParameters->prioritisedBitRate);
|
|
||||||
}
|
|
||||||
|
|
||||||
// bj > max bucket size, set bj to max bucket size, as in ts38.321 5.4.3.1 Logical Channel Prioritization
|
// bj > max bucket size, set bj to max bucket size, as in ts38.321 5.4.3.1 Logical Channel Prioritization
|
||||||
sched_lc->Bj = min(bj, bucketSize_max);
|
mac->scheduling_info.lc_sched_info[lcid - 1].Bj = min(bj, bucketSize_max);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call BSR procedure as described in Section 5.4.5 in 38.321
|
// Call BSR procedure as described in Section 5.4.5 in 38.321
|
||||||
@@ -1196,8 +1193,8 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Get Buffer Occupancy and fill lcid_reordered_array
|
//Get Buffer Occupancy and fill lcid_reordered_array
|
||||||
for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) {
|
for (int i = 0; i < mac->lc_ordered_list.count; i++) {
|
||||||
if (mac->logicalChannelConfig[lcid - 1] != NULL) { // todo
|
int lcid = mac->lc_ordered_list.array[i]->lcid;
|
||||||
int lcgid = mac->scheduling_info.lc_sched_info[lcid - 1].LCGID;
|
int lcgid = mac->scheduling_info.lc_sched_info[lcid - 1].LCGID;
|
||||||
|
|
||||||
// Store already available data to transmit per Group
|
// Store already available data to transmit per Group
|
||||||
@@ -1220,7 +1217,7 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t
|
|||||||
|
|
||||||
if (rlc_status.bytes_in_buffer > 0) {
|
if (rlc_status.bytes_in_buffer > 0) {
|
||||||
LOG_D(NR_MAC,"[UE %d] PDCCH Tick : LCID%d LCGID%d has data to transmit =%d bytes at frame %d slot %d\n",
|
LOG_D(NR_MAC,"[UE %d] PDCCH Tick : LCID%d LCGID%d has data to transmit =%d bytes at frame %d slot %d\n",
|
||||||
module_idP, lcid,lcgid,rlc_status.bytes_in_buffer,frameP,slotP);
|
module_idP, lcid, lcgid, rlc_status.bytes_in_buffer, frameP, slotP);
|
||||||
mac->scheduling_info.lc_sched_info[lcid - 1].LCID_status = LCID_NOT_EMPTY;
|
mac->scheduling_info.lc_sched_info[lcid - 1].LCID_status = LCID_NOT_EMPTY;
|
||||||
|
|
||||||
//Update BSR_bytes and position in lcid_reordered_array only if Group is defined
|
//Update BSR_bytes and position in lcid_reordered_array only if Group is defined
|
||||||
@@ -1248,7 +1245,6 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Check whether a regular BSR can be triggered according to the first cases in 38.321
|
// Check whether a regular BSR can be triggered according to the first cases in 38.321
|
||||||
if (num_lcid_with_data) {
|
if (num_lcid_with_data) {
|
||||||
@@ -1267,7 +1263,7 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t
|
|||||||
{
|
{
|
||||||
bsr_regular_triggered = true;
|
bsr_regular_triggered = true;
|
||||||
LOG_D(NR_MAC,
|
LOG_D(NR_MAC,
|
||||||
"[UE %d] PDCCH Tick : MAC BSR Triggered LCID%d LCGID%d data become available at frame %d slot %d\n",
|
"[UE %d] PDCCH Tick : MAC BSR Triggered LCID %d LCGID %ld data become available at frame %d slot %d\n",
|
||||||
module_idP,
|
module_idP,
|
||||||
lcid,
|
lcid,
|
||||||
mac->scheduling_info.lc_sched_info[lcid - 1].LCGID,
|
mac->scheduling_info.lc_sched_info[lcid - 1].LCGID,
|
||||||
@@ -2909,16 +2905,13 @@ void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t get_count_lcids_same_priority(NR_UE_MAC_INST_t *mac, uint8_t start, uint8_t total_active_lcids, int *lcid_ordered_array)
|
uint32_t get_count_lcids_same_priority(uint8_t start, uint8_t total_active_lcids, nr_lcordered_info_t *lcid_ordered_array)
|
||||||
{
|
{
|
||||||
// count number of logical channels with same priority as curr_lcid
|
// count number of logical channels with same priority as curr_lcid
|
||||||
uint8_t same_priority_count = 0;
|
uint8_t same_priority_count = 0;
|
||||||
uint8_t curr_lcid = lcid_ordered_array[start];
|
uint8_t curr_lcid = lcid_ordered_array[start].lcid;
|
||||||
NR_LogicalChannelConfig_t *lc_config_curr = mac->logicalChannelConfig[curr_lcid - 1];
|
|
||||||
for (uint8_t index = start; index < total_active_lcids; index++) {
|
for (uint8_t index = start; index < total_active_lcids; index++) {
|
||||||
uint8_t next_lcid = lcid_ordered_array[index];
|
if (lcid_ordered_array[start].priority == lcid_ordered_array[index].priority) {
|
||||||
NR_LogicalChannelConfig_t *lc_config_next = mac->logicalChannelConfig[next_lcid - 1];
|
|
||||||
if (lc_config_curr->ul_SpecificParameters->priority == lc_config_next->ul_SpecificParameters->priority) {
|
|
||||||
same_priority_count++;
|
same_priority_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2936,8 +2929,15 @@ long get_num_bytes_to_reqlc(NR_UE_MAC_INST_t *mac,
|
|||||||
long *target)
|
long *target)
|
||||||
{
|
{
|
||||||
/* Calculates the number of bytes the logical channel should request from the correcponding RLC buffer*/
|
/* Calculates the number of bytes the logical channel should request from the correcponding RLC buffer*/
|
||||||
NR_LogicalChannelConfig_t *lc_config = mac->logicalChannelConfig[lc_num - 1];
|
long found_pbr = -1;
|
||||||
long pbr = nr_get_pbr(lc_config->ul_SpecificParameters->prioritisedBitRate);
|
for (int i = 0; i < mac->lc_ordered_list.count; i++) {
|
||||||
|
if (mac->lc_ordered_list.array[i]->lcid == lc_num) {
|
||||||
|
found_pbr = mac->lc_ordered_list.array[i]->prioritisedBitRate;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AssertFatal(found_pbr >= 0, "Couldn't find LC config for ID %d\n", lc_num);
|
||||||
|
uint32_t pbr = nr_get_pbr(found_pbr);
|
||||||
int32_t lcid_remain_buffer = mac->scheduling_info.lc_sched_info[lc_num - 1].LCID_buffer_remain;
|
int32_t lcid_remain_buffer = mac->scheduling_info.lc_sched_info[lc_num - 1].LCID_buffer_remain;
|
||||||
*target = (same_priority_count > 1) ? min(buflen_remain_ep, pbr) : pbr;
|
*target = (same_priority_count > 1) ? min(buflen_remain_ep, pbr) : pbr;
|
||||||
|
|
||||||
@@ -2963,11 +2963,11 @@ long get_num_bytes_to_reqlc(NR_UE_MAC_INST_t *mac,
|
|||||||
return num_bytes_requested;
|
return num_bytes_requested;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get_dataavailability_buffers(uint8_t total_active_lcids, int *lcid_ordered_array, bool *data_status_lcbuffers)
|
bool get_dataavailability_buffers(uint8_t total_active_lcids, nr_lcordered_info_t *lcid_ordered_array, bool *data_status_lcbuffers)
|
||||||
{
|
{
|
||||||
// check whether there is any data in the rlc buffer corresponding to active lcs
|
// check whether there is any data in the rlc buffer corresponding to active lcs
|
||||||
for (uint8_t id = 0; id < total_active_lcids; id++) {
|
for (uint8_t id = 0; id < total_active_lcids; id++) {
|
||||||
int lcid = lcid_ordered_array[id];
|
int lcid = lcid_ordered_array[id].lcid;
|
||||||
if (data_status_lcbuffers[lcid - 1]) {
|
if (data_status_lcbuffers[lcid - 1]) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -2975,21 +2975,20 @@ bool get_dataavailability_buffers(uint8_t total_active_lcids, int *lcid_ordered_
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t select_logical_channels(NR_UE_MAC_INST_t *mac, uint8_t *num_active_lcids, int *active_lcids)
|
static void select_logical_channels(NR_UE_MAC_INST_t *mac, int *num_active_lcids, nr_lcordered_info_t *active_lcids)
|
||||||
{
|
{
|
||||||
// (TODO: selection of logical channels for logical channel prioritization procedure as per 5.4.3.1.2 Selection of logical
|
// (TODO: selection of logical channels for logical channel prioritization procedure as per 5.4.3.1.2 Selection of logical
|
||||||
// channels, TS38.321)
|
// channels, TS38.321)
|
||||||
|
|
||||||
// selection of logical channels with Bj > 0
|
// selection of logical channels with Bj > 0
|
||||||
for (nr_lcordered_info_t *lc_bearer = mac->lc_ordered_info; lc_bearer->logicalChannelConfig_ordered != NULL; lc_bearer++) {
|
for (int i = 0; i < mac->lc_ordered_list.count; i++) {
|
||||||
uint8_t lcid = lc_bearer->lcids_ordered;
|
int lcid = mac->lc_ordered_list.array[i]->lcid;
|
||||||
if (mac->scheduling_info.lc_sched_info[lcid - 1].Bj > 0) {
|
if (mac->scheduling_info.lc_sched_info[lcid - 1].Bj > 0) {
|
||||||
active_lcids[*num_active_lcids] = lcid;
|
active_lcids[*num_active_lcids] = *mac->lc_ordered_list.array[i];
|
||||||
(*num_active_lcids)++;
|
(*num_active_lcids)++;
|
||||||
LOG_D(NR_MAC, "The available lcid is %d with total active channels count = %d\n", lcid, *num_active_lcids);
|
LOG_D(NR_MAC, "The available lcid is %d with total active channels count = %d\n", lcid, *num_active_lcids);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool fill_mac_sdu(module_id_t module_idP,
|
static bool fill_mac_sdu(module_id_t module_idP,
|
||||||
@@ -3059,7 +3058,7 @@ static bool fill_mac_sdu(module_id_t module_idP,
|
|||||||
// currently the Bj is drecremented by size of MAC SDus everytime it is served to logical channel, so by this approach there
|
// currently the Bj is drecremented by size of MAC SDus everytime it is served to logical channel, so by this approach there
|
||||||
// will be more chance for lower priority logical channels to be served in the next TTI
|
// will be more chance for lower priority logical channels to be served in the next TTI
|
||||||
// second approach can also be followed where Bj is decremented only in the first round but not in the subsequent rounds
|
// second approach can also be followed where Bj is decremented only in the first round but not in the subsequent rounds
|
||||||
sched_info->lc_sched_info[lcid - 1].Bj -= sdu_length;
|
sched_info->lc_sched_info[lcid - 1].Bj -= sdu_length; // TODO avoid Bj to go below 0
|
||||||
LOG_D(NR_MAC,
|
LOG_D(NR_MAC,
|
||||||
"decrement Bj of the lcid %d by size of sdu length = %d and new Bj for lcid %d is %d\n",
|
"decrement Bj of the lcid %d by size of sdu length = %d and new Bj for lcid %d is %d\n",
|
||||||
lcid,
|
lcid,
|
||||||
@@ -3113,7 +3112,7 @@ static bool fill_mac_sdu(module_id_t module_idP,
|
|||||||
lc_info->LCID_buffer_remain -= sdu_length;
|
lc_info->LCID_buffer_remain -= sdu_length;
|
||||||
(lcg_info + lc_info->LCGID)->BSR_bytes -= sdu_length;
|
(lcg_info + lc_info->LCGID)->BSR_bytes -= sdu_length;
|
||||||
LOG_D(NR_MAC,
|
LOG_D(NR_MAC,
|
||||||
"[UE %d] Update BSR [%d.%d] BSR_bytes for LCG%d = %d\n",
|
"[UE %d] Update BSR [%d.%d] BSR_bytes for LCG %ld = %d\n",
|
||||||
module_idP,
|
module_idP,
|
||||||
frameP,
|
frameP,
|
||||||
subframe,
|
subframe,
|
||||||
@@ -3188,10 +3187,6 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
|
|||||||
// Pointer used to build the MAC PDU by placing the RLC SDUs in the ULSCH buffer
|
// Pointer used to build the MAC PDU by placing the RLC SDUs in the ULSCH buffer
|
||||||
uint8_t *pdu = ulsch_buffer;
|
uint8_t *pdu = ulsch_buffer;
|
||||||
|
|
||||||
// variable used to build the lcids with positive Bj
|
|
||||||
int lcids_bj_pos[NR_MAX_NUM_LCID] = {0};
|
|
||||||
uint8_t avail_lcids_count = 0;
|
|
||||||
|
|
||||||
// variable used to store the lcid data status during lcp
|
// variable used to store the lcid data status during lcp
|
||||||
bool lcids_data_status[NR_MAX_NUM_LCID] = {0};
|
bool lcids_data_status[NR_MAX_NUM_LCID] = {0};
|
||||||
memset(lcids_data_status, 1, NR_MAX_NUM_LCID);
|
memset(lcids_data_status, 1, NR_MAX_NUM_LCID);
|
||||||
@@ -3209,6 +3204,9 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
|
|||||||
LOG_D(NR_MAC, "In %s: [UE %d] [%d.%d] process UL transport block at with size TBS = %d bytes \n", __FUNCTION__, module_idP, frameP, subframe, buflen);
|
LOG_D(NR_MAC, "In %s: [UE %d] [%d.%d] process UL transport block at with size TBS = %d bytes \n", __FUNCTION__, module_idP, frameP, subframe, buflen);
|
||||||
|
|
||||||
// selection of logical channels
|
// selection of logical channels
|
||||||
|
int avail_lcids_count = 0;
|
||||||
|
// variable used to build the lcids with positive Bj
|
||||||
|
nr_lcordered_info_t lcids_bj_pos[mac->lc_ordered_list.count];
|
||||||
select_logical_channels(mac, &avail_lcids_count, lcids_bj_pos);
|
select_logical_channels(mac, &avail_lcids_count, lcids_bj_pos);
|
||||||
|
|
||||||
// multiplex in the order of highest priority
|
// multiplex in the order of highest priority
|
||||||
@@ -3229,7 +3227,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
|
|||||||
still space availble in the MAC PDU, then from the next run all the remaining data from the higher priority logical channel
|
still space availble in the MAC PDU, then from the next run all the remaining data from the higher priority logical channel
|
||||||
is placed in the MAC PDU before going on to next high priority logical channel
|
is placed in the MAC PDU before going on to next high priority logical channel
|
||||||
*/
|
*/
|
||||||
int lcid = lcids_bj_pos[id];
|
int lcid = lcids_bj_pos[id].lcid;
|
||||||
|
|
||||||
// skip the logical channel if no data in the buffer initially or the data in the buffer was zero because it was written in to
|
// skip the logical channel if no data in the buffer initially or the data in the buffer was zero because it was written in to
|
||||||
// MAC PDU
|
// MAC PDU
|
||||||
@@ -3241,7 +3239,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
|
|||||||
// count number of lc with same priority as lcid
|
// count number of lc with same priority as lcid
|
||||||
if (!num_lcids_same_priority) {
|
if (!num_lcids_same_priority) {
|
||||||
num_lcids_same_priority = count_same_priority_lcids =
|
num_lcids_same_priority = count_same_priority_lcids =
|
||||||
get_count_lcids_same_priority(mac, id, avail_lcids_count, lcids_bj_pos);
|
get_count_lcids_same_priority(id, avail_lcids_count, lcids_bj_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size);
|
buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size);
|
||||||
@@ -3361,7 +3359,7 @@ void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UL_TIME_ALIG
|
|||||||
ul_time_alignment->ta_apply = false;
|
ul_time_alignment->ta_apply = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t nr_get_pbr(uint8_t prioritizedbitrate)
|
uint32_t nr_get_pbr(long prioritizedbitrate)
|
||||||
{
|
{
|
||||||
int32_t pbr = -1;
|
int32_t pbr = -1;
|
||||||
switch (prioritizedbitrate) {
|
switch (prioritizedbitrate) {
|
||||||
|
|||||||
Reference in New Issue
Block a user