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:
+14
-9
@@ -29,40 +29,40 @@ gNBs =
|
||||
# downlinkConfigCommon
|
||||
#frequencyInfoDL
|
||||
# this is pointA + 16 PRBs@120kHz SCS (same as initial BWP)
|
||||
absoluteFrequencySSB = 2071387;
|
||||
dl_frequencyBand = 261;
|
||||
absoluteFrequencySSB = 2078299;
|
||||
dl_frequencyBand = 257;
|
||||
# this is 27.900 GHz
|
||||
dl_absoluteFrequencyPointA = 2071001;
|
||||
dl_absoluteFrequencyPointA = 2077963;
|
||||
#scs-SpecificCarrierList
|
||||
dl_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
dl_subcarrierSpacing = 3;
|
||||
dl_carrierBandwidth = 32;
|
||||
dl_carrierBandwidth = 66;
|
||||
#initialDownlinkBWP
|
||||
#genericParameters
|
||||
# this is RBstart=0,L=32 (275*(L-1))+RBstart
|
||||
initialDLBWPlocationAndBandwidth = 8525;
|
||||
initialDLBWPlocationAndBandwidth = 6349;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialDLBWPsubcarrierSpacing = 3;
|
||||
#pdcch-ConfigCommon
|
||||
initialDLBWPcontrolResourceSetZero = 1;
|
||||
initialDLBWPcontrolResourceSetZero = 4;
|
||||
initialDLBWPsearchSpaceZero = 0;
|
||||
|
||||
#uplinkConfigCommon
|
||||
#frequencyInfoUL
|
||||
ul_frequencyBand = 261;
|
||||
ul_frequencyBand = 257;
|
||||
#scs-SpecificCarrierList
|
||||
ul_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
ul_subcarrierSpacing = 3;
|
||||
ul_carrierBandwidth = 32;
|
||||
ul_carrierBandwidth = 66;
|
||||
pMax = 20;
|
||||
#initialUplinkBWP
|
||||
#genericParameters
|
||||
initialULBWPlocationAndBandwidth = 8525;
|
||||
initialULBWPlocationAndBandwidth = 6349;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialULBWPsubcarrierSpacing = 3;
|
||||
@@ -143,6 +143,11 @@ gNBs =
|
||||
|
||||
);
|
||||
|
||||
first_active_bwp = 1;
|
||||
bwp_list = (
|
||||
{ scs = 3; bwpStart = 0; bwpSize = 66;}
|
||||
);
|
||||
|
||||
# ------- SCTP definitions
|
||||
SCTP :
|
||||
{
|
||||
+4
-4
@@ -21,7 +21,7 @@
|
||||
|
||||
-->
|
||||
<testCaseList>
|
||||
<htmlTabRef>rfsim-fr2-32prb-5gnr-tdd</htmlTabRef>
|
||||
<htmlTabRef>rfsim-fr2-66prb-5gnr-tdd</htmlTabRef>
|
||||
<htmlTabName>Monolithic FR2 gNB</htmlTabName>
|
||||
<htmlTabIcon>wrench</htmlTabIcon>
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
<class>Deploy_Object</class>
|
||||
<desc>Deploy OAI gNB</desc>
|
||||
<node>localhost</node>
|
||||
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_fr2_32prb</yaml_path>
|
||||
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_fr2_66prb</yaml_path>
|
||||
<services>mysql oai-amf oai-smf oai-upf oai-ext-dn</services>
|
||||
</testCase>
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
<class>Deploy_Object</class>
|
||||
<desc>Deploy OAI NR-UE</desc>
|
||||
<node>localhost</node>
|
||||
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_fr2_32prb</yaml_path>
|
||||
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_fr2_66prb</yaml_path>
|
||||
<services>oai-gnb oai-nr-ue</services>
|
||||
</testCase>
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
<always_exec>true</always_exec>
|
||||
<desc>Undeploy all OAI 5G stack</desc>
|
||||
<node>localhost</node>
|
||||
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_fr2_32prb</yaml_path>
|
||||
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_fr2_66prb</yaml_path>
|
||||
<d_retx_th>10,0,0,0</d_retx_th>
|
||||
<u_retx_th>10,0,0,0</u_retx_th>
|
||||
</testCase>
|
||||
+2
-2
@@ -102,7 +102,7 @@ services:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.140
|
||||
volumes:
|
||||
- ../../conf_files/gnb.sa.band261.u3.32prb.rfsim.conf:/opt/oai-gnb/etc/gnb.conf
|
||||
- ../../conf_files/gnb.sa.band257.u3.66prb.rfsim.conf:/opt/oai-gnb/etc/gnb.conf
|
||||
healthcheck:
|
||||
test: /bin/bash -c "pgrep nr-softmodem"
|
||||
start_period: 10s
|
||||
@@ -122,7 +122,7 @@ services:
|
||||
environment:
|
||||
USE_ADDITIONAL_OPTIONS: --rfsim
|
||||
--rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
|
||||
-r 32 --numerology 3 --band 261 -C 27533160000 --ssb 73
|
||||
-C 27975360000 -r 66 --numerology 3 --ssb 48 --band 257
|
||||
ASAN_OPTIONS: detect_leaks=0
|
||||
devices:
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
@@ -345,8 +345,8 @@ static int set_bwconfig(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
ERROR_MSG_RET("unhandled option %s\n", buf);
|
||||
}
|
||||
|
||||
free(RC.nrmac[0]->sched_ctrlCommon);
|
||||
RC.nrmac[0]->sched_ctrlCommon = NULL;
|
||||
free(RC.nrmac[0]->sched_ctrlSIB1);
|
||||
RC.nrmac[0]->sched_ctrlSIB1 = NULL;
|
||||
|
||||
free_MIB_NR(mac->common_channels[0].mib);
|
||||
mac->common_channels[0].mib = get_new_MIB_NR(scc);
|
||||
|
||||
@@ -14,7 +14,7 @@ Analog beamforming implementation also allows to enable distributed antenna syst
|
||||
|
||||
# Configuration file fields for analog beamforming
|
||||
|
||||
A set of parameters in configuration files controls the implementation of analog beamforming and instructs the scheduler on how to behave in such scenarios. Since most notably this technique in 5G is employed in FR2, the configuration file example currently available is a RFsim one for band 261. [Config file example](../ci-scripts/conf_files/gnb.sa.band261.u3.32prb.rfsim.conf)
|
||||
A set of parameters in configuration files controls the implementation of analog beamforming and instructs the scheduler on how to behave in such scenarios. Since most notably this technique in 5G is employed in FR2, the configuration file example currently available is a RFsim one for band 261. [Config file example](../ci-scripts/conf_files/gnb.sa.band257.u3.66prb.rfsim.conf)
|
||||
|
||||
In the `MACRLC` section of configuration files, there are three new parameters: `set_analog_beamforming`, `beam_duration` and `beams_per_period`. The explanation of these parameters is here provided:
|
||||
- `set_analog_beamforming` can be set a value equal to 1 or 2 to activate or 0 to desactivate analog beamforming (default value is 0)
|
||||
|
||||
@@ -828,7 +828,7 @@ void nr_pdcch_channel_estimation(const PHY_VARS_NR_UE *ue,
|
||||
first_carrier_offset, BWPStart, coreset_start_rb, nb_rb_coreset);
|
||||
#endif
|
||||
|
||||
unsigned short coreset_start_subcarrier = first_carrier_offset+(BWPStart + coreset_start_rb)*12;
|
||||
unsigned short coreset_start_subcarrier = (first_carrier_offset + (BWPStart + coreset_start_rb) * 12) % symb_sz;
|
||||
|
||||
#if CH_INTERP
|
||||
int16_t *fl = filt16a_l1;
|
||||
|
||||
@@ -198,16 +198,12 @@ void nr_dlsim_preprocessor(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pp_pdsch)
|
||||
NR_UE_DL_BWP_t *current_BWP = &UE_info->current_DL_BWP;
|
||||
NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels[0].ServingCellConfigCommon;
|
||||
|
||||
uint8_t nr_of_candidates = 0;
|
||||
int nr_of_candidates = 0;
|
||||
if (g_mcsIndex < 4) {
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space,8);
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level, &nr_of_candidates, sched_ctrl->search_space, 8);
|
||||
}
|
||||
if (nr_of_candidates == 0) {
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space,4);
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level, &nr_of_candidates, sched_ctrl->search_space, 4);
|
||||
}
|
||||
uint32_t Y = get_Y(sched_ctrl->search_space, pp_pdsch->slot, UE_info->rnti);
|
||||
int CCEIndex = find_pdcch_candidate(nr_mac,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user