Implementation of functions required for the BWP switching based on RRC method
This commit is contained in:
@@ -615,6 +615,8 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
LOG_I(NR_MAC,"Modified UE_id %d/%x with CellGroup\n",UE_id,rnti);
|
||||
process_CellGroup(CellGroup,&UE_info->UE_sched_ctrl[UE_id]);
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
sched_ctrl->update_pdsch_ps = true;
|
||||
sched_ctrl->update_pusch_ps = true;
|
||||
const NR_PDSCH_ServingCellConfig_t *pdsch = servingCellConfig ? servingCellConfig->pdsch_ServingCellConfig->choice.setup : NULL;
|
||||
if (sched_ctrl->available_dl_harq.len == 0) {
|
||||
// add all available DL HARQ processes for this UE in SA
|
||||
|
||||
@@ -346,6 +346,9 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
LOG_I(NR_MAC,"Frame.Slot %d.%d\n%s\n",frame,slot,stats_output);
|
||||
}
|
||||
|
||||
// This schedules the BWP switching
|
||||
schedule_nr_bwp_switch(module_idP, frame, slot);
|
||||
|
||||
// This schedules MIB
|
||||
schedule_nr_mib(module_idP, frame, slot);
|
||||
|
||||
|
||||
@@ -500,14 +500,14 @@ void nr_store_dlsch_buffer(module_id_t module_id,
|
||||
0);
|
||||
stop_meas(&RC.nrmac[module_id]->rlc_status_ind);
|
||||
}
|
||||
if(sched_ctrl->rlc_status[DL_SCH_LCID_DCCH].bytes_in_buffer > 0){
|
||||
if(sched_ctrl->rlc_status[DL_SCH_LCID_DCCH].bytes_in_buffer > 0) {
|
||||
lcid = DL_SCH_LCID_DCCH;
|
||||
}
|
||||
else if (sched_ctrl->rlc_status[DL_SCH_LCID_DCCH1].bytes_in_buffer > 0)
|
||||
{
|
||||
} else if (sched_ctrl->rlc_status[DL_SCH_LCID_DCCH1].bytes_in_buffer > 0) {
|
||||
lcid = DL_SCH_LCID_DCCH1;
|
||||
}else{
|
||||
lcid = DL_SCH_LCID_DTCH;
|
||||
} else if (sched_ctrl->bwp_switch_info.bwp_switch_state != BWP_SWITCH_RUNNING) {
|
||||
lcid = DL_SCH_LCID_DTCH;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer;
|
||||
@@ -577,8 +577,10 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
}
|
||||
/* check whether we need to switch the TDA allocation since the last
|
||||
* (re-)transmission */
|
||||
if (ps->time_domain_allocation != tda)
|
||||
if (ps->time_domain_allocation != tda || sched_ctrl->update_pdsch_ps) {
|
||||
nr_set_pdsch_semi_static(scc, cg, sched_ctrl->active_bwp, bwpd, tda, f, ps);
|
||||
sched_ctrl->update_pdsch_ps = false;
|
||||
}
|
||||
} else {
|
||||
/* the retransmission will use a different time domain allocation, check
|
||||
* that we have enough resources */
|
||||
@@ -838,8 +840,10 @@ void pf_dl(module_id_t module_id,
|
||||
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
|
||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||
const long f = (sched_ctrl->active_bwp || bwpd) ? sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats : 0;
|
||||
if (ps->time_domain_allocation != tda)
|
||||
if (ps->time_domain_allocation != tda || sched_ctrl->update_pdsch_ps) {
|
||||
nr_set_pdsch_semi_static(scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, bwpd, tda, f, ps);
|
||||
sched_ctrl->update_pdsch_ps = false;
|
||||
}
|
||||
|
||||
const uint16_t slbitmap = SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols);
|
||||
// Freq-demain allocation
|
||||
@@ -964,6 +968,70 @@ nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id)
|
||||
return nr_fr1_dlsch_preprocessor;
|
||||
}
|
||||
|
||||
void nr_bwp_switch(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int UE_id,
|
||||
int bwp_id) {
|
||||
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
|
||||
switch(sched_ctrl->bwp_switch_info.bwp_switch_state) {
|
||||
|
||||
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;
|
||||
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) {
|
||||
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 ?
|
||||
*servingCellConfig->firstActiveDownlinkBWP_Id : 0;
|
||||
sched_ctrl->active_bwp = bwpList && bwp_id > 0 ? bwpList->list.array[bwp_id - 1] : NULL;
|
||||
const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig ? servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList : NULL;
|
||||
const int ubwp_id = servingCellConfig && servingCellConfig->uplinkConfig && servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id ?
|
||||
*servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id : 0;
|
||||
sched_ctrl->active_ubwp = ubwpList && ubwp_id > 0 ? ubwpList->list.array[ubwp_id - 1] : NULL;
|
||||
sched_ctrl->bwp_switch_info.bwp_switch_state = BWP_SWITCH_INACTIVE;
|
||||
}
|
||||
break;
|
||||
|
||||
case BWP_SWITCH_INACTIVE:
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(1==0,"Invalid bwp switch state\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void schedule_nr_bwp_switch(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot) {
|
||||
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
const NR_list_t *UE_list = &UE_info->list;
|
||||
|
||||
// TODO: Implementation of a algorithm to perform:
|
||||
// - the BWP switch trigger: sched_ctrl->bwp_switch_info.bwp_switch_state = BWP_SWITCH_TO_START
|
||||
// - the BWP selection: sched_ctrl->bwp_switch_info.next_bwp = bwp_id
|
||||
|
||||
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
if(sched_ctrl->bwp_switch_info.bwp_switch_state > BWP_SWITCH_INACTIVE) {
|
||||
nr_bwp_switch(module_id, frame, slot, UE_id, sched_ctrl->bwp_switch_info.next_bwp);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void nr_schedule_ue_spec(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot) {
|
||||
|
||||
@@ -2076,6 +2076,11 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellG
|
||||
scc,
|
||||
genericParameters,
|
||||
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",
|
||||
|
||||
@@ -983,8 +983,11 @@ bool allocate_ul_retransmission(module_id_t module_id,
|
||||
|
||||
if (ps->time_domain_allocation != tda
|
||||
|| ps->dci_format != dci_format
|
||||
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
|
||||
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data
|
||||
|| sched_ctrl->update_pusch_ps) {
|
||||
nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
|
||||
sched_ctrl->update_pusch_ps = false;
|
||||
}
|
||||
LOG_D(NR_MAC, "%s(): retransmission keeping TDA %d and TBS %d\n", __func__, tda, retInfo->tb_size);
|
||||
} else {
|
||||
/* the retransmission will use a different time domain allocation, check
|
||||
@@ -1163,6 +1166,10 @@ void pf_ul(module_id_t module_id,
|
||||
if (B == 0 && !do_sched)
|
||||
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) {
|
||||
@@ -1220,8 +1227,11 @@ void pf_ul(module_id_t module_id,
|
||||
const int tda = sched_ctrl->active_ubwp ? nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0;
|
||||
if (ps->time_domain_allocation != tda
|
||||
|| ps->dci_format != dci_format
|
||||
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
|
||||
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data
|
||||
|| sched_ctrl->update_pusch_ps) {
|
||||
nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
|
||||
sched_ctrl->update_pusch_ps = false;
|
||||
}
|
||||
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
|
||||
sched_pusch->mcs = 9;
|
||||
update_ul_ue_R_Qm(sched_pusch, ps);
|
||||
@@ -1337,8 +1347,11 @@ void pf_ul(module_id_t module_id,
|
||||
const int tda = sched_ctrl->active_ubwp ? nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0;
|
||||
if (ps->time_domain_allocation != tda
|
||||
|| ps->dci_format != dci_format
|
||||
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
|
||||
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data
|
||||
|| sched_ctrl->update_pusch_ps) {
|
||||
nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
|
||||
sched_ctrl->update_pusch_ps = false;
|
||||
}
|
||||
update_ul_ue_R_Qm(sched_pusch, ps);
|
||||
|
||||
/* Calculate the current scheduling bytes and the necessary RBs */
|
||||
|
||||
@@ -64,6 +64,10 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
|
||||
void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
frame_t frame_rxP, sub_frame_t slot_rxP);
|
||||
|
||||
void schedule_nr_bwp_switch(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot);
|
||||
|
||||
/* \brief main DL scheduler function. Calls a preprocessor to decide on
|
||||
* resource allocation, then "post-processes" resource allocation (nFAPI
|
||||
* messages, statistics, HARQ handling, CEs, ... */
|
||||
|
||||
@@ -551,6 +551,20 @@ typedef struct NR_UE_ul_harq {
|
||||
NR_sched_pusch_t sched_pusch;
|
||||
} NR_UE_ul_harq_t;
|
||||
|
||||
typedef enum {
|
||||
BWP_SWITCH_INACTIVE = 0,
|
||||
BWP_SWITCH_TO_START,
|
||||
BWP_SWITCH_RUNNING
|
||||
} NR_BWP_switch_states_t;
|
||||
|
||||
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;
|
||||
NR_BWP_switch_states_t bwp_switch_state;
|
||||
} NR_BWP_switch_info_t;
|
||||
|
||||
/*! \brief scheduling control information set through an API */
|
||||
#define MAX_CSI_REPORTS 48
|
||||
typedef struct {
|
||||
@@ -558,6 +572,10 @@ typedef struct {
|
||||
NR_BWP_Downlink_t *active_bwp;
|
||||
/// the currently active BWP in UL
|
||||
NR_BWP_Uplink_t *active_ubwp;
|
||||
|
||||
/// the state of bwp switch procedure
|
||||
NR_BWP_switch_info_t bwp_switch_info;
|
||||
|
||||
/// CCE index and aggregation, should be coherent with cce_list
|
||||
NR_SearchSpace_t *search_space;
|
||||
NR_ControlResourceSet_t *coreset;
|
||||
@@ -624,7 +642,8 @@ typedef struct {
|
||||
int ul_failure;
|
||||
struct CSI_Report CSI_report[MAX_CSI_REPORTS];
|
||||
bool SR;
|
||||
|
||||
bool update_pdsch_ps;
|
||||
bool update_pusch_ps;
|
||||
/// information about every HARQ process
|
||||
NR_UE_harq_t harq_processes[NR_MAX_NB_HARQ_PROCESSES];
|
||||
/// HARQ processes that are free
|
||||
|
||||
@@ -304,6 +304,19 @@ uint16_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
|
||||
|
||||
}
|
||||
|
||||
int8_t nr_mac_rrc_bwp_switch_req(const module_id_t module_idP,
|
||||
const frame_t frameP,
|
||||
const sub_frame_t sub_frameP,
|
||||
const rnti_t rntiP,
|
||||
const int bwp_id) {
|
||||
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[module_idP], rntiP);
|
||||
|
||||
protocol_ctxt_t ctxt;
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, GNB_FLAG_YES, rntiP, frameP, sub_frameP, 0);
|
||||
nr_rrc_reconfiguration_req(ue_context_p, &ctxt, bwp_id);
|
||||
}
|
||||
|
||||
int8_t nr_mac_rrc_data_ind(const module_id_t module_idP,
|
||||
const int CC_id,
|
||||
const frame_t frameP,
|
||||
|
||||
@@ -2493,7 +2493,9 @@ int16_t do_RRCReconfiguration(
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
return -1;
|
||||
}
|
||||
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)cellGroupConfig);
|
||||
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
|
||||
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig);
|
||||
}
|
||||
ie->nonCriticalExtension->masterCellGroup = calloc(1,sizeof(OCTET_STRING_t));
|
||||
|
||||
ie->nonCriticalExtension->masterCellGroup->buf = masterCellGroup_buf;
|
||||
@@ -2502,9 +2504,9 @@ int16_t do_RRCReconfiguration(
|
||||
|
||||
dl_dcch_msg.message.choice.c1->choice.rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration = ie;
|
||||
|
||||
//if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
|
||||
xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg);
|
||||
//}
|
||||
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
|
||||
xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg);
|
||||
}
|
||||
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_DCCH_Message,
|
||||
NULL,
|
||||
|
||||
@@ -178,6 +178,12 @@ int
|
||||
nr_rrc_mac_remove_ue(module_id_t mod_idP,
|
||||
rnti_t rntiP);
|
||||
|
||||
int8_t nr_mac_rrc_bwp_switch_req(const module_id_t module_idP,
|
||||
const frame_t frameP,
|
||||
const sub_frame_t sub_frameP,
|
||||
const rnti_t rntiP,
|
||||
const int bwp_id);
|
||||
|
||||
int8_t nr_mac_rrc_data_ind(
|
||||
const module_id_t module_idP,
|
||||
const int CC_id,
|
||||
@@ -191,6 +197,10 @@ int8_t nr_mac_rrc_data_ind(
|
||||
const boolean_t brOption
|
||||
);
|
||||
|
||||
int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
protocol_ctxt_t *const ctxt_pP,
|
||||
const int bwp_id);
|
||||
|
||||
int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP,
|
||||
const uint8_t *buffer,
|
||||
int buffer_length,
|
||||
|
||||
@@ -1775,6 +1775,44 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete(
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
protocol_ctxt_t *const ctxt_pP,
|
||||
const int bwp_id) {
|
||||
|
||||
uint8_t buffer[RRC_BUF_SIZE];
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
|
||||
|
||||
NR_CellGroupConfig_t *masterCellGroup = ue_context_pP->ue_context.masterCellGroup;
|
||||
*masterCellGroup->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id = bwp_id;
|
||||
*masterCellGroup->spCellConfig->spCellConfigDedicated->defaultDownlinkBWP_Id = bwp_id;
|
||||
*masterCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id = bwp_id;
|
||||
|
||||
uint16_t size = do_RRCReconfiguration(ctxt_pP,
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
xid,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
masterCellGroup);
|
||||
|
||||
nr_rrc_data_req(ctxt_pP,
|
||||
DCCH,
|
||||
rrc_gNB_mui++,
|
||||
SDU_CONFIRM_NO,
|
||||
size,
|
||||
buffer,
|
||||
PDCP_TRANSMISSION_MODE_CONTROL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP,
|
||||
const uint8_t *buffer,
|
||||
|
||||
Reference in New Issue
Block a user