diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 33cb2b1b1d..bda19f252a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -1035,23 +1035,26 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, else { // this is the default PUCCH configuration, PUCCH format 0 or 1 LOG_D(NR_MAC,"pucch_acknak: Filling default PUCCH configuration from Tables (r_pucch %d, bwp %p)\n",r_pucch,bwp); int rsetindex = *scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->pucch_ResourceCommon; - int prboffset = r_pucch/default_pucch_csset[rsetindex]; - int prboffsetm8 = (r_pucch-8)/default_pucch_csset[rsetindex]; - pucch_pdu->prb_start = (r_pucch>>3)==0 ? - default_pucch_prboffset[rsetindex] + prboffset: - pucch_pdu->bwp_size-1-default_pucch_prboffset[rsetindex]-prboffsetm8; + int prb_start, second_hop_prb, nr_of_symb, start_symb; + set_r_pucch_parms(rsetindex, + r_pucch, + pucch_pdu->bwp_size, + &prb_start, + &second_hop_prb, + &nr_of_symb, + &start_symb); + + pucch_pdu->prb_start = prb_start; pucch_pdu->rnti = rnti; pucch_pdu->freq_hop_flag = 1; - pucch_pdu->second_hop_prb = (r_pucch>>3)==0? - pucch_pdu->bwp_size-1-default_pucch_prboffset[rsetindex]-prboffset: - default_pucch_prboffset[rsetindex] + prboffsetm8; + pucch_pdu->second_hop_prb = second_hop_prb; pucch_pdu->format_type = default_pucch_fmt[rsetindex]; pucch_pdu->initial_cyclic_shift = r_pucch%default_pucch_csset[rsetindex]; if (rsetindex==3||rsetindex==7||rsetindex==11) pucch_pdu->initial_cyclic_shift*=6; else if (rsetindex==1||rsetindex==2) pucch_pdu->initial_cyclic_shift*=3; else pucch_pdu->initial_cyclic_shift*=4; - pucch_pdu->nr_of_symbols = default_pucch_numbsymb[rsetindex]; - pucch_pdu->start_symbol_index = default_pucch_firstsymb[rsetindex]; + pucch_pdu->nr_of_symbols = nr_of_symb; + pucch_pdu->start_symbol_index = start_symb; if (pucch_pdu->format_type == 1) pucch_pdu->time_domain_occ_idx = 0; // check this!! pucch_pdu->sr_flag = O_sr; pucch_pdu->prb_size=1; @@ -1059,6 +1062,30 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, } +void set_r_pucch_parms(int rsetindex, + int r_pucch, + int bwp_size, + int *prb_start, + int *second_hop_prb, + int *nr_of_symbols, + int *start_symbol_index) { + + int prboffset = r_pucch/default_pucch_csset[rsetindex]; + int prboffsetm8 = (r_pucch-8)/default_pucch_csset[rsetindex]; + + *prb_start = (r_pucch>>3)==0 ? + default_pucch_prboffset[rsetindex] + prboffset: + bwp_size-1-default_pucch_prboffset[rsetindex]-prboffsetm8; + + *second_hop_prb = (r_pucch>>3)==0? + bwp_size-1-default_pucch_prboffset[rsetindex]-prboffset: + default_pucch_prboffset[rsetindex] + prboffsetm8; + + *nr_of_symbols = default_pucch_numbsymb[rsetindex]; + *start_symbol_index = default_pucch_firstsymb[rsetindex]; +} + + void prepare_dci(const NR_CellGroupConfig_t *CellGroup, dci_pdu_rel15_t *dci_pdu_rel15, nr_dci_format_t format, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index a94559769d..d0c2f16157 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -32,6 +32,7 @@ #include "NR_MAC_COMMON/nr_mac_extern.h" #include "NR_MAC_gNB/mac_proto.h" #include "common/ran_context.h" +#include "common/utils/nr/nr_common.h" #include "nfapi/oai_integration/vendor_ext.h" extern RAN_CONTEXT_t RC; @@ -539,16 +540,16 @@ void nr_csi_meas_reporting(int Mod_idP, switch(pucchres->format.present){ case NR_PUCCH_Resource__format_PR_format2: len = pucchres->format.choice.format2->nrofPRBs; - mask = ((1 << pucchres->format.choice.format2->nrofSymbols) - 1) << pucchres->format.choice.format2->startingSymbolIndex; + mask = SL_to_bitmap(pucchres->format.choice.format2->startingSymbolIndex, pucchres->format.choice.format2->nrofSymbols); curr_pucch->simultaneous_harqcsi = pucch_Config->format2->choice.setup->simultaneousHARQ_ACK_CSI; break; case NR_PUCCH_Resource__format_PR_format3: len = pucchres->format.choice.format3->nrofPRBs; - mask = ((1 << pucchres->format.choice.format3->nrofSymbols) - 1) << pucchres->format.choice.format3->startingSymbolIndex; + mask = SL_to_bitmap(pucchres->format.choice.format3->startingSymbolIndex, pucchres->format.choice.format3->nrofSymbols); curr_pucch->simultaneous_harqcsi = pucch_Config->format3->choice.setup->simultaneousHARQ_ACK_CSI; break; case NR_PUCCH_Resource__format_PR_format4: - mask = ((1 << pucchres->format.choice.format4->nrofSymbols) - 1) << pucchres->format.choice.format4->startingSymbolIndex; + mask = SL_to_bitmap(pucchres->format.choice.format4->startingSymbolIndex, pucchres->format.choice.format4->nrofSymbols); curr_pucch->simultaneous_harqcsi = pucch_Config->format4->choice.setup->simultaneousHARQ_ACK_CSI; break; default: @@ -556,7 +557,12 @@ void nr_csi_meas_reporting(int Mod_idP, } // verify resources are free for (int i = start; i < start + len; ++i) { - vrb_map_UL[i+bwp_start] |= mask; + if((vrb_map_UL[i+bwp_start] & mask) != 0) { + LOG_E(NR_MAC, "%s(): VRB MAP not free. Can't schedule CSI reporting on PUCCH.\n", __func__); + memset(curr_pucch, 0, sizeof(*curr_pucch)); + } + else + vrb_map_UL[i+bwp_start] |= mask; } } } @@ -1170,6 +1176,63 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, } } +bool test_acknack_vrb_occupation(NR_UE_sched_ctrl_t *sched_ctrl, + NR_sched_pucch_t *pucch, + uint16_t *vrb_map_UL, + const NR_ServingCellConfigCommon_t *scc, + NR_PUCCH_Config_t *pucch_Config, + int r_pucch, + int bwp_start, + int bwp_size) { + + // We assume initial cyclic shift is always 0 so different pucch resources can't overlap + + NR_sched_pucch_t *csi_pucch = &sched_ctrl->sched_pucch[1]; + if (csi_pucch && + csi_pucch->csi_bits > 0 && + csi_pucch->frame == pucch->frame && + csi_pucch->ul_slot == pucch->ul_slot && + csi_pucch->simultaneous_harqcsi && + (csi_pucch->csi_bits + csi_pucch->dai_c) < 11) + return true; // available resources for csi_pucch already verified + + int prb_start, second_hop_prb, nr_of_symb, start_symb; + if(r_pucch<0){ + const NR_PUCCH_Resource_t *resource = pucch_Config->resourceToAddModList->list.array[0]; + DevAssert(resource->format.present == NR_PUCCH_Resource__format_PR_format0); + second_hop_prb = resource->secondHopPRB!= NULL ? *resource->secondHopPRB : 0; + nr_of_symb = resource->format.choice.format0->nrofSymbols; + start_symb = resource->format.choice.format0->startingSymbolIndex; + prb_start = resource->startingPRB; + } + else{ + int rsetindex = *scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->pucch_ResourceCommon; + set_r_pucch_parms(rsetindex, + r_pucch, + bwp_size, + &prb_start, + &second_hop_prb, + &nr_of_symb, + &start_symb); + } + + // verifying occupation of PRBs for ACK/NACK on dedicated pucch + bool ret = true; + for (int l=0; lUE_info.UE_sched_ctrl[UE_id]; + + NR_PUCCH_Config_t *pucch_Config = NULL; + if (sched_ctrl->active_ubwp) { + pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup; + } else if (RC.nrmac[mod_id]->UE_info.CellGroup[UE_id] && + RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig && + RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated && + RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig && + RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP && + RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) { + pucch_Config = RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup; + } + NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? + &sched_ctrl->active_ubwp->bwp_Common->genericParameters: + &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; + int bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE); + int bwp_size = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[0]; LOG_D(NR_MAC,"pucch_acknak %d.%d Trying to allocate pucch, current DAI %d\n",frame,slot,pucch->dai_c); pucch->r_pucch=r_pucch; @@ -1321,21 +1402,32 @@ int nr_acknack_scheduling(int mod_id, int ind_found = -1; // while we are within the feedback limits while ((n_slots_frame + pucch->ul_slot - slot) % n_slots_frame <= max_fb_time) { - int i = 0; - while (i < 8) { - LOG_D(NR_MAC,"pdsch_to_harq_feedback[%d] = %d (pucch->ul_slot %d - slot %d)\n", - i,pdsch_to_harq_feedback[i],pucch->ul_slot,slot); - int diff = pucch->ul_slot - slot; - if (diff<0) - diff += n_slots_frame; - if (pdsch_to_harq_feedback[i] == diff) { - ind_found = i; - break; + // checking if in ul_slot the resources potentially to be assigned to this PUCCH are available + bool ret = test_acknack_vrb_occupation(sched_ctrl, + pucch, + &RC.nrmac[mod_id]->common_channels[CC_id].vrb_map_UL[pucch->ul_slot * MAX_BWP_SIZE], + scc, + pucch_Config, + r_pucch, + bwp_start, + bwp_size); + if (ret) { + int i = 0; + while (i < 8) { + LOG_D(NR_MAC,"pdsch_to_harq_feedback[%d] = %d (pucch->ul_slot %d - slot %d)\n", + i,pdsch_to_harq_feedback[i],pucch->ul_slot,slot); + int diff = pucch->ul_slot - slot; + if (diff<0) + diff += n_slots_frame; + if (pdsch_to_harq_feedback[i] == diff) { + ind_found = i; + break; + } + ++i; } - ++i; + if (ind_found!=-1) + break; } - if (ind_found!=-1) - break; // advance to the next ul slot const int f = pucch->frame; const int s = pucch->ul_slot; @@ -1396,45 +1488,36 @@ int nr_acknack_scheduling(int mod_id, pucch->dai_c++; pucch->resource_indicator = 0; // each UE has dedicated PUCCH resources pucch->r_pucch=r_pucch; - NR_PUCCH_Config_t *pucch_Config = NULL; - if (sched_ctrl->active_ubwp) { - pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup; - } else if (RC.nrmac[mod_id]->UE_info.CellGroup[UE_id] && - RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig && - RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated && - RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig && - RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP && - RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) { - pucch_Config = RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup; - } - NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? - &sched_ctrl->active_ubwp->bwp_Common->genericParameters: - &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; - int bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE); - - /* verify that at that slot and symbol, resources are free. We only do this - * for initialCyclicShift 0 (we assume it always has that one), so other - * initialCyclicShifts can overlap with ICS 0!*/ - if (pucch_Config) { + int prb_start, second_hop_prb, nr_of_symb, start_symb; + if(r_pucch<0){ const NR_PUCCH_Resource_t *resource = pucch_Config->resourceToAddModList->list.array[pucch->resource_indicator]; DevAssert(resource->format.present == NR_PUCCH_Resource__format_PR_format0); - int second_hop_prb = resource->secondHopPRB!= NULL ? *resource->secondHopPRB : 0; - int nr_of_symbols = resource->format.choice.format0->nrofSymbols; - if (resource->format.choice.format0->initialCyclicShift == 0) { - uint16_t *vrb_map_UL = &RC.nrmac[mod_id]->common_channels[CC_id].vrb_map_UL[pucch->ul_slot * MAX_BWP_SIZE]; - for (int l=0; lformat.choice.format0->startingSymbolIndex + l); - int prb; - if (l==1 && second_hop_prb != 0) - prb = second_hop_prb; - else - prb = resource->startingPRB; - if ((vrb_map_UL[bwp_start+prb] & symb) != 0) - LOG_W(MAC, "symbol 0x%x is not free for PUCCH alloc in vrb_map_UL at RB %ld and slot %d.%d\n", symb, resource->startingPRB, pucch->frame, pucch->ul_slot); - vrb_map_UL[bwp_start+prb] |= symb; - } - } + second_hop_prb = resource->secondHopPRB!= NULL ? *resource->secondHopPRB : 0; + nr_of_symb = resource->format.choice.format0->nrofSymbols; + start_symb = resource->format.choice.format0->startingSymbolIndex; + prb_start = resource->startingPRB; + } + else{ + int rsetindex = *scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->pucch_ResourceCommon; + set_r_pucch_parms(rsetindex, + r_pucch, + bwp_size, + &prb_start, + &second_hop_prb, + &nr_of_symb, + &start_symb); + } + + uint16_t *vrb_map_UL = &RC.nrmac[mod_id]->common_channels[CC_id].vrb_map_UL[pucch->ul_slot * MAX_BWP_SIZE]; + for (int l=0; l