From e6719d7718ad5bbbdf671f9cda7f334fe9b57ae2 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Tue, 9 Jul 2024 14:37:06 +0200 Subject: [PATCH 01/14] remove superfluous semicolon from multi-line macros in oai_asn1.h --- common/utils/oai_asn1.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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. From ae4cbcfb0cd325cfdccc9ca25e78dbbec361b569 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Tue, 9 Jul 2024 14:56:18 +0200 Subject: [PATCH 02/14] gNB: add config file option "disable_harq" and set pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17 accordingly --- openair2/GNB_APP/gnb_config.c | 18 ++++++++++---- openair2/GNB_APP/gnb_paramdef.h | 17 ++++++++----- openair2/LAYER2/NR_MAC_COMMON/nr_mac.h | 1 + openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 11 +++++++++ openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h | 2 ++ .../NR_MAC_gNB/gNB_scheduler_primitives.c | 3 +++ openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 1 + openair2/RRC/NR/nr_rrc_config.c | 24 +++++++++++++++++++ .../gnb.sa.band66.fr1.24PRB.usrpx300.conf | 1 + .../gnb.sa.band66.fr1.25PRB.usrpx300.conf | 1 + 10 files changed, 69 insertions(+), 10 deletions(-) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index b732a88879..1d638dd91c 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -1250,13 +1250,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); @@ -1360,12 +1364,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 ad8267e984..144fca43d7 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_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/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 7fe0c8994e..a1c75dfe76 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; diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index de660f1765..edd192eee9 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; @@ -3289,6 +3301,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 = ( { From bf2baf2ffec87b51ad4659f31921d2dab7168756 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 22 May 2024 10:48:07 +0200 Subject: [PATCH 03/14] immediately reuse DL HARQ ID and don't wait for feedback if DL HARQ feedback is disabled --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 95832f5158..a182a9e2c1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -999,12 +999,21 @@ 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]; - 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; + DevAssert(!harq->is_waiting); + if (get_FeedbackDisabled(UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, current_harq_pid)) { + add_tail_nr_list(&sched_ctrl->available_dl_harq, current_harq_pid); + harq->feedback_frame = -1; + harq->feedback_slot = -1; + harq->is_waiting = false; + harq->ndi ^= 1; + harq->round = 0; + } else { + 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", From 4baac21ec612188530a567bb82e9e6979afe2ac7 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 22 May 2024 10:52:14 +0200 Subject: [PATCH 04/14] immediately reuse UL HARQ ID and don't wait for feedback if disable_harq == 1 --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 1048be2528..66ff87e80f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -2270,9 +2270,17 @@ 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) { + add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_id); + cur_harq->feedback_slot = -1; + cur_harq->is_waiting = false; + cur_harq->ndi ^= 1; + cur_harq->round = 0; + } 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); From 9a0408a5c7d34afeffbbb9b876f53daefa59077b Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 22 May 2024 10:54:07 +0200 Subject: [PATCH 05/14] immediately reuse Msg4 HARQ ID and don't wait for Msg4 feedback if DL HARQ feedback is disabled --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 39 +++++++++++++++---- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 9daabdddaf..f8ad0aa9a2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -1880,15 +1880,24 @@ static void nr_generate_Msg4(module_id_t module_idP, remove_front_nr_list(&sched_ctrl->available_dl_harq); } NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid]; + NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[alloc]; DevAssert(!harq->is_waiting); - add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid); - harq->is_waiting = true; + if (get_FeedbackDisabled(UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, current_harq_pid)) { + add_tail_nr_list(&sched_ctrl->available_dl_harq, current_harq_pid); + harq->feedback_frame = -1; + harq->feedback_slot = -1; + harq->is_waiting = false; + harq->ndi ^= 1; + harq->round = 0; + } else { + 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 +1976,24 @@ 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 (get_FeedbackDisabled(UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, current_harq_pid)) { + LOG_I(NR_MAC,"UE %04x Generate msg4: feedback at %4d.%2d, payload %d bytes\n", ra->rnti, pucch->frame, pucch->ul_slot, harq->tb_size); + + 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); + } } } From f7665357fcb7b5c8910ccbb0b53524e937cb0057 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 22 May 2024 10:57:02 +0200 Subject: [PATCH 06/14] dont't print warning in handle_nr_ul_harq() if disable_harq == 1 --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 66ff87e80f..3b097e5e32 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -566,6 +566,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); From b331ad21f4d421511446b20c60293119307c7392 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 22 May 2024 11:12:56 +0200 Subject: [PATCH 07/14] in nr_rx_sdu() use HARQ ID from nfapi_nr_crc_t instead of feedback_ul_harq --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 5 +++-- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 1 + openair2/NR_PHY_INTERFACE/NR_IF_Module.c | 4 ++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 3b097e5e32..094d7aafe5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -656,6 +656,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) @@ -673,7 +674,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), @@ -951,13 +951,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); } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index fe2fec8ab1..5c998f4d2a 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); diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 869c0f9882..c685bb47af 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -192,6 +192,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, @@ -207,6 +210,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); From a6fb797477b4ca66033494472945799cfeb64864 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 22 May 2024 11:18:10 +0200 Subject: [PATCH 08/14] improve tracking of sched_ul_bytes in nr_rx_sdu() by using sdu_lenP instead of sched_pusch.tb_size sched_ul_bytes tracks the volume of in-flight data. When data is successfully received, sched_ul_bytes is decreased in nr_rx_sdu(). In case of reusing HARQ processes, the tb_size stored there is not correct. Therefore use the actual SDU size instead. --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 094d7aafe5..610a58deb3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -749,8 +749,7 @@ 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; From 44410df5988bcc600830b8559cb129ec87ccdda0 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 22 May 2024 11:47:14 +0200 Subject: [PATCH 09/14] fix double reduction of sched_ul_bytes in case of failing 4th HARQ round sched_ul_bytes is reduced already in case the last HARQ round fails through handle_nr_ul_harq() -> abort_nr_ul_harq(). Therefore, the reduction in nr_rx_sdu() is wrong, and btw. it wrongly assumes the max. UL HARQ rounds to 4. So simply remove this peace of code in nr_rx_sdu(). --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 610a58deb3..02770f2b2d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -756,14 +756,6 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, 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++; From fe7be3f130635589b7e39650f584c8dcc33745d3 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 22 May 2024 12:47:02 +0200 Subject: [PATCH 10/14] Make handle_nr_uci_pucch_2_3_4() more consistent regarding logs with handle_nr_uci_pucch_0_1() --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 1e133a028b..2d59e72db2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -1105,11 +1105,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); From 3a014e199f990cd281ac069e7b75a195b8e7f161 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Tue, 9 Jul 2024 17:39:41 +0200 Subject: [PATCH 11/14] NR UE: skip DLSCH ACK/NACK reporting for harq pid where feedback is disabled --- openair2/LAYER2/NR_MAC_UE/config_ue.c | 24 ++++++++++++++++++++ openair2/LAYER2/NR_MAC_UE/main_ue_nr.c | 1 + openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 13 +++++++++-- 3 files changed, 36 insertions(+), 2 deletions(-) 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 From cd052951d54e8e72313e142cec85e176b42e4e0e Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Tue, 16 Jul 2024 13:22:51 +0200 Subject: [PATCH 12/14] gNB: do not schedule DLSCH ACK/NACK reporting in PUCCH for harq pid where feedback is disabled --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 36 ++++++------ .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 55 +++++++++++-------- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 28 ++++++---- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 2 +- 4 files changed, 69 insertions(+), 52 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index f8ad0aa9a2..9f7199d7d5 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,10 +1868,26 @@ 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 = &sched_ctrl->sched_pucch[alloc]; + NR_sched_pucch_t *pucch = NULL; DevAssert(!harq->is_waiting); - if (get_FeedbackDisabled(UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, current_harq_pid)) { + if (alloc < 0) { add_tail_nr_list(&sched_ctrl->available_dl_harq, current_harq_pid); harq->feedback_frame = -1; harq->feedback_slot = -1; @@ -1890,6 +1895,7 @@ static void nr_generate_Msg4(module_id_t module_idP, harq->ndi ^= 1; harq->round = 0; } 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; @@ -1976,9 +1982,7 @@ static void nr_generate_Msg4(module_id_t module_idP, vrb_map[BWPStart + rb + rbStart] |= SL_to_bitmap(msg4_tda.startSymbolIndex, msg4_tda.nrOfSymbols); } - if (get_FeedbackDisabled(UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, current_harq_pid)) { - LOG_I(NR_MAC,"UE %04x Generate msg4: feedback at %4d.%2d, payload %d bytes\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; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index a182a9e2c1..7e80ff7dfd 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -556,14 +556,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 +727,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 +749,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 +771,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,9 +1005,9 @@ 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 = &sched_ctrl->sched_pucch[sched_pdsch->pucch_allocation]; + NR_sched_pucch_t *pucch = NULL; DevAssert(!harq->is_waiting); - if (get_FeedbackDisabled(UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, current_harq_pid)) { + if (sched_pdsch->pucch_allocation < 0) { add_tail_nr_list(&sched_ctrl->available_dl_harq, current_harq_pid); harq->feedback_frame = -1; harq->feedback_slot = -1; @@ -1009,6 +1015,7 @@ void nr_schedule_ue_spec(module_id_t module_id, harq->ndi ^= 1; harq->round = 0; } 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; @@ -1205,10 +1212,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/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index a1c75dfe76..127b19ee2f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -437,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; From b76eb194715e702e621d00c19b5d83d9307b36ae Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Fri, 19 Jul 2024 16:09:04 +0200 Subject: [PATCH 13/14] gNB: refactor code to handle end of using a specific HARQ process - finish_nr_dl_harq() and finish_nr_ul_harq() --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 7 +----- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 23 +++++++++--------- .../LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 9 ++++--- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 24 ++++++++++--------- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 1 + 5 files changed, 31 insertions(+), 33 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 9f7199d7d5..c51e1209b5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -1888,12 +1888,7 @@ static void nr_generate_Msg4(module_id_t module_idP, NR_sched_pucch_t *pucch = NULL; DevAssert(!harq->is_waiting); if (alloc < 0) { - add_tail_nr_list(&sched_ctrl->available_dl_harq, current_harq_pid); - harq->feedback_frame = -1; - harq->feedback_slot = -1; - harq->is_waiting = false; - harq->ndi ^= 1; - harq->round = 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); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 7e80ff7dfd..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, @@ -1008,12 +1014,7 @@ void nr_schedule_ue_spec(module_id_t module_id, NR_sched_pucch_t *pucch = NULL; DevAssert(!harq->is_waiting); if (sched_pdsch->pucch_allocation < 0) { - add_tail_nr_list(&sched_ctrl->available_dl_harq, current_harq_pid); - harq->feedback_frame = -1; - harq->feedback_slot = -1; - harq->is_waiting = false; - harq->ndi ^= 1; - harq->round = 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); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 2d59e72db2..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++; } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 02770f2b2d..d5a03c4cd7 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 */ @@ -602,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, @@ -2268,11 +2274,7 @@ 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); if (nr_mac->radio_config.disable_harq) { - add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_id); - cur_harq->feedback_slot = -1; - cur_harq->is_waiting = false; - cur_harq->ndi ^= 1; - cur_harq->round = 0; + 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; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 5c998f4d2a..84f06c873c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -433,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); From fae529b384c2ff1b56cad38ebc1db16fa4ce6b89 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Tue, 23 Jul 2024 10:42:10 +0200 Subject: [PATCH 14/14] add documentation for `disable_harq` flag in NTN section of doc/RUNMODEM.md --- doc/RUNMODEM.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) 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