diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 954dfbfb91..8fd98a0fe3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -518,7 +518,7 @@ void nr_store_dlsch_buffer(module_id_t module_id, lcid = DL_SCH_LCID_DCCH; } else if (sched_ctrl->rlc_status[DL_SCH_LCID_DCCH1].bytes_in_buffer > 0) { lcid = DL_SCH_LCID_DCCH1; - } else if ( (sched_ctrl->bwp_switch_info.bwp_switch_state != BWP_SWITCH_RUNNING) || (sched_ctrl->schedule_enabled == true) ) { + } else if (sched_ctrl->schedule_enabled == true) { lcid = DL_SCH_LCID_DTCH; } else { continue; @@ -1015,14 +1015,16 @@ void nr_bwp_switch(module_id_t module_id, case BWP_SWITCH_TO_START: LOG_W(NR_MAC,"(%d.%d) [UE_id %d] Schedule BWP switch from bwp_id %ld to %d\n", frame, slot, UE_id, UE_info->UE_sched_ctrl[UE_id].active_bwp->bwp_Id, bwp_id); - sched_ctrl->bwp_switch_info.bwp_switch_timer = 0; sched_ctrl->bwp_switch_info.bwp_switch_state = BWP_SWITCH_RUNNING; + sched_ctrl->bwp_switch_info.bwp_switch_slot = slot; nr_mac_rrc_bwp_switch_req(module_id, frame, slot, UE_info->rnti[UE_id], bwp_id); break; case BWP_SWITCH_RUNNING: - sched_ctrl->bwp_switch_info.bwp_switch_timer++; - if(sched_ctrl->bwp_switch_info.bwp_switch_timer == sched_ctrl->bwp_switch_info.bwp_switch_delay) { + // The BWP switching takes at least 10+6 ms (3GPP TS 38.331 Section 12) + // gNB needs time to schedule and send RRCReconfiguration message + // Therefore, we wait for the same slot in next frame (10 ms) before update bwp_id in the gNB + if (sched_ctrl->bwp_switch_info.bwp_switch_slot == slot) { const NR_ServingCellConfig_t *servingCellConfig = UE_info->CellGroup[UE_id] ? UE_info->CellGroup[UE_id]->spCellConfig->spCellConfigDedicated : NULL; const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig ? servingCellConfig->downlinkBWP_ToAddModList : NULL; const int bwp_id = servingCellConfig && servingCellConfig->firstActiveDownlinkBWP_Id ? diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 453a10f82a..b0b877f84e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2260,9 +2260,7 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellG NULL); sched_ctrl->bwp_switch_info.current_bwp = bwp_id; sched_ctrl->bwp_switch_info.next_bwp = -1; - sched_ctrl->bwp_switch_info.bwp_switch_timer = 0; sched_ctrl->bwp_switch_info.bwp_switch_state = BWP_SWITCH_INACTIVE; - sched_ctrl->bwp_switch_info.bwp_switch_delay = 40; const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig ? servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList : NULL; if (ubwpList) AssertFatal(ubwpList->list.count <= NR_MAX_NUM_BWP, "uplinkBWP_ToAddModList has %d BWP!\n", diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 3e1448ce87..15db47d9cb 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -1181,10 +1181,6 @@ void pf_ul(module_id_t module_id, continue; } - if(sched_ctrl->bwp_switch_info.bwp_switch_state == BWP_SWITCH_RUNNING) { - continue; - } - /* Schedule UE on SR or UL inactivity and no data (otherwise, will be scheduled * based on data to transmit) */ if (B == 0 && do_sched) { diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 0bb26e6f55..ae33a3b6b4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -566,8 +566,7 @@ typedef enum { typedef struct NR_BWP_switch_info { NR_BWP_Id_t current_bwp; NR_BWP_Id_t next_bwp; - int bwp_switch_timer; - uint8_t bwp_switch_delay; + sub_frame_t bwp_switch_slot; NR_BWP_switch_states_t bwp_switch_state; } NR_BWP_switch_info_t; diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index 06489e18b4..19b6a83105 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -414,7 +414,13 @@ void nr_mac_gNB_enable_rrc_processing_timer_req(const module_id_t Mod_instP, con ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[Mod_instP], rntiP); if (ue_context_p != NULL) { ue_context_p->ue_context.nr_rrc_processing_timer = 1; - ue_context_p->ue_context.nr_rrc_processing_delay = NR_RRC_PROCESSING_DELAY_MS; + uint32_t delay_ms = NR_RRC_PROCESSING_DELAY_MS; + if (ue_context_p->ue_context.masterCellGroup && + ue_context_p->ue_context.masterCellGroup->spCellConfig->spCellConfigDedicated && + ue_context_p->ue_context.masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList) { + delay_ms += NR_RRC_BWP_SWITCH_DELAY_MS; + } + ue_context_p->ue_context.nr_rrc_processing_delay = delay_ms; } else { LOG_D(RRC,"%s: Unknown RNTI 0x%04x\n", __FUNCTION__, rntiP); } diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index f7e6ab3943..3927c4ec26 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -101,6 +101,7 @@ typedef struct nr_uid_linear_allocator_s { // 3GPP TS 38.331 Section 12 Table 12.1-1: UE performance requirements for RRC procedures for UEs #define NR_RRC_PROCESSING_DELAY_MS 10 +#define NR_RRC_BWP_SWITCH_DELAY_MS 6 #define NR_UE_MODULE_INVALID ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!! #define NR_UE_INDEX_INVALID ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!! used to be -1 diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 188810f626..1f0dc9d8dd 100755 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -743,7 +743,14 @@ rrc_gNB_generate_defaultRRCReconfiguration( NULL, ue_p->masterCellGroup); - enable_nr_rrc_processing_timer(ctxt_pP->module_id, ue_context_pP, TX_SL_AHEAD_DELAY + NR_RRC_PROCESSING_DELAY_MS); + uint32_t delay_ms = TX_SL_AHEAD_DELAY + NR_RRC_PROCESSING_DELAY_MS; + if (ue_p->masterCellGroup && + ue_p->masterCellGroup->spCellConfig && + ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated && + ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList) { + delay_ms += NR_RRC_BWP_SWITCH_DELAY_MS; + } + enable_nr_rrc_processing_timer(ctxt_pP->module_id, ue_context_pP, delay_ms); free(ue_context_pP->ue_context.nas_pdu.buffer); @@ -1008,7 +1015,14 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( NULL, cellGroupConfig); - enable_nr_rrc_processing_timer(ctxt_pP->module_id, ue_context_pP, TX_SL_AHEAD_DELAY + NR_RRC_PROCESSING_DELAY_MS); + uint32_t delay_ms = TX_SL_AHEAD_DELAY + NR_RRC_PROCESSING_DELAY_MS; + if (cellGroupConfig && + cellGroupConfig->spCellConfig && + cellGroupConfig->spCellConfig->spCellConfigDedicated && + cellGroupConfig->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList) { + delay_ms += NR_RRC_BWP_SWITCH_DELAY_MS; + } + enable_nr_rrc_processing_timer(ctxt_pP->module_id, ue_context_pP, delay_ms); LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Reconfiguration\n"); @@ -1914,6 +1928,8 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP NULL, masterCellGroup); + enable_nr_rrc_processing_timer(ctxt_pP->module_id, ue_context_pP, TX_SL_AHEAD_DELAY + NR_RRC_PROCESSING_DELAY_MS + NR_RRC_BWP_SWITCH_DELAY_MS); + nr_rrc_data_req(ctxt_pP, DCCH, rrc_gNB_mui++,