functions to map LCID to structures in the UE MAC
This commit is contained in:
@@ -91,6 +91,30 @@ fapi_nr_ul_config_request_pdu_t *lockGet_ul_config(NR_UE_MAC_INST_t *mac, frame_
|
||||
return pdu;
|
||||
}
|
||||
|
||||
static nr_lcordered_info_t *get_lc_info_from_lcid(NR_UE_MAC_INST_t *mac, NR_LogicalChannelIdentity_t lcid)
|
||||
{
|
||||
nr_lcordered_info_t *lc_info = NULL;
|
||||
for (int i = 0; i < mac->lc_ordered_list.count; i++) {
|
||||
if (mac->lc_ordered_list.array[i]->lcid == lcid) {
|
||||
lc_info = mac->lc_ordered_list.array[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return lc_info;
|
||||
}
|
||||
|
||||
static int lcid_buffer_index(NR_LogicalChannelIdentity_t lcid)
|
||||
{
|
||||
AssertFatal(lcid > 0 && lcid <= NR_MAX_NUM_LCID, "Invalid LCID %ld\n", lcid);
|
||||
return lcid - 1;
|
||||
}
|
||||
|
||||
static NR_LC_SCHEDULING_INFO *get_scheduling_info_from_lcid(NR_UE_MAC_INST_t *mac, NR_LogicalChannelIdentity_t lcid)
|
||||
{
|
||||
int idx = lcid_buffer_index(lcid);
|
||||
return &mac->scheduling_info.lc_sched_info[idx];
|
||||
}
|
||||
|
||||
void update_mac_timers(NR_UE_MAC_INST_t *mac)
|
||||
{
|
||||
nr_timer_tick(&mac->ra.contention_resolution_timer);
|
||||
@@ -1133,14 +1157,15 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info)
|
||||
measure Bj
|
||||
increment the value of Bj by product PBR * T
|
||||
*/
|
||||
NR_LC_SCHEDULING_INFO *sched_info = get_scheduling_info_from_lcid(mac, lcid);
|
||||
int T = 1; // time elapsed since Bj was last incremented
|
||||
int32_t bj = mac->scheduling_info.lc_sched_info[lcid - 1].Bj;
|
||||
int32_t bj = sched_info->Bj;
|
||||
bj += nr_get_pbr(lc_info->prioritisedBitRate) * T;
|
||||
if (lc_info->prioritisedBitRate == NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity)
|
||||
bj = nr_get_pbr(lc_info->prioritisedBitRate);
|
||||
|
||||
// bj > max bucket size, set bj to max bucket size, as in ts38.321 5.4.3.1 Logical Channel Prioritization
|
||||
mac->scheduling_info.lc_sched_info[lcid - 1].Bj = min(bj, bucketSize_max);
|
||||
sched_info->Bj = min(bj, bucketSize_max);
|
||||
}
|
||||
|
||||
// Call BSR procedure as described in Section 5.4.5 in 38.321
|
||||
@@ -1188,13 +1213,11 @@ bool nr_update_bsr(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP, uint8_t
|
||||
//uint8_t highest_priority = 16;
|
||||
uint8_t array_index = 0;
|
||||
// Reset All BSR Infos
|
||||
lcid_bytes_in_buffer[0] = 0;
|
||||
// TO BE NOTED LCID = 0 is excluded from buffers
|
||||
// so they need to be addressed with lcid - 1
|
||||
for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) {
|
||||
// Reset transmission status
|
||||
lcid_bytes_in_buffer[lcid - 1] = 0;
|
||||
mac->scheduling_info.lc_sched_info[lcid - 1].LCID_buffer_with_data = false;
|
||||
int idx = lcid_buffer_index(lcid);
|
||||
lcid_bytes_in_buffer[idx] = 0;
|
||||
mac->scheduling_info.lc_sched_info[idx].LCID_buffer_with_data = false;
|
||||
}
|
||||
|
||||
for (int lcgid = 0; lcgid < NR_MAX_NUM_LCGID; lcgid++) {
|
||||
@@ -1206,11 +1229,12 @@ bool nr_update_bsr(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP, uint8_t
|
||||
//Get Buffer Occupancy and fill lcid_reordered_array
|
||||
for (int i = 0; i < mac->lc_ordered_list.count; i++) {
|
||||
int lcid = mac->lc_ordered_list.array[i]->lcid;
|
||||
int lcgid = mac->scheduling_info.lc_sched_info[lcid - 1].LCGID;
|
||||
NR_LC_SCHEDULING_INFO *sched_info = get_scheduling_info_from_lcid(mac, lcid);
|
||||
int lcgid = sched_info->LCGID;
|
||||
|
||||
// Store already available data to transmit per Group
|
||||
if (lcgid < NR_MAX_NUM_LCGID) {
|
||||
lcgid_buffer_remain[lcgid] += mac->scheduling_info.lc_sched_info[lcid - 1].LCID_buffer_remain;
|
||||
lcgid_buffer_remain[lcgid] += sched_info->LCID_buffer_remain;
|
||||
}
|
||||
|
||||
mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mac->ue_id,
|
||||
@@ -1224,7 +1248,8 @@ bool nr_update_bsr(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP, uint8_t
|
||||
0,
|
||||
0);
|
||||
|
||||
lcid_bytes_in_buffer[lcid - 1] = rlc_status.bytes_in_buffer;
|
||||
int lc_idx = lcid_buffer_index(lcid);
|
||||
lcid_bytes_in_buffer[lc_idx] = rlc_status.bytes_in_buffer;
|
||||
|
||||
if (rlc_status.bytes_in_buffer > 0) {
|
||||
LOG_D(NR_MAC,
|
||||
@@ -1235,7 +1260,7 @@ bool nr_update_bsr(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP, uint8_t
|
||||
rlc_status.bytes_in_buffer,
|
||||
frameP,
|
||||
slotP);
|
||||
mac->scheduling_info.lc_sched_info[lcid - 1].LCID_buffer_with_data = true;
|
||||
sched_info->LCID_buffer_with_data = true;
|
||||
|
||||
//Update BSR_bytes and position in lcid_reordered_array only if Group is defined
|
||||
if (lcgid < NR_MAX_NUM_LCGID) {
|
||||
@@ -1276,7 +1301,7 @@ bool nr_update_bsr(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP, uint8_t
|
||||
|
||||
for (array_index = 0; array_index < num_lcid_with_data; array_index++) {
|
||||
int lcid = lcid_reordered_array[array_index];
|
||||
|
||||
NR_LC_SCHEDULING_INFO *sched_info = get_scheduling_info_from_lcid(mac, lcid);
|
||||
/* UL data, for a logical channel which belongs to a LCG, becomes available for transmission in the RLC entity
|
||||
either the data belongs to a logical channel with higher priority than the priorities of the logical channels
|
||||
which belong to any LCG and for which data is already available for transmission
|
||||
@@ -1287,7 +1312,7 @@ bool nr_update_bsr(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP, uint8_t
|
||||
"[UE %d] PDCCH Tick : MAC BSR Triggered LCID%d LCGID%ld data become available at frame %d slot %d\n",
|
||||
mac->ue_id,
|
||||
lcid,
|
||||
mac->scheduling_info.lc_sched_info[lcid - 1].LCGID,
|
||||
sched_info->LCGID,
|
||||
frameP,
|
||||
slotP);
|
||||
break;
|
||||
@@ -1306,7 +1331,8 @@ bool nr_update_bsr(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP, uint8_t
|
||||
|
||||
//Store Buffer Occupancy in remain buffers for next TTI
|
||||
for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) {
|
||||
mac->scheduling_info.lc_sched_info[lcid - 1].LCID_buffer_remain = lcid_bytes_in_buffer[lcid - 1];
|
||||
NR_LC_SCHEDULING_INFO *sched_info = get_scheduling_info_from_lcid(mac, lcid);
|
||||
sched_info->LCID_buffer_remain = lcid_bytes_in_buffer[lcid_buffer_index(lcid)];
|
||||
}
|
||||
|
||||
return bsr_regular_triggered;
|
||||
@@ -2722,7 +2748,8 @@ static void nr_ue_get_sdu_mac_ce_post(NR_UE_MAC_INST_t *mac,
|
||||
// REPORT SHORT TRUNCATED BSR
|
||||
// Get LCGID of highest priority LCID with data (todo)
|
||||
for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) {
|
||||
lcg_id = mac->scheduling_info.lc_sched_info[lcid - 1].LCGID;
|
||||
NR_LC_SCHEDULING_INFO *sched_info = get_scheduling_info_from_lcid(mac, lcid);
|
||||
lcg_id = sched_info->LCGID;
|
||||
if ((lcg_id < NR_MAX_NUM_LCGID) && (mac->scheduling_info.lcg_sched_info[lcg_id].BSR_bytes)) {
|
||||
lcg_id_bsr_trunc = lcg_id;
|
||||
}
|
||||
@@ -2854,16 +2881,11 @@ long get_num_bytes_to_reqlc(NR_UE_MAC_INST_t *mac,
|
||||
long *target)
|
||||
{
|
||||
/* Calculates the number of bytes the logical channel should request from the correcponding RLC buffer*/
|
||||
long found_pbr = -1;
|
||||
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;
|
||||
nr_lcordered_info_t *lc_info = get_lc_info_from_lcid(mac, lc_num);
|
||||
AssertFatal(lc_info, "Couldn't find logical channel with LCID %d\n", lc_num);
|
||||
uint32_t pbr = nr_get_pbr(lc_info->prioritisedBitRate);
|
||||
NR_LC_SCHEDULING_INFO *sched_info = get_scheduling_info_from_lcid(mac, lc_num);
|
||||
int32_t lcid_remain_buffer = sched_info->LCID_buffer_remain;
|
||||
*target = (same_priority_count > 1) ? min(buflen_remain_ep, pbr) : pbr;
|
||||
|
||||
long num_remaining_bytes = 0;
|
||||
@@ -2893,7 +2915,7 @@ bool get_dataavailability_buffers(uint8_t total_active_lcids, nr_lcordered_info_
|
||||
// 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].lcid;
|
||||
if (data_status_lcbuffers[lcid - 1]) {
|
||||
if (data_status_lcbuffers[lcid_buffer_index(lcid)]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -2908,7 +2930,8 @@ static void select_logical_channels(NR_UE_MAC_INST_t *mac, int *num_active_lcids
|
||||
// selection of logical channels with Bj > 0
|
||||
for (int i = 0; i < mac->lc_ordered_list.count; i++) {
|
||||
int lcid = mac->lc_ordered_list.array[i]->lcid;
|
||||
if (mac->scheduling_info.lc_sched_info[lcid - 1].Bj > 0) {
|
||||
NR_LC_SCHEDULING_INFO *sched_info = get_scheduling_info_from_lcid(mac, lcid);
|
||||
if (sched_info->Bj > 0) {
|
||||
active_lcids[*num_active_lcids] = *mac->lc_ordered_list.array[i];
|
||||
(*num_active_lcids)++;
|
||||
LOG_D(NR_MAC, "The available lcid is %d with total active channels count = %d\n", lcid, *num_active_lcids);
|
||||
@@ -2933,11 +2956,11 @@ static bool fill_mac_sdu(NR_UE_MAC_INST_t *mac,
|
||||
bool *lcids_data_status,
|
||||
uint8_t *num_lcids_same_priority)
|
||||
{
|
||||
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;
|
||||
NR_LC_SCHEDULING_INFO *sched_info = get_scheduling_info_from_lcid(mac, lcid);
|
||||
int32_t lcid_remain_buffer = sched_info->LCID_buffer_remain;
|
||||
LOG_D(NR_MAC,
|
||||
"[UE %d] [%d.%d] lcp round = %d, remaining mac pdu length = %d, lcid buffer remaining = %d, lcid = %d \n",
|
||||
mac->ue_id,
|
||||
@@ -2980,14 +3003,15 @@ static bool fill_mac_sdu(NR_UE_MAC_INST_t *mac,
|
||||
// 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; // TODO avoid Bj to go below 0
|
||||
sched_info->Bj -= sdu_length; // TODO avoid Bj to go below 0
|
||||
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);
|
||||
sched_info->Bj);
|
||||
|
||||
int lc_idx = lcid_buffer_index(lcid);
|
||||
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 "
|
||||
@@ -3019,7 +3043,7 @@ static bool fill_mac_sdu(NR_UE_MAC_INST_t *mac,
|
||||
(*num_sdus)++;
|
||||
} else {
|
||||
*pdu -= sh_size;
|
||||
lcids_data_status[lcid - 1] = false;
|
||||
lcids_data_status[lc_idx] = false;
|
||||
(*num_lcids_same_priority)--;
|
||||
LOG_D(NR_MAC, "No data to transmit for RB with LCID 0x%02x\n and hence set to false", lcid);
|
||||
return 0;
|
||||
@@ -3028,31 +3052,30 @@ static bool fill_mac_sdu(NR_UE_MAC_INST_t *mac,
|
||||
*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;
|
||||
NR_LCG_SCHEDULING_INFO *lcg_info = &mac->scheduling_info.lcg_sched_info[0];
|
||||
sched_info->LCID_buffer_remain -= sdu_length;
|
||||
(lcg_info + sched_info->LCGID)->BSR_bytes -= sdu_length;
|
||||
LOG_D(NR_MAC,
|
||||
"[UE %d] Update BSR [%d.%d] BSR_bytes for LCG%ld = %d\n",
|
||||
mac->ue_id,
|
||||
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;
|
||||
sched_info->LCGID,
|
||||
(lcg_info + sched_info->LCGID)->BSR_bytes);
|
||||
if ((lcg_info + sched_info->LCGID)->BSR_bytes < 0)
|
||||
(lcg_info + sched_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);
|
||||
lcids_bytes_tot[lc_idx] += (sdu_length + (count_same_priority_lcids > 1 ? 1 : 0) * sh_size);
|
||||
|
||||
if ((*counter == 0 && lcids_bytes_tot[lcid - 1] >= target)
|
||||
if ((*counter == 0 && lcids_bytes_tot[lc_idx] >= target)
|
||||
|| (count_same_priority_lcids > 1
|
||||
&& lcids_bytes_tot[lcid - 1] >= buflen_ep)) { // only prioritized bit rate should be taken from logical channel in
|
||||
&& lcids_bytes_tot[lc_idx] >= buflen_ep)) { // only prioritized bit rate should be taken from logical channel in
|
||||
// the first lcp run except when infinity
|
||||
LOG_D(NR_MAC,
|
||||
"Total number bytes read from rlc buffer for lcid %d are %d\n",
|
||||
lcid,
|
||||
lcids_bytes_tot[lcid - 1]);
|
||||
lcids_bytes_tot[lc_idx]);
|
||||
(*num_lcids_same_priority)--;
|
||||
return 0;
|
||||
}
|
||||
@@ -3099,7 +3122,6 @@ uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac,
|
||||
//NR_POWER_HEADROOM_CMD phr;
|
||||
//mac_ce_p->phr_p = &phr;
|
||||
|
||||
NR_UE_SCHEDULING_INFO *sched_info = &mac->scheduling_info;
|
||||
//int highest_priority = 16;
|
||||
const uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_LONG);
|
||||
|
||||
@@ -3147,11 +3169,12 @@ uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac,
|
||||
is placed in the MAC PDU before going on to next high priority logical channel
|
||||
*/
|
||||
int lcid = lcids_bj_pos[id].lcid;
|
||||
|
||||
NR_LC_SCHEDULING_INFO *lc_sched_info = get_scheduling_info_from_lcid(mac, lcid);
|
||||
int idx = lcid_buffer_index(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
|
||||
// MAC PDU
|
||||
if (!sched_info->lc_sched_info[lcid - 1].LCID_buffer_with_data || !lcids_data_status[lcid - 1]) {
|
||||
lcids_data_status[lcid - 1] = false;
|
||||
if (!lc_sched_info->LCID_buffer_with_data || !lcids_data_status[idx]) {
|
||||
lcids_data_status[idx] = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user