mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-19 15:40:30 +00:00
Use list of UEs during RA instead of array of RA processes
- rewrite add_UE_to_list() and rewrite remove_UE_from_list() to simplify list handling - return pointer from get_new_nr_ue_inst(); it's completely freed by delete_nr_ue_data() - have add_new_UE_RA() add UE context to access list; remove with nr_release_ra_UE() - have add_connected_nr_ue() only add UE to connected list; to move from access to connected use transition_ra_connected_nr_ue(); remove with mac_remove_nr_ue() as previously - free memory on problems during RA - add some documentation - in NSA/HO: check for pre-configured RA process - there are asserts in all functions to clarify when a UE has RA
This commit is contained in:
committed by
Robert Schmidt
parent
a7c199cabf
commit
8f62baefa6
@@ -185,7 +185,7 @@ int g_mcsIndex = -1, g_mcsTableIdx = 0, g_rbStart = -1, g_rbSize = -1, g_nrOfLay
|
||||
void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot)
|
||||
{
|
||||
NR_UE_info_t *UE_info = RC.nrmac[module_id]->UE_info.connected_ue_list[0];
|
||||
AssertFatal(RC.nrmac[module_id]->UE_info.connected_ue_list[1] == NULL, "can have only a single UE\n");
|
||||
AssertFatal(RC.nrmac[module_id]->UE_info.connected_ue_list[1] == NULL, "Only single UE allowed in dlsim\n");
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl;
|
||||
NR_UE_DL_BWP_t *current_BWP = &UE_info->current_DL_BWP;
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[0]->common_channels[0].ServingCellConfigCommon;
|
||||
@@ -804,7 +804,7 @@ printf("%d\n", slot);
|
||||
N_RB_DL = gNB->frame_parms.N_RB_DL;
|
||||
NR_UE_info_t *UE_info = RC.nrmac[0]->UE_info.connected_ue_list[0];
|
||||
|
||||
configure_UE_BWP(RC.nrmac[0], scc, &UE_info->UE_sched_ctrl, NULL, UE_info, -1, -1);
|
||||
configure_UE_BWP(RC.nrmac[0], scc, UE_info, false, -1, -1);
|
||||
|
||||
// stub to configure frame_parms
|
||||
// nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions);
|
||||
|
||||
@@ -858,14 +858,6 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, c
|
||||
|
||||
find_SSB_and_RO_available(nrmac);
|
||||
|
||||
NR_COMMON_channels_t *cc = &nrmac->common_channels[0];
|
||||
NR_SCHED_LOCK(&nrmac->sched_lock);
|
||||
for (int n = 0; n < NR_NB_RA_PROC_MAX; n++) {
|
||||
NR_RA_t *ra = &cc->ra[n];
|
||||
nr_clear_ra_proc(ra);
|
||||
}
|
||||
NR_SCHED_UNLOCK(&nrmac->sched_lock);
|
||||
|
||||
if (IS_SA_MODE(get_softmodem_params()))
|
||||
config_sched_ctrlCommon(nrmac);
|
||||
}
|
||||
@@ -979,18 +971,17 @@ bool nr_mac_add_test_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t
|
||||
DevAssert(get_softmodem_params()->phy_test);
|
||||
NR_SCHED_LOCK(&nrmac->sched_lock);
|
||||
|
||||
NR_UE_info_t *UE = add_new_nr_ue(nrmac, rnti, CellGroup);
|
||||
if (!UE) {
|
||||
NR_UE_info_t *UE = get_new_nr_ue_inst(&nrmac->UE_info.uid_allocator, rnti, CellGroup);
|
||||
DevAssert(UE != NULL); // test-mode: we assume we can always create a UE
|
||||
free_and_zero(UE->ra); // test-mode (sims, phy-test): UE will not do RA
|
||||
bool res = add_connected_nr_ue(nrmac, UE);
|
||||
if (!res) {
|
||||
LOG_E(NR_MAC, "Error adding UE %04x\n", rnti);
|
||||
delete_nr_ue_data(UE, NULL, &nrmac->UE_info.uid_allocator);
|
||||
NR_SCHED_UNLOCK(&nrmac->sched_lock);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (CellGroup->spCellConfig && CellGroup->spCellConfig->reconfigurationWithSync
|
||||
&& CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated
|
||||
&& CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra) {
|
||||
nr_mac_prepare_ra_ue(RC.nrmac[0], UE->rnti, CellGroup);
|
||||
}
|
||||
configure_UE_BWP(nrmac, nrmac->common_channels[0].ServingCellConfigCommon, UE, false, -1, -1);
|
||||
process_addmod_bearers_cellGroupConfig(&UE->UE_sched_ctrl, CellGroup->rlc_BearerToAddModList);
|
||||
AssertFatal(CellGroup->rlc_BearerToReleaseList == NULL, "cannot release bearers while adding new UEs\n");
|
||||
NR_SCHED_UNLOCK(&nrmac->sched_lock);
|
||||
@@ -998,32 +989,18 @@ bool nr_mac_add_test_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nr_mac_prepare_ra_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup)
|
||||
void nr_mac_prepare_ra_ue(gNB_MAC_INST *nrmac, NR_UE_info_t *UE)
|
||||
{
|
||||
DevAssert(nrmac != NULL);
|
||||
DevAssert(CellGroup != NULL);
|
||||
NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
|
||||
|
||||
// NSA case: need to pre-configure CFRA
|
||||
const int CC_id = 0;
|
||||
NR_COMMON_channels_t *cc = &nrmac->common_channels[CC_id];
|
||||
uint8_t ra_index = 0;
|
||||
/* checking for free RA process */
|
||||
for(; ra_index < NR_NB_RA_PROC_MAX; ra_index++) {
|
||||
if ((cc->ra[ra_index].ra_state == nrRA_gNB_IDLE) && (!cc->ra[ra_index].cfra))
|
||||
break;
|
||||
}
|
||||
if (ra_index == NR_NB_RA_PROC_MAX) {
|
||||
LOG_E(NR_MAC, "RA processes are not available for CFRA RNTI %04x\n", rnti);
|
||||
return false;
|
||||
}
|
||||
NR_RA_t *ra = &cc->ra[ra_index];
|
||||
NR_RA_t *ra = UE->ra;
|
||||
ra->cfra = true;
|
||||
ra->rnti = rnti;
|
||||
ra->CellGroup = CellGroup;
|
||||
NR_CellGroupConfig_t *CellGroup = UE->CellGroup;
|
||||
DevAssert(CellGroup != NULL);
|
||||
struct NR_CFRA *cfra = CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra;
|
||||
uint8_t num_preamble = cfra->resources.choice.ssb->ssb_ResourceList.list.count;
|
||||
ra->preambles.num_preambles = num_preamble;
|
||||
NR_COMMON_channels_t *cc = &nrmac->common_channels[0];
|
||||
for (int i = 0; i < cc->num_active_ssb; i++) {
|
||||
for (int j = 0; j < num_preamble; j++) {
|
||||
if (cc->ssb_index[i] == cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ssb) {
|
||||
@@ -1033,8 +1010,7 @@ bool nr_mac_prepare_ra_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG_I(NR_MAC, "Added new %s process for UE RNTI %04x with initial CellGroup\n", ra->cfra ? "CFRA" : "CBRA", rnti);
|
||||
return true;
|
||||
LOG_I(NR_MAC, "Added new %s process for UE RNTI %04x with initial CellGroup\n", ra->cfra ? "CFRA" : "CBRA", UE->rnti);
|
||||
}
|
||||
|
||||
/* Prepare a new CellGroupConfig to be applied for this UE. We cannot
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -609,9 +609,6 @@ static void pf_dl(module_id_t module_id,
|
||||
|
||||
/* Loop UE_info->list to check retransmission */
|
||||
UE_iterator(UE_list, UE) {
|
||||
if (!UE->Msg4_MsgB_ACKed)
|
||||
continue;
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
NR_UE_DL_BWP_t *current_BWP = &UE->current_DL_BWP;
|
||||
|
||||
|
||||
@@ -2060,7 +2060,6 @@ void remove_front_nr_list(NR_list_t *listP)
|
||||
|
||||
NR_UE_info_t *find_nr_UE(NR_UEs_t *UEs, rnti_t rntiP)
|
||||
{
|
||||
|
||||
UE_iterator(UEs->connected_ue_list, UE) {
|
||||
if (UE->rnti == rntiP) {
|
||||
LOG_D(NR_MAC,"Search and found rnti: %04x\n", rntiP);
|
||||
@@ -2070,6 +2069,17 @@ NR_UE_info_t *find_nr_UE(NR_UEs_t *UEs, rnti_t rntiP)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NR_UE_info_t *find_ra_UE(NR_UEs_t *UEs, rnti_t rntiP)
|
||||
{
|
||||
UE_iterator(UEs->access_ue_list, UE) {
|
||||
if (UE->rnti == rntiP) {
|
||||
LOG_D(NR_MAC,"Search and found rnti: %04x\n", rntiP);
|
||||
return UE;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_allocator_t *uia)
|
||||
{
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup);
|
||||
@@ -2088,6 +2098,7 @@ void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_alloca
|
||||
free_sched_pucch_list(sched_ctrl);
|
||||
uid_linear_allocator_free(uia, UE->uid);
|
||||
LOG_I(NR_MAC, "Remove NR rnti 0x%04x\n", UE->rnti);
|
||||
free(UE->ra);
|
||||
free(UE);
|
||||
}
|
||||
|
||||
@@ -2195,31 +2206,16 @@ static void set_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl,
|
||||
// main function to configure parameters of current BWP
|
||||
void configure_UE_BWP(gNB_MAC_INST *nr_mac,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
NR_UE_sched_ctrl_t *sched_ctrl,
|
||||
NR_RA_t *ra,
|
||||
NR_UE_info_t *UE,
|
||||
bool is_RA,
|
||||
int dl_bwp_switch,
|
||||
int ul_bwp_switch)
|
||||
{
|
||||
AssertFatal((ra != NULL && UE == NULL) || (ra == NULL && UE != NULL), "RA and UE structures are mutually exlusive in BWP configuration\n");
|
||||
NR_CellGroupConfig_t *CellGroup = UE->CellGroup;
|
||||
NR_UE_ServingCell_Info_t *sc_info = &UE->sc_info;
|
||||
NR_UE_DL_BWP_t *DL_BWP = &UE->current_DL_BWP;
|
||||
NR_UE_UL_BWP_t *UL_BWP = &UE->current_UL_BWP;
|
||||
|
||||
NR_CellGroupConfig_t *CellGroup;
|
||||
NR_UE_ServingCell_Info_t *sc_info;
|
||||
NR_UE_DL_BWP_t *DL_BWP;
|
||||
NR_UE_UL_BWP_t *UL_BWP;
|
||||
|
||||
if (ra) {
|
||||
DL_BWP = &ra->DL_BWP;
|
||||
UL_BWP = &ra->UL_BWP;
|
||||
CellGroup = ra->CellGroup;
|
||||
sc_info = &ra->sc_info;
|
||||
}
|
||||
else {
|
||||
DL_BWP = &UE->current_DL_BWP;
|
||||
UL_BWP = &UE->current_UL_BWP;
|
||||
CellGroup = UE->CellGroup;
|
||||
sc_info = &UE->sc_info;
|
||||
}
|
||||
NR_BWP_Downlink_t *dl_bwp = NULL;
|
||||
NR_BWP_Uplink_t *ul_bwp = NULL;
|
||||
NR_BWP_DownlinkDedicated_t *bwpd = NULL;
|
||||
@@ -2229,13 +2225,10 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac,
|
||||
sc_info->n_ul_bwp = 0;
|
||||
int old_dl_bwp_id = DL_BWP->bwp_id;
|
||||
int old_ul_bwp_id = UL_BWP->bwp_id;
|
||||
|
||||
int target_ss;
|
||||
|
||||
NR_ServingCellConfig_t *servingCellConfig = NULL;
|
||||
if (CellGroup &&
|
||||
CellGroup->spCellConfig &&
|
||||
CellGroup->spCellConfig->spCellConfigDedicated) {
|
||||
if (CellGroup && CellGroup->spCellConfig && CellGroup->spCellConfig->spCellConfigDedicated) {
|
||||
|
||||
servingCellConfig = CellGroup->spCellConfig->spCellConfigDedicated;
|
||||
target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
|
||||
@@ -2359,7 +2352,10 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac,
|
||||
UL_BWP->rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
|
||||
}
|
||||
|
||||
if(UE) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
// Reset required fields in sched_ctrl (e.g. ul_ri and tpmi)
|
||||
reset_sched_ctrl(sched_ctrl);
|
||||
if(!is_RA) {
|
||||
if (servingCellConfig) {
|
||||
if (servingCellConfig->csi_MeasConfig) {
|
||||
sc_info->csi_MeasConfig = servingCellConfig->csi_MeasConfig->choice.setup;
|
||||
@@ -2403,18 +2399,9 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac,
|
||||
if (CellGroup && CellGroup->physicalCellGroupConfig)
|
||||
UE->pdsch_HARQ_ACK_Codebook = CellGroup->physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook;
|
||||
|
||||
// Reset required fields in sched_ctrl (e.g. ul_ri and tpmi)
|
||||
reset_sched_ctrl(sched_ctrl);
|
||||
|
||||
// setting PDCCH related structures for sched_ctrl
|
||||
sched_ctrl->search_space = get_searchspace(scc,
|
||||
bwpd,
|
||||
target_ss);
|
||||
sched_ctrl->coreset = get_coreset(nr_mac,
|
||||
scc,
|
||||
bwpd,
|
||||
sched_ctrl->search_space,
|
||||
target_ss);
|
||||
sched_ctrl->search_space = get_searchspace(scc, bwpd, target_ss);
|
||||
sched_ctrl->coreset = get_coreset(nr_mac, scc, bwpd, sched_ctrl->search_space, target_ss);
|
||||
|
||||
sched_ctrl->sched_pdcch = set_pdcch_structure(nr_mac,
|
||||
sched_ctrl->search_space,
|
||||
@@ -2436,11 +2423,7 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac,
|
||||
NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0) :
|
||||
NR_UL_DCI_FORMAT_0_0;
|
||||
|
||||
set_max_fb_time(UL_BWP, DL_BWP);
|
||||
set_sched_pucch_list(sched_ctrl, UL_BWP, scc, &nr_mac->frame_structure);
|
||||
}
|
||||
|
||||
if(ra) {
|
||||
} else {
|
||||
// setting PDCCH related structures for RA
|
||||
struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = NULL;
|
||||
NR_SearchSpaceId_t ra_SearchSpace = 0;
|
||||
@@ -2453,26 +2436,29 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac,
|
||||
}
|
||||
AssertFatal(commonSearchSpaceList->list.count > 0, "common SearchSpace list has 0 elements\n");
|
||||
for (int i = 0; i < commonSearchSpaceList->list.count; i++) {
|
||||
NR_SearchSpace_t * ss = commonSearchSpaceList->list.array[i];
|
||||
NR_SearchSpace_t *ss = commonSearchSpaceList->list.array[i];
|
||||
if (ss->searchSpaceId == ra_SearchSpace)
|
||||
ra->ra_ss = ss;
|
||||
sched_ctrl->search_space = ss;
|
||||
}
|
||||
AssertFatal(ra->ra_ss!=NULL,"SearchSpace cannot be null for RA\n");
|
||||
AssertFatal(sched_ctrl->search_space != NULL, "SearchSpace cannot be null for RA\n");
|
||||
|
||||
ra->coreset = get_coreset(nr_mac, scc, dl_bwp, ra->ra_ss, NR_SearchSpace__searchSpaceType_PR_common);
|
||||
sched_ctrl->coreset = get_coreset(nr_mac, scc, dl_bwp, sched_ctrl->search_space, NR_SearchSpace__searchSpaceType_PR_common);
|
||||
NR_COMMON_channels_t *cc = &nr_mac->common_channels[0];
|
||||
int ssb_index = cc->ssb_index[ra->beam_id];
|
||||
ra->sched_pdcch = set_pdcch_structure(nr_mac,
|
||||
ra->ra_ss,
|
||||
ra->coreset,
|
||||
scc,
|
||||
&dl_genericParameters,
|
||||
&nr_mac->type0_PDCCH_CSS_config[ssb_index]);
|
||||
int ssb_index = cc->ssb_index[UE->UE_beam_index];
|
||||
sched_ctrl->sched_pdcch = set_pdcch_structure(nr_mac,
|
||||
sched_ctrl->search_space,
|
||||
sched_ctrl->coreset,
|
||||
scc,
|
||||
&dl_genericParameters,
|
||||
&nr_mac->type0_PDCCH_CSS_config[ssb_index]);
|
||||
|
||||
UL_BWP->dci_format = NR_UL_DCI_FORMAT_0_0;
|
||||
DL_BWP->dci_format = NR_DL_DCI_FORMAT_1_0;
|
||||
}
|
||||
|
||||
set_max_fb_time(UL_BWP, DL_BWP);
|
||||
set_sched_pucch_list(sched_ctrl, UL_BWP, scc, &nr_mac->frame_structure);
|
||||
|
||||
// Set MCS tables
|
||||
long *dl_mcs_Table = DL_BWP->pdsch_Config ? DL_BWP->pdsch_Config->mcs_Table : NULL;
|
||||
DL_BWP->mcsTableIdx = get_pdsch_mcs_table(dl_mcs_Table, DL_BWP->dci_format, TYPE_C_RNTI_, target_ss);
|
||||
@@ -2482,9 +2468,7 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac,
|
||||
// Set uplink MCS table
|
||||
long *mcs_Table = NULL;
|
||||
if (UL_BWP->pusch_Config)
|
||||
mcs_Table = UL_BWP->transform_precoding ?
|
||||
UL_BWP->pusch_Config->mcs_Table :
|
||||
UL_BWP->pusch_Config->mcs_TableTransformPrecoder;
|
||||
mcs_Table = UL_BWP->transform_precoding ? UL_BWP->pusch_Config->mcs_Table : UL_BWP->pusch_Config->mcs_TableTransformPrecoder;
|
||||
|
||||
UL_BWP->mcs_table = get_pusch_mcs_table(mcs_Table, !UL_BWP->transform_precoding, UL_BWP->dci_format, TYPE_C_RNTI_, target_ss, false);
|
||||
}
|
||||
@@ -2502,49 +2486,29 @@ static void init_bler_stats(const NR_bler_options_t *bler_options, NR_bler_stats
|
||||
bler_stats->bler = (float)(bler_options->lower + bler_options->upper) / 2.0f;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConfig_t *CellGroup)
|
||||
/* @brief returns a new UE allocated instance.
|
||||
*
|
||||
* It will be typically added to the access_ue_list, but not always (e.g.,
|
||||
* phytest mode), so this is not done in this function (and also, to allow
|
||||
* error handling). Remove with delete_nr_ue_data(). */
|
||||
NR_UE_info_t *get_new_nr_ue_inst(uid_allocator_t *uia, rnti_t rnti, NR_CellGroupConfig_t *CellGroup)
|
||||
{
|
||||
NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels[0].ServingCellConfigCommon;
|
||||
NR_UEs_t *UE_info = &nr_mac->UE_info;
|
||||
LOG_I(NR_MAC, "Adding new UE context with RNTI 0x%04x\n", rntiP);
|
||||
dump_nr_list(UE_info->connected_ue_list);
|
||||
|
||||
// We will attach at the end, to mitigate race conditions
|
||||
// This is not good, but we will fix it progressively
|
||||
NR_UE_info_t *UE = calloc(1, sizeof(NR_UE_info_t));
|
||||
if(!UE) {
|
||||
LOG_E(NR_MAC,"want to add UE %04x but the fixed allocated size is full\n",rntiP);
|
||||
uid_t uid = uid_linear_allocator_new(uia);
|
||||
/* if the UE list is full, we should reject the UE with an RRC reject
|
||||
* message, but we do not have this functionality. To keep it simple, do not
|
||||
* create a UE context here, so we can print an error message. */
|
||||
if (uid >= MAX_MOBILES_PER_GNB) {
|
||||
uid_linear_allocator_free(uia, uid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
UE->rnti = rntiP;
|
||||
UE->uid = uid_linear_allocator_new(&UE_info->uid_allocator);
|
||||
NR_UE_info_t *UE = calloc_or_fail(1, sizeof(NR_UE_info_t));
|
||||
UE->rnti = rnti;
|
||||
UE->CellGroup = CellGroup;
|
||||
|
||||
UE->Msg4_MsgB_ACKed = CellGroup != NULL;
|
||||
|
||||
UE->uid = uid;
|
||||
UE->ra = calloc(1, sizeof(*UE->ra));
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
memset(sched_ctrl, 0, sizeof(*sched_ctrl));
|
||||
sched_ctrl->dl_max_mcs = 28; /* do not limit MCS for individual UEs */
|
||||
sched_ctrl->ta_update = 31;
|
||||
sched_ctrl->sched_srs.frame = -1;
|
||||
sched_ctrl->sched_srs.slot = -1;
|
||||
sched_ctrl->pdcch_cl_adjust = 0;
|
||||
|
||||
// Initialize bler_stats
|
||||
init_bler_stats(&nr_mac->dl_bler, &sched_ctrl->dl_bler_stats, nr_mac->frame);
|
||||
init_bler_stats(&nr_mac->ul_bler, &sched_ctrl->ul_bler_stats, nr_mac->frame);
|
||||
|
||||
// initialize LCID structure
|
||||
seq_arr_init(&sched_ctrl->lc_config, sizeof(nr_lc_config_t));
|
||||
|
||||
// initialize UE BWP information
|
||||
NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP;
|
||||
memset(dl_bwp, 0, sizeof(*dl_bwp));
|
||||
NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
|
||||
memset(ul_bwp, 0, sizeof(*ul_bwp));
|
||||
configure_UE_BWP(nr_mac, scc, sched_ctrl, NULL, UE, -1, -1);
|
||||
|
||||
/* set illegal time domain allocation to force recomputation of all fields */
|
||||
sched_ctrl->sched_pdsch.time_domain_allocation = -1;
|
||||
@@ -2558,27 +2522,87 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf
|
||||
create_dl_harq_list(sched_ctrl, &UE->sc_info);
|
||||
create_ul_harq_list(sched_ctrl, &UE->sc_info);
|
||||
|
||||
reset_srs_stats(UE);
|
||||
// initialize LCID structure
|
||||
seq_arr_init(&sched_ctrl->lc_config, sizeof(nr_lc_config_t));
|
||||
return UE;
|
||||
}
|
||||
|
||||
NR_SCHED_LOCK(&UE_info->mutex);
|
||||
int i;
|
||||
for(i=0; i<MAX_MOBILES_PER_GNB; i++) {
|
||||
if (UE_info->connected_ue_list[i] == NULL) {
|
||||
UE_info->connected_ue_list[i] = UE;
|
||||
break;
|
||||
bool add_UE_to_list(int list_size, NR_UE_info_t *list[list_size], NR_UE_info_t *UE)
|
||||
{
|
||||
for (int i = 0; i < list_size; i++) {
|
||||
if (!list[i]) {
|
||||
list[i] = UE;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (i == MAX_MOBILES_PER_GNB) {
|
||||
LOG_E(NR_MAC,"Try to add UE %04x but the list is full\n", rntiP);
|
||||
delete_nr_ue_data(UE, nr_mac->common_channels, &UE_info->uid_allocator);
|
||||
NR_SCHED_UNLOCK(&UE_info->mutex);
|
||||
return NULL;
|
||||
}
|
||||
NR_SCHED_UNLOCK(&UE_info->mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_D(NR_MAC, "Add NR rnti %x\n", rntiP);
|
||||
NR_UE_info_t *remove_UE_from_list(int list_size, NR_UE_info_t *list[list_size], rnti_t rnti)
|
||||
{
|
||||
for (int i = 0; i < list_size; i++) {
|
||||
NR_UE_info_t *curr_UE = list[i];
|
||||
if (curr_UE->rnti != rnti)
|
||||
continue;
|
||||
|
||||
/* remove this UE from the list, return the pointer */
|
||||
memmove(&list[i], &list[i+1], sizeof(list[0]) * (list_size - i - 1));
|
||||
list[list_size - 1] = NULL;
|
||||
return curr_UE;
|
||||
}
|
||||
LOG_E(NR_MAC, "UE %04x to be removed not found in list\n", rnti);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** @brief Transitions a UE from access list to connected list (i.e., the RA
|
||||
* list to the "normal" UE context list. */
|
||||
bool transition_ra_connected_nr_ue(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE)
|
||||
{
|
||||
NR_UEs_t *UE_info = &nr_mac->UE_info;
|
||||
|
||||
// remove UE from initial access list (moved to connected mode)
|
||||
NR_UE_info_t *r = remove_UE_from_list(NR_NB_RA_PROC_MAX, UE_info->access_ue_list, UE->rnti);
|
||||
DevAssert(r == UE); /* sanity check: we should have removed the current UE ptr from list */
|
||||
|
||||
free_and_zero(UE->ra);
|
||||
|
||||
return add_connected_nr_ue(nr_mac, UE);
|
||||
}
|
||||
|
||||
/** @brief Add a UE to the list of UEs in * connected mode.
|
||||
*
|
||||
* To remove the UE, use mac_remove_nr_ue(). */
|
||||
bool add_connected_nr_ue(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE)
|
||||
{
|
||||
LOG_I(NR_MAC, "Adding new UE context with RNTI 0x%04x\n", UE->rnti);
|
||||
NR_UEs_t *UE_info = &nr_mac->UE_info;
|
||||
dump_nr_list(UE_info->connected_ue_list);
|
||||
return (UE);
|
||||
AssertFatal(!UE->ra, "UE in connected cannot have RA process\n");
|
||||
|
||||
NR_SCHED_LOCK(&UE_info->mutex);
|
||||
|
||||
bool success = add_UE_to_list(MAX_MOBILES_PER_GNB, UE_info->connected_ue_list, UE);
|
||||
if (!success) {
|
||||
LOG_E(NR_MAC,"Try to add UE %04x but the list is full\n", UE->rnti);
|
||||
delete_nr_ue_data(UE, NULL, &UE_info->uid_allocator);
|
||||
NR_SCHED_UNLOCK(&UE_info->mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
sched_ctrl->dl_max_mcs = 28; /* do not limit MCS for individual UEs */
|
||||
sched_ctrl->sched_srs.frame = -1;
|
||||
sched_ctrl->sched_srs.slot = -1;
|
||||
sched_ctrl->pdcch_cl_adjust = 0;
|
||||
reset_srs_stats(UE);
|
||||
|
||||
// Initialize bler_stats
|
||||
init_bler_stats(&nr_mac->dl_bler, &sched_ctrl->dl_bler_stats, nr_mac->frame);
|
||||
init_bler_stats(&nr_mac->ul_bler, &sched_ctrl->ul_bler_stats, nr_mac->frame);
|
||||
|
||||
NR_SCHED_UNLOCK(&UE_info->mutex);
|
||||
dump_nr_list(UE_info->connected_ue_list);
|
||||
return true;
|
||||
}
|
||||
|
||||
void free_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl)
|
||||
@@ -2683,38 +2707,11 @@ void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti)
|
||||
{
|
||||
/* already mutex protected */
|
||||
NR_SCHED_ENSURE_LOCKED(&nr_mac->sched_lock);
|
||||
|
||||
NR_UEs_t *UE_info = &nr_mac->UE_info;
|
||||
NR_SCHED_LOCK(&UE_info->mutex);
|
||||
UE_iterator(UE_info->connected_ue_list, UE) {
|
||||
if (UE->rnti==rnti)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!UE) {
|
||||
LOG_W(NR_MAC,"Call to del rnti %04x, but not existing\n", rnti);
|
||||
NR_SCHED_UNLOCK(&UE_info->mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
NR_UE_info_t * newUEs[MAX_MOBILES_PER_GNB+1]={0};
|
||||
int newListIdx = 0;
|
||||
for (int i = 0; i < MAX_MOBILES_PER_GNB; i++)
|
||||
if(UE_info->connected_ue_list[i] && UE_info->connected_ue_list[i]->rnti != rnti)
|
||||
newUEs[newListIdx++] = UE_info->connected_ue_list[i];
|
||||
memcpy(UE_info->connected_ue_list, newUEs, sizeof(UE_info->connected_ue_list));
|
||||
NR_UE_info_t *UE = remove_UE_from_list(MAX_MOBILES_PER_GNB + 1, UE_info->connected_ue_list, rnti);
|
||||
NR_SCHED_UNLOCK(&UE_info->mutex);
|
||||
|
||||
const int CC_id = 0;
|
||||
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
|
||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
||||
NR_RA_t *ra = &cc->ra[i];
|
||||
if (ra->rnti == UE->rnti) {
|
||||
nr_clear_ra_proc(ra);
|
||||
ra->cfra = 0;
|
||||
}
|
||||
}
|
||||
|
||||
delete_nr_ue_data(UE, nr_mac->common_channels, &UE_info->uid_allocator);
|
||||
}
|
||||
|
||||
@@ -3071,7 +3068,7 @@ static void nr_mac_apply_cellgroup(gNB_MAC_INST *mac, NR_UE_info_t *UE, frame_t
|
||||
NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon;
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
configure_UE_BWP(mac, scc, sched_ctrl, NULL, UE, -1, -1);
|
||||
configure_UE_BWP(mac, scc, UE, false, -1, -1);
|
||||
|
||||
reset_srs_stats(UE);
|
||||
|
||||
@@ -3519,24 +3516,14 @@ bool nr_mac_remove_lcid(NR_UE_sched_ctrl_t *sched_ctrl, long lcid)
|
||||
return true;
|
||||
}
|
||||
|
||||
static const NR_RA_t *find_nr_RA_rnti(const NR_RA_t *ra_base, int ra_count, rnti_t rnti)
|
||||
{
|
||||
for (int i = 0; i < ra_count; ++i) {
|
||||
const NR_RA_t *ra = &ra_base[i];
|
||||
if (ra->ra_state != nrRA_gNB_IDLE && ra->rnti == rnti)
|
||||
return ra;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool nr_mac_get_new_rnti(NR_UEs_t *UEs, const NR_RA_t *ra_base, int ra_count, rnti_t *rnti)
|
||||
bool nr_mac_get_new_rnti(NR_UEs_t *UEs, rnti_t *rnti)
|
||||
{
|
||||
int loop = 0;
|
||||
bool exist_connected_ue, exist_in_pending_ra_ue;
|
||||
do {
|
||||
*rnti = (taus() % 0xffef) + 1;
|
||||
exist_connected_ue = find_nr_UE(UEs, *rnti) != NULL;
|
||||
exist_in_pending_ra_ue = find_nr_RA_rnti(ra_base, ra_count, *rnti) != NULL;
|
||||
exist_in_pending_ra_ue = find_ra_UE(UEs, *rnti) != NULL;
|
||||
loop++;
|
||||
} while (loop < 100 && (exist_connected_ue || exist_in_pending_ra_ue));
|
||||
return loop < 100; // nothing found: loop count 100
|
||||
|
||||
@@ -171,39 +171,54 @@ static int get_pucch_index(int frame, int slot, const frame_structure_t *fs, int
|
||||
return (frame_start + ul_period_start + ul_period_slot) % sched_pucch_size;
|
||||
}
|
||||
|
||||
void nr_schedule_pucch(gNB_MAC_INST *nrmac, frame_t frameP, slot_t slotP)
|
||||
static void schedule_pucch_core(gNB_MAC_INST *nrmac, NR_UE_info_t *UE, frame_t frame, slot_t slot)
|
||||
{
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
const int pucch_index = get_pucch_index(frame, slot, &nrmac->frame_structure, sched_ctrl->sched_pucch_size);
|
||||
NR_sched_pucch_t *curr_pucch = &UE->UE_sched_ctrl.sched_pucch[pucch_index];
|
||||
if (!curr_pucch->active)
|
||||
return;
|
||||
if (frame != curr_pucch->frame || slot != curr_pucch->ul_slot) {
|
||||
LOG_E(NR_MAC,
|
||||
"PUCCH frame/slot mismatch: current %4d.%2d vs. request %4d.%2d: not scheduling PUCCH\n",
|
||||
curr_pucch->frame,
|
||||
curr_pucch->ul_slot,
|
||||
frame,
|
||||
slot);
|
||||
memset(curr_pucch, 0, sizeof(*curr_pucch));;
|
||||
return;
|
||||
}
|
||||
|
||||
const uint16_t O_ack = curr_pucch->dai_c;
|
||||
const uint16_t O_csi = curr_pucch->csi_bits;
|
||||
const uint8_t O_sr = curr_pucch->sr_flag;
|
||||
LOG_D(NR_MAC,
|
||||
"Scheduling PUCCH[%d] RX for UE %04x in %4d.%2d O_ack %d, O_sr %d, O_csi %d\n",
|
||||
pucch_index,
|
||||
UE->rnti,
|
||||
curr_pucch->frame,
|
||||
curr_pucch->ul_slot,
|
||||
O_ack,O_sr,
|
||||
O_csi);
|
||||
nr_fill_nfapi_pucch(nrmac, frame, slot, curr_pucch, UE);
|
||||
memset(curr_pucch, 0, sizeof(*curr_pucch));
|
||||
}
|
||||
|
||||
void nr_schedule_pucch(gNB_MAC_INST *nrmac, frame_t frame, slot_t slot)
|
||||
{
|
||||
/* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
|
||||
NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
|
||||
|
||||
if (!is_ul_slot(slotP, &nrmac->frame_structure))
|
||||
if (!is_ul_slot(slot, &nrmac->frame_structure))
|
||||
return;
|
||||
|
||||
UE_iterator(nrmac->UE_info.access_ue_list, init_UE) {
|
||||
if (init_UE->ra->ra_state == nrRA_WAIT_Msg4_MsgB_ACK)
|
||||
schedule_pucch_core(nrmac, init_UE, frame, slot);
|
||||
}
|
||||
|
||||
UE_iterator(nrmac->UE_info.connected_ue_list, UE) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
const int pucch_index = get_pucch_index(frameP, slotP, &nrmac->frame_structure, sched_ctrl->sched_pucch_size);
|
||||
NR_sched_pucch_t *curr_pucch = &UE->UE_sched_ctrl.sched_pucch[pucch_index];
|
||||
if (!curr_pucch->active)
|
||||
continue;
|
||||
if (frameP != curr_pucch->frame || slotP != curr_pucch->ul_slot) {
|
||||
LOG_E(NR_MAC,
|
||||
"PUCCH frame/slot mismatch: current %4d.%2d vs. request %4d.%2d: not scheduling PUCCH\n",
|
||||
curr_pucch->frame,
|
||||
curr_pucch->ul_slot,
|
||||
frameP,
|
||||
slotP);
|
||||
memset(curr_pucch, 0, sizeof(*curr_pucch));;
|
||||
continue;
|
||||
}
|
||||
|
||||
const uint16_t O_ack = curr_pucch->dai_c;
|
||||
const uint16_t O_csi = curr_pucch->csi_bits;
|
||||
const uint8_t O_sr = curr_pucch->sr_flag;
|
||||
LOG_D(NR_MAC,"Scheduling PUCCH[%d] RX for UE %04x in %4d.%2d O_ack %d, O_sr %d, O_csi %d\n",
|
||||
pucch_index,UE->rnti,curr_pucch->frame,curr_pucch->ul_slot,O_ack,O_sr,O_csi);
|
||||
nr_fill_nfapi_pucch(nrmac, frameP, slotP, curr_pucch, UE);
|
||||
memset(curr_pucch, 0, sizeof(*curr_pucch));
|
||||
|
||||
schedule_pucch_core(nrmac, UE, frame, slot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -854,14 +869,19 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, frame_t frame, slot_t slot, con
|
||||
gNB_MAC_INST *nrmac = RC.nrmac[mod_id];
|
||||
int rssi_threshold = nrmac->pucch_rssi_threshold;
|
||||
NR_SCHED_LOCK(&nrmac->sched_lock);
|
||||
NR_UE_info_t * UE = find_nr_UE(&nrmac->UE_info, uci_01->rnti);
|
||||
NR_UE_info_t *UE = find_nr_UE(&nrmac->UE_info, uci_01->rnti);
|
||||
bool is_ra = false;
|
||||
if (!UE) {
|
||||
LOG_E(NR_MAC, "%s(): unknown RNTI %04x in PUCCH UCI\n", __func__, uci_01->rnti);
|
||||
NR_SCHED_UNLOCK(&nrmac->sched_lock);
|
||||
return;
|
||||
UE = find_ra_UE(&nrmac->UE_info, uci_01->rnti);
|
||||
if (UE)
|
||||
is_ra = true;
|
||||
else {
|
||||
LOG_E(NR_MAC, "Unknown RNTI %04x in PUCCH UCI\n", uci_01->rnti);
|
||||
NR_SCHED_UNLOCK(&nrmac->sched_lock);
|
||||
return;
|
||||
}
|
||||
}
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
|
||||
if (((uci_01->pduBitmap >> 1) & 0x01)) {
|
||||
// iterate over received harq bits
|
||||
for (int harq_bit = 0; harq_bit < uci_01->harq.num_harq; harq_bit++) {
|
||||
@@ -877,10 +897,12 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, frame_t frame, slot_t slot, con
|
||||
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,harq_value);
|
||||
nr_mac_update_pdcch_closed_loop_adjust(sched_ctrl, harq_confidence != 0);
|
||||
handle_dl_harq(UE, pid, harq_value == 0 && harq_confidence == 0, nrmac->dl_bler.harq_round_max);
|
||||
if (!UE->Msg4_MsgB_ACKed && harq_value == 0 && harq_confidence == 0)
|
||||
UE->Msg4_MsgB_ACKed = true;
|
||||
if (harq_confidence == 1) UE->mac_stats.pucch0_DTX++;
|
||||
bool success = harq_value == 0 && harq_confidence == 0;
|
||||
handle_dl_harq(UE, pid, success, nrmac->dl_bler.harq_round_max);
|
||||
if (is_ra)
|
||||
nr_check_Msg4_MsgB_Ack(mod_id, frame, slot, UE, success);
|
||||
if (harq_confidence == 1)
|
||||
UE->mac_stats.pucch0_DTX++;
|
||||
}
|
||||
|
||||
// tpc (power control) only if we received AckNack
|
||||
|
||||
@@ -461,17 +461,13 @@ static int nr_process_mac_pdu(instance_t module_idP,
|
||||
break;
|
||||
|
||||
case UL_SCH_LCID_C_RNTI:
|
||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
||||
NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i];
|
||||
if (ra->ra_state == nrRA_gNB_IDLE && ra->rnti == UE->rnti) {
|
||||
// Extract C-RNTI value
|
||||
rnti_t crnti = ((pduP[1] & 0xFF) << 8) | (pduP[2] & 0xFF);
|
||||
AssertFatal(false,
|
||||
"Received MAC CE for C-RNTI %04x without RA running, procedure exists? Or is it a bug while decoding the "
|
||||
"MAC PDU?\n",
|
||||
crnti);
|
||||
break;
|
||||
}
|
||||
if (UE->ra && UE->ra->ra_state == nrRA_gNB_IDLE) {
|
||||
// Extract C-RNTI value
|
||||
rnti_t crnti = ((pduP[1] & 0xFF) << 8) | (pduP[2] & 0xFF);
|
||||
AssertFatal(false,
|
||||
"Received MAC CE for C-RNTI %04x without RA running, procedure exists? Or is it a bug while decoding the "
|
||||
"MAC PDU?\n",
|
||||
crnti);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -547,24 +543,7 @@ static void abort_nr_ul_harq(NR_UE_info_t *UE, int8_t harq_pid)
|
||||
sched_ctrl->sched_ul_bytes = 0;
|
||||
}
|
||||
|
||||
static bool get_UE_waiting_CFRA_msg3(const gNB_MAC_INST *gNB_mac,
|
||||
const int CC_id,
|
||||
const frame_t frame,
|
||||
const slot_t slot,
|
||||
rnti_t rnti)
|
||||
{
|
||||
bool UE_waiting_CFRA_msg3 = false;
|
||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
||||
const NR_RA_t *ra = &gNB_mac->common_channels[CC_id].ra[i];
|
||||
if (ra->cfra && ra->ra_state == nrRA_WAIT_Msg3 && frame == ra->Msg3_frame && slot == ra->Msg3_slot && rnti == ra->rnti) {
|
||||
UE_waiting_CFRA_msg3 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return UE_waiting_CFRA_msg3;
|
||||
}
|
||||
|
||||
void handle_nr_ul_harq(const int CC_idP, module_id_t mod_id, frame_t frame, slot_t slot, const nfapi_nr_crc_t *crc_pdu)
|
||||
void handle_nr_ul_harq(module_id_t mod_id, frame_t frame, slot_t slot, const nfapi_nr_crc_t *crc_pdu)
|
||||
{
|
||||
gNB_MAC_INST *nrmac = RC.nrmac[mod_id];
|
||||
if (nrmac->radio_config.disable_harq) {
|
||||
@@ -573,12 +552,13 @@ void handle_nr_ul_harq(const int CC_idP, module_id_t mod_id, frame_t frame, slot
|
||||
}
|
||||
|
||||
NR_SCHED_LOCK(&nrmac->sched_lock);
|
||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) {
|
||||
NR_RA_t *ra = &nrmac->common_channels[CC_idP].ra[i];
|
||||
NR_UEs_t *UE_info = &nrmac->UE_info;
|
||||
UE_iterator(UE_info->access_ue_list, ra_UE) {
|
||||
const NR_RA_t *ra = ra_UE->ra;
|
||||
// if we find any ongoing RA that has already scheduled MSG3
|
||||
// and it is expecting its reception in current frame and slot with matching RNTI
|
||||
// we can exit the function (no HARQ involved)
|
||||
if (ra->ra_state >= nrRA_WAIT_Msg3 && ra->rnti == crc_pdu->rnti && frame == ra->Msg3_frame && slot == ra->Msg3_slot) {
|
||||
if (ra->ra_state >= nrRA_WAIT_Msg3 && ra_UE->rnti == crc_pdu->rnti && frame == ra->Msg3_frame && slot == ra->Msg3_slot) {
|
||||
LOG_D(NR_MAC, "UL for rnti %04x in RA (MSG3), no need to process HARQ\n", crc_pdu->rnti);
|
||||
NR_SCHED_UNLOCK(&nrmac->sched_lock);
|
||||
return;
|
||||
@@ -586,6 +566,7 @@ void handle_nr_ul_harq(const int CC_idP, module_id_t mod_id, frame_t frame, slot
|
||||
}
|
||||
|
||||
NR_UE_info_t *UE = find_nr_UE(&nrmac->UE_info, crc_pdu->rnti);
|
||||
UE = UE ? UE : find_ra_UE(&nrmac->UE_info, crc_pdu->rnti);
|
||||
if (!UE) {
|
||||
NR_SCHED_UNLOCK(&nrmac->sched_lock);
|
||||
LOG_E(NR_MAC, "Couldn't identify UE connected with current UL HARQ process\n");
|
||||
@@ -641,29 +622,56 @@ void handle_nr_ul_harq(const int CC_idP, module_id_t mod_id, frame_t frame, slot
|
||||
NR_SCHED_UNLOCK(&nrmac->sched_lock);
|
||||
}
|
||||
|
||||
static void handle_msg3_failed_rx(NR_RA_t *ra, int i, int harq_round_max)
|
||||
static void handle_msg3_failed_rx(gNB_MAC_INST *mac, NR_RA_t *ra, rnti_t rnti, int harq_round_max)
|
||||
{
|
||||
// for CFRA (NSA) do not schedule retransmission of msg3
|
||||
if (ra->cfra) {
|
||||
LOG_D(NR_MAC, "Random Access %i failed at state %s (NSA msg3 reception failed)\n", i, nrra_text[ra->ra_state]);
|
||||
nr_clear_ra_proc(ra);
|
||||
LOG_W(NR_MAC, "UE %04x RA failed at state %s (NSA msg3 reception failed)\n", rnti, nrra_text[ra->ra_state]);
|
||||
nr_release_ra_UE(mac, rnti);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ra->msg3_round >= harq_round_max - 1) {
|
||||
LOG_W(NR_MAC, "Random Access %i failed at state %s (Reached msg3 max harq rounds)\n", i, nrra_text[ra->ra_state]);
|
||||
nr_clear_ra_proc(ra);
|
||||
LOG_W(NR_MAC, "UE %04x RA failed at state %s (Reached msg3 max harq rounds)\n", rnti, nrra_text[ra->ra_state]);
|
||||
nr_release_ra_UE(mac, rnti);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_D(NR_MAC, "Random Access %i Msg3 CRC did not pass\n", i);
|
||||
LOG_D(NR_MAC, "UE %04x Msg3 CRC did not pass\n", rnti);
|
||||
ra->msg3_round++;
|
||||
ra->ra_state = nrRA_Msg3_retransmission;
|
||||
}
|
||||
|
||||
/*
|
||||
* When data are received on PHY and transmitted to MAC
|
||||
*/
|
||||
static NR_UE_info_t *configure_UE_crnti_msg3(gNB_MAC_INST *mac, NR_UE_info_t *old_UE, NR_UE_info_t *new_UE)
|
||||
{
|
||||
// in case UE beam has changed
|
||||
old_UE->UE_beam_index = new_UE->UE_beam_index;
|
||||
// Reset UL failure for old UE
|
||||
nr_mac_reset_ul_failure(&old_UE->UE_sched_ctrl);
|
||||
// Reset HARQ processes
|
||||
reset_dl_harq_list(&old_UE->UE_sched_ctrl);
|
||||
reset_ul_harq_list(&old_UE->UE_sched_ctrl);
|
||||
// old UE need to complete RA by sending DL
|
||||
free_and_zero(old_UE->ra);
|
||||
old_UE->ra = new_UE->ra;
|
||||
new_UE->ra = NULL;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &old_UE->UE_sched_ctrl;
|
||||
sched_ctrl->search_space = new_UE->UE_sched_ctrl.search_space;
|
||||
sched_ctrl->coreset = new_UE->UE_sched_ctrl.coreset;
|
||||
memcpy(&sched_ctrl->sched_pdcch, &new_UE->UE_sched_ctrl.sched_pdcch, sizeof(NR_sched_pdcch_t));
|
||||
old_UE->current_DL_BWP.dci_format = NR_DL_DCI_FORMAT_1_0;
|
||||
// replace new UE with old UE in the access list
|
||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
||||
if (mac->UE_info.access_ue_list[i] && mac->UE_info.access_ue_list[i]->rnti == new_UE->rnti) {
|
||||
mac->UE_info.access_ue_list[i] = old_UE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// remove new UE
|
||||
delete_nr_ue_data(new_UE, mac->common_channels, &mac->UE_info.uid_allocator);
|
||||
return old_UE;
|
||||
}
|
||||
|
||||
static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
const int CC_idP,
|
||||
const frame_t frameP,
|
||||
@@ -685,9 +693,8 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
const int pusch_failure_thres = gNB_mac->pusch_failure_thres;
|
||||
|
||||
NR_UE_info_t *UE = find_nr_UE(&gNB_mac->UE_info, current_rnti);
|
||||
bool UE_waiting_CFRA_msg3 = get_UE_waiting_CFRA_msg3(gNB_mac, CC_idP, frameP, slotP, current_rnti);
|
||||
|
||||
if (UE && UE_waiting_CFRA_msg3 == false) {
|
||||
if (UE) {
|
||||
|
||||
NR_UE_sched_ctrl_t *UE_scheduling_control = &UE->UE_sched_ctrl;
|
||||
|
||||
@@ -791,74 +798,45 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
nr_mac_trigger_ul_failure(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs);
|
||||
}
|
||||
}
|
||||
} else if (sduP) {
|
||||
|
||||
bool no_sig = true;
|
||||
for (uint32_t k = 0; k < sdu_lenP; k++) {
|
||||
if (sduP[k] != 0) {
|
||||
no_sig = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
UE = find_ra_UE(&gNB_mac->UE_info, current_rnti);
|
||||
if (!UE) {
|
||||
LOG_E(NR_MAC, "UL SDU discarded. Couldn't finde UE with RNTI %04x \n", current_rnti);
|
||||
return;
|
||||
}
|
||||
NR_RA_t *ra = UE->ra;
|
||||
if (ra->ra_type == RA_4_STEP && ra->ra_state != nrRA_WAIT_Msg3) {
|
||||
LOG_W(NR_MAC, "UL SDU discarded for RNTI %04x RA state not waiting for PUSCH\n", UE->rnti);
|
||||
return;
|
||||
}
|
||||
if (sduP) {
|
||||
bool no_sig = true;
|
||||
for (uint32_t k = 0; k < sdu_lenP; k++) {
|
||||
if (sduP[k] != 0) {
|
||||
no_sig = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
T(T_GNB_MAC_UL_PDU_WITH_DATA, T_INT(gnb_mod_idP), T_INT(CC_idP),
|
||||
T_INT(rntiP), T_INT(frameP), T_INT(slotP), T_INT(-1) /* harq_pid */,
|
||||
T_BUFFER(sduP, sdu_lenP));
|
||||
T(T_GNB_MAC_UL_PDU_WITH_DATA, T_INT(gnb_mod_idP), T_INT(CC_idP),
|
||||
T_INT(rntiP), T_INT(frameP), T_INT(slotP), T_INT(-1) /* harq_pid */,
|
||||
T_BUFFER(sduP, sdu_lenP));
|
||||
|
||||
/* we don't know this UE (yet). Check whether there is a ongoing RA (Msg 3)
|
||||
* and check the corresponding UE's RNTI match, in which case we activate
|
||||
* it. */
|
||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) {
|
||||
NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[i];
|
||||
if (ra->ra_type == RA_4_STEP && ra->ra_state != nrRA_WAIT_Msg3)
|
||||
continue;
|
||||
|
||||
if (no_sig) {
|
||||
LOG_W(NR_MAC, "Random Access %i ULSCH with no signal\n", i);
|
||||
handle_msg3_failed_rx(ra, i, gNB_mac->ul_bler.harq_round_max);
|
||||
continue;
|
||||
LOG_W(NR_MAC, "MSG3 ULSCH with no signal\n");
|
||||
handle_msg3_failed_rx(gNB_mac, ra, current_rnti, gNB_mac->ul_bler.harq_round_max);
|
||||
return;
|
||||
}
|
||||
if (ra->ra_type == RA_2_STEP) {
|
||||
// random access pusch with RA-RNTI
|
||||
if (ra->RA_rnti != current_rnti) {
|
||||
LOG_E(NR_MAC, "expected TC_RNTI %04x to match current RNTI %04x\n", ra->RA_rnti, current_rnti);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// random access pusch with TC-RNTI
|
||||
if (ra->rnti != current_rnti) {
|
||||
LOG_E(NR_MAC, "expected TC_RNTI %04x to match current RNTI %04x\n", ra->rnti, current_rnti);
|
||||
|
||||
if ((frameP == ra->Msg3_frame) && (slotP == ra->Msg3_slot)) {
|
||||
LOG_W(NR_MAC,
|
||||
"Random Access %i failed at state %s (TC_RNTI %04x RNTI %04x)\n",
|
||||
i,
|
||||
nrra_text[ra->ra_state],
|
||||
ra->rnti,
|
||||
current_rnti);
|
||||
nr_clear_ra_proc(ra);
|
||||
}
|
||||
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
UE = UE ? UE : add_new_nr_ue(gNB_mac, ra->rnti, ra->CellGroup);
|
||||
if (!UE) {
|
||||
LOG_W(NR_MAC,
|
||||
"Random Access %i discarded at state %s (TC_RNTI %04x RNTI %04x): max number of users achieved!\n",
|
||||
i,
|
||||
nrra_text[ra->ra_state],
|
||||
ra->rnti,
|
||||
current_rnti);
|
||||
|
||||
nr_clear_ra_proc(ra);
|
||||
return;
|
||||
}
|
||||
|
||||
UE->UE_beam_index = ra->beam_id;
|
||||
|
||||
// re-initialize ta update variables after RA procedure completion
|
||||
// re-initialize ta update variables after RA procedure completion
|
||||
UE->UE_sched_ctrl.ta_frame = frameP;
|
||||
|
||||
LOG_A(NR_MAC, "%4d.%2d PUSCH with TC_RNTI 0x%04x received correctly\n", frameP, slotP, current_rnti);
|
||||
@@ -873,12 +851,16 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
UE_scheduling_control->raw_rssi = rssi;
|
||||
LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n", UE->rnti, UE_scheduling_control->tpc0, UE_scheduling_control->ta_update);
|
||||
if (ra->cfra) {
|
||||
LOG_A(NR_MAC, "(rnti 0x%04x) CFRA procedure succeeded!\n", ra->rnti);
|
||||
LOG_A(NR_MAC, "(rnti 0x%04x) CFRA procedure succeeded!\n", UE->rnti);
|
||||
nr_mac_reset_ul_failure(UE_scheduling_control);
|
||||
reset_dl_harq_list(UE_scheduling_control);
|
||||
reset_ul_harq_list(UE_scheduling_control);
|
||||
process_addmod_bearers_cellGroupConfig(&UE->UE_sched_ctrl, ra->CellGroup->rlc_BearerToAddModList);
|
||||
nr_clear_ra_proc(ra);
|
||||
process_addmod_bearers_cellGroupConfig(&UE->UE_sched_ctrl, UE->CellGroup->rlc_BearerToAddModList);
|
||||
if (!transition_ra_connected_nr_ue(gNB_mac, UE)) {
|
||||
LOG_E(NR_MAC, "cannot add UE %04x: list is full\n", UE->rnti);
|
||||
delete_nr_ue_data(UE, NULL, &gNB_mac->UE_info.uid_allocator);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
LOG_D(NR_MAC, "[RAPROC] Received %s:\n", ra->ra_type == RA_2_STEP ? "MsgA-PUSCH" : "Msg3");
|
||||
for (uint32_t k = 0; k < sdu_lenP; k++) {
|
||||
@@ -892,40 +874,20 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
// Search for MAC CE for C-RNTI
|
||||
rnti_t crnti = lcid_crnti_lookahead(sduP, sdu_lenP);
|
||||
if (crnti != 0) { // 3GPP TS 38.321 Table 7.1-1: RNTI values, RNTI 0x0000: N/A
|
||||
// this UE is the one identified by the RNTI in sduP
|
||||
ra->rnti = crnti;
|
||||
// Remove UE context just created after Msg.3 in some milliseconds as the UE is one already known (not now, as the UE
|
||||
// context is still needed for the moment)
|
||||
nr_mac_trigger_release_timer(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs);
|
||||
|
||||
// Replace the current UE by the UE identified by C-RNTI
|
||||
UE = find_nr_UE(&gNB_mac->UE_info, crnti);
|
||||
if (!UE) {
|
||||
NR_UE_info_t *old_UE = find_nr_UE(&gNB_mac->UE_info, crnti);
|
||||
if (!old_UE) {
|
||||
// The UE identified by C-RNTI no longer exists at the gNB
|
||||
// Let's abort the current RA, so the UE will trigger a new RA later but using RRCSetupRequest instead. A better
|
||||
// solution may be implemented
|
||||
LOG_W(NR_MAC, "No UE found with C-RNTI %04x, ignoring Msg3 to have UE come back with new RA attempt\n", ra->rnti);
|
||||
mac_remove_nr_ue(gNB_mac, ra->rnti);
|
||||
nr_clear_ra_proc(ra);
|
||||
LOG_W(NR_MAC, "No UE found with C-RNTI %04x, ignoring Msg3 to have UE come back with new RA attempt\n", UE->rnti);
|
||||
nr_release_ra_UE(gNB_mac, current_rnti);
|
||||
return;
|
||||
}
|
||||
|
||||
// The UE identified by C-RNTI still exists at the gNB
|
||||
// Reset Msg4_ACKed to not schedule ULSCH and DLSCH before RRC Reconfiguration
|
||||
UE->Msg4_MsgB_ACKed = false;
|
||||
nr_mac_reset_ul_failure(&UE->UE_sched_ctrl);
|
||||
// Reset HARQ processes
|
||||
reset_dl_harq_list(&UE->UE_sched_ctrl);
|
||||
reset_ul_harq_list(&UE->UE_sched_ctrl);
|
||||
|
||||
// Switch to BWP where RA is configured, typically in the InitialBWP
|
||||
// At this point, UE already switched and triggered RA in that BWP, need to do BWP switching also at gNB for C-RNTI
|
||||
if (ra->DL_BWP.bwp_id != UE->current_DL_BWP.bwp_id || ra->UL_BWP.bwp_id != UE->current_UL_BWP.bwp_id) {
|
||||
LOG_D(NR_MAC, "UE %04x Switch BWP from %ld to BWP id %ld\n", UE->rnti, UE->current_DL_BWP.bwp_id, ra->DL_BWP.bwp_id);
|
||||
NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_idP].ServingCellConfigCommon;
|
||||
configure_UE_BWP(gNB_mac, scc, &UE->UE_sched_ctrl, NULL, UE, ra->DL_BWP.bwp_id, ra->UL_BWP.bwp_id);
|
||||
}
|
||||
|
||||
// remove old UE from connected UEs
|
||||
remove_UE_from_list(MAX_MOBILES_PER_GNB + 1, gNB_mac->UE_info.connected_ue_list, crnti);
|
||||
UE = configure_UE_crnti_msg3(gNB_mac, old_UE, UE);
|
||||
ra = UE->ra;
|
||||
if (UE->reconfigCellGroup) {
|
||||
// Nothing to do
|
||||
// A RRCReconfiguration message should be already pending (for example, an ongoing RRCReestablishment), and it will be
|
||||
@@ -950,26 +912,23 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
LOG_I(NR_MAC,
|
||||
"Activating scheduling %s for TC_RNTI 0x%04x (state %s)\n",
|
||||
ra->ra_type == RA_2_STEP ? "MsgB" : "Msg4",
|
||||
ra->rnti,
|
||||
UE->rnti,
|
||||
nrra_text[ra->ra_state]);
|
||||
ra->ra_state = ra->ra_type == RA_2_STEP ? nrRA_MsgB : nrRA_Msg4;
|
||||
LOG_D(NR_MAC, "TC_RNTI 0x%04x next RA state %s\n", ra->rnti, nrra_text[ra->ra_state]);
|
||||
LOG_D(NR_MAC, "TC_RNTI 0x%04x next RA state %s\n", UE->rnti, nrra_text[ra->ra_state]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) {
|
||||
NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[i];
|
||||
} else {
|
||||
if (ra->ra_state != nrRA_WAIT_Msg3)
|
||||
continue;
|
||||
return;
|
||||
|
||||
if((frameP!=ra->Msg3_frame) || (slotP!=ra->Msg3_slot))
|
||||
continue;
|
||||
return;
|
||||
|
||||
if (ul_cqi != 0xff)
|
||||
ra->msg3_TPC = nr_get_tpc(target_snrx10, ul_cqi, 30, 0);
|
||||
|
||||
handle_msg3_failed_rx(ra, i, gNB_mac->ul_bler.harq_round_max);
|
||||
handle_msg3_failed_rx(gNB_mac, ra, current_rnti, gNB_mac->ul_bler.harq_round_max);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1891,7 +1850,7 @@ static void pf_ul(module_id_t module_id,
|
||||
UE_iterator(UE_list, UE) {
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
if (!UE->Msg4_MsgB_ACKed || sched_ctrl->ul_failure)
|
||||
if (sched_ctrl->ul_failure)
|
||||
continue;
|
||||
|
||||
LOG_D(NR_MAC,"pf_ul: preparing UL scheduling for UE %04x\n",UE->rnti);
|
||||
|
||||
@@ -60,8 +60,8 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, c
|
||||
void nr_mac_configure_sib1(gNB_MAC_INST *nrmac, const plmn_id_t *plmn, uint64_t cellID, int tac);
|
||||
bool nr_mac_configure_other_sib(gNB_MAC_INST *nrmac, int num_cu_sib, const f1ap_sib_msg_t cu_sib[num_cu_sib]);
|
||||
bool nr_mac_add_test_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup);
|
||||
bool nr_mac_prepare_ra_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t *CellGroup);
|
||||
|
||||
void nr_mac_prepare_ra_ue(gNB_MAC_INST *nrmac, NR_UE_info_t *UE);
|
||||
bool add_new_UE_RA(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE);
|
||||
int nr_mac_get_reconfig_delay_slots(NR_SubcarrierSpacing_t scs);
|
||||
|
||||
bool nr_mac_prepare_cellgroup_update(gNB_MAC_INST *nrmac, NR_UE_info_t *UE, NR_CellGroupConfig_t *CellGroup);
|
||||
@@ -135,8 +135,6 @@ void nr_initiate_ra_proc(module_id_t module_idP,
|
||||
int16_t timing_offset,
|
||||
uint32_t preamble_power);
|
||||
|
||||
void nr_clear_ra_proc(NR_RA_t *ra);
|
||||
|
||||
int nr_allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, slot_t slotP, int test_only);
|
||||
|
||||
void schedule_nr_prach(module_id_t module_idP, frame_t frameP, slot_t slotP);
|
||||
@@ -310,21 +308,22 @@ void remove_nr_list(NR_list_t *listP, int id);
|
||||
void add_tail_nr_list(NR_list_t *listP, int id);
|
||||
void add_front_nr_list(NR_list_t *listP, int id);
|
||||
void remove_front_nr_list(NR_list_t *listP);
|
||||
|
||||
void nr_release_ra_UE(gNB_MAC_INST *mac, rnti_t rnti);
|
||||
NR_UE_info_t * find_nr_UE(NR_UEs_t* UEs, rnti_t rntiP);
|
||||
|
||||
NR_UE_info_t *find_ra_UE(NR_UEs_t *UEs, rnti_t rntiP);
|
||||
void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_allocator_t *uia);
|
||||
void configure_UE_BWP(gNB_MAC_INST *nr_mac,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
NR_UE_sched_ctrl_t *sched_ctrl,
|
||||
NR_RA_t *ra,
|
||||
NR_UE_info_t *UE,
|
||||
bool is_RA,
|
||||
int dl_bwp_switch,
|
||||
int ul_bwp_switch);
|
||||
|
||||
NR_UE_info_t* add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConfig_t *CellGroup);
|
||||
|
||||
bool transition_ra_connected_nr_ue(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE);
|
||||
bool add_connected_nr_ue(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE);
|
||||
void nr_check_Msg4_MsgB_Ack(module_id_t module_id, frame_t frame, slot_t slot, NR_UE_info_t *UE, bool success);
|
||||
void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti);
|
||||
|
||||
NR_UE_info_t *get_new_nr_ue_inst(uid_allocator_t *uia, rnti_t rnti, NR_CellGroupConfig_t *CellGroup);
|
||||
int nr_get_default_pucch_res(int pucch_ResourceCommon);
|
||||
|
||||
int nr_write_ce_dlsch_pdu(module_id_t module_idP,
|
||||
@@ -362,11 +361,7 @@ void reset_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl);
|
||||
|
||||
void reset_ul_harq_list(NR_UE_sched_ctrl_t *sched_ctrl);
|
||||
|
||||
void handle_nr_ul_harq(const int CC_idP,
|
||||
module_id_t mod_id,
|
||||
frame_t frame,
|
||||
slot_t slot,
|
||||
const nfapi_nr_crc_t *crc_pdu);
|
||||
void handle_nr_ul_harq(module_id_t mod_id, frame_t frame, slot_t slot, const nfapi_nr_crc_t *crc_pdu);
|
||||
|
||||
uint8_t *allocate_transportBlock_buffer(byte_array_t *tb, uint32_t needed);
|
||||
void free_transportBlock_buffer(byte_array_t *tb);
|
||||
@@ -394,7 +389,8 @@ uint8_t get_mcs_from_cqi(int mcs_table, int cqi_table, int cqi_idx);
|
||||
uint8_t get_dl_nrOfLayers(const NR_UE_sched_ctrl_t *sched_ctrl, const nr_dci_format_t dci_format);
|
||||
|
||||
void free_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl);
|
||||
|
||||
bool add_UE_to_list(int list_size, NR_UE_info_t *list[list_size], NR_UE_info_t *UE);
|
||||
NR_UE_info_t *remove_UE_from_list(int list_size, NR_UE_info_t *list[list_size], rnti_t rnti);
|
||||
int get_dl_tda(const gNB_MAC_INST *nrmac, int slot);
|
||||
int get_ul_tda(gNB_MAC_INST *nrmac, int frame, int slot);
|
||||
|
||||
@@ -430,7 +426,6 @@ int get_mcs_from_bler(const NR_bler_options_t *bler_options,
|
||||
|
||||
int ul_buffer_index(int frame, int slot, int slots_per_frame, int size);
|
||||
void UL_tti_req_ahead_initialization(gNB_MAC_INST *gNB, int n, int CCid, frame_t frameP, int slotP);
|
||||
|
||||
void fapi_beam_index_allocation(NR_ServingCellConfigCommon_t *scc, gNB_MAC_INST *mac);
|
||||
int get_fapi_beamforming_index(gNB_MAC_INST *mac, int ssb_idx);
|
||||
NR_beam_alloc_t beam_allocation_procedure(NR_beam_info_t *beam_info, int frame, int slot, int beam_index, int slots_per_frame);
|
||||
@@ -467,7 +462,7 @@ void process_addmod_bearers_cellGroupConfig(NR_UE_sched_ctrl_t *sched_ctrl,
|
||||
bool nr_mac_add_lcid(NR_UE_sched_ctrl_t *sched_ctrl, const nr_lc_config_t *c);
|
||||
bool nr_mac_remove_lcid(NR_UE_sched_ctrl_t *sched_ctrl, long lcid);
|
||||
|
||||
bool nr_mac_get_new_rnti(NR_UEs_t *UEs, const NR_RA_t *ra_base, int ra_count, rnti_t *rnti);
|
||||
bool nr_mac_get_new_rnti(NR_UEs_t *UEs, rnti_t *rnti);
|
||||
void nr_mac_update_pdcch_closed_loop_adjust(NR_UE_sched_ctrl_t *sched_ctrl, bool feedback_not_detected);
|
||||
|
||||
void prepare_du_configuration_update(gNB_MAC_INST *mac,
|
||||
|
||||
@@ -476,15 +476,18 @@ NR_CellGroupConfig_t *clone_CellGroupConfig(const NR_CellGroupConfig_t *orig)
|
||||
static NR_UE_info_t *create_new_UE(gNB_MAC_INST *mac, uint32_t cu_id)
|
||||
{
|
||||
int CC_id = 0;
|
||||
const NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
|
||||
rnti_t rnti;
|
||||
bool found = nr_mac_get_new_rnti(&mac->UE_info, cc->ra, sizeofArray(cc->ra), &rnti);
|
||||
bool found = nr_mac_get_new_rnti(&mac->UE_info, &rnti);
|
||||
if (!found)
|
||||
return NULL;
|
||||
|
||||
NR_UE_info_t* UE = add_new_nr_ue(mac, rnti, NULL);
|
||||
if (!UE)
|
||||
NR_UE_info_t *UE = get_new_nr_ue_inst(&mac->UE_info.uid_allocator, rnti, NULL);
|
||||
AssertFatal(UE != NULL, "cannot create UE context, UE context setup failure not implemented\n");
|
||||
if (!add_new_UE_RA(mac, UE)) {
|
||||
delete_nr_ue_data(UE, /*not used*/ NULL, &mac->UE_info.uid_allocator);
|
||||
LOG_E(NR_MAC, "UE list full while creating new UE\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
f1_ue_data_t new_ue_data = {.secondary_ue = cu_id};
|
||||
bool success = du_add_f1_ue_data(rnti, &new_ue_data);
|
||||
@@ -499,11 +502,10 @@ static NR_UE_info_t *create_new_UE(gNB_MAC_INST *mac, uint32_t cu_id)
|
||||
// by add_new_nr_ue(); it's a kind of chicken-and-egg problem), so below we
|
||||
// complete the UE context with the information that add_new_nr_ue() would
|
||||
// have added
|
||||
UE->Msg4_MsgB_ACKed = true;
|
||||
UE->CellGroup = cellGroupConfig;
|
||||
|
||||
nr_rlc_activate_srb0(UE->rnti, UE, NULL);
|
||||
nr_mac_prepare_ra_ue(mac, rnti, UE->CellGroup);
|
||||
nr_mac_prepare_ra_ue(mac, UE);
|
||||
/* SRB1 is added to RLC and MAC in the handler later */
|
||||
return UE;
|
||||
}
|
||||
@@ -759,13 +761,6 @@ void ue_context_modification_refuse(const f1ap_ue_context_modif_refuse_t *refuse
|
||||
return;
|
||||
}
|
||||
|
||||
const int CC_id = 0;
|
||||
NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
|
||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
||||
NR_RA_t *ra = &cc->ra[i];
|
||||
if (ra->rnti == UE->rnti)
|
||||
nr_clear_ra_proc(ra);
|
||||
}
|
||||
NR_SCHED_UNLOCK(&mac->sched_lock);
|
||||
|
||||
f1ap_ue_context_release_req_t request = {
|
||||
@@ -822,6 +817,7 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc)
|
||||
pthread_mutex_lock(&mac->sched_lock);
|
||||
/* check first that the scheduler knows such UE */
|
||||
NR_UE_info_t *UE = find_nr_UE(&mac->UE_info, dl_rrc->gNB_DU_ue_id);
|
||||
UE = UE ? UE : find_ra_UE(&mac->UE_info, dl_rrc->gNB_DU_ue_id);
|
||||
if (UE == NULL) {
|
||||
LOG_E(MAC, "ERROR: unknown UE with RNTI %04x, ignoring DL RRC Message Transfer\n", dl_rrc->gNB_DU_ue_id);
|
||||
pthread_mutex_unlock(&mac->sched_lock);
|
||||
@@ -870,12 +866,11 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc)
|
||||
* from the current configuration. Also, expect the reconfiguration from
|
||||
* the CU, so save the old UE's CellGroup for the new UE */
|
||||
UE->CellGroup->spCellConfig = NULL;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon;
|
||||
uid_t temp_uid = UE->uid;
|
||||
UE->uid = oldUE->uid;
|
||||
oldUE->uid = temp_uid;
|
||||
configure_UE_BWP(mac, scc, sched_ctrl, NULL, UE, -1, -1);
|
||||
configure_UE_BWP(mac, scc, UE, false, -1, -1);
|
||||
for (int i = 1; i < seq_arr_size(&oldUE->UE_sched_ctrl.lc_config); ++i) {
|
||||
const nr_lc_config_t *c = seq_arr_at(&oldUE->UE_sched_ctrl.lc_config, i);
|
||||
nr_mac_add_lcid(&UE->UE_sched_ctrl, c);
|
||||
|
||||
@@ -362,6 +362,9 @@ void mac_top_destroy_gNB(gNB_MAC_INST *mac)
|
||||
for (int i = 0; i < sizeofArray(UE_info->connected_ue_list); ++i)
|
||||
if (UE_info->connected_ue_list[i])
|
||||
delete_nr_ue_data(UE_info->connected_ue_list[i], cc, &UE_info->uid_allocator);
|
||||
for (int i = 0; i < sizeofArray(UE_info->access_ue_list); ++i)
|
||||
if (UE_info->access_ue_list[i])
|
||||
delete_nr_ue_data(UE_info->access_ue_list[i], cc, &UE_info->uid_allocator);
|
||||
}
|
||||
|
||||
void nr_mac_send_f1_setup_req(void)
|
||||
|
||||
@@ -229,8 +229,6 @@ typedef struct {
|
||||
NR_beam_alloc_t Msg3_beam;
|
||||
/// harq_pid used for Msg4 transmission
|
||||
uint8_t harq_pid;
|
||||
/// UE RNTI allocated during RAR
|
||||
rnti_t rnti;
|
||||
/// RA RNTI allocated from received PRACH
|
||||
uint16_t RA_rnti;
|
||||
/// MsgB RNTI allocated from received MsgA
|
||||
@@ -251,25 +249,12 @@ typedef struct {
|
||||
int msg3_nbSymb;
|
||||
/// MAC PDU length for Msg4
|
||||
int mac_pdu_length;
|
||||
/// RA search space
|
||||
NR_SearchSpace_t *ra_ss;
|
||||
/// RA Coreset
|
||||
NR_ControlResourceSet_t *coreset;
|
||||
NR_sched_pdcch_t sched_pdcch;
|
||||
// Beam index
|
||||
uint8_t beam_id;
|
||||
/// CellGroup for UE that is to come (NSA is non-null, null for SA)
|
||||
NR_CellGroupConfig_t *CellGroup;
|
||||
/// Preambles for contention-free access
|
||||
NR_preamble_ue_t preambles;
|
||||
int contention_resolution_timer;
|
||||
nr_ra_type_t ra_type;
|
||||
/// CFRA flag
|
||||
bool cfra;
|
||||
// BWP for RA
|
||||
NR_UE_DL_BWP_t DL_BWP;
|
||||
NR_UE_UL_BWP_t UL_BWP;
|
||||
NR_UE_ServingCell_Info_t sc_info;
|
||||
} NR_RA_t;
|
||||
|
||||
/*! \brief gNB common channels */
|
||||
@@ -289,8 +274,6 @@ typedef struct {
|
||||
/// used for otherSIB data
|
||||
uint8_t other_sib_bcch_pdu[2][NR_MAX_SIB_LENGTH / 8];
|
||||
int other_sib_bcch_length[2];
|
||||
/// Template for RA computations
|
||||
NR_RA_t ra[NR_NB_RA_PROC_MAX];
|
||||
/// VRB map for common channels
|
||||
uint16_t vrb_map[MAX_NUM_BEAM_PERIODS][275];
|
||||
/// VRB map for common channels and PUSCH, dynamically allocated because
|
||||
@@ -654,7 +637,6 @@ typedef struct {
|
||||
int pusch_snrx10;
|
||||
int pucch_snrx10;
|
||||
uint16_t ul_rssi;
|
||||
uint8_t current_harq_pid;
|
||||
int pusch_consecutive_dtx_cnt;
|
||||
int pucch_consecutive_dtx_cnt;
|
||||
bool ul_failure;
|
||||
@@ -770,11 +752,11 @@ typedef struct {
|
||||
NR_UE_NR_Capability_t *capability;
|
||||
// UE selected beam index
|
||||
uint8_t UE_beam_index;
|
||||
bool Msg4_MsgB_ACKed;
|
||||
float ul_thr_ue;
|
||||
float dl_thr_ue;
|
||||
long pdsch_HARQ_ACK_Codebook;
|
||||
bool is_redcap;
|
||||
NR_RA_t *ra;
|
||||
} NR_UE_info_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -782,6 +764,7 @@ typedef struct {
|
||||
// last element always NULL
|
||||
pthread_mutex_t mutex;
|
||||
NR_UE_info_t *connected_ue_list[MAX_MOBILES_PER_GNB + 1];
|
||||
NR_UE_info_t *access_ue_list[NR_NB_RA_PROC_MAX];
|
||||
// bitmap of CSI-RS already scheduled in current slot
|
||||
int sched_csirs;
|
||||
uid_allocator_t uid_allocator;
|
||||
|
||||
@@ -203,7 +203,7 @@ static void handle_nr_ulsch(NR_UL_IND_t *UL_info)
|
||||
crc->timing_advance,
|
||||
crc->ul_cqi,
|
||||
crc->rssi);
|
||||
handle_nr_ul_harq(UL_info->CC_id, UL_info->module_id, UL_info->frame, UL_info->slot, crc);
|
||||
handle_nr_ul_harq(UL_info->module_id, UL_info->frame, UL_info->slot, crc);
|
||||
}
|
||||
UL_info->rx_ind.number_of_pdus = 0;
|
||||
UL_info->crc_ind.number_crcs = 0;
|
||||
|
||||
@@ -371,9 +371,17 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a
|
||||
&& secondaryCellGroup->spCellConfig->reconfigurationWithSync
|
||||
&& secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated
|
||||
&& secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra);
|
||||
NR_SCHED_LOCK(&RC.nrmac[rrc->module_id]->sched_lock);
|
||||
ret = nr_mac_prepare_ra_ue(RC.nrmac[rrc->module_id], du_ue_id, secondaryCellGroup);
|
||||
NR_SCHED_UNLOCK(&RC.nrmac[rrc->module_id]->sched_lock);
|
||||
gNB_MAC_INST *nrmac = RC.nrmac[rrc->module_id];
|
||||
NR_SCHED_LOCK(&nrmac->sched_lock);
|
||||
NR_UE_info_t *UE_info = get_new_nr_ue_inst(&nrmac->UE_info.uid_allocator, UE->rnti, secondaryCellGroup);
|
||||
AssertFatal(UE_info != NULL, "cannot create UE context: list is full?\n");
|
||||
if (add_new_UE_RA(nrmac, UE_info)) {
|
||||
ret = true;
|
||||
nr_mac_prepare_ra_ue(nrmac, UE_info);
|
||||
} else {
|
||||
delete_nr_ue_data(UE_info, /* not used */ NULL, &nrmac->UE_info.uid_allocator);
|
||||
}
|
||||
NR_SCHED_UNLOCK(&nrmac->sched_lock);
|
||||
}
|
||||
AssertFatal(ret, "cannot add NSA UE in MAC, aborting\n");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user