diff --git a/common/utils/oai_asn1.h b/common/utils/oai_asn1.h index cc8392b0cf..573fa94d75 100644 --- a/common/utils/oai_asn1.h +++ b/common/utils/oai_asn1.h @@ -34,7 +34,7 @@ TYPE *tmp = ORIGIN; \ ORIGIN = DESTINATION; \ DESTINATION = tmp; \ - } while(0); \ + } while (0) \ // Same as above but swapping ASN1 elements that are not pointers #define UPDATE_NP_IE(DESTINATION, ORIGIN, TYPE) \ @@ -42,7 +42,7 @@ TYPE tmp = ORIGIN; \ ORIGIN = DESTINATION; \ DESTINATION = tmp; \ - } while(0); \ + } while (0) \ // Macro handles reception of SetupRelease element ORIGIN (see NR_SetupRelease.h) // If release (NR_SetupRelease_xxx_PR_release equivalent to 1), removing structure from DESTINATION @@ -55,7 +55,7 @@ } \ if (ORIGIN->present == 2) \ UPDATE_IE(DESTINATION, ORIGIN->choice.setup, TYPE); \ - } while(0); \ + } while (0) \ // Macro handles reception of SetupRelease element ORIGIN (see NR_SetupRelease.h) // If release (NR_SetupRelease_xxx_PR_release equivalent to 1), removing structure from DESTINATION @@ -72,7 +72,7 @@ DESTINATION->present = ORIGIN->present; \ UPDATE_IE(DESTINATION->choice.setup, ORIGIN->choice.setup, TYPE); \ } \ - } while(0); \ + } while (0) \ // Macro releases entries in list TARGET if the corresponding ID is found in list SOURCE. // Prints an error if ID not found in list. diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md index 9ee9083e6d..b1b5090ae7 100644 --- a/doc/RUNMODEM.md +++ b/doc/RUNMODEM.md @@ -182,6 +182,20 @@ Besides this, some timers, e.g. `sr_ProhibitTimer_v1700`, `t300`, `t301` and `t3 ... ``` +To improve the achievable UL and DL throughput in conditions with large RTT, there is a feature defined in REL17 to disable HARQ feedback. +This allows to reuse HARQ processes immediately, but it breaks compatibility with UEs not supporting this REL17 feature. +To enable this feature, the `disable_harq` flag has to be added to the gNB conf file in the section `gNBs.[0]` +``` +... + sib1_tda = 5; + min_rxtxtime = 6; + disable_harq = 1; // <-- + + servingCellConfigCommon = ( + { +... +``` + So with these modifications to the file `targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf` an example gNB command for FDD, 5 MHz BW, 15 kHz SCS, GEO satellite 5G NR NTN is this: ``` cd cmake_targets diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index df4cdf1afa..9d9de98f8b 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -1260,13 +1260,17 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) config.force_UL256qam_off = *GNBParamList.paramarray[0][GNB_FORCEUL256QAMOFF_IDX].iptr; config.use_deltaMCS = *GNBParamList.paramarray[0][GNB_USE_DELTA_MCS_IDX].iptr != 0; config.maxMIMO_layers = *GNBParamList.paramarray[0][GNB_MAXMIMOLAYERS_IDX].iptr; + config.disable_harq = *GNBParamList.paramarray[0][GNB_DISABLE_HARQ_IDX].iptr; + if (config.disable_harq) + LOG_W(GNB_APP, "\"disable_harq\" is a REL17 feature and is incompatible with REL15 and REL16 UEs!\n"); LOG_I(GNB_APP, - "CSI-RS %d, SRS %d, 256 QAM %s, delta_MCS %s, maxMIMO_Layers %d\n", + "CSI-RS %d, SRS %d, 256 QAM %s, delta_MCS %s, maxMIMO_Layers %d, HARQ feedback %s\n", config.do_CSIRS, config.do_SRS, config.force_256qam_off ? "force off" : "may be on", config.use_deltaMCS ? "on" : "off", - config.maxMIMO_layers); + config.maxMIMO_layers, + config.disable_harq ? "disabled" : "enabled"); int tot_ant = config.pdsch_AntennaPorts.N1 * config.pdsch_AntennaPorts.N2 * config.pdsch_AntennaPorts.XP; AssertFatal(config.maxMIMO_layers != 0 && config.maxMIMO_layers <= tot_ant, "Invalid maxMIMO_layers %d\n", config.maxMIMO_layers); @@ -1373,12 +1377,18 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) dl_bler_options->upper = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_UPPER_IDX].dblptr); dl_bler_options->lower = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_LOWER_IDX].dblptr); dl_bler_options->max_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_MAX_MCS_IDX].u8ptr); - dl_bler_options->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_HARQ_ROUND_MAX_IDX].u8ptr); + if (config.disable_harq) + dl_bler_options->harq_round_max = 1; + else + dl_bler_options->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_HARQ_ROUND_MAX_IDX].u8ptr); NR_bler_options_t *ul_bler_options = &RC.nrmac[j]->ul_bler; ul_bler_options->upper = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_BLER_TARGET_UPPER_IDX].dblptr); ul_bler_options->lower = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_BLER_TARGET_LOWER_IDX].dblptr); ul_bler_options->max_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_MAX_MCS_IDX].u8ptr); - ul_bler_options->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_HARQ_ROUND_MAX_IDX].u8ptr); + if (config.disable_harq) + ul_bler_options->harq_round_max = 1; + else + ul_bler_options->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_HARQ_ROUND_MAX_IDX].u8ptr); RC.nrmac[j]->min_grant_prb = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_PRB_IDX].u8ptr); RC.nrmac[j]->min_grant_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_MCS_IDX].u8ptr); RC.nrmac[j]->identity_pm = *(MacRLC_ParamList.paramarray[j][MACRLC_IDENTITY_PM_IDX].u8ptr); diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index a56b64b407..339ea75714 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -126,6 +126,7 @@ typedef enum { #define GNB_CONFIG_STRING_UMONDEFAULTDRB "um_on_default_drb" #define GNB_CONFIG_STRING_FORCE256QAMOFF "force_256qam_off" #define GNB_CONFIG_STRING_MAXMIMOLAYERS "maxMIMO_layers" +#define GNB_CONFIG_STRING_DISABLE_HARQ "disable_harq" #define GNB_CONFIG_STRING_ENABLE_SDAP "enable_sdap" #define GNB_CONFIG_STRING_DRBS "drbs" #define GNB_CONFIG_STRING_USE_DELTA_MCS "use_deltaMCS" @@ -138,6 +139,7 @@ typedef enum { #define GNB_CONFIG_HLP_STRING_ENABLE_SDAP "enable the SDAP layer\n" #define GNB_CONFIG_HLP_FORCE256QAMOFF "suppress activation of 256 QAM despite UE support" #define GNB_CONFIG_HLP_MAXMIMOLAYERS "limit on maxMIMO-layers for DL" +#define GNB_CONFIG_HLP_DISABLE_HARQ "disable feedback for all HARQ processes (REL17 feature)" #define GNB_CONFIG_HLP_STRING_DRBS "Number of total DRBs to establish, including the mandatory for PDU SEssion (default=1)\n" #define GNB_CONFIG_HLP_GNB_DU_ID "defines the gNB-DU ID (only applicable for DU)" #define GNB_CONFIG_HLP_GNB_CU_UP_ID "defines the gNB-CU-UP ID (only applicable for CU-UP)" @@ -172,14 +174,15 @@ typedef enum { {GNB_CONFIG_STRING_MINRXTXTIME, NULL, 0, .iptr=NULL, .defintval=2, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_ULPRBBLACKLIST, NULL, 0, .strptr=NULL,.defstrval="", TYPE_STRING, 0}, \ {GNB_CONFIG_STRING_UMONDEFAULTDRB, NULL, PARAMFLAG_BOOL, .uptr=NULL, .defuintval=0, TYPE_UINT, 0}, \ -{GNB_CONFIG_STRING_FORCE256QAMOFF, GNB_CONFIG_HLP_FORCE256QAMOFF, PARAMFLAG_BOOL, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \ +{GNB_CONFIG_STRING_FORCE256QAMOFF, GNB_CONFIG_HLP_FORCE256QAMOFF, PARAMFLAG_BOOL, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_ENABLE_SDAP, GNB_CONFIG_HLP_STRING_ENABLE_SDAP, PARAMFLAG_BOOL,.iptr=NULL, .defintval=0, TYPE_INT, 0}, \ -{GNB_CONFIG_STRING_DRBS, GNB_CONFIG_HLP_STRING_DRBS, 0, .iptr=NULL, .defintval=1, TYPE_INT, 0}, \ -{GNB_CONFIG_STRING_GNB_DU_ID, GNB_CONFIG_HLP_GNB_DU_ID, 0, .u64ptr=NULL, .defint64val=1, TYPE_UINT64, 0}, \ +{GNB_CONFIG_STRING_DRBS, GNB_CONFIG_HLP_STRING_DRBS, 0, .iptr=NULL, .defintval=1, TYPE_INT, 0}, \ +{GNB_CONFIG_STRING_GNB_DU_ID, GNB_CONFIG_HLP_GNB_DU_ID, 0, .u64ptr=NULL, .defint64val=1, TYPE_UINT64, 0}, \ {GNB_CONFIG_STRING_GNB_CU_UP_ID, GNB_CONFIG_HLP_GNB_CU_UP_ID, 0, .u64ptr=NULL, .defint64val=1, TYPE_UINT64, 0}, \ -{GNB_CONFIG_STRING_USE_DELTA_MCS, GNB_CONFIG_HLP_USE_DELTA_MCS, 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \ -{GNB_CONFIG_STRING_FORCEUL256QAMOFF, GNB_CONFIG_HLP_FORCEUL256QAMOFF, 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \ -{GNB_CONFIG_STRING_MAXMIMOLAYERS, GNB_CONFIG_HLP_MAXMIMOLAYERS, 0, .iptr=NULL, .defintval=-1, TYPE_INT, 0}, \ +{GNB_CONFIG_STRING_USE_DELTA_MCS, GNB_CONFIG_HLP_USE_DELTA_MCS, 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \ +{GNB_CONFIG_STRING_FORCEUL256QAMOFF, GNB_CONFIG_HLP_FORCEUL256QAMOFF, 0,.iptr=NULL, .defintval=0, TYPE_INT, 0}, \ +{GNB_CONFIG_STRING_MAXMIMOLAYERS, GNB_CONFIG_HLP_MAXMIMOLAYERS, 0, .iptr=NULL, .defintval=-1, TYPE_INT, 0}, \ +{GNB_CONFIG_STRING_DISABLE_HARQ, GNB_CONFIG_HLP_DISABLE_HARQ, PARAMFLAG_BOOL, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \ } // clang-format on @@ -216,6 +219,7 @@ typedef enum { #define GNB_USE_DELTA_MCS_IDX 29 #define GNB_FORCEUL256QAMOFF_IDX 30 #define GNB_MAXMIMOLAYERS_IDX 31 +#define GNB_DISABLE_HARQ_IDX 32 #define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD} #define GNBPARAMS_CHECK { \ @@ -251,6 +255,7 @@ typedef enum { { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ } /*-------------------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index e43b038266..d141215846 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -599,6 +599,7 @@ typedef struct { int dl_bw_tbslbrm; int ul_bw_tbslbrm; NR_NTN_Config_r17_t *ntn_Config_r17; + NR_DownlinkHARQ_FeedbackDisabled_r17_t *downlinkHARQ_FeedbackDisabled_r17; } NR_UE_ServingCell_Info_t; typedef enum { diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 151cee026d..acbc1ff1ca 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -5243,3 +5243,14 @@ rnti_t nr_get_ra_rnti(uint8_t s_id, uint8_t t_id, uint8_t f_id, uint8_t ul_carri return ra_rnti; } + +int get_FeedbackDisabled(NR_DownlinkHARQ_FeedbackDisabled_r17_t *downlinkHARQ_FeedbackDisabled_r17, int harq_pid) +{ + if (downlinkHARQ_FeedbackDisabled_r17 == NULL) + return 0; + + const int byte_index = harq_pid / 8; + const int bit_index = harq_pid % 8; + + return (downlinkHARQ_FeedbackDisabled_r17->buf[byte_index] >> (7 - bit_index)) & 1; +} diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index e809c3e521..72872a7e1f 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -317,4 +317,6 @@ rnti_t nr_get_ra_rnti(uint8_t s_id, uint8_t t_id, uint8_t f_id, uint8_t ul_carri bool supported_bw_comparison(int bw_mhz, NR_SupportedBandwidth_t *supported_BW, long *support_90mhz); +int get_FeedbackDisabled(NR_DownlinkHARQ_FeedbackDisabled_r17_t *downlinkHARQ_FeedbackDisabled_r17, int harq_pid); + #endif diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 507b45ebd3..c6c69311f7 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -2064,6 +2064,8 @@ static void configure_servingcell_info(NR_UE_MAC_INST_t *mac, NR_ServingCellConf free(sc_info->maxMIMO_Layers_PDSCH); sc_info->maxMIMO_Layers_PDSCH = NULL; } + if (sc_info->downlinkHARQ_FeedbackDisabled_r17) + asn1cFreeStruc(asn_DEF_NR_DownlinkHARQ_FeedbackDisabled_r17, sc_info->downlinkHARQ_FeedbackDisabled_r17); break; case NR_SetupRelease_PDSCH_ServingCellConfig_PR_setup: { NR_PDSCH_ServingCellConfig_t *pdsch_servingcellconfig = scd->pdsch_ServingCellConfig->choice.setup; @@ -2075,6 +2077,28 @@ static void configure_servingcell_info(NR_UE_MAC_INST_t *mac, NR_ServingCellConf UPDATE_IE(sc_info->xOverhead_PDSCH, pdsch_servingcellconfig->xOverhead, long); if (pdsch_servingcellconfig->ext1 && pdsch_servingcellconfig->ext1->maxMIMO_Layers) UPDATE_IE(sc_info->maxMIMO_Layers_PDSCH, pdsch_servingcellconfig->ext1->maxMIMO_Layers, long); + if (pdsch_servingcellconfig->ext3 && pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17) { + switch (pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->present) { + case NR_SetupRelease_DownlinkHARQ_FeedbackDisabled_r17_PR_NOTHING: + break; + case NR_SetupRelease_DownlinkHARQ_FeedbackDisabled_r17_PR_release: + if (sc_info->downlinkHARQ_FeedbackDisabled_r17) + asn1cFreeStruc(asn_DEF_NR_DownlinkHARQ_FeedbackDisabled_r17, sc_info->downlinkHARQ_FeedbackDisabled_r17); + break; + case NR_SetupRelease_DownlinkHARQ_FeedbackDisabled_r17_PR_setup: + if (sc_info->downlinkHARQ_FeedbackDisabled_r17 == NULL) { + sc_info->downlinkHARQ_FeedbackDisabled_r17 = calloc(1, sizeof(*sc_info->downlinkHARQ_FeedbackDisabled_r17)); + sc_info->downlinkHARQ_FeedbackDisabled_r17->buf = calloc(4, sizeof(*sc_info->downlinkHARQ_FeedbackDisabled_r17->buf)); + } + sc_info->downlinkHARQ_FeedbackDisabled_r17->size = pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.size; + sc_info->downlinkHARQ_FeedbackDisabled_r17->bits_unused = pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.bits_unused; + for (int i = 0; i < sc_info->downlinkHARQ_FeedbackDisabled_r17->size; i++) + sc_info->downlinkHARQ_FeedbackDisabled_r17->buf[i] = pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[i]; + break; + default: + AssertFatal(false, "Invalid case\n"); + } + } break; } default: diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index f67e8d25c3..b6a289cc45 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -269,6 +269,7 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac, asn1cFreeStruc(asn_DEF_NR_CSI_MeasConfig, sc->csi_MeasConfig); asn1cFreeStruc(asn_DEF_NR_CSI_AperiodicTriggerStateList, sc->aperiodicTriggerStateList); asn1cFreeStruc(asn_DEF_NR_NTN_Config_r17, sc->ntn_Config_r17); + asn1cFreeStruc(asn_DEF_NR_DownlinkHARQ_FeedbackDisabled_r17, sc->downlinkHARQ_FeedbackDisabled_r17); free(sc->xOverhead_PDSCH); free(sc->nrofHARQ_ProcessesForPDSCH); free(sc->rateMatching_PUSCH); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index af148e6bd5..c7903a9666 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2341,7 +2341,17 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche "Value of pucch_resource_indicator %d not matching with what set before %d (Possibly due to a false DCI) \n", current_harq->pucch_resource_indicator, res_ind); - else{ + else { + if (!current_harq->ack_received) + LOG_E(NR_MAC, "DLSCH ACK/NACK reporting initiated for harq pid %d before DLSCH decoding completed\n", dl_harq_pid); + + if (get_FeedbackDisabled(mac->sc_info.downlinkHARQ_FeedbackDisabled_r17, dl_harq_pid)) { + LOG_D(NR_MAC, "skipping DLSCH ACK/NACK reporting for harq pid %d\n", dl_harq_pid); + current_harq->active = false; + current_harq->ack_received = false; + continue; + } + if (current_harq->dai_cumul == 0) { LOG_E(NR_MAC,"PUCCH Downlink DAI is invalid\n"); return false; @@ -2356,7 +2366,6 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche current_harq->active = false; current_harq->ack_received = false; } else { - LOG_E(NR_MAC, "DLSCH ACK/NACK reporting initiated for harq pid %d before DLSCH decoding completed\n", dl_harq_pid); ack_data[code_word][dai_index] = 0; } dai[code_word][dai_index] = (dai_index % 4) + 1; // value between 1 and 4 diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 6fb183fb28..200a21258e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -1861,17 +1861,6 @@ static void nr_generate_Msg4(module_id_t module_idP, return; } - const int delta_PRI = 0; - int r_pucch = nr_get_pucch_resource(coreset, ra->UL_BWP.pucch_Config, CCEIndex); - - LOG_D(NR_MAC, "Msg4 r_pucch %d (CCEIndex %d, delta_PRI %d)\n", r_pucch, CCEIndex, delta_PRI); - - int alloc = nr_acknack_scheduling(nr_mac, UE, frameP, slotP, r_pucch, 1); - if (alloc < 0) { - LOG_D(NR_MAC,"Couldn't find a pucch allocation for ack nack (msg4) in frame %d slot %d\n",frameP,slotP); - return; - } - // HARQ management if (current_harq_pid < 0) { AssertFatal(sched_ctrl->available_dl_harq.head >= 0, @@ -1879,16 +1868,37 @@ static void nr_generate_Msg4(module_id_t module_idP, current_harq_pid = sched_ctrl->available_dl_harq.head; remove_front_nr_list(&sched_ctrl->available_dl_harq); } + + const int delta_PRI = 0; + + int alloc = -1; + if (!get_FeedbackDisabled(UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, current_harq_pid)) { + int r_pucch = nr_get_pucch_resource(coreset, ra->UL_BWP.pucch_Config, CCEIndex); + + LOG_D(NR_MAC, "Msg4 r_pucch %d (CCEIndex %d, delta_PRI %d)\n", r_pucch, CCEIndex, delta_PRI); + + alloc = nr_acknack_scheduling(nr_mac, UE, frameP, slotP, r_pucch, 1); + if (alloc < 0) { + LOG_D(NR_MAC,"Couldn't find a pucch allocation for ack nack (msg4) in frame %d slot %d\n",frameP,slotP); + return; + } + } + NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid]; + NR_sched_pucch_t *pucch = NULL; DevAssert(!harq->is_waiting); - add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid); - harq->is_waiting = true; + if (alloc < 0) { + finish_nr_dl_harq(sched_ctrl, current_harq_pid); + } else { + pucch = &sched_ctrl->sched_pucch[alloc]; + add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid); + harq->feedback_slot = pucch->ul_slot; + harq->feedback_frame = pucch->frame; + harq->is_waiting = true; + } ra->harq_pid = current_harq_pid; UE->mac_stats.dl.rounds[harq->round]++; - NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[alloc]; - harq->feedback_slot = pucch->ul_slot; - harq->feedback_frame = pucch->frame; harq->tb_size = tb_size; uint8_t *buf = (uint8_t *) harq->transportBlock; @@ -1967,8 +1977,22 @@ static void nr_generate_Msg4(module_id_t module_idP, vrb_map[BWPStart + rb + rbStart] |= SL_to_bitmap(msg4_tda.startSymbolIndex, msg4_tda.nrOfSymbols); } - ra->ra_state = nrRA_WAIT_Msg4_ACK; - LOG_I(NR_MAC,"UE %04x Generate msg4: feedback at %4d.%2d, payload %d bytes, next state WAIT_Msg4_ACK\n", ra->rnti, pucch->frame, pucch->ul_slot, harq->tb_size); + if (pucch == NULL) { + LOG_A(NR_MAC, "(UE RNTI 0x%04x) Skipping Ack of RA-Msg4. CBRA procedure succeeded!\n", ra->rnti); + UE->Msg4_ACKed = true; + + // Pause scheduling according to: + // 3GPP TS 38.331 Section 12 Table 12.1-1: UE performance requirements for RRC procedures for UEs + // Msg4 may transmit a RRCReconfiguration, for example when UE sends RRCReestablishmentComplete and MAC CE for C-RNTI in Msg3. + // In that case, gNB will generate a RRCReconfiguration that will be transmitted in Msg4, so we need to apply CellGroup after the Ack, + // UE->apply_cellgroup was already set when processing RRCReestablishment message + nr_mac_enable_ue_rrc_processing_timer(nr_mac, UE, UE->apply_cellgroup); + + nr_clear_ra_proc(ra); + } else { + ra->ra_state = nrRA_WAIT_Msg4_ACK; + LOG_I(NR_MAC,"UE %04x Generate msg4: feedback at %4d.%2d, payload %d bytes, next state WAIT_Msg4_ACK\n", ra->rnti, pucch->frame, pucch->ul_slot, harq->tb_size); + } } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 95832f5158..cd4fc9b197 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -371,17 +371,23 @@ static void nr_store_dlsch_buffer(module_id_t module_id, frame_t frame, sub_fram } } -void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid) +void finish_nr_dl_harq(NR_UE_sched_ctrl_t *sched_ctrl, int harq_pid) { - /* already mutex protected through handle_dl_harq() */ - NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_harq_t *harq = &sched_ctrl->harq_processes[harq_pid]; harq->ndi ^= 1; harq->round = 0; - UE->mac_stats.dl.errors++; - add_tail_nr_list(&sched_ctrl->available_dl_harq, harq_pid); + add_tail_nr_list(&sched_ctrl->available_dl_harq, harq_pid); +} + +void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid) +{ + /* already mutex protected through handle_dl_harq() */ + NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + + finish_nr_dl_harq(sched_ctrl, harq_pid); + UE->mac_stats.dl.errors++; } static void get_start_stop_allocation(gNB_MAC_INST *mac, @@ -556,14 +562,17 @@ static bool allocate_dl_retransmission(module_id_t module_id, /* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH * allocation after CCE alloc fail would be more complex) */ - int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, ul_bwp->pucch_Config, CCEIndex); - const int alloc = nr_acknack_scheduling(nr_mac, UE, frame, slot, r_pucch, 0); - if (alloc<0) { - LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find PUCCH for DL DCI retransmission\n", - UE->rnti, - frame, - slot); - return false; + int alloc = -1; + if (!get_FeedbackDisabled(UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, current_harq_pid)) { + int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, ul_bwp->pucch_Config, CCEIndex); + alloc = nr_acknack_scheduling(nr_mac, UE, frame, slot, r_pucch, 0); + if (alloc<0) { + LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find PUCCH for DL DCI retransmission\n", + UE->rnti, + frame, + slot); + return false; + } } sched_ctrl->cce_index = CCEIndex; @@ -724,6 +733,8 @@ static void pf_dl(module_id_t module_id, iterator++; continue; } + NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; + sched_pdsch->dl_harq_pid = sched_ctrl->available_dl_harq.head; int CCEIndex = get_cce_index(mac, CC_id, slot, iterator->UE->rnti, @@ -744,16 +755,18 @@ static void pf_dl(module_id_t module_id, /* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH * allocation after CCE alloc fail would be more complex) */ - int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, ul_bwp->pucch_Config, CCEIndex); - const int alloc = nr_acknack_scheduling(mac, iterator->UE, frame, slot, r_pucch, 0); - - if (alloc<0) { - LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find PUCCH for DL DCI\n", - rnti, - frame, - slot); - iterator++; - continue; + int alloc = -1; + if (!get_FeedbackDisabled(iterator->UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, sched_pdsch->dl_harq_pid)) { + int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, ul_bwp->pucch_Config, CCEIndex); + alloc = nr_acknack_scheduling(mac, iterator->UE, frame, slot, r_pucch, 0); + if (alloc<0) { + LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find PUCCH for DL DCI\n", + rnti, + frame, + slot); + iterator++; + continue; + } } sched_ctrl->cce_index = CCEIndex; @@ -764,7 +777,6 @@ static void pf_dl(module_id_t module_id, sched_ctrl->aggregation_level); /* MCS has been set above */ - NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; sched_pdsch->time_domain_allocation = get_dl_tda(mac, scc, slot); AssertFatal(sched_pdsch->time_domain_allocation>=0,"Unable to find PDSCH time domain allocation in list\n"); @@ -999,12 +1011,17 @@ void nr_schedule_ue_spec(module_id_t module_id, NR_tda_info_t *tda_info = &sched_pdsch->tda_info; NR_pdsch_dmrs_t *dmrs_parms = &sched_pdsch->dmrs_parms; NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid]; + NR_sched_pucch_t *pucch = NULL; DevAssert(!harq->is_waiting); - add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid); - NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[sched_pdsch->pucch_allocation]; - harq->feedback_frame = pucch->frame; - harq->feedback_slot = pucch->ul_slot; - harq->is_waiting = true; + if (sched_pdsch->pucch_allocation < 0) { + finish_nr_dl_harq(sched_ctrl, current_harq_pid); + } else { + pucch = &sched_ctrl->sched_pucch[sched_pdsch->pucch_allocation]; + add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid); + harq->feedback_frame = pucch->frame; + harq->feedback_slot = pucch->ul_slot; + harq->is_waiting = true; + } UE->mac_stats.dl.rounds[harq->round]++; LOG_D(NR_MAC, "%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", @@ -1196,10 +1213,10 @@ void nr_schedule_ue_spec(module_id_t module_id, dci_payload.rv = pdsch_pdu->rvIndex[0]; dci_payload.harq_pid = current_harq_pid; dci_payload.ndi = harq->ndi; - dci_payload.dai[0].val = (pucch->dai_c-1)&3; + dci_payload.dai[0].val = pucch ? (pucch->dai_c-1)&3 : 0; dci_payload.tpc = sched_ctrl->tpc1; // TPC for PUCCH: table 7.2.1-1 in 38.213 - dci_payload.pucch_resource_indicator = pucch->resource_indicator; - dci_payload.pdsch_to_harq_feedback_timing_indicator.val = pucch->timing_indicator; // PDSCH to HARQ TI + dci_payload.pucch_resource_indicator = pucch ? pucch->resource_indicator : 0; + dci_payload.pdsch_to_harq_feedback_timing_indicator.val = pucch ? pucch->timing_indicator : 0; // PDSCH to HARQ TI dci_payload.antenna_ports.val = dmrs_parms->dmrs_ports_id; dci_payload.dmrs_sequence_initialization.val = pdsch_pdu->SCID; LOG_D(NR_MAC, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 4dbcdd72e7..c02691e82c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -142,16 +142,23 @@ void nr_preprocessor_phytest(module_id_t module_id, __func__, UE->rnti); - int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, UE->current_UL_BWP.pucch_Config, CCEIndex); - const int alloc = nr_acknack_scheduling(RC.nrmac[module_id], UE, frame, slot, r_pucch, 0); - if (alloc < 0) { - LOG_D(MAC, - "%s(): could not find PUCCH for UE %04x@%d.%d\n", - __func__, - rnti, - frame, - slot); - return; + NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; + if (sched_pdsch->dl_harq_pid == -1) + sched_pdsch->dl_harq_pid = sched_ctrl->available_dl_harq.head; + + int alloc = -1; + if (!get_FeedbackDisabled(UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, sched_pdsch->dl_harq_pid)) { + int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, UE->current_UL_BWP.pucch_Config, CCEIndex); + alloc = nr_acknack_scheduling(RC.nrmac[module_id], UE, frame, slot, r_pucch, 0); + if (alloc < 0) { + LOG_D(MAC, + "%s(): could not find PUCCH for UE %04x@%d.%d\n", + __func__, + rnti, + frame, + slot); + return; + } } sched_ctrl->cce_index = CCEIndex; @@ -166,7 +173,6 @@ void nr_preprocessor_phytest(module_id_t module_id, // "could not find uplink slot for PUCCH (RNTI %04x@%d.%d)!\n", // rnti, frame, slot); - NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; sched_pdsch->pucch_allocation = alloc; sched_pdsch->rbStart = rbStart; sched_pdsch->rbSize = rbSize; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 8ae9c3dcc5..4c67bfdf35 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2345,6 +2345,9 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, sc_info->nrofHARQ_ProcessesForPDSCH = pdsch_servingcellconfig->nrofHARQ_ProcessesForPDSCH; if (pdsch_servingcellconfig->ext1) sc_info->maxMIMO_Layers_PDSCH = pdsch_servingcellconfig->ext1->maxMIMO_Layers; + if (pdsch_servingcellconfig->ext3 && + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17) + sc_info->downlinkHARQ_FeedbackDisabled_r17 = &pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup; if (pdsch_servingcellconfig->codeBlockGroupTransmission && pdsch_servingcellconfig->codeBlockGroupTransmission->choice.setup) sc_info->pdsch_CGB_Transmission = pdsch_servingcellconfig->codeBlockGroupTransmission->choice.setup; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 1e133a028b..3de5c1ea7a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -385,19 +385,18 @@ static void handle_dl_harq(NR_UE_info_t * UE, bool success, int harq_round_max) { - NR_UE_harq_t *harq = &UE->UE_sched_ctrl.harq_processes[harq_pid]; + NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_harq_t *harq = &sched_ctrl->harq_processes[harq_pid]; harq->feedback_slot = -1; harq->is_waiting = false; if (success) { - add_tail_nr_list(&UE->UE_sched_ctrl.available_dl_harq, harq_pid); - harq->round = 0; - harq->ndi ^= 1; + finish_nr_dl_harq(sched_ctrl, harq_pid); } else if (harq->round >= harq_round_max - 1) { abort_nr_dl_harq(UE, harq_pid); LOG_D(NR_MAC, "retransmission error for UE %04x (total %"PRIu64")\n", UE->rnti, UE->mac_stats.dl.errors); } else { LOG_D(PHY,"NACK for: pid %d, ue %04x\n",harq_pid, UE->rnti); - add_tail_nr_list(&UE->UE_sched_ctrl.retrans_dl_harq, harq_pid); + add_tail_nr_list(&sched_ctrl->retrans_dl_harq, harq_pid); harq->round++; } } @@ -1105,11 +1104,14 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, 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; NR_UE_harq_t *harq = find_harq(frame, slot, UE, RC.nrmac[mod_id]->dl_bler.harq_round_max); - if (!harq) + if (!harq) { + LOG_E(NR_MAC, "UE %04x: Could not find a HARQ process at %4d.%2d!\n", UE->rnti, frame, slot); break; + } DevAssert(harq->is_waiting); const int8_t pid = sched_ctrl->feedback_dl_harq.head; 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, acknack); handle_dl_harq(UE, pid, uci_234->harq.harq_crc != 1 && acknack, nrmac->dl_bler.harq_round_max); } free(uci_234->harq.harq_payload); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index bdc1309743..772b9bf582 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -511,15 +511,23 @@ static int nr_process_mac_pdu(instance_t module_idP, return 0; } +static void finish_nr_ul_harq(NR_UE_sched_ctrl_t *sched_ctrl, int harq_pid) +{ + NR_UE_ul_harq_t *harq = &sched_ctrl->ul_harq_processes[harq_pid]; + + harq->ndi ^= 1; + harq->round = 0; + + add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid); +} + static void abort_nr_ul_harq(NR_UE_info_t *UE, int8_t harq_pid) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_ul_harq_t *harq = &sched_ctrl->ul_harq_processes[harq_pid]; - harq->ndi ^= 1; - harq->round = 0; + finish_nr_ul_harq(sched_ctrl, harq_pid); UE->mac_stats.ul.errors++; - add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid); /* the transmission failed: the UE won't send the data we expected initially, * so retrieve to correctly schedule after next BSR */ @@ -566,6 +574,11 @@ void handle_nr_ul_harq(const int CC_idP, LOG_E(NR_MAC, "no RA proc for RNTI 0x%04x in Msg3/PUSCH\n", crc_pdu->rnti); return; } + if (nrmac->radio_config.disable_harq) { + LOG_D(NR_MAC, "skipping UL feedback handling as HARQ is disabled\n"); + NR_SCHED_UNLOCK(&nrmac->sched_lock); + return; + } NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; 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); @@ -597,13 +610,11 @@ void handle_nr_ul_harq(const int CC_idP, harq->feedback_slot = -1; harq->is_waiting = false; if (!crc_pdu->tb_crc_status) { - harq->ndi ^= 1; - harq->round = 0; + finish_nr_ul_harq(sched_ctrl, harq_pid); LOG_D(NR_MAC, "Ulharq id %d crc passed for RNTI %04x\n", harq_pid, crc_pdu->rnti); - add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid); } else if (harq->round >= RC.nrmac[mod_id]->ul_bler.harq_round_max - 1) { abort_nr_ul_harq(UE, harq_pid); LOG_D(NR_MAC, @@ -651,6 +662,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, const rnti_t rntiP, uint8_t *sduP, const uint32_t sdu_lenP, + const int8_t harq_pid, const uint16_t timing_advance, const uint8_t ul_cqi, const uint16_t rssi) @@ -668,7 +680,6 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, if (UE && UE_waiting_CFRA_msg3 == false) { NR_UE_sched_ctrl_t *UE_scheduling_control = &UE->UE_sched_ctrl; - const int8_t harq_pid = UE_scheduling_control->feedback_ul_harq.head; if (sduP) T(T_GNB_MAC_UL_PDU_WITH_DATA, T_INT(gnb_mod_idP), T_INT(CC_idP), @@ -744,22 +755,13 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, LOG_D(NR_MAC, "Received PDU at MAC gNB \n"); 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; - UE_scheduling_control->sched_ul_bytes -= tb_size; + UE_scheduling_control->sched_ul_bytes -= sdu_lenP; if (UE_scheduling_control->sched_ul_bytes < 0) UE_scheduling_control->sched_ul_bytes = 0; nr_process_mac_pdu(gnb_mod_idP, UE, CC_idP, frameP, slotP, sduP, sdu_lenP, harq_pid); } else { - NR_UE_ul_harq_t *cur_harq = &UE_scheduling_control->ul_harq_processes[harq_pid]; - /* reduce sched_ul_bytes when cur_harq->round == 3 */ - if (cur_harq->round == 3) { - 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; - if (UE_scheduling_control->sched_ul_bytes < 0) - UE_scheduling_control->sched_ul_bytes = 0; - } if (ul_cqi == 0xff || ul_cqi <= 128) { UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt++; UE->mac_stats.ulsch_DTX++; @@ -954,13 +956,14 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, const rnti_t rntiP, uint8_t *sduP, const uint32_t sdu_lenP, + const int8_t harq_pid, const uint16_t timing_advance, const uint8_t ul_cqi, const uint16_t rssi) { gNB_MAC_INST *gNB_mac = RC.nrmac[gnb_mod_idP]; NR_SCHED_LOCK(&gNB_mac->sched_lock); - _nr_rx_sdu(gnb_mod_idP, CC_idP, frameP, slotP, rntiP, sduP, sdu_lenP, timing_advance, ul_cqi, rssi); + _nr_rx_sdu(gnb_mod_idP, CC_idP, frameP, slotP, rntiP, sduP, sdu_lenP, harq_pid, timing_advance, ul_cqi, rssi); NR_SCHED_UNLOCK(&gNB_mac->sched_lock); } @@ -2278,9 +2281,13 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n } NR_UE_ul_harq_t *cur_harq = &sched_ctrl->ul_harq_processes[harq_id]; DevAssert(!cur_harq->is_waiting); - add_tail_nr_list(&sched_ctrl->feedback_ul_harq, harq_id); - cur_harq->feedback_slot = sched_pusch->slot; - cur_harq->is_waiting = true; + if (nr_mac->radio_config.disable_harq) { + finish_nr_ul_harq(sched_ctrl, harq_id); + } else { + add_tail_nr_list(&sched_ctrl->feedback_ul_harq, harq_id); + cur_harq->feedback_slot = sched_pusch->slot; + cur_harq->is_waiting = true; + } /* Statistics */ AssertFatal(cur_harq->round < nr_mac->ul_bler.harq_round_max, "Indexing ulsch_rounds[%d] is out of bounds\n", cur_harq->round); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index fe2fec8ab1..84f06c873c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -344,6 +344,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, const rnti_t rntiP, uint8_t * sduP, const uint32_t sdu_lenP, + const int8_t harq_pid, const uint16_t timing_advance, const uint8_t ul_cqi, const uint16_t rssi); @@ -432,6 +433,7 @@ long get_lcid_from_srbid(int srb_id); void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE); void send_initial_ul_rrc_message(int rnti, const uint8_t *sdu, sdu_size_t sdu_len, void *data); +void finish_nr_dl_harq(NR_UE_sched_ctrl_t *sched_ctrl, int harq_pid); void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid); void nr_mac_trigger_release_timer(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 42d65c3bed..350a909088 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -152,6 +152,7 @@ typedef struct nr_mac_config_t { bool force_UL256qam_off; bool use_deltaMCS; int maxMIMO_layers; + bool disable_harq; //int pusch_TargetSNRx10; //int pucch_TargetSNRx10; nr_mac_timers_t timer_config; @@ -436,7 +437,7 @@ typedef struct NR_sched_pdsch { int8_t dl_harq_pid; // pucch format allocation - uint16_t pucch_allocation; + int16_t pucch_allocation; uint16_t pm_index; uint8_t nrOfLayers; diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index a4a6dbb973..b4dbe486c6 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -194,6 +194,9 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) AssertFatal(crc->rnti == rx->rnti, "mis-match between CRC RNTI %04x and RX RNTI %04x\n", crc->rnti, rx->rnti); + AssertFatal(crc->harq_id == rx->harq_id, "mis-match between CRC HARQ ID %04x and RX HARQ ID %04x\n", + crc->harq_id, rx->harq_id); + LOG_D(NR_MAC, "%4d.%2d Calling rx_sdu (CRC %s/tb_crc_status %d)\n", UL_info->frame, @@ -209,6 +212,7 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) crc->rnti, crc->tb_crc_status ? NULL : rx->pdu, rx->pdu_length, + crc->harq_id, crc->timing_advance, crc->ul_cqi, crc->rssi); diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index 597dba1cdd..d0b692232f 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -2685,6 +2685,18 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid, *pdsch_servingcellconfig->nrofHARQ_ProcessesForPDSCH = NR_PDSCH_ServingCellConfig__nrofHARQ_ProcessesForPDSCH_n16; pdsch_servingcellconfig->pucch_Cell = NULL; set_dl_maxmimolayers(pdsch_servingcellconfig, scc, NULL, configuration->maxMIMO_layers); + if (configuration->disable_harq) { + pdsch_servingcellconfig->ext3 = calloc(1, sizeof(*pdsch_servingcellconfig->ext3)); + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17 = calloc(1, sizeof(*pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17)); + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->present = NR_SetupRelease_DownlinkHARQ_FeedbackDisabled_r17_PR_setup; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf = calloc(4, sizeof(uint8_t)); + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.size = 4; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.bits_unused = 0; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[0] = 0xFF; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[1] = 0xFF; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[2] = 0xFF; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[3] = 0xFF; + } // Downlink BWPs int n_dl_bwp = 0; @@ -3268,6 +3280,18 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC pdsch_servingcellconfig->pucch_Cell = NULL; set_dl_maxmimolayers(pdsch_servingcellconfig, servingcellconfigcommon, uecap, configuration->maxMIMO_layers); pdsch_servingcellconfig->ext1->processingType2Enabled = NULL; + if (configuration->disable_harq) { + pdsch_servingcellconfig->ext3 = calloc(1, sizeof(*pdsch_servingcellconfig->ext3)); + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17 = calloc(1, sizeof(*pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17)); + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->present = NR_SetupRelease_DownlinkHARQ_FeedbackDisabled_r17_PR_setup; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf = calloc(4, sizeof(uint8_t)); + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.size = 4; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.bits_unused = 0; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[0] = 0xFF; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[1] = 0xFF; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[2] = 0xFF; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[3] = 0xFF; + } secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig = NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig = diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf index 0ad01d6e93..602c31f42c 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf @@ -34,6 +34,7 @@ gNBs = sib1_tda = 5; min_rxtxtime = 6; +# disable_harq = 1; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf index f29bbf9cf6..0934508e91 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf @@ -34,6 +34,7 @@ gNBs = sib1_tda = 5; min_rxtxtime = 6; +# disable_harq = 1; servingCellConfigCommon = ( {