Merge remote-tracking branch 'origin/Fix_DedicatedBWPs' into integration_2025_w31 (!3461)

Fix Dedicated BWPs

- Improve SearchSpace selection
- Improve CORESET selection
- Fix fill 'initialDownlinkBWP->pdsch_Config' when there are
  DedicatedBWPs
  * This fixes the reported 'RSRP = 0' issue when the UE is in the
    InitialBWP and we have DedicatedBWPs configured
- Add a 'common' type SearchSpace in the NR_BWP_DownlinkDedicated IE for
  DedicatedBWPs
- Fix hardcoded 'controlResourceSetId' by making it dynamic
- Remove 'searchspaceid' from 'verify_agg_levels' function because it
  was used only for LOG
- CI: Add DedicatedBWP to '40 MHz TDD F1+E1 SA' in
  'RAN-SA-B200-Module-SABOX-Container'
This commit is contained in:
Robert Schmidt
2025-07-31 15:53:31 +02:00
7 changed files with 120 additions and 76 deletions
@@ -686,7 +686,8 @@ static void other_sib_sched_control(module_id_t module_idP,
}
AssertFatal(nr_of_candidates > 0, "nr_of_candidates is 0\n");
NR_ControlResourceSet_t *coreset = get_coreset(gNB_mac, scc, NULL, ss, NR_SearchSpace__searchSpaceType_PR_common);
AssertFatal(ss->controlResourceSetId, "ss->controlResourceSetId is NULL\n");
NR_ControlResourceSet_t *coreset = get_coreset(gNB_mac, scc, NULL, *ss->controlResourceSetId);
if (!gNB_mac->sched_pdcch_otherSI) {
gNB_mac->sched_pdcch_otherSI = calloc(1, sizeof(*gNB_mac->sched_pdcch_otherSI));
*gNB_mac->sched_pdcch_otherSI = set_pdcch_structure(gNB_mac, ss, coreset, scc, NULL, type0_PDCCH_CSS_config);
@@ -369,64 +369,59 @@ NR_pdsch_dmrs_t get_dl_dmrs_params(const NR_ServingCellConfigCommon_t *scc,
NR_ControlResourceSet_t *get_coreset(gNB_MAC_INST *nrmac,
NR_ServingCellConfigCommon_t *scc,
void *bwp,
NR_SearchSpace_t *ss,
NR_SearchSpace__searchSpaceType_PR ss_type) {
NR_ControlResourceSetId_t coreset_id = *ss->controlResourceSetId;
if (ss_type == NR_SearchSpace__searchSpaceType_PR_common) { // common search space
NR_ControlResourceSet_t *coreset;
if(coreset_id == 0) {
coreset = nrmac->sched_ctrlCommon->coreset; // this is coreset 0
} else if (bwp) {
coreset = ((NR_BWP_Downlink_t*)bwp)->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet;
} else if (scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet) {
coreset = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet;
} else {
coreset = NULL;
}
if (coreset) AssertFatal(coreset_id == coreset->controlResourceSetId,
"ID of common ss coreset does not correspond to id set in the "
"search space\n");
return coreset;
} else {
const int n = ((NR_BWP_DownlinkDedicated_t*)bwp)->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count;
NR_BWP_DownlinkDedicated_t *bwp_dedicated,
NR_ControlResourceSetId_t coreset_id)
{
if (coreset_id == 0) {
return nrmac->sched_ctrlCommon->coreset; // this is coreset 0
}
if (bwp_dedicated) {
const int n = bwp_dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count;
for (int i = 0; i < n; i++) {
NR_ControlResourceSet_t *coreset =
((NR_BWP_DownlinkDedicated_t*)bwp)->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[i];
if (coreset_id == coreset->controlResourceSetId) {
NR_ControlResourceSet_t *coreset = bwp_dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[i];
if (coreset->controlResourceSetId == coreset_id) {
return coreset;
}
}
AssertFatal(0, "Couldn't find coreset with id %ld\n", coreset_id);
AssertFatal(false, "Couldn't find CORESET with id %ld in BWP_DownlinkDedicated\n", coreset_id);
}
if (scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet) {
NR_ControlResourceSet_t *coreset =
scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet;
if (coreset->controlResourceSetId == coreset_id) {
return coreset;
}
AssertFatal(false, "Couldn't find CORESET with id %ld in commonControlResourceSet\n", coreset_id);
}
AssertFatal(false, "Couldn't find coreset with id %ld\n", coreset_id);
}
static NR_SearchSpace_t *get_searchspace(NR_ServingCellConfigCommon_t *scc,
NR_BWP_DownlinkDedicated_t *bwp_Dedicated,
NR_BWP_DownlinkDedicated_t *bwp_dedicated,
NR_SearchSpace__searchSpaceType_PR target_ss)
{
int n = 0;
if(bwp_Dedicated)
n = bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;
else
n = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.count;
if (bwp_dedicated) {
const int n = bwp_dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;
for (int i = 0; i < n; i++) {
NR_SearchSpace_t *ss = bwp_dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i];
if (ss->searchSpaceType->present == target_ss) {
AssertFatal(ss->controlResourceSetId, "searchSpaceId %ld has a NULL controlResourceSetId\n", ss->searchSpaceId);
return ss;
}
}
AssertFatal(false, "Couldn't find an adequate SearchSpace for target SearchSpace %d in BWP_DownlinkDedicated\n", target_ss);
}
for (int i=0;i<n;i++) {
NR_SearchSpace_t *ss = NULL;
if(bwp_Dedicated)
ss = bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i];
else
ss = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.array[i];
AssertFatal(ss->controlResourceSetId != NULL, "ss->controlResourceSetId is null\n");
AssertFatal(ss->searchSpaceType != NULL, "ss->searchSpaceType is null\n");
const int n = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.count;
for (int i = 0; i < n; i++) {
NR_SearchSpace_t *ss =
scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.array[i];
if (ss->searchSpaceType->present == target_ss) {
AssertFatal(ss->controlResourceSetId, "searchSpaceId %ld has a NULL controlResourceSetId\n", ss->searchSpaceId);
return ss;
}
}
AssertFatal(0, "Couldn't find an adequate searchspace bwp_Dedicated %p\n",bwp_Dedicated);
AssertFatal(false, "Couldn't find an adequate SearchSpace for target SearchSpace %d in ServingCellConfigCommon\n", target_ss);
}
NR_sched_pdcch_t set_pdcch_structure(gNB_MAC_INST *gNB_mac,
@@ -2591,7 +2586,7 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac,
// 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->coreset = get_coreset(nr_mac, scc, bwpd, *sched_ctrl->search_space->controlResourceSetId);
sched_ctrl->sched_pdcch = set_pdcch_structure(nr_mac,
sched_ctrl->search_space,
@@ -2632,7 +2627,7 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac,
}
AssertFatal(sched_ctrl->search_space != NULL, "SearchSpace cannot be null for RA\n");
sched_ctrl->coreset = get_coreset(nr_mac, scc, dl_bwp, sched_ctrl->search_space, NR_SearchSpace__searchSpaceType_PR_common);
sched_ctrl->coreset = get_coreset(nr_mac, scc, bwpd, *sched_ctrl->search_space->controlResourceSetId);
NR_COMMON_channels_t *cc = &nr_mac->common_channels[0];
int ssb_index = cc->ssb_index[UE->UE_beam_index];
sched_ctrl->sched_pdcch = set_pdcch_structure(nr_mac,
+2 -3
View File
@@ -283,9 +283,8 @@ void set_r_pucch_parms(int rsetindex,
/* find coreset within the search space */
NR_ControlResourceSet_t *get_coreset(gNB_MAC_INST *nrmac,
NR_ServingCellConfigCommon_t *scc,
void *bwp,
NR_SearchSpace_t *ss,
NR_SearchSpace__searchSpaceType_PR ss_type);
NR_BWP_DownlinkDedicated_t *bwp_dedicated,
NR_ControlResourceSetId_t coreset_id);
long get_K2(NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList,
int time_domain_assignment,
+28 -16
View File
@@ -80,7 +80,6 @@ static NR_BWP_t clone_generic_parameters(const NR_BWP_t *gp)
static void verify_agg_levels(int num_cce_in_coreset,
const int in_num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS],
int coresetid,
int searchspaceid,
int out_num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS])
{
int agg_level_to_n_cces[] = {1, 2, 4, 8, 16};
@@ -94,10 +93,9 @@ static void verify_agg_levels(int num_cce_in_coreset,
if (num_agg_level_candidates * agg_level_to_n_cces[i] > num_cce_in_coreset) {
int new_agg_level_candidates = num_cce_in_coreset / agg_level_to_n_cces[i];
LOG_E(NR_RRC,
"Invalid configuration: Not enough CCEs in coreset %d, searchspace %d, agg_level %d, number of requested "
"Invalid configuration: Not enough CCEs in coreset %d, agg_level %d, number of requested "
"candidates = %d, number of CCES in coreset %d. Aggregation level candidates limited to %d\n",
coresetid,
searchspaceid,
agg_level_to_n_cces[i],
in_num_agg_level_candidates[i],
num_cce_in_coreset,
@@ -1592,17 +1590,27 @@ static void config_downlinkBWP(NR_BWP_Downlink_t *bwp,
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList));
int searchspaceid = 5 + bwp->bwp_Id;
int rrc_num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS];
int num_cces = get_coreset_num_cces(coreset->frequencyDomainResources.buf, coreset->duration);
verify_agg_levels(num_cces, num_agg_level_candidates, coreset->controlResourceSetId, searchspaceid, rrc_num_agg_level_candidates);
NR_SearchSpace_t *ss = rrc_searchspace_config(true, searchspaceid, coreset->controlResourceSetId, rrc_num_agg_level_candidates);
int agg_level_candidates[NUM_PDCCH_AGG_LEVELS];
NR_SearchSpace_t *ss = NULL;
if (!is_SA) {
int num_cces = get_coreset_num_cces(coreset->frequencyDomainResources.buf, coreset->duration);
verify_agg_levels(num_cces, num_agg_level_candidates, coreset->controlResourceSetId, agg_level_candidates);
ss = rrc_searchspace_config(true, searchspaceid, coreset->controlResourceSetId, agg_level_candidates);
} else {
agg_level_candidates[PDCCH_AGG_LEVEL1] = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0;
agg_level_candidates[PDCCH_AGG_LEVEL2] = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0;
agg_level_candidates[PDCCH_AGG_LEVEL4] = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1;
agg_level_candidates[PDCCH_AGG_LEVEL8] = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0;
agg_level_candidates[PDCCH_AGG_LEVEL16] = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0;
ss = rrc_searchspace_config(true, searchspaceid, 0, agg_level_candidates);
}
asn1cSeqAdd(&bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list, ss);
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1=NULL;
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceOtherSystemInformation=NULL;
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->pagingSearchSpace=NULL;
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace=NULL;
if(is_SA == false) {
if(!is_SA) {
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace));
*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace=ss->searchSpaceId;
}
@@ -1630,14 +1638,19 @@ static void config_downlinkBWP(NR_BWP_Downlink_t *bwp,
// frees
NR_ControlResourceSet_t *coreset2 = get_coreset_config(bwp->bwp_Id, curr_bwp, ssb_bitmap);
asn1cSeqAdd(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list, coreset2);
int rrc_num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS];
int num_cces = get_coreset_num_cces(coreset2->frequencyDomainResources.buf, coreset2->duration);
verify_agg_levels(num_cces, num_agg_level_candidates, coreset2->controlResourceSetId, rrc_num_agg_level_candidates);
searchspaceid = 10 + bwp->bwp_Id;
num_cces = get_coreset_num_cces(coreset2->frequencyDomainResources.buf, coreset2->duration);
verify_agg_levels(num_cces, num_agg_level_candidates, coreset->controlResourceSetId, searchspaceid, rrc_num_agg_level_candidates);
NR_SearchSpace_t *ss2 =
rrc_searchspace_config(false, searchspaceid, coreset2->controlResourceSetId, rrc_num_agg_level_candidates);
NR_SearchSpace_t *ss2 = rrc_searchspace_config(true, searchspaceid, is_SA ? 0 : coreset2->controlResourceSetId, agg_level_candidates);
asn1cSeqAdd(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list, ss2);
searchspaceid = 20 + bwp->bwp_Id;
NR_SearchSpace_t *ss3 =
rrc_searchspace_config(false, searchspaceid, coreset2->controlResourceSetId, rrc_num_agg_level_candidates);
asn1cSeqAdd(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list, ss3);
bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToReleaseList = NULL;
bwp->bwp_Dedicated->pdsch_Config = config_pdsch(ssb_bitmap, bwp->bwp_Id, dl_antenna_ports);
@@ -3173,7 +3186,6 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid,
verify_agg_levels(num_cces,
configuration->num_agg_level_candidates,
coreset->controlResourceSetId,
searchspaceid,
rrc_num_agg_level_candidates);
NR_SearchSpace_t *ss2 = rrc_searchspace_config(false, searchspaceid, coreset->controlResourceSetId, rrc_num_agg_level_candidates);
asn1cSeqAdd(&bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list, ss);
@@ -3276,16 +3288,16 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid,
}
asn1cSeqAdd(&csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list, ssbresset0);
int bwp_loop_end = n_dl_bwp > 0 ? n_dl_bwp : 1;
int bwp_loop_end = n_dl_bwp + 1;
for (int bwp_loop = 0; bwp_loop < bwp_loop_end; bwp_loop++) {
int curr_bwp, bwp_id;
struct NR_SetupRelease_PDSCH_Config *pdsch_Config;
if (n_dl_bwp == 0) {
if (bwp_loop == 0) {
pdsch_Config = SpCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config;
curr_bwp = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
bwp_id = 0;
} else {
NR_BWP_Downlink_t *bwp = SpCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_loop];
NR_BWP_Downlink_t *bwp = SpCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_loop - 1];
pdsch_Config = bwp->bwp_Dedicated->pdsch_Config;
curr_bwp = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
bwp_id = bwp->bwp_Id;