From ccba7c875df082c924f65a65c5b8ec2996d5d624 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Tue, 7 May 2024 18:00:53 +0200 Subject: [PATCH] gNB: add NTN specific parameter cellSpecificKoffset_r17 and use it for UL scheduling According to the RRC specification, cellSpecificKoffset is: Scheduling offset used for the timing relationships that are modified for NTN (see TS 38.213 [13]). The unit of the field K_offset is number of slots for a given subcarrier spacing of 15 kHz. If the field is absent UE assumes value 0 This parameter `cellSpecificKoffset_r17` can be set in the gNB conf file, in the section `servingCellConfigCommon` --- openair2/GNB_APP/RRC_nr_paramsvalues.h | 2 ++ openair2/GNB_APP/gnb_config.c | 12 +++++++++- openair2/LAYER2/NR_MAC_gNB/config.c | 22 +++++++++++++---- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c | 2 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 16 ++++++++----- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 4 ++-- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 24 +++++++------------ .../LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c | 9 ++++--- .../LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 23 +++++++++++------- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 24 ++++++++++--------- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 6 +++-- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 2 +- 12 files changed, 90 insertions(+), 56 deletions(-) diff --git a/openair2/GNB_APP/RRC_nr_paramsvalues.h b/openair2/GNB_APP/RRC_nr_paramsvalues.h index 14e8cb13de..16a5939fc5 100644 --- a/openair2/GNB_APP/RRC_nr_paramsvalues.h +++ b/openair2/GNB_APP/RRC_nr_paramsvalues.h @@ -109,6 +109,7 @@ #define GNB_CONFIG_STRING_NROFUPLINKSYMBOLS2 "nrofUplinkSymbols2" #define GNB_CONFIG_STRING_SSPBCHBLOCKPOWER "ssPBCH_BlockPower" +#define GNB_CONFIG_STRING_CELLSPECIFICKOFFSET "cellSpecificKoffset_r17" #define CARRIERBANDWIDTH_OKVALUES {11,18,24,25,31,32,38,51,52,65,66,78,79,93,106,107,121,132,133,135,160,162,189,216,217,245,264,270,273} @@ -232,6 +233,7 @@ {GNB_CONFIG_STRING_NROFUPLINKSLOTS2,NULL,0,.i64ptr=&scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofUplinkSlots,.defint64val=-1,TYPE_INT64,0},\ {GNB_CONFIG_STRING_NROFUPLINKSYMBOLS2,NULL,0,.i64ptr=&scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofUplinkSymbols,.defint64val=-1,TYPE_INT64,0},\ {GNB_CONFIG_STRING_SSPBCHBLOCKPOWER,NULL,0,.i64ptr=&scc->ss_PBCH_BlockPower,.defint64val=20,TYPE_INT64,0}, \ +{GNB_CONFIG_STRING_CELLSPECIFICKOFFSET,NULL,0,.i64ptr=scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17,.defint64val=0,TYPE_INT64,0}, \ {GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING,NULL,0,.i64ptr=scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing,.defintval=-1,TYPE_INT64,0}} /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index e4e93c36a2..b0a49e02fb 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -279,7 +279,10 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) { //ratematchpattern->patternType.choice.bitmaps->periodicityAndPattern->choice.n40.buf = MALLOC(5); //ratematchpattern->subcarrierSpacing = CALLOC(1,sizeof(NR_SubcarrierSpacing_t)); //ratematchpatternid = CALLOC(1,sizeof(NR_RateMatchPatternId_t)); - + + scc->ext2 = CALLOC(1, sizeof(*scc->ext2)); + scc->ext2->ntn_Config_r17 = CALLOC(1, sizeof(*scc->ext2->ntn_Config_r17)); + scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17 = CALLOC(1, sizeof(*scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17)); } void fill_scc_sim(NR_ServingCellConfigCommon_t *scc,uint64_t *ssb_bitmap,int N_RB_DL,int N_RB_UL,int mu_dl,int mu_ul) { @@ -471,6 +474,13 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap) { // check pucch_ResourceConfig AssertFatal(*scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->pucch_ResourceCommon < 2, "pucch_ResourceConfig should be 0 or 1 for now\n"); + + if(*scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17 == 0) { + free(scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17); + free(scc->ext2->ntn_Config_r17); + free(scc->ext2); + scc->ext2 = NULL; + } } /* Function to allocate dedicated serving cell config strutures */ diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index e313cdb190..e4fbfa6a4b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -97,6 +97,13 @@ void get_K1_K2(int N1, int N2, int *K1, int *K2, int layers) } } +int get_NTN_Koffset(const NR_ServingCellConfigCommon_t *scc) +{ + if (scc->ext2 && scc->ext2->ntn_Config_r17 && scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17) + return *scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17 << *scc->ssbSubcarrierSpacing; + return 0; +} + int precoding_weigths_generation(nfapi_nr_pm_list_t *mat, int pmiq, int L, @@ -602,14 +609,19 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, c "SSB Bitmap type %d is not valid\n", scc->ssb_PositionsInBurst->present); - int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; - if (*scc->ssbSubcarrierSpacing == 0) - n <<= 1; // to have enough room for feedback possibly beyond the frame we need a larger array at 15kHz SCS - nrmac->common_channels[0].vrb_map_UL = calloc(n * MAX_BWP_SIZE, sizeof(uint16_t)); - nrmac->vrb_map_UL_size = n; + const int NTN_gNB_Koffset = get_NTN_Koffset(scc); + const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; + const int size = n << (int)ceil(log2((NTN_gNB_Koffset + 13) / n + 1)); // 13 is upper limit for max_fb_time + + nrmac->vrb_map_UL_size = size; + nrmac->common_channels[0].vrb_map_UL = calloc(size * MAX_BWP_SIZE, sizeof(uint16_t)); AssertFatal(nrmac->common_channels[0].vrb_map_UL, "could not allocate memory for RC.nrmac[]->common_channels[0].vrb_map_UL\n"); + nrmac->UL_tti_req_ahead_size = size; + nrmac->UL_tti_req_ahead[0] = calloc(size, sizeof(nfapi_nr_ul_tti_request_t)); + AssertFatal(nrmac->UL_tti_req_ahead[0], "could not allocate memory for nrmac->UL_tti_req_ahead[0]\n"); + LOG_I(NR_MAC, "Configuring common parameters from NR ServingCellConfig\n"); config_common(nrmac, config->pdsch_AntennaPorts, config->pusch_AntennaPorts, scc); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 34a372247c..dbd64f524e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -68,7 +68,7 @@ void clear_nr_nfapi_information(gNB_MAC_INST *gNB, NR_ServingCellConfigCommon_t *scc = gNB->common_channels->ServingCellConfigCommon; const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; - UL_tti_req_ahead_initialization(gNB, scc, num_slots, CC_idP, frameP, slotP, *scc->ssbSubcarrierSpacing); + UL_tti_req_ahead_initialization(gNB, num_slots, CC_idP, frameP, slotP); nfapi_nr_dl_tti_pdcch_pdu_rel15_t **pdcch = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t **)gNB->pdcch_pdu_idx[CC_idP]; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 7507207ac8..1955d50dbb 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -580,8 +580,8 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = ul_bwp->tdaList_Common; int mu = ul_bwp->scs; - uint8_t K2 = *pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2; - const int sched_frame = (frame + (slot + K2 >= nr_slots_per_frame[mu])) % 1024; + uint16_t K2 = *pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2 + get_NTN_Koffset(scc); + const int sched_frame = (frame + (slot + K2) / nr_slots_per_frame[mu]) % MAX_FRAME_NUMBER; const int sched_slot = (slot + K2) % nr_slots_per_frame[mu]; if (is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot)) { @@ -747,6 +747,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, } static int get_feasible_msg3_tda(frame_type_t frame_type, + const NR_ServingCellConfigCommon_t *scc, int mu_delta, uint64_t ulsch_slot_bitmap[3], const NR_PUSCH_TimeDomainResourceAllocationList_t *tda_list, @@ -761,12 +762,14 @@ static int get_feasible_msg3_tda(frame_type_t frame_type, return tda; } + const int NTN_gNB_Koffset = get_NTN_Koffset(scc); + // TDD DevAssert(tdd != NULL); uint8_t tdd_period_slot = slots_per_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity); for (int i = 0; i < tda_list->list.count; i++) { // check if it is UL - long k2 = *tda_list->list.array[i]->k2; + long k2 = *tda_list->list.array[i]->k2 + NTN_gNB_Koffset; int temp_slot = (slot + k2 + mu_delta) % slots_per_frame; // msg3 slot according to 8.3 in 38.213 if (!is_xlsch_in_slot(ulsch_slot_bitmap[temp_slot / 64], temp_slot)) continue; @@ -820,10 +823,10 @@ static void nr_get_Msg3alloc(module_id_t module_id, int startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength; SLIV2SL(startSymbolAndLength, &ra->msg3_startsymb, &ra->msg3_nbSymb); - long k2 = *pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2; + long k2 = *pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2 + get_NTN_Koffset(scc); int abs_slot = current_slot + k2 + DELTA[mu]; ra->Msg3_slot = abs_slot % n_slots_frame; - ra->Msg3_frame = (current_frame + (abs_slot / n_slots_frame)) % 1024; + ra->Msg3_frame = (current_frame + (abs_slot / n_slots_frame)) % MAX_FRAME_NUMBER; LOG_I(NR_MAC, "UE %04x: Msg3 scheduled at %d.%d (%d.%d k2 %ld TDA %u)\n", @@ -1224,6 +1227,7 @@ static void nr_generate_Msg2(module_id_t module_idP, } ra->Msg3_tda_id = get_feasible_msg3_tda(cc->frame_type, + scc, DELTA[ul_bwp->scs], nr_mac->ulsch_slot_bitmap, ul_bwp->tdaList_Common, @@ -1464,7 +1468,7 @@ static void nr_generate_Msg2(module_id_t module_idP, start_ra_contention_resolution_timer( ra, scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ra_ContentionResolutionTimer, - *ra->UL_BWP.tdaList_Common->list.array[ra->Msg3_tda_id]->k2, + *ra->UL_BWP.tdaList_Common->list.array[ra->Msg3_tda_id]->k2 + get_NTN_Koffset(scc), ra->UL_BWP.scs); if (ra->cfra) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 3eb9a9ce7b..16a975dc6e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -227,8 +227,8 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ "time domain assignment %d >= %d\n", temp_tda, tdaList->list.count); - int K2 = get_K2(tdaList, temp_tda, mu); - const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]); + int K2 = get_K2(tdaList, temp_tda, mu, scc); + const int sched_frame = frame + (slot + K2) / nr_slots_per_frame[mu]; const int sched_slot = (slot + K2) % nr_slots_per_frame[mu]; const int tda = get_ul_tda(nr_mac, scc, sched_frame, sched_slot); if (tda < 0) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 1aeba91026..8ae9c3dcc5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2546,15 +2546,16 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf void set_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl, const NR_UE_UL_BWP_t *ul_bwp, - const NR_ServingCellConfigCommon_t *scc) { - + const NR_ServingCellConfigCommon_t *scc) +{ + const int NTN_gNB_Koffset = get_NTN_Koffset(scc); const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs]; const int nr_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame; const int n_ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0 ? 1 : 0) : n_slots_frame; // PUCCH list size is given by the number of UL slots in the PUCCH period // the length PUCCH period is determined by max_fb_time since we may need to prepare PUCCH for ACK/NACK max_fb_time slots ahead - const int list_size = n_ul_slots_period << (ul_bwp->max_fb_time/nr_slots_period); + const int list_size = n_ul_slots_period << (int)ceil(log2((ul_bwp->max_fb_time + NTN_gNB_Koffset) / nr_slots_period + 1)); if(!sched_ctrl->sched_pucch) { sched_ctrl->sched_pucch = calloc(list_size, sizeof(*sched_ctrl->sched_pucch)); sched_ctrl->sched_pucch_size = list_size; @@ -3075,26 +3076,19 @@ int ul_buffer_index(int frame, int slot, int scs, int size) return abs_slot % size; } -void UL_tti_req_ahead_initialization(gNB_MAC_INST * gNB, NR_ServingCellConfigCommon_t *scc, int n, int CCid, frame_t frameP, int slotP, int scs) +void UL_tti_req_ahead_initialization(gNB_MAC_INST *gNB, int n, int CCid, frame_t frameP, int slotP) { - if(gNB->UL_tti_req_ahead[CCid]) + if(gNB->UL_tti_req_ahead[CCid][1].Slot == 1) return; - int size = n; - if (scs == 0) - size <<= 1; // to have enough room for feedback possibly beyond the frame we need a larger array at 15kHz SCS - - gNB->UL_tti_req_ahead_size = size; - gNB->UL_tti_req_ahead[CCid] = calloc(size, sizeof(nfapi_nr_ul_tti_request_t)); - AssertFatal(gNB->UL_tti_req_ahead[CCid], "could not allocate memory for RC.nrmac[]->UL_tti_req_ahead[]\n"); /* fill in slot/frame numbers: slot is fixed, frame will be updated by scheduler * consider that scheduler runs sl_ahead: the first sl_ahead slots are * already "in the past" and thus we put frame 1 instead of 0! */ - for (int i = 0; i < size; ++i) { + for (int i = 0; i < gNB->UL_tti_req_ahead_size; ++i) { int abs_slot = frameP * n + slotP + i; - nfapi_nr_ul_tti_request_t *req = &gNB->UL_tti_req_ahead[CCid][abs_slot % size]; - req->SFN = abs_slot / n; + nfapi_nr_ul_tti_request_t *req = &gNB->UL_tti_req_ahead[CCid][abs_slot % gNB->UL_tti_req_ahead_size]; + req->SFN = (abs_slot / n) % MAX_FRAME_NUMBER; req->Slot = abs_slot % n; } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c index 2e5fb0c7a1..b4492ffa44 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c @@ -512,8 +512,11 @@ static void nr_fill_nfapi_srs(int module_id, *********************************************************************/ void nr_schedule_srs(int module_id, frame_t frame, int slot) { - /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */ + const int CC_id = 0; gNB_MAC_INST *nrmac = RC.nrmac[module_id]; + const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon; + + /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */ NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock); NR_UEs_t *UE_info = &nrmac->UE_info; @@ -571,14 +574,14 @@ void nr_schedule_srs(int module_id, frame_t frame, int slot) int max_k2 = 0; // avoid last one in the list (for msg3) for (int i = 0; i < num_tda - 1; i++) { - int k2 = get_K2(tdaList, i, current_BWP->scs); + int k2 = get_K2(tdaList, i, current_BWP->scs, scc); max_k2 = k2 > max_k2 ? k2 : max_k2; } // we are sheduling SRS max_k2 slot in advance for the presence of SRS to be taken into account when scheduling PUSCH const int n_slots_frame = nr_slots_per_frame[current_BWP->scs]; const int sched_slot = (slot + max_k2) % n_slots_frame; - const int sched_frame = (frame + ((slot + max_k2) / n_slots_frame)) % 1024; + const int sched_frame = (frame + (slot + max_k2) / n_slots_frame) % MAX_FRAME_NUMBER; const uint16_t period = srs_period[srs_resource->resourceType.choice.periodic->periodicityAndOffset_p.present]; const uint16_t offset = get_nr_srs_offset(srs_resource->resourceType.choice.periodic->periodicityAndOffset_p); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index ac067044eb..af657a399f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -211,8 +211,12 @@ void nr_csi_meas_reporting(int Mod_idP, frame_t frame, sub_frame_t slot) { - /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */ + const int CC_id = 0; gNB_MAC_INST *nrmac = RC.nrmac[Mod_idP]; + const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon; + const int NTN_gNB_Koffset = get_NTN_Koffset(scc); + + /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */ NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock); UE_iterator(nrmac->UE_info.list, UE ) { @@ -242,8 +246,8 @@ void nr_csi_meas_reporting(int Mod_idP, // we schedule CSI reporting max_fb_time slots in advance int period, offset; csi_period_offset(csirep, NULL, &period, &offset); - const int sched_slot = (slot + ul_bwp->max_fb_time) % n_slots_frame; - const int sched_frame = (frame + ((slot + ul_bwp->max_fb_time) / n_slots_frame)) % 1024; + const int sched_slot = (slot + ul_bwp->max_fb_time + NTN_gNB_Koffset) % n_slots_frame; + const int sched_frame = (frame + ((slot + ul_bwp->max_fb_time + NTN_gNB_Koffset) / n_slots_frame)) % MAX_FRAME_NUMBER; // prepare to schedule csi measurement reception according to 5.2.1.4 in 38.214 if ((sched_frame * n_slots_frame + sched_slot - offset) % period != 0) continue; @@ -260,7 +264,6 @@ void nr_csi_meas_reporting(int Mod_idP, AssertFatal(res_index < n, "CSI pucch resource %ld not found among PUCCH resources\n", pucchcsires->pucch_Resource); - const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[0].ServingCellConfigCommon; const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; AssertFatal(tdd || nrmac->common_channels[0].frame_type == FDD, "Dynamic TDD not handled yet\n"); const int pucch_index = get_pucch_index(sched_frame, sched_slot, n_slots_frame, tdd, sched_ctrl->sched_pucch_size); @@ -1237,8 +1240,10 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac, * called often, don't try to lock every time */ const int CC_id = 0; - const int minfbtime = mac->radio_config.minRXTXTIME; const NR_ServingCellConfigCommon_t *scc = mac->common_channels[CC_id].ServingCellConfigCommon; + const int NTN_gNB_Koffset = get_NTN_Koffset(scc); + + const int minfbtime = mac->radio_config.minRXTXTIME + NTN_gNB_Koffset; const NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs]; const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; @@ -1261,13 +1266,13 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac, for (int f = 0; f < fb_size; f++) { // can't schedule ACKNACK before minimum feedback time - if(pdsch_to_harq_feedback[f] < minfbtime) + if((pdsch_to_harq_feedback[f] + NTN_gNB_Koffset) < minfbtime) continue; - const int pucch_slot = (slot + pdsch_to_harq_feedback[f]) % n_slots_frame; + const int pucch_slot = (slot + pdsch_to_harq_feedback[f] + NTN_gNB_Koffset) % n_slots_frame; // check if the slot is UL if(pucch_slot%nr_slots_period < first_ul_slot_period) continue; - const int pucch_frame = (frame + ((slot + pdsch_to_harq_feedback[f]) / n_slots_frame)) & 1023; + const int pucch_frame = (frame + ((slot + pdsch_to_harq_feedback[f] + NTN_gNB_Koffset) / n_slots_frame)) % MAX_FRAME_NUMBER; // we store PUCCH resources according to slot, TDD configuration and size of the vector containing PUCCH structures const int pucch_index = get_pucch_index(pucch_frame, pucch_slot, n_slots_frame, tdd, sched_ctrl->sched_pucch_size); NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[pucch_index]; @@ -1346,7 +1351,7 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac, return pucch_index; // index of current PUCCH structure } } - LOG_D(NR_MAC, "DL %4d.%2d, Couldn't find scheduling occasion for this HARQ process\n", frame, slot); + LOG_W(NR_MAC, "DL %4d.%2d, Couldn't find scheduling occasion for this HARQ process\n", frame, slot); return -1; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index fec34b753f..1d1a8afab9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -1408,19 +1408,21 @@ void handle_nr_srs_measurements(const module_id_t module_id, long get_K2(NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList, int time_domain_assignment, - int mu) { - + int mu, + const NR_ServingCellConfigCommon_t *scc) +{ /* we assume that this function is mutex-protected from outside */ NR_PUSCH_TimeDomainResourceAllocation_t *tda = tdaList->list.array[time_domain_assignment]; + const int NTN_gNB_Koffset = get_NTN_Koffset(scc); if (tda->k2) - return *tda->k2; + return *tda->k2 + NTN_gNB_Koffset; else if (mu < 2) - return 1; + return 1 + NTN_gNB_Koffset; else if (mu == 2) - return 2; + return 2 + NTN_gNB_Koffset; else - return 3; + return 3 + NTN_gNB_Koffset; } 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) @@ -2059,13 +2061,13 @@ static bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_ sched_ctrl->coreset->controlResourceSetId, sched_ctrl->search_space->searchSpaceType->present, TYPE_C_RNTI_); - int K2 = get_K2(tdaList, temp_tda, mu); - const int sched_frame = (frame + (slot + K2 >= nr_slots_per_frame[mu])) & 1023; + int K2 = get_K2(tdaList, temp_tda, mu, scc); + const int sched_frame = (frame + (slot + K2) / nr_slots_per_frame[mu]) % MAX_FRAME_NUMBER; const int sched_slot = (slot + K2) % nr_slots_per_frame[mu]; const int tda = get_ul_tda(nr_mac, scc, sched_frame, sched_slot); if (tda < 0) return false; - DevAssert(K2 == get_K2(tdaList, tda, mu)); + DevAssert(K2 == get_K2(tdaList, tda, mu, scc)); if (!is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot)) return false; @@ -2074,9 +2076,9 @@ static bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_ sched_ctrl->sched_pusch.frame = sched_frame; UE_iterator(nr_mac->UE_info.list, UE2) { NR_UE_sched_ctrl_t *sched_ctrl = &UE2->UE_sched_ctrl; - AssertFatal(K2 == get_K2(tdaList, tda, mu), + AssertFatal(K2 == get_K2(tdaList, tda, mu, scc), "Different K2, %d(UE%d) != %ld(UE%04x)\n", - K2, 0, get_K2(tdaList, tda, mu), UE2->rnti); + K2, 0, get_K2(tdaList, tda, mu, scc), UE2->rnti); sched_ctrl->sched_pusch.slot = sched_slot; sched_ctrl->sched_pusch.frame = sched_frame; } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 0fc1071c5f..a23e588a49 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -37,6 +37,7 @@ void set_cset_offset(uint16_t); void get_K1_K2(int N1, int N2, int *K1, int *K2, int layers); +int get_NTN_Koffset(const NR_ServingCellConfigCommon_t *scc); void mac_top_init_gNB(ngran_node_t node_type, NR_ServingCellConfigCommon_t *scc, @@ -264,7 +265,8 @@ NR_SearchSpace_t *get_searchspace(NR_ServingCellConfigCommon_t *scc, long get_K2(NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList, int time_domain_assignment, - int mu); + int mu, + const NR_ServingCellConfigCommon_t *scc); const NR_DMRS_UplinkConfig_t *get_DMRS_UplinkConfig(const NR_PUSCH_Config_t *pusch_Config, const NR_tda_info_t *tda_info); @@ -418,7 +420,7 @@ int get_mcs_from_bler(const NR_bler_options_t *bler_options, int ul_buffer_index(int frame, int slot, int scs, int size); -void UL_tti_req_ahead_initialization(gNB_MAC_INST * gNB, NR_ServingCellConfigCommon_t *scc, int n, int CCid, frame_t frameP, int slotP, int scs); +void UL_tti_req_ahead_initialization(gNB_MAC_INST *gNB, int n, int CCid, frame_t frameP, int slotP); void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t frameP, sub_frame_t slotP); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index eeeff6543c..48e25e794b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -421,7 +421,7 @@ typedef struct NR_sched_pdsch { int8_t dl_harq_pid; // pucch format allocation - uint8_t pucch_allocation; + uint16_t pucch_allocation; uint16_t pm_index; uint8_t nrOfLayers;