diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 286b71ece3..d0a8f27a0f 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -751,7 +751,8 @@ static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE, } sampleShift = pbch_pdcch_processing(UE, proc, phy_data); - if (phy_data->dlsch[0].active && phy_data->dlsch[0].rnti_type == TYPE_C_RNTI_) { + if (phy_data->dlsch[0].active + && (phy_data->dlsch[0].rnti_type == TYPE_C_RNTI_ || phy_data->dlsch[0].rnti_type == TYPE_RA_RNTI_)) { // indicate to tx thread to wait for DLSCH decoding if (phy_data->dlsch[0].dlsch_config.k1_feedback) { // if feedback is 0 there is no HARQ associated with this DLSCH const int ack_nack_slot = (proc->nr_slot_rx + phy_data->dlsch[0].dlsch_config.k1_feedback) % fp->slots_per_frame; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 976a5f8d88..791f3e4631 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -847,7 +847,7 @@ static void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, } // DLSCH decoding finished! don't wait anymore in Tx process, we know if we should answer ACK/NACK PUCCH - if (dlsch[0].rnti_type == TYPE_C_RNTI_ && dlsch[0].dlsch_config.k1_feedback) { + if ((dlsch[0].rnti_type == TYPE_C_RNTI_ || dlsch[0].rnti_type == TYPE_RA_RNTI_) && dlsch[0].dlsch_config.k1_feedback) { const int ack_nack_slot_and_frame = (proc->nr_slot_rx + dlsch[0].dlsch_config.k1_feedback) + proc->frame_rx * ue->frame_parms.slots_per_frame; dynamic_barrier_join(&ue->process_slot_tx_barriers[ack_nack_slot_and_frame % NUM_PROCESS_SLOT_TX_BARRIERS]); diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 594992c1cb..b435e9e265 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -368,8 +368,7 @@ NR_tda_info_t get_ul_tda_info(const NR_UE_UL_BWP_t *ul_bwp, NR_PUSCH_TimeDomainResourceAllocationList_t *tdalist = get_ul_tdalist(ul_bwp, controlResourceSetId, ss_type, rnti_type); // Definition of value j in Table 6.1.2.1.1-4 of 38.214 int scs = ul_bwp->scs; - AssertFatal(scs >= 0 && scs < 5, "Subcarrier spacing indicatior %d invalid value\n", scs); - int j = scs == 0 ? 1 : scs; + int j = get_j_for_k2(scs); if (tdalist) { tda_info.valid_tda = tda_index < tdalist->list.count; if (!tda_info.valid_tda) { @@ -5129,3 +5128,19 @@ int nr_get_prach_or_ul_mu(const NR_MsgA_ConfigCommon_r16_t *msgacc, return mu; } + +int get_delta_for_k2(int mu) +{ + // 38.214 Table 6.1.2.1.1-5: Definition of value Δ + int delta_table[] = {2, 3, 4, 6, 24, 48}; + AssertFatal(mu >= 0 && mu < sizeofArray(delta_table), "Invalid numerology %d\n", mu); + return delta_table[mu]; +} + +int get_j_for_k2(int mu) +{ + // 38.214 Table 6.1.2.1.1-4: Definition of value j + int j_table[] = {1, 1, 2, 3, 11, 21}; + AssertFatal(mu >= 0 && mu < sizeofArray(j_table), "Invalid numerology %d\n", mu); + return j_table[mu]; +} diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index 2607d8f587..84284f0c48 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -318,4 +318,8 @@ int get_nrofHARQ_ProcessesForPUSCH(const NR_UE_ServingCell_Info_t *sc_info); int nr_get_prach_or_ul_mu(const NR_MsgA_ConfigCommon_r16_t *msgacc, const NR_RACH_ConfigCommon_t *rach_ConfigCommon, const int ul_mu); +int get_delta_for_k2(int mu); + +int get_j_for_k2(int mu); + #endif diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index b6728df0dc..5d3102c07d 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -933,6 +933,15 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac, const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, dlsch_pdu->SubcarrierSpacing); uint16_t feedback_ti = 0; + if (rnti_type == TYPE_RA_RNTI_) { + // RA-RNTI indicates RAR. Ensure we can decode RAR before the earliest UL scheduler call + // that can process the MSG3. Also assume that RAR is sent in the same slot as DCI (k0 == 0) + // This is not perfect as the MSG3 might end up being scheduled later, so we could be + // halting the UL scheduler for a longer time than necessary. + feedback_ti = max(1 + GET_DURATION_RX_TO_TX(&mac->ntn_ta, dlsch_pdu->SubcarrierSpacing), + get_delta_for_k2(mac->current_UL_BWP->scs) + get_j_for_k2(mac->current_UL_BWP->scs)); + } + if (rnti_type != TYPE_RA_RNTI_ && rnti_type != TYPE_SI_RNTI_) { if (!get_FeedbackDisabled(mac->sc_info.downlinkHARQ_FeedbackDisabled_r17, dci->harq_pid.val)) { feedback_ti = 1 + dci->pdsch_to_harq_feedback_timing_indicator.val + ntn_ue_koffset; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 7a44b0cf73..1922a3420e 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1547,22 +1547,7 @@ int nr_ue_pusch_scheduler(const NR_UE_MAC_INST_t *mac, if (is_Msg3) { - switch (mu) { - case 0: - delta = 2; - break; - case 1: - delta = 3; - break; - case 2: - delta = 4; - break; - case 3: - delta = 6; - break; - default: - AssertFatal(1 == 0, "Invalid numerology %i\n", mu); - } + delta = get_delta_for_k2(mu); AssertFatal((k2 + delta) > GET_DURATION_RX_TO_TX(&mac->ntn_ta, mu), "Slot offset (%ld) for Msg3 needs to be higher than DURATION_RX_TO_TX (%ld). Please set min_rxtxtime at least to " diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 63700d2a72..e67a30e67a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -58,8 +58,6 @@ static void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, int fh); static void nr_fill_rar(uint8_t Mod_idP, NR_UE_info_t *UE, uint8_t *dlsch_buffer, nfapi_nr_pusch_pdu_t *pusch_pdu); -static const uint8_t DELTA[4] = {2, 3, 4, 6}; - static const float ssb_per_rach_occasion[8] = {0.125, 0.25, 0.5, 1, 2, 4, 8}; static int16_t ssb_index_from_prach(module_id_t module_idP, @@ -1566,7 +1564,7 @@ static void nr_generate_Msg2(module_id_t module_idP, const NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; bool ret = get_feasible_msg3_tda(scc, - DELTA[ul_bwp->scs], + get_delta_for_k2(ul_bwp->scs), ul_bwp->tdaList_Common, frameP, slotP, diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c index fe4b138f49..22c2207be1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c @@ -1057,7 +1057,6 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay) AssertFatal(tda->list.count == 0, "already have pusch_TimeDomainAllocationList members\n"); const int k2 = min_fb_delay; - uint8_t DELTA[4]= {2,3,4,6}; // Delta parameter for Msg3 int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; struct NR_SetupRelease_PUSCH_ConfigCommon *pusch_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon; @@ -1090,7 +1089,7 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay) int tdd_period_idx = get_tdd_period_idx(scc->tdd_UL_DL_ConfigurationCommon); int nb_periods_per_frame = get_nb_periods_per_frame(tdd_period_idx); int nb_slots_per_period = ((1 << mu) * 10) / nb_periods_per_frame; - int k2_msg3 = nb_slots_per_period - DELTA[mu]; + int k2_msg3 = nb_slots_per_period - get_delta_for_k2(mu); struct NR_PUSCH_TimeDomainResourceAllocation *puschTdrAllocMsg3 = set_TimeDomainResourceAllocation(k2_msg3, 3, ul_symb); if (*puschTdrAllocMsg3->k2 < min_fb_delay) *puschTdrAllocMsg3->k2 += nb_slots_per_period;