Merge remote-tracking branch 'origin/fix_mux_23' into integration_2026_w04 (!3782)

Improvements to support CSET0 multiplexing pattern 3 for FR2
This commit is contained in:
Jaroslava Fiedlerova
2026-01-21 11:02:40 +01:00
25 changed files with 619 additions and 550 deletions
+1 -1
View File
@@ -587,7 +587,7 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc, uint64_t ssbmap)
nr_rrc_config_dl_tda(dlcc->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList,
frame_type,
scc->tdd_UL_DL_ConfigurationCommon,
dlcc->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
NRRIV2BW(dlcc->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE));
if (frame_type == FDD) {
ASN_STRUCT_FREE(asn_DEF_NR_TDD_UL_DL_ConfigCommon, scc->tdd_UL_DL_ConfigurationCommon);
+1 -2
View File
@@ -472,8 +472,7 @@ typedef struct Type0_PDCCH_CSS_config_s {
uint32_t type0_pdcch_ss_mux_pattern;
uint16_t frame;
int sfn_c;
uint32_t n_c;
uint32_t n_0;
uint32_t slot;
uint32_t first_symbol_index;
uint32_t search_space_duration;
uint32_t search_space_frame_period; // in slots
+118 -108
View File
@@ -1463,14 +1463,11 @@ int get_format0(uint8_t index, uint8_t unpaired, frequency_range_t frequency_ran
return format;
}
void find_aggregation_candidates(uint8_t *aggregation_level,
uint8_t *nr_of_candidates,
const NR_SearchSpace_t *ss,
int L)
void find_aggregation_candidates(int *aggregation_level, int *nr_of_candidates, const NR_SearchSpace_t *ss, int L)
{
AssertFatal(L>=1 && L<=16,"L %d not ok\n", L);
AssertFatal(L >= 1 && L <= 16,"L %d not ok\n", L);
*nr_of_candidates = 0;
switch(L) {
switch (L) {
case 1:
if (ss->nrofCandidates->aggregationLevel1 != NR_SearchSpace__nrofCandidates__aggregationLevel1_n0) {
*aggregation_level = 1;
@@ -3217,7 +3214,7 @@ int16_t fill_dmrs_mask(const NR_PDSCH_Config_t *pdsch_Config,
// For TypeB, ld is the duration of the scheduled PDSCH resources
int ld = (mappingtype == typeA) ? (NrOfSymbols + startSymbol) : NrOfSymbols;
AssertFatal(ld > 2 && ld < 15,"Illegal NrOfSymbols according to Table 5.1.2.1-1 Spec 38.214 %d\n",ld);
AssertFatal(ld > 1 && ld < 15,"Illegal NrOfSymbols according to Table 5.1.2.1-1 Spec 38.214 %d\n",ld);
AssertFatal((NrOfSymbols + startSymbol) < 15,"Illegal S+L according to Table 5.1.2.1-1 Spec 38.214 S:%d L:%d\n",startSymbol, NrOfSymbols);
if (mappingtype == typeA) {
@@ -3556,30 +3553,28 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
NR_SubcarrierSpacing_t scs_ssb,
frequency_range_t frequency_range,
int nr_band,
int grid_size,
uint32_t ssb_index,
uint32_t ssb_period,
uint32_t ssb_offset_point_a)
{
NR_SubcarrierSpacing_t scs_pdcch;
channel_bandwidth_t min_channel_bw;
// according to Table 5.3.5-1 in 38.104
// band 79 is the only one which minimum is 40
// for all the other channels it is either 10 or 5
// and there is no difference between the two for this implementation so it is set it to 10
channel_bandwidth_t min_channel_bw;
if (nr_band == 79)
min_channel_bw = bw_40MHz;
else
min_channel_bw = bw_10MHz;
NR_SubcarrierSpacing_t scs_pdcch;
if (frequency_range == FR2) {
if(mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60)
scs_pdcch = NR_SubcarrierSpacing_kHz60;
else
scs_pdcch = NR_SubcarrierSpacing_kHz120;
}
else {
} else {
frequency_range = FR1;
if(mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60)
scs_pdcch = NR_SubcarrierSpacing_kHz15;
@@ -3590,8 +3585,7 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
type0_PDCCH_CSS_config->ssb_index = ssb_index;
type0_PDCCH_CSS_config->frame = frameP;
uint8_t ssb_slot = ssb_start_symbol/14;
uint8_t ssb_slot = ssb_start_symbol / 14;
uint32_t is_condition_A = (ssb_subcarrier_offset == 0); // 38.213 ch.13
uint32_t index_4msb = (mib->pdcch_ConfigSIB1.controlResourceSetZero);
uint32_t index_4lsb = (mib->pdcch_ConfigSIB1.searchSpaceZero);
@@ -3599,59 +3593,59 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
type0_PDCCH_CSS_config->num_rbs = -1;
type0_PDCCH_CSS_config->num_symbols = -1;
type0_PDCCH_CSS_config->rb_offset = -1;
LOG_D(NR_MAC,"NR_SubcarrierSpacing_kHz30 %d, scs_ssb %d, scs_pdcch %d, min_chan_bw %d\n",(int)NR_SubcarrierSpacing_kHz30,(int)scs_ssb,(int)scs_pdcch,min_channel_bw);
LOG_D(NR_MAC,
"NR_SubcarrierSpacing_kHz30 %d, scs_ssb %d, scs_pdcch %d, min_chan_bw %d\n",
(int)NR_SubcarrierSpacing_kHz30,
(int)scs_ssb,
(int)scs_pdcch,
min_channel_bw);
// type0-pdcch coreset
switch( ((int)scs_ssb << 3) | (int)scs_pdcch ){
switch(((int)scs_ssb << 3) | (int)scs_pdcch) {
case (NR_SubcarrierSpacing_kHz15 << 3) | NR_SubcarrierSpacing_kHz15:
AssertFatal(index_4msb < 15, "38.213 Table 13-1 4 MSB out of range\n");
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
type0_PDCCH_CSS_config->num_rbs = table_38213_13_1_c2[index_4msb];
type0_PDCCH_CSS_config->num_rbs = table_38213_13_1_c2[index_4msb];
type0_PDCCH_CSS_config->num_symbols = table_38213_13_1_c3[index_4msb];
type0_PDCCH_CSS_config->rb_offset = table_38213_13_1_c4[index_4msb];
type0_PDCCH_CSS_config->rb_offset = table_38213_13_1_c4[index_4msb];
break;
case (NR_SubcarrierSpacing_kHz15 << 3) | NR_SubcarrierSpacing_kHz30:
AssertFatal(index_4msb < 14, "38.213 Table 13-2 4 MSB out of range\n");
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
type0_PDCCH_CSS_config->num_rbs = table_38213_13_2_c2[index_4msb];
type0_PDCCH_CSS_config->num_rbs = table_38213_13_2_c2[index_4msb];
type0_PDCCH_CSS_config->num_symbols = table_38213_13_2_c3[index_4msb];
type0_PDCCH_CSS_config->rb_offset = table_38213_13_2_c4[index_4msb];
type0_PDCCH_CSS_config->rb_offset = table_38213_13_2_c4[index_4msb];
break;
case (NR_SubcarrierSpacing_kHz30 << 3) | NR_SubcarrierSpacing_kHz15:
if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)){
if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)) {
AssertFatal(index_4msb < 9, "38.213 Table 13-3 4 MSB out of range\n");
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
type0_PDCCH_CSS_config->num_rbs = table_38213_13_3_c2[index_4msb];
type0_PDCCH_CSS_config->num_rbs = table_38213_13_3_c2[index_4msb];
type0_PDCCH_CSS_config->num_symbols = table_38213_13_3_c3[index_4msb];
type0_PDCCH_CSS_config->rb_offset = table_38213_13_3_c4[index_4msb];
}else if(min_channel_bw & bw_40MHz){
type0_PDCCH_CSS_config->rb_offset = table_38213_13_3_c4[index_4msb];
} else if(min_channel_bw & bw_40MHz) {
AssertFatal(index_4msb < 9, "38.213 Table 13-5 4 MSB out of range\n");
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
type0_PDCCH_CSS_config->num_rbs = table_38213_13_5_c2[index_4msb];
type0_PDCCH_CSS_config->num_rbs = table_38213_13_5_c2[index_4msb];
type0_PDCCH_CSS_config->num_symbols = table_38213_13_5_c3[index_4msb];
type0_PDCCH_CSS_config->rb_offset = table_38213_13_5_c4[index_4msb];
}else{ ; }
type0_PDCCH_CSS_config->rb_offset = table_38213_13_5_c4[index_4msb];
} else{ ; }
break;
case (NR_SubcarrierSpacing_kHz30 << 3) | NR_SubcarrierSpacing_kHz30:
if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)){
if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)) {
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
type0_PDCCH_CSS_config->num_rbs = table_38213_13_4_c2[index_4msb];
type0_PDCCH_CSS_config->num_rbs = table_38213_13_4_c2[index_4msb];
type0_PDCCH_CSS_config->num_symbols = table_38213_13_4_c3[index_4msb];
type0_PDCCH_CSS_config->rb_offset = table_38213_13_4_c4[index_4msb];
type0_PDCCH_CSS_config->rb_offset = table_38213_13_4_c4[index_4msb];
}else if(min_channel_bw & bw_40MHz){
} else if(min_channel_bw & bw_40MHz) {
AssertFatal(index_4msb < 10, "38.213 Table 13-6 4 MSB out of range\n");
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
type0_PDCCH_CSS_config->num_rbs = table_38213_13_6_c2[index_4msb];
type0_PDCCH_CSS_config->num_rbs = table_38213_13_6_c2[index_4msb];
type0_PDCCH_CSS_config->num_symbols = table_38213_13_6_c3[index_4msb];
type0_PDCCH_CSS_config->rb_offset = table_38213_13_6_c4[index_4msb];
}else{ ; }
type0_PDCCH_CSS_config->rb_offset = table_38213_13_6_c4[index_4msb];
} else{ ; }
break;
case (NR_SubcarrierSpacing_kHz120 << 3) | NR_SubcarrierSpacing_kHz60:
AssertFatal(index_4msb < 12, "38.213 Table 13-7 4 MSB out of range\n");
if (index_4msb < 8) {
@@ -3660,15 +3654,14 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 2;
}
type0_PDCCH_CSS_config->num_rbs = table_38213_13_7_c2[index_4msb];
type0_PDCCH_CSS_config->num_rbs = table_38213_13_7_c2[index_4msb];
type0_PDCCH_CSS_config->num_symbols = table_38213_13_7_c3[index_4msb];
if(!is_condition_A && (index_4msb == 8 || index_4msb == 10)){
type0_PDCCH_CSS_config->rb_offset = table_38213_13_7_c4[index_4msb] - 1;
}else{
type0_PDCCH_CSS_config->rb_offset = table_38213_13_7_c4[index_4msb];
if(!is_condition_A && (index_4msb == 8 || index_4msb == 10)) {
type0_PDCCH_CSS_config->rb_offset = table_38213_13_7_c4[index_4msb] - 1;
} else {
type0_PDCCH_CSS_config->rb_offset = table_38213_13_7_c4[index_4msb];
}
break;
case (NR_SubcarrierSpacing_kHz120 << 3) | NR_SubcarrierSpacing_kHz120:
AssertFatal(index_4msb < 8, "38.213 Table 13-8 4 MSB out of range\n");
if (index_4msb < 4) {
@@ -3677,23 +3670,21 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 3;
}
type0_PDCCH_CSS_config->num_rbs = table_38213_13_8_c2[index_4msb];
type0_PDCCH_CSS_config->num_rbs = table_38213_13_8_c2[index_4msb];
type0_PDCCH_CSS_config->num_symbols = table_38213_13_8_c3[index_4msb];
if(!is_condition_A && (index_4msb == 4 || index_4msb == 6)){
type0_PDCCH_CSS_config->rb_offset = table_38213_13_8_c4[index_4msb] - 1;
}else{
type0_PDCCH_CSS_config->rb_offset = table_38213_13_8_c4[index_4msb];
if(!is_condition_A && (index_4msb == 4 || index_4msb == 6)) {
type0_PDCCH_CSS_config->rb_offset = table_38213_13_8_c4[index_4msb] - 1;
} else {
type0_PDCCH_CSS_config->rb_offset = table_38213_13_8_c4[index_4msb];
}
break;
case (NR_SubcarrierSpacing_kHz240 << 3) | NR_SubcarrierSpacing_kHz60:
AssertFatal(index_4msb < 4, "38.213 Table 13-9 4 MSB out of range\n");
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
type0_PDCCH_CSS_config->num_rbs = table_38213_13_9_c2[index_4msb];
type0_PDCCH_CSS_config->num_rbs = table_38213_13_9_c2[index_4msb];
type0_PDCCH_CSS_config->num_symbols = table_38213_13_9_c3[index_4msb];
type0_PDCCH_CSS_config->rb_offset = table_38213_13_9_c4[index_4msb];
type0_PDCCH_CSS_config->rb_offset = table_38213_13_9_c4[index_4msb];
break;
case (NR_SubcarrierSpacing_kHz240 << 3) | NR_SubcarrierSpacing_kHz120:
AssertFatal(index_4msb < 8, "38.213 Table 13-10 4 MSB out of range\n");
if (index_4msb < 4) {
@@ -3701,50 +3692,62 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
} else if (index_4msb < 8) {
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 2;
}
type0_PDCCH_CSS_config->num_rbs = table_38213_13_10_c2[index_4msb];
type0_PDCCH_CSS_config->num_rbs = table_38213_13_10_c2[index_4msb];
type0_PDCCH_CSS_config->num_symbols = table_38213_13_10_c3[index_4msb];
if(!is_condition_A && (index_4msb == 4 || index_4msb == 6)){
type0_PDCCH_CSS_config->rb_offset = table_38213_13_10_c4[index_4msb]-1;
}else{
type0_PDCCH_CSS_config->rb_offset = table_38213_13_10_c4[index_4msb];
if(!is_condition_A && (index_4msb == 4 || index_4msb == 6)) {
type0_PDCCH_CSS_config->rb_offset = table_38213_13_10_c4[index_4msb]-1;
} else {
type0_PDCCH_CSS_config->rb_offset = table_38213_13_10_c4[index_4msb];
}
break;
default:
LOG_E(NR_MAC,"NR_SubcarrierSpacing_kHz30 %d, scs_ssb %d, scs_pdcch %d, min_chan_bw %d\n",NR_SubcarrierSpacing_kHz30,(int)scs_ssb,(int)scs_pdcch,min_channel_bw);
LOG_E(NR_MAC,
"NR_SubcarrierSpacing_kHz30 %d, scs_ssb %d, scs_pdcch %d, min_chan_bw %d\n",
NR_SubcarrierSpacing_kHz30,
(int)scs_ssb,
(int)scs_pdcch,
min_channel_bw);
break;
}
LOG_D(NR_MAC,"Coreset0: index_4msb=%d, num_rbs=%d, num_symb=%d, rb_offset=%d\n",
index_4msb,type0_PDCCH_CSS_config->num_rbs,type0_PDCCH_CSS_config->num_symbols,type0_PDCCH_CSS_config->rb_offset );
LOG_D(NR_MAC,
"Coreset0: index_4msb=%d, num_rbs=%d, num_symb=%d, rb_offset=%d\n",
index_4msb,
type0_PDCCH_CSS_config->num_rbs,
type0_PDCCH_CSS_config->num_symbols,
type0_PDCCH_CSS_config->rb_offset);
AssertFatal(type0_PDCCH_CSS_config->num_rbs != -1, "Type0 PDCCH coreset num_rbs undefined, index_4msb=%d, min_channel_bw %d, scs_ssb %d, scs_pdcch %d\n",index_4msb,min_channel_bw,(int)scs_ssb,(int)scs_pdcch);
AssertFatal(type0_PDCCH_CSS_config->num_rbs != -1,
"Type0 PDCCH coreset num_rbs undefined, index_4msb=%d, min_channel_bw %d, scs_ssb %d, scs_pdcch %d\n",
index_4msb,
min_channel_bw,
(int)scs_ssb,
(int)scs_pdcch);
AssertFatal(type0_PDCCH_CSS_config->num_symbols != -1, "Type0 PDCCH coreset num_symbols undefined");
AssertFatal(type0_PDCCH_CSS_config->rb_offset != -1, "Type0 PDCCH coreset rb_offset undefined");
// type0-pdcch search space
float big_o = 0.0f;
float big_m = 0.0f;
type0_PDCCH_CSS_config->sfn_c = -1; // only valid for mux=1
type0_PDCCH_CSS_config->n_c = UINT_MAX;
type0_PDCCH_CSS_config->sfn_c = 0; // only valid for mux=1
type0_PDCCH_CSS_config->slot = UINT_MAX;
type0_PDCCH_CSS_config->first_symbol_index = UINT_MAX;
type0_PDCCH_CSS_config->search_space_duration = 0; // element of search space
// 38.213 table 10.1-1
/// MUX PATTERN 1
int slots_per_frame = get_slots_per_frame_from_scs(scs_ssb);
if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 1 && frequency_range == FR1){
if (type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 1 && frequency_range == FR1) {
big_o = table_38213_13_11_c1[index_4lsb];
big_m = table_38213_13_11_c3[index_4lsb];
uint32_t temp = (uint32_t)(big_o*(1<<scs_pdcch)) + (uint32_t)(type0_PDCCH_CSS_config->ssb_index*big_m);
type0_PDCCH_CSS_config->n_c = temp / num_slot_per_frame;
type0_PDCCH_CSS_config->sfn_c = type0_PDCCH_CSS_config->n_c % 2;
uint32_t temp = (uint32_t)(big_o * (1 << scs_pdcch)) + (uint32_t)(type0_PDCCH_CSS_config->ssb_index * big_m);
type0_PDCCH_CSS_config->slot = temp % num_slot_per_frame;
type0_PDCCH_CSS_config->sfn_c = (temp / num_slot_per_frame) % 2;
if((index_4lsb == 1 || index_4lsb == 3 || index_4lsb == 5 || index_4lsb == 7) && (type0_PDCCH_CSS_config->ssb_index&1)){
if((index_4lsb == 1 || index_4lsb == 3 || index_4lsb == 5 || index_4lsb == 7) && (type0_PDCCH_CSS_config->ssb_index & 1)) {
type0_PDCCH_CSS_config->first_symbol_index = type0_PDCCH_CSS_config->num_symbols;
}else{
} else {
type0_PDCCH_CSS_config->first_symbol_index = table_38213_13_11_c4[index_4lsb];
}
// 38.213 chapter 13: over two consecutive slots
@@ -3753,19 +3756,19 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
type0_PDCCH_CSS_config->search_space_frame_period = slots_per_frame << 1;
}
if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 1 && frequency_range == FR2){
if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 1 && frequency_range == FR2) {
big_o = table_38213_13_12_c1[index_4lsb];
big_m = table_38213_13_12_c3[index_4lsb];
uint32_t temp = (uint32_t)(big_o*(1<<scs_pdcch)) + (uint32_t)(type0_PDCCH_CSS_config->ssb_index*big_m);
type0_PDCCH_CSS_config->n_c = temp / num_slot_per_frame;
type0_PDCCH_CSS_config->sfn_c = type0_PDCCH_CSS_config->n_c % 2;
uint32_t temp = (uint32_t)(big_o * (1 << scs_pdcch)) + (uint32_t)(type0_PDCCH_CSS_config->ssb_index * big_m);
type0_PDCCH_CSS_config->slot = temp % num_slot_per_frame;
type0_PDCCH_CSS_config->sfn_c = (temp / num_slot_per_frame) % 2;
if((index_4lsb == 1 || index_4lsb == 3 || index_4lsb == 5 || index_4lsb == 10) && (type0_PDCCH_CSS_config->ssb_index&1)){
if((index_4lsb == 1 || index_4lsb == 3 || index_4lsb == 5 || index_4lsb == 10) && (type0_PDCCH_CSS_config->ssb_index & 1)) {
type0_PDCCH_CSS_config->first_symbol_index = 7;
}else if((index_4lsb == 6 || index_4lsb == 7 || index_4lsb == 8 || index_4lsb == 11) && (type0_PDCCH_CSS_config->ssb_index&1)){
} else if ((index_4lsb == 6 || index_4lsb == 7 || index_4lsb == 8 || index_4lsb == 11) && (type0_PDCCH_CSS_config->ssb_index & 1)) {
type0_PDCCH_CSS_config->first_symbol_index = type0_PDCCH_CSS_config->num_symbols;
}else{
} else {
type0_PDCCH_CSS_config->first_symbol_index = 0;
}
// 38.213 chapter 13: over two consecutive slots
@@ -3775,15 +3778,15 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
}
/// MUX PATTERN 2
if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 2){
if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 2) {
if((scs_ssb == NR_SubcarrierSpacing_kHz120) && (scs_pdcch == NR_SubcarrierSpacing_kHz60)){
if((scs_ssb == NR_SubcarrierSpacing_kHz120) && (scs_pdcch == NR_SubcarrierSpacing_kHz60)) {
// 38.213 Table 13-13
AssertFatal(index_4lsb == 0, "38.213 Table 13-13 4 LSB out of range\n");
// PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot
// sfn_c = SFN_C_EQ_SFN_SSB;
type0_PDCCH_CSS_config->n_c = ssb_slot;
switch(type0_PDCCH_CSS_config->ssb_index & 0x3){ // ssb_index(i) mod 4
type0_PDCCH_CSS_config->slot = ssb_slot;
switch(type0_PDCCH_CSS_config->ssb_index & 0x3) { // ssb_index(i) mod 4
case 0:
type0_PDCCH_CSS_config->first_symbol_index = 0;
break;
@@ -3796,16 +3799,16 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
case 3:
type0_PDCCH_CSS_config->first_symbol_index = 7;
break;
default: break;
default:
break;
}
}else if((scs_ssb == NR_SubcarrierSpacing_kHz240) && (scs_pdcch == NR_SubcarrierSpacing_kHz120)){
} else if((scs_ssb == NR_SubcarrierSpacing_kHz240) && (scs_pdcch == NR_SubcarrierSpacing_kHz120)) {
// 38.213 Table 13-14
AssertFatal(index_4lsb == 0, "38.213 Table 13-14 4 LSB out of range\n");
// PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot
// sfn_c = SFN_C_EQ_SFN_SSB;
type0_PDCCH_CSS_config->n_c = ssb_slot;
switch(type0_PDCCH_CSS_config->ssb_index & 0x7){ // ssb_index(i) mod 8
type0_PDCCH_CSS_config->slot = ssb_slot;
switch(type0_PDCCH_CSS_config->ssb_index & 0x7) { // ssb_index(i) mod 8
case 0:
type0_PDCCH_CSS_config->first_symbol_index = 0;
break;
@@ -3820,11 +3823,11 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
break;
case 4:
type0_PDCCH_CSS_config->first_symbol_index = 12;
type0_PDCCH_CSS_config->n_c = ssb_slot - 1;
type0_PDCCH_CSS_config->slot = ssb_slot - 1;
break;
case 5:
type0_PDCCH_CSS_config->first_symbol_index = 13;
type0_PDCCH_CSS_config->n_c = ssb_slot - 1;
type0_PDCCH_CSS_config->slot = ssb_slot - 1;
break;
case 6:
type0_PDCCH_CSS_config->first_symbol_index = 0;
@@ -3832,9 +3835,10 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
case 7:
type0_PDCCH_CSS_config->first_symbol_index = 1;
break;
default: break;
default:
break;
}
}else{ ; }
} else { ; }
// 38.213 chapter 13: over one slot
type0_PDCCH_CSS_config->search_space_duration = 1;
// SSB periodicity in slots
@@ -3842,14 +3846,14 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
}
/// MUX PATTERN 3
if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 3){
if((scs_ssb == NR_SubcarrierSpacing_kHz120) && (scs_pdcch == NR_SubcarrierSpacing_kHz120)){
if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 3) {
if((scs_ssb == NR_SubcarrierSpacing_kHz120) && (scs_pdcch == NR_SubcarrierSpacing_kHz120)) {
// 38.213 Table 13-15
AssertFatal(index_4lsb == 0, "38.213 Table 13-15 4 LSB out of range\n");
// PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot
// sfn_c = SFN_C_EQ_SFN_SSB;
type0_PDCCH_CSS_config->n_c = ssb_slot;
switch(type0_PDCCH_CSS_config->ssb_index & 0x3){ // ssb_index(i) mod 4
type0_PDCCH_CSS_config->slot = ssb_slot;
switch(type0_PDCCH_CSS_config->ssb_index & 0x3) { // ssb_index(i) mod 4
case 0:
type0_PDCCH_CSS_config->first_symbol_index = 4;
break;
@@ -3862,22 +3866,28 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
case 3:
type0_PDCCH_CSS_config->first_symbol_index = 6;
break;
default: break;
default:
break;
}
}else{ ; }
} else { ; }
// 38.213 chapter 13: over one slot
type0_PDCCH_CSS_config->search_space_duration = 1;
// SSB periodicity in slots
type0_PDCCH_CSS_config->search_space_frame_period = ssb_period * slots_per_frame;
}
AssertFatal(type0_PDCCH_CSS_config->slot != UINT_MAX, "type0_PDCCH_CSS_config slot not configured");
AssertFatal(type0_PDCCH_CSS_config->sfn_c >= 0, "");
AssertFatal(type0_PDCCH_CSS_config->n_c != UINT_MAX, "");
type0_PDCCH_CSS_config->n_0 = ((uint32_t)(big_o*(1<<scs_pdcch)) + (uint32_t)(type0_PDCCH_CSS_config->ssb_index*big_m))%num_slot_per_frame;
type0_PDCCH_CSS_config->cset_start_rb = ssb_offset_point_a - type0_PDCCH_CSS_config->rb_offset;
AssertFatal(type0_PDCCH_CSS_config->cset_start_rb >= 0, "Invalid CSET0 start PRB %d SSB offset point A %d RB offset %d\n",
type0_PDCCH_CSS_config->cset_start_rb, ssb_offset_point_a, type0_PDCCH_CSS_config->rb_offset);
AssertFatal(type0_PDCCH_CSS_config->cset_start_rb >= 0,
"Invalid CSET0 start PRB %d SSB offset point A %d RB offset %d\n",
type0_PDCCH_CSS_config->cset_start_rb,
ssb_offset_point_a,
type0_PDCCH_CSS_config->rb_offset);
AssertFatal(type0_PDCCH_CSS_config->cset_start_rb + type0_PDCCH_CSS_config->num_rbs <= grid_size,
"Invalid combination of start PRB %d and size %d of CSET0. Exceeds full BW %d\n",
type0_PDCCH_CSS_config->cset_start_rb,
type0_PDCCH_CSS_config->num_rbs,
grid_size);
}
void fill_coresetZero(NR_ControlResourceSet_t *coreset0, NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config)
@@ -3950,8 +3960,8 @@ void fill_searchSpaceZero(NR_SearchSpace_t *ss0, int slots_per_frame, NR_Type0_P
const uint32_t periodicity = type0_PDCCH_CSS_config->search_space_frame_period;
const uint32_t offset = type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 1 ?
type0_PDCCH_CSS_config->n_0 + (slots_per_frame * type0_PDCCH_CSS_config->sfn_c) :
type0_PDCCH_CSS_config->n_c;
type0_PDCCH_CSS_config->slot + (slots_per_frame * type0_PDCCH_CSS_config->sfn_c) :
type0_PDCCH_CSS_config->slot;
ss0->searchSpaceId = 0;
*ss0->controlResourceSetId = 0;
@@ -114,6 +114,7 @@ int16_t fill_dmrs_mask(const NR_PDSCH_Config_t *pdsch_Config,
mappingType_t mappingtype,
int length);
int get_slots_per_frame_from_scs(int scs);
uint16_t get_ul_bitmap(const frame_structure_t *fs, int slot);
bool is_ul_slot(const slot_t slot, const frame_structure_t *fs);
bool is_dl_slot(const slot_t slot, const frame_structure_t *fs);
bool is_mixed_slot(const slot_t slot, const frame_structure_t *fs);
@@ -171,10 +172,7 @@ uint16_t get_rb_bwp_dci(nr_dci_format_t format,
uint16_t initial_ul_bwp_size,
uint16_t initial_dl_bwp_size);
void find_aggregation_candidates(uint8_t *aggregation_level,
uint8_t *nr_of_candidates,
const NR_SearchSpace_t *ss,
int maxL);
void find_aggregation_candidates(int *aggregation_level, int *nr_of_candidates, const NR_SearchSpace_t *ss, int L);
bool get_nr_prach_sched_from_info(nr_prach_info_t info,
int config_index,
@@ -244,6 +242,7 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
NR_SubcarrierSpacing_t scs_ssb,
frequency_range_t frequency_range,
int nr_band,
int grid_size,
uint32_t ssb_index,
uint32_t ssb_period,
uint32_t ssb_offset_point_a);
@@ -24,6 +24,15 @@
#include "common/utils/nr/nr_common.h"
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h"
uint16_t get_ul_bitmap(const frame_structure_t *fs, int slot)
{
const int slot_period = slot % fs->numb_slots_period;
const tdd_bitmap_t *bm = &fs->period_cfg.tdd_slot_bitmap[slot_period];
/* For some reason, we only store the number of symbols if it's mixed */
const int num_ul_symbols = bm->slot_type == TDD_NR_MIXED_SLOT ? bm->num_ul_symbols : 14;
return SL_to_bitmap(14 - num_ul_symbols, num_ul_symbols);
}
int get_slots_per_frame_from_scs(int scs)
{
const int nr_slots_per_frame[5] = {10, 20, 40, 80, 160};
@@ -44,11 +44,8 @@ static void fill_dci_search_candidates(const NR_SearchSpace_t *ss, fapi_nr_dl_co
int i = 0;
for (int maxL = 16; maxL > 0; maxL >>= 1) {
uint8_t aggregation, max_number_of_candidates;
find_aggregation_candidates(&aggregation,
&max_number_of_candidates,
ss,
maxL);
int aggregation, max_number_of_candidates;
find_aggregation_candidates(&aggregation, &max_number_of_candidates, ss, maxL);
if (max_number_of_candidates == 0)
continue;
LOG_T(NR_MAC_DCI, "L %d, max number of candidates %d, aggregation %d\n", maxL, max_number_of_candidates, aggregation);
@@ -449,6 +446,7 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
scs,
mac->frequency_range,
mac->nr_band,
273, // at this point UE in principle doesn't know the grid size (we assume the largest)
mac->mib_ssb,
1, // If the UE is not configured with a periodicity, the UE assumes a periodicity of a half frame
ssb_offset_point_a);
+1 -4
View File
@@ -195,10 +195,7 @@ void nr_ue_decode_mib(NR_UE_MAC_INST_t *mac, int cc_id)
frame = frame << 4;
mac->mib_frame = frame | frame_number_4lsb;
if (mac->frequency_range == FR2) {
for (int i = 0; i < 3; i++)
mac->mib_ssb += (((extra_bits >> (7 - i)) & 0x01) << (3 + i));
} else{
if (mac->frequency_range == FR1) {
if(ssb_subcarrier_offset_msb)
ssb_subcarrier_offset = ssb_subcarrier_offset | 0x10;
}
+35 -24
View File
@@ -777,20 +777,17 @@ static void initialize_beam_information(NR_beam_info_t *beam_info, int mu, int s
}
}
static void config_sched_ctrlCommon(gNB_MAC_INST *nr_mac)
static void config_sched_ctrlSIB1(gNB_MAC_INST *nr_mac)
{
const NR_MIB_t *mib = nr_mac->common_channels[0].mib->message.choice.mib;
NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels[0].ServingCellConfigCommon;
NR_UE_sched_ctrl_t *sched_ctrlCommon = calloc_or_fail(1, sizeof(*sched_ctrlCommon));
nr_mac->sched_ctrlCommon = sched_ctrlCommon;
sched_ctrlCommon->search_space = calloc_or_fail(1, sizeof(*sched_ctrlCommon->search_space));
sched_ctrlCommon->coreset = calloc_or_fail(1, sizeof(*sched_ctrlCommon->coreset));
NR_sched_ctrl_sib1_t *sched_ctrlCommon = calloc_or_fail(1, sizeof(*sched_ctrlCommon));
nr_mac->sched_ctrlSIB1 = sched_ctrlCommon;
NR_SubcarrierSpacing_t scs = *scc->ssbSubcarrierSpacing;
const long band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
uint16_t ssb_start_symbol = get_ssb_start_symbol(band, scs, 0);
const int bw = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
int8_t ssb_period = *scc->ssb_periodicityServingCell;
uint8_t ssb_frame_periodicity = 1;
if (ssb_period > 1)
@@ -801,24 +798,38 @@ static void config_sched_ctrlCommon(gNB_MAC_INST *nr_mac)
const int prb_offset = frequency_range == FR1 ? nr_mac->ssb_OffsetPointA >> scs : nr_mac->ssb_OffsetPointA >> (scs - 2);
NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config = {0};
get_type0_PDCCH_CSS_config_parameters(&type0_PDCCH_CSS_config,
0,
mib,
numb_slots_frame,
nr_mac->ssb_SubcarrierOffset,
ssb_start_symbol,
scs,
frequency_range,
band,
0,
ssb_frame_periodicity,
prb_offset);
fill_searchSpaceZero(sched_ctrlCommon->search_space, numb_slots_frame, &type0_PDCCH_CSS_config);
fill_coresetZero(sched_ctrlCommon->coreset, &type0_PDCCH_CSS_config);
for (int i = 0; i < get_max_ssbs(scc); i++) {
if (is_ssb_configured(scc, i)) {
uint16_t ssb_start_symbol = get_ssb_start_symbol(band, scs, i);
get_type0_PDCCH_CSS_config_parameters(&type0_PDCCH_CSS_config,
0,
mib,
numb_slots_frame,
nr_mac->ssb_SubcarrierOffset,
ssb_start_symbol,
scs,
frequency_range,
band,
bw,
i,
ssb_frame_periodicity,
prb_offset);
fill_searchSpaceZero(&sched_ctrlCommon->search_space[i], numb_slots_frame, &type0_PDCCH_CSS_config);
}
}
// CSET0 doesn't depend on SSB index
fill_coresetZero(&sched_ctrlCommon->coreset, &type0_PDCCH_CSS_config);
nr_mac->cset0_bwp_start = type0_PDCCH_CSS_config.cset_start_rb;
nr_mac->cset0_bwp_size = type0_PDCCH_CSS_config.num_rbs;
if (type0_PDCCH_CSS_config.type0_pdcch_ss_mux_pattern > 1) {
int bwp_start = NRRIV2PRBOFFSET(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,
MAX_BWP_SIZE);
int bwp_size = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
// we need to configure a commonControlResourceSet != 0
// because CSET0 would start from a symbol != 0 and that's unwanted for anything but SIB1
// The network configures the commonControlResourceSet in SIB1 so that it is contained in the bandwidth of CSET0
configure_coreset_for_mux23(scc, nr_mac->cset0_bwp_start - bwp_start, nr_mac->cset0_bwp_size, bwp_start, bwp_size);
}
}
/**
@@ -888,7 +899,7 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, c
find_SSB_and_RO_available(nrmac);
if (IS_SA_MODE(get_softmodem_params()))
config_sched_ctrlCommon(nrmac);
config_sched_ctrlSIB1(nrmac);
seq_arr_init(&nrmac->ul_tda, sizeof(NR_tda_info_t));
init_ul_tda_info(scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList, &nrmac->ul_tda);
+184 -180
View File
@@ -812,187 +812,191 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
uint16_t K2 = tda_info.k2 + get_NTN_Koffset(scc);
const int sched_frame = (frame + (slot + K2) / slots_frame) % MAX_FRAME_NUMBER;
const int sched_slot = (slot + K2) % slots_frame;
uint16_t slot_bitmap = get_ul_bitmap(&nr_mac->frame_structure, sched_slot);
uint16_t msg3_mask = SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols);
if (is_dl_slot(slot, &nr_mac->frame_structure) && is_ul_slot(sched_slot, &nr_mac->frame_structure)) {
NR_beam_alloc_t beam_ul = beam_allocation_procedure(&nr_mac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_frame);
if (beam_ul.idx < 0)
return;
NR_beam_alloc_t beam_dci = beam_allocation_procedure(&nr_mac->beam_info, frame, slot, UE->UE_beam_index, slots_frame);
if (beam_dci.idx < 0) {
reset_beam_status(&nr_mac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_frame, beam_ul.new_beam);
return;
}
int buffer_index = ul_buffer_index(sched_frame, sched_slot, slots_frame, nr_mac->vrb_map_UL_size);
uint16_t *vrb_map_UL = &nr_mac->common_channels[CC_id].vrb_map_UL[beam_ul.idx][buffer_index * MAX_BWP_SIZE];
if (!is_dl_slot(slot, &nr_mac->frame_structure)
|| !is_ul_slot(sched_slot, &nr_mac->frame_structure)
|| !((msg3_mask & slot_bitmap) == msg3_mask))
return;
NR_pusch_dmrs_t dmrs_info = get_ul_dmrs_params(scc, ul_bwp, &tda_info, 1);
int num_dmrs_symb = count_bits64_with_mask(dmrs_info.ul_dmrs_symb_pos, tda_info.startSymbolIndex, tda_info.nrOfSymbols);
int TBS = 0, mcsindex = 0, R = 0, Qm = 0;
while(TBS < 7) { // TBS for msg3 is 7 bytes (except for RRCResumeRequest1 currently not implemented)
mcsindex++;
AssertFatal(mcsindex <= 28, "Exceeding MCS limit for Msg3\n");
R = nr_get_code_rate_ul(mcsindex, ul_bwp->mcs_table);
Qm = nr_get_Qm_ul(mcsindex, ul_bwp->mcs_table);
TBS = nr_compute_tbs(Qm,
R,
ra->msg3_nb_rb,
tda_info.nrOfSymbols,
num_dmrs_symb * 12, // nb dmrs set for no data in dmrs symbol
0, //nb_rb_oh
0, // to verify tb scaling
1) >> 3;
}
NR_sched_pusch_t sched_pusch = {
.bwp_info = get_pusch_bwp_start_size(UE),
.tb_size = TBS,
.rbSize = ra->msg3_nb_rb,
.R = R,
.Qm = Qm,
.mcs = mcsindex,
.nrOfLayers = 1,
.tda_info = tda_info,
.dmrs_info = dmrs_info,
};
int rbStart = 0;
for (int i = 0; (i < ra->msg3_nb_rb) && (rbStart <= (sched_pusch.bwp_info.bwpSize - ra->msg3_nb_rb)); i++) {
if (vrb_map_UL[rbStart + sched_pusch.bwp_info.bwpStart + i] & SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols)) {
rbStart += i;
i = 0;
}
}
if (rbStart > (sched_pusch.bwp_info.bwpSize - ra->msg3_nb_rb)) {
// cannot find free vrb_map for msg3 retransmission in this slot
reset_beam_status(&nr_mac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_frame, beam_ul.new_beam);
reset_beam_status(&nr_mac->beam_info, frame, slot, UE->UE_beam_index, slots_frame, beam_dci.new_beam);
return;
}
sched_pusch.rbStart = rbStart;
LOG_I(NR_MAC,
"%4d%2d: RA RNTI %04x CC_id %d Scheduling retransmission of Msg3 in (%d,%d)\n",
frame,
slot,
UE->rnti,
CC_id,
sched_frame,
sched_slot);
buffer_index = ul_buffer_index(sched_frame, sched_slot, slots_frame, nr_mac->UL_tti_req_ahead_size);
nfapi_nr_ul_tti_request_t *future_ul_tti_req = &nr_mac->UL_tti_req_ahead[CC_id][buffer_index];
AssertFatal(future_ul_tti_req->SFN == sched_frame
&& future_ul_tti_req->Slot == sched_slot,
"future UL_tti_req's frame.slot %d.%d does not match PUSCH %d.%d\n",
future_ul_tti_req->SFN,
future_ul_tti_req->Slot,
sched_frame,
sched_slot);
AssertFatal(future_ul_tti_req->n_pdus <
sizeof(future_ul_tti_req->pdus_list) / sizeof(future_ul_tti_req->pdus_list[0]),
"Invalid future_ul_tti_req->n_pdus %d\n", future_ul_tti_req->n_pdus);
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
nfapi_nr_pusch_pdu_t *pusch_pdu = prepare_pusch_pdu(future_ul_tti_req,
UE,
scc,
&sched_pusch,
get_transformPrecoding(ul_bwp, NR_UL_DCI_FORMAT_0_0, 0),
0,
ra->msg3_round,
ul_bwp->pusch_Config && ul_bwp->pusch_Config->frequencyHopping,
UE->rnti,
nr_mac->beam_info.beam_mode);
future_ul_tti_req->n_pdus += 1;
// generation of DCI 0_0 to schedule msg3 retransmission
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][coresetid];
if (!pdcch_pdu_rel15) {
nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu = &ul_dci_req->ul_dci_pdu_list[ul_dci_req->numPdus];
memset(ul_dci_request_pdu, 0, sizeof(nfapi_nr_ul_dci_request_pdus_t));
ul_dci_request_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15;
ul_dci_req->numPdus += 1;
nr_configure_pdcch(pdcch_pdu_rel15, coreset, &UE->UE_sched_ctrl.sched_pdcch);
nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15;
}
uint8_t aggregation_level;
int CCEIndex = get_cce_index(nr_mac,
CC_id, slot, 0,
&aggregation_level,
beam_dci.idx,
ss,
coreset,
&UE->UE_sched_ctrl.sched_pdcch,
0);
if (CCEIndex < 0) {
LOG_E(NR_MAC, "UE %04x cannot find free CCE!\n", UE->rnti);
reset_beam_status(&nr_mac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_frame, beam_ul.new_beam);
reset_beam_status(&nr_mac->beam_info, frame, slot, UE->UE_beam_index, slots_frame, beam_dci.new_beam);
return;
}
// Fill PDCCH DL DCI PDU
const uint16_t fapi_beam = convert_to_fapi_beam(UE->UE_beam_index, nr_mac->beam_info.beam_mode);
nfapi_nr_dl_dci_pdu_t *dci_pdu =
prepare_dci_pdu(pdcch_pdu_rel15, scc, ss, coreset, aggregation_level, CCEIndex, fapi_beam, UE->rnti);
pdcch_pdu_rel15->numDlDci++;
dci_pdu_rel15_t uldci_payload = {0};
config_uldci(sc_info,
pusch_pdu,
&uldci_payload,
NULL,
NULL,
ra->Msg3_tda_id,
ra->msg3_TPC,
1, // Not toggling NDI in msg3 retransmissions
ul_bwp,
ss->searchSpaceType->present);
// Reset TPC to 0 dB to not request new gain multiple times before computing new value for SNR
ra->msg3_TPC = 1;
fill_dci_pdu_rel15(sc_info,
&UE->current_DL_BWP,
ul_bwp,
dci_pdu,
&uldci_payload,
NR_UL_DCI_FORMAT_0_0,
TYPE_TC_RNTI_,
ss,
coreset,
0, // parameter not needed for DCI 0_0
nr_mac->cset0_bwp_size);
// Mark the corresponding RBs as used
fill_pdcch_vrb_map(nr_mac,
CC_id,
&UE->UE_sched_ctrl.sched_pdcch,
CCEIndex,
aggregation_level,
beam_dci.idx);
for (int rb = 0; rb < ra->msg3_nb_rb; rb++) {
vrb_map_UL[rbStart + sched_pusch.bwp_info.bwpStart + rb] |= SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols);
}
// Restart RA contention resolution timer in Msg3 retransmission slot (current slot + K2)
// 3GPP TS 38.321 Section 5.1.5 Contention Resolution
start_ra_contention_resolution_timer(
ra,
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ra_ContentionResolutionTimer,
K2,
ul_bwp->scs);
// reset state to wait msg3
ra->ra_state = nrRA_WAIT_Msg3;
ra->Msg3_frame = sched_frame;
ra->Msg3_slot = sched_slot;
NR_beam_alloc_t beam_ul = beam_allocation_procedure(&nr_mac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_frame);
if (beam_ul.idx < 0)
return;
NR_beam_alloc_t beam_dci = beam_allocation_procedure(&nr_mac->beam_info, frame, slot, UE->UE_beam_index, slots_frame);
if (beam_dci.idx < 0) {
reset_beam_status(&nr_mac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_frame, beam_ul.new_beam);
return;
}
int buffer_index = ul_buffer_index(sched_frame, sched_slot, slots_frame, nr_mac->vrb_map_UL_size);
uint16_t *vrb_map_UL = &nr_mac->common_channels[CC_id].vrb_map_UL[beam_ul.idx][buffer_index * MAX_BWP_SIZE];
NR_pusch_dmrs_t dmrs_info = get_ul_dmrs_params(scc, ul_bwp, &tda_info, 1);
int num_dmrs_symb = count_bits64_with_mask(dmrs_info.ul_dmrs_symb_pos, tda_info.startSymbolIndex, tda_info.nrOfSymbols);
int TBS = 0, mcsindex = 0, R = 0, Qm = 0;
while(TBS < 7) { // TBS for msg3 is 7 bytes (except for RRCResumeRequest1 currently not implemented)
mcsindex++;
AssertFatal(mcsindex <= 28, "Exceeding MCS limit for Msg3\n");
R = nr_get_code_rate_ul(mcsindex, ul_bwp->mcs_table);
Qm = nr_get_Qm_ul(mcsindex, ul_bwp->mcs_table);
TBS = nr_compute_tbs(Qm,
R,
ra->msg3_nb_rb,
tda_info.nrOfSymbols,
num_dmrs_symb * 12, // nb dmrs set for no data in dmrs symbol
0, //nb_rb_oh
0, // to verify tb scaling
1) >> 3;
}
NR_sched_pusch_t sched_pusch = {
.bwp_info = get_pusch_bwp_start_size(UE),
.tb_size = TBS,
.rbSize = ra->msg3_nb_rb,
.R = R,
.Qm = Qm,
.mcs = mcsindex,
.nrOfLayers = 1,
.tda_info = tda_info,
.dmrs_info = dmrs_info,
};
int rbStart = 0;
for (int i = 0; (i < ra->msg3_nb_rb) && (rbStart <= (sched_pusch.bwp_info.bwpSize - ra->msg3_nb_rb)); i++) {
if (vrb_map_UL[rbStart + sched_pusch.bwp_info.bwpStart + i] & SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols)) {
rbStart += i;
i = 0;
}
}
if (rbStart > (sched_pusch.bwp_info.bwpSize - ra->msg3_nb_rb)) {
// cannot find free vrb_map for msg3 retransmission in this slot
reset_beam_status(&nr_mac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_frame, beam_ul.new_beam);
reset_beam_status(&nr_mac->beam_info, frame, slot, UE->UE_beam_index, slots_frame, beam_dci.new_beam);
return;
}
sched_pusch.rbStart = rbStart;
LOG_I(NR_MAC,
"%4d%2d: RA RNTI %04x CC_id %d Scheduling retransmission of Msg3 in (%d,%d)\n",
frame,
slot,
UE->rnti,
CC_id,
sched_frame,
sched_slot);
buffer_index = ul_buffer_index(sched_frame, sched_slot, slots_frame, nr_mac->UL_tti_req_ahead_size);
nfapi_nr_ul_tti_request_t *future_ul_tti_req = &nr_mac->UL_tti_req_ahead[CC_id][buffer_index];
AssertFatal(future_ul_tti_req->SFN == sched_frame
&& future_ul_tti_req->Slot == sched_slot,
"future UL_tti_req's frame.slot %d.%d does not match PUSCH %d.%d\n",
future_ul_tti_req->SFN,
future_ul_tti_req->Slot,
sched_frame,
sched_slot);
AssertFatal(future_ul_tti_req->n_pdus <
sizeof(future_ul_tti_req->pdus_list) / sizeof(future_ul_tti_req->pdus_list[0]),
"Invalid future_ul_tti_req->n_pdus %d\n", future_ul_tti_req->n_pdus);
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
nfapi_nr_pusch_pdu_t *pusch_pdu = prepare_pusch_pdu(future_ul_tti_req,
UE,
scc,
&sched_pusch,
get_transformPrecoding(ul_bwp, NR_UL_DCI_FORMAT_0_0, 0),
0,
ra->msg3_round,
ul_bwp->pusch_Config && ul_bwp->pusch_Config->frequencyHopping,
UE->rnti,
nr_mac->beam_info.beam_mode);
future_ul_tti_req->n_pdus += 1;
// generation of DCI 0_0 to schedule msg3 retransmission
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][coresetid];
if (!pdcch_pdu_rel15) {
nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu = &ul_dci_req->ul_dci_pdu_list[ul_dci_req->numPdus];
memset(ul_dci_request_pdu, 0, sizeof(nfapi_nr_ul_dci_request_pdus_t));
ul_dci_request_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15;
ul_dci_req->numPdus += 1;
nr_configure_pdcch(pdcch_pdu_rel15, coreset, &UE->UE_sched_ctrl.sched_pdcch);
nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15;
}
int aggregation_level;
int CCEIndex = get_cce_index(nr_mac,
CC_id, slot, 0,
&aggregation_level,
beam_dci.idx,
ss,
coreset,
&UE->UE_sched_ctrl.sched_pdcch,
0);
if (CCEIndex < 0) {
LOG_E(NR_MAC, "UE %04x cannot find free CCE!\n", UE->rnti);
reset_beam_status(&nr_mac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_frame, beam_ul.new_beam);
reset_beam_status(&nr_mac->beam_info, frame, slot, UE->UE_beam_index, slots_frame, beam_dci.new_beam);
return;
}
// Fill PDCCH DL DCI PDU
const uint16_t fapi_beam = convert_to_fapi_beam(UE->UE_beam_index, nr_mac->beam_info.beam_mode);
nfapi_nr_dl_dci_pdu_t *dci_pdu =
prepare_dci_pdu(pdcch_pdu_rel15, scc, ss, coreset, aggregation_level, CCEIndex, fapi_beam, UE->rnti);
pdcch_pdu_rel15->numDlDci++;
dci_pdu_rel15_t uldci_payload = {0};
config_uldci(sc_info,
pusch_pdu,
&uldci_payload,
NULL,
NULL,
ra->Msg3_tda_id,
ra->msg3_TPC,
1, // Not toggling NDI in msg3 retransmissions
ul_bwp,
ss->searchSpaceType->present);
// Reset TPC to 0 dB to not request new gain multiple times before computing new value for SNR
ra->msg3_TPC = 1;
fill_dci_pdu_rel15(sc_info,
&UE->current_DL_BWP,
ul_bwp,
dci_pdu,
&uldci_payload,
NR_UL_DCI_FORMAT_0_0,
TYPE_TC_RNTI_,
ss,
coreset,
0, // parameter not needed for DCI 0_0
nr_mac->cset0_bwp_size);
// Mark the corresponding RBs as used
fill_pdcch_vrb_map(nr_mac,
CC_id,
&UE->UE_sched_ctrl.sched_pdcch,
CCEIndex,
aggregation_level,
beam_dci.idx);
for (int rb = 0; rb < ra->msg3_nb_rb; rb++) {
vrb_map_UL[rbStart + sched_pusch.bwp_info.bwpStart + rb] |= SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols);
}
// Restart RA contention resolution timer in Msg3 retransmission slot (current slot + K2)
// 3GPP TS 38.321 Section 5.1.5 Contention Resolution
start_ra_contention_resolution_timer(
ra,
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ra_ContentionResolutionTimer,
K2,
ul_bwp->scs);
// reset state to wait msg3
ra->ra_state = nrRA_WAIT_Msg3;
ra->Msg3_frame = sched_frame;
ra->Msg3_slot = sched_slot;
}
static bool get_feasible_msg3_tda(const NR_ServingCellConfigCommon_t *scc,
@@ -1517,7 +1521,7 @@ static void nr_generate_Msg2(module_id_t module_idP,
return;
}
uint8_t aggregation_level;
int aggregation_level;
int CCEIndex = get_cce_index(nr_mac, CC_id, slotP, 0, &aggregation_level, beam.idx, ss, coreset, &sched_ctrl->sched_pdcch, 0);
if (CCEIndex < 0) {
@@ -1716,7 +1720,7 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
return;
// get CCEindex, needed also for PUCCH and then later for PDCCH
uint8_t aggregation_level;
int aggregation_level;
int CCEIndex = get_cce_index(nr_mac,
CC_id, slotP, 0,
&aggregation_level,
+162 -157
View File
@@ -85,7 +85,7 @@ static void schedule_ssb(frame_t frame,
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = beam_index;
dl_req->nPDUs++;
LOG_D(MAC,"Scheduling ssb %d at frame %d and slot %d\n", i_ssb, frame, slot);
LOG_D(NR_MAC,"Scheduling ssb %d at frame %d and slot %d\n", i_ssb, frame, slot);
}
static void fill_ssb_vrb_map(NR_COMMON_channels_t *cc,
@@ -114,56 +114,46 @@ static int encode_mib(NR_BCCH_BCH_Message_t *mib, frame_t frame, uint8_t *buffer
return encode_size;
}
static void schedule_one_ssb(gNB_MAC_INST *gNB,
nfapi_nr_dl_tti_request_body_t *dl_req,
const long band,
const NR_SubcarrierSpacing_t scs,
const int i_ssb,
const int rel_slot,
const frame_t frameP,
const slot_t slotP,
const int CC_id,
const uint8_t ssb_frame_periodicity,
const frequency_range_t FR)
int get_max_ssbs(const NR_ServingCellConfigCommon_t *scc)
{
// if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters
const int slots_per_frame = gNB->frame_structure.numb_slots_frame;
const uint16_t offset_pointa = gNB->ssb_OffsetPointA;
NR_COMMON_channels_t *cc = &gNB->common_channels[CC_id];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
const NR_MIB_t *mib = cc->mib->message.choice.mib;
uint32_t mib_pdu = (*(uint32_t *)cc->MIB_pdu) & ((1 << 24) - 1);
uint8_t ssbSubcarrierOffset = gNB->ssb_SubcarrierOffset;
uint16_t ssb_start_symbol = get_ssb_start_symbol(band, scs, i_ssb);
NR_beam_alloc_t beam =
beam_allocation_procedure(&gNB->beam_info, frameP, slotP, get_beam_from_ssbidx(gNB, i_ssb), slots_per_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate SSB %d in any available beam\n", i_ssb);
const uint16_t beam_index =
convert_to_fapi_beam(get_allocated_beam(&gNB->beam_info, frameP, slotP, slots_per_frame, beam.idx), gNB->beam_info.beam_mode);
const int prb_offset = (FR == FR2) ? offset_pointa >> (scs - 2) : offset_pointa >> scs;
schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, beam_index, ssbSubcarrierOffset, offset_pointa, mib_pdu);
fill_ssb_vrb_map(cc,
prb_offset,
(FR == FR2) ? ssbSubcarrierOffset >> (scs - 2) : ssbSubcarrierOffset,
ssb_start_symbol,
CC_id,
beam.idx);
if (IS_SA_MODE(get_softmodem_params())) {
get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb],
frameP,
mib,
slots_per_frame,
ssbSubcarrierOffset,
ssb_start_symbol,
scs,
FR,
band,
i_ssb,
ssb_frame_periodicity,
prb_offset);
gNB->type0_PDCCH_CSS_config[i_ssb].active = true;
int L_max = 0;
switch (scc->ssb_PositionsInBurst->present) {
case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_shortBitmap:
L_max = 4;
break;
case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap:
L_max = 8;
break;
case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_longBitmap:
L_max = 64;
break;
default:
AssertFatal(false, "Invalid SSB configuration\n");
}
return L_max;
}
bool is_ssb_configured(const NR_ServingCellConfigCommon_t *scc, int ssb_index)
{
const BIT_STRING_t *shortBitmap = &scc->ssb_PositionsInBurst->choice.shortBitmap;
const BIT_STRING_t *mediumBitmap = &scc->ssb_PositionsInBurst->choice.mediumBitmap;
const BIT_STRING_t *longBitmap = &scc->ssb_PositionsInBurst->choice.longBitmap;
int pos = 0;
switch (scc->ssb_PositionsInBurst->present) {
case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_shortBitmap:
pos = shortBitmap->buf[0] >> (7 - ssb_index);
break;
case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap:
pos = mediumBitmap->buf[0] >> (7 - ssb_index);
break;
case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_longBitmap:
pos = longBitmap->buf[ssb_index / 8] >> (7 - (ssb_index % 8));
break;
default:
AssertFatal(false, "Invalid SSB configuration\n");
}
return pos & 0x01;
}
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, slot_t slotP, nfapi_nr_dl_tti_request_t *DL_req)
@@ -174,6 +164,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, slot_t slotP, nfapi
for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
NR_COMMON_channels_t *cc = &gNB->common_channels[CC_id];
const NR_MIB_t *mib = cc->mib->message.choice.mib;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
const int slots_per_frame = gNB->frame_structure.numb_slots_frame;
dl_req = &DL_req->dl_tti_request_body;
@@ -194,6 +185,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, slot_t slotP, nfapi
mib_sdu_length);
}
uint32_t mib_pdu = (*(uint32_t *)cc->MIB_pdu) & ((1 << 24) - 1);
int8_t ssb_period = *scc->ssb_periodicityServingCell;
uint8_t ssb_frame_periodicity = 1; // every how many frames SSB are generated
@@ -211,45 +203,45 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, slot_t slotP, nfapi
NR_SubcarrierSpacing_t scs = *scc->ssbSubcarrierSpacing;
const long band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
const BIT_STRING_t *shortBitmap = &scc->ssb_PositionsInBurst->choice.shortBitmap;
const BIT_STRING_t *mediumBitmap = &scc->ssb_PositionsInBurst->choice.mediumBitmap;
const BIT_STRING_t *longBitmap = &scc->ssb_PositionsInBurst->choice.longBitmap;
switch (scc->ssb_PositionsInBurst->present) {
case 1:
// short bitmap (<3GHz) max 4 SSBs
for (int i_ssb = 0; i_ssb < 4; i_ssb++) {
if ((shortBitmap->buf[0] >> (7 - i_ssb)) & 0x01) {
uint16_t ssb_start_symbol = get_ssb_start_symbol(band, scs, i_ssb);
if ((ssb_start_symbol / 14) == rel_slot)
schedule_one_ssb(gNB, dl_req, band, scs, i_ssb, rel_slot, frameP, slotP, CC_id, ssb_frame_periodicity, FR1);
const int bw = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
const uint16_t offset_pointa = gNB->ssb_OffsetPointA;
uint8_t ssbSubcarrierOffset = gNB->ssb_SubcarrierOffset;
const int L_max = get_max_ssbs(scc);
const frequency_range_t frequency_range = scc->ssb_PositionsInBurst->present == 3 ? FR2 : FR1;
const int prb_offset = frequency_range == FR1 ? offset_pointa >> scs : offset_pointa >> (scs - 2);
for (int i_ssb = 0; i_ssb < L_max; i_ssb++) {
if (is_ssb_configured(scc, i_ssb)) {
uint16_t ssb_start_symbol = get_ssb_start_symbol(band, scs, i_ssb);
// if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters
if ((ssb_start_symbol / 14) == rel_slot) {
NR_beam_alloc_t beam = beam_allocation_procedure(&gNB->beam_info,
frameP,
slotP,
get_beam_from_ssbidx(gNB, i_ssb),
slots_per_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate SSB %d in any available beam\n", i_ssb);
const uint16_t alloc_beam_idx = get_allocated_beam(&gNB->beam_info, frameP, slotP, slots_per_frame, beam.idx);
const uint16_t fapi_beam = convert_to_fapi_beam(alloc_beam_idx, gNB->beam_info.beam_mode);
schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, fapi_beam, ssbSubcarrierOffset, offset_pointa, mib_pdu);
fill_ssb_vrb_map(cc, prb_offset, ssbSubcarrierOffset, ssb_start_symbol, CC_id, beam.idx);
if (IS_SA_MODE(get_softmodem_params())) {
get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb],
frameP,
mib,
slots_per_frame,
ssbSubcarrierOffset,
ssb_start_symbol,
scs,
frequency_range,
band,
bw,
i_ssb,
ssb_frame_periodicity,
prb_offset);
gNB->type0_PDCCH_CSS_config[i_ssb].active = true;
}
}
break;
case 2:
// medium bitmap (<6GHz) max 8 SSBs
for (int i_ssb = 0; i_ssb < 8; i_ssb++) {
if ((mediumBitmap->buf[0] >> (7 - i_ssb)) & 0x01) {
uint16_t ssb_start_symbol = get_ssb_start_symbol(band, scs, i_ssb);
if ((ssb_start_symbol / 14) == rel_slot)
schedule_one_ssb(gNB, dl_req, band, scs, i_ssb, rel_slot, frameP, slotP, CC_id, ssb_frame_periodicity, FR1);
}
}
break;
case 3:
// long bitmap FR2 max 64 SSBs
for (int i_ssb = 0; i_ssb < 64; i_ssb++) {
if ((longBitmap->buf[i_ssb / 8] >> (7 - (i_ssb % 8))) & 0x01) {
uint16_t ssb_start_symbol = get_ssb_start_symbol(band, scs, i_ssb);
if ((ssb_start_symbol / 14) == rel_slot)
schedule_one_ssb(gNB, dl_req, band, scs, i_ssb, rel_slot, frameP, slotP, CC_id, ssb_frame_periodicity, FR2);
}
}
break;
default:
AssertFatal(0,"SSB bitmap size value %d undefined (allowed values 1,2,3)\n",
scc->ssb_PositionsInBurst->present);
}
}
}
}
@@ -319,62 +311,37 @@ static bool update_rb_mcs_tbs(NR_sched_pdsch_t *pdsch, uint32_t num_total_bytes,
return true;
}
static NR_sched_pdsch_t schedule_control_sib1(gNB_MAC_INST *gNB_mac,
int CC_id,
NR_sched_pdcch_t *pdcch,
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
int time_domain_allocation,
NR_pdsch_dmrs_t *dmrs_parms,
NR_tda_info_t *tda_info,
uint8_t candidate_idx,
int beam,
uint16_t num_total_bytes)
static NR_sched_pdsch_t allocate_sib1(gNB_MAC_INST *gNB_mac,
int CC_id,
NR_sched_pdcch_t *pdcch,
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
int aggregation_level,
int cce_index,
int time_domain_allocation,
NR_tda_info_t *tda_info,
int beam,
uint16_t num_total_bytes)
{
AssertFatal(gNB_mac->sched_ctrlCommon, "sched_ctrlCommon is NULL\n");
NR_COMMON_channels_t *cc = &gNB_mac->common_channels[CC_id];
uint16_t *vrb_map = cc->vrb_map[beam];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
NR_pdsch_dmrs_t dmrs_parms = get_dl_dmrs_params(scc, NULL, tda_info, 1);
NR_sched_pdsch_t pdsch = {
.bwp_info = get_pdsch_bwp_start_size(gNB_mac, NULL),
.time_domain_allocation = time_domain_allocation,
.dmrs_parms = *dmrs_parms,
.dmrs_parms = dmrs_parms,
.tda_info = *tda_info,
.nrOfLayers = 1,
.pm_index = 0,
.mcs = 0, // starting from mcs 0
};
gNB_mac->sched_ctrlCommon->num_total_bytes = num_total_bytes;
uint8_t nr_of_candidates = 0;
for (int i = 0; i < 3; i++) {
find_aggregation_candidates(&gNB_mac->sched_ctrlCommon->aggregation_level, &nr_of_candidates, gNB_mac->sched_ctrlCommon->search_space,4<<i);
if (nr_of_candidates > 0)
break; // choosing the lower value of aggregation level available
}
AssertFatal(nr_of_candidates > 0, "nr_of_candidates is 0\n");
gNB_mac->sched_ctrlCommon->cce_index = find_pdcch_candidate(gNB_mac,
CC_id,
gNB_mac->sched_ctrlCommon->aggregation_level,
nr_of_candidates,
beam,
pdcch,
gNB_mac->sched_ctrlCommon->coreset,
0);
AssertFatal(gNB_mac->sched_ctrlCommon->cce_index >= 0, "Could not find CCE for coreset0\n");
bool success = update_rb_mcs_tbs(&pdsch, gNB_mac->sched_ctrlCommon->num_total_bytes, vrb_map);
uint16_t *vrb_map = cc->vrb_map[beam];
bool success = update_rb_mcs_tbs(&pdsch, num_total_bytes, vrb_map);
if (success) {
// Mark the corresponding RBs as used
fill_pdcch_vrb_map(gNB_mac,
CC_id,
pdcch,
gNB_mac->sched_ctrlCommon->cce_index,
gNB_mac->sched_ctrlCommon->aggregation_level,
beam);
for (int rb = 0; rb < pdsch.rbSize; rb++) {
fill_pdcch_vrb_map(gNB_mac, CC_id, pdcch, cce_index, aggregation_level, beam);
for (int rb = 0; rb < pdsch.rbSize; rb++)
vrb_map[rb + type0_PDCCH_CSS_config->cset_start_rb] |= SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols);
}
} else {
pdsch.tb_size = 0; // to signal we couldn't allocate TBS
pdsch.time_domain_allocation = -1;
@@ -477,10 +444,11 @@ static void nr_fill_nfapi_dl_SIB_pdu(gNB_MAC_INST *gNB_mac,
static bool check_sib1_tda(gNB_MAC_INST *gNB_mac,
NR_sched_pdcch_t *sched_pdcch,
NR_beam_alloc_t *beam,
int aggregation_level,
int cce_index,
int tda,
int ssb_index,
int CC_id,
int candidate_idx)
int CC_id)
{
NR_COMMON_channels_t *cc = &gNB_mac->common_channels[CC_id];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
@@ -501,18 +469,17 @@ static bool check_sib1_tda(gNB_MAC_INST *gNB_mac,
if (tda_info.startSymbolIndex < type0_PDCCH_CSS_config->first_symbol_index + type0_PDCCH_CSS_config->num_symbols)
return false;
NR_pdsch_dmrs_t dmrs_parms = get_dl_dmrs_params(scc, NULL, &tda_info, 1);
// Configure sched_ctrlCommon for SIB1
gNB_mac->sib1_pdsch[ssb_index] = schedule_control_sib1(gNB_mac,
CC_id,
sched_pdcch,
type0_PDCCH_CSS_config,
tda,
&dmrs_parms,
&tda_info,
candidate_idx,
beam->idx,
cc->sib1_bcch_length);
gNB_mac->sib1_pdsch[ssb_index] = allocate_sib1(gNB_mac,
CC_id,
sched_pdcch,
type0_PDCCH_CSS_config,
aggregation_level,
cce_index,
tda,
&tda_info,
beam->idx,
cc->sib1_bcch_length);
if (gNB_mac->sib1_pdsch[ssb_index].tb_size > 0) {
LOG_D(NR_MAC, "Found TDA for SIB1: %d\n", tda);
return true;
@@ -521,6 +488,19 @@ static bool check_sib1_tda(gNB_MAC_INST *gNB_mac,
}
}
static bool check_frame_sib1(NR_ServingCellConfigCommon_t *scc, NR_Type0_PDCCH_CSS_config_t *type0, int frame)
{
if (type0->type0_pdcch_ss_mux_pattern == 1)
return frame % 2 == type0->sfn_c;
else {
long ssb_period = *scc->ssb_periodicityServingCell;
int ssb_frame_periodicity = 1; // every how many frames SSB are generated
if (ssb_period > 1) // 0 is every half frame
ssb_frame_periodicity = 1 << (ssb_period -1);
return frame % ssb_frame_periodicity == 0;
}
}
void schedule_nr_sib1(module_id_t module_idP,
frame_t frameP,
slot_t slotP,
@@ -530,7 +510,6 @@ void schedule_nr_sib1(module_id_t module_idP,
/* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
// TODO: Get these values from RRC
const int CC_id = 0;
uint8_t candidate_idx = 0;
gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &gNB_mac->common_channels[CC_id];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
@@ -553,13 +532,14 @@ void schedule_nr_sib1(module_id_t module_idP,
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &gNB_mac->type0_PDCCH_CSS_config[i];
if((frameP % 2 == type0_PDCCH_CSS_config->sfn_c) &&
(slotP == type0_PDCCH_CSS_config->n_0) &&
if(check_frame_sib1(scc, type0_PDCCH_CSS_config, frameP) &&
(slotP == type0_PDCCH_CSS_config->slot) &&
(type0_PDCCH_CSS_config->num_rbs > 0) &&
(type0_PDCCH_CSS_config->active == true)) {
AssertFatal(is_dl_slot(slotP, &gNB_mac->frame_structure),
"Trying to schedule SIB1 in slot %d which is not DL. Check searchSpaceZero configuration.\n",
"Trying to schedule SIB1 for SSB %d in slot %d which is not DL. Check searchSpaceZero configuration.\n",
type0_PDCCH_CSS_config->ssb_index,
slotP);
const int n_slots_frame = gNB_mac->frame_structure.numb_slots_frame;
int beam_index = get_beam_from_ssbidx(gNB_mac, i);
@@ -567,16 +547,35 @@ void schedule_nr_sib1(module_id_t module_idP,
AssertFatal(beam.idx >= 0, "Cannot allocate SIB1 corresponding to SSB %d in any available beam\n", i);
LOG_D(NR_MAC,"(%d.%d) SIB1 transmission: ssb_index %d\n", frameP, slotP, type0_PDCCH_CSS_config->ssb_index);
NR_sched_pdcch_t sched_pdcch = set_pdcch_structure(NULL,
gNB_mac->sched_ctrlCommon->search_space,
gNB_mac->sched_ctrlCommon->coreset,
&gNB_mac->sched_ctrlSIB1->search_space[i],
&gNB_mac->sched_ctrlSIB1->coreset,
scc,
NULL,
type0_PDCCH_CSS_config);
int nr_of_candidates, aggregation_level;
for (int c = 0; c < 3; c++) {
find_aggregation_candidates(&aggregation_level,
&nr_of_candidates,
&gNB_mac->sched_ctrlSIB1->search_space[i],
4 << c);
if (nr_of_candidates > 0)
break; // choosing the lower value of aggregation level available
}
AssertFatal(nr_of_candidates > 0, "nr_of_candidates is 0\n");
int cce_index = find_pdcch_candidate(gNB_mac,
CC_id,
aggregation_level,
nr_of_candidates,
beam.idx,
&sched_pdcch,
&gNB_mac->sched_ctrlSIB1->coreset,
0);
bool res = false;
if (gNB_mac->sib1_pdsch[i].time_domain_allocation < 0) {
for (int t = 0; t < 16; t++) {
if (check_sib1_tda(gNB_mac, &sched_pdcch, &beam, t, i, CC_id, candidate_idx)) {
if (check_sib1_tda(gNB_mac, &sched_pdcch, &beam, aggregation_level, cce_index, t, i, CC_id)) {
res = true;
break;
}
@@ -584,7 +583,14 @@ void schedule_nr_sib1(module_id_t module_idP,
}
AssertFatal(gNB_mac->sib1_pdsch[i].time_domain_allocation >= 0, "Couldn't select any TDA for SIB1\n");
if (!res)
res = check_sib1_tda(gNB_mac, &sched_pdcch, &beam, gNB_mac->sib1_pdsch[i].time_domain_allocation, i, CC_id, candidate_idx);
res = check_sib1_tda(gNB_mac,
&sched_pdcch,
&beam,
aggregation_level,
cce_index,
gNB_mac->sib1_pdsch[i].time_domain_allocation,
i,
CC_id);
int tb_size = gNB_mac->sib1_pdsch[i].tb_size;
AssertFatal(res && tb_size > 0, "Couldn't allocate TB for SIB1 for an already allocated TDA\n");
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
@@ -592,10 +598,10 @@ void schedule_nr_sib1(module_id_t module_idP,
nr_fill_nfapi_dl_SIB_pdu(gNB_mac,
&gNB_mac->sib1_pdsch[i],
&sched_pdcch,
gNB_mac->sched_ctrlCommon->search_space,
gNB_mac->sched_ctrlCommon->coreset,
gNB_mac->sched_ctrlCommon->aggregation_level,
gNB_mac->sched_ctrlCommon->cce_index,
&gNB_mac->sched_ctrlSIB1->search_space[i],
&gNB_mac->sched_ctrlSIB1->coreset,
aggregation_level,
cce_index,
dl_req,
pdu_index,
type0_PDCCH_CSS_config,
@@ -667,7 +673,6 @@ static void other_sib_sched_control(module_id_t module_idP,
NR_COMMON_channels_t *cc = &gNB_mac->common_channels[0];
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &gNB_mac->type0_PDCCH_CSS_config[cc->ssb_index[beam_index]];
AssertFatal(gNB_mac->sched_ctrlCommon, "sched_ctrlCommon is NULL\n");
NR_PDSCH_ConfigCommon_t *pdsch_ConfigCommon = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup;
int time_domain_allocation = 1;
NR_tda_info_t tda_info = set_tda_info_from_list(pdsch_ConfigCommon->pdsch_TimeDomainAllocationList, time_domain_allocation);
@@ -675,8 +680,8 @@ static void other_sib_sched_control(module_id_t module_idP,
NR_pdsch_dmrs_t dmrs_parms = get_dl_dmrs_params(scc, NULL, &tda_info, 1);
uint8_t aggregation_level = 0;
uint8_t nr_of_candidates = 0;
int aggregation_level = 0;
int nr_of_candidates = 0;
for (int i = 0; i < 5; i++) {
find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss, 16 >> i);
if (nr_of_candidates > 0)
@@ -397,7 +397,7 @@ NR_ControlResourceSet_t *get_coreset(gNB_MAC_INST *nrmac,
NR_ControlResourceSetId_t coreset_id)
{
if (coreset_id == 0) {
return nrmac->sched_ctrlCommon->coreset; // this is coreset 0
return &nrmac->sched_ctrlSIB1->coreset; // this is coreset 0
}
if (bwp_dedicated) {
const int n = bwp_dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count;
@@ -513,7 +513,7 @@ NR_sched_pdcch_t set_pdcch_structure(gNB_MAC_INST *gNB_mac,
for (int i = 0; i < sps; i++) {
if ((monitoringSymbolsWithinSlot >> (sps - 1 - i)) & 1) {
pdcch.StartSymbolIndex = ss->searchSpaceId == 0 ? i + type0_PDCCH_CSS_config->first_symbol_index : i;
pdcch.StartSymbolIndex = i;
break;
}
}
@@ -592,7 +592,7 @@ int get_cce_index(const gNB_MAC_INST *nrmac,
const int CC_id,
const int slot,
const rnti_t rnti,
uint8_t *aggregation_level,
int *aggregation_level,
int beam_idx,
const NR_SearchSpace_t *ss,
const NR_ControlResourceSet_t *coreset,
@@ -600,11 +600,9 @@ int get_cce_index(const gNB_MAC_INST *nrmac,
float pdcch_cl_adjust)
{
const uint32_t Y = get_Y(ss, slot, rnti);
uint8_t nr_of_candidates;
int agg_level_search_order[NUM_PDCCH_AGG_LEVELS];
determine_aggregation_level_search_order(agg_level_search_order, pdcch_cl_adjust);
int nr_of_candidates;
for (int i = 0; i < NUM_PDCCH_AGG_LEVELS; i++) {
find_aggregation_candidates(aggregation_level, &nr_of_candidates, ss, 1 << agg_level_search_order[i]);
if (nr_of_candidates > 0)
@@ -1150,8 +1150,8 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac,
const int minfbtime = mac->radio_config.minRXTXTIME + NTN_gNB_Koffset;
const NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
const int n_slots_frame = mac->frame_structure.numb_slots_frame;
const frame_structure_t *fs = &mac->frame_structure;
const int n_slots_frame = fs->numb_slots_frame;
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_PUCCH_Config_t *pucch_Config = ul_bwp->pucch_Config;
@@ -1173,9 +1173,12 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac,
const int pucch_slot = (slot + pdsch_to_harq_feedback[f] + NTN_gNB_Koffset) % n_slots_frame;
// check if the slot is UL
if (fs->frame_type == TDD) {
int mod_slot = pucch_slot % fs->numb_slots_period;
int mod_slot = get_slot_idx_in_period(pucch_slot, fs);
if (!is_ul_slot(mod_slot, fs))
continue;
const tdd_period_config_t *pc = &fs->period_cfg;
if (r_pucch >= 0 && is_mixed_slot(mod_slot, fs) && pc->tdd_slot_bitmap[mod_slot].num_ul_symbols < 2)
continue;
}
const int pucch_frame = (frame + ((slot + pdsch_to_harq_feedback[f] + NTN_gNB_Koffset) / n_slots_frame)) % MAX_FRAME_NUMBER;
// we store PUCCH resources according to slot, TDD configuration and size of the vector containing PUCCH structures
@@ -46,13 +46,7 @@ int get_num_ul_tda(gNB_MAC_INST *nrmac, int slot, int k2, const NR_tda_info_t **
/* we assume that this function is mutex-protected from outside */
NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
const frame_structure_t *fs = &nrmac->frame_structure;
const int slot_period = slot % fs->numb_slots_period;
const tdd_bitmap_t *bm = &fs->period_cfg.tdd_slot_bitmap[slot_period];
/* For some reason, we only store the number of symbols if it's mixed */
const int num_ul_symbols = bm->slot_type == TDD_NR_MIXED_SLOT ? bm->num_ul_symbols : 14;
const uint16_t ul_bitmap = SL_to_bitmap(14 - num_ul_symbols, num_ul_symbols);
const uint16_t ul_bitmap = get_ul_bitmap(&nrmac->frame_structure, slot);
*first_idx = NULL;
FOR_EACH_SEQ_ARR(NR_tda_info_t *, tda, &nrmac->ul_tda) {
DevAssert(tda->valid_tda);
+3 -3
View File
@@ -39,7 +39,8 @@
void set_cset_offset(uint16_t);
void get_K1_K2(int N1, int N2, int *K1, int *K2, int layers);
int get_NTN_Koffset(const NR_ServingCellConfigCommon_t *scc);
bool is_ssb_configured(const NR_ServingCellConfigCommon_t *scc, int ssb_index);
int get_max_ssbs(const NR_ServingCellConfigCommon_t *scc);
int get_first_ul_slot(const frame_structure_t *fs, bool mixed);
int get_ul_slots_per_period(const frame_structure_t *fs);
int get_ul_slots_per_frame(const frame_structure_t *fs);
@@ -47,7 +48,6 @@ int get_dl_slots_per_period(const frame_structure_t *fs);
int get_full_ul_slots_per_period(const frame_structure_t *fs);
int get_full_dl_slots_per_period(const frame_structure_t *fs);
int get_ul_slot_offset(const frame_structure_t *fs, int idx, bool count_mixed);
void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_allocator_t *uia);
void mac_top_init_gNB(ngran_node_t node_type,
@@ -420,7 +420,7 @@ int get_cce_index(const gNB_MAC_INST *nrmac,
const int CC_id,
const int slot,
const rnti_t rnti,
uint8_t *aggregation_level,
int *aggregation_level,
int beam_idx,
const NR_SearchSpace_t *ss,
const NR_ControlResourceSet_t *coreset,
+8 -3
View File
@@ -620,7 +620,7 @@ typedef struct {
/// CCE index and Aggr. Level are shared for PUSCH/PDSCH allocation decisions
/// corresponding to the sched_pusch/sched_pdsch structures below
int cce_index;
uint8_t aggregation_level;
int aggregation_level;
uint32_t dl_cce_fail, ul_cce_fail;
/// Array of PUCCH scheduling information
@@ -883,6 +883,11 @@ typedef struct dlul_mac_stats {
mac_stats_t ul;
} dlul_mac_stats_t;
typedef struct {
NR_SearchSpace_t search_space[MAX_NUM_OF_SSB];
NR_ControlResourceSet_t coreset;
} NR_sched_ctrl_sib1_t;
/// helper type to encapsulate a frame/slot combination in a single type.
/// Currently only used in the UL preprocessor. Note: if you use this type
/// further, please refactor it into a common type first.
@@ -979,11 +984,11 @@ typedef struct gNB_MAC_INST_s {
nr_mac_config_t radio_config;
nr_rlc_configuration_t rlc_config;
NR_UE_sched_ctrl_t *sched_ctrlCommon;
NR_sched_ctrl_sib1_t *sched_ctrlSIB1;
NR_sched_pdcch_t *sched_pdcch_otherSI;
uint16_t cset0_bwp_start;
uint16_t cset0_bwp_size;
NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config[64];
NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config[MAX_NUM_OF_SSB];
bool first_MIB;
NR_bler_options_t dl_bler;
+45 -14
View File
@@ -273,20 +273,41 @@ NR_SearchSpace_t *rrc_searchspace_config(bool is_common,
return ss;
}
static NR_ControlResourceSet_t *get_coreset_config(int bwp_id, int bwp_start, int bwp_size, uint64_t ssb_bitmap)
static NR_ControlResourceSet_t *get_coreset_config(int bwp_id,
int cset_offset,
int cset_limit,
int bwp_start,
int bwp_size,
uint64_t ssb_bitmap)
{
NR_ControlResourceSet_t *coreset = calloc(1, sizeof(*coreset));
AssertFatal(coreset != NULL, "out of memory\n");
// frequency domain resources depending on BWP size
int additional_offset = (bwp_start + 5) / 6 * 6 - bwp_start;
int cset_shift = 0;
if (cset_offset > additional_offset) {
cset_shift = cset_offset / 6 + (cset_offset % 6 > 0);
additional_offset += cset_shift * 6;
}
int eff_bwp_size = bwp_size - additional_offset;
if (cset_limit && eff_bwp_size > cset_limit)
eff_bwp_size = cset_limit;
AssertFatal(eff_bwp_size >= 24, "CORESET effective BWP size %d is less than 24 PRB, can't allocate\n", eff_bwp_size);
coreset->frequencyDomainResources.buf = calloc(1,6);
coreset->frequencyDomainResources.buf[0] = (eff_bwp_size < 48) ? 0xf0 : 0xff;
coreset->frequencyDomainResources.buf[1] = (eff_bwp_size < 96) ? 0x00 : 0xff;
coreset->frequencyDomainResources.buf[2] = (eff_bwp_size < 144) ? 0x00 : 0xff;
coreset->frequencyDomainResources.buf[3] = (eff_bwp_size < 192) ? 0x00 : 0xff;
coreset->frequencyDomainResources.buf[4] = (eff_bwp_size < 240) ? 0x00 : 0xff;
coreset->frequencyDomainResources.buf[5] = 0x00;
uint64_t buf = 0;
if (eff_bwp_size < 48)
buf = 0xf;
else {
for (int i = 0; i < eff_bwp_size / 48; i++) {
buf <<= 8;
buf += 0xff;
}
}
buf <<= cset_shift;
for (int b = 0; b < 6; b++) {
uint8_t temp_buf = (buf >> (8 * b)) & 0xff;
reverse_bits_u8(&temp_buf, 1, &coreset->frequencyDomainResources.buf[b]);
}
coreset->frequencyDomainResources.size = 6;
coreset->frequencyDomainResources.bits_unused = 3;
coreset->duration = (eff_bwp_size < 48) ? 2 : 1;
@@ -1001,8 +1022,8 @@ void prepare_sim_uecap(NR_UE_NR_Capability_t *cap,
void nr_rrc_config_dl_tda(struct NR_PDSCH_TimeDomainResourceAllocationList *pdsch_TimeDomainAllocationList,
frame_type_t frame_type,
NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon,
int curr_bwp) {
int curr_bwp)
{
// coreset duration setting to be improved in the framework of RRC harmonization, potentially using a common function
int len_coreset = 1;
if (curr_bwp < 48)
@@ -1751,7 +1772,7 @@ static NR_BWP_Downlink_t *config_downlinkBWP(const NR_ServingCellConfigCommon_t
int bwp_size = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
int bwp_start = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
uint64_t ssb_bitmap = get_ssb_bitmap(scc);
NR_ControlResourceSet_t *coreset = get_coreset_config(bwp->bwp_Id, bwp_start, bwp_size, ssb_bitmap);
NR_ControlResourceSet_t *coreset = get_coreset_config(bwp->bwp_Id, 0, 0, bwp_start, bwp_size, ssb_bitmap);
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet = coreset;
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceZero=NULL;
@@ -1803,9 +1824,8 @@ static NR_BWP_Downlink_t *config_downlinkBWP(const NR_ServingCellConfigCommon_t
bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList = calloc(1,sizeof(*bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList));
bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList = calloc(1,sizeof(*bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList));
// coreset2 is identical to coreset above, but reallocated to prevent double
// frees
NR_ControlResourceSet_t *coreset2 = get_coreset_config(bwp->bwp_Id, bwp_start, bwp_size, ssb_bitmap);
// coreset2 is identical to coreset above, but reallocated to prevent double frees
NR_ControlResourceSet_t *coreset2 = get_coreset_config(bwp->bwp_Id, 0, 0, bwp_start, bwp_size, 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);
@@ -2710,6 +2730,17 @@ static BIT_STRING_t bit_string_clone(const BIT_STRING_t *orig)
return bs;
}
void configure_coreset_for_mux23(const NR_ServingCellConfigCommon_t *scc, int offset, int limit, int bwp_start, int bwp_size)
{
NR_ControlResourceSet_t *coreset = get_coreset_config(5, offset, limit, bwp_start, bwp_size, get_ssb_bitmap(scc));
NR_PDCCH_ConfigCommon_t *pdcch_common = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup;
pdcch_common->commonControlResourceSet = coreset;
for (int i = 0; i < pdcch_common->commonSearchSpaceList->list.count; i++) {
*pdcch_common->commonSearchSpaceList->list.array[i]->controlResourceSetId = coreset->controlResourceSetId;
}
}
NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc,
const plmn_id_t *plmn,
uint64_t cellID,
@@ -3336,7 +3367,7 @@ static NR_BWP_DownlinkDedicated_t *configure_initial_dl_bwp(const NR_ServingCell
NR_BWP_t *genericParameters = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
int bwp_size = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
int bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
NR_ControlResourceSet_t *coreset = get_coreset_config(0, bwp_start, bwp_size, bitmap);
NR_ControlResourceSet_t *coreset = get_coreset_config(0, 0, 0, bwp_start, bwp_size, bitmap);
asn1cSeqAdd(&pdcch_Config->controlResourceSetToAddModList->list, coreset);
int css_num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS];
+1 -1
View File
@@ -68,7 +68,7 @@ NR_BCCH_BCH_Message_t *get_new_MIB_NR(const NR_ServingCellConfigCommon_t *scc);
void free_MIB_NR(NR_BCCH_BCH_Message_t *mib);
int encode_MIB_NR(NR_BCCH_BCH_Message_t *mib, int frame, uint8_t *buf, int buf_size);
int encode_MIB_NR_setup(NR_MIB_t *mib, int frame, uint8_t *buf, int buf_size);
void configure_coreset_for_mux23(const NR_ServingCellConfigCommon_t *scc, int offset, int limit, int bwp_start, int bwp_size);
struct NR_MeasurementTimingConfiguration;
struct NR_MeasurementTimingConfiguration *get_new_MeasurementTimingConfiguration(const NR_ServingCellConfigCommon_t *scc);
int encode_MeasurementTimingConfiguration(const struct NR_MeasurementTimingConfiguration *mtc, uint8_t *buf, int buf_len);
+8 -3
View File
@@ -108,18 +108,23 @@ static int handle_bcch_bch(NR_UE_MAC_INST_t *mac,
void *phy_data,
uint8_t *pduP,
unsigned int additional_bits,
uint32_t ssb_index,
uint32_t ssb_index_mod8,
uint32_t ssb_length,
uint16_t ssb_start_subcarrier,
long ssb_arfcn,
uint16_t cell_id)
{
mac->mib_ssb = ssb_index;
mac->mib_ssb = ssb_index_mod8;
mac->physCellId = cell_id;
mac->mib_additional_bits = additional_bits;
mac->ssb_start_subcarrier = ssb_start_subcarrier;
if(ssb_length == 64)
if(ssb_length == 64) {
mac->frequency_range = FR2;
uint8_t ab = additional_bits & 0xff;
uint8_t out;
reverse_bits_u8(&ab, 1, &out);
mac->mib_ssb += (out & 0x7) << 3;
}
else
mac->frequency_range = FR1;
// fixed 3 bytes MIB PDU