Merge remote-tracking branch 'origin/implement_logical_channel_prioritization_ue' into integration_2023_w47
This commit is contained in:
@@ -305,6 +305,7 @@ Furthermore, the gNB and UE support
|
|||||||
- HARQ procedures
|
- HARQ procedures
|
||||||
* ULSCH scheduler
|
* ULSCH scheduler
|
||||||
- Configuration of fapi PDU according to DCI
|
- Configuration of fapi PDU according to DCI
|
||||||
|
- Logical channel prioritization of 'data from any logical channel'
|
||||||
* NR-CSIRS scheduler
|
* NR-CSIRS scheduler
|
||||||
- Scheduling of NR-CSIRS reception
|
- Scheduling of NR-CSIRS reception
|
||||||
- Fill UCI for CSI measurement reporting
|
- Fill UCI for CSI measurement reporting
|
||||||
|
|||||||
+1
-1
@@ -975,7 +975,7 @@ void init_NR_UE(int nb_inst, char *uecap_file, char *reconfig_file, char *rbconf
|
|||||||
nr_rrc_mac_config_req_ue_logicalChannelBearer(0, &rlc_toadd_list, NULL);
|
nr_rrc_mac_config_req_ue_logicalChannelBearer(0, &rlc_toadd_list, NULL);
|
||||||
|
|
||||||
// free memory
|
// free memory
|
||||||
free_nr_noS1_bearer_config(&rbconfig, &rlc_rbconfig);
|
free_nr_noS1_bearer_config(&rbconfig, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,8 @@
|
|||||||
* \warning
|
* \warning
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
//#include "mac_defs.h"
|
//#include "mac_defs.h"
|
||||||
#include <NR_MAC_gNB/mac_proto.h>
|
#include <NR_MAC_gNB/mac_proto.h>
|
||||||
#include "NR_MAC_UE/mac_proto.h"
|
#include "NR_MAC_UE/mac_proto.h"
|
||||||
@@ -39,6 +41,32 @@
|
|||||||
#include "executables/softmodem-common.h"
|
#include "executables/softmodem-common.h"
|
||||||
#include "SCHED_NR/phy_frame_config_nr.h"
|
#include "SCHED_NR/phy_frame_config_nr.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)
|
||||||
@@ -511,26 +539,145 @@ void configure_ss_coreset(NR_UE_MAC_INST_t *mac,
|
|||||||
mac->BWP_coresets[i] = NULL;
|
mac->BWP_coresets[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int lcid_cmp(const void *lc1, const void *lc2, void *mac_inst)
|
||||||
|
{
|
||||||
|
uint8_t id1 = ((nr_lcordered_info_t *)lc1)->lcids_ordered;
|
||||||
|
uint8_t id2 = ((nr_lcordered_info_t *)lc2)->lcids_ordered;
|
||||||
|
NR_UE_MAC_INST_t *mac = (NR_UE_MAC_INST_t *)mac_inst;
|
||||||
|
|
||||||
|
NR_LogicalChannelConfig_t **lc_config = &mac->logicalChannelConfig[0];
|
||||||
|
|
||||||
|
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(module_id_t module_id, long channel_identity)
|
||||||
|
{
|
||||||
|
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
||||||
|
if (mac->logicalChannelConfig[channel_identity - 1] != NULL) {
|
||||||
|
mac->logicalChannelConfig[channel_identity - 1] = NULL;
|
||||||
|
memset(&mac->scheduling_info.lc_sched_info[channel_identity - 1], 0, sizeof(NR_LC_SCHEDULING_INFO));
|
||||||
|
} else {
|
||||||
|
LOG_E(NR_MAC, "Trying to release a non configured logical channel bearer %li\n", channel_identity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t nr_get_ms_bucketsizeduration(uint8_t bucketsizeduration)
|
||||||
|
{
|
||||||
|
switch (bucketsizeduration) {
|
||||||
|
case NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50:
|
||||||
|
return 50;
|
||||||
|
|
||||||
|
case NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms100:
|
||||||
|
return 100;
|
||||||
|
|
||||||
|
case NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms150:
|
||||||
|
return 150;
|
||||||
|
|
||||||
|
case NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms300:
|
||||||
|
return 300;
|
||||||
|
|
||||||
|
case NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms500:
|
||||||
|
return 500;
|
||||||
|
|
||||||
|
case NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms1000:
|
||||||
|
return 1000;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void nr_configure_mac_config_logicalChannelBearer(module_id_t module_id,
|
||||||
|
long channel_identity,
|
||||||
|
NR_LogicalChannelConfig_t *lc_config)
|
||||||
|
{
|
||||||
|
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
||||||
|
|
||||||
|
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
|
||||||
|
if (lc_config->ul_SpecificParameters->prioritisedBitRate
|
||||||
|
== NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity) {
|
||||||
|
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
|
||||||
|
mac->scheduling_info.lc_sched_info[channel_identity - 1].LCGID = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void nr_rrc_mac_config_req_ue_logicalChannelBearer(module_id_t module_id,
|
void nr_rrc_mac_config_req_ue_logicalChannelBearer(module_id_t module_id,
|
||||||
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_toadd_list,
|
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_toadd_list,
|
||||||
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_toadd_list) {
|
|
||||||
for (int i = 0; i < rlc_toadd_list->list.count; i++) {
|
|
||||||
NR_RLC_BearerConfig_t *rlc_bearer = rlc_toadd_list->list.array[i];
|
|
||||||
int id = rlc_bearer->logicalChannelIdentity - 1;
|
|
||||||
mac->active_RLC_bearer[id] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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]) {
|
if (rlc_torelease_list->list.array[i]) {
|
||||||
int id = *rlc_torelease_list->list.array[i] - 1;
|
int lc_identity = *rlc_torelease_list->list.array[i];
|
||||||
mac->active_RLC_bearer[id] = false;
|
nr_release_mac_config_logicalChannelBearer(module_id, lc_identity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (rlc_toadd_list) {
|
||||||
|
for (int i = 0; i < rlc_toadd_list->list.count; i++) {
|
||||||
|
NR_RLC_BearerConfig_t *rlc_bearer = rlc_toadd_list->list.array[i];
|
||||||
|
int lc_identity = rlc_bearer->logicalChannelIdentity;
|
||||||
|
mac->lc_ordered_info[i].lcids_ordered = lc_identity;
|
||||||
|
NR_LogicalChannelConfig_t *mac_lc_config;
|
||||||
|
if (mac->logicalChannelConfig[lc_identity - 1] == NULL) {
|
||||||
|
/* setup of new LCID*/
|
||||||
|
LOG_D(NR_MAC, "Establishing the logical channel %d\n", lc_identity);
|
||||||
|
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 */
|
||||||
|
NR_SRB_Identity_t srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity;
|
||||||
|
if (rlc_bearer->mac_LogicalChannelConfig != NULL) {
|
||||||
|
mac_lc_config = rlc_bearer->mac_LogicalChannelConfig;
|
||||||
|
} 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
|
||||||
|
AssertFatal(1 == 0, "The logical id %d is not a valid SRB id %li\n", lc_identity, srb_id);
|
||||||
|
}
|
||||||
|
} else { /* DRB */
|
||||||
|
mac_lc_config = rlc_bearer->mac_LogicalChannelConfig;
|
||||||
|
AssertFatal(mac_lc_config != NULL, "For DRB, it should be mandatorily present\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* 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) {
|
||||||
|
mac_lc_config = rlc_bearer->mac_LogicalChannelConfig;
|
||||||
|
} else {
|
||||||
|
/* Need M - Maintains current value */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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
|
||||||
|
qsort_r(mac->lc_ordered_info, rlc_toadd_list->list.count, sizeof(nr_lcordered_info_t), lcid_cmp, mac);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void configure_scc(NR_UE_MAC_INST_t *mac,
|
void configure_scc(NR_UE_MAC_INST_t *mac,
|
||||||
|
|||||||
@@ -170,24 +170,38 @@ typedef enum {
|
|||||||
RA_4STEP
|
RA_4STEP
|
||||||
} nr_ra_type_e;
|
} nr_ra_type_e;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
// after multiplexing buffer remain for each lcid
|
||||||
|
int32_t LCID_buffer_remain;
|
||||||
|
// buffer status for each lcid
|
||||||
|
uint8_t LCID_status;
|
||||||
|
// Bj bucket usage per lcid
|
||||||
|
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;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
// buffer status for each lcgid
|
||||||
|
uint8_t BSR; // should be more for mesh topology
|
||||||
|
// keep the number of bytes in rlc buffer for each lcgid
|
||||||
|
int32_t BSR_bytes;
|
||||||
|
} NR_LCG_SCHEDULING_INFO;
|
||||||
|
|
||||||
// LTE structure, might need to be adapted for NR
|
// LTE structure, might need to be adapted for NR
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/// buffer status for each lcgid
|
// lcs scheduling info
|
||||||
uint8_t BSR[NR_MAX_NUM_LCGID]; // should be more for mesh topology
|
NR_LC_SCHEDULING_INFO lc_sched_info[NR_MAX_NUM_LCID];
|
||||||
/// keep the number of bytes in rlc buffer for each lcgid
|
// lcg scheduling info
|
||||||
int32_t BSR_bytes[NR_MAX_NUM_LCGID];
|
NR_LCG_SCHEDULING_INFO lcg_sched_info[NR_MAX_NUM_LCGID];
|
||||||
/// after multiplexing buffer remain for each lcid
|
|
||||||
int32_t LCID_buffer_remain[NR_MAX_NUM_LCID];
|
|
||||||
/// sum of all lcid buffer size
|
/// sum of all lcid buffer size
|
||||||
uint16_t All_lcid_buffer_size_lastTTI;
|
uint16_t All_lcid_buffer_size_lastTTI;
|
||||||
/// buffer status for each lcid
|
|
||||||
uint8_t LCID_status[NR_MAX_NUM_LCID];
|
|
||||||
/// SR pending as defined in 38.321
|
/// SR pending as defined in 38.321
|
||||||
uint8_t SR_pending;
|
uint8_t SR_pending;
|
||||||
/// SR_COUNTER as defined in 38.321
|
/// SR_COUNTER as defined in 38.321
|
||||||
uint16_t SR_COUNTER;
|
uint16_t SR_COUNTER;
|
||||||
/// logical channel group ide for each LCID
|
|
||||||
uint8_t LCGID[NR_MAX_NUM_LCID];
|
|
||||||
/// retxBSR-Timer, default value is sf2560
|
/// retxBSR-Timer, default value is sf2560
|
||||||
uint16_t retxBSR_Timer;
|
uint16_t retxBSR_Timer;
|
||||||
/// retxBSR_SF, number of subframe before triggering a regular BSR
|
/// retxBSR_SF, number of subframe before triggering a regular BSR
|
||||||
@@ -225,11 +239,6 @@ typedef struct {
|
|||||||
uint16_t extendedBSR_Sizes_r10;
|
uint16_t extendedBSR_Sizes_r10;
|
||||||
/// default value is false
|
/// default value is false
|
||||||
uint16_t extendedPHR_r10;
|
uint16_t extendedPHR_r10;
|
||||||
|
|
||||||
//Bj bucket usage per lcid
|
|
||||||
int16_t Bj[NR_MAX_NUM_LCID];
|
|
||||||
// Bucket size per lcid
|
|
||||||
int16_t bucket_size[NR_MAX_NUM_LCID];
|
|
||||||
} NR_UE_SCHEDULING_INFO;
|
} NR_UE_SCHEDULING_INFO;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -423,6 +432,14 @@ typedef struct ssb_list_info {
|
|||||||
uint8_t nb_tx_ssb;
|
uint8_t nb_tx_ssb;
|
||||||
} ssb_list_info_t;
|
} ssb_list_info_t;
|
||||||
|
|
||||||
|
typedef struct nr_lcordered_info_s {
|
||||||
|
// logical channels ids ordered as per priority
|
||||||
|
int lcids_ordered;
|
||||||
|
|
||||||
|
// logical channel configurations reordered as per priority
|
||||||
|
NR_LogicalChannelConfig_t *logicalChannelConfig_ordered;
|
||||||
|
} nr_lcordered_info_t;
|
||||||
|
|
||||||
/*!\brief Top level UE MAC structure */
|
/*!\brief Top level UE MAC structure */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
NR_UE_L2_STATE_t state;
|
NR_UE_L2_STATE_t state;
|
||||||
@@ -503,8 +520,11 @@ typedef struct {
|
|||||||
/// BSR report flag management
|
/// BSR report flag management
|
||||||
uint8_t BSR_reporting_active;
|
uint8_t BSR_reporting_active;
|
||||||
|
|
||||||
/// LogicalChannelConfig has bearer.
|
// Pointers to LogicalChannelConfig indexed by LogicalChannelIdentity. Note NULL means LCHAN is inactive.
|
||||||
bool active_RLC_bearer[NR_MAX_NUM_LCID];
|
NR_LogicalChannelConfig_t *logicalChannelConfig[NR_MAX_NUM_LCID];
|
||||||
|
|
||||||
|
// order lc info
|
||||||
|
nr_lcordered_info_t lc_ordered_info[NR_MAX_NUM_LCID];
|
||||||
NR_UE_SCHEDULING_INFO scheduling_info;
|
NR_UE_SCHEDULING_INFO scheduling_info;
|
||||||
|
|
||||||
/// PHR
|
/// PHR
|
||||||
|
|||||||
@@ -145,6 +145,13 @@ 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)
|
||||||
|
\brief get the rate in kbps from the rate configured by the higher layer
|
||||||
|
\param[in] prioritizedbitrate
|
||||||
|
\return the rate in kbps
|
||||||
|
*/
|
||||||
|
uint32_t nr_get_pbr(uint8_t 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
|
||||||
\param[in] periodicBSR_Timer timer for periodic BSR
|
\param[in] periodicBSR_Timer timer for periodic BSR
|
||||||
|
|||||||
@@ -191,17 +191,11 @@ 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.Bj[i] = -1;
|
mac->scheduling_info.lc_sched_info[i].Bj = -1;
|
||||||
mac->scheduling_info.bucket_size[i] = -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
|
||||||
if (i < UL_SCH_LCID_DTCH) { // initialize all control channels lcgid to 0
|
mac->scheduling_info.lc_sched_info[i].LCID_status = LCID_EMPTY;
|
||||||
mac->scheduling_info.LCGID[i] = 0;
|
mac->scheduling_info.lc_sched_info[i].LCID_buffer_remain = 0;
|
||||||
} else { // initialize all the data channels lcgid to 1
|
|
||||||
mac->scheduling_info.LCGID[i] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
mac->scheduling_info.LCID_status[i] = LCID_EMPTY;
|
|
||||||
mac->scheduling_info.LCID_buffer_remain[i] = 0;
|
|
||||||
for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++)
|
for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++)
|
||||||
mac->first_ul_tx[k] = 1;
|
mac->first_ul_tx[k] = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1094,6 +1094,31 @@ void nr_ue_ul_scheduler(nr_uplink_indication_t *ul_info)
|
|||||||
pthread_mutex_unlock(&ul_config->mutex_ul_config);
|
pthread_mutex_unlock(&ul_config->mutex_ul_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
for (nr_lcordered_info_t *lc_bearer = mac->lc_ordered_info; lc_bearer->logicalChannelConfig_ordered != NULL; lc_bearer++) {
|
||||||
|
int lcid = lc_bearer->lcids_ordered;
|
||||||
|
NR_LogicalChannelConfig_t *lcconfig = mac->logicalChannelConfig[lcid - 1];
|
||||||
|
NR_LC_SCHEDULING_INFO *sched_lc = &mac->scheduling_info.lc_sched_info[lcid - 1];
|
||||||
|
int32_t bucketSize_max =
|
||||||
|
sched_lc->bucket_size; // max amount of data that can be buffered/accumulated in a logical channel buffer
|
||||||
|
|
||||||
|
/*
|
||||||
|
measure Bj
|
||||||
|
increment the value of Bj by product PBR * T
|
||||||
|
*/
|
||||||
|
int T = 1; // time elapsed since Bj was last incremented
|
||||||
|
int32_t bj = sched_lc->Bj;
|
||||||
|
bj += nr_get_pbr(lcconfig->ul_SpecificParameters->prioritisedBitRate) * T;
|
||||||
|
if (lcconfig->ul_SpecificParameters->prioritisedBitRate
|
||||||
|
== NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity) {
|
||||||
|
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
|
||||||
|
sched_lc->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
|
||||||
|
|
||||||
// First check ReTxBSR Timer because it is always configured
|
// First check ReTxBSR Timer because it is always configured
|
||||||
@@ -1146,23 +1171,23 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t
|
|||||||
for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) {
|
for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) {
|
||||||
// Reset transmission status
|
// Reset transmission status
|
||||||
lcid_bytes_in_buffer[lcid - 1] = 0;
|
lcid_bytes_in_buffer[lcid - 1] = 0;
|
||||||
mac->scheduling_info.LCID_status[lcid - 1] = LCID_EMPTY;
|
mac->scheduling_info.lc_sched_info[lcid - 1].LCID_status = LCID_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int lcgid = 0; lcgid < NR_MAX_NUM_LCGID; lcgid++) {
|
for (int lcgid = 0; lcgid < NR_MAX_NUM_LCGID; lcgid++) {
|
||||||
// Reset Buffer Info
|
// Reset Buffer Info
|
||||||
mac->scheduling_info.BSR[lcgid] = 0;
|
mac->scheduling_info.lcg_sched_info[lcgid].BSR = 0;
|
||||||
mac->scheduling_info.BSR_bytes[lcgid] = 0;
|
mac->scheduling_info.lcg_sched_info[lcgid].BSR_bytes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//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 lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) {
|
||||||
if (mac->active_RLC_bearer[lcid - 1]) { // todo
|
if (mac->logicalChannelConfig[lcid - 1] != NULL) { // todo
|
||||||
int lcgid = mac->scheduling_info.LCGID[lcid - 1];
|
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
|
||||||
if (lcgid < NR_MAX_NUM_LCGID) {
|
if (lcgid < NR_MAX_NUM_LCGID) {
|
||||||
lcgid_buffer_remain[lcgid] += mac->scheduling_info.LCID_buffer_remain[lcid - 1];
|
lcgid_buffer_remain[lcgid] += mac->scheduling_info.lc_sched_info[lcid - 1].LCID_buffer_remain;
|
||||||
}
|
}
|
||||||
|
|
||||||
mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(module_idP, mac->crnti,gNB_index,frameP,slotP,ENB_FLAG_NO,MBMS_FLAG_NO, lcid, 0, 0);
|
mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(module_idP, mac->crnti,gNB_index,frameP,slotP,ENB_FLAG_NO,MBMS_FLAG_NO, lcid, 0, 0);
|
||||||
@@ -1172,13 +1197,13 @@ 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.LCID_status[lcid - 1] = 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
|
||||||
if (lcgid < NR_MAX_NUM_LCGID) {
|
if (lcgid < NR_MAX_NUM_LCGID) {
|
||||||
num_lcid_with_data ++;
|
num_lcid_with_data ++;
|
||||||
// sum lcid buffer which has same lcgid
|
// sum lcid buffer which has same lcgid
|
||||||
mac->scheduling_info.BSR_bytes[lcgid] += rlc_status.bytes_in_buffer;
|
mac->scheduling_info.lcg_sched_info[lcgid].BSR_bytes += rlc_status.bytes_in_buffer;
|
||||||
//Fill in the array
|
//Fill in the array
|
||||||
array_index = 0;
|
array_index = 0;
|
||||||
|
|
||||||
@@ -1221,7 +1246,7 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t
|
|||||||
"[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%d data become available at frame %d slot %d\n",
|
||||||
module_idP,
|
module_idP,
|
||||||
lcid,
|
lcid,
|
||||||
mac->scheduling_info.LCGID[lcid - 1],
|
mac->scheduling_info.lc_sched_info[lcid - 1].LCGID,
|
||||||
frameP,
|
frameP,
|
||||||
slotP);
|
slotP);
|
||||||
break;
|
break;
|
||||||
@@ -1241,7 +1266,7 @@ bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t
|
|||||||
|
|
||||||
//Store Buffer Occupancy in remain buffers for next TTI
|
//Store Buffer Occupancy in remain buffers for next TTI
|
||||||
for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) {
|
for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) {
|
||||||
mac->scheduling_info.LCID_buffer_remain[lcid - 1] = lcid_bytes_in_buffer[lcid - 1];
|
mac->scheduling_info.lc_sched_info[lcid - 1].LCID_buffer_remain = lcid_bytes_in_buffer[lcid - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
return bsr_regular_triggered;
|
return bsr_regular_triggered;
|
||||||
@@ -2629,7 +2654,7 @@ int nr_ue_get_sdu_mac_ce_pre(module_id_t module_idP,
|
|||||||
mac_ce_p->phr_header_len = 0; //sizeof(SCH_SUBHEADER_FIXED);
|
mac_ce_p->phr_header_len = 0; //sizeof(SCH_SUBHEADER_FIXED);
|
||||||
int lcg_id = 0;
|
int lcg_id = 0;
|
||||||
while (lcg_id < NR_MAX_NUM_LCGID) {
|
while (lcg_id < NR_MAX_NUM_LCGID) {
|
||||||
if (mac->scheduling_info.BSR_bytes[lcg_id]) {
|
if (mac->scheduling_info.lcg_sched_info[lcg_id].BSR_bytes) {
|
||||||
num_lcg_id_with_data++;
|
num_lcg_id_with_data++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2710,11 +2735,17 @@ void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP,
|
|||||||
int lcg_id_bsr_trunc = 0;
|
int lcg_id_bsr_trunc = 0;
|
||||||
for (lcg_id = 0; lcg_id < NR_MAX_NUM_LCGID; lcg_id++) {
|
for (lcg_id = 0; lcg_id < NR_MAX_NUM_LCGID; lcg_id++) {
|
||||||
if (mac_ce_p->bsr_ce_len == sizeof(NR_BSR_SHORT)) {
|
if (mac_ce_p->bsr_ce_len == sizeof(NR_BSR_SHORT)) {
|
||||||
mac->scheduling_info.BSR[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_SHORT_BSR_TABLE, NR_SHORT_BSR_TABLE_SIZE, mac->scheduling_info.BSR_bytes[lcg_id]);
|
mac->scheduling_info.lcg_sched_info[lcg_id].BSR =
|
||||||
|
nr_locate_BsrIndexByBufferSize(NR_SHORT_BSR_TABLE,
|
||||||
|
NR_SHORT_BSR_TABLE_SIZE,
|
||||||
|
mac->scheduling_info.lcg_sched_info[lcg_id].BSR_bytes);
|
||||||
} else {
|
} else {
|
||||||
mac->scheduling_info.BSR[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_LONG_BSR_TABLE, NR_LONG_BSR_TABLE_SIZE, mac->scheduling_info.BSR_bytes[lcg_id]);
|
mac->scheduling_info.lcg_sched_info[lcg_id].BSR =
|
||||||
|
nr_locate_BsrIndexByBufferSize(NR_LONG_BSR_TABLE,
|
||||||
|
NR_LONG_BSR_TABLE_SIZE,
|
||||||
|
mac->scheduling_info.lcg_sched_info[lcg_id].BSR_bytes);
|
||||||
}
|
}
|
||||||
if (mac->scheduling_info.BSR_bytes[lcg_id]) {
|
if (mac->scheduling_info.lcg_sched_info[lcg_id].BSR_bytes) {
|
||||||
num_lcg_id_with_data++;
|
num_lcg_id_with_data++;
|
||||||
lcg_id_bsr_trunc = lcg_id;
|
lcg_id_bsr_trunc = lcg_id;
|
||||||
}
|
}
|
||||||
@@ -2748,8 +2779,8 @@ void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP,
|
|||||||
// REPORT SHORT TRUNCATED BSR
|
// REPORT SHORT TRUNCATED BSR
|
||||||
//Get LCGID of highest priority LCID with data (todo)
|
//Get LCGID of highest priority LCID with data (todo)
|
||||||
for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) {
|
for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) {
|
||||||
lcg_id = mac->scheduling_info.LCGID[lcid - 1];
|
lcg_id = mac->scheduling_info.lc_sched_info[lcid - 1].LCGID;
|
||||||
if ((lcg_id < NR_MAX_NUM_LCGID) && (mac->scheduling_info.BSR_bytes[lcg_id])) {
|
if ((lcg_id < NR_MAX_NUM_LCGID) && (mac->scheduling_info.lcg_sched_info[lcg_id].BSR_bytes)) {
|
||||||
lcg_id_bsr_trunc = lcg_id;
|
lcg_id_bsr_trunc = lcg_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2775,25 +2806,29 @@ void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP,
|
|||||||
} else if (mac_ce_p->bsr_header_len == sizeof(NR_MAC_SUBHEADER_SHORT)) {
|
} else if (mac_ce_p->bsr_header_len == sizeof(NR_MAC_SUBHEADER_SHORT)) {
|
||||||
mac_ce_p->bsr_s = NULL;
|
mac_ce_p->bsr_s = NULL;
|
||||||
mac_ce_p->bsr_t = NULL;
|
mac_ce_p->bsr_t = NULL;
|
||||||
mac_ce_p->bsr_l->Buffer_size0 = mac->scheduling_info.BSR[0];
|
mac_ce_p->bsr_l->Buffer_size0 = mac->scheduling_info.lcg_sched_info[0].BSR;
|
||||||
mac_ce_p->bsr_l->Buffer_size1 = mac->scheduling_info.BSR[1];
|
mac_ce_p->bsr_l->Buffer_size1 = mac->scheduling_info.lcg_sched_info[1].BSR;
|
||||||
mac_ce_p->bsr_l->Buffer_size2 = mac->scheduling_info.BSR[2];
|
mac_ce_p->bsr_l->Buffer_size2 = mac->scheduling_info.lcg_sched_info[2].BSR;
|
||||||
mac_ce_p->bsr_l->Buffer_size3 = mac->scheduling_info.BSR[3];
|
mac_ce_p->bsr_l->Buffer_size3 = mac->scheduling_info.lcg_sched_info[3].BSR;
|
||||||
mac_ce_p->bsr_l->Buffer_size4 = mac->scheduling_info.BSR[4];
|
mac_ce_p->bsr_l->Buffer_size4 = mac->scheduling_info.lcg_sched_info[4].BSR;
|
||||||
mac_ce_p->bsr_l->Buffer_size5 = mac->scheduling_info.BSR[5];
|
mac_ce_p->bsr_l->Buffer_size5 = mac->scheduling_info.lcg_sched_info[5].BSR;
|
||||||
mac_ce_p->bsr_l->Buffer_size6 = mac->scheduling_info.BSR[6];
|
mac_ce_p->bsr_l->Buffer_size6 = mac->scheduling_info.lcg_sched_info[6].BSR;
|
||||||
mac_ce_p->bsr_l->Buffer_size7 = mac->scheduling_info.BSR[7];
|
mac_ce_p->bsr_l->Buffer_size7 = mac->scheduling_info.lcg_sched_info[7].BSR;
|
||||||
LOG_D(NR_MAC, "[UE %d] Frame %d subframe %d BSR Trig=%d report LONG BSR (level LCGID0 %d,level LCGID1 %d,level LCGID2 %d,level LCGID3 %d level LCGID4 %d,level LCGID5 %d,level LCGID6 %d,level LCGID7 %d)\n",
|
LOG_D(NR_MAC,
|
||||||
module_idP, frameP, subframe,
|
"[UE %d] Frame %d subframe %d BSR Trig=%d report LONG BSR (level LCGID0 %d,level LCGID1 %d,level LCGID2 %d,level LCGID3 "
|
||||||
|
"%d level LCGID4 %d,level LCGID5 %d,level LCGID6 %d,level LCGID7 %d)\n",
|
||||||
|
module_idP,
|
||||||
|
frameP,
|
||||||
|
subframe,
|
||||||
mac->BSR_reporting_active,
|
mac->BSR_reporting_active,
|
||||||
mac->scheduling_info.BSR[0],
|
mac->scheduling_info.lcg_sched_info[0].BSR,
|
||||||
mac->scheduling_info.BSR[1],
|
mac->scheduling_info.lcg_sched_info[1].BSR,
|
||||||
mac->scheduling_info.BSR[2],
|
mac->scheduling_info.lcg_sched_info[2].BSR,
|
||||||
mac->scheduling_info.BSR[3],
|
mac->scheduling_info.lcg_sched_info[3].BSR,
|
||||||
mac->scheduling_info.BSR[4],
|
mac->scheduling_info.lcg_sched_info[4].BSR,
|
||||||
mac->scheduling_info.BSR[5],
|
mac->scheduling_info.lcg_sched_info[5].BSR,
|
||||||
mac->scheduling_info.BSR[6],
|
mac->scheduling_info.lcg_sched_info[6].BSR,
|
||||||
mac->scheduling_info.BSR[7]);
|
mac->scheduling_info.lcg_sched_info[7].BSR);
|
||||||
} else if (mac_ce_p->bsr_header_len == sizeof(NR_MAC_SUBHEADER_FIXED)) {
|
} else if (mac_ce_p->bsr_header_len == sizeof(NR_MAC_SUBHEADER_FIXED)) {
|
||||||
mac_ce_p->bsr_l = NULL;
|
mac_ce_p->bsr_l = NULL;
|
||||||
|
|
||||||
@@ -2801,19 +2836,27 @@ void nr_ue_get_sdu_mac_ce_post(module_id_t module_idP,
|
|||||||
//Truncated BSR
|
//Truncated BSR
|
||||||
mac_ce_p->bsr_s = NULL;
|
mac_ce_p->bsr_s = NULL;
|
||||||
mac_ce_p->bsr_t->LcgID = lcg_id_bsr_trunc;
|
mac_ce_p->bsr_t->LcgID = lcg_id_bsr_trunc;
|
||||||
mac_ce_p->bsr_t->Buffer_size = mac->scheduling_info.BSR[lcg_id_bsr_trunc];
|
mac_ce_p->bsr_t->Buffer_size = mac->scheduling_info.lcg_sched_info[lcg_id_bsr_trunc].BSR;
|
||||||
LOG_D(NR_MAC, "[UE %d] Frame %d subframe %d BSR Trig=%d report TRUNCATED BSR with level %d for LCGID %d\n",
|
LOG_D(NR_MAC,
|
||||||
module_idP, frameP, subframe,
|
"[UE %d] Frame %d subframe %d BSR Trig=%d report TRUNCATED BSR with level %d for LCGID %d\n",
|
||||||
|
module_idP,
|
||||||
|
frameP,
|
||||||
|
subframe,
|
||||||
mac->BSR_reporting_active,
|
mac->BSR_reporting_active,
|
||||||
mac->scheduling_info.BSR[lcg_id_bsr_trunc], lcg_id_bsr_trunc);
|
mac->scheduling_info.lcg_sched_info[lcg_id_bsr_trunc].BSR,
|
||||||
|
lcg_id_bsr_trunc);
|
||||||
} else {
|
} else {
|
||||||
mac_ce_p->bsr_t = NULL;
|
mac_ce_p->bsr_t = NULL;
|
||||||
mac_ce_p->bsr_s->LcgID = lcg_id_bsr_trunc;
|
mac_ce_p->bsr_s->LcgID = lcg_id_bsr_trunc;
|
||||||
mac_ce_p->bsr_s->Buffer_size = mac->scheduling_info.BSR[lcg_id_bsr_trunc];
|
mac_ce_p->bsr_s->Buffer_size = mac->scheduling_info.lcg_sched_info[lcg_id_bsr_trunc].BSR;
|
||||||
LOG_D(NR_MAC, "[UE %d] Frame %d subframe %d BSR Trig=%d report SHORT BSR with level %d for LCGID %d\n",
|
LOG_D(NR_MAC,
|
||||||
module_idP, frameP, subframe,
|
"[UE %d] Frame %d subframe %d BSR Trig=%d report SHORT BSR with level %d for LCGID %d\n",
|
||||||
|
module_idP,
|
||||||
|
frameP,
|
||||||
|
subframe,
|
||||||
mac->BSR_reporting_active,
|
mac->BSR_reporting_active,
|
||||||
mac->scheduling_info.BSR[lcg_id_bsr_trunc], lcg_id_bsr_trunc);
|
mac->scheduling_info.lcg_sched_info[lcg_id_bsr_trunc].BSR,
|
||||||
|
lcg_id_bsr_trunc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2842,6 +2885,237 @@ 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)
|
||||||
|
{
|
||||||
|
// count number of logical channels with same priority as curr_lcid
|
||||||
|
uint8_t same_priority_count = 0;
|
||||||
|
uint8_t curr_lcid = lcid_ordered_array[start];
|
||||||
|
NR_LogicalChannelConfig_t *lc_config_curr = mac->logicalChannelConfig[curr_lcid - 1];
|
||||||
|
for (uint8_t index = start; index < total_active_lcids; index++) {
|
||||||
|
uint8_t next_lcid = lcid_ordered_array[index];
|
||||||
|
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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG_D(NR_MAC, "Number of lcids with same priority as that of lcid %d is %d\n", curr_lcid, same_priority_count);
|
||||||
|
return same_priority_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
long get_num_bytes_to_reqlc(NR_UE_MAC_INST_t *mac,
|
||||||
|
uint8_t same_priority_count,
|
||||||
|
uint8_t lc_num,
|
||||||
|
uint16_t buflen_remain_ep,
|
||||||
|
int16_t buflen_remain,
|
||||||
|
uint8_t round_id,
|
||||||
|
uint32_t *bytes_read_fromlc,
|
||||||
|
long *target)
|
||||||
|
{
|
||||||
|
/* 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 pbr = nr_get_pbr(lc_config->ul_SpecificParameters->prioritisedBitRate);
|
||||||
|
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;
|
||||||
|
|
||||||
|
long num_remaining_bytes = 0;
|
||||||
|
long num_bytes_requested = 0;
|
||||||
|
if (round_id == 0) { // initial round
|
||||||
|
uint16_t pdu_remain = (same_priority_count > 1) ? buflen_remain_ep : buflen_remain;
|
||||||
|
num_bytes_requested = (pdu_remain < pbr) ? min(pdu_remain, lcid_remain_buffer) : min(pbr, lcid_remain_buffer);
|
||||||
|
num_remaining_bytes = *target - bytes_read_fromlc[lc_num - 1];
|
||||||
|
num_bytes_requested = min(num_bytes_requested, num_remaining_bytes);
|
||||||
|
} else { // from first round
|
||||||
|
if (same_priority_count > 1) {
|
||||||
|
num_bytes_requested = min(buflen_remain_ep, lcid_remain_buffer);
|
||||||
|
num_remaining_bytes = buflen_remain_ep - bytes_read_fromlc[lc_num - 1];
|
||||||
|
num_bytes_requested = min(num_bytes_requested, num_remaining_bytes);
|
||||||
|
} else {
|
||||||
|
num_bytes_requested = min(buflen_remain, lcid_remain_buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AssertFatal(num_remaining_bytes >= 0, "the total number of bytes allocated until target length is greater than expected\n");
|
||||||
|
LOG_D(NR_MAC, "number of bytes requested for lcid %d is %li\n", lc_num, num_bytes_requested);
|
||||||
|
|
||||||
|
return num_bytes_requested;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get_dataavailability_buffers(uint8_t total_active_lcids, int *lcid_ordered_array, bool *data_status_lcbuffers)
|
||||||
|
{
|
||||||
|
// check whether there is any data in the rlc buffer corresponding to active lcs
|
||||||
|
for (uint8_t id = 0; id < total_active_lcids; id++) {
|
||||||
|
int lcid = lcid_ordered_array[id];
|
||||||
|
if (data_status_lcbuffers[lcid - 1]) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t select_logical_channels(NR_UE_MAC_INST_t *mac, uint8_t *num_active_lcids, int *active_lcids)
|
||||||
|
{
|
||||||
|
// (TODO: selection of logical channels for logical channel prioritization procedure as per 5.4.3.1.2 Selection of logical
|
||||||
|
// channels, TS38.321)
|
||||||
|
|
||||||
|
// 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++) {
|
||||||
|
uint8_t lcid = lc_bearer->lcids_ordered;
|
||||||
|
if (mac->scheduling_info.lc_sched_info[lcid - 1].Bj > 0) {
|
||||||
|
active_lcids[*num_active_lcids] = 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,
|
||||||
|
frame_t frameP,
|
||||||
|
sub_frame_t subframe,
|
||||||
|
uint8_t gNB_index,
|
||||||
|
uint16_t buflen,
|
||||||
|
int16_t *buflen_remain,
|
||||||
|
int lcid,
|
||||||
|
uint8_t **pdu,
|
||||||
|
uint32_t *counter,
|
||||||
|
uint8_t count_same_priority_lcids,
|
||||||
|
uint16_t buflen_ep,
|
||||||
|
uint32_t *lcids_bytes_tot,
|
||||||
|
uint16_t *num_sdus,
|
||||||
|
NR_UE_MAC_CE_INFO *mac_ce_p,
|
||||||
|
bool *lcids_data_status,
|
||||||
|
uint8_t *num_lcids_same_priority)
|
||||||
|
{
|
||||||
|
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
|
||||||
|
NR_UE_SCHEDULING_INFO *sched_info = &mac->scheduling_info;
|
||||||
|
const uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_LONG);
|
||||||
|
|
||||||
|
/* prepare the MAC sdu */
|
||||||
|
int32_t lcid_remain_buffer = sched_info->lc_sched_info[lcid - 1].LCID_buffer_remain;
|
||||||
|
LOG_D(NR_MAC,
|
||||||
|
"In %s: [UE %d] [%d.%d] lcp round = %d, remaining mac pdu length = %d, lcid buffer remaining = %d, lcid = %d \n",
|
||||||
|
__FUNCTION__,
|
||||||
|
module_idP,
|
||||||
|
frameP,
|
||||||
|
subframe,
|
||||||
|
*counter,
|
||||||
|
*buflen_remain,
|
||||||
|
lcid_remain_buffer,
|
||||||
|
lcid);
|
||||||
|
|
||||||
|
// Pointer used to build the MAC sub-PDU headers in the ULSCH buffer for each SDU
|
||||||
|
NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *)(*pdu);
|
||||||
|
|
||||||
|
*pdu += sh_size;
|
||||||
|
|
||||||
|
// number of bytes requested from RLC for each LCID
|
||||||
|
long target = 0;
|
||||||
|
long bytes_requested =
|
||||||
|
get_num_bytes_to_reqlc(mac, count_same_priority_lcids, lcid, buflen_ep, *buflen_remain, *counter, lcids_bytes_tot, &target);
|
||||||
|
|
||||||
|
uint16_t sdu_length = mac_rlc_data_req(module_idP,
|
||||||
|
mac->crnti,
|
||||||
|
gNB_index,
|
||||||
|
frameP,
|
||||||
|
ENB_FLAG_NO,
|
||||||
|
MBMS_FLAG_NO,
|
||||||
|
lcid,
|
||||||
|
bytes_requested,
|
||||||
|
(char *)(*pdu),
|
||||||
|
0,
|
||||||
|
0);
|
||||||
|
|
||||||
|
AssertFatal(bytes_requested >= sdu_length,
|
||||||
|
"In %s: LCID = 0x%02x RLC has segmented %d bytes but MAC has max %li remaining bytes\n",
|
||||||
|
__FUNCTION__,
|
||||||
|
lcid,
|
||||||
|
sdu_length,
|
||||||
|
bytes_requested);
|
||||||
|
|
||||||
|
// Decrement Bj by the total size of MAC SDUs(RLC PDU) served to logical channel
|
||||||
|
// 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
|
||||||
|
// 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;
|
||||||
|
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",
|
||||||
|
lcid,
|
||||||
|
sdu_length,
|
||||||
|
lcid,
|
||||||
|
sched_info->lc_sched_info[lcid - 1].Bj);
|
||||||
|
|
||||||
|
if (sdu_length > 0) {
|
||||||
|
LOG_D(NR_MAC,
|
||||||
|
"In %s: [UE %d] [%d.%d] UL-DXCH -> ULSCH, Generating UL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID "
|
||||||
|
"0x%02x (buflen (TBS) %d bytes)\n",
|
||||||
|
__FUNCTION__,
|
||||||
|
module_idP,
|
||||||
|
frameP,
|
||||||
|
subframe,
|
||||||
|
(*num_sdus) + 1,
|
||||||
|
sdu_length,
|
||||||
|
lcid,
|
||||||
|
buflen);
|
||||||
|
|
||||||
|
header->R = 0;
|
||||||
|
header->F = 1;
|
||||||
|
header->LCID = lcid;
|
||||||
|
header->L = htons(sdu_length);
|
||||||
|
|
||||||
|
#ifdef ENABLE_MAC_PAYLOAD_DEBUG
|
||||||
|
LOG_I(NR_MAC, "In %s: dumping MAC sub-header with length %d: \n", __FUNCTION__, sh_size);
|
||||||
|
log_dump(NR_MAC, header, sh_size, LOG_DUMP_CHAR, "\n");
|
||||||
|
LOG_I(NR_MAC, "In %s: dumping MAC SDU with length %d \n", __FUNCTION__, sdu_length);
|
||||||
|
log_dump(NR_MAC, *pdu, sdu_length, LOG_DUMP_CHAR, "\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*pdu += sdu_length;
|
||||||
|
mac_ce_p->sdu_length_total += sdu_length;
|
||||||
|
mac_ce_p->total_mac_pdu_header_len += sh_size;
|
||||||
|
|
||||||
|
(*num_sdus)++;
|
||||||
|
} else {
|
||||||
|
*pdu -= sh_size;
|
||||||
|
lcids_data_status[lcid - 1] = false;
|
||||||
|
(*num_lcids_same_priority)--;
|
||||||
|
LOG_D(NR_MAC, "In %s: no data to transmit for RB with LCID 0x%02x\n and hence set to false", __FUNCTION__, lcid);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size);
|
||||||
|
|
||||||
|
// Update Buffer remain and BSR bytes after transmission
|
||||||
|
NR_LC_SCHEDULING_INFO *lc_info = &sched_info->lc_sched_info[0] + lcid - 1;
|
||||||
|
NR_LCG_SCHEDULING_INFO *lcg_info = &sched_info->lcg_sched_info[0];
|
||||||
|
lc_info->LCID_buffer_remain -= sdu_length;
|
||||||
|
(lcg_info + lc_info->LCGID)->BSR_bytes -= sdu_length;
|
||||||
|
LOG_D(NR_MAC,
|
||||||
|
"[UE %d] Update BSR [%d.%d] BSR_bytes for LCG%d = %d\n",
|
||||||
|
module_idP,
|
||||||
|
frameP,
|
||||||
|
subframe,
|
||||||
|
lc_info->LCGID,
|
||||||
|
(lcg_info + lc_info->LCGID)->BSR_bytes);
|
||||||
|
if ((lcg_info + lc_info->LCGID)->BSR_bytes < 0)
|
||||||
|
(lcg_info + lc_info->LCGID)->BSR_bytes = 0;
|
||||||
|
|
||||||
|
// update number of bytes served from the current lcid
|
||||||
|
lcids_bytes_tot[lcid - 1] += (sdu_length + (count_same_priority_lcids > 1 ? 1 : 0) * sh_size);
|
||||||
|
|
||||||
|
if ((*counter == 0 && lcids_bytes_tot[lcid - 1] >= target)
|
||||||
|
|| (count_same_priority_lcids > 1
|
||||||
|
&& lcids_bytes_tot[lcid - 1] >= buflen_ep)) { // only prioritized bit rate should be taken from logical channel in
|
||||||
|
// the first lcp run except when infinity
|
||||||
|
LOG_D(NR_MAC,
|
||||||
|
"In %s: total number bytes read from rlc buffer for lcid %d are %d\n",
|
||||||
|
__FUNCTION__,
|
||||||
|
lcid,
|
||||||
|
lcids_bytes_tot[lcid - 1]);
|
||||||
|
(*num_lcids_same_priority)--;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function: to fetch data to be transmitted from RLC, place it in the ULSCH PDU buffer
|
* Function: to fetch data to be transmitted from RLC, place it in the ULSCH PDU buffer
|
||||||
to generate the complete MAC PDU with sub-headers and MAC CEs according to ULSCH MAC PDU generation (6.1.2 TS 38.321)
|
to generate the complete MAC PDU with sub-headers and MAC CEs according to ULSCH MAC PDU generation (6.1.2 TS 38.321)
|
||||||
@@ -2872,7 +3146,6 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
|
|||||||
//mac_ce_p->phr_ce_len = 0;
|
//mac_ce_p->phr_ce_len = 0;
|
||||||
//mac_ce_p->phr_header_len = 0;
|
//mac_ce_p->phr_header_len = 0;
|
||||||
|
|
||||||
uint16_t sdu_length = 0;
|
|
||||||
uint16_t num_sdus = 0;
|
uint16_t num_sdus = 0;
|
||||||
mac_ce_p->sdu_length_total = 0;
|
mac_ce_p->sdu_length_total = 0;
|
||||||
NR_BSR_SHORT bsr_short, bsr_truncated;
|
NR_BSR_SHORT bsr_short, bsr_truncated;
|
||||||
@@ -2883,113 +3156,120 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
|
|||||||
//NR_POWER_HEADROOM_CMD phr;
|
//NR_POWER_HEADROOM_CMD phr;
|
||||||
//mac_ce_p->phr_p = &phr;
|
//mac_ce_p->phr_p = &phr;
|
||||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
|
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
|
||||||
|
|
||||||
|
NR_UE_SCHEDULING_INFO *sched_info = &mac->scheduling_info;
|
||||||
//int highest_priority = 16;
|
//int highest_priority = 16;
|
||||||
const uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_LONG);
|
const uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_LONG);
|
||||||
|
|
||||||
// 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;
|
||||||
|
|
||||||
//nr_ue_get_sdu_mac_ce_pre updates all mac_ce related header field related to length
|
// 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
|
||||||
|
bool lcids_data_status[NR_MAX_NUM_LCID] = {0};
|
||||||
|
memset(lcids_data_status, 1, NR_MAX_NUM_LCID);
|
||||||
|
|
||||||
|
uint32_t lcp_allocation_counter =
|
||||||
|
0; // in the first run all the lc are allocated as per bj and prioritized bit rate but in subsequent runs, no need to consider
|
||||||
|
// bj and prioritized bit rate but just consider priority
|
||||||
|
uint16_t buflen_ep = 0; // this variable holds the length in bytes in mac pdu when multiple equal priority channels are present
|
||||||
|
// because as per standard(TS38.321), all equal priority channels should be served equally
|
||||||
|
|
||||||
|
// nr_ue_get_sdu_mac_ce_pre updates all mac_ce related header field related to length
|
||||||
mac_ce_p->tot_mac_ce_len = nr_ue_get_sdu_mac_ce_pre(module_idP, CC_id, frameP, subframe, gNB_index, ulsch_buffer, buflen, mac_ce_p);
|
mac_ce_p->tot_mac_ce_len = nr_ue_get_sdu_mac_ce_pre(module_idP, CC_id, frameP, subframe, gNB_index, ulsch_buffer, buflen, mac_ce_p);
|
||||||
mac_ce_p->total_mac_pdu_header_len = mac_ce_p->tot_mac_ce_len;
|
mac_ce_p->total_mac_pdu_header_len = mac_ce_p->tot_mac_ce_len;
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
// Check for DCCH first
|
// selection of logical channels
|
||||||
// TO DO: Multiplex in the order defined by the logical channel prioritization
|
select_logical_channels(mac, &avail_lcids_count, lcids_bj_pos);
|
||||||
for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) {
|
|
||||||
if (!mac->active_RLC_bearer[lcid - 1])
|
|
||||||
continue;
|
|
||||||
buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size);
|
|
||||||
|
|
||||||
LOG_D(NR_MAC,
|
// multiplex in the order of highest priority
|
||||||
"[UE %d] [%d.%d] UL-DXCH -> ULSCH, RLC with LCID 0x%02x (TBS %d bytes, sdu_length_total %d bytes, MAC header len %d "
|
do {
|
||||||
"bytes, buflen_remain %d bytes)\n",
|
/*
|
||||||
module_idP,
|
go until there is space availabile in the MAC PDU and there is data available in RLC buffers of active logical channels
|
||||||
frameP,
|
*/
|
||||||
subframe,
|
uint8_t num_lcids_same_priority = 0;
|
||||||
lcid,
|
uint8_t count_same_priority_lcids = 0;
|
||||||
buflen,
|
|
||||||
mac_ce_p->sdu_length_total,
|
|
||||||
mac_ce_p->tot_mac_ce_len,
|
|
||||||
buflen_remain);
|
|
||||||
|
|
||||||
while (buflen_remain > 0) {
|
// variable used to store the total bytes read from rlc for each lcid
|
||||||
// Pointer used to build the MAC sub-PDU headers in the ULSCH buffer for each SDU
|
uint32_t lcids_bytes_tot[NR_MAX_NUM_LCID] = {0};
|
||||||
NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) pdu;
|
|
||||||
|
|
||||||
pdu += sh_size;
|
for (uint8_t id = 0; id < avail_lcids_count; id++) {
|
||||||
|
/*
|
||||||
|
loop over all logical channels in the order of priority. As stated in TS138.321 Section 5.4.3.1, in the first run, only
|
||||||
|
prioritized number of bytes are taken out from the corresponding RLC buffers of all active logical channels and if there is
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
int lcid = lcids_bj_pos[id];
|
||||||
|
|
||||||
sdu_length = mac_rlc_data_req(module_idP,
|
// 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->crnti,
|
// MAC PDU
|
||||||
gNB_index,
|
if (!sched_info->lc_sched_info[lcid - 1].LCID_status || !lcids_data_status[lcid - 1]) {
|
||||||
frameP,
|
lcids_data_status[lcid - 1] = false;
|
||||||
ENB_FLAG_NO,
|
continue;
|
||||||
MBMS_FLAG_NO,
|
}
|
||||||
lcid,
|
|
||||||
buflen_remain,
|
|
||||||
(char *)pdu,
|
|
||||||
0,
|
|
||||||
0);
|
|
||||||
|
|
||||||
AssertFatal(buflen_remain >= sdu_length,
|
// count number of lc with same priority as lcid
|
||||||
"LCID = 0x%02x RLC has segmented %d bytes but MAC has max %d remaining bytes\n",
|
if (!num_lcids_same_priority) {
|
||||||
lcid,
|
num_lcids_same_priority = count_same_priority_lcids =
|
||||||
sdu_length,
|
get_count_lcids_same_priority(mac, id, avail_lcids_count, lcids_bj_pos);
|
||||||
buflen_remain);
|
|
||||||
|
|
||||||
if (sdu_length > 0) {
|
|
||||||
LOG_D(NR_MAC,
|
|
||||||
"[UE %d] [%d.%d] UL-DXCH -> ULSCH, Generating UL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID 0x%02x "
|
|
||||||
"(buflen (TBS) %d bytes)\n",
|
|
||||||
module_idP,
|
|
||||||
frameP,
|
|
||||||
subframe,
|
|
||||||
num_sdus + 1,
|
|
||||||
sdu_length,
|
|
||||||
lcid,
|
|
||||||
buflen);
|
|
||||||
|
|
||||||
header->R = 0;
|
|
||||||
header->F = 1;
|
|
||||||
header->LCID = lcid;
|
|
||||||
header->L = htons(sdu_length);
|
|
||||||
|
|
||||||
#ifdef ENABLE_MAC_PAYLOAD_DEBUG
|
|
||||||
LOG_I(NR_MAC, "In %s: dumping MAC sub-header with length %d: \n", __FUNCTION__, sh_size);
|
|
||||||
log_dump(NR_MAC, header, sh_size, LOG_DUMP_CHAR, "\n");
|
|
||||||
LOG_I(NR_MAC, "In %s: dumping MAC SDU with length %d \n", __FUNCTION__, sdu_length);
|
|
||||||
log_dump(NR_MAC, pdu, sdu_length, LOG_DUMP_CHAR, "\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pdu += sdu_length;
|
|
||||||
mac_ce_p->sdu_length_total += sdu_length;
|
|
||||||
mac_ce_p->total_mac_pdu_header_len += sh_size;
|
|
||||||
|
|
||||||
num_sdus++;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
pdu -= sh_size;
|
|
||||||
LOG_D(NR_MAC, "no data to transmit for RB with LCID 0x%02x\n", lcid);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
//Update Buffer remain and BSR bytes after transmission
|
|
||||||
mac->scheduling_info.LCID_buffer_remain[lcid - 1] -= sdu_length;
|
|
||||||
mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid - 1]] -= sdu_length;
|
|
||||||
LOG_D(NR_MAC,
|
LOG_D(NR_MAC,
|
||||||
"[UE %d] Update BSR [%d.%d] BSR_bytes for LCG%d=%d\n",
|
"In %s: [UE %d] [%d.%d] UL-DXCH -> ULSCH, RLC with LCID 0x%02x (TBS %d bytes, sdu_length_total %d bytes, MAC header "
|
||||||
|
"len %d bytes,"
|
||||||
|
"buflen_remain %d bytes)\n",
|
||||||
|
__FUNCTION__,
|
||||||
module_idP,
|
module_idP,
|
||||||
frameP,
|
frameP,
|
||||||
subframe,
|
subframe,
|
||||||
mac->scheduling_info.LCGID[lcid - 1],
|
lcid,
|
||||||
mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid - 1]]);
|
buflen,
|
||||||
if (mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid - 1]] < 0)
|
mac_ce_p->sdu_length_total,
|
||||||
mac->scheduling_info.BSR_bytes[mac->scheduling_info.LCGID[lcid - 1]] = 0;
|
mac_ce_p->tot_mac_ce_len,
|
||||||
|
buflen_remain);
|
||||||
|
|
||||||
|
if (num_lcids_same_priority == count_same_priority_lcids) {
|
||||||
|
buflen_ep = (buflen_remain - (count_same_priority_lcids * sh_size)) / count_same_priority_lcids;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (buflen_remain > 0) {
|
||||||
|
/*
|
||||||
|
loops until the requested number of bytes from MAC to RLC are placed in the MAC PDU. The number of requested bytes
|
||||||
|
depends on whether it is the first run or otherwise because in the first run only prioritited number of bytes of all
|
||||||
|
active logical channels in the order of priority are placed in the MAC PDU. The 'get_num_bytes_to_reqlc' calculates
|
||||||
|
the target number of bytes to request from RLC via 'mac_rlc_data_req'
|
||||||
|
*/
|
||||||
|
if (!fill_mac_sdu(module_idP,
|
||||||
|
frameP,
|
||||||
|
subframe,
|
||||||
|
gNB_index,
|
||||||
|
buflen,
|
||||||
|
&buflen_remain,
|
||||||
|
lcid,
|
||||||
|
&pdu,
|
||||||
|
&lcp_allocation_counter,
|
||||||
|
count_same_priority_lcids,
|
||||||
|
buflen_ep,
|
||||||
|
lcids_bytes_tot,
|
||||||
|
&num_sdus,
|
||||||
|
mac_ce_p,
|
||||||
|
lcids_data_status,
|
||||||
|
&num_lcids_same_priority)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
lcp_allocation_counter++;
|
||||||
|
} while (buflen_remain > 0 && get_dataavailability_buffers(avail_lcids_count, lcids_bj_pos, lcids_data_status));
|
||||||
|
|
||||||
//nr_ue_get_sdu_mac_ce_post recalculates all mac_ce related header fields since buffer has been changed after mac_rlc_data_req.
|
//nr_ue_get_sdu_mac_ce_post recalculates all mac_ce related header fields since buffer has been changed after mac_rlc_data_req.
|
||||||
//Also, BSR padding is handled here after knowing mac_ce_p->sdu_length_total.
|
//Also, BSR padding is handled here after knowing mac_ce_p->sdu_length_total.
|
||||||
@@ -3058,3 +3338,80 @@ void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UL_TIME_ALIG
|
|||||||
dl_config->number_pdus += 1;
|
dl_config->number_pdus += 1;
|
||||||
ul_time_alignment->ta_apply = false;
|
ul_time_alignment->ta_apply = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t nr_get_pbr(uint8_t prioritizedbitrate)
|
||||||
|
{
|
||||||
|
int32_t pbr = -1;
|
||||||
|
switch (prioritizedbitrate) {
|
||||||
|
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps0:
|
||||||
|
pbr = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8:
|
||||||
|
pbr = 8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps16:
|
||||||
|
pbr = 16;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps32:
|
||||||
|
pbr = 32;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps64:
|
||||||
|
pbr = 64;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps128:
|
||||||
|
pbr = 128;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps256:
|
||||||
|
pbr = 256;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps512:
|
||||||
|
pbr = 512;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps1024:
|
||||||
|
pbr = 1024;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps2048:
|
||||||
|
pbr = 2048;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps4096:
|
||||||
|
pbr = 4096;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8192:
|
||||||
|
pbr = 8192;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps16384:
|
||||||
|
pbr = 16384;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps32768:
|
||||||
|
pbr = 32768;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps65536:
|
||||||
|
pbr = 65536;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity:
|
||||||
|
pbr = INT32_MAX;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
pbr = -1;
|
||||||
|
}
|
||||||
|
AssertFatal(pbr >= 0, "The proritized bit rate value is not one of the enum values\n");
|
||||||
|
uint32_t pbr_bytes =
|
||||||
|
(prioritizedbitrate < NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity) ? pbr * 1000 : pbr;
|
||||||
|
return pbr_bytes;
|
||||||
|
}
|
||||||
|
|||||||
@@ -460,8 +460,10 @@ void free_nr_noS1_bearer_config(NR_RadioBearerConfig_t **rbconfig,
|
|||||||
{
|
{
|
||||||
ASN_STRUCT_FREE(asn_DEF_NR_RadioBearerConfig, *rbconfig);
|
ASN_STRUCT_FREE(asn_DEF_NR_RadioBearerConfig, *rbconfig);
|
||||||
*rbconfig = NULL;
|
*rbconfig = NULL;
|
||||||
ASN_STRUCT_FREE(asn_DEF_NR_RLC_BearerConfig, *rlc_rbconfig);
|
if (rlc_rbconfig != NULL) {
|
||||||
*rlc_rbconfig = NULL;
|
ASN_STRUCT_FREE(asn_DEF_NR_RLC_BearerConfig, *rlc_rbconfig);
|
||||||
|
*rlc_rbconfig = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user