Remove UEid in the MAC

After this commit, only the RNTI is used as an identifier in the MAC.
Further, it removes some module_id, but a lot of them remain (the goal
to remove all is still far from us)
This commit is contained in:
Laurent THOMAS
2022-05-28 16:37:26 +02:00
committed by laurent
parent 72d0a4ff05
commit 236f7d56e5
22 changed files with 821 additions and 848 deletions
+1 -1
View File
@@ -310,7 +310,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
uint32_t A = rel15->TBSize[0]<<3; uint32_t A = rel15->TBSize[0]<<3;
unsigned char *a=harq->pdu; unsigned char *a=harq->pdu;
if ( rel15->rnti != SI_RNTI) if ( rel15->rnti != SI_RNTI)
trace_NRpdu(DIRECTION_DOWNLINK, a, rel15->TBSize[0], 0, WS_C_RNTI, rel15->rnti, frame, slot,0, 0); trace_NRpdu(DIRECTION_DOWNLINK, a, rel15->TBSize[0], WS_C_RNTI, rel15->rnti, frame, slot,0, 0);
NR_gNB_SCH_STATS_t *stats=NULL; NR_gNB_SCH_STATS_t *stats=NULL;
int first_free=-1; int first_free=-1;
+1 -1
View File
@@ -171,7 +171,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
trace_NRpdu(DIRECTION_UPLINK, trace_NRpdu(DIRECTION_UPLINK,
harq_process_ul_ue->a, harq_process_ul_ue->a,
harq_process_ul_ue->pusch_pdu.pusch_data.tb_size, harq_process_ul_ue->pusch_pdu.pusch_data.tb_size,
0, WS_C_RNTI, rnti, frame, slot, 0, 0); WS_C_RNTI, rnti, frame, slot, 0, 0);
if (nr_ulsch_encoding(UE, ulsch_ue, frame_parms, harq_pid, G) == -1) if (nr_ulsch_encoding(UE, ulsch_ue, frame_parms, harq_pid, G) == -1)
return; return;
@@ -134,7 +134,6 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
trace_NRpdu(DIRECTION_DOWNLINK, trace_NRpdu(DIRECTION_DOWNLINK,
dlsch0->harq_processes[dlsch0->current_harq_pid]->b, dlsch0->harq_processes[dlsch0->current_harq_pid]->b,
dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS / 8, dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS / 8,
pdu_type,
WS_C_RNTI, WS_C_RNTI,
dlsch0->rnti, dlsch0->rnti,
proc->frame_rx, proc->frame_rx,
+8 -9
View File
@@ -270,9 +270,9 @@ int g_mcsIndex = -1, g_mcsTableIdx = 0, g_rbStart = -1, g_rbSize = -1, g_nrOfLay
void nr_dlsim_preprocessor(module_id_t module_id, void nr_dlsim_preprocessor(module_id_t module_id,
frame_t frame, frame_t frame,
sub_frame_t slot) { sub_frame_t slot) {
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; NR_UE_info_t *UE_info = RC.nrmac[module_id]->UE_info.list[0];
AssertFatal(UE_info->num_UEs == 1, "can have only a single UE\n"); AssertFatal(RC.nrmac[module_id]->UE_info.list[1]==NULL, "can have only a single UE\n");
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[0]; NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl;
NR_ServingCellConfigCommon_t *scc = RC.nrmac[0]->common_channels[0].ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = RC.nrmac[0]->common_channels[0].ServingCellConfigCommon;
/* manually set free CCE to 0 */ /* manually set free CCE to 0 */
@@ -282,14 +282,14 @@ void nr_dlsim_preprocessor(module_id_t module_id,
find_aggregation_candidates(&sched_ctrl->aggregation_level, find_aggregation_candidates(&sched_ctrl->aggregation_level,
&nr_of_candidates, &nr_of_candidates,
sched_ctrl->search_space,4); sched_ctrl->search_space,4);
sched_ctrl->coreset = get_coreset(module_id, scc, sched_ctrl->active_bwp->bwp_Dedicated, sched_ctrl->search_space, target_ss); sched_ctrl->coreset = get_coreset(RC.nrmac[module_id], scc, sched_ctrl->active_bwp->bwp_Dedicated, sched_ctrl->search_space, target_ss);
sched_ctrl->cce_index = 0; sched_ctrl->cce_index = 0;
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
nr_set_pdsch_semi_static(NULL, nr_set_pdsch_semi_static(NULL,
scc, scc,
UE_info->CellGroup[0], UE_info->CellGroup,
sched_ctrl->active_bwp, sched_ctrl->active_bwp,
NULL, NULL,
/* tda = */ 0, /* tda = */ 0,
@@ -837,8 +837,7 @@ int main(int argc, char **argv)
gNB_mac->pre_processor_dl = nr_dlsim_preprocessor; gNB_mac->pre_processor_dl = nr_dlsim_preprocessor;
phy_init_nr_gNB(gNB,0,1); phy_init_nr_gNB(gNB,0,1);
N_RB_DL = gNB->frame_parms.N_RB_DL; N_RB_DL = gNB->frame_parms.N_RB_DL;
NR_UE_info_t *UE_info = &RC.nrmac[0]->UE_info; NR_UE_info_t *UE_info = RC.nrmac[0]->UE_info.list[0];
UE_info->num_UEs=1;
// stub to configure frame_parms // stub to configure frame_parms
// nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions); // nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions);
@@ -1098,10 +1097,10 @@ int main(int argc, char **argv)
clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot); clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot);
UE_info->UE_sched_ctrl[0].harq_processes[harq_pid].ndi = !(trial&1); UE_info->UE_sched_ctrl.harq_processes[harq_pid].ndi = !(trial&1);
UE_info->UE_sched_ctrl[0].harq_processes[harq_pid].round = round; UE_info->UE_sched_ctrl.harq_processes[harq_pid].round = round;
for (int i=0; i<MAX_NUM_CORESET; i++) for (int i=0; i<MAX_NUM_CORESET; i++)
gNB_mac->pdcch_cand[i] = 0; gNB_mac->pdcch_cand[i] = 0;
@@ -683,15 +683,15 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance,
"RNTI obtained through DU ID (%x) is different from CU ID (%x)\n", "RNTI obtained through DU ID (%x) is different from CU ID (%x)\n",
rnti, ctxt.rnti); rnti, ctxt.rnti);
int UE_out_of_sync = 0; int UE_out_of_sync = 0;
if (RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU) { if (RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU) {
for (int n = 0; n < MAX_MOBILES_PER_GNB; ++n) { UE_iterator(RC.nrmac[instance]->UE_info.list, UE) {
if (RC.nrmac[instance]->UE_info.active[n] == TRUE if (UE->rnti == rnti) {
&& rnti == RC.nrmac[instance]->UE_info.rnti[n]) {
UE_out_of_sync = 0; UE_out_of_sync = 0;
break; break;
} }
} }
if (!UE)
LOG_E(F1AP,"Not found rnti: %x\n", rnti);
} else { } else {
for (int n = 0; n < MAX_MOBILES_PER_ENB; ++n) { for (int n = 0; n < MAX_MOBILES_PER_ENB; ++n) {
if (RC.mac[instance]->UE_info.active[n] == TRUE if (RC.mac[instance]->UE_info.active[n] == TRUE
@@ -701,7 +701,6 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance,
} }
} }
} }
/* We don't need the Cause */ /* We don't need the Cause */
/* Optional RRC Container: if present, send to UE */ /* Optional RRC Container: if present, send to UE */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container,
+26 -17
View File
@@ -455,18 +455,17 @@ int nr_mac_enable_ue_rrc_processing_timer(module_id_t Mod_idP, rnti_t rnti, NR_S
if (rrc_reconfiguration_delay == 0) { if (rrc_reconfiguration_delay == 0) {
return -1; return -1;
} }
const int UE_id = find_nr_UE_id(Mod_idP,rnti);
if (UE_id < 0) { NR_UE_info_t *UE_info = find_nr_UE(&RC.nrmac[Mod_idP]->UE_info,rnti);
if (!UE_info) {
LOG_W(NR_MAC, "Could not find UE for RNTI 0x%04x\n", rnti); LOG_W(NR_MAC, "Could not find UE for RNTI 0x%04x\n", rnti);
return -1; return -1;
} }
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl;
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
const uint16_t sf_ahead = 6/(0x01<<subcarrierSpacing) + ((6%(0x01<<subcarrierSpacing))>0); const uint16_t sf_ahead = 6/(0x01<<subcarrierSpacing) + ((6%(0x01<<subcarrierSpacing))>0);
const uint16_t sl_ahead = sf_ahead * (0x01<<subcarrierSpacing); const uint16_t sl_ahead = sf_ahead * (0x01<<subcarrierSpacing);
sched_ctrl->rrc_processing_timer = (rrc_reconfiguration_delay<<subcarrierSpacing) + sl_ahead; sched_ctrl->rrc_processing_timer = (rrc_reconfiguration_delay<<subcarrierSpacing) + sl_ahead;
LOG_I(NR_MAC, "Activating RRC processing timer for UE %d with %d ms\n", UE_id, rrc_reconfiguration_delay); LOG_I(NR_MAC, "Activating RRC processing timer for UE %04x with %d ms\n", UE_info->rnti, rrc_reconfiguration_delay);
return 0; return 0;
} }
@@ -593,11 +592,15 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
if(CellGroup->spCellConfig && CellGroup->spCellConfig->spCellConfigDedicated) if(CellGroup->spCellConfig && CellGroup->spCellConfig->spCellConfigDedicated)
servingCellConfig = CellGroup->spCellConfig->spCellConfigDedicated; servingCellConfig = CellGroup->spCellConfig->spCellConfigDedicated;
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
if (add_ue == 1 && get_softmodem_params()->phy_test) { if (add_ue == 1 && get_softmodem_params()->phy_test) {
const int UE_id = add_new_nr_ue(Mod_idP, rnti, CellGroup); NR_UE_info_t* UE = add_new_nr_ue(RC.nrmac[Mod_idP], rnti, CellGroup);
LOG_I(NR_MAC,"Added new UE_id %d/%x with initial CellGroup\n",UE_id,rnti); if (UE)
process_CellGroup(CellGroup,&UE_info->UE_sched_ctrl[UE_id]); LOG_I(NR_MAC,"Added new UE %x with initial CellGroup\n", rnti);
else {
LOG_E(NR_MAC,"Error adding UE %04x\n", rnti);
return -1;
}
process_CellGroup(CellGroup,&UE->UE_sched_ctrl);
} else if (add_ue == 1 && !get_softmodem_params()->phy_test) { } else if (add_ue == 1 && !get_softmodem_params()->phy_test) {
const int CC_id = 0; const int CC_id = 0;
NR_COMMON_channels_t *cc = &RC.nrmac[Mod_idP]->common_channels[CC_id]; NR_COMMON_channels_t *cc = &RC.nrmac[Mod_idP]->common_channels[CC_id];
@@ -644,12 +647,18 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
LOG_I(NR_MAC,"Added new RA process for UE RNTI %04x with initial CellGroup\n", rnti); LOG_I(NR_MAC,"Added new RA process for UE RNTI %04x with initial CellGroup\n", rnti);
} else { // CellGroup has been updated } else { // CellGroup has been updated
NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels[0].ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels[0].ServingCellConfigCommon;
const int UE_id = find_nr_UE_id(Mod_idP,rnti); NR_UE_info_t * UE = find_nr_UE(&RC.nrmac[Mod_idP]->UE_info,rnti);
if (!UE) {
LOG_E(NR_MAC, "Can't find UE %04x\n", rnti);
return -1;
}
int target_ss; int target_ss;
UE_info->CellGroup[UE_id] = CellGroup;
LOG_I(NR_MAC,"Modified UE_id %d/%x with CellGroup\n",UE_id,rnti); UE->CellGroup = CellGroup;
process_CellGroup(CellGroup,&UE_info->UE_sched_ctrl[UE_id]); LOG_I(NR_MAC,"Modified rnti %04x with CellGroup\n",rnti);
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; process_CellGroup(CellGroup,&UE->UE_sched_ctrl);
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
const NR_PDSCH_ServingCellConfig_t *pdsch = servingCellConfig ? servingCellConfig->pdsch_ServingCellConfig->choice.setup : NULL; const NR_PDSCH_ServingCellConfig_t *pdsch = servingCellConfig ? servingCellConfig->pdsch_ServingCellConfig->choice.setup : NULL;
if (get_softmodem_params()->sa) { if (get_softmodem_params()->sa) {
// add all available DL HARQ processes for this UE in SA // add all available DL HARQ processes for this UE in SA
@@ -672,7 +681,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
genericParameters = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters; genericParameters = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
} }
sched_ctrl->search_space = get_searchspace(sib1 ? sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL, scc, bwpd, target_ss); sched_ctrl->search_space = get_searchspace(sib1 ? sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL, scc, bwpd, target_ss);
sched_ctrl->coreset = get_coreset(Mod_idP, scc, bwpd, sched_ctrl->search_space, target_ss); sched_ctrl->coreset = get_coreset(RC.nrmac[Mod_idP], scc, bwpd, sched_ctrl->search_space, target_ss);
sched_ctrl->sched_pdcch = set_pdcch_structure(RC.nrmac[Mod_idP], sched_ctrl->sched_pdcch = set_pdcch_structure(RC.nrmac[Mod_idP],
sched_ctrl->search_space, sched_ctrl->search_space,
sched_ctrl->coreset, sched_ctrl->coreset,
@@ -685,7 +694,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig && CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig &&
CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup
) )
compute_csi_bitlen (CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE_info, UE_id, Mod_idP); compute_csi_bitlen (CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE);
} }
} }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT);
+3 -4
View File
@@ -218,7 +218,7 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram
if ((1 << tmp) & deltaTSFC) { if ((1 << tmp) & deltaTSFC) {
// This is an SRS subframe, loop over UEs // This is an SRS subframe, loop over UEs
for (UE_id = 0; UE_id < MAX_MOBILES_PER_GNB; UE_id++) { UEs_iterator() {
if (!RC.nrmac[module_idP]->UE_info.active[UE_id]) continue; if (!RC.nrmac[module_idP]->UE_info.active[UE_id]) continue;
ul_req = &RC.nrmac[module_idP]->UL_req[CC_id].ul_config_request_body; ul_req = &RC.nrmac[module_idP]->UL_req[CC_id].ul_config_request_body;
// drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet
@@ -372,7 +372,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
schedule_nr_prach(module_idP, f, s); schedule_nr_prach(module_idP, f, s);
} }
// Schedule CSI-RS transmission // Schedule CSI-RS transmission
nr_csirs_scheduling(module_idP, frame, slot, nr_slots_per_frame[*scc->ssbSubcarrierSpacing]); nr_csirs_scheduling(module_idP, frame, slot, nr_slots_per_frame[*scc->ssbSubcarrierSpacing]);
@@ -398,10 +397,10 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
nr_schedule_ue_spec(module_idP, frame, slot); nr_schedule_ue_spec(module_idP, frame, slot);
stop_meas(&gNB->schedule_dlsch); stop_meas(&gNB->schedule_dlsch);
nr_schedule_pucch(module_idP, frame, slot); nr_schedule_pucch(RC.nrmac[module_idP], frame, slot);
// This schedule SR after PUCCH for multiplexing // This schedule SR after PUCCH for multiplexing
nr_sr_reporting(module_idP, frame, slot); nr_sr_reporting(RC.nrmac[module_idP], frame, slot);
stop_meas(&RC.nrmac[module_idP]->eNB_scheduler); stop_meas(&RC.nrmac[module_idP]->eNB_scheduler);
+32 -26
View File
@@ -539,8 +539,10 @@ void nr_initiate_ra_proc(module_id_t module_idP,
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
NR_RA_t *ra = &cc->ra[i]; NR_RA_t *ra = &cc->ra[i];
pr_found = 0; pr_found = 0;
const int UE_id = find_nr_UE_id(module_idP, ra->rnti); const NR_UE_info_t * UE = find_nr_UE(&nr_mac->UE_info, ra->rnti);
if (UE_id != -1) { if (UE) {
// the UE is already registered
LOG_W(NR_MAC, "Received RA for existing RNTI %04x\n", ra->rnti);
continue; continue;
} }
if (ra->state == RA_IDLE) { if (ra->state == RA_IDLE) {
@@ -634,7 +636,7 @@ void nr_initiate_ra_proc(module_id_t module_idP,
AssertFatal(ra->ra_ss!=NULL,"SearchSpace cannot be null for RA\n"); AssertFatal(ra->ra_ss!=NULL,"SearchSpace cannot be null for RA\n");
ra->coreset = get_coreset(module_idP, scc, bwp, ra->ra_ss, NR_SearchSpace__searchSpaceType_PR_common); ra->coreset = get_coreset(nr_mac, scc, bwp, ra->ra_ss, NR_SearchSpace__searchSpaceType_PR_common);
ra->sched_pdcch = set_pdcch_structure(nr_mac, ra->sched_pdcch = set_pdcch_structure(nr_mac,
ra->ra_ss, ra->ra_ss,
ra->coreset, ra->coreset,
@@ -669,7 +671,7 @@ void nr_initiate_ra_proc(module_id_t module_idP,
ra->rnti = (taus() % 65518) + 1; ra->rnti = (taus() % 65518) + 1;
loop++; loop++;
} while (loop != 100 } while (loop != 100
&& !((find_nr_UE_id(module_idP, ra->rnti) == -1) && (find_nr_RA_id(module_idP, CC_id, ra->rnti) == -1) && !((find_nr_UE(&nr_mac->UE_info, ra->rnti) == NULL) && (find_nr_RA_id(module_idP, CC_id, ra->rnti) == -1)
&& ra->rnti >= 1 && ra->rnti <= 65519)); && ra->rnti >= 1 && ra->rnti <= 65519));
if (loop == 100) { if (loop == 100) {
LOG_E(NR_MAC, "%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__); LOG_E(NR_MAC, "%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__);
@@ -682,7 +684,7 @@ void nr_initiate_ra_proc(module_id_t module_idP,
ra->beam_id = beam_index; ra->beam_id = beam_index;
LOG_I(NR_MAC, LOG_I(NR_MAC,
"[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB " "[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB, new rnti %04x "
"index %u RA index %d\n", "index %u RA index %d\n",
module_idP, module_idP,
CC_id, CC_id,
@@ -690,6 +692,7 @@ void nr_initiate_ra_proc(module_id_t module_idP,
ra->Msg2_frame, ra->Msg2_frame,
ra->Msg2_slot, ra->Msg2_slot,
ra->RA_rnti, ra->RA_rnti,
ra->rnti,
cc->ssb_index[beam_index], cc->ssb_index[beam_index],
i); i);
@@ -1517,7 +1520,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
} }
ra->state = WAIT_Msg3; ra->state = WAIT_Msg3;
LOG_D(NR_MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state); LOG_W(NR_MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: rnti %04x RA state %d\n", module_idP, frameP, slotP, ra->rnti, ra->state);
} }
} }
@@ -1560,9 +1563,14 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
ra->rnti = ra->crnti; ra->rnti = ra->crnti;
} }
int UE_id = find_nr_UE_id(module_idP, ra->rnti); NR_UE_info_t * UE = find_nr_UE(&nr_mac->UE_info, ra->rnti);
NR_UE_info_t *UE_info = &nr_mac->UE_info; if (!UE) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; LOG_E(NR_MAC,"want to generate Msg4, but rnti %04x not in the table\n", ra->rnti);
return;
}
LOG_I(NR_MAC,"Generate msg4, rnti: %04x\n", ra->rnti);
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_BWP_t *genericParameters = bwp ? & bwp->bwp_Common->genericParameters : &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters; NR_BWP_t *genericParameters = bwp ? & bwp->bwp_Common->genericParameters : &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
@@ -1595,7 +1603,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
// Remove UE associated to TC-RNTI // Remove UE associated to TC-RNTI
if(harq->round==0 && ra->msg3_dcch_dtch) { if(harq->round==0 && ra->msg3_dcch_dtch) {
mac_remove_nr_ue(module_idP, tc_rnti); mac_remove_nr_ue(nr_mac, tc_rnti);
} }
// get CCEindex, needed also for PUCCH and then later for PDCCH // get CCEindex, needed also for PUCCH and then later for PDCCH
@@ -1626,7 +1634,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
LOG_D(NR_MAC,"[RAPROC] Msg4 r_pucch %d (CCEIndex %d, nb_of_candidates %d, delta_PRI %d)\n", r_pucch, CCEIndex, nr_of_candidates, delta_PRI); LOG_D(NR_MAC,"[RAPROC] Msg4 r_pucch %d (CCEIndex %d, nb_of_candidates %d, delta_PRI %d)\n", r_pucch, CCEIndex, nr_of_candidates, delta_PRI);
int alloc = nr_acknack_scheduling(module_idP, UE_id, frameP, slotP, r_pucch, 1); int alloc = nr_acknack_scheduling(module_idP, UE, frameP, slotP, r_pucch, 1);
AssertFatal(alloc>=0,"Couldn't find a pucch allocation for ack nack (msg4)\n"); AssertFatal(alloc>=0,"Couldn't find a pucch allocation for ack nack (msg4)\n");
NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[alloc]; NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[alloc];
harq->feedback_slot = pucch->ul_slot; harq->feedback_slot = pucch->ul_slot;
@@ -1942,10 +1950,9 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
if(ra->msg3_dcch_dtch) { if(ra->msg3_dcch_dtch) {
// If the UE used MSG3 to transfer a DCCH or DTCH message, then contention resolution is successful upon transmission of PDCCH // If the UE used MSG3 to transfer a DCCH or DTCH message, then contention resolution is successful upon transmission of PDCCH
LOG_I(NR_MAC, "(ue %i, rnti 0x%04x) CBRA procedure succeeded!\n", UE_id, ra->rnti); LOG_I(NR_MAC, "(ue rnti 0x%04x) CBRA procedure succeeded!\n", ra->rnti);
nr_clear_ra_proc(module_idP, CC_id, frameP, ra); nr_clear_ra_proc(module_idP, CC_id, frameP, ra);
UE_info->active[UE_id] = true; UE->Msg4_ACKed = true;
UE_info->Msg4_ACKed[UE_id] = true;
remove_front_nr_list(&sched_ctrl->feedback_dl_harq); remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
harq->feedback_slot = -1; harq->feedback_slot = -1;
@@ -1962,28 +1969,27 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra) { void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra) {
int UE_id = find_nr_UE_id(module_id, ra->rnti); NR_UE_info_t * UE = find_nr_UE(&RC.nrmac[module_id]->UE_info, ra->rnti);
const int current_harq_pid = ra->harq_pid; const int current_harq_pid = ra->harq_pid;
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid]; NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid];
NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id]; NR_mac_stats_t *stats = &UE->mac_stats;
LOG_D(NR_MAC, "ue %d, rnti 0x%04x, harq is waiting %d, round %d, frame %d %d, harq id %d\n", UE_id, ra->rnti, harq->is_waiting, harq->round, frame, slot, current_harq_pid); LOG_D(NR_MAC, "ue rnti 0x%04x, harq is waiting %d, round %d, frame %d %d, harq id %d\n", ra->rnti, harq->is_waiting, harq->round, frame, slot, current_harq_pid);
if (harq->is_waiting == 0) { if (harq->is_waiting == 0) {
if (harq->round == 0) { if (harq->round == 0) {
if (stats->dl.errors == 0) { if (stats->dl.errors == 0) {
LOG_A(NR_MAC, "(ue %i, rnti 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", UE_id, ra->rnti); LOG_A(NR_MAC, "(UE RNTI 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", ra->rnti);
UE_info->active[UE_id] = true; UE->Msg4_ACKed = true;
UE_info->Msg4_ACKed[UE_id] = true;
// Pause scheduling according to: // Pause scheduling according to:
// 3GPP TS 38.331 Section 12 Table 12.1-1: UE performance requirements for RRC procedures for UEs // 3GPP TS 38.331 Section 12 Table 12.1-1: UE performance requirements for RRC procedures for UEs
const NR_COMMON_channels_t *common_channels = &RC.nrmac[module_id]->common_channels[0]; const NR_COMMON_channels_t *common_channels = &RC.nrmac[module_id]->common_channels[0];
const NR_SIB1_t *sib1 = common_channels->sib1 ? common_channels->sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; const NR_SIB1_t *sib1 = common_channels->sib1 ? common_channels->sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
const NR_ServingCellConfig_t *servingCellConfig = UE_info->CellGroup[UE_id] ? UE_info->CellGroup[UE_id]->spCellConfig->spCellConfigDedicated : NULL; const NR_ServingCellConfig_t *servingCellConfig = UE->CellGroup ? UE->CellGroup->spCellConfig->spCellConfigDedicated : NULL;
NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(sched_ctrl->active_bwp, NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(sched_ctrl->active_bwp,
common_channels->ServingCellConfigCommon, common_channels->ServingCellConfigCommon,
sib1); sib1);
@@ -1991,9 +1997,9 @@ void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_fram
NR_RRC_SETUP_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_SETUP_DELAY_MS; NR_RRC_SETUP_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_SETUP_DELAY_MS;
sched_ctrl->rrc_processing_timer = (delay_ms << genericParameters->subcarrierSpacing); sched_ctrl->rrc_processing_timer = (delay_ms << genericParameters->subcarrierSpacing);
LOG_I(NR_MAC, "(%d.%d) Activating RRC processing timer for UE %d with %d ms\n", frame, slot, UE_id, delay_ms); LOG_I(NR_MAC, "(%d.%d) Activating RRC processing timer for UE %04x with %d ms\n", frame, slot, UE->rnti, delay_ms);
} else { } else {
LOG_I(NR_MAC, "(ue %i, rnti 0x%04x) RA Procedure failed at Msg4!\n", UE_id, ra->rnti); LOG_I(NR_MAC, "(ue rnti 0x%04x) RA Procedure failed at Msg4!\n", ra->rnti);
} }
nr_clear_ra_proc(module_id, CC_id, frame, ra); nr_clear_ra_proc(module_id, CC_id, frame, ra);
@@ -2001,7 +2007,7 @@ void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_fram
remove_nr_list(&sched_ctrl->retrans_dl_harq, current_harq_pid); remove_nr_list(&sched_ctrl->retrans_dl_harq, current_harq_pid);
} }
} else { } else {
LOG_D(NR_MAC, "(ue %i, rnti 0x%04x) Received Nack of RA-Msg4. Preparing retransmission!\n", UE_id, ra->rnti); LOG_I(NR_MAC, "(UE %04x) Received Nack of RA-Msg4. Preparing retransmission!\n", ra->rnti);
ra->Msg4_frame = (frame + 1) % 1024; ra->Msg4_frame = (frame + 1) % 1024;
ra->Msg4_slot = 1; ra->Msg4_slot = 1;
ra->state = Msg4; ra->state = Msg4;
+110 -122
View File
@@ -317,10 +317,9 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
void nr_store_dlsch_buffer(module_id_t module_id, void nr_store_dlsch_buffer(module_id_t module_id,
frame_t frame, frame_t frame,
sub_frame_t slot) { sub_frame_t slot) {
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { UE_iterator(RC.nrmac[module_id]->UE_info.list, UE) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
sched_ctrl->num_total_bytes = 0; sched_ctrl->num_total_bytes = 0;
sched_ctrl->dl_pdus_total = 0; sched_ctrl->dl_pdus_total = 0;
@@ -328,13 +327,11 @@ void nr_store_dlsch_buffer(module_id_t module_id,
// Note: DL_SCH_LCID_DCCH, DL_SCH_LCID_DCCH1, DL_SCH_LCID_DTCH // Note: DL_SCH_LCID_DCCH, DL_SCH_LCID_DCCH1, DL_SCH_LCID_DTCH
for (int i = 0; i < sched_ctrl->dl_lc_num; ++i) { for (int i = 0; i < sched_ctrl->dl_lc_num; ++i) {
const int lcid = sched_ctrl->dl_lc_ids[i]; const int lcid = sched_ctrl->dl_lc_ids[i];
const uint16_t rnti = UE_info->rnti[UE_id]; const uint16_t rnti = UE->rnti;
LOG_D(NR_MAC, "In %s: UE %d/%x: LCID %d\n", __FUNCTION__, UE_id, rnti, lcid); LOG_D(NR_MAC, "In %s: UE %x: LCID %d\n", __FUNCTION__, rnti, lcid);
if (lcid == DL_SCH_LCID_DTCH && sched_ctrl->rrc_processing_timer > 0) { if (lcid == DL_SCH_LCID_DTCH && sched_ctrl->rrc_processing_timer > 0) {
continue; continue;
} }
start_meas(&RC.nrmac[module_id]->rlc_status_ind); start_meas(&RC.nrmac[module_id]->rlc_status_ind);
sched_ctrl->rlc_status[lcid] = mac_rlc_status_ind(module_id, sched_ctrl->rlc_status[lcid] = mac_rlc_status_ind(module_id,
rnti, rnti,
@@ -360,7 +357,7 @@ void nr_store_dlsch_buffer(module_id_t module_id,
slot, slot,
lcid < 4 ? "DCCH":"DTCH", lcid < 4 ? "DCCH":"DTCH",
lcid, lcid,
UE_id, UE->rnti,
sched_ctrl->rlc_status[lcid].bytes_in_buffer, sched_ctrl->rlc_status[lcid].bytes_in_buffer,
sched_ctrl->num_total_bytes, sched_ctrl->num_total_bytes,
sched_ctrl->dl_pdus_total, sched_ctrl->dl_pdus_total,
@@ -374,15 +371,14 @@ bool allocate_dl_retransmission(module_id_t module_id,
sub_frame_t slot, sub_frame_t slot,
uint16_t *rballoc_mask, uint16_t *rballoc_mask,
int *n_rb_sched, int *n_rb_sched,
int UE_id, NR_UE_info_t * UE,
int current_harq_pid) { int current_harq_pid) {
gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
const NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels->ServingCellConfigCommon; const NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels->ServingCellConfigCommon;
NR_UE_info_t *UE_info = &nr_mac->UE_info; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
NR_sched_pdsch_t *retInfo = &sched_ctrl->harq_processes[current_harq_pid].sched_pdsch; NR_sched_pdsch_t *retInfo = &sched_ctrl->harq_processes[current_harq_pid].sched_pdsch;
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id]; NR_CellGroupConfig_t *cg = UE->CellGroup;
NR_BWP_DownlinkDedicated_t *bwpd = NR_BWP_DownlinkDedicated_t *bwpd =
cg && cg &&
@@ -422,7 +418,7 @@ bool allocate_dl_retransmission(module_id_t module_id,
rbStart++; rbStart++;
if (rbStart >= bwpSize) { if (rbStart >= bwpSize) {
LOG_D(NR_MAC, "cannot allocate retransmission for UE %d/RNTI %04x: no resources\n", UE_id, UE_info->rnti[UE_id]); LOG_D(NR_MAC, "cannot allocate retransmission for RNTI %04x: no resources\n", UE->rnti);
return false; return false;
} }
@@ -495,7 +491,7 @@ bool allocate_dl_retransmission(module_id_t module_id,
/* Find a free CCE */ /* Find a free CCE */
const int cid = sched_ctrl->coreset->controlResourceSetId; const int cid = sched_ctrl->coreset->controlResourceSetId;
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]); const uint16_t Y = get_Y(cid%3, slot, UE->rnti);
uint8_t nr_of_candidates; uint8_t nr_of_candidates;
for (int i=0; i<5; i++) { for (int i=0; i<5; i++) {
@@ -517,8 +513,8 @@ bool allocate_dl_retransmission(module_id_t module_id,
Y); Y);
if (CCEIndex<0) { if (CCEIndex<0) {
LOG_D(MAC, "%4d.%2d could not find CCE for DL DCI retransmission UE %d/RNTI %04x\n", LOG_D(MAC, "%4d.%2d could not find CCE for DL DCI retransmission RNTI %04x\n",
frame, slot, UE_id, UE_info->rnti[UE_id]); frame, slot, UE->rnti);
return false; return false;
} }
@@ -526,12 +522,11 @@ bool allocate_dl_retransmission(module_id_t module_id,
* allocation after CCE alloc fail would be more complex) */ * allocation after CCE alloc fail would be more complex) */
int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, ubwpd, CCEIndex); int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, ubwpd, CCEIndex);
const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, r_pucch, 0); const int alloc = nr_acknack_scheduling(module_id, UE, frame, slot, r_pucch, 0);
if (alloc<0) { if (alloc<0) {
LOG_D(MAC, LOG_D(MAC,
"could not find PUCCH for UE %d/%04x@%d.%d\n", "could not find PUCCH for UE %04x@%d.%d\n",
UE_id, UE->rnti,
UE_info->rnti[UE_id],
frame, frame,
slot); slot);
RC.nrmac[module_id]->pdcch_cand[cid]--; RC.nrmac[module_id]->pdcch_cand[cid]--;
@@ -557,48 +552,54 @@ bool allocate_dl_retransmission(module_id_t module_id,
return true; return true;
} }
float thr_ue[MAX_MOBILES_PER_GNB];
uint32_t pf_tbs[3][29]; // pre-computed, approximate TBS values for PF coefficient uint32_t pf_tbs[3][29]; // pre-computed, approximate TBS values for PF coefficient
typedef struct UEsched_s {
float coef;
NR_UE_info_t * UE;
} UEsched_t;
static int comparator(const void *p, const void *q) {
return ((UEsched_t*)p)->coef < ((UEsched_t*)q)->coef;
}
void pf_dl(module_id_t module_id, void pf_dl(module_id_t module_id,
frame_t frame, frame_t frame,
sub_frame_t slot, sub_frame_t slot,
NR_list_t *UE_list, NR_UE_info_t **UE_list,
int max_num_ue, int max_num_ue,
int n_rb_sched, int n_rb_sched,
uint16_t *rballoc_mask) { uint16_t *rballoc_mask) {
gNB_MAC_INST *mac = RC.nrmac[module_id]; gNB_MAC_INST *mac = RC.nrmac[module_id];
NR_UE_info_t *UE_info = &mac->UE_info;
NR_ServingCellConfigCommon_t *scc=mac->common_channels[0].ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc=mac->common_channels[0].ServingCellConfigCommon;
float coeff_ue[MAX_MOBILES_PER_GNB];
// UEs that could be scheduled // UEs that could be scheduled
int ue_array[MAX_MOBILES_PER_GNB]; UEsched_t UE_sched[MAX_MOBILES_PER_GNB] = {0};
int layers[MAX_MOBILES_PER_GNB]; int remainUEs = max_num_ue;
NR_list_t UE_sched = { .head = -1, .next = ue_array, .tail = -1, .len = MAX_MOBILES_PER_GNB }; int curUE = 0;
/* Loop UE_info->list to check retransmission */ /* Loop UE_info->list to check retransmission */
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { UE_iterator(UE_list, UE) {
if (UE_info->Msg4_ACKed[UE_id] != true) continue; if (UE->Msg4_ACKed != true)
continue;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue; if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue;
const NR_mac_dir_stats_t *stats = &UE_info->mac_stats[UE_id].dl; const NR_mac_dir_stats_t *stats = &UE->mac_stats.dl;
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
/* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */ /* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */
sched_pdsch->dl_harq_pid = sched_ctrl->retrans_dl_harq.head; sched_pdsch->dl_harq_pid = sched_ctrl->retrans_dl_harq.head;
layers[UE_id] = ps->nrOfLayers; // initialization of layers to the previous value in the strcuture UE->layers = ps->nrOfLayers; // initialization of layers to the previous value in the strcuture
/* Calculate Throughput */ /* Calculate Throughput */
const float a = 0.0005f; // corresponds to 200ms window const float a = 0.0005f; // corresponds to 200ms window
const uint32_t b = stats->current_bytes; const uint32_t b = UE->mac_stats.dl.current_bytes;
thr_ue[UE_id] = (1 - a) * thr_ue[UE_id] + a * b; UE->dl_thr_ue = (1 - a) * UE->dl_thr_ue + a * b;
/* retransmission */ /* retransmission */
if (sched_pdsch->dl_harq_pid >= 0) { if (sched_pdsch->dl_harq_pid >= 0) {
/* Allocate retransmission */ /* Allocate retransmission */
bool r = allocate_dl_retransmission(module_id, frame, slot, rballoc_mask, &n_rb_sched, UE_id, sched_pdsch->dl_harq_pid); bool r = allocate_dl_retransmission(module_id, frame, slot, rballoc_mask, &n_rb_sched, UE, sched_pdsch->dl_harq_pid);
if (!r) { if (!r) {
LOG_D(NR_MAC, "%4d.%2d retransmission can NOT be allocated\n", frame, slot); LOG_D(NR_MAC, "%4d.%2d retransmission can NOT be allocated\n", frame, slot);
@@ -606,9 +607,12 @@ void pf_dl(module_id_t module_id,
} }
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */ /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
max_num_ue--; remainUEs--;
if (max_num_ue < 0) return; if (remainUEs == 0)
// we have filled all with mandatory retransmissions
// no need to schedule new transmissions
return;
} else { } else {
/* Check DL buffer and skip this UE if no bytes and no TA necessary */ /* Check DL buffer and skip this UE if no bytes and no TA necessary */
if (sched_ctrl->num_total_bytes == 0 && frame != (sched_ctrl->ta_frame + 10) % 1024) if (sched_ctrl->num_total_bytes == 0 && frame != (sched_ctrl->ta_frame + 10) % 1024)
@@ -619,7 +623,7 @@ void pf_dl(module_id_t module_id,
const int max_mcs_table = ps->mcsTableIdx == 1 ? 27 : 28; const int max_mcs_table = ps->mcsTableIdx == 1 ? 27 : 28;
const int max_mcs = min(sched_ctrl->dl_max_mcs, max_mcs_table); const int max_mcs = min(sched_ctrl->dl_max_mcs, max_mcs_table);
sched_pdsch->mcs = get_mcs_from_bler(bo, stats, &sched_ctrl->dl_bler_stats, max_mcs, frame); sched_pdsch->mcs = get_mcs_from_bler(bo, stats, &sched_ctrl->dl_bler_stats, max_mcs, frame);
layers[UE_id] = set_dl_nrOfLayers(sched_ctrl); UE->layers = set_dl_nrOfLayers(sched_ctrl);
const uint8_t Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx); const uint8_t Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx);
const uint16_t R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx); const uint16_t R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx);
uint32_t tbs = nr_compute_tbs(Qm, uint32_t tbs = nr_compute_tbs(Qm,
@@ -629,40 +633,26 @@ void pf_dl(module_id_t module_id,
0, /* N_PRB_DMRS * N_DMRS_SLOT */ 0, /* N_PRB_DMRS * N_DMRS_SLOT */
0 /* N_PRB_oh, 0 for initialBWP */, 0 /* N_PRB_oh, 0 for initialBWP */,
0 /* tb_scaling */, 0 /* tb_scaling */,
layers[UE_id]) >> 3; UE->layers) >> 3;
coeff_ue[UE_id] = (float) tbs / thr_ue[UE_id]; float coeff_ue = (float) tbs / UE->dl_thr_ue;
LOG_D(NR_MAC,"b %d, thr_ue[%d] %f, tbs %d, coeff_ue[%d] %f\n", LOG_D(NR_MAC,"UE %04x b %d, thr_ue %f, tbs %d, coeff_ue %f\n",
b, UE_id, thr_ue[UE_id], tbs, UE_id, coeff_ue[UE_id]); UE->rnti, b, UE->dl_thr_ue, tbs, coeff_ue);
/* Create UE_sched list for UEs eligible for new transmission*/ /* Create UE_sched list for UEs eligible for new transmission*/
add_tail_nr_list(&UE_sched, UE_id); UE_sched[curUE].coef=coeff_ue;
UE_sched[curUE].UE=UE;
curUE++;
} }
} }
qsort(UE_sched, sizeof(*UE_sched), sizeofArray(UE_sched), comparator);
UEsched_t *iterator = UE_sched;
const int min_rbSize = 5; const int min_rbSize = 5;
/* Loop UE_sched to find max coeff and allocate transmission */ /* Loop UE_sched to find max coeff and allocate transmission */
while (max_num_ue > 0 && n_rb_sched >= min_rbSize && UE_sched.head >= 0) { while (remainUEs> 0 && n_rb_sched >= min_rbSize && iterator->UE != NULL) {
/* Find max coeff from UE_sched*/
int *max = &UE_sched.head; /* assume head is max */
int *p = &UE_sched.next[*max];
while (*p >= 0) {
/* if the current one has larger coeff, save for later */
if (coeff_ue[*p] > coeff_ue[*max])
max = p;
p = &UE_sched.next[*p];
}
/* remove the max one: do not use remove_nr_list() it goes through the
* whole list every time. Note that UE_sched.tail might not be set
* correctly anymore */
const int UE_id = *max;
p = &UE_sched.next[*max];
*max = UE_sched.next[*max];
*p = -1;
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
NR_CellGroupConfig_t *cg = iterator->UE->CellGroup;
NR_BWP_DownlinkDedicated_t *bwpd = NR_BWP_DownlinkDedicated_t *bwpd =
cg && cg &&
@@ -677,26 +667,33 @@ void pf_dl(module_id_t module_id,
cg->spCellConfig->spCellConfigDedicated->uplinkConfig ? cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL; cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; NR_UE_sched_ctrl_t *sched_ctrl = &iterator->UE->UE_sched_ctrl;
const uint16_t rnti = UE_info->rnti[UE_id]; const uint16_t rnti = iterator->UE->rnti;
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ?
RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 :
NULL;
NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(sched_ctrl->active_bwp, NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(sched_ctrl->active_bwp,
RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon, RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon,
sib1); sib1);
const int coresetid = (sched_ctrl->active_bwp||bwpd) ? sched_ctrl->coreset->controlResourceSetId : RC.nrmac[module_id]->sched_ctrlCommon->coreset->controlResourceSetId; const int coresetid = (sched_ctrl->active_bwp||bwpd) ?
const uint16_t bwpSize = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_size : NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); sched_ctrl->coreset->controlResourceSetId :
RC.nrmac[module_id]->sched_ctrlCommon->coreset->controlResourceSetId;
const uint16_t bwpSize = coresetid == 0 ?
RC.nrmac[module_id]->cset0_bwp_size :
NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
int rbStart = 0; // start wrt BWPstart int rbStart = 0; // start wrt BWPstart
if (sched_ctrl->available_dl_harq.head < 0) { if (sched_ctrl->available_dl_harq.head < 0) {
LOG_D(MAC, "UE %d RNTI %04x has no free HARQ process, skipping\n", UE_id, UE_info->rnti[UE_id]); LOG_D(MAC, "RNTI %04x has no free HARQ process, skipping\n", iterator->UE->rnti);
iterator++;
continue; continue;
} }
/* Find a free CCE */ /* Find a free CCE */
const int cid = sched_ctrl->coreset->controlResourceSetId; const int cid = sched_ctrl->coreset->controlResourceSetId;
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]); const uint16_t Y = get_Y(cid%3, slot, iterator->UE->rnti);
uint8_t nr_of_candidates; uint8_t nr_of_candidates;
for (int i=0; i<5; i++) { for (int i=0; i<5; i++) {
@@ -718,7 +715,8 @@ void pf_dl(module_id_t module_id,
Y); Y);
if (CCEIndex<0) { if (CCEIndex<0) {
LOG_D(NR_MAC, "%4d.%2d could not find CCE for DL DCI UE %d/RNTI %04x\n", frame, slot, UE_id, rnti); LOG_D(NR_MAC, "%4d.%2d could not find CCE for DL DCI RNTI %04x\n", frame, slot, rnti);
iterator++;
continue; continue;
} }
@@ -726,33 +724,25 @@ void pf_dl(module_id_t module_id,
* allocation after CCE alloc fail would be more complex) */ * allocation after CCE alloc fail would be more complex) */
int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, ubwpd, CCEIndex); int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, ubwpd, CCEIndex);
const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, r_pucch, 0); const int alloc = nr_acknack_scheduling(module_id, iterator->UE, frame, slot, r_pucch, 0);
if (alloc<0) { if (alloc<0) {
LOG_D(NR_MAC, LOG_D(NR_MAC,
"could not find PUCCH for UE %d/%04x@%d.%d\n", "could not find PUCCH for %04x@%d.%d\n",
UE_id,
rnti, rnti,
frame, frame,
slot); slot);
mac->pdcch_cand[cid]--; mac->pdcch_cand[cid]--;
iterator++;
continue; continue;
} }
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE
* and PUCCH */
max_num_ue--;
AssertFatal(max_num_ue >= 0, "Illegal max_num_ue %d\n", max_num_ue);
sched_ctrl->cce_index = CCEIndex; sched_ctrl->cce_index = CCEIndex;
fill_pdcch_vrb_map(mac, fill_pdcch_vrb_map(mac,
/* CC_id = */ 0, /* CC_id = */ 0,
&sched_ctrl->sched_pdcch, &sched_ctrl->sched_pdcch,
CCEIndex, CCEIndex,
sched_ctrl->aggregation_level); sched_ctrl->aggregation_level);
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
max_num_ue--;
if (max_num_ue < 0) return;
/* MCS has been set above */ /* MCS has been set above */
const int tda = get_dl_tda(RC.nrmac[module_id], scc, slot); const int tda = get_dl_tda(RC.nrmac[module_id], scc, slot);
@@ -760,14 +750,14 @@ void pf_dl(module_id_t module_id,
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
if (ps->nrOfLayers != layers[UE_id] || ps->time_domain_allocation != tda) { if (ps->nrOfLayers != iterator->UE->layers || ps->time_domain_allocation != tda ) {
nr_set_pdsch_semi_static(sib1, nr_set_pdsch_semi_static(sib1,
scc, scc,
UE_info->CellGroup[UE_id], iterator->UE->CellGroup,
sched_ctrl->active_bwp, sched_ctrl->active_bwp,
bwpd, bwpd,
tda, tda,
layers[UE_id], iterator->UE->layers,
sched_ctrl, sched_ctrl,
ps); ps);
} }
@@ -812,21 +802,24 @@ void pf_dl(module_id_t module_id,
for (int rb = 0; rb < sched_pdsch->rbSize; rb++) for (int rb = 0; rb < sched_pdsch->rbSize; rb++)
rballoc_mask[rb + sched_pdsch->rbStart] ^= slbitmap; rballoc_mask[rb + sched_pdsch->rbStart] ^= slbitmap;
remainUEs--;
iterator++;
} }
} }
void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot) { void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot) {
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; NR_UEs_t *UE_info = &RC.nrmac[module_id]->UE_info;
if (UE_info->num_UEs == 0) if (UE_info->list[0] == NULL)
return; return;
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
const int CC_id = 0; const int CC_id = 0;
/* Get bwpSize and TDAfrom the first UE */ /* Get bwpSize and TDAfrom the first UE */
/* This is temporary and it assumes all UEs have the same BWP and TDA*/ /* This is temporary and it assumes all UEs have the same BWP and TDA*/
int UE_id = UE_info->list.head; NR_UE_info_t *UE=UE_info->list[0];
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
const int tda = get_dl_tda(RC.nrmac[module_id], scc, slot); const int tda = get_dl_tda(RC.nrmac[module_id], scc, slot);
int startSymbolIndex, nrOfSymbols; int startSymbolIndex, nrOfSymbols;
const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = sched_ctrl->active_bwp ? const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = sched_ctrl->active_bwp ?
@@ -842,10 +835,10 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
sib1); sib1);
NR_BWP_DownlinkDedicated_t *bwpd = NR_BWP_DownlinkDedicated_t *bwpd =
UE_info->CellGroup[UE_id] && UE->CellGroup &&
UE_info->CellGroup[UE_id]->spCellConfig && UE->CellGroup->spCellConfig &&
UE_info->CellGroup[UE_id]->spCellConfig->spCellConfigDedicated ? UE->CellGroup->spCellConfig->spCellConfigDedicated ?
UE_info->CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL; UE->CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL;
const int coresetid = (sched_ctrl->active_bwp||bwpd) ? sched_ctrl->coreset->controlResourceSetId : RC.nrmac[module_id]->sched_ctrlCommon->coreset->controlResourceSetId; const int coresetid = (sched_ctrl->active_bwp||bwpd) ? sched_ctrl->coreset->controlResourceSetId : RC.nrmac[module_id]->sched_ctrlCommon->coreset->controlResourceSetId;
@@ -874,7 +867,7 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
pf_dl(module_id, pf_dl(module_id,
frame, frame,
slot, slot,
&UE_info->list, UE_info->list,
MAX_MOBILES_PER_GNB, MAX_MOBILES_PER_GNB,
n_rb_sched, n_rb_sched,
rballoc_mask); rballoc_mask);
@@ -921,18 +914,17 @@ void nr_schedule_ue_spec(module_id_t module_id,
gNB_mac->pre_processor_dl(module_id, frame, slot); gNB_mac->pre_processor_dl(module_id, frame, slot);
const int CC_id = 0; const int CC_id = 0;
NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon;
NR_UE_info_t *UE_info = &gNB_mac->UE_info; NR_UEs_t *UE_info = &gNB_mac->UE_info;
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body; nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
NR_list_t *UE_list = &UE_info->list;
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { UE_iterator(UE_info->list, UE) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue; if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue;
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
UE_info->mac_stats[UE_id].dl.current_bytes = 0; UE->mac_stats.dl.current_bytes = 0;
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id]; NR_CellGroupConfig_t *cg = UE->CellGroup;
NR_BWP_DownlinkDedicated_t *bwpd = NR_BWP_DownlinkDedicated_t *bwpd =
cg && cg &&
@@ -946,13 +938,13 @@ void nr_schedule_ue_spec(module_id_t module_id,
* If we add the CE, ta_apply will be reset */ * If we add the CE, ta_apply will be reset */
if (frame == (sched_ctrl->ta_frame + 10) % 1024) { if (frame == (sched_ctrl->ta_frame + 10) % 1024) {
sched_ctrl->ta_apply = true; /* the timer is reset once TA CE is scheduled */ sched_ctrl->ta_apply = true; /* the timer is reset once TA CE is scheduled */
LOG_D(NR_MAC, "[UE %d][%d.%d] UL timing alignment procedures: setting flag for Timing Advance command\n", UE_id, frame, slot); LOG_D(NR_MAC, "[UE %04x][%d.%d] UL timing alignment procedures: setting flag for Timing Advance command\n", UE->rnti, frame, slot);
} }
if (sched_pdsch->rbSize <= 0) if (sched_pdsch->rbSize <= 0)
continue; continue;
const rnti_t rnti = UE_info->rnti[UE_id]; const rnti_t rnti = UE->rnti;
/* pre-computed PDSCH values that only change if time domain /* pre-computed PDSCH values that only change if time domain
* allocation/DMRS parameters change. Updated in the preprocessor through * allocation/DMRS parameters change. Updated in the preprocessor through
* nr_set_pdsch_semi_static() */ * nr_set_pdsch_semi_static() */
@@ -968,8 +960,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
/* PP has not selected a specific HARQ Process, get a new one */ /* PP has not selected a specific HARQ Process, get a new one */
current_harq_pid = sched_ctrl->available_dl_harq.head; current_harq_pid = sched_ctrl->available_dl_harq.head;
AssertFatal(current_harq_pid >= 0, AssertFatal(current_harq_pid >= 0,
"no free HARQ process available for UE %d\n", "no free HARQ process available for UE %04x\n",
UE_id); UE->rnti);
remove_front_nr_list(&sched_ctrl->available_dl_harq); remove_front_nr_list(&sched_ctrl->available_dl_harq);
sched_pdsch->dl_harq_pid = current_harq_pid; sched_pdsch->dl_harq_pid = current_harq_pid;
} else { } else {
@@ -989,12 +981,11 @@ void nr_schedule_ue_spec(module_id_t module_id,
harq->feedback_frame = pucch->frame; harq->feedback_frame = pucch->frame;
harq->feedback_slot = pucch->ul_slot; harq->feedback_slot = pucch->ul_slot;
harq->is_waiting = true; harq->is_waiting = true;
UE_info->mac_stats[UE_id].dl.rounds[harq->round]++; UE->mac_stats.dl.rounds[harq->round]++;
LOG_D(NR_MAC, LOG_D(NR_MAC,
"%4d.%2d [DLSCH/PDSCH/PUCCH] UE %d RNTI %04x DCI L %d start %3d RBs %3d startSymbol %2d nb_symbol %2d dmrspos %x MCS %2d nrOfLayers %d TBS %4d HARQ PID %2d round %d RV %d NDI %d dl_data_to_ULACK %d (%d.%d) PUCCH allocation %d TPC %d\n", "%4d.%2d [DLSCH/PDSCH/PUCCH] RNTI %04x DCI L %d start %3d RBs %3d startSymbol %2d nb_symbol %2d dmrspos %x MCS %2d nrOfLayers %d TBS %4d HARQ PID %2d round %d RV %d NDI %d dl_data_to_ULACK %d (%d.%d) PUCCH allocation %d TPC %d\n",
frame, frame,
slot, slot,
UE_id,
rnti, rnti,
sched_ctrl->aggregation_level, sched_ctrl->aggregation_level,
sched_pdsch->rbStart, sched_pdsch->rbStart,
@@ -1037,7 +1028,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
dl_req->nPDUs += 1; dl_req->nPDUs += 1;
pdcch_pdu = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; pdcch_pdu = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
LOG_D(NR_MAC,"Trying to configure DL pdcch for UE %d, bwp %d, cs %d\n",UE_id,bwp_id,coresetid); LOG_D(NR_MAC,"Trying to configure DL pdcch for UE %04x, bwp %d, cs %d\n", UE->rnti, bwp_id, coresetid);
NR_ControlResourceSet_t *coreset = (bwp||bwpd)? sched_ctrl->coreset:gNB_mac->sched_ctrlCommon->coreset; NR_ControlResourceSet_t *coreset = (bwp||bwpd)? sched_ctrl->coreset:gNB_mac->sched_ctrlCommon->coreset;
nr_configure_pdcch(pdcch_pdu, coreset, genericParameters, &sched_ctrl->sched_pdcch); nr_configure_pdcch(pdcch_pdu, coreset, genericParameters, &sched_ctrl->sched_pdcch);
gNB_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu; gNB_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu;
@@ -1099,8 +1090,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
pdsch_pdu->NrOfSymbols = ps->nrOfSymbols; pdsch_pdu->NrOfSymbols = ps->nrOfSymbols;
// Precoding // Precoding
if (sched_ctrl->set_pmi) { if (sched_ctrl->set_pmi) {
int report_id = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.csi_report_id; const int report_id = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.csi_report_id;
nr_csi_report_t *csi_report = &UE_info->csi_report_template[UE_id][report_id]; nr_csi_report_t *csi_report = &UE->csi_report_template[report_id];
pdsch_pdu->precodingAndBeamforming.prg_size = pdsch_pdu->rbSize; pdsch_pdu->precodingAndBeamforming.prg_size = pdsch_pdu->rbSize;
pdsch_pdu->precodingAndBeamforming.prgs_list[0].pm_idx = set_pm_index(sched_ctrl, pdsch_pdu->precodingAndBeamforming.prgs_list[0].pm_idx = set_pm_index(sched_ctrl,
nrOfLayers, nrOfLayers,
@@ -1241,17 +1232,16 @@ void nr_schedule_ue_spec(module_id_t module_id,
* from RLC or encode MAC CEs. The TX_req structure is filled below * from RLC or encode MAC CEs. The TX_req structure is filled below
* or copy data to FAPI structures */ * or copy data to FAPI structures */
LOG_D(NR_MAC, LOG_D(NR_MAC,
"%d.%2d DL retransmission UE %d/RNTI %04x HARQ PID %d round %d NDI %d\n", "%d.%2d DL retransmission RNTI %04x HARQ PID %d round %d NDI %d\n",
frame, frame,
slot, slot,
UE_id,
rnti, rnti,
current_harq_pid, current_harq_pid,
harq->round, harq->round,
harq->ndi); harq->ndi);
AssertFatal(harq->sched_pdsch.tb_size == TBS, AssertFatal(harq->sched_pdsch.tb_size == TBS,
"UE %d mismatch between scheduled TBS and buffered TB for HARQ PID %d\n", "UE %04x mismatch between scheduled TBS and buffered TB for HARQ PID %d\n",
UE_id, UE->rnti,
current_harq_pid); current_harq_pid);
T(T_GNB_MAC_RETRANSMISSION_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti), T(T_GNB_MAC_RETRANSMISSION_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti),
T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_INT(harq->round), T_BUFFER(harq->transportBlock, TBS)); T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_INT(harq->round), T_BUFFER(harq->transportBlock, TBS));
@@ -1323,7 +1313,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
lcid_bytes += len; lcid_bytes += len;
} }
UE_info->mac_stats[UE_id].dl.lc_bytes[lcid] += lcid_bytes; UE->mac_stats.dl.lc_bytes[lcid] += lcid_bytes;
} }
} else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra) { } else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra) {
/* we will need the large header, phy-test typically allocates all /* we will need the large header, phy-test typically allocates all
@@ -1361,10 +1351,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
buf=bufEnd; buf=bufEnd;
} }
NR_mac_stats_t *mac_stats = &UE_info->mac_stats[UE_id]; UE->mac_stats.dl.total_bytes += TBS;
mac_stats->dl.total_bytes += TBS; UE->mac_stats.dl.current_bytes = TBS;
mac_stats->dl.current_bytes = TBS;
/* save retransmission information */ /* save retransmission information */
harq->sched_pdsch = *sched_pdsch; harq->sched_pdsch = *sched_pdsch;
/* save which time allocation has been used, to be used on /* save which time allocation has been used, to be used on
@@ -1376,10 +1364,10 @@ void nr_schedule_ue_spec(module_id_t module_id,
sched_ctrl->ta_apply = false; sched_ctrl->ta_apply = false;
sched_ctrl->ta_frame = frame; sched_ctrl->ta_frame = frame;
LOG_D(NR_MAC, LOG_D(NR_MAC,
"%d.%2d UE %d TA scheduled, resetting TA frame\n", "%d.%2d UE %04x TA scheduled, resetting TA frame\n",
frame, frame,
slot, slot,
UE_id); UE->rnti);
} }
T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti), T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti),
@@ -69,7 +69,6 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
nfapi_nr_pdu_t *TX_req; nfapi_nr_pdu_t *TX_req;
uint16_t rnti = 0x1234; uint16_t rnti = 0x1234;
// int time_domain_assignment,k0; // int time_domain_assignment,k0;
NR_ServingCellConfigCommon_t *scc=cc->ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc=cc->ServingCellConfigCommon;
@@ -266,21 +265,16 @@ void nr_preprocessor_phytest(module_id_t module_id,
{ {
if (!is_xlsch_in_slot(dlsch_slot_bitmap, slot)) if (!is_xlsch_in_slot(dlsch_slot_bitmap, slot))
return; return;
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; NR_UE_info_t *UE = RC.nrmac[module_id]->UE_info.list[0];
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
const int UE_id = 0; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
const int CC_id = 0; const int CC_id = 0;
AssertFatal(UE_info->active[UE_id],
"%s(): expected UE %d to be active\n",
__func__,
UE_id);
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
const int tda = get_dl_tda(RC.nrmac[module_id], scc, slot); const int tda = get_dl_tda(RC.nrmac[module_id], scc, slot);
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
ps->nrOfLayers = target_dl_Nl; ps->nrOfLayers = target_dl_Nl;
if (ps->time_domain_allocation != tda || ps->nrOfLayers != target_dl_Nl) if (ps->time_domain_allocation != tda || ps->nrOfLayers != target_dl_Nl)
nr_set_pdsch_semi_static(NULL, scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, NULL, tda, target_dl_Nl, sched_ctrl, ps); nr_set_pdsch_semi_static(NULL, scc, UE->CellGroup, sched_ctrl->active_bwp, NULL, tda, target_dl_Nl,sched_ctrl , ps);
/* find largest unallocated chunk */ /* find largest unallocated chunk */
const int bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); const int bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
@@ -316,7 +310,7 @@ void nr_preprocessor_phytest(module_id_t module_id,
sched_ctrl->dl_lc_num = 1; sched_ctrl->dl_lc_num = 1;
const int lcid = DL_SCH_LCID_DTCH; const int lcid = DL_SCH_LCID_DTCH;
sched_ctrl->dl_lc_ids[sched_ctrl->dl_lc_num - 1] = lcid; sched_ctrl->dl_lc_ids[sched_ctrl->dl_lc_num - 1] = lcid;
const uint16_t rnti = UE_info->rnti[UE_id]; const uint16_t rnti = UE->rnti;
/* update sched_ctrl->num_total_bytes so that postprocessor schedules data, /* update sched_ctrl->num_total_bytes so that postprocessor schedules data,
* if available */ * if available */
sched_ctrl->rlc_status[lcid] = mac_rlc_status_ind(module_id, sched_ctrl->rlc_status[lcid] = mac_rlc_status_ind(module_id,
@@ -343,7 +337,7 @@ void nr_preprocessor_phytest(module_id_t module_id,
AssertFatal(nr_of_candidates>0,"nr_of_candidates is 0\n"); AssertFatal(nr_of_candidates>0,"nr_of_candidates is 0\n");
const int cid = sched_ctrl->coreset->controlResourceSetId; const int cid = sched_ctrl->coreset->controlResourceSetId;
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]); const uint16_t Y = get_Y(cid%3, slot, UE->rnti);
int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id], int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id],
CC_id, CC_id,
@@ -354,17 +348,16 @@ void nr_preprocessor_phytest(module_id_t module_id,
Y); Y);
AssertFatal(CCEIndex >= 0, AssertFatal(CCEIndex >= 0,
"%s(): could not find CCE for UE %d\n", "%s(): could not find CCE for UE %04x\n",
__func__, __func__,
UE_id); UE->rnti);
int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, NULL, CCEIndex); int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, NULL, CCEIndex);
const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, r_pucch, 0); const int alloc = nr_acknack_scheduling(module_id, UE, frame, slot, r_pucch, 0);
if (alloc < 0) { if (alloc < 0) {
LOG_D(MAC, LOG_D(MAC,
"%s(): could not find PUCCH for UE %d/%04x@%d.%d\n", "%s(): could not find PUCCH for UE %04x@%d.%d\n",
__func__, __func__,
UE_id,
rnti, rnti,
frame, frame,
slot); slot);
@@ -422,19 +415,16 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
NR_COMMON_channels_t *cc = nr_mac->common_channels; NR_COMMON_channels_t *cc = nr_mac->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
const int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; const int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
NR_UE_info_t *UE_info = &nr_mac->UE_info; NR_UE_info_t *UE = nr_mac->UE_info.list[0];
AssertFatal(UE_info->num_UEs <= 1, AssertFatal(nr_mac->UE_info.list[1] == NULL,
"%s() cannot handle more than one UE, but found %d\n", "cannot handle more than one UE\n");
__func__, if (UE == NULL)
UE_info->num_UEs);
if (UE_info->num_UEs == 0)
return false; return false;
const int UE_id = 0;
const int CC_id = 0; const int CC_id = 0;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList = const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList =
sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
@@ -523,7 +513,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
AssertFatal(nr_of_candidates>0,"nr_of_candidates is 0\n"); AssertFatal(nr_of_candidates>0,"nr_of_candidates is 0\n");
const int cid = sched_ctrl->coreset->controlResourceSetId; const int cid = sched_ctrl->coreset->controlResourceSetId;
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]); const uint16_t Y = get_Y(cid%3, slot, UE->rnti);
int CCEIndex = find_pdcch_candidate(nr_mac, int CCEIndex = find_pdcch_candidate(nr_mac,
CC_id, CC_id,
@@ -288,7 +288,7 @@ NR_PDSCH_TimeDomainResourceAllocationList_t *get_pdsch_TimeDomainAllocationList(
} }
NR_ControlResourceSet_t *get_coreset(module_id_t module_idP, NR_ControlResourceSet_t *get_coreset(gNB_MAC_INST *nrmac,
NR_ServingCellConfigCommon_t *scc, NR_ServingCellConfigCommon_t *scc,
void *bwp, void *bwp,
NR_SearchSpace_t *ss, NR_SearchSpace_t *ss,
@@ -298,7 +298,7 @@ NR_ControlResourceSet_t *get_coreset(module_id_t module_idP,
if (ss_type == NR_SearchSpace__searchSpaceType_PR_common) { // common search space if (ss_type == NR_SearchSpace__searchSpaceType_PR_common) { // common search space
NR_ControlResourceSet_t *coreset; NR_ControlResourceSet_t *coreset;
if(coreset_id == 0) { if(coreset_id == 0) {
coreset = RC.nrmac[module_idP]->sched_ctrlCommon->coreset; // this is coreset 0 coreset = nrmac->sched_ctrlCommon->coreset; // this is coreset 0
} else if (bwp) { } else if (bwp) {
coreset = ((NR_BWP_Downlink_t*)bwp)->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet; coreset = ((NR_BWP_Downlink_t*)bwp)->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet;
} else if (scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet) { } else if (scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet) {
@@ -607,11 +607,10 @@ void nr_set_pdsch_semi_static(const NR_SIB1_t *sib1,
bwpd->pdsch_Config && bwpd->pdsch_Config &&
bwpd->pdsch_Config->choice.setup && bwpd->pdsch_Config->choice.setup &&
bwpd->pdsch_Config->choice.setup->mcs_Table) { bwpd->pdsch_Config->choice.setup->mcs_Table) {
if (*bwpd->pdsch_Config->choice.setup->mcs_Table == 0) { if (*bwpd->pdsch_Config->choice.setup->mcs_Table == 0)
ps->mcsTableIdx = 1; ps->mcsTableIdx = 1;
} else { else
ps->mcsTableIdx = 2; ps->mcsTableIdx = 2;
}
} else { } else {
ps->mcsTableIdx = 0; ps->mcsTableIdx = 0;
} }
@@ -628,9 +627,9 @@ void nr_set_pdsch_semi_static(const NR_SIB1_t *sib1,
ps->mapping_type = tdaList->list.array[tda]->mappingType; ps->mapping_type = tdaList->list.array[tda]->mappingType;
if (pdsch_Config) { if (pdsch_Config) {
if (ps->mapping_type == NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB) if (ps->mapping_type == NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB)
ps->dmrsConfigType = pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type == NULL ? 0 : 1; ps->dmrsConfigType = pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type != NULL;
else else
ps->dmrsConfigType = pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1; ps->dmrsConfigType = pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type != NULL;
} }
else else
ps->dmrsConfigType = NFAPI_NR_DMRS_TYPE1; ps->dmrsConfigType = NFAPI_NR_DMRS_TYPE1;
@@ -2135,10 +2134,11 @@ int extract_length(int startSymbolAndLength) {
/* /*
* Dump the UL or DL UE_info into LOG_T(MAC) * Dump the UL or DL UE_info into LOG_T(MAC)
*/ */
void dump_nr_list(NR_list_t *listP) void dump_nr_list(NR_UE_info_t **list)
{ {
for (int j = listP->head; j >= 0; j = listP->next[j]) UE_iterator(list, UE) {
LOG_T(NR_MAC, "NR list node %d => %d\n", j, listP->next[j]); LOG_T(NR_MAC, "NR list UEs rntis %04x\n", (*list)->rnti);
}
} }
/* /*
@@ -2193,7 +2193,7 @@ void destroy_nr_list(NR_list_t *list)
{ {
free(list->next); free(list->next);
} }
//------------------------------------------------------------------------------
/* /*
* Add an ID to an NR_list at the end, traversing the whole list. Note: * Add an ID to an NR_list at the end, traversing the whole list. Note:
* add_tail_nr_list() is a faster alternative, but this implementation ensures * add_tail_nr_list() is a faster alternative, but this implementation ensures
@@ -2222,16 +2222,7 @@ void remove_nr_list(NR_list_t *listP, int id)
prev = cur; prev = cur;
cur = &listP->next[*cur]; cur = &listP->next[*cur];
} }
if (*cur == -1) { AssertFatal(*cur != -1, "ID %d not found in UE_list\n", id);
cur = &listP->head;
prev=&listP->head;
while (*cur != -1 && *cur != id) {
LOG_I(NR_MAC,"remove_nr_list : id %d, *cur %d\n",id,*cur);
prev = cur;
cur = &listP->next[*cur];
}
AssertFatal(1==0, "ID %d not found in UE_list\n", id);
}
int *next = &listP->next[*cur]; int *next = &listP->next[*cur];
*cur = listP->next[*cur]; *cur = listP->next[*cur];
*next = -1; *next = -1;
@@ -2276,21 +2267,17 @@ void remove_front_nr_list(NR_list_t *listP)
listP->tail = -1; listP->tail = -1;
} }
int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP) NR_UE_info_t * find_nr_UE(NR_UEs_t* UEs, rnti_t rntiP)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
int UE_id; UE_iterator(UEs->list, UE) {
NR_UE_info_t *UE_info = &RC.nrmac[mod_idP]->UE_info; if (UE->rnti == rntiP) {
LOG_D(NR_MAC,"Search and found rnti: %04x\n", rntiP);
for (UE_id = 0; UE_id < MAX_MOBILES_PER_GNB; UE_id++) { return UE;
if (UE_info->active[UE_id]) {
if (UE_info->rnti[UE_id] == rntiP) {
return UE_id;
}
} }
} }
LOG_W(NR_MAC,"Search for not existing rnti: %04x\n", rntiP);
return -1; return NULL;
} }
uint16_t get_Y(int cid, int slot, rnti_t rnti) { uint16_t get_Y(int cid, int slot, rnti_t rnti) {
@@ -2363,39 +2350,80 @@ int get_ul_bwp_id(const NR_ServingCellConfig_t *servingCellConfig)
return 1; return 1;
} }
//------------------------------------------------------------------------------ /* hack data to remove UE in the phy */
int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellGroup) int rnti_to_remove[10];
{ volatile int rnti_to_remove_count;
gNB_MAC_INST *nr_mac = RC.nrmac[mod_idP]; pthread_mutex_t rnti_to_remove_mutex = PTHREAD_MUTEX_INITIALIZER;
NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels[0].ServingCellConfigCommon;
NR_UE_info_t *UE_info = &nr_mac->UE_info;
LOG_I(NR_MAC, "[gNB %d] Adding UE with rnti 0x%04x (num_UEs %d)\n",
mod_idP,
rntiP,
UE_info->num_UEs);
dump_nr_list(&UE_info->list);
for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr)
if (UE_info->active[i]) { {
LOG_D(NR_MAC,"UE %x is active, skipping\n",rntiP); NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
continue; destroy_nr_list(&sched_ctrl->available_dl_harq);
destroy_nr_list(&sched_ctrl->feedback_dl_harq);
destroy_nr_list(&sched_ctrl->retrans_dl_harq);
destroy_nr_list(&sched_ctrl->available_ul_harq);
destroy_nr_list(&sched_ctrl->feedback_ul_harq);
destroy_nr_list(&sched_ctrl->retrans_ul_harq);
LOG_I(NR_MAC, "Remove NR rnti 0x%04x\n", UE->rnti);
const rnti_t rnti = UE->rnti;
free(UE);
/* hack to remove UE in the phy */
if (pthread_mutex_lock(&rnti_to_remove_mutex))
exit(1);
if (rnti_to_remove_count == 10)
exit(1);
rnti_to_remove[rnti_to_remove_count] = rnti;
LOG_W(NR_MAC, "to remove in mac rnti_to_remove[%d] = 0x%04x\n", rnti_to_remove_count, rnti);
rnti_to_remove_count++;
if (pthread_mutex_unlock(&rnti_to_remove_mutex))
exit(1);
/* clear RA process(es?) associated to the UE */
for (int cc_id = 0; cc_id < NFAPI_CC_MAX; cc_id++) {
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
NR_COMMON_channels_t *cc = &ccPtr[cc_id];
if (cc->ra[i].rnti == rnti) {
LOG_D(NR_MAC, "free RA process %d for rnti %04x\n", i, rnti);
/* is it enough? */
cc->ra[i].cfra = false;
cc->ra[i].rnti = 0;
cc->ra[i].crnti = 0;
}
} }
int UE_id = i; }
UE_info->num_UEs++; }
UE_info->active[UE_id] = true;
if (CellGroup) UE_info->Msg4_ACKed[UE_id] = true; //------------------------------------------------------------------------------
else UE_info->Msg4_ACKed[UE_id] = false; NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConfig_t *CellGroup)
UE_info->rnti[UE_id] = rntiP; {
UE_info->CellGroup[UE_id] = CellGroup; NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels[0].ServingCellConfigCommon;
add_nr_list(&UE_info->list, UE_id); NR_UEs_t *UE_info = &nr_mac->UE_info;
memset(&UE_info->mac_stats[UE_id], 0, sizeof(NR_mac_stats_t)); LOG_I(NR_MAC, "Adding UE with rnti 0x%04x\n",
if (CellGroup && rntiP);
CellGroup->spCellConfig && dump_nr_list(UE_info->list);
CellGroup->spCellConfig->spCellConfigDedicated &&
CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig && // We will attach at the end, to mitigate race conditions
CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup) // This is not good, but we will fix it progressively
compute_csi_bitlen (CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE_info, UE_id, mod_idP); NR_UE_info_t *UE=calloc(1,sizeof(NR_UE_info_t));
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; if(!UE) {
LOG_E(NR_MAC,"want to add UE %04x but the fixed allocated size is full\n",rntiP);
return NULL;
}
UE->rnti = rntiP;
UE->CellGroup = CellGroup;
if (CellGroup)
UE->Msg4_ACKed = true;
else
UE->Msg4_ACKed = false;
if (CellGroup &&
CellGroup->spCellConfig &&
CellGroup->spCellConfig->spCellConfigDedicated &&
CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig &&
CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup)
compute_csi_bitlen (CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE);
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
memset(sched_ctrl, 0, sizeof(*sched_ctrl)); memset(sched_ctrl, 0, sizeof(*sched_ctrl));
sched_ctrl->dl_max_mcs = 28; /* do not limit MCS for individual UEs */ sched_ctrl->dl_max_mcs = 28; /* do not limit MCS for individual UEs */
sched_ctrl->set_pmi = false; sched_ctrl->set_pmi = false;
@@ -2406,7 +2434,6 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellG
sched_ctrl->pucch_consecutive_dtx_cnt = 0; sched_ctrl->pucch_consecutive_dtx_cnt = 0;
sched_ctrl->pusch_consecutive_dtx_cnt = 0; sched_ctrl->pusch_consecutive_dtx_cnt = 0;
sched_ctrl->ul_failure = 0; sched_ctrl->ul_failure = 0;
sched_ctrl->sched_srs.frame = -1; sched_ctrl->sched_srs.frame = -1;
sched_ctrl->sched_srs.slot = -1; sched_ctrl->sched_srs.slot = -1;
sched_ctrl->sched_srs.srs_scheduled = false; sched_ctrl->sched_srs.srs_scheduled = false;
@@ -2416,11 +2443,8 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellG
sched_ctrl->pusch_semi_static.time_domain_allocation = -1; sched_ctrl->pusch_semi_static.time_domain_allocation = -1;
const NR_ServingCellConfig_t *servingCellConfig = CellGroup && CellGroup->spCellConfig ? CellGroup->spCellConfig->spCellConfigDedicated : NULL; const NR_ServingCellConfig_t *servingCellConfig = CellGroup && CellGroup->spCellConfig ? CellGroup->spCellConfig->spCellConfigDedicated : NULL;
/* Set default BWPs */ /* Set default BWPs */
const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig ? servingCellConfig->downlinkBWP_ToAddModList : NULL; const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig ? servingCellConfig->downlinkBWP_ToAddModList : NULL;
if (bwpList) AssertFatal(bwpList->list.count <= NR_MAX_NUM_BWP,
"downlinkBWP_ToAddModList has %d BWP!\n",
bwpList->list.count);
const int bwp_id = servingCellConfig ? *servingCellConfig->firstActiveDownlinkBWP_Id : 0; const int bwp_id = servingCellConfig ? *servingCellConfig->firstActiveDownlinkBWP_Id : 0;
sched_ctrl->active_bwp = bwpList && bwp_id > 0 ? bwpList->list.array[bwp_id - 1] : NULL; sched_ctrl->active_bwp = bwpList && bwp_id > 0 ? bwpList->list.array[bwp_id - 1] : NULL;
@@ -2433,10 +2457,12 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellG
scc, scc,
sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Dedicated : NULL, sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Dedicated : NULL,
target_ss); target_ss);
sched_ctrl->coreset = get_coreset(mod_idP, scc, sched_ctrl->coreset = get_coreset(nr_mac,
sched_ctrl->active_bwp ? (void*)sched_ctrl->active_bwp->bwp_Dedicated : NULL, scc,
sched_ctrl->search_space, target_ss); sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Dedicated : NULL,
sched_ctrl->sched_pdcch = set_pdcch_structure(RC.nrmac[mod_idP], sched_ctrl->search_space,
target_ss);
sched_ctrl->sched_pdcch = set_pdcch_structure(nr_mac,
sched_ctrl->search_space, sched_ctrl->search_space,
sched_ctrl->coreset, sched_ctrl->coreset,
scc, scc,
@@ -2445,16 +2471,18 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellG
sched_ctrl->next_dl_bwp_id = -1; sched_ctrl->next_dl_bwp_id = -1;
sched_ctrl->next_ul_bwp_id = -1; sched_ctrl->next_ul_bwp_id = -1;
const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig ? servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList : NULL; const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig ? servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList : NULL;
if (ubwpList) AssertFatal(ubwpList->list.count <= NR_MAX_NUM_BWP, if (ubwpList)
AssertFatal(ubwpList->list.count <= NR_MAX_NUM_BWP,
"uplinkBWP_ToAddModList has %d BWP!\n", "uplinkBWP_ToAddModList has %d BWP!\n",
ubwpList->list.count); ubwpList->list.count);
const int ul_bwp_id = servingCellConfig ? *servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id : 0; const int ul_bwp_id = servingCellConfig ? *servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id : 0;
sched_ctrl->active_ubwp = ubwpList && ul_bwp_id > 0 ? ubwpList->list.array[ul_bwp_id - 1] : NULL; sched_ctrl->active_ubwp = ubwpList && ul_bwp_id > 0 ? ubwpList->list.array[ul_bwp_id - 1] : NULL;
/* get Number of HARQ processes for this UE */ /* get Number of HARQ processes for this UE */
if (servingCellConfig) AssertFatal(servingCellConfig->pdsch_ServingCellConfig->present == NR_SetupRelease_PDSCH_ServingCellConfig_PR_setup, if (servingCellConfig)
"no pdsch-ServingCellConfig found for UE %d\n", AssertFatal(servingCellConfig->pdsch_ServingCellConfig->present == NR_SetupRelease_PDSCH_ServingCellConfig_PR_setup,
UE_id); "no pdsch-ServingCellConfig found for UE %04x\n",
UE->rnti);
const NR_PDSCH_ServingCellConfig_t *pdsch = servingCellConfig ? servingCellConfig->pdsch_ServingCellConfig->choice.setup : NULL; const NR_PDSCH_ServingCellConfig_t *pdsch = servingCellConfig ? servingCellConfig->pdsch_ServingCellConfig->choice.setup : NULL;
// pdsch == NULL in SA -> will create default (8) number of HARQ processes // pdsch == NULL in SA -> will create default (8) number of HARQ processes
create_dl_harq_list(sched_ctrl, pdsch); create_dl_harq_list(sched_ctrl, pdsch);
@@ -2465,21 +2493,27 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellG
add_tail_nr_list(&sched_ctrl->available_ul_harq, harq); add_tail_nr_list(&sched_ctrl->available_ul_harq, harq);
create_nr_list(&sched_ctrl->feedback_ul_harq, 16); create_nr_list(&sched_ctrl->feedback_ul_harq, 16);
create_nr_list(&sched_ctrl->retrans_ul_harq, 16); create_nr_list(&sched_ctrl->retrans_ul_harq, 16);
LOG_D(NR_MAC, "[gNB %d] Add NR UE_id %d : rnti %x\n",
mod_idP, pthread_mutex_lock(&UE_info->mutex);
UE_id, int i;
rntiP); for(i=0; i<MAX_MOBILES_PER_GNB; i++)
dump_nr_list(&UE_info->list); if (UE_info->list[i] == NULL) {
return (UE_id); UE_info->list[i] = UE;
break;
}
if (i == MAX_MOBILES_PER_GNB) {
LOG_E(NR_MAC,"Try to add UE %04x but the list is full\n", rntiP);
delete_nr_ue_data(UE, nr_mac->common_channels);
pthread_mutex_unlock(&UE_info->mutex);
return NULL;
} }
pthread_mutex_unlock(&UE_info->mutex);
// printf("MAC: cannot add new UE for rnti %x\n", rntiP); LOG_D(NR_MAC, "Add NR rnti %x\n", rntiP);
LOG_E(NR_MAC, "error in add_new_ue(), could not find space in UE_info, Dumping UE list\n"); dump_nr_list(UE_info->list);
dump_nr_list(&UE_info->list); return (UE);
return -1;
} }
void create_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl, void create_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl,
const NR_PDSCH_ServingCellConfig_t *pdsch) { const NR_PDSCH_ServingCellConfig_t *pdsch) {
const int nrofHARQ = pdsch && pdsch->nrofHARQ_ProcessesForPDSCH ? const int nrofHARQ = pdsch && pdsch->nrofHARQ_ProcessesForPDSCH ?
@@ -2512,66 +2546,30 @@ void create_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl,
} }
} }
/* hack data to remove UE in the phy */ void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti)
int rnti_to_remove[10];
volatile int rnti_to_remove_count;
pthread_mutex_t rnti_to_remove_mutex = PTHREAD_MUTEX_INITIALIZER;
void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti)
{ {
int UE_id; NR_UEs_t *UE_info = &nr_mac->UE_info;
int i; pthread_mutex_lock(&UE_info->mutex);
int cc_id; UE_iterator(UE_info->list, UE) {
NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info; if (UE->rnti==rnti)
break;
}
for (i = 0; i < MAX_MOBILES_PER_GNB; i++) { if (!UE) {
LOG_W(NR_MAC,"Call to del rnti %04x, but not existing\n", rnti);
pthread_mutex_unlock(&UE_info->mutex);
return;
}
if (UE_info->active[i] != TRUE) NR_UE_info_t * newUEs[MAX_MOBILES_PER_GNB+1]={0};
continue; int newListIdx=0;
if (UE_info->rnti[i] != rnti) for (int i=0; i<MAX_MOBILES_PER_GNB; i++)
continue; if(UE_info->list[i] && UE_info->list[i]->rnti != rnti)
newUEs[newListIdx++]=UE_info->list[i];
memcpy(UE_info->list, newUEs, sizeof(UE_info->list));
pthread_mutex_unlock(&UE_info->mutex);
/* UE found, remove it */ delete_nr_ue_data(UE, nr_mac->common_channels);
UE_id = i;
UE_info->num_UEs--;
UE_info->active[UE_id] = FALSE;
UE_info->rnti[UE_id] = 0;
remove_nr_list(&UE_info->list, UE_id);
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
destroy_nr_list(&sched_ctrl->available_dl_harq);
destroy_nr_list(&sched_ctrl->feedback_dl_harq);
destroy_nr_list(&sched_ctrl->retrans_dl_harq);
destroy_nr_list(&sched_ctrl->available_ul_harq);
destroy_nr_list(&sched_ctrl->feedback_ul_harq);
destroy_nr_list(&sched_ctrl->retrans_ul_harq);
LOG_I(NR_MAC, "[gNB %d] Remove NR UE_id %d: rnti 0x%04x\n",
mod_id,
UE_id,
rnti);
/* hack to remove UE in the phy */
if (pthread_mutex_lock(&rnti_to_remove_mutex)) exit(1);
if (rnti_to_remove_count == 10) exit(1);
rnti_to_remove[rnti_to_remove_count] = rnti;
LOG_W(NR_MAC, "to remove in mac rnti_to_remove[%d] = 0x%04x\n", rnti_to_remove_count, rnti);
rnti_to_remove_count++;
if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1);
}
/* clear RA process(es?) associated to the UE */
for (cc_id = 0; cc_id < NFAPI_CC_MAX; cc_id++) {
NR_COMMON_channels_t *cc = &RC.nrmac[mod_id]->common_channels[cc_id];
for (i = 0; i < NR_NB_RA_PROC_MAX; i++) {
if (cc->ra[i].rnti == rnti) {
LOG_D(NR_MAC, "free RA process %d for rnti %d\n", i, rnti);
/* is it enough? */
cc->ra[i].cfra = false;
cc->ra[i].rnti = 0;
cc->ra[i].crnti = 0;
}
}
}
} }
void nr_mac_remove_ra_rnti(module_id_t mod_id, rnti_t rnti) { void nr_mac_remove_ra_rnti(module_id_t mod_id, rnti_t rnti) {
@@ -2595,20 +2593,18 @@ uint8_t nr_get_tpc(int target, uint8_t cqi, int incr) {
} }
void get_pdsch_to_harq_feedback(int Mod_idP, void get_pdsch_to_harq_feedback( NR_UE_info_t * UE,
int UE_id,
int bwp_id, int bwp_id,
NR_SearchSpace__searchSpaceType_PR ss_type, NR_SearchSpace__searchSpaceType_PR ss_type,
int *max_fb_time, int *max_fb_time,
uint8_t *pdsch_to_harq_feedback) { uint8_t *pdsch_to_harq_feedback) {
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; NR_CellGroupConfig_t *CellGroup = UE->CellGroup;
NR_CellGroupConfig_t *CellGroup = UE_info->CellGroup[UE_id];
NR_BWP_DownlinkDedicated_t *bwpd=NULL; NR_BWP_DownlinkDedicated_t *bwpd=NULL;
NR_BWP_UplinkDedicated_t *ubwpd=NULL; NR_BWP_UplinkDedicated_t *ubwpd=NULL;
if (ss_type == NR_SearchSpace__searchSpaceType_PR_ue_Specific) { if (ss_type == NR_SearchSpace__searchSpaceType_PR_ue_Specific) {
AssertFatal(CellGroup!=NULL,"Cellgroup is not defined for UE_id %d\n",UE_id); AssertFatal(CellGroup!=NULL,"Cellgroup is not defined for UE %04x\n",UE->rnti);
AssertFatal(CellGroup->spCellConfig!=NULL,"Cellgroup->spCellConfig is null\n"); AssertFatal(CellGroup->spCellConfig!=NULL,"Cellgroup->spCellConfig is null\n");
AssertFatal(CellGroup->spCellConfig->spCellConfigDedicated!=NULL,"CellGroup->spCellConfig->spCellConfigDedicated is null\n"); AssertFatal(CellGroup->spCellConfig->spCellConfigDedicated!=NULL,"CellGroup->spCellConfig->spCellConfigDedicated is null\n");
} }
@@ -2692,22 +2688,18 @@ void nr_csirs_scheduling(int Mod_idP,
int n_slots_frame){ int n_slots_frame){
int CC_id = 0; int CC_id = 0;
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; NR_UEs_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
NR_list_t *UE_list = &UE_info->list;
gNB_MAC_INST *gNB_mac = RC.nrmac[Mod_idP]; gNB_MAC_INST *gNB_mac = RC.nrmac[Mod_idP];
uint16_t *vrb_map = gNB_mac->common_channels[CC_id].vrb_map; uint16_t *vrb_map = gNB_mac->common_channels[CC_id].vrb_map;
UE_info->sched_csirs = false;
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { UE_iterator(UE_info->list, UE) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
if (sched_ctrl->rrc_processing_timer > 0) { if (sched_ctrl->rrc_processing_timer > 0) {
continue; continue;
} }
NR_CellGroupConfig_t *CellGroup = UE->CellGroup;
NR_CellGroupConfig_t *CellGroup = UE_info->CellGroup[UE_id];
if (!CellGroup || !CellGroup->spCellConfig || !CellGroup->spCellConfig->spCellConfigDedicated || if (!CellGroup || !CellGroup->spCellConfig || !CellGroup->spCellConfig->spCellConfigDedicated ||
!CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig) continue; !CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig) continue;
@@ -2723,6 +2715,7 @@ void nr_csirs_scheduling(int Mod_idP,
NR_BWP_t *genericParameters = sched_ctrl->active_bwp ? NR_BWP_t *genericParameters = sched_ctrl->active_bwp ?
&sched_ctrl->active_bwp->bwp_Common->genericParameters : &sched_ctrl->active_bwp->bwp_Common->genericParameters :
&gNB_mac->common_channels[0].ServingCellConfigCommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters; &gNB_mac->common_channels[0].ServingCellConfigCommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
for (int id = 0; id < csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.count; id++){ for (int id = 0; id < csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.count; id++){
nzpcsi = csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.array[id]; nzpcsi = csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.array[id];
NR_CSI_RS_ResourceMapping_t resourceMapping = nzpcsi->resourceMapping; NR_CSI_RS_ResourceMapping_t resourceMapping = nzpcsi->resourceMapping;
@@ -2731,7 +2724,7 @@ void nr_csirs_scheduling(int Mod_idP,
if((frame*n_slots_frame+slot-offset)%period == 0) { if((frame*n_slots_frame+slot-offset)%period == 0) {
LOG_D(NR_MAC,"Scheduling CSI-RS in frame %d slot %d\n",frame,slot); LOG_D(NR_MAC,"Scheduling CSI-RS in frame %d slot %d\n",frame,slot);
UE_info->sched_csirs = true; UE->sched_csirs = true;
nfapi_nr_dl_tti_request_pdu_t *dl_tti_csirs_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; nfapi_nr_dl_tti_request_pdu_t *dl_tti_csirs_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
memset((void*)dl_tti_csirs_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); memset((void*)dl_tti_csirs_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
@@ -2899,18 +2892,17 @@ void nr_csirs_scheduling(int Mod_idP,
void nr_mac_update_timers(module_id_t module_id, void nr_mac_update_timers(module_id_t module_id,
frame_t frame, frame_t frame,
sub_frame_t slot) { sub_frame_t slot) {
NR_UEs_t *UE_info = &RC.nrmac[module_id]->UE_info;
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; UE_iterator(UE_info->list, UE) {
const NR_list_t *UE_list = &UE_info->list; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
if (sched_ctrl->rrc_processing_timer > 0) { if (sched_ctrl->rrc_processing_timer > 0) {
sched_ctrl->rrc_processing_timer--; sched_ctrl->rrc_processing_timer--;
if (sched_ctrl->rrc_processing_timer == 0) { if (sched_ctrl->rrc_processing_timer == 0) {
LOG_I(NR_MAC, "(%d.%d) De-activating RRC processing timer for UE %d\n", frame, slot, UE_id); LOG_I(NR_MAC, "(%d.%d) De-activating RRC processing timer for UE %04x\n", frame, slot, UE->rnti);
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id]; NR_CellGroupConfig_t *cg = UE->CellGroup;
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
const NR_ServingCellConfig_t *spCellConfigDedicated = cg && cg->spCellConfig ? cg->spCellConfig->spCellConfigDedicated : NULL; const NR_ServingCellConfig_t *spCellConfigDedicated = cg && cg->spCellConfig ? cg->spCellConfig->spCellConfigDedicated : NULL;
@@ -2984,23 +2976,22 @@ void schedule_nr_bwp_switch(module_id_t module_id,
frame_t frame, frame_t frame,
sub_frame_t slot) { sub_frame_t slot) {
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; NR_UEs_t *UE_info = &RC.nrmac[module_id]->UE_info;
const NR_list_t *UE_list = &UE_info->list;
// TODO: Implementation of a algorithm to perform: // TODO: Implementation of a algorithm to perform:
// - DL BWP selection: sched_ctrl->next_dl_bwp_id = dl_bwp_id // - DL BWP selection: sched_ctrl->next_dl_bwp_id = dl_bwp_id
// - UL BWP selection: sched_ctrl->next_ul_bwp_id = ul_bwp_id // - UL BWP selection: sched_ctrl->next_ul_bwp_id = ul_bwp_id
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { UE_iterator(UE_info->list, UE) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
if (sched_ctrl->rrc_processing_timer == 0 && if (sched_ctrl->rrc_processing_timer == 0 &&
UE_info->Msg4_ACKed[UE_id] == true && UE->Msg4_ACKed &&
((sched_ctrl->next_dl_bwp_id >= 0 && sched_ctrl->active_bwp && sched_ctrl->active_bwp->bwp_Id != sched_ctrl->next_dl_bwp_id) || ((sched_ctrl->next_dl_bwp_id >= 0 && sched_ctrl->active_bwp && sched_ctrl->active_bwp->bwp_Id != sched_ctrl->next_dl_bwp_id) ||
(sched_ctrl->next_ul_bwp_id >= 0 && sched_ctrl->active_ubwp && sched_ctrl->active_ubwp->bwp_Id != sched_ctrl->next_ul_bwp_id))) { (sched_ctrl->next_ul_bwp_id >= 0 && sched_ctrl->active_ubwp && sched_ctrl->active_ubwp->bwp_Id != sched_ctrl->next_ul_bwp_id))) {
LOG_W(NR_MAC,"(%d.%d) [UE_id %d] Schedule BWP switch from dl_bwp_id %ld to %ld and from ul_bwp_id %ld to %ld\n", LOG_W(NR_MAC,"%4d.%2d UE %04x Schedule BWP switch from dl_bwp_id %ld to %ld and from ul_bwp_id %ld to %ld\n",
frame, slot, UE_id, sched_ctrl->active_bwp->bwp_Id, sched_ctrl->next_dl_bwp_id, sched_ctrl->active_ubwp->bwp_Id, sched_ctrl->next_ul_bwp_id); frame, slot, UE->rnti, sched_ctrl->active_bwp->bwp_Id, sched_ctrl->next_dl_bwp_id, sched_ctrl->active_ubwp->bwp_Id, sched_ctrl->next_ul_bwp_id);
nr_mac_rrc_bwp_switch_req(module_id, frame, slot, UE_info->rnti[UE_id], sched_ctrl->next_dl_bwp_id, sched_ctrl->next_ul_bwp_id); nr_mac_rrc_bwp_switch_req(module_id, frame, slot, UE->rnti, sched_ctrl->next_dl_bwp_id, sched_ctrl->next_ul_bwp_id);
} }
} }
} }
+12 -15
View File
@@ -34,18 +34,17 @@
extern RAN_CONTEXT_t RC; extern RAN_CONTEXT_t RC;
void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu, int module_id, int CC_id, int UE_id, NR_SRS_Resource_t *srs_resource) { void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu, int module_id, int CC_id,NR_UE_info_t* UE, NR_SRS_Resource_t *srs_resource) {
gNB_MAC_INST *nrmac = RC.nrmac[module_id]; gNB_MAC_INST *nrmac = RC.nrmac[module_id];
NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
NR_UE_info_t *UE_info = &nrmac->UE_info; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
NR_BWP_t ubwp = sched_ctrl->active_ubwp ? NR_BWP_t ubwp = sched_ctrl->active_ubwp ?
sched_ctrl->active_ubwp->bwp_Common->genericParameters : sched_ctrl->active_ubwp->bwp_Common->genericParameters :
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
srs_pdu->rnti = UE_info->rnti[UE_id]; srs_pdu->rnti = UE->rnti;
srs_pdu->handle = 0; srs_pdu->handle = 0;
srs_pdu->bwp_size = NRRIV2BW(ubwp.locationAndBandwidth, MAX_BWP_SIZE);; srs_pdu->bwp_size = NRRIV2BW(ubwp.locationAndBandwidth, MAX_BWP_SIZE);;
srs_pdu->bwp_start = NRRIV2PRBOFFSET(ubwp.locationAndBandwidth, MAX_BWP_SIZE);; srs_pdu->bwp_start = NRRIV2PRBOFFSET(ubwp.locationAndBandwidth, MAX_BWP_SIZE);;
@@ -82,7 +81,7 @@ void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu, int module_id, int CC_id, int
srs_pdu->t_offset = get_nr_srs_offset(srs_resource->resourceType.choice.periodic->periodicityAndOffset_p); srs_pdu->t_offset = get_nr_srs_offset(srs_resource->resourceType.choice.periodic->periodicityAndOffset_p);
} }
void nr_fill_nfapi_srs(int module_id, int CC_id, int UE_id, sub_frame_t slot, NR_SRS_Resource_t *srs_resource) { void nr_fill_nfapi_srs(int module_id, int CC_id, NR_UE_info_t* UE, sub_frame_t slot, NR_SRS_Resource_t *srs_resource) {
nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_id]->UL_tti_req_ahead[0][slot]; nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_id]->UL_tti_req_ahead[0][slot];
AssertFatal(future_ul_tti_req->n_pdus < AssertFatal(future_ul_tti_req->n_pdus <
@@ -94,7 +93,7 @@ void nr_fill_nfapi_srs(int module_id, int CC_id, int UE_id, sub_frame_t slot, NR
memset(srs_pdu, 0, sizeof(nfapi_nr_srs_pdu_t)); memset(srs_pdu, 0, sizeof(nfapi_nr_srs_pdu_t));
future_ul_tti_req->n_pdus += 1; future_ul_tti_req->n_pdus += 1;
nr_configure_srs(srs_pdu, module_id, CC_id, UE_id, srs_resource); nr_configure_srs(srs_pdu, module_id, CC_id, UE, srs_resource);
} }
/******************************************************************* /*******************************************************************
@@ -111,21 +110,19 @@ void nr_fill_nfapi_srs(int module_id, int CC_id, int UE_id, sub_frame_t slot, NR
void nr_schedule_srs(int module_id, frame_t frame) { void nr_schedule_srs(int module_id, frame_t frame) {
gNB_MAC_INST *nrmac = RC.nrmac[module_id]; gNB_MAC_INST *nrmac = RC.nrmac[module_id];
NR_UE_info_t *UE_info = &nrmac->UE_info; NR_UEs_t *UE_info = &nrmac->UE_info;
const NR_list_t *UE_list = &UE_info->list;
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
UE_iterator(UE_info->list, UE) {
const int CC_id = 0; const int CC_id = 0;
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[CC_id].ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[CC_id].ServingCellConfigCommon;
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id]; NR_CellGroupConfig_t *cg = UE->CellGroup;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
sched_ctrl->sched_srs.frame = -1; sched_ctrl->sched_srs.frame = -1;
sched_ctrl->sched_srs.slot = -1; sched_ctrl->sched_srs.slot = -1;
sched_ctrl->sched_srs.srs_scheduled = false; sched_ctrl->sched_srs.srs_scheduled = false;
if(!UE_info->Msg4_ACKed[UE_id] || sched_ctrl->rrc_processing_timer > 0) { if(!UE->Msg4_ACKed || sched_ctrl->rrc_processing_timer > 0) {
continue; continue;
} }
@@ -178,11 +175,11 @@ void nr_schedule_srs(int module_id, frame_t frame) {
// Check if UE will transmit the SRS in this frame // Check if UE will transmit the SRS in this frame
if ( ((frame - offset/n_slots_frame)*n_slots_frame)%period == 0) { if ( ((frame - offset/n_slots_frame)*n_slots_frame)%period == 0) {
LOG_D(NR_MAC,"Scheduling SRS reception for %d.%d\n", frame, offset%n_slots_frame); LOG_D(NR_MAC,"Scheduling SRS reception for %d.%d\n", frame, offset%n_slots_frame);
nr_fill_nfapi_srs(module_id, CC_id, UE_id, offset%n_slots_frame, srs_resource); nr_fill_nfapi_srs(module_id, CC_id, UE, offset%n_slots_frame, srs_resource);
sched_ctrl->sched_srs.frame = frame; sched_ctrl->sched_srs.frame = frame;
sched_ctrl->sched_srs.slot = offset%n_slots_frame; sched_ctrl->sched_srs.slot = offset%n_slots_frame;
sched_ctrl->sched_srs.srs_scheduled = true; sched_ctrl->sched_srs.srs_scheduled = true;
} }
} }
} }
} }
+139 -150
View File
@@ -38,17 +38,15 @@
extern RAN_CONTEXT_t RC; extern RAN_CONTEXT_t RC;
void nr_fill_nfapi_pucch(module_id_t mod_id,
frame_t frame,
sub_frame_t slot,
const NR_sched_pucch_t *pucch,
int UE_id)
{
gNB_MAC_INST *nr_mac = RC.nrmac[mod_id];
NR_UE_info_t *UE_info = &nr_mac->UE_info;
static void nr_fill_nfapi_pucch(gNB_MAC_INST *nrmac,
frame_t frame,
sub_frame_t slot,
const NR_sched_pucch_t *pucch,
NR_UE_info_t* UE)
{
nfapi_nr_ul_tti_request_t *future_ul_tti_req = nfapi_nr_ul_tti_request_t *future_ul_tti_req =
&RC.nrmac[mod_id]->UL_tti_req_ahead[0][pucch->ul_slot]; &nrmac->UL_tti_req_ahead[0][pucch->ul_slot];
AssertFatal(future_ul_tti_req->SFN == pucch->frame AssertFatal(future_ul_tti_req->SFN == pucch->frame
&& future_ul_tti_req->Slot == pucch->ul_slot, && future_ul_tti_req->Slot == pucch->ul_slot,
"Current %4d.%2d : future UL_tti_req's frame.slot %4d.%2d does not match PUCCH %4d.%2d\n", "Current %4d.%2d : future UL_tti_req's frame.slot %4d.%2d does not match PUCCH %4d.%2d\n",
@@ -57,8 +55,7 @@ void nr_fill_nfapi_pucch(module_id_t mod_id,
future_ul_tti_req->Slot, future_ul_tti_req->Slot,
pucch->frame, pucch->frame,
pucch->ul_slot); pucch->ul_slot);
AssertFatal(future_ul_tti_req->n_pdus < AssertFatal(future_ul_tti_req->n_pdus < sizeofArray(future_ul_tti_req->pdus_list),
sizeof(future_ul_tti_req->pdus_list) / sizeof(future_ul_tti_req->pdus_list[0]),
"Invalid future_ul_tti_req->n_pdus %d\n", future_ul_tti_req->n_pdus); "Invalid future_ul_tti_req->n_pdus %d\n", future_ul_tti_req->n_pdus);
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE; future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE;
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pucch_pdu_t); future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pucch_pdu_t);
@@ -77,9 +74,9 @@ void nr_fill_nfapi_pucch(module_id_t mod_id,
pucch->dai_c, pucch->dai_c,
pucch->csi_bits, pucch->csi_bits,
pucch->resource_indicator); pucch->resource_indicator);
NR_COMMON_channels_t * common_ch=nrmac->common_channels;
NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = common_ch->ServingCellConfigCommon;
NR_CellGroupConfig_t *cg=UE_info->CellGroup[UE_id]; NR_CellGroupConfig_t *cg=UE->CellGroup;
NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated && NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated &&
cg->spCellConfig->spCellConfigDedicated->uplinkConfig ? cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
@@ -88,14 +85,14 @@ void nr_fill_nfapi_pucch(module_id_t mod_id,
LOG_D(NR_MAC,"%4d.%2d Calling nr_configure_pucch (ubwpd %p,r_pucch %d) pucch to be scheduled in %4d.%2d\n", LOG_D(NR_MAC,"%4d.%2d Calling nr_configure_pucch (ubwpd %p,r_pucch %d) pucch to be scheduled in %4d.%2d\n",
frame,slot,ubwpd,pucch->r_pucch,pucch->frame,pucch->ul_slot); frame,slot,ubwpd,pucch->r_pucch,pucch->frame,pucch->ul_slot);
const NR_SIB1_t *sib1 = nr_mac->common_channels[0].sib1 ? nr_mac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; const NR_SIB1_t *sib1 = common_ch->sib1 ? common_ch->sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
nr_configure_pucch(sib1, nr_configure_pucch(sib1,
pucch_pdu, pucch_pdu,
scc, scc,
UE_info->CellGroup[UE_id], UE->CellGroup,
UE_info->UE_sched_ctrl[UE_id].active_ubwp, UE->UE_sched_ctrl.active_ubwp,
ubwpd, ubwpd,
UE_info->rnti[UE_id], UE->rnti,
pucch->resource_indicator, pucch->resource_indicator,
pucch->csi_bits, pucch->csi_bits,
pucch->dai_c, pucch->dai_c,
@@ -139,22 +136,18 @@ int diff_rsrp_ssb_csi_meas_10_1_6_1_2[16] = {
}; };
void nr_schedule_pucch(int Mod_idP, void nr_schedule_pucch(gNB_MAC_INST *nrmac,
frame_t frameP, frame_t frameP,
sub_frame_t slotP) sub_frame_t slotP)
{ {
gNB_MAC_INST *nrmac = RC.nrmac[Mod_idP];
if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slotP / 64], slotP)) if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slotP / 64], slotP))
return; return;
NR_UE_info_t *UE_info = &nrmac->UE_info; UE_iterator(nrmac->UE_info.list, UE) {
const NR_list_t *UE_list = &UE_info->list; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
const int n = sizeof(sched_ctrl->sched_pucch) / sizeof(*sched_ctrl->sched_pucch); const int n = sizeof(sched_ctrl->sched_pucch) / sizeof(*sched_ctrl->sched_pucch);
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
NR_sched_pucch_t *curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[i]; NR_sched_pucch_t *curr_pucch = &UE->UE_sched_ctrl.sched_pucch[i];
const uint16_t O_ack = curr_pucch->dai_c; const uint16_t O_ack = curr_pucch->dai_c;
const uint16_t O_csi = curr_pucch->csi_bits; const uint16_t O_csi = curr_pucch->csi_bits;
const uint8_t O_sr = curr_pucch->sr_flag; const uint8_t O_sr = curr_pucch->sr_flag;
@@ -162,9 +155,11 @@ void nr_schedule_pucch(int Mod_idP,
|| frameP != curr_pucch->frame || frameP != curr_pucch->frame
|| slotP != curr_pucch->ul_slot) || slotP != curr_pucch->ul_slot)
continue; continue;
if (O_csi > 0) LOG_D(NR_MAC,"Scheduling PUCCH[%d] RX for UE %d in %4d.%2d O_ack %d, O_sr %d, O_csi %d\n",
i,UE_id,curr_pucch->frame,curr_pucch->ul_slot,O_ack,O_sr,O_csi); if (O_csi > 0)
nr_fill_nfapi_pucch(Mod_idP, frameP, slotP, curr_pucch, UE_id); LOG_D(NR_MAC,"Scheduling PUCCH[%d] RX for UE %04x in %4d.%2d O_ack %d, O_sr %d, O_csi %d\n",
i,UE->rnti,curr_pucch->frame,curr_pucch->ul_slot,O_ack,O_sr,O_csi);
nr_fill_nfapi_pucch(nrmac, frameP, slotP, curr_pucch, UE);
memset(curr_pucch, 0, sizeof(*curr_pucch)); memset(curr_pucch, 0, sizeof(*curr_pucch));
} }
} }
@@ -565,7 +560,7 @@ void compute_cqi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
//!TODO : same function can be written to handle csi_resources //!TODO : same function can be written to handle csi_resources
void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_info, int UE_id, module_id_t Mod_idP){ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE){
uint8_t csi_report_id = 0; uint8_t csi_report_id = 0;
uint8_t nb_resources = 0; uint8_t nb_resources = 0;
NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type; NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type;
@@ -577,7 +572,7 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in
for (csi_report_id=0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){ for (csi_report_id=0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){
struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]; struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
// MAC structure for CSI measurement reports (per UE and per report) // MAC structure for CSI measurement reports (per UE and per report)
nr_csi_report_t *csi_report = &UE_info->csi_report_template[UE_id][csi_report_id]; nr_csi_report_t *csi_report = &UE->csi_report_template[csi_report_id];
// csi-ResourceConfigId of a CSI-ResourceConfig included in the configuration // csi-ResourceConfigId of a CSI-ResourceConfig included in the configuration
// (either CSI-RS or SSB) // (either CSI-RS or SSB)
csi_ResourceConfigId = csi_reportconfig->resourcesForChannelMeasurement; csi_ResourceConfigId = csi_reportconfig->resourcesForChannelMeasurement;
@@ -662,24 +657,22 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in
} }
uint16_t nr_get_csi_bitlen(int Mod_idP, uint16_t nr_get_csi_bitlen(NR_UE_info_t *UE,
int UE_id,
uint8_t csi_report_id) { uint8_t csi_report_id) {
uint16_t csi_bitlen = 0; uint16_t csi_bitlen = 0;
uint16_t max_bitlen = 0; uint16_t max_bitlen = 0;
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
L1_RSRP_bitlen_t * CSI_report_bitlen = NULL; L1_RSRP_bitlen_t * CSI_report_bitlen = NULL;
CSI_Meas_bitlen_t * csi_meas_bitlen = NULL; CSI_Meas_bitlen_t * csi_meas_bitlen = NULL;
if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP==UE_info->csi_report_template[UE_id][csi_report_id].reportQuantity_type|| if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP==UE->csi_report_template[csi_report_id].reportQuantity_type||
NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP==UE_info->csi_report_template[UE_id][csi_report_id].reportQuantity_type){ NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP==UE->csi_report_template[csi_report_id].reportQuantity_type){
CSI_report_bitlen = &(UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements CSI_report_bitlen = &(UE->csi_report_template[csi_report_id].CSI_report_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements
csi_bitlen+= ((CSI_report_bitlen->cri_ssbri_bitlen * CSI_report_bitlen->nb_ssbri_cri) + csi_bitlen+= ((CSI_report_bitlen->cri_ssbri_bitlen * CSI_report_bitlen->nb_ssbri_cri) +
CSI_report_bitlen->rsrp_bitlen +(CSI_report_bitlen->diff_rsrp_bitlen * CSI_report_bitlen->rsrp_bitlen +(CSI_report_bitlen->diff_rsrp_bitlen *
(CSI_report_bitlen->nb_ssbri_cri -1 ))); (CSI_report_bitlen->nb_ssbri_cri -1 )));
} else{ } else{
csi_meas_bitlen = &(UE_info->csi_report_template[UE_id][csi_report_id].csi_meas_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements csi_meas_bitlen = &(UE->csi_report_template[csi_report_id].csi_meas_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements
uint16_t temp_bitlen; uint16_t temp_bitlen;
for (int i=0; i<8; i++) { for (int i=0; i<8; i++) {
temp_bitlen = (csi_meas_bitlen->cri_bitlen+ temp_bitlen = (csi_meas_bitlen->cri_bitlen+
@@ -705,11 +698,10 @@ void nr_csi_meas_reporting(int Mod_idP,
NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
NR_list_t *UE_list = &UE_info->list; UE_iterator(RC.nrmac[Mod_idP]->UE_info.list, UE ) {
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { const NR_CellGroupConfig_t *CellGroup = UE->CellGroup;
const NR_CellGroupConfig_t *CellGroup = UE_info->CellGroup[UE_id]; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
if ((sched_ctrl->rrc_processing_timer > 0) || (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0)) { if ((sched_ctrl->rrc_processing_timer > 0) || (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0)) {
continue; continue;
} }
@@ -761,13 +753,13 @@ void nr_csi_meas_reporting(int Mod_idP,
&& !curr_pucch->sr_flag && !curr_pucch->sr_flag
&& curr_pucch->dai_c == 0, && curr_pucch->dai_c == 0,
"PUCCH not free at index 1 for UE %04x\n", "PUCCH not free at index 1 for UE %04x\n",
UE_info->rnti[UE_id]); UE->rnti);
curr_pucch->r_pucch = -1; curr_pucch->r_pucch = -1;
curr_pucch->frame = frame; curr_pucch->frame = frame;
curr_pucch->ul_slot = sched_slot; curr_pucch->ul_slot = sched_slot;
curr_pucch->resource_indicator = res_index; curr_pucch->resource_indicator = res_index;
curr_pucch->csi_bits += curr_pucch->csi_bits +=
nr_get_csi_bitlen(Mod_idP,UE_id,csi_report_id); nr_get_csi_bitlen(UE,csi_report_id);
const NR_SIB1_t *sib1 = RC.nrmac[Mod_idP]->common_channels[0].sib1 ? RC.nrmac[Mod_idP]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; const NR_SIB1_t *sib1 = RC.nrmac[Mod_idP]->common_channels[0].sib1 ? RC.nrmac[Mod_idP]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp, NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp,
@@ -819,37 +811,37 @@ void nr_csi_meas_reporting(int Mod_idP,
} }
} }
__attribute__((unused)) static void handle_dl_harq(NR_UE_info_t * UE,
static void handle_dl_harq(module_id_t mod_id,
int UE_id,
int8_t harq_pid, int8_t harq_pid,
bool success) bool success,
int harq_round_max)
{ {
NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info; NR_UE_harq_t *harq = &UE->UE_sched_ctrl.harq_processes[harq_pid];
NR_UE_harq_t *harq = &UE_info->UE_sched_ctrl[UE_id].harq_processes[harq_pid];
harq->feedback_slot = -1; harq->feedback_slot = -1;
harq->is_waiting = false; harq->is_waiting = false;
if (success) { if (success) {
add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].available_dl_harq, harq_pid); add_tail_nr_list(&UE->UE_sched_ctrl.available_dl_harq, harq_pid);
harq->round = 0; harq->round = 0;
harq->ndi ^= 1; harq->ndi ^= 1;
} else if (harq->round >= RC.nrmac[mod_id]->harq_round_max - 1) {
add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].available_dl_harq, harq_pid); } else if (harq->round >= harq_round_max - 1) {
add_tail_nr_list(&UE->UE_sched_ctrl.available_dl_harq, harq_pid);
harq->round = 0; harq->round = 0;
harq->ndi ^= 1; harq->ndi ^= 1;
NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id];
NR_mac_stats_t *stats = &UE->mac_stats;
stats->dl.errors++; stats->dl.errors++;
LOG_D(NR_MAC, "retransmission error for UE %d (total %"PRIu64")\n", UE_id, stats->dl.errors); LOG_D(NR_MAC, "retransmission error for UE %04x (total %"PRIu64")\n", UE->rnti, stats->dl.errors);
} else { } else {
LOG_D(PHY,"NACK for: pid %d, ue %x\n",harq_pid, UE_id); LOG_D(PHY,"NACK for: pid %d, ue %04x\n",harq_pid, UE->rnti);
add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].retrans_dl_harq, harq_pid); add_tail_nr_list(&UE->UE_sched_ctrl.retrans_dl_harq, harq_pid);
harq->round++; harq->round++;
} }
} }
int checkTargetSSBInFirst64TCIStates_pdschConfig(int ssb_index_t, int Mod_idP, int UE_id) { int checkTargetSSBInFirst64TCIStates_pdschConfig(int ssb_index_t, NR_UE_info_t * UE) {
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; NR_CellGroupConfig_t *CellGroup = UE->CellGroup;
NR_CellGroupConfig_t *CellGroup = UE_info->CellGroup[UE_id] ;
int nb_tci_states = CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.count; int nb_tci_states = CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.count;
NR_TCI_State_t *tci =NULL; NR_TCI_State_t *tci =NULL;
int i; int i;
@@ -874,13 +866,12 @@ int checkTargetSSBInFirst64TCIStates_pdschConfig(int ssb_index_t, int Mod_idP, i
return -1; return -1;
} }
int checkTargetSSBInTCIStates_pdcchConfig(int ssb_index_t, int Mod_idP, int UE_id) { int checkTargetSSBInTCIStates_pdcchConfig(int ssb_index_t, NR_UE_info_t *UE) {
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; NR_CellGroupConfig_t *CellGroup = UE->CellGroup ;
NR_CellGroupConfig_t *CellGroup = UE_info->CellGroup[UE_id] ;
int nb_tci_states = CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.count; int nb_tci_states = CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.count;
NR_TCI_State_t *tci =NULL; NR_TCI_State_t *tci =NULL;
NR_TCI_StateId_t *tci_id = NULL; NR_TCI_StateId_t *tci_id = NULL;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_ControlResourceSet_t *coreset = sched_ctrl->coreset; NR_ControlResourceSet_t *coreset = sched_ctrl->coreset;
int i; int i;
int flag = 0; int flag = 0;
@@ -935,7 +926,7 @@ int get_diff_rsrp(uint8_t index, int strongest_rsrp) {
//identifies the target SSB Beam index //identifies the target SSB Beam index
//keeps the required date for PDCCH and PDSCH TCI state activation/deactivation CE consutruction globally //keeps the required date for PDCCH and PDSCH TCI state activation/deactivation CE consutruction globally
//handles triggering of PDCCH and PDSCH MAC CEs //handles triggering of PDCCH and PDSCH MAC CEs
void tci_handling(module_id_t Mod_idP, int UE_id, frame_t frame, slot_t slot) { void tci_handling(NR_UE_info_t *UE, frame_t frame, slot_t slot) {
int strongest_ssb_rsrp = 0; int strongest_ssb_rsrp = 0;
int cqi_idx = 0; int cqi_idx = 0;
@@ -947,10 +938,10 @@ void tci_handling(module_id_t Mod_idP, int UE_id, frame_t frame, slot_t slot) {
int ssb_index[MAX_NUM_SSB] = {0}; int ssb_index[MAX_NUM_SSB] = {0};
int ssb_rsrp[MAX_NUM_SSB] = {0}; int ssb_rsrp[MAX_NUM_SSB] = {0};
uint8_t idx = 0; uint8_t idx = 0;
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
const int bwp_id = sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0; const int bwp_id = sched_ctrl->active_bwp ? 1 : 0;
NR_CellGroupConfig_t *CellGroup = UE_info->CellGroup[UE_id]; NR_CellGroupConfig_t *CellGroup = UE->CellGroup;
//bwp indicator //bwp indicator
int n_dl_bwp=0; int n_dl_bwp=0;
@@ -960,7 +951,7 @@ void tci_handling(module_id_t Mod_idP, int UE_id, frame_t frame, slot_t slot) {
n_dl_bwp = CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count; n_dl_bwp = CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count;
uint8_t nr_ssbri_cri = 0; uint8_t nr_ssbri_cri = 0;
uint8_t nb_of_csi_ssb_report = UE_info->csi_report_template[UE_id][cqi_idx].nb_of_csi_ssb_report; uint8_t nb_of_csi_ssb_report = UE->csi_report_template[cqi_idx].nb_of_csi_ssb_report;
int better_rsrp_reported = -140-(-0); /*minimum_measured_RSRP_value - minimum_differntail_RSRP_value*///considering the minimum RSRP value as better RSRP initially int better_rsrp_reported = -140-(-0); /*minimum_measured_RSRP_value - minimum_differntail_RSRP_value*///considering the minimum RSRP value as better RSRP initially
uint8_t diff_rsrp_idx = 0; uint8_t diff_rsrp_idx = 0;
uint8_t i, j; uint8_t i, j;
@@ -1031,7 +1022,7 @@ void tci_handling(module_id_t Mod_idP, int UE_id, frame_t frame, slot_t slot) {
The length of the field is 7 bits The length of the field is 7 bits
*/ */
if(sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.coresetId == 0) { if(sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.coresetId == 0) {
int tci_state_id = checkTargetSSBInFirst64TCIStates_pdschConfig(ssb_index[target_ssb_beam_index], Mod_idP, UE_id); int tci_state_id = checkTargetSSBInFirst64TCIStates_pdschConfig(ssb_index[target_ssb_beam_index], UE);
if( tci_state_id != -1) if( tci_state_id != -1)
sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId = tci_state_id; sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId = tci_state_id;
@@ -1041,7 +1032,7 @@ void tci_handling(module_id_t Mod_idP, int UE_id, frame_t frame, slot_t slot) {
int flag = 0; int flag = 0;
for(i =0; ssb_index_sorted[i]!=0; i++) { for(i =0; ssb_index_sorted[i]!=0; i++) {
tci_state_id = checkTargetSSBInFirst64TCIStates_pdschConfig(ssb_index_sorted[i], Mod_idP, UE_id) ; tci_state_id = checkTargetSSBInFirst64TCIStates_pdschConfig(ssb_index_sorted[i],UE) ;
if(tci_state_id != -1 && ssb_rsrp_sorted[i] > ssb_rsrp[curr_ssb_beam_index] && ssb_rsrp_sorted[i] - ssb_rsrp[curr_ssb_beam_index] > L1_RSRP_HYSTERIS) { if(tci_state_id != -1 && ssb_rsrp_sorted[i] > ssb_rsrp[curr_ssb_beam_index] && ssb_rsrp_sorted[i] - ssb_rsrp[curr_ssb_beam_index] > L1_RSRP_HYSTERIS) {
sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId = tci_state_id; sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId = tci_state_id;
@@ -1055,7 +1046,7 @@ void tci_handling(module_id_t Mod_idP, int UE_id, frame_t frame, slot_t slot) {
} }
} }
} else { } else {
int tci_state_id = checkTargetSSBInTCIStates_pdcchConfig(ssb_index[target_ssb_beam_index], Mod_idP, UE_id); int tci_state_id = checkTargetSSBInTCIStates_pdcchConfig(ssb_index[target_ssb_beam_index], UE);
if (tci_state_id !=-1) if (tci_state_id !=-1)
sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId = tci_state_id; sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId = tci_state_id;
@@ -1065,7 +1056,7 @@ void tci_handling(module_id_t Mod_idP, int UE_id, frame_t frame, slot_t slot) {
int flag = 0; int flag = 0;
for(i =0; ssb_index_sorted[i]!=0; i++) { for(i =0; ssb_index_sorted[i]!=0; i++) {
tci_state_id = checkTargetSSBInTCIStates_pdcchConfig(ssb_index_sorted[i], Mod_idP, UE_id); tci_state_id = checkTargetSSBInTCIStates_pdcchConfig(ssb_index_sorted[i], UE);
if( tci_state_id != -1 && ssb_rsrp_sorted[i] > ssb_rsrp[curr_ssb_beam_index] && ssb_rsrp_sorted[i] - ssb_rsrp[curr_ssb_beam_index] > L1_RSRP_HYSTERIS) { if( tci_state_id != -1 && ssb_rsrp_sorted[i] > ssb_rsrp[curr_ssb_beam_index] && ssb_rsrp_sorted[i] - ssb_rsrp[curr_ssb_beam_index] > L1_RSRP_HYSTERIS) {
sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId = tci_state_id; sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId = tci_state_id;
@@ -1126,15 +1117,14 @@ uint8_t pickandreverse_bits(uint8_t *payload, uint16_t bitlen, uint8_t start_bit
} }
void evaluate_rsrp_report(NR_UE_info_t *UE_info, void evaluate_rsrp_report(NR_UE_info_t *UE,
NR_UE_sched_ctrl_t *sched_ctrl, NR_UE_sched_ctrl_t *sched_ctrl,
int UE_id,
uint8_t csi_report_id, uint8_t csi_report_id,
uint8_t *payload, uint8_t *payload,
int *cumul_bits, int *cumul_bits,
NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type){ NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type){
nr_csi_report_t *csi_report = &UE_info->csi_report_template[UE_id][csi_report_id]; nr_csi_report_t *csi_report = &UE->csi_report_template[csi_report_id];
uint8_t cri_ssbri_bitlen = csi_report->CSI_report_bitlen.cri_ssbri_bitlen; uint8_t cri_ssbri_bitlen = csi_report->CSI_report_bitlen.cri_ssbri_bitlen;
uint16_t curr_payload; uint16_t curr_payload;
@@ -1186,7 +1176,7 @@ void evaluate_rsrp_report(NR_UE_info_t *UE_info,
} }
csi_report->nb_of_csi_ssb_report++; csi_report->nb_of_csi_ssb_report++;
int strongest_ssb_rsrp = get_measured_rsrp(sched_ctrl->CSI_report.ssb_cri_report.RSRP); int strongest_ssb_rsrp = get_measured_rsrp(sched_ctrl->CSI_report.ssb_cri_report.RSRP);
NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id]; NR_mac_stats_t *stats = &UE->mac_stats;
// including ssb rsrp in mac stats // including ssb rsrp in mac stats
stats->cumul_rsrp += strongest_ssb_rsrp; stats->cumul_rsrp += strongest_ssb_rsrp;
stats->num_rsrp_meas++; stats->num_rsrp_meas++;
@@ -1324,22 +1314,19 @@ void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu, const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu,
frame_t frame, frame_t frame,
slot_t slot, slot_t slot,
int UE_id, NR_UE_info_t *UE,
module_id_t Mod_idP) { NR_ServingCellConfigCommon_t *scc)
{
/** From Table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel */ /** From Table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel */
NR_ServingCellConfigCommon_t *scc =
RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
uint8_t *payload = uci_pdu->csi_part1.csi_part1_payload; uint8_t *payload = uci_pdu->csi_part1.csi_part1_payload;
uint16_t bitlen = uci_pdu->csi_part1.csi_part1_bit_len; uint16_t bitlen = uci_pdu->csi_part1.csi_part1_bit_len;
NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type = NR_CSI_ReportConfig__reportQuantity_PR_NOTHING; NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type = NR_CSI_ReportConfig__reportQuantity_PR_NOTHING;
NR_UE_info_t *UE_info = &(RC.nrmac[Mod_idP]->UE_info); NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
int cumul_bits = 0; int cumul_bits = 0;
int r_index = -1; int r_index = -1;
for (int csi_report_id = 0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++ ) { for (int csi_report_id = 0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++ ) {
nr_csi_report_t *csi_report = &UE_info->csi_report_template[UE_id][csi_report_id]; nr_csi_report_t *csi_report = &UE->csi_report_template[csi_report_id];
csi_report->nb_of_csi_ssb_report = 0; csi_report->nb_of_csi_ssb_report = 0;
uint8_t cri_bitlen = 0; uint8_t cri_bitlen = 0;
uint8_t ri_bitlen = 0; uint8_t ri_bitlen = 0;
@@ -1354,10 +1341,10 @@ void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
LOG_D(MAC,"SFN/SF:%d/%d reportQuantity type = %d\n",frame,slot,reportQuantity_type); LOG_D(MAC,"SFN/SF:%d/%d reportQuantity type = %d\n",frame,slot,reportQuantity_type);
switch(reportQuantity_type){ switch(reportQuantity_type){
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP: case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP:
evaluate_rsrp_report(UE_info,sched_ctrl,UE_id,csi_report_id,payload,&cumul_bits,reportQuantity_type); evaluate_rsrp_report(UE,sched_ctrl,csi_report_id,payload,&cumul_bits,reportQuantity_type);
break; break;
case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP: case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP:
evaluate_rsrp_report(UE_info,sched_ctrl,UE_id,csi_report_id,payload,&cumul_bits,reportQuantity_type); evaluate_rsrp_report(UE,sched_ctrl,csi_report_id,payload,&cumul_bits,reportQuantity_type);
break; break;
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI: case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI:
cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen; cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen;
@@ -1413,7 +1400,7 @@ void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
} }
} }
static NR_UE_harq_t *find_harq(module_id_t mod_id, frame_t frame, sub_frame_t slot, int UE_id) static NR_UE_harq_t *find_harq(frame_t frame, sub_frame_t slot, NR_UE_info_t * UE, int harq_round_max)
{ {
/* In case of realtime problems: we can only identify a HARQ process by /* In case of realtime problems: we can only identify a HARQ process by
* timing. If the HARQ process's feedback_frame/feedback_slot is not the one we * timing. If the HARQ process's feedback_frame/feedback_slot is not the one we
@@ -1421,7 +1408,7 @@ static NR_UE_harq_t *find_harq(module_id_t mod_id, frame_t frame, sub_frame_t sl
* skip this HARQ process, which is what happens in the loop below. * skip this HARQ process, which is what happens in the loop below.
* Similarly, we might be "in advance", in which case we need to skip * Similarly, we might be "in advance", in which case we need to skip
* this result. */ * this result. */
NR_UE_sched_ctrl_t *sched_ctrl = &RC.nrmac[mod_id]->UE_info.UE_sched_ctrl[UE_id]; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
int8_t pid = sched_ctrl->feedback_dl_harq.head; int8_t pid = sched_ctrl->feedback_dl_harq.head;
if (pid < 0) if (pid < 0)
return NULL; return NULL;
@@ -1437,7 +1424,7 @@ static NR_UE_harq_t *find_harq(module_id_t mod_id, frame_t frame, sub_frame_t sl
frame, frame,
slot); slot);
remove_front_nr_list(&sched_ctrl->feedback_dl_harq); remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
handle_dl_harq(mod_id, UE_id, pid, 0); handle_dl_harq(UE, pid, 0, harq_round_max);
pid = sched_ctrl->feedback_dl_harq.head; pid = sched_ctrl->feedback_dl_harq.head;
if (pid < 0) if (pid < 0)
return NULL; return NULL;
@@ -1462,20 +1449,19 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
sub_frame_t slot, sub_frame_t slot,
const nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_01) const nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_01)
{ {
int UE_id = find_nr_UE_id(mod_id, uci_01->rnti); NR_UE_info_t * UE = find_nr_UE(&RC.nrmac[mod_id]->UE_info, uci_01->rnti);
if (UE_id < 0) { if (!UE) {
LOG_E(NR_MAC, "%s(): unknown RNTI %04x in PUCCH UCI\n", __func__, uci_01->rnti); LOG_E(NR_MAC, "%s(): unknown RNTI %04x in PUCCH UCI\n", __func__, uci_01->rnti);
return; return;
} }
NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
if (((uci_01->pduBitmap >> 1) & 0x01)) { if (((uci_01->pduBitmap >> 1) & 0x01)) {
// iterate over received harq bits // iterate over received harq bits
for (int harq_bit = 0; harq_bit < uci_01->harq->num_harq; harq_bit++) { for (int harq_bit = 0; harq_bit < uci_01->harq->num_harq; harq_bit++) {
const uint8_t harq_value = uci_01->harq->harq_list[harq_bit].harq_value; const uint8_t harq_value = uci_01->harq->harq_list[harq_bit].harq_value;
const uint8_t harq_confidence = uci_01->harq->harq_confidence_level; const uint8_t harq_confidence = uci_01->harq->harq_confidence_level;
NR_UE_harq_t *harq = find_harq(mod_id, frame, slot, UE_id); NR_UE_harq_t *harq = find_harq(frame, slot, UE, RC.nrmac[mod_id]->harq_round_max);
if (!harq) { if (!harq) {
LOG_E(NR_MAC, "Oh no! Could not find a harq in %s!\n", __FUNCTION__); LOG_E(NR_MAC, "Oh no! Could not find a harq in %s!\n", __FUNCTION__);
break; break;
@@ -1484,8 +1470,8 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
const int8_t pid = sched_ctrl->feedback_dl_harq.head; const int8_t pid = sched_ctrl->feedback_dl_harq.head;
remove_front_nr_list(&sched_ctrl->feedback_dl_harq); remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
LOG_D(NR_MAC,"%4d.%2d bit %d pid %d ack/nack %d\n",frame, slot, harq_bit,pid,harq_value); LOG_D(NR_MAC,"%4d.%2d bit %d pid %d ack/nack %d\n",frame, slot, harq_bit,pid,harq_value);
handle_dl_harq(mod_id, UE_id, pid, harq_value == 0 && harq_confidence == 0); handle_dl_harq(UE, pid, harq_value == 0 && harq_confidence == 0, RC.nrmac[mod_id]->harq_round_max);
if (harq_confidence == 1) UE_info->mac_stats[UE_id].pucch0_DTX++; if (harq_confidence == 1) UE->mac_stats.pucch0_DTX++;
} }
} }
@@ -1510,19 +1496,21 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
sub_frame_t slot, sub_frame_t slot,
const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_234) const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_234)
{ {
int UE_id = find_nr_UE_id(mod_id, uci_234->rnti); NR_UE_info_t * UE = find_nr_UE(&RC.nrmac[mod_id]->UE_info, uci_234->rnti);
if (UE_id < 0) { if (!UE) {
LOG_E(NR_MAC, "%s(): unknown RNTI %04x in PUCCH UCI\n", __func__, uci_234->rnti); LOG_E(NR_MAC, "%s(): unknown RNTI %04x in PUCCH UCI\n", __func__, uci_234->rnti);
return; return;
} }
AssertFatal(RC.nrmac[mod_id]->UE_info.CellGroup[UE_id],"Cellgroup is null for UE %d/%x\n",UE_id,uci_234->rnti); AssertFatal(UE->CellGroup,"Cellgroup is null for UE %04x\n", uci_234->rnti);
AssertFatal(RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig, "Cellgroup->spCellConfig is null for UE %d/%x\n",UE_id,uci_234->rnti); AssertFatal(UE->CellGroup->spCellConfig,
AssertFatal(RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated, "Cellgroup->spCellConfig->spCellConfigDedicated is null for UE %d/%x\n",UE_id,uci_234->rnti); "Cellgroup->spCellConfig is null for UE %04x\n", uci_234->rnti);
if ( RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->csi_MeasConfig==NULL) return; AssertFatal(UE->CellGroup->spCellConfig->spCellConfigDedicated,
"Cellgroup->spCellConfig->spCellConfigDedicated is null for UE %04x\n", uci_234->rnti);
if ( UE->CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig==NULL)
return;
NR_CSI_MeasConfig_t *csi_MeasConfig = RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup; NR_CSI_MeasConfig_t *csi_MeasConfig = UE->CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup;
NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
// tpc (power control) // tpc (power control)
// TODO PUCCH2 SNR computation is not correct -> ignore the following // TODO PUCCH2 SNR computation is not correct -> ignore the following
@@ -1535,20 +1523,20 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
// iterate over received harq bits // iterate over received harq bits
for (int harq_bit = 0; harq_bit < uci_234->harq.harq_bit_len; harq_bit++) { for (int harq_bit = 0; harq_bit < uci_234->harq.harq_bit_len; harq_bit++) {
const int acknack = ((uci_234->harq.harq_payload[harq_bit >> 3]) >> harq_bit) & 0x01; const int acknack = ((uci_234->harq.harq_payload[harq_bit >> 3]) >> harq_bit) & 0x01;
NR_UE_harq_t *harq = find_harq(mod_id, frame, slot, UE_id); NR_UE_harq_t *harq = find_harq(frame, slot, UE, RC.nrmac[mod_id]->harq_round_max);
if (!harq) if (!harq)
break; break;
DevAssert(harq->is_waiting); DevAssert(harq->is_waiting);
const int8_t pid = sched_ctrl->feedback_dl_harq.head; const int8_t pid = sched_ctrl->feedback_dl_harq.head;
remove_front_nr_list(&sched_ctrl->feedback_dl_harq); remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
handle_dl_harq(mod_id, UE_id, pid, uci_234->harq.harq_crc != 1 && acknack); handle_dl_harq(UE, pid, uci_234->harq.harq_crc != 1 && acknack, RC.nrmac[mod_id]->harq_round_max);
} }
} }
if ((uci_234->pduBitmap >> 2) & 0x01) { if ((uci_234->pduBitmap >> 2) & 0x01) {
//API to parse the csi report and store it into sched_ctrl //API to parse the csi report and store it into sched_ctrl
extract_pucch_csi_report(csi_MeasConfig, uci_234, frame, slot, UE_id, mod_id); extract_pucch_csi_report(csi_MeasConfig, uci_234, frame, slot, UE, RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon);
//TCI handling function //TCI handling function
tci_handling(mod_id, UE_id,frame, slot); tci_handling(UE,frame, slot);
} }
if ((uci_234->pduBitmap >> 3) & 0x01) { if ((uci_234->pduBitmap >> 3) & 0x01) {
//@TODO:Handle CSI Report 2 //@TODO:Handle CSI Report 2
@@ -1616,12 +1604,11 @@ bool test_acknack_vrb_occupation(NR_UE_sched_ctrl_t *sched_ctrl,
// if the function returns -1 it was not possible to schedule acknack // if the function returns -1 it was not possible to schedule acknack
// when current pucch is ready to be scheduled nr_fill_nfapi_pucch is called // when current pucch is ready to be scheduled nr_fill_nfapi_pucch is called
int nr_acknack_scheduling(int mod_id, int nr_acknack_scheduling(int mod_id,
int UE_id, NR_UE_info_t * UE,
frame_t frame, frame_t frame,
sub_frame_t slot, sub_frame_t slot,
int r_pucch, int r_pucch,
int is_common) { int is_common) {
const int CC_id = 0; const int CC_id = 0;
const int minfbtime = RC.nrmac[mod_id]->minRXTXTIMEpdsch; const int minfbtime = RC.nrmac[mod_id]->minRXTXTIMEpdsch;
const NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels[CC_id].ServingCellConfigCommon; const NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels[CC_id].ServingCellConfigCommon;
@@ -1639,8 +1626,8 @@ int nr_acknack_scheduling(int mod_id,
* * SR uses format 0 and is allocated in the first UL (mixed) slot (and not * * SR uses format 0 and is allocated in the first UL (mixed) slot (and not
* later) * later)
* * each UE has dedicated PUCCH Format 0 resources, and we use index 0! */ * * each UE has dedicated PUCCH Format 0 resources, and we use index 0! */
NR_UE_sched_ctrl_t *sched_ctrl = &RC.nrmac[mod_id]->UE_info.UE_sched_ctrl[UE_id]; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_CellGroupConfig_t *cg = RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]; NR_CellGroupConfig_t *cg = UE->CellGroup;
NR_PUCCH_Config_t *pucch_Config = NULL; NR_PUCCH_Config_t *pucch_Config = NULL;
if (sched_ctrl->active_ubwp) { if (sched_ctrl->active_ubwp) {
@@ -1675,11 +1662,13 @@ int nr_acknack_scheduling(int mod_id,
const int f = pucch->frame; const int f = pucch->frame;
const int s = pucch->ul_slot; const int s = pucch->ul_slot;
LOG_D(NR_MAC, "In %s: %4d.%2d DAI = 2 pucch currently in %4d.%2d, advancing by 1 slot\n", __FUNCTION__, frame, slot, f, s); LOG_D(NR_MAC, "In %s: %4d.%2d DAI = 2 pucch currently in %4d.%2d, advancing by 1 slot\n", __FUNCTION__, frame, slot, f, s);
if (!(csi_pucch
&& csi_pucch->csi_bits > 0 if (!(csi_pucch
&& csi_pucch->frame == f && csi_pucch->csi_bits > 0
&& csi_pucch->ul_slot == s)) && csi_pucch->frame == f
nr_fill_nfapi_pucch(mod_id, frame, slot, pucch, UE_id); && csi_pucch->ul_slot == s))
nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, pucch, UE);
memset(pucch, 0, sizeof(*pucch)); memset(pucch, 0, sizeof(*pucch));
pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f; pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
if(((s + 1)%nr_slots_period) == 0) if(((s + 1)%nr_slots_period) == 0)
@@ -1696,7 +1685,8 @@ int nr_acknack_scheduling(int mod_id,
&& csi_pucch->ul_slot == pucch->ul_slot && csi_pucch->ul_slot == pucch->ul_slot
&& !csi_pucch->simultaneous_harqcsi) { && !csi_pucch->simultaneous_harqcsi) {
LOG_D(NR_MAC,"Cannot multiplex csi_pucch for %d.%d\n",csi_pucch->frame,csi_pucch->ul_slot); LOG_D(NR_MAC,"Cannot multiplex csi_pucch for %d.%d\n",csi_pucch->frame,csi_pucch->ul_slot);
nr_fill_nfapi_pucch(mod_id, frame, slot, csi_pucch, UE_id); nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, csi_pucch, UE);
memset(csi_pucch, 0, sizeof(*csi_pucch)); memset(csi_pucch, 0, sizeof(*csi_pucch));
pucch->frame = pucch->ul_slot == n_slots_frame - 1 ? (pucch->frame + 1) % 1024 : pucch->frame; pucch->frame = pucch->ul_slot == n_slots_frame - 1 ? (pucch->frame + 1) % 1024 : pucch->frame;
if(((pucch->ul_slot + 1)%nr_slots_period) == 0) if(((pucch->ul_slot + 1)%nr_slots_period) == 0)
@@ -1723,7 +1713,7 @@ int nr_acknack_scheduling(int mod_id,
const int bwp_id = sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0; const int bwp_id = sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0;
int max_fb_time = 0; int max_fb_time = 0;
get_pdsch_to_harq_feedback(mod_id, UE_id, bwp_id, ss_type, &max_fb_time, pdsch_to_harq_feedback); get_pdsch_to_harq_feedback(UE, bwp_id, ss_type, &max_fb_time, pdsch_to_harq_feedback);
LOG_D(NR_MAC, "In %s: 1b. DL %4d.%2d, UL_ACK %4d.%2d, DAI_C %d\n", __FUNCTION__, frame,slot,pucch->frame,pucch->ul_slot,pucch->dai_c); LOG_D(NR_MAC, "In %s: 1b. DL %4d.%2d, UL_ACK %4d.%2d, DAI_C %d\n", __FUNCTION__, frame,slot,pucch->frame,pucch->ul_slot,pucch->dai_c);
/* there is a HARQ. Check whether we can use it for this ACKNACK */ /* there is a HARQ. Check whether we can use it for this ACKNACK */
@@ -1750,14 +1740,14 @@ int nr_acknack_scheduling(int mod_id,
csi_pucch->csi_bits > 0 && csi_pucch->csi_bits > 0 &&
csi_pucch->frame == f && csi_pucch->frame == f &&
csi_pucch->ul_slot == s)) csi_pucch->ul_slot == s))
nr_fill_nfapi_pucch(mod_id, frame, slot, pucch, UE_id); nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, pucch, UE);
memset(pucch, 0, sizeof(*pucch)); memset(pucch, 0, sizeof(*pucch));
pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f; pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
if(((s + 1)%nr_slots_period) == 0) if(((s + 1)%nr_slots_period) == 0)
pucch->ul_slot = (s + 1 + first_ul_slot_period) % n_slots_frame; pucch->ul_slot = (s + 1 + first_ul_slot_period) % n_slots_frame;
else else
pucch->ul_slot = (s + 1) % n_slots_frame; pucch->ul_slot = (s + 1) % n_slots_frame;
return nr_acknack_scheduling(mod_id, UE_id, frame, slot, r_pucch,is_common); return nr_acknack_scheduling(mod_id, UE, frame, slot, r_pucch,is_common);
} }
pucch->timing_indicator = i; pucch->timing_indicator = i;
@@ -1783,10 +1773,11 @@ int nr_acknack_scheduling(int mod_id,
((pucch->frame*n_slots_frame + pucch->ul_slot) < ((pucch->frame*n_slots_frame + pucch->ul_slot) <
(frame*n_slots_frame + slot))) { (frame*n_slots_frame + slot))) {
AssertFatal(pucch->sr_flag + pucch->dai_c == 0, AssertFatal(pucch->sr_flag + pucch->dai_c == 0,
"expected no SR/AckNack for UE %d in %4d.%2d, but has %d/%d for %4d.%2d\n", "expected no SR/AckNack for UE %04x in %4d.%2d, but has %d/%d for %4d.%2d\n",
UE_id, frame, slot, pucch->sr_flag, pucch->dai_c, pucch->frame, pucch->ul_slot); UE->rnti, frame, slot, pucch->sr_flag, pucch->dai_c, pucch->frame, pucch->ul_slot);
const int s = next_ul_slot; const int s = next_ul_slot;
pucch->frame = s < n_slots_frame ? frame : (frame + 1) % 1024; pucch->frame = s < n_slots_frame ? frame : (frame + 1) % 1024;
pucch->ul_slot = s % n_slots_frame; pucch->ul_slot = s % n_slots_frame;
} }
@@ -1834,11 +1825,11 @@ int nr_acknack_scheduling(int mod_id,
} }
if (ind_found==-1) { if (ind_found==-1) {
LOG_D(NR_MAC, LOG_D(NR_MAC,
"%4d.%2d could not find pdsch_to_harq_feedback for UE %d: earliest " "%4d.%2d could not find pdsch_to_harq_feedback for UE %04x: earliest "
"ack slot %d\n", "ack slot %d\n",
frame, frame,
slot, slot,
UE_id, UE->rnti,
pucch->ul_slot); pucch->ul_slot);
return -1; return -1;
} }
@@ -1852,8 +1843,9 @@ int nr_acknack_scheduling(int mod_id,
// FIXME currently we support at most 11 bits in pucch2 so skip also in that case // FIXME currently we support at most 11 bits in pucch2 so skip also in that case
if(!csi_pucch->simultaneous_harqcsi if(!csi_pucch->simultaneous_harqcsi
|| ((csi_pucch->csi_bits + csi_pucch->dai_c) >= 11)) { || ((csi_pucch->csi_bits + csi_pucch->dai_c) >= 11)) {
LOG_D(NR_MAC,"Cannot multiplex csi_pucch %d +csi_pucch->dai_c %d for %d.%d\n",csi_pucch->csi_bits,csi_pucch->dai_c,csi_pucch->frame,csi_pucch->ul_slot); LOG_D(NR_MAC,"Cannot multiplex csi_pucch %d +csi_pucch->dai_c %d for %d.%d\n",csi_pucch->csi_bits,csi_pucch->dai_c,csi_pucch->frame,csi_pucch->ul_slot);
nr_fill_nfapi_pucch(mod_id, frame, slot, csi_pucch, UE_id); nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, csi_pucch, UE);
memset(csi_pucch, 0, sizeof(*csi_pucch)); memset(csi_pucch, 0, sizeof(*csi_pucch));
/* advance the UL slot information in PUCCH by one so we won't schedule in /* advance the UL slot information in PUCCH by one so we won't schedule in
* the same slot again */ * the same slot again */
@@ -1865,7 +1857,7 @@ int nr_acknack_scheduling(int mod_id,
pucch->ul_slot = (s + 1 + first_ul_slot_period) % n_slots_frame; pucch->ul_slot = (s + 1 + first_ul_slot_period) % n_slots_frame;
else else
pucch->ul_slot = (s + 1) % n_slots_frame; pucch->ul_slot = (s + 1) % n_slots_frame;
return nr_acknack_scheduling(mod_id, UE_id, frame, slot, r_pucch,is_common); return nr_acknack_scheduling(mod_id, UE, frame, slot, r_pucch,is_common);
} }
// multiplexing harq and csi in a pucch // multiplexing harq and csi in a pucch
else { else {
@@ -1902,29 +1894,26 @@ int nr_acknack_scheduling(int mod_id,
} }
void nr_sr_reporting(int Mod_idP, frame_t SFN, sub_frame_t slot) void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot)
{ {
gNB_MAC_INST *nrmac = RC.nrmac[Mod_idP];
if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slot / 64], slot)) if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slot / 64], slot))
return; return;
NR_ServingCellConfigCommon_t *scc = nrmac->common_channels->ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = nrmac->common_channels->ServingCellConfigCommon;
const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
NR_UE_info_t *UE_info = &nrmac->UE_info; UE_iterator(nrmac->UE_info.list, UE) {
NR_list_t *UE_list = &UE_info->list; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
if (sched_ctrl->ul_failure==1) continue; if (sched_ctrl->ul_failure==1) continue;
NR_PUCCH_Config_t *pucch_Config = NULL; NR_PUCCH_Config_t *pucch_Config = NULL;
if (sched_ctrl->active_ubwp) { if (sched_ctrl->active_ubwp) {
pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup; pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup;
} else if (RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id] && } else if (UE->CellGroup &&
RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig && UE->CellGroup->spCellConfig &&
RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated && UE->CellGroup->spCellConfig->spCellConfigDedicated &&
RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig && UE->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig &&
RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP && UE->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP &&
RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) { UE->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) {
pucch_Config = RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup; pucch_Config = UE->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup;
} }
else continue; else continue;
@@ -1971,7 +1960,7 @@ void nr_sr_reporting(int Mod_idP, frame_t SFN, sub_frame_t slot)
continue; continue;
nfapi_nr_pucch_pdu_t *pdu = &ul_tti_req->pdus_list[i].pucch_pdu; nfapi_nr_pucch_pdu_t *pdu = &ul_tti_req->pdus_list[i].pucch_pdu;
/* check that it is our PUCCH F0. Assuming there can be only one */ /* check that it is our PUCCH F0. Assuming there can be only one */
if (pdu->rnti == UE_info->rnti[UE_id] if (pdu->rnti == UE->rnti
&& pdu->format_type == 0 // does not use NR_PUCCH_Resource__format_PR_format0 && pdu->format_type == 0 // does not use NR_PUCCH_Resource__format_PR_format0
&& pdu->initial_cyclic_shift == pucch_res->format.choice.format0->initialCyclicShift && pdu->initial_cyclic_shift == pucch_res->format.choice.format0->initialCyclicShift
&& pdu->nr_of_symbols == pucch_res->format.choice.format0->nrofSymbols && pdu->nr_of_symbols == pucch_res->format.choice.format0->nrofSymbols
@@ -1981,7 +1970,7 @@ void nr_sr_reporting(int Mod_idP, frame_t SFN, sub_frame_t slot)
nfapi_allocated = true; nfapi_allocated = true;
break; break;
} }
else if (pdu->rnti == UE_info->rnti[UE_id] else if (pdu->rnti == UE->rnti
&& pdu->format_type == 2 // does not use NR_PUCCH_Resource__format_PR_format0 && pdu->format_type == 2 // does not use NR_PUCCH_Resource__format_PR_format0
&& pdu->nr_of_symbols == pucch_res->format.choice.format2->nrofSymbols && pdu->nr_of_symbols == pucch_res->format.choice.format2->nrofSymbols
&& pdu->start_symbol_index == pucch_res->format.choice.format2->startingSymbolIndex) { && pdu->start_symbol_index == pucch_res->format.choice.format2->startingSymbolIndex) {
@@ -1991,7 +1980,7 @@ void nr_sr_reporting(int Mod_idP, frame_t SFN, sub_frame_t slot)
break; break;
} }
else if (pdu->rnti == UE_info->rnti[UE_id] else if (pdu->rnti == UE->rnti
&& pdu->format_type == 1 // does not use NR_PUCCH_Resource__format_PR_format0 && pdu->format_type == 1 // does not use NR_PUCCH_Resource__format_PR_format0
&& pdu->nr_of_symbols == pucch_res->format.choice.format1->nrofSymbols && pdu->nr_of_symbols == pucch_res->format.choice.format1->nrofSymbols
&& pdu->start_symbol_index == pucch_res->format.choice.format1->startingSymbolIndex) { && pdu->start_symbol_index == pucch_res->format.choice.format1->startingSymbolIndex) {
@@ -2001,7 +1990,7 @@ void nr_sr_reporting(int Mod_idP, frame_t SFN, sub_frame_t slot)
break; break;
} }
else if (pdu->rnti == UE_info->rnti[UE_id] else if (pdu->rnti == UE->rnti
&& pdu->format_type == 3 // does not use NR_PUCCH_Resource__format_PR_format0 && pdu->format_type == 3 // does not use NR_PUCCH_Resource__format_PR_format0
&& pdu->nr_of_symbols == pucch_res->format.choice.format3->nrofSymbols && pdu->nr_of_symbols == pucch_res->format.choice.format3->nrofSymbols
&& pdu->start_symbol_index == pucch_res->format.choice.format3->startingSymbolIndex) { && pdu->start_symbol_index == pucch_res->format.choice.format3->startingSymbolIndex) {
@@ -2011,7 +2000,7 @@ void nr_sr_reporting(int Mod_idP, frame_t SFN, sub_frame_t slot)
break; break;
} }
else if (pdu->rnti == UE_info->rnti[UE_id] else if (pdu->rnti == UE->rnti
&& pdu->format_type == 4 // does not use NR_PUCCH_Resource__format_PR_format0 && pdu->format_type == 4 // does not use NR_PUCCH_Resource__format_PR_format0
&& pdu->nr_of_symbols == pucch_res->format.choice.format4->nrofSymbols && pdu->nr_of_symbols == pucch_res->format.choice.format4->nrofSymbols
&& pdu->start_symbol_index == pucch_res->format.choice.format4->startingSymbolIndex) { && pdu->start_symbol_index == pucch_res->format.choice.format4->startingSymbolIndex) {
@@ -2043,7 +2032,7 @@ void nr_sr_reporting(int Mod_idP, frame_t SFN, sub_frame_t slot)
.resource_indicator = found, .resource_indicator = found,
.r_pucch = -1 .r_pucch = -1
}; };
nr_fill_nfapi_pucch(Mod_idP, SFN, slot, &sched_sr, UE_id); nr_fill_nfapi_pucch(nrmac, SFN, slot, &sched_sr, UE);
} }
} }
} }
+215 -223
View File
@@ -84,8 +84,8 @@ const int get_ul_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon
// F: length of L is 0:8 or 1:16 bits wide // F: length of L is 0:8 or 1:16 bits wide
// R: Reserved bit, set to zero. // R: Reserved bit, set to zero.
int nr_process_mac_pdu(module_id_t module_idP, int nr_process_mac_pdu( instance_t module_idP,
int UE_id, NR_UE_info_t* UE,
uint8_t CC_id, uint8_t CC_id,
frame_t frameP, frame_t frameP,
sub_frame_t slot, sub_frame_t slot,
@@ -96,11 +96,10 @@ int nr_process_mac_pdu(module_id_t module_idP,
uint8_t done = 0; uint8_t done = 0;
NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
if ( pduP[0] != UL_SCH_LCID_PADDING ) if ( pduP[0] != UL_SCH_LCID_PADDING )
trace_NRpdu(DIRECTION_UPLINK, pduP, pdu_len, UE_id, WS_C_RNTI, UE_info->rnti[UE_id], frameP, 0, 0, 0); trace_NRpdu(DIRECTION_UPLINK, pduP, pdu_len, WS_C_RNTI, UE->rnti, frameP, 0, 0, 0);
#ifdef ENABLE_MAC_PAYLOAD_DEBUG #ifdef ENABLE_MAC_PAYLOAD_DEBUG
LOG_I(NR_MAC, "In %s: dumping MAC PDU in %d.%d:\n", __func__, frameP, slot); LOG_I(NR_MAC, "In %s: dumping MAC PDU in %d.%d:\n", __func__, frameP, slot);
@@ -197,7 +196,7 @@ int nr_process_mac_pdu(module_id_t module_idP,
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i]; NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i];
if (ra->state >= WAIT_Msg3 && ra->rnti == UE_info->rnti[UE_id]) { if (ra->state >= WAIT_Msg3 && ra->rnti == UE->rnti) {
ra->crnti = ((pduP[1]&0xFF)<<8)|(pduP[2]&0xFF); ra->crnti = ((pduP[1]&0xFF)<<8)|(pduP[2]&0xFF);
ra->msg3_dcch_dtch = true; ra->msg3_dcch_dtch = true;
LOG_I(NR_MAC, "Received UL_SCH_LCID_C_RNTI with C-RNTI 0x%04x\n", ra->crnti); LOG_I(NR_MAC, "Received UL_SCH_LCID_C_RNTI with C-RNTI 0x%04x\n", ra->crnti);
@@ -258,22 +257,23 @@ int nr_process_mac_pdu(module_id_t module_idP,
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len)) if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
return 0; return 0;
rnti_t crnti = UE_info->rnti[UE_id]; rnti_t crnti = UE->rnti;
int UE_idx = UE_id; NR_UE_info_t* UE_idx = UE;
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i]; NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i];
if (ra->state >= WAIT_Msg3 && ra->rnti == UE_info->rnti[UE_id]) { if (ra->state >= WAIT_Msg3 && ra->rnti == UE->rnti) {
uint8_t *next_subpduP = pduP + mac_subheader_len + mac_len; uint8_t *next_subpduP = pduP + mac_subheader_len + mac_len;
if ((pduP[mac_subheader_len+mac_len] & 0x3F) == UL_SCH_LCID_C_RNTI) { if ((pduP[mac_subheader_len+mac_len] & 0x3F) == UL_SCH_LCID_C_RNTI) {
crnti = ((next_subpduP[1]&0xFF)<<8)|(next_subpduP[2]&0xFF); crnti = ((next_subpduP[1]&0xFF)<<8)|(next_subpduP[2]&0xFF);
UE_idx = find_nr_UE_id(module_idP, crnti); LOG_W(NR_MAC, " UL_SCH_LCID_SRB for rnti %04x\n", crnti);
UE_idx = find_nr_UE(&RC.nrmac[module_idP]->UE_info, crnti);
break; break;
} }
} }
} }
if (UE_info->CellGroup[UE_idx]) { if (UE_idx->CellGroup) {
LOG_D(NR_MAC, "[UE %d] Frame %d : ULSCH -> UL-DCCH %d (gNB %d, %d bytes), rnti: 0x%04x \n", module_idP, frameP, rx_lcid, module_idP, mac_len, crnti); LOG_D(NR_MAC, "Frame %d : ULSCH -> UL-DCCH %d (gNB %ld, %d bytes), rnti: 0x%04x \n", frameP, rx_lcid, module_idP, mac_len, crnti);
mac_rlc_data_ind(module_idP, mac_rlc_data_ind(module_idP,
crnti, crnti,
module_idP, module_idP,
@@ -286,7 +286,7 @@ int nr_process_mac_pdu(module_id_t module_idP,
1, 1,
NULL); NULL);
} else { } else {
AssertFatal(1==0,"[UE %d] Frame/Slot %d.%d : Received LCID %d which is not configured, dropping packet\n",UE_id,frameP,slot,rx_lcid); AssertFatal(1==0,"[UE %04x] Frame/Slot %d.%d : Received LCID %d which is not configured, dropping packet\n",UE->rnti,frameP,slot,rx_lcid);
} }
break; break;
case UL_SCH_LCID_SRB3: case UL_SCH_LCID_SRB3:
@@ -324,7 +324,7 @@ int nr_process_mac_pdu(module_id_t module_idP,
frameP, frameP,
0, 0,
0, 0,
UE_info->rnti[UE_id], UE->rnti,
CCCH, CCCH,
pduP + mac_subheader_len, pduP + mac_subheader_len,
mac_len, mac_len,
@@ -336,18 +336,19 @@ int nr_process_mac_pdu(module_id_t module_idP,
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len)) if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
return 0; return 0;
LOG_D(NR_MAC, "[UE %x] %d.%d: ULSCH -> UL-%s %d (gNB %d, %d bytes)\n",
UE_info->rnti[UE_id], LOG_D(NR_MAC, "[UE %04x] %d.%d : ULSCH -> UL-%s %d (gNB %ld, %d bytes)\n",
UE->rnti,
frameP, frameP,
slot, slot,
rx_lcid<4?"DCCH":"DTCH", rx_lcid<4?"DCCH":"DTCH",
rx_lcid, rx_lcid,
module_idP, module_idP,
mac_len); mac_len);
UE_info->mac_stats[UE_id].ul.lc_bytes[rx_lcid] += mac_len; UE->mac_stats.ul.lc_bytes[rx_lcid] += mac_len;
mac_rlc_data_ind(module_idP, mac_rlc_data_ind(module_idP,
UE_info->rnti[UE_id], UE->rnti,
module_idP, module_idP,
frameP, frameP,
ENB_FLAG_YES, ENB_FLAG_YES,
@@ -398,15 +399,14 @@ int nr_process_mac_pdu(module_id_t module_idP,
return 0; return 0;
} }
void abort_nr_ul_harq(module_id_t mod_id, int UE_id, int8_t harq_pid) void abort_nr_ul_harq( NR_UE_info_t* UE, int8_t harq_pid)
{ {
NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
NR_UE_ul_harq_t *harq = &sched_ctrl->ul_harq_processes[harq_pid]; NR_UE_ul_harq_t *harq = &sched_ctrl->ul_harq_processes[harq_pid];
harq->ndi ^= 1; harq->ndi ^= 1;
harq->round = 0; harq->round = 0;
UE_info->mac_stats[UE_id].ul.errors++; UE->mac_stats.ul.errors++;
add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid); add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid);
/* the transmission failed: the UE won't send the data we expected initially, /* the transmission failed: the UE won't send the data we expected initially,
@@ -422,11 +422,11 @@ void handle_nr_ul_harq(const int CC_idP,
sub_frame_t slot, sub_frame_t slot,
const nfapi_nr_crc_t *crc_pdu) const nfapi_nr_crc_t *crc_pdu)
{ {
gNB_MAC_INST *gNB_mac = RC.nrmac[mod_id]; NR_UE_info_t* UE = find_nr_UE(&RC.nrmac[mod_id]->UE_info, crc_pdu->rnti);
int UE_id = find_nr_UE_id(mod_id, crc_pdu->rnti); if (!UE) {
if (UE_id < 0) { LOG_W(NR_MAC, "handle harq for rnti %04x, in RA process\n", crc_pdu->rnti);
for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) { for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) {
NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[i]; NR_RA_t *ra = &RC.nrmac[mod_id]->common_channels[CC_idP].ra[i];
if (ra->state >= WAIT_Msg3 && if (ra->state >= WAIT_Msg3 &&
ra->rnti == crc_pdu->rnti) ra->rnti == crc_pdu->rnti)
return; return;
@@ -434,8 +434,7 @@ void handle_nr_ul_harq(const int CC_idP,
LOG_E(NR_MAC, "%s(): unknown RNTI 0x%04x in PUSCH\n", __func__, crc_pdu->rnti); LOG_E(NR_MAC, "%s(): unknown RNTI 0x%04x in PUSCH\n", __func__, crc_pdu->rnti);
return; return;
} }
NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
int8_t harq_pid = sched_ctrl->feedback_ul_harq.head; int8_t harq_pid = sched_ctrl->feedback_ul_harq.head;
LOG_D(NR_MAC, "Comparing crc_pdu->harq_id vs feedback harq_pid = %d %d\n",crc_pdu->harq_id, harq_pid); LOG_D(NR_MAC, "Comparing crc_pdu->harq_id vs feedback harq_pid = %d %d\n",crc_pdu->harq_id, harq_pid);
while (crc_pdu->harq_id != harq_pid || harq_pid < 0) { while (crc_pdu->harq_id != harq_pid || harq_pid < 0) {
@@ -449,8 +448,9 @@ void handle_nr_ul_harq(const int CC_idP,
remove_front_nr_list(&sched_ctrl->feedback_ul_harq); remove_front_nr_list(&sched_ctrl->feedback_ul_harq);
sched_ctrl->ul_harq_processes[harq_pid].is_waiting = false; sched_ctrl->ul_harq_processes[harq_pid].is_waiting = false;
if(sched_ctrl->ul_harq_processes[harq_pid].round >= gNB_mac->harq_round_max - 1) {
abort_nr_ul_harq(mod_id, UE_id, harq_pid); if(sched_ctrl->ul_harq_processes[harq_pid].round >= RC.nrmac[mod_id]->harq_round_max - 1) {
abort_nr_ul_harq(UE, harq_pid);
} else { } else {
sched_ctrl->ul_harq_processes[harq_pid].round++; sched_ctrl->ul_harq_processes[harq_pid].round++;
add_tail_nr_list(&sched_ctrl->retrans_ul_harq, harq_pid); add_tail_nr_list(&sched_ctrl->retrans_ul_harq, harq_pid);
@@ -470,8 +470,8 @@ void handle_nr_ul_harq(const int CC_idP,
harq_pid, harq_pid,
crc_pdu->rnti); crc_pdu->rnti);
add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid); add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid);
} else if (harq->round >= gNB_mac->harq_round_max - 1) { } else if (harq->round >= RC.nrmac[mod_id]->harq_round_max - 1) {
abort_nr_ul_harq(mod_id, UE_id, harq_pid); abort_nr_ul_harq(UE, harq_pid);
LOG_D(NR_MAC, LOG_D(NR_MAC,
"RNTI %04x: Ulharq id %d crc failed in all rounds\n", "RNTI %04x: Ulharq id %d crc failed in all rounds\n",
crc_pdu->rnti, crc_pdu->rnti,
@@ -501,15 +501,15 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
const uint16_t rssi){ const uint16_t rssi){
gNB_MAC_INST *gNB_mac = RC.nrmac[gnb_mod_idP]; gNB_MAC_INST *gNB_mac = RC.nrmac[gnb_mod_idP];
NR_UE_info_t *UE_info = &gNB_mac->UE_info;
const int current_rnti = rntiP; const int current_rnti = rntiP;
const int UE_id = find_nr_UE_id(gnb_mod_idP, current_rnti); LOG_D(NR_MAC, "rx_sdu for rnti %04x\n", current_rnti);
const int target_snrx10 = gNB_mac->pusch_target_snrx10; const int target_snrx10 = gNB_mac->pusch_target_snrx10;
const int pusch_failure_thres = gNB_mac->pusch_failure_thres; const int pusch_failure_thres = gNB_mac->pusch_failure_thres;
if (UE_id != -1) { NR_UE_info_t* UE = find_nr_UE(&gNB_mac->UE_info, current_rnti);
NR_UE_sched_ctrl_t *UE_scheduling_control = &UE_info->UE_sched_ctrl[UE_id]; if (UE) {
NR_UE_sched_ctrl_t *UE_scheduling_control = &UE->UE_sched_ctrl;
const int8_t harq_pid = UE_scheduling_control->feedback_ul_harq.head; const int8_t harq_pid = UE_scheduling_control->feedback_ul_harq.head;
if (sduP) if (sduP)
@@ -517,15 +517,14 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
T_INT(rntiP), T_INT(frameP), T_INT(slotP), T_INT(harq_pid), T_INT(rntiP), T_INT(frameP), T_INT(slotP), T_INT(harq_pid),
T_BUFFER(sduP, sdu_lenP)); T_BUFFER(sduP, sdu_lenP));
UE_info->mac_stats[UE_id].ul.total_bytes += sdu_lenP; UE->mac_stats.ul.total_bytes += sdu_lenP;
LOG_D(NR_MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d TA %d sduP %p, rssi %d\n", LOG_D(NR_MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %04x) ul_cqi %d TA %d sduP %p, rssi %d\n",
gnb_mod_idP, gnb_mod_idP,
harq_pid, harq_pid,
CC_idP, CC_idP,
frameP, frameP,
slotP, slotP,
current_rnti, current_rnti,
UE_id,
ul_cqi, ul_cqi,
timing_advance, timing_advance,
sduP, sduP,
@@ -538,11 +537,13 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
UE_scheduling_control->ta_update = timing_advance; UE_scheduling_control->ta_update = timing_advance;
UE_scheduling_control->raw_rssi = rssi; UE_scheduling_control->raw_rssi = rssi;
UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640; UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640;
LOG_D(NR_MAC, "[UE %d] PUSCH TPC %d(SNRx10 %d) and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->pusch_snrx10,UE_scheduling_control->ta_update);
LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n",UE->rnti,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update);
} }
else{ else{
LOG_D(NR_MAC,"[UE %d] Detected DTX : increasing UE TX power\n",UE_id); LOG_D(NR_MAC,"[UE %04x] Detected DTX : increasing UE TX power\n",UE->rnti);
UE_scheduling_control->tpc0 = 1; UE_scheduling_control->tpc0 = 1;
} }
#if defined(ENABLE_MAC_PAYLOAD_DEBUG) #if defined(ENABLE_MAC_PAYLOAD_DEBUG)
@@ -560,13 +561,13 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
if (sduP != NULL){ if (sduP != NULL){
LOG_D(NR_MAC, "Received PDU at MAC gNB \n"); LOG_D(NR_MAC, "Received PDU at MAC gNB \n");
UE_info->UE_sched_ctrl[UE_id].pusch_consecutive_dtx_cnt = 0; UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt = 0;
const uint32_t tb_size = UE_scheduling_control->ul_harq_processes[harq_pid].sched_pusch.tb_size; const uint32_t tb_size = UE_scheduling_control->ul_harq_processes[harq_pid].sched_pusch.tb_size;
UE_scheduling_control->sched_ul_bytes -= tb_size; UE_scheduling_control->sched_ul_bytes -= tb_size;
if (UE_scheduling_control->sched_ul_bytes < 0) if (UE_scheduling_control->sched_ul_bytes < 0)
UE_scheduling_control->sched_ul_bytes = 0; UE_scheduling_control->sched_ul_bytes = 0;
nr_process_mac_pdu(gnb_mod_idP, UE_id, CC_idP, frameP, slotP, sduP, sdu_lenP); nr_process_mac_pdu(gnb_mod_idP, UE, CC_idP, frameP, slotP, sduP, sdu_lenP);
} }
else { else {
NR_UE_ul_harq_t *cur_harq = &UE_scheduling_control->ul_harq_processes[harq_pid]; NR_UE_ul_harq_t *cur_harq = &UE_scheduling_control->ul_harq_processes[harq_pid];
@@ -578,13 +579,15 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
UE_scheduling_control->sched_ul_bytes = 0; UE_scheduling_control->sched_ul_bytes = 0;
} }
if (ul_cqi <= 128) { if (ul_cqi <= 128) {
UE_info->UE_sched_ctrl[UE_id].pusch_consecutive_dtx_cnt++; UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt++;
UE_info->mac_stats[UE_id].ulsch_DTX++; UE->mac_stats.ulsch_DTX++;
} }
if (!get_softmodem_params()->phy_test && UE_info->UE_sched_ctrl[UE_id].pusch_consecutive_dtx_cnt >= pusch_failure_thres) {
LOG_W(NR_MAC,"%d.%d Detected UL Failure on PUSCH after %d PUSCH DTX, stopping scheduling\n", if (!get_softmodem_params()->phy_test && UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt >= pusch_failure_thres) {
frameP,slotP,UE_info->UE_sched_ctrl[UE_id].pusch_consecutive_dtx_cnt); LOG_W(NR_MAC,"Detected UL Failure on PUSCH after %d PUSCH DTX, stopping scheduling\n",
UE_info->UE_sched_ctrl[UE_id].ul_failure = 1; UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt);
UE->UE_sched_ctrl.ul_failure = 1;
nr_mac_gNB_rrc_ul_failure(gnb_mod_idP,CC_idP,frameP,slotP,rntiP); nr_mac_gNB_rrc_ul_failure(gnb_mod_idP,CC_idP,frameP,slotP,rntiP);
} }
} }
@@ -605,7 +608,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
T(T_GNB_MAC_UL_PDU_WITH_DATA, T_INT(gnb_mod_idP), T_INT(CC_idP), T(T_GNB_MAC_UL_PDU_WITH_DATA, T_INT(gnb_mod_idP), T_INT(CC_idP),
T_INT(rntiP), T_INT(frameP), T_INT(slotP), T_INT(-1) /* harq_pid */, T_INT(rntiP), T_INT(frameP), T_INT(slotP), T_INT(-1) /* harq_pid */,
T_BUFFER(sduP, sdu_lenP)); T_BUFFER(sduP, sdu_lenP));
/* we don't know this UE (yet). Check whether there is a ongoing RA (Msg 3) /* we don't know this UE (yet). Check whether there is a ongoing RA (Msg 3)
* and check the corresponding UE's RNTI match, in which case we activate * and check the corresponding UE's RNTI match, in which case we activate
* it. */ * it. */
@@ -613,7 +616,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[i]; NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[i];
if (ra->state != WAIT_Msg3) if (ra->state != WAIT_Msg3)
continue; continue;
if(no_sig) { if(no_sig) {
LOG_D(NR_MAC, "Random Access %i failed at state %i (no signal)\n", i, ra->state); LOG_D(NR_MAC, "Random Access %i failed at state %i (no signal)\n", i, ra->state);
nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti); nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
@@ -636,20 +639,20 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
continue; continue;
} }
int UE_id=-1;
UE_id = add_new_nr_ue(gnb_mod_idP, ra->rnti, ra->CellGroup); NR_UE_info_t* UE = add_new_nr_ue(gNB_mac, ra->rnti, ra->CellGroup);
if (UE_id<0) { if (!UE) {
LOG_D(NR_MAC, "Random Access %i discarded at state %i (TC_RNTI %04x RNTI %04x): max number of users achieved!\n", i, ra->state,ra->rnti,current_rnti); LOG_W(NR_MAC, "Random Access %i discarded at state %i (TC_RNTI %04x RNTI %04x): max number of users achieved!\n", i, ra->state,ra->rnti,current_rnti);
nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti); nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
return; return;
} }
UE_info->UE_beam_index[UE_id] = ra->beam_id; UE->UE_beam_index = ra->beam_id;
// re-initialize ta update variables after RA procedure completion // re-initialize ta update variables after RA procedure completion
UE_info->UE_sched_ctrl[UE_id].ta_frame = frameP; UE->UE_sched_ctrl.ta_frame = frameP;
LOG_D(NR_MAC, LOG_D(NR_MAC,
"reset RA state information for RA-RNTI 0x%04x/index %d\n", "reset RA state information for RA-RNTI 0x%04x/index %d\n",
@@ -658,27 +661,24 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
LOG_I(NR_MAC, LOG_I(NR_MAC,
"[gNB %d][RAPROC] PUSCH with TC_RNTI 0x%04x received correctly, " "[gNB %d][RAPROC] PUSCH with TC_RNTI 0x%04x received correctly, "
"adding UE MAC Context UE_id %d/RNTI 0x%04x\n", "adding UE MAC Context RNTI 0x%04x\n",
gnb_mod_idP, gnb_mod_idP,
current_rnti, current_rnti,
UE_id,
ra->rnti); ra->rnti);
NR_UE_sched_ctrl_t *UE_scheduling_control = &UE_info->UE_sched_ctrl[UE_id]; NR_UE_sched_ctrl_t *UE_scheduling_control = &UE->UE_sched_ctrl;
UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10,ul_cqi,30); UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10,ul_cqi,30);
if (timing_advance != 0xffff) if (timing_advance != 0xffff)
UE_scheduling_control->ta_update = timing_advance; UE_scheduling_control->ta_update = timing_advance;
UE_scheduling_control->raw_rssi = rssi; UE_scheduling_control->raw_rssi = rssi;
UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640; UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640;
LOG_D(NR_MAC, "[UE %d] PUSCH TPC %d and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update); LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n",UE->rnti,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update);
if(ra->cfra) { if(ra->cfra) {
LOG_A(NR_MAC, "(ue %i, rnti 0x%04x) CFRA procedure succeeded!\n", UE_id, ra->rnti); LOG_A(NR_MAC, "(rnti 0x%04x) CFRA procedure succeeded!\n", ra->rnti);
nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti); nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
UE_info->active[UE_id] = true;
process_CellGroup(ra->CellGroup, UE_scheduling_control); process_CellGroup(ra->CellGroup, UE_scheduling_control);
} else { } else {
@@ -694,25 +694,25 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
// First byte corresponds to R/LCID MAC sub-header // First byte corresponds to R/LCID MAC sub-header
memcpy(ra->cont_res_id, &sduP[1], sizeof(uint8_t) * 6); memcpy(ra->cont_res_id, &sduP[1], sizeof(uint8_t) * 6);
if (nr_process_mac_pdu(gnb_mod_idP, UE_id, CC_idP, frameP, slotP, sduP, sdu_lenP) == 0) { if (nr_process_mac_pdu(gnb_mod_idP, UE, CC_idP, frameP, slotP, sduP, sdu_lenP) == 0) {
ra->state = Msg4; ra->state = Msg4;
ra->Msg4_frame = (frameP + 2) % 1024; ra->Msg4_frame = (frameP + 2) % 1024;
ra->Msg4_slot = 1; ra->Msg4_slot = 1;
if (ra->msg3_dcch_dtch) { if (ra->msg3_dcch_dtch) {
// Check if the UE identified by C-RNTI still exists at the gNB // Check if the UE identified by C-RNTI still exists at the gNB
int UE_id_C = find_nr_UE_id(gnb_mod_idP, ra->crnti); NR_UE_info_t * UE_C = find_nr_UE(&gNB_mac->UE_info, ra->crnti);
if (UE_id_C < 0) { if (!UE_C) {
// The UE identified by C-RNTI no longer exists at the gNB // The UE identified by C-RNTI no longer exists at the gNB
// Let's abort the current RA, so the UE will trigger a new RA later but using RRCSetupRequest instead. A better solution may be implemented // Let's abort the current RA, so the UE will trigger a new RA later but using RRCSetupRequest instead. A better solution may be implemented
mac_remove_nr_ue(gnb_mod_idP, ra->rnti); mac_remove_nr_ue(gNB_mac, ra->rnti);
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
return; return;
} else { } else {
// The UE identified by C-RNTI still exists at the gNB // The UE identified by C-RNTI still exists at the gNB
// Reset uplink failure flags/counters/timers at MAC and at RRC so gNB will resume again scheduling resources for this UE // Reset uplink failure flags/counters/timers at MAC and at RRC so gNB will resume again scheduling resources for this UE
UE_info->UE_sched_ctrl[UE_id_C].pusch_consecutive_dtx_cnt = 0; UE_C->UE_sched_ctrl.pusch_consecutive_dtx_cnt = 0;
UE_info->UE_sched_ctrl[UE_id_C].ul_failure = 0; UE_C->UE_sched_ctrl.ul_failure = 0;
nr_mac_gNB_rrc_ul_failure_reset(gnb_mod_idP, frameP, slotP, ra->crnti); nr_mac_gNB_rrc_ul_failure_reset(gnb_mod_idP, frameP, slotP, ra->crnti);
} }
} }
@@ -751,7 +751,9 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
return; return;
} }
LOG_D(NR_MAC, "Random Access %i Msg3 CRC did not pass)\n", i); LOG_D(NR_MAC, "Random Access %i Msg3 CRC did not pass)\n", i);
ra->msg3_round++; ra->msg3_round++;
ra->state = Msg3_retransmission; ra->state = Msg3_retransmission;
} }
@@ -783,19 +785,20 @@ long get_K2(NR_ServingCellConfigCommon_t *scc,
return 3; return 3;
} }
bool nr_UE_is_to_be_scheduled(module_id_t mod_id, int CC_id, int UE_id, frame_t frame, sub_frame_t slot) static bool nr_UE_is_to_be_scheduled(const NR_ServingCellConfigCommon_t *scc,
int CC_id, NR_UE_info_t* UE, frame_t frame, sub_frame_t slot, uint32_t ulsch_max_frame_inactivity)
{ {
const NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon;
const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
const int now = frame * n + slot; const int now = frame * n + slot;
const struct gNB_MAC_INST_s *nrmac = RC.nrmac[mod_id];
const NR_UE_sched_ctrl_t *sched_ctrl = &nrmac->UE_info.UE_sched_ctrl[UE_id]; const NR_UE_sched_ctrl_t *sched_ctrl =&UE->UE_sched_ctrl;
const NR_TDD_UL_DL_Pattern_t *tdd = const NR_TDD_UL_DL_Pattern_t *tdd =
scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
int num_slots_per_period; int num_slots_per_period;
int last_ul_slot,last_ul_sched; int last_ul_slot;
int tdd_period_len[8] = {500,625,1000,1250,2000,2500,5000,10000}; int tdd_period_len[8] = {500,625,1000,1250,2000,2500,5000,10000};
if (tdd) { // Force the default transmission in a full slot as early as possible in the UL portion of TDD period (last_ul_slot) if (tdd) { // Force the default transmission in a full slot as early as possible in the UL portion of TDD period (last_ul_slot)
num_slots_per_period = n*tdd_period_len[tdd->dl_UL_TransmissionPeriodicity]/10000; num_slots_per_period = n*tdd_period_len[tdd->dl_UL_TransmissionPeriodicity]/10000;
@@ -806,14 +809,14 @@ bool nr_UE_is_to_be_scheduled(module_id_t mod_id, int CC_id, int UE_id, frame_t
last_ul_slot = sched_ctrl->last_ul_slot; last_ul_slot = sched_ctrl->last_ul_slot;
} }
last_ul_sched = sched_ctrl->last_ul_frame * n + last_ul_slot; const int last_ul_sched = sched_ctrl->last_ul_frame * n + last_ul_slot;
const int diff = (now - last_ul_sched + 1024 * n) % (1024 * n); const int diff = (now - last_ul_sched + 1024 * n) % (1024 * n);
/* UE is to be scheduled if /* UE is to be scheduled if
* (1) we think the UE has more bytes awaiting than what we scheduled * (1) we think the UE has more bytes awaiting than what we scheduled
* (2) there is a scheduling request * (2) there is a scheduling request
* (3) or we did not schedule it in more than 10 frames */ * (3) or we did not schedule it in more than 10 frames */
const bool has_data = sched_ctrl->estimated_ul_buffer > sched_ctrl->sched_ul_bytes; const bool has_data = sched_ctrl->estimated_ul_buffer > sched_ctrl->sched_ul_bytes;
const bool high_inactivity = diff >= (nrmac->ulsch_max_frame_inactivity>0 ? (nrmac->ulsch_max_frame_inactivity * n) : num_slots_per_period); const bool high_inactivity = diff >= (ulsch_max_frame_inactivity > 0 ? ulsch_max_frame_inactivity * n : num_slots_per_period);
LOG_D(NR_MAC, LOG_D(NR_MAC,
"%4d.%2d UL inactivity %d slots has_data %d SR %d\n", "%4d.%2d UL inactivity %d slots has_data %d SR %d\n",
frame, frame,
@@ -824,34 +827,26 @@ bool nr_UE_is_to_be_scheduled(module_id_t mod_id, int CC_id, int UE_id, frame_t
return has_data || sched_ctrl->SR || high_inactivity; return has_data || sched_ctrl->SR || high_inactivity;
} }
int next_list_entry_looped(NR_list_t *list, int UE_id) static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
{ frame_t frame,
if (UE_id < 0) sub_frame_t slot,
return list->head; uint16_t *rballoc_mask,
return list->next[UE_id] < 0 ? list->head : list->next[UE_id]; int *n_rb_sched,
} NR_UE_info_t* UE,
int harq_pid,
bool allocate_ul_retransmission(module_id_t module_id, const NR_SIB1_t *sib1,
frame_t frame, const NR_ServingCellConfigCommon_t *scc,
sub_frame_t slot, const int tda)
uint16_t *rballoc_mask,
int *n_rb_sched,
int UE_id,
int harq_pid)
{ {
const int CC_id = 0; const int CC_id = 0;
gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
const NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels[CC_id].ServingCellConfigCommon;
NR_UE_info_t *UE_info = &nr_mac->UE_info;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
NR_sched_pusch_t *retInfo = &sched_ctrl->ul_harq_processes[harq_pid].sched_pusch; NR_sched_pusch_t *retInfo = &sched_ctrl->ul_harq_processes[harq_pid].sched_pusch;
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id]; NR_CellGroupConfig_t *cg = UE->CellGroup;
NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated && NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated &&
cg->spCellConfig->spCellConfigDedicated->uplinkConfig ? cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL; cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp, NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp,
(NR_ServingCellConfigCommon_t *)scc, (NR_ServingCellConfigCommon_t *)scc,
sib1); sib1);
@@ -860,7 +855,6 @@ bool allocate_ul_retransmission(module_id_t module_id,
const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
const uint8_t nrOfLayers = 1; const uint8_t nrOfLayers = 1;
const uint8_t num_dmrs_cdm_grps_no_data = (sched_ctrl->active_bwp || ubwpd) ? 1 : 2; const uint8_t num_dmrs_cdm_grps_no_data = (sched_ctrl->active_bwp || ubwpd) ? 1 : 2;
const int tda = get_ul_tda(nr_mac, scc, retInfo->slot);
LOG_D(NR_MAC,"retInfo->time_domain_allocation = %d, tda = %d\n", retInfo->time_domain_allocation, tda); LOG_D(NR_MAC,"retInfo->time_domain_allocation = %d, tda = %d\n", retInfo->time_domain_allocation, tda);
LOG_D(NR_MAC,"num_dmrs_cdm_grps_no_data %d, tbs %d\n",num_dmrs_cdm_grps_no_data, retInfo->tb_size); LOG_D(NR_MAC,"num_dmrs_cdm_grps_no_data %d, tbs %d\n",num_dmrs_cdm_grps_no_data, retInfo->tb_size);
if (tda == retInfo->time_domain_allocation) { if (tda == retInfo->time_domain_allocation) {
@@ -890,7 +884,7 @@ bool allocate_ul_retransmission(module_id_t module_id,
while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap) != slbitmap) while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap) != slbitmap)
rbStart++; rbStart++;
if (rbStart + retInfo->rbSize > bwpSize) { if (rbStart + retInfo->rbSize > bwpSize) {
LOG_W(NR_MAC, "cannot allocate retransmission of UE %d/RNTI %04x: no resources (rbStart %d, retInfo->rbSize %d, bwpSize %d\n", UE_id, UE_info->rnti[UE_id], rbStart, retInfo->rbSize, bwpSize); LOG_W(NR_MAC, "cannot allocate retransmission of RNTI %04x: no resources (rbStart %d, retInfo->rbSize %d, bwpSize %d\n", UE->rnti, rbStart, retInfo->rbSize, bwpSize);
return false; return false;
} }
LOG_D(NR_MAC, "%s(): retransmission keeping TDA %d and TBS %d\n", __func__, tda, retInfo->tb_size); LOG_D(NR_MAC, "%s(): retransmission keeping TDA %d and TBS %d\n", __func__, tda, retInfo->tb_size);
@@ -941,7 +935,7 @@ bool allocate_ul_retransmission(module_id_t module_id,
/* Find a free CCE */ /* Find a free CCE */
const int cid = sched_ctrl->coreset->controlResourceSetId; const int cid = sched_ctrl->coreset->controlResourceSetId;
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]); const uint16_t Y = get_Y(cid%3, slot, UE->rnti);
uint8_t nr_of_candidates; uint8_t nr_of_candidates;
for (int i=0; i<5; i++) { for (int i=0; i<5; i++) {
// for now taking the lowest value among the available aggregation levels // for now taking the lowest value among the available aggregation levels
@@ -951,7 +945,7 @@ bool allocate_ul_retransmission(module_id_t module_id,
1<<i); 1<<i);
if(nr_of_candidates>0) break; if(nr_of_candidates>0) break;
} }
int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id], int CCEIndex = find_pdcch_candidate(nrmac,
CC_id, CC_id,
sched_ctrl->aggregation_level, sched_ctrl->aggregation_level,
nr_of_candidates, nr_of_candidates,
@@ -960,12 +954,12 @@ bool allocate_ul_retransmission(module_id_t module_id,
Y); Y);
if (CCEIndex<0) { if (CCEIndex<0) {
LOG_D(NR_MAC, "%4d.%2d no free CCE for retransmission UL DCI UE %04x\n", frame, slot, UE_info->rnti[UE_id]); LOG_D(NR_MAC, "%4d.%2d no free CCE for retransmission UL DCI UE %04x\n", frame, slot, UE->rnti);
return false; return false;
} }
sched_ctrl->cce_index = CCEIndex; sched_ctrl->cce_index = CCEIndex;
fill_pdcch_vrb_map(RC.nrmac[module_id], fill_pdcch_vrb_map(nrmac,
CC_id, CC_id,
&sched_ctrl->sched_pdcch, &sched_ctrl->sched_pdcch,
CCEIndex, CCEIndex,
@@ -981,11 +975,10 @@ bool allocate_ul_retransmission(module_id_t module_id,
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
LOG_D(NR_MAC, LOG_D(NR_MAC,
"%4d.%2d Allocate UL retransmission UE %d/RNTI %04x sched %4d.%2d (%d RBs)\n", "%4d.%2d Allocate UL retransmission RNTI %04x sched %4d.%2d (%d RBs)\n",
frame, frame,
slot, slot,
UE_id, UE->rnti,
UE_info->rnti[UE_id],
sched_pusch->frame, sched_pusch->frame,
sched_pusch->slot, sched_pusch->slot,
sched_pusch->rbSize); sched_pusch->rbSize);
@@ -1012,12 +1005,20 @@ void update_ul_ue_R_Qm(NR_sched_pusch_t *sched_pusch, const NR_pusch_semi_static
} }
} }
float ul_thr_ue[MAX_MOBILES_PER_GNB];
uint32_t ul_pf_tbs[3][29]; // pre-computed, approximate TBS values for PF coefficient uint32_t ul_pf_tbs[3][29]; // pre-computed, approximate TBS values for PF coefficient
typedef struct UEsched_s {
float coef;
NR_UE_info_t * UE;
} UEsched_t;
static int comparator(const void *p, const void *q) {
return ((UEsched_t*)p)->coef < ((UEsched_t*)q)->coef;
}
void pf_ul(module_id_t module_id, void pf_ul(module_id_t module_id,
frame_t frame, frame_t frame,
sub_frame_t slot, sub_frame_t slot,
NR_list_t *UE_list, NR_UE_info_t *UE_list[],
int max_num_ue, int max_num_ue,
int n_rb_sched, int n_rb_sched,
uint16_t *rballoc_mask) { uint16_t *rballoc_mask) {
@@ -1025,28 +1026,29 @@ void pf_ul(module_id_t module_id,
const int CC_id = 0; const int CC_id = 0;
gNB_MAC_INST *nrmac = RC.nrmac[module_id]; gNB_MAC_INST *nrmac = RC.nrmac[module_id];
NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
NR_UE_info_t *UE_info = &nrmac->UE_info;
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
const int min_rb = nrmac->min_grant_prb;
float coeff_ue[MAX_MOBILES_PER_GNB]; const int min_rb = 5;
// UEs that could be scheduled // UEs that could be scheduled
int ue_array[MAX_MOBILES_PER_GNB]; UEsched_t UE_sched[MAX_MOBILES_PER_GNB] = {0};
NR_list_t UE_sched = { .head = -1, .next = ue_array, .tail = -1, .len = MAX_MOBILES_PER_GNB }; int remainUEs=max_num_ue;
int curUE=0;
/* Loop UE_list to calculate throughput and coeff */ /* Loop UE_list to calculate throughput and coeff */
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { UE_iterator(UE_list, UE) {
if (UE_info->Msg4_ACKed[UE_id] != true) continue; if (UE->Msg4_ACKed != true)
continue;
LOG_D(NR_MAC,"pf_ul: preparing UL scheduling for UE %d\n",UE_id); LOG_D(NR_MAC,"pf_ul: preparing UL scheduling for UE %04x\n",UE->rnti);
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp, NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp,
scc, scc,
sib1); sib1);
int rbStart = 0; // wrt BWP start int rbStart = 0; // wrt BWP start
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id]; NR_CellGroupConfig_t *cg = UE->CellGroup;
NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated && NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated &&
cg->spCellConfig->spCellConfigDedicated->uplinkConfig ? cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL; cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
@@ -1054,45 +1056,46 @@ void pf_ul(module_id_t module_id,
const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static;
const NR_mac_dir_stats_t *stats = &UE_info->mac_stats[UE_id].ul; const NR_mac_dir_stats_t *stats = &UE->mac_stats.ul;
/* Calculate throughput */ /* Calculate throughput */
const float a = 0.0005f; // corresponds to 200ms window const float a = 0.0005f; // corresponds to 200ms window
const uint32_t b = stats->current_bytes; const uint32_t b = stats->current_bytes;
ul_thr_ue[UE_id] = (1 - a) * ul_thr_ue[UE_id] + a * b; UE->ul_thr_ue = (1 - a) * UE->ul_thr_ue + a * b;
/* Check if retransmission is necessary */ /* Check if retransmission is necessary */
sched_pusch->ul_harq_pid = sched_ctrl->retrans_ul_harq.head; sched_pusch->ul_harq_pid = sched_ctrl->retrans_ul_harq.head;
LOG_D(NR_MAC,"pf_ul: UE %d harq_pid %d\n",UE_id,sched_pusch->ul_harq_pid); LOG_D(NR_MAC,"pf_ul: UE %04x harq_pid %d\n",UE->rnti,sched_pusch->ul_harq_pid);
if (sched_pusch->ul_harq_pid >= 0) { if (sched_pusch->ul_harq_pid >= 0) {
/* Allocate retransmission*/ /* Allocate retransmission*/
bool r = allocate_ul_retransmission( const int tda = get_ul_tda(nrmac, scc, slot);
module_id, frame, slot, rballoc_mask, &n_rb_sched, UE_id, sched_pusch->ul_harq_pid); bool r = allocate_ul_retransmission(nrmac, frame, slot, rballoc_mask, &n_rb_sched, UE, sched_pusch->ul_harq_pid, sib1, scc, tda);
if (!r) { if (!r) {
LOG_D(NR_MAC, "%4d.%2d UL retransmission UE RNTI %04x can NOT be allocated\n", frame, slot, UE_info->rnti[UE_id]); LOG_D(NR_MAC, "%4d.%2d UL retransmission UE RNTI %04x can NOT be allocated\n", frame, slot, UE->rnti);
continue; continue;
} }
else LOG_D(NR_MAC,"%4d.%2d UL Retransmission UE RNTI %04x to be allocated, max_num_ue %d\n",frame,slot,UE_info->rnti[UE_id],max_num_ue); else LOG_D(NR_MAC,"%4d.%2d UL Retransmission UE RNTI %04x to be allocated, max_num_ue %d\n",frame,slot,UE->rnti,max_num_ue);
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */ /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
max_num_ue--; remainUEs--;
if (max_num_ue < 0)
return;
continue;
}
if (remainUEs == 0)
// we have filled all with mandatory retransmissions
// no need to schedule new transmissions
return;
continue;
}
const int B = max(0, sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes); const int B = max(0, sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes);
/* preprocessor computed sched_frame/sched_slot */ /* preprocessor computed sched_frame/sched_slot */
const bool do_sched = nr_UE_is_to_be_scheduled(module_id, 0, UE_id, sched_pusch->frame, sched_pusch->slot); const bool do_sched = nr_UE_is_to_be_scheduled(scc, 0, UE, sched_pusch->frame, sched_pusch->slot, nrmac->ulsch_max_frame_inactivity);
LOG_D(NR_MAC,"pf_ul: do_sched UE %d => %s\n",UE_id,do_sched ? "yes" : "no"); LOG_D(NR_MAC,"pf_ul: do_sched UE %04x => %s\n",UE->rnti,do_sched ? "yes" : "no");
if ((B == 0 && !do_sched) || (sched_ctrl->rrc_processing_timer > 0)) { if ((B == 0 && !do_sched) || (sched_ctrl->rrc_processing_timer > 0))
continue; continue;
}
const NR_bler_options_t *bo = &nrmac->ul_bler; const NR_bler_options_t *bo = &nrmac->ul_bler;
const int max_mcs = bo->max_mcs; /* no per-user maximum MCS yet */ const int max_mcs = bo->max_mcs; /* no per-user maximum MCS yet */
sched_pusch->mcs = get_mcs_from_bler(bo, stats, &sched_ctrl->ul_bler_stats, max_mcs, frame); sched_pusch->mcs = get_mcs_from_bler(bo, stats, &UE->UE_sched_ctrl.ul_bler_stats, max_mcs, frame);
/* Schedule UE on SR or UL inactivity and no data (otherwise, will be scheduled /* Schedule UE on SR or UL inactivity and no data (otherwise, will be scheduled
* based on data to transmit) */ * based on data to transmit) */
@@ -1100,32 +1103,35 @@ void pf_ul(module_id_t module_id,
/* if no data, pre-allocate 5RB */ /* if no data, pre-allocate 5RB */
/* Find a free CCE */ /* Find a free CCE */
const int cid = sched_ctrl->coreset->controlResourceSetId; const int cid = sched_ctrl->coreset->controlResourceSetId;
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]); const uint16_t Y = get_Y(cid%3, slot, UE->rnti);
uint8_t nr_of_candidates; uint8_t nr_of_candidates;
for (int i=0; i<5; i++) { for (int i=0; i<5; i++) {
// for now taking the lowest value among the available aggregation levels // for now taking the lowest value among the available aggregation levels
find_aggregation_candidates(&sched_ctrl->aggregation_level, find_aggregation_candidates(&sched_ctrl->aggregation_level,
&nr_of_candidates, &nr_of_candidates,
sched_ctrl->search_space, sched_ctrl->search_space,
1<<i); 1<<i);
if(nr_of_candidates>0) break; if(nr_of_candidates>0) break;
} }
int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id], int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id],
CC_id, CC_id,
sched_ctrl->aggregation_level, sched_ctrl->aggregation_level,
nr_of_candidates, nr_of_candidates,
&sched_ctrl->sched_pdcch, &sched_ctrl->sched_pdcch,
sched_ctrl->coreset, sched_ctrl->coreset,
Y); Y);
if (CCEIndex<0) { if (CCEIndex<0) {
LOG_D(NR_MAC, "%4d.%2d no free CCE for UL DCI UE %04x (BSR 0)\n", frame, slot, UE_info->rnti[UE_id]); LOG_D(NR_MAC, "%4d.%2d no free CCE for UL DCI UE %04x (BSR 0)\n", frame, slot, UE->rnti);
continue; continue;
} }
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */ /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
max_num_ue--; remainUEs--;
if (max_num_ue < 0)
return; if (remainUEs == 0)
// we have filled all with mandatory retransmissions
// no need to schedule new transmissions
return;
/* Save PUSCH field */ /* Save PUSCH field */
/* we want to avoid a lengthy deduction of DMRS and other parameters in /* we want to avoid a lengthy deduction of DMRS and other parameters in
@@ -1156,8 +1162,8 @@ void pf_ul(module_id_t module_id,
while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap) != slbitmap) while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap) != slbitmap)
rbStart++; rbStart++;
if (rbStart + min_rb >= bwpSize) { if (rbStart + min_rb >= bwpSize) {
LOG_W(NR_MAC, "cannot allocate continuous UL data for UE %d/RNTI %04x: no resources (rbStart %d, min_rb %d, bwpSize %d\n", LOG_W(NR_MAC, "cannot allocate continuous UL data for RNTI %04x: no resources (rbStart %d, min_rb %d, bwpSize %d\n",
UE_id, UE_info->rnti[UE_id],rbStart,min_rb,bwpSize); UE->rnti,rbStart,min_rb,bwpSize);
return; return;
} }
@@ -1192,40 +1198,27 @@ void pf_ul(module_id_t module_id,
} }
/* Create UE_sched for UEs eligibale for new data transmission*/ /* Create UE_sched for UEs eligibale for new data transmission*/
add_tail_nr_list(&UE_sched, UE_id);
/* Calculate coefficient*/ /* Calculate coefficient*/
const uint32_t tbs = ul_pf_tbs[ps->mcs_table][sched_pusch->mcs]; const uint32_t tbs = ul_pf_tbs[ps->mcs_table][sched_pusch->mcs];
coeff_ue[UE_id] = (float) tbs / ul_thr_ue[UE_id]; float coeff_ue = (float) tbs / UE->ul_thr_ue;
LOG_D(NR_MAC,"b %d, ul_thr_ue[%d] %f, tbs %d, coeff_ue[%d] %f\n", LOG_D(NR_MAC,"rnti %04x b %d, ul_thr_ue %f, tbs %d, coeff_ue %f\n",
b, UE_id, ul_thr_ue[UE_id], tbs, UE_id, coeff_ue[UE_id]); UE->rnti, b, UE->ul_thr_ue, tbs, coeff_ue);
UE_sched[curUE].coef=coeff_ue;
UE_sched[curUE].UE=UE;
curUE++;
} }
qsort(UE_sched, sizeof(*UE_sched), sizeofArray(UE_sched), comparator);
UEsched_t *iterator=UE_sched;
const int min_rbSize = 5; const int min_rbSize = 5;
/* Loop UE_sched to find max coeff and allocate transmission */ /* Loop UE_sched to find max coeff and allocate transmission */
while (UE_sched.head >= 0 && max_num_ue> 0 && n_rb_sched >= min_rbSize) { while (remainUEs> 0 && n_rb_sched >= min_rbSize && iterator->UE != NULL) {
/* Find max coeff */
int *max = &UE_sched.head; /* Find max coeff: assume head is max */
int *p = &UE_sched.next[*max];
while (*p >= 0) {
/* Find max coeff: if the current one has larger coeff, save for later */
if (coeff_ue[*p] > coeff_ue[*max])
max = p;
p = &UE_sched.next[*p];
}
/* Find max coeff: remove the max one: do not use remove_nr_list() since it
* goes through the whole list every time. Note that UE_sched.tail might
* not be set correctly anymore */
const int UE_id = *max;
p = &UE_sched.next[*max];
*max = UE_sched.next[*max];
*p = -1;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; NR_UE_sched_ctrl_t *sched_ctrl = &iterator->UE->UE_sched_ctrl;
const int cid = sched_ctrl->coreset->controlResourceSetId; const int cid = sched_ctrl->coreset->controlResourceSetId;
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]); const uint16_t Y = get_Y(cid%3, slot, iterator->UE->rnti);
uint8_t nr_of_candidates; uint8_t nr_of_candidates;
for (int i=0; i<5; i++) { for (int i=0; i<5; i++) {
// for now taking the lowest value among the available aggregation levels // for now taking the lowest value among the available aggregation levels
@@ -1233,7 +1226,8 @@ void pf_ul(module_id_t module_id,
&nr_of_candidates, &nr_of_candidates,
sched_ctrl->search_space, sched_ctrl->search_space,
1<<i); 1<<i);
if(nr_of_candidates>0) break; if(nr_of_candidates>0)
break;
} }
int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id], int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id],
CC_id, CC_id,
@@ -1243,16 +1237,13 @@ void pf_ul(module_id_t module_id,
sched_ctrl->coreset, sched_ctrl->coreset,
Y); Y);
if (CCEIndex<0) { if (CCEIndex<0) {
LOG_D(NR_MAC, "%4d.%2d no free CCE for UL DCI UE %04x\n", frame, slot, UE_info->rnti[UE_id]); LOG_D(NR_MAC, "%4d.%2d no free CCE for UL DCI UE %04x\n", frame, slot, iterator->UE->rnti);
iterator++;
continue; continue;
} }
else LOG_D(NR_MAC, "%4d.%2d free CCE for UL DCI UE %04x\n",frame,slot, UE_info->rnti[UE_id]); else LOG_D(NR_MAC, "%4d.%2d free CCE for UL DCI UE %04x\n",frame,slot, iterator->UE->rnti);
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */ NR_CellGroupConfig_t *cg = iterator->UE->CellGroup;
max_num_ue--;
AssertFatal(max_num_ue >= 0, "Illegal max_num_ue %d\n", max_num_ue);
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated
&& cg->spCellConfig->spCellConfigDedicated->uplinkConfig ? && cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL; cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
@@ -1299,11 +1290,12 @@ void pf_ul(module_id_t module_id,
max_rbSize++; max_rbSize++;
if (rbStart + min_rb >= bwpSize) { if (rbStart + min_rb >= bwpSize) {
LOG_W(NR_MAC, "cannot allocate UL data for UE %d/RNTI %04x: no resources (rbStart %d, min_rb %d, bwpSize %d\n", LOG_W(NR_MAC, "cannot allocate UL data for RNTI %04x: no resources (rbStart %d, min_rb %d, bwpSize %d)\n",
UE_id, UE_info->rnti[UE_id],rbStart,min_rb,bwpSize); iterator->UE->rnti,rbStart,min_rb,bwpSize);
return; return;
} }
else LOG_D(NR_MAC,"allocating UL data for UE %d/RNTI %04x (rbStsart %d, min_rb %d, bwpSize %d\n",UE_id, UE_info->rnti[UE_id],rbStart,min_rb,bwpSize); else
LOG_D(NR_MAC,"allocating UL data for RNTI %04x (rbStsart %d, min_rb %d, bwpSize %d)\n", iterator->UE->rnti,rbStart,min_rb,bwpSize);
/* Calculate the current scheduling bytes and the necessary RBs */ /* Calculate the current scheduling bytes and the necessary RBs */
const int B = cmax(sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes, 0); const int B = cmax(sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes, 0);
@@ -1336,7 +1328,11 @@ void pf_ul(module_id_t module_id,
n_rb_sched -= sched_pusch->rbSize; n_rb_sched -= sched_pusch->rbSize;
for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++) for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++)
rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] ^= slbitmap; rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] ^= slbitmap;
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
remainUEs--;
iterator++;
} }
} }
@@ -1353,9 +1349,8 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
const int mu = scc ? scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing : const int mu = scc ? scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing :
scc_sib1->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing; scc_sib1->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing;
NR_UE_info_t *UE_info = &nr_mac->UE_info; if (nr_mac->UE_info.list[0] == NULL)
// no UEs
if (UE_info->num_UEs == 0)
return false; return false;
const int CC_id = 0; const int CC_id = 0;
@@ -1364,8 +1359,7 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
* have the same K2 (we don't support multiple/different K2s via different * have the same K2 (we don't support multiple/different K2s via different
* TDAs yet). If the TDA is negative, it means that there is no UL slot to * TDAs yet). If the TDA is negative, it means that there is no UL slot to
* schedule now (slot + k2 is not UL slot) */ * schedule now (slot + k2 is not UL slot) */
int UE_id = UE_info->list.head; NR_UE_sched_ctrl_t *sched_ctrl = &nr_mac->UE_info.list[0]->UE_sched_ctrl;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
const int temp_tda = get_ul_tda(nr_mac, scc, slot); const int temp_tda = get_ul_tda(nr_mac, scc, slot);
int K2 = get_K2(scc, scc_sib1, sched_ctrl->active_ubwp, temp_tda, mu); int K2 = get_K2(scc, scc_sib1, sched_ctrl->active_ubwp, temp_tda, mu);
const int sched_frame = (frame + (slot + K2 >= nr_slots_per_frame[mu])) & 1023; const int sched_frame = (frame + (slot + K2 >= nr_slots_per_frame[mu])) & 1023;
@@ -1391,9 +1385,8 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
return false; return false;
// Avoid slots with the SRS // Avoid slots with the SRS
const NR_list_t *UE_list = &UE_info->list; UE_iterator(nr_mac->UE_info.list, UE) {
for (int UE_idx = UE_list->head; UE_idx >= 0; UE_idx = UE_list->next[UE_idx]) { NR_sched_srs_t sched_srs = UE->UE_sched_ctrl.sched_srs;
NR_sched_srs_t sched_srs = UE_info->UE_sched_ctrl[UE_idx].sched_srs;
if(sched_srs.srs_scheduled && sched_srs.frame==sched_frame && sched_srs.slot==sched_slot) { if(sched_srs.srs_scheduled && sched_srs.frame==sched_frame && sched_srs.slot==sched_slot) {
return false; return false;
} }
@@ -1401,10 +1394,11 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
sched_ctrl->sched_pusch.slot = sched_slot; sched_ctrl->sched_pusch.slot = sched_slot;
sched_ctrl->sched_pusch.frame = sched_frame; sched_ctrl->sched_pusch.frame = sched_frame;
for (UE_id = UE_info->list.next[UE_id]; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { UE_iterator(nr_mac->UE_info.list, UE2) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; NR_UE_sched_ctrl_t *sched_ctrl = &UE2->UE_sched_ctrl;
AssertFatal(K2 == get_K2(scc,scc_sib1,sched_ctrl->active_ubwp, tda, mu), AssertFatal(K2 == get_K2(scc,scc_sib1,sched_ctrl->active_ubwp, tda, mu),
"Different K2, %d(UE%d) != %ld(UE%d)\n", K2, 0, get_K2(scc,scc_sib1,sched_ctrl->active_ubwp, tda, mu), UE_id); "Different K2, %d(UE%d) != %ld(UE%04x)\n",
K2, 0, get_K2(scc,scc_sib1,sched_ctrl->active_ubwp, tda, mu), UE2->rnti);
sched_ctrl->sched_pusch.slot = sched_slot; sched_ctrl->sched_pusch.slot = sched_slot;
sched_ctrl->sched_pusch.frame = sched_frame; sched_ctrl->sched_pusch.frame = sched_frame;
} }
@@ -1464,7 +1458,7 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
pf_ul(module_id, pf_ul(module_id,
frame, frame,
slot, slot,
&UE_info->list, nr_mac->UE_info.list,
2, 2,
len, len,
rballoc_mask); rballoc_mask);
@@ -1525,30 +1519,28 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon; NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; NR_UEs_t *UE_info = &RC.nrmac[module_id]->UE_info;
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
const NR_list_t *UE_list = &UE_info->list; UE_iterator( UE_info->list, UE) {
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
if (sched_ctrl->ul_failure == 1 && get_softmodem_params()->phy_test==0) continue; if (sched_ctrl->ul_failure == 1 && get_softmodem_params()->phy_test==0) continue;
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id]; NR_CellGroupConfig_t *cg = UE->CellGroup;
NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated && NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated &&
cg->spCellConfig->spCellConfigDedicated->uplinkConfig ? cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL; cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
NR_mac_stats_t *mac_stats = &UE_info->mac_stats[UE_id]; UE->mac_stats.ul.current_bytes = 0;
mac_stats->ul.current_bytes = 0;
/* dynamic PUSCH values (RB alloc, MCS, hence R, Qm, TBS) that change in /* dynamic PUSCH values (RB alloc, MCS, hence R, Qm, TBS) that change in
* every TTI are pre-populated by the preprocessor and used below */ * every TTI are pre-populated by the preprocessor and used below */
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
LOG_D(NR_MAC,"UE %x : sched_pusch->rbSize %d\n",UE_info->rnti[UE_id],sched_pusch->rbSize); LOG_D(NR_MAC,"UE %04x : sched_pusch->rbSize %d\n",UE->rnti,sched_pusch->rbSize);
if (sched_pusch->rbSize <= 0) if (sched_pusch->rbSize <= 0)
continue; continue;
uint16_t rnti = UE_info->rnti[UE_id]; uint16_t rnti = UE->rnti;
sched_ctrl->SR = false; sched_ctrl->SR = false;
int8_t harq_id = sched_pusch->ul_harq_pid; int8_t harq_id = sched_pusch->ul_harq_pid;
@@ -1556,8 +1548,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
/* PP has not selected a specific HARQ Process, get a new one */ /* PP has not selected a specific HARQ Process, get a new one */
harq_id = sched_ctrl->available_ul_harq.head; harq_id = sched_ctrl->available_ul_harq.head;
AssertFatal(harq_id >= 0, AssertFatal(harq_id >= 0,
"no free HARQ process available for UE %d\n", "no free HARQ process available for UE %04x\n",
UE_id); UE->rnti);
remove_front_nr_list(&sched_ctrl->available_ul_harq); remove_front_nr_list(&sched_ctrl->available_ul_harq);
sched_pusch->ul_harq_pid = harq_id; sched_pusch->ul_harq_pid = harq_id;
} else { } else {
@@ -1583,10 +1575,10 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static;
/* Statistics */ /* Statistics */
AssertFatal(cur_harq->round < 8, "Indexing UL rounds[%d] is out of bounds\n", cur_harq->round); AssertFatal(cur_harq->round < 8, "Indexing ulsch_rounds[%d] is out of bounds\n", cur_harq->round);
mac_stats->ul.rounds[cur_harq->round]++; UE->mac_stats.ul.rounds[cur_harq->round]++;
if (cur_harq->round == 0) { if (cur_harq->round == 0) {
mac_stats->ulsch_total_bytes_scheduled += sched_pusch->tb_size; UE->mac_stats.ulsch_total_bytes_scheduled += sched_pusch->tb_size;
/* Save information on MCS, TBS etc for the current initial transmission /* Save information on MCS, TBS etc for the current initial transmission
* so we have access to it when retransmitting */ * so we have access to it when retransmitting */
cur_harq->sched_pusch = *sched_pusch; cur_harq->sched_pusch = *sched_pusch;
@@ -1606,7 +1598,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
cur_harq->round, cur_harq->round,
cur_harq->ndi); cur_harq->ndi);
} }
mac_stats->ul.current_bytes = sched_pusch->tb_size; UE->mac_stats.ul.current_bytes = sched_pusch->tb_size;
sched_ctrl->last_ul_frame = sched_pusch->frame; sched_ctrl->last_ul_frame = sched_pusch->frame;
sched_ctrl->last_ul_slot = sched_pusch->slot; sched_ctrl->last_ul_slot = sched_pusch->slot;
@@ -1789,7 +1781,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
pdcch_pdu_coreset[coresetid] = pdcch_pdu; pdcch_pdu_coreset[coresetid] = pdcch_pdu;
} }
LOG_D(NR_MAC,"Configuring ULDCI/PDCCH in %d.%d at CCE %d, rnti %x\n", frame,slot,sched_ctrl->cce_index,rnti); LOG_D(NR_MAC,"Configuring ULDCI/PDCCH in %d.%d at CCE %d, rnti %04x\n", frame,slot,sched_ctrl->cce_index,rnti);
/* Fill PDCCH DL DCI PDU */ /* Fill PDCCH DL DCI PDU */
nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu->dci_pdu[pdcch_pdu->numDlDci]; nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu->dci_pdu[pdcch_pdu->numDlDci];
@@ -1827,7 +1819,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
&uldci_payload, &uldci_payload,
ps->dci_format, ps->dci_format,
ps->time_domain_allocation, ps->time_domain_allocation,
UE_info->UE_sched_ctrl[UE_id].tpc0, UE->UE_sched_ctrl.tpc0,
n_ubwp, n_ubwp,
bwp_id); bwp_id);
fill_dci_pdu_rel15(scc, fill_dci_pdu_rel15(scc,
+11 -13
View File
@@ -203,7 +203,7 @@ void config_uldci(const NR_SIB1_t *sib1,
int n_ubwp, int n_ubwp,
int bwp_id); int bwp_id);
void nr_schedule_pucch(int Mod_idP, void nr_schedule_pucch(gNB_MAC_INST* nrmac,
frame_t frameP, frame_t frameP,
sub_frame_t slotP); sub_frame_t slotP);
@@ -218,15 +218,14 @@ void nr_csi_meas_reporting(int Mod_idP,
frame_t frameP, frame_t frameP,
sub_frame_t slotP); sub_frame_t slotP);
int nr_acknack_scheduling(int Mod_idP, int nr_acknack_scheduling( int Mod_idP,
int UE_id, NR_UE_info_t * UE,
frame_t frameP, frame_t frameP,
sub_frame_t slotP, sub_frame_t slotP,
int r_pucch, int r_pucch,
int do_common); int do_common);
void get_pdsch_to_harq_feedback(int Mod_idP, void get_pdsch_to_harq_feedback(NR_UE_info_t *,
int UE_id,
int bwp_id, int bwp_id,
NR_SearchSpace__searchSpaceType_PR ss_type, NR_SearchSpace__searchSpaceType_PR ss_type,
int *max_fb_time, int *max_fb_time,
@@ -336,7 +335,7 @@ NR_PDSCH_TimeDomainResourceAllocationList_t *get_pdsch_TimeDomainAllocationList(
const NR_SIB1_t *sib1); const NR_SIB1_t *sib1);
/* find coreset within the search space */ /* find coreset within the search space */
NR_ControlResourceSet_t *get_coreset(module_id_t module_idP, NR_ControlResourceSet_t *get_coreset(gNB_MAC_INST *nrmac,
NR_ServingCellConfigCommon_t *scc, NR_ServingCellConfigCommon_t *scc,
void *bwp, void *bwp,
NR_SearchSpace_t *ss, NR_SearchSpace_t *ss,
@@ -394,7 +393,6 @@ int NRRIV2BW(int locationAndBandwidth,int N_RB);
int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB); int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB);
/* Functions to manage an NR_list_t */ /* Functions to manage an NR_list_t */
void dump_nr_list(NR_list_t *listP);
void create_nr_list(NR_list_t *listP, int len); void create_nr_list(NR_list_t *listP, int len);
void resize_nr_list(NR_list_t *list, int new_len); void resize_nr_list(NR_list_t *list, int new_len);
void destroy_nr_list(NR_list_t *list); void destroy_nr_list(NR_list_t *list);
@@ -404,13 +402,13 @@ void add_tail_nr_list(NR_list_t *listP, int id);
void add_front_nr_list(NR_list_t *listP, int id); void add_front_nr_list(NR_list_t *listP, int id);
void remove_front_nr_list(NR_list_t *listP); void remove_front_nr_list(NR_list_t *listP);
int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP); NR_UE_info_t * find_nr_UE(NR_UEs_t* UEs, rnti_t rntiP);
int find_nr_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP); int find_nr_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP);
int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellGroup); NR_UE_info_t*add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConfig_t *CellGroup);
void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti); void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti);
void nr_mac_remove_ra_rnti(module_id_t mod_id, rnti_t rnti); void nr_mac_remove_ra_rnti(module_id_t mod_id, rnti_t rnti);
@@ -424,7 +422,7 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
int nr_get_default_pucch_res(int pucch_ResourceCommon); int nr_get_default_pucch_res(int pucch_ResourceCommon);
void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_info, int UE_id, module_id_t Mod_idP); void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE);
int get_dlscs(nfapi_nr_config_request_t *cfg); int get_dlscs(nfapi_nr_config_request_t *cfg);
@@ -515,7 +513,7 @@ int get_dci_format(NR_UE_sched_ctrl_t *sched_ctrl);
const int get_dl_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot); const int get_dl_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot);
const int get_ul_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot); const int get_ul_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot);
bool find_free_CCE(module_id_t module_id, sub_frame_t slot, int UE_id); bool find_free_CCE(sub_frame_t slot, NR_UE_info_t *UE);
bool nr_find_nb_rb(uint16_t Qm, bool nr_find_nb_rb(uint16_t Qm,
uint16_t R, uint16_t R,
@@ -534,7 +532,7 @@ int get_mcs_from_bler(const NR_bler_options_t *bler_options,
int max_mcs, int max_mcs,
frame_t frame); frame_t frame);
void nr_sr_reporting(int Mod_idP, frame_t frameP, sub_frame_t slotP); void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t frameP, sub_frame_t slotP);
void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp); void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp);
+40 -44
View File
@@ -57,7 +57,7 @@ void *nrmac_stats_thread(void *arg) {
AssertFatal(fd!=NULL,"Cannot open nrMAC_stats.log, error %s\n",strerror(errno)); AssertFatal(fd!=NULL,"Cannot open nrMAC_stats.log, error %s\n",strerror(errno));
while (oai_exit == 0) { while (oai_exit == 0) {
dump_mac_stats(gNB,output,MACSTATSSTRLEN,false); dump_mac_stats(gNB,output,MACSTATSSTRLEN,false);
fprintf(fd,"%s\n",output); fprintf(fd,"%s\n",output);
fflush(fd); fflush(fd);
usleep(200000); usleep(200000);
@@ -68,40 +68,40 @@ void *nrmac_stats_thread(void *arg) {
} }
void clear_mac_stats(gNB_MAC_INST *gNB) { void clear_mac_stats(gNB_MAC_INST *gNB) {
memset((void*)gNB->UE_info.mac_stats,0,MAX_MOBILES_PER_GNB*sizeof(NR_mac_stats_t)); UE_iterator(gNB->UE_info.list, UE) {
memset(&UE->mac_stats,0,sizeof(UE->mac_stats));
}
} }
void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp) void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp)
{ {
NR_UE_info_t *UE_info = &gNB->UE_info;
int num = 1; int num = 1;
int stroff=0; int stroff=0;
if (UE_info->num_UEs == 0) return; pthread_mutex_lock(&gNB->UE_info.mutex);
UE_iterator(gNB->UE_info.list, UE) {
for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_mac_stats_t *stats = &UE->mac_stats;
const NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id];
const int avg_rsrp = stats->num_rsrp_meas > 0 ? stats->cumul_rsrp / stats->num_rsrp_meas : 0; const int avg_rsrp = stats->num_rsrp_meas > 0 ? stats->cumul_rsrp / stats->num_rsrp_meas : 0;
stroff+=sprintf(output+stroff,"UE ID %d RNTI %04x (%d/%d) PH %d dB PCMAX %d dBm, average RSRP %d (%d meas)\n",
UE_id,
UE_info->rnti[UE_id],
num++,
UE_info->num_UEs,
sched_ctrl->ph,
sched_ctrl->pcmax,
avg_rsrp,
stats->num_rsrp_meas);
stroff+=sprintf(output+stroff,"UE %d: CQI %d, RI %d, PMI (%d,%d)\n",
UE_id,
UE_info->UE_sched_ctrl[UE_id].CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb,
UE_info->UE_sched_ctrl[UE_id].CSI_report.cri_ri_li_pmi_cqi_report.ri+1,
UE_info->UE_sched_ctrl[UE_id].CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1,
UE_info->UE_sched_ctrl[UE_id].CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2);
stroff+=sprintf(output+stroff,"UE %d: dlsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS %d\n",
UE_id, stroff+=sprintf(output+stroff,"UE RNTI %04x (%d) PH %d dB PCMAX %d dBm, average RSRP %d (%d meas)\n",
UE->rnti,
num++,
sched_ctrl->ph,
sched_ctrl->pcmax,
avg_rsrp,
stats->num_rsrp_meas);
stroff+=sprintf(output+stroff,"UE %04x: CQI %d, RI %d, PMI (%d,%d)\n",
UE->rnti,
UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb,
UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.ri+1,
UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1,
UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2);
stroff+=sprintf(output+stroff,"UE %04x: dlsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS %d\n",
UE->rnti,
stats->dl.rounds[0], stats->dl.rounds[1], stats->dl.rounds[0], stats->dl.rounds[1],
stats->dl.rounds[2], stats->dl.rounds[3], stats->dl.rounds[2], stats->dl.rounds[3],
stats->dl.errors, stats->dl.errors,
@@ -112,9 +112,9 @@ void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp
stats->num_rsrp_meas = 0; stats->num_rsrp_meas = 0;
stats->cumul_rsrp = 0; stats->cumul_rsrp = 0;
} }
stroff+=sprintf(output+stroff,"UE %d: dlsch_total_bytes %"PRIu64"\n", UE_id, stats->dl.total_bytes); stroff+=sprintf(output+stroff,"UE %04x: dlsch_total_bytes %"PRIu64"\n", UE->rnti, stats->dl.total_bytes);
stroff+=sprintf(output+stroff,"UE %d: ulsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", ulsch_DTX %d, ulsch_errors %"PRIu64", BLER %.5f MCS %d\n", stroff+=sprintf(output+stroff,"UE %04x: ulsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", ulsch_DTX %d, ulsch_errors %"PRIu64"\n",
UE_id, UE->rnti,
stats->ul.rounds[0], stats->ul.rounds[1], stats->ul.rounds[0], stats->ul.rounds[1],
stats->ul.rounds[2], stats->ul.rounds[3], stats->ul.rounds[2], stats->ul.rounds[3],
stats->ulsch_DTX, stats->ulsch_DTX,
@@ -122,20 +122,22 @@ void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp
sched_ctrl->ul_bler_stats.bler, sched_ctrl->ul_bler_stats.bler,
sched_ctrl->ul_bler_stats.mcs); sched_ctrl->ul_bler_stats.mcs);
stroff+=sprintf(output+stroff, stroff+=sprintf(output+stroff,
"UE %d: ulsch_total_bytes_scheduled %"PRIu64", ulsch_total_bytes_received %"PRIu64"\n", "UE %04x: ulsch_total_bytes_scheduled %"PRIu64", ulsch_total_bytes_received %"PRIu64"\n",
UE_id, UE->rnti,
stats->ulsch_total_bytes_scheduled, stats->ul.total_bytes); stats->ulsch_total_bytes_scheduled, stats->ul.total_bytes);
for (int lc_id = 0; lc_id < 63; lc_id++) { for (int lc_id = 0; lc_id < 63; lc_id++) {
if (stats->dl.lc_bytes[lc_id] > 0) { if (stats->dl.lc_bytes[lc_id] > 0) {
stroff+=sprintf(output+stroff, "UE %d: LCID %d: %"PRIu64" bytes TX\n", UE_id, lc_id, stats->dl.lc_bytes[lc_id]); stroff+=sprintf(output+stroff, "UE %04x: LCID %d: %"PRIu64" bytes TX\n", UE->rnti, lc_id, stats->dl.lc_bytes[lc_id]);
LOG_D(NR_MAC, "UE %d: LCID %d: %"PRIu64" bytes TX\n", UE_id, lc_id, stats->dl.lc_bytes[lc_id]); LOG_D(NR_MAC, "UE %04x: LCID %d: %"PRIu64" bytes TX\n", UE->rnti, lc_id, stats->dl.lc_bytes[lc_id]);
} }
if (stats->ul.lc_bytes[lc_id] > 0) { if (stats->ul.lc_bytes[lc_id] > 0) {
stroff+=sprintf(output+stroff, "UE %d: LCID %d: %"PRIu64" bytes RX\n", UE_id, lc_id, stats->ul.lc_bytes[lc_id]); stroff+=sprintf(output+stroff, "UE %04x: LCID %d: %"PRIu64" bytes RX\n", UE->rnti, lc_id, stats->ul.lc_bytes[lc_id]);
LOG_D(NR_MAC, "UE %d: LCID %d: %"PRIu64" bytes RX\n", UE_id, lc_id, stats->ul.lc_bytes[lc_id]); LOG_D(NR_MAC, "UE %04x: LCID %d: %"PRIu64" bytes RX\n", UE->rnti, lc_id, stats->ul.lc_bytes[lc_id]);
} }
} }
} }
pthread_mutex_unlock(&gNB->UE_info.mutex);
print_meas(&gNB->eNB_scheduler, "DL & UL scheduling timing stats", NULL, NULL); print_meas(&gNB->eNB_scheduler, "DL & UL scheduling timing stats", NULL, NULL);
print_meas(&gNB->schedule_dlsch,"dlsch scheduler",NULL,NULL); print_meas(&gNB->schedule_dlsch,"dlsch scheduler",NULL,NULL);
print_meas(&gNB->rlc_data_req, "rlc_data_req",NULL,NULL); print_meas(&gNB->rlc_data_req, "rlc_data_req",NULL,NULL);
@@ -146,8 +148,6 @@ void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp
void mac_top_init_gNB(void) void mac_top_init_gNB(void)
{ {
module_id_t i; module_id_t i;
int list_el;
NR_UE_info_t *UE_info;
gNB_MAC_INST *nrmac; gNB_MAC_INST *nrmac;
LOG_I(MAC, "[MAIN] Init function start:nb_nr_macrlc_inst=%d\n",RC.nb_nr_macrlc_inst); LOG_I(MAC, "[MAIN] Init function start:nb_nr_macrlc_inst=%d\n",RC.nb_nr_macrlc_inst);
@@ -181,6 +181,8 @@ void mac_top_init_gNB(void)
RC.nrmac[i]->first_MIB = true; RC.nrmac[i]->first_MIB = true;
pthread_mutex_init(&RC.nrmac[i]->UE_info.mutex, NULL);
if (get_softmodem_params()->phy_test) { if (get_softmodem_params()->phy_test) {
RC.nrmac[i]->pre_processor_dl = nr_preprocessor_phytest; RC.nrmac[i]->pre_processor_dl = nr_preprocessor_phytest;
RC.nrmac[i]->pre_processor_ul = nr_ul_preprocessor_phytest; RC.nrmac[i]->pre_processor_ul = nr_ul_preprocessor_phytest;
@@ -212,13 +214,7 @@ void mac_top_init_gNB(void)
nrmac = RC.nrmac[i]; nrmac = RC.nrmac[i];
nrmac->if_inst = NR_IF_Module_init(i); nrmac->if_inst = NR_IF_Module_init(i);
memset(&nrmac->UE_info, 0, sizeof(nrmac->UE_info));
UE_info = &nrmac->UE_info;
UE_info->num_UEs = 0;
create_nr_list(&UE_info->list, MAX_MOBILES_PER_GNB);
for (list_el = 0; list_el < MAX_MOBILES_PER_GNB; list_el++) {
UE_info->active[list_el] = false;
}
} }
srand48(0); srand48(0);
+23 -12
View File
@@ -91,6 +91,7 @@ typedef struct {
int len; int len;
} NR_list_t; } NR_list_t;
typedef enum { typedef enum {
RA_IDLE = 0, RA_IDLE = 0,
Msg2 = 1, Msg2 = 1,
@@ -703,24 +704,34 @@ typedef struct NR_bler_options {
/*! \brief UE list used by gNB to order UEs/CC for scheduling*/ /*! \brief UE list used by gNB to order UEs/CC for scheduling*/
#define MAX_CSI_REPORTCONFIG 48 #define MAX_CSI_REPORTCONFIG 48
typedef struct { typedef struct {
rnti_t rnti;
/// scheduling control info /// scheduling control info
nr_csi_report_t csi_report_template[MAX_MOBILES_PER_GNB][MAX_CSI_REPORTCONFIG]; nr_csi_report_t csi_report_template[MAX_CSI_REPORTCONFIG];
NR_UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB]; NR_UE_sched_ctrl_t UE_sched_ctrl;
NR_mac_stats_t mac_stats[MAX_MOBILES_PER_GNB]; NR_mac_stats_t mac_stats;
NR_list_t list; NR_CellGroupConfig_t *CellGroup;
int num_UEs;
bool active[MAX_MOBILES_PER_GNB];
rnti_t rnti[MAX_MOBILES_PER_GNB];
NR_CellGroupConfig_t *CellGroup[MAX_MOBILES_PER_GNB];
/// CCE indexing /// CCE indexing
int m[MAX_MOBILES_PER_GNB]; int m;
// UE selected beam index // UE selected beam index
uint8_t UE_beam_index[MAX_MOBILES_PER_GNB]; uint8_t UE_beam_index;
bool Msg4_ACKed[MAX_MOBILES_PER_GNB]; bool Msg4_ACKed;
/// Sched CSI-RS: scheduling decisions /// Sched CSI-RS: scheduling decisions
bool sched_csirs; bool sched_csirs;
NR_gNB_UCI_STATS_t uci_statS;
float ul_thr_ue;
float dl_thr_ue;
int layers;
} NR_UE_info_t; } NR_UE_info_t;
typedef struct {
/// scheduling control info
// last element always NULL
pthread_mutex_t mutex;
NR_UE_info_t *list[MAX_MOBILES_PER_GNB+1];
} NR_UEs_t;
#define UE_iterator(BaSe, VaR) NR_UE_info_t ** VaR##pptr=BaSe, *VaR; while ((VaR=*(VaR##pptr++)))
typedef void (*nr_pp_impl_dl)(module_id_t mod_id, typedef void (*nr_pp_impl_dl)(module_id_t mod_id,
frame_t frame, frame_t frame,
sub_frame_t slot); sub_frame_t slot);
@@ -779,7 +790,7 @@ typedef struct gNB_MAC_INST_s {
/// NFAPI DL PDU structure /// NFAPI DL PDU structure
nfapi_nr_tx_data_request_t TX_req[NFAPI_CC_MAX]; nfapi_nr_tx_data_request_t TX_req[NFAPI_CC_MAX];
int pdcch_cand[MAX_NUM_CORESET]; int pdcch_cand[MAX_NUM_CORESET];
NR_UE_info_t UE_info; NR_UEs_t UE_info;
/// UL handle /// UL handle
uint32_t ul_handle; uint32_t ul_handle;
-3
View File
@@ -372,9 +372,6 @@ static void match_crc_rx_pdu(nfapi_nr_rx_data_indication_t *rx_ind, nfapi_nr_crc
void NR_UL_indication(NR_UL_IND_t *UL_info) { void NR_UL_indication(NR_UL_IND_t *UL_info) {
AssertFatal(UL_info!=NULL,"UL_info is null\n"); AssertFatal(UL_info!=NULL,"UL_info is null\n");
#ifdef DUMP_FAPI
dump_ul(UL_info);
#endif
module_id_t module_id = UL_info->module_id; module_id_t module_id = UL_info->module_id;
int CC_id = UL_info->CC_id; int CC_id = UL_info->CC_id;
NR_Sched_Rsp_t *sched_info = &NR_Sched_INFO[module_id][CC_id]; NR_Sched_Rsp_t *sched_info = &NR_Sched_INFO[module_id][CC_id];
+4 -3
View File
@@ -1643,7 +1643,7 @@ rrc_gNB_generate_RRCReestablishment(
ue_context->Srb0.Tx_buffer.payload_size); ue_context->Srb0.Tx_buffer.payload_size);
#if(0) #if(0)
/* TODO : It may be needed if gNB goes into full stack working. */ /* TODO : It may be needed if gNB goes into full stack working. */
UE_id = find_nr_UE_id(module_id, rnti); UE = find_nr_UE(module_id, rnti);
if (UE_id != -1) { if (UE_id != -1) {
/* Activate reject timer, if RRCComplete not received after 10 frames, reject UE */ /* Activate reject timer, if RRCComplete not received after 10 frames, reject UE */
RC.nrmac[module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1; RC.nrmac[module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1;
@@ -3549,6 +3549,7 @@ void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
FILE *fd=NULL;//fopen("nrRRCstats.log","w"); FILE *fd=NULL;//fopen("nrRRCstats.log","w");
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(RC.nrrrc[ctxt_pP->module_id]->rrc_ue_head)) { RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(RC.nrrrc[ctxt_pP->module_id]->rrc_ue_head)) {
ctxt_pP->rnti = ue_context_p->ue_id_rnti; ctxt_pP->rnti = ue_context_p->ue_id_rnti;
gNB_MAC_INST *nrmac=RC.nrmac[ctxt_pP->module_id]; //WHAT A BEAUTIFULL RACE CONDITION !!!
if (fd) { if (fd) {
if (ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence == TRUE) { if (ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence == TRUE) {
@@ -3588,7 +3589,7 @@ void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
// Remove here the MAC and RRC context when RRC is not connected or gNB is not connected to CN5G // Remove here the MAC and RRC context when RRC is not connected or gNB is not connected to CN5G
if(ue_context_p->ue_context.StatusRrc < NR_RRC_CONNECTED || ue_context_p->ue_context.gNB_ue_ngap_id == 0) { if(ue_context_p->ue_context.StatusRrc < NR_RRC_CONNECTED || ue_context_p->ue_context.gNB_ue_ngap_id == 0) {
mac_remove_nr_ue(ctxt_pP->module_id, ctxt_pP->rnti); mac_remove_nr_ue(nrmac, ctxt_pP->rnti);
rrc_rlc_remove_ue(ctxt_pP); rrc_rlc_remove_ue(ctxt_pP);
pdcp_remove_UE(ctxt_pP); pdcp_remove_UE(ctxt_pP);
@@ -3612,7 +3613,7 @@ void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
ue_context_p->ue_context.rnti); ue_context_p->ue_context.rnti);
ue_context_p->ue_context.ue_release_timer_rrc = 0; ue_context_p->ue_context.ue_release_timer_rrc = 0;
mac_remove_nr_ue(ctxt_pP->module_id, ctxt_pP->rnti); mac_remove_nr_ue(nrmac, ctxt_pP->rnti);
rrc_rlc_remove_ue(ctxt_pP); rrc_rlc_remove_ue(ctxt_pP);
pdcp_remove_UE(ctxt_pP); pdcp_remove_UE(ctxt_pP);
newGtpuDeleteAllTunnels(ctxt_pP->instance, ctxt_pP->rnti); newGtpuDeleteAllTunnels(ctxt_pP->instance, ctxt_pP->rnti);
+2 -1
View File
@@ -426,7 +426,8 @@ void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) {
rrc_rlc_remove_ue(&ctxt); rrc_rlc_remove_ue(&ctxt);
mac_remove_nr_ue(rrc->module_id, rnti); // WHAT A RACE CONDITION
mac_remove_nr_ue(RC.nrmac[rrc->module_id], rnti);
gtpv1u_enb_delete_tunnel_req_t tmp={0}; gtpv1u_enb_delete_tunnel_req_t tmp={0};
tmp.rnti=rnti; tmp.rnti=rnti;
tmp.from_gnb=1; tmp.from_gnb=1;
+4 -1
View File
@@ -109,11 +109,14 @@ typedef enum radio_type_e {
extern int opt_enabled; extern int opt_enabled;
#define trace_pdu(x...) if (opt_enabled) trace_pdu_implementation(0, x) #define trace_pdu(x...) if (opt_enabled) trace_pdu_implementation(0, x)
#define trace_NRpdu(x...) if (opt_enabled) trace_pdu_implementation(1, x) #define trace_NRpdu(x...) if (opt_enabled) nr_trace_pdu_implementation(1, x)
void trace_pdu_implementation(int nr, int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size, void trace_pdu_implementation(int nr, int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
int ueid, int rntiType, int rnti, uint16_t sysFrame, uint8_t subframe, int ueid, int rntiType, int rnti, uint16_t sysFrame, uint8_t subframe,
int oob_event, int oob_event_value); int oob_event, int oob_event_value);
void nr_trace_pdu_implementation(int nr, int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
int rntiType, int rnti, uint16_t sysFrame, uint8_t subframe,
int oob_event, int oob_event_value);
int init_opt(void); int init_opt(void);
+8
View File
@@ -476,6 +476,14 @@ static void SendFrameNR(guint8 radioType, guint8 direction, guint8 rntiType,
extern RAN_CONTEXT_t RC; extern RAN_CONTEXT_t RC;
#include <openair1/PHY/phy_extern_ue.h> #include <openair1/PHY/phy_extern_ue.h>
/* Remote serveraddress (where Wireshark is running) */ /* Remote serveraddress (where Wireshark is running) */
void nr_trace_pdu_implementation(int nr, int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
int rntiType, int rnti, uint16_t sysFrameNumber, uint8_t subFrameNumber, int oob_event,
int oob_event_value) {
trace_pdu_implementation(nr, direction, pdu_buffer, pdu_buffer_size,
rnti, rntiType, rnti, sysFrameNumber, subFrameNumber, oob_event,
oob_event_value);
}
void trace_pdu_implementation(int nr, int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size, void trace_pdu_implementation(int nr, int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
int ueid, int rntiType, int rnti, uint16_t sysFrameNumber, uint8_t subFrameNumber, int oob_event, int ueid, int rntiType, int rnti, uint16_t sysFrameNumber, uint8_t subFrameNumber, int oob_event,
int oob_event_value) { int oob_event_value) {