add option to configure max MIMO layers for PDSCH TBSLBRM computation from UE capabilities
This commit is contained in:
@@ -698,9 +698,8 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
validate_input_pmi(&gNB_mac->config[0], pdsch_AntennaPorts, g_nrOfLayers, g_pmi);
|
validate_input_pmi(&gNB_mac->config[0], pdsch_AntennaPorts, g_nrOfLayers, g_pmi);
|
||||||
|
|
||||||
NR_UE_NR_Capability_t* UE_Capability_nr = CALLOC(1,sizeof(NR_UE_NR_Capability_t));
|
NR_UE_NR_Capability_t *UE_Capability_nr = CALLOC(1,sizeof(NR_UE_NR_Capability_t));
|
||||||
prepare_sim_uecap(UE_Capability_nr,scc,mu,
|
prepare_sim_uecap(UE_Capability_nr, scc, mu, N_RB_DL, g_mcsTableIdx, 0);
|
||||||
N_RB_DL,g_mcsTableIdx,0);
|
|
||||||
|
|
||||||
NR_CellGroupConfig_t *secondaryCellGroup = get_default_secondaryCellGroup(scc, scd, UE_Capability_nr, 0, 1, &conf, 0);
|
NR_CellGroupConfig_t *secondaryCellGroup = get_default_secondaryCellGroup(scc, scd, UE_Capability_nr, 0, 1, &conf, 0);
|
||||||
|
|
||||||
@@ -869,7 +868,7 @@ int main(int argc, char **argv)
|
|||||||
//Configure UE
|
//Configure UE
|
||||||
NR_BCCH_BCH_Message_t *mib = get_new_MIB_NR(scc);
|
NR_BCCH_BCH_Message_t *mib = get_new_MIB_NR(scc);
|
||||||
nr_rrc_mac_config_req_mib(0, 0, mib->message.choice.mib, false);
|
nr_rrc_mac_config_req_mib(0, 0, mib->message.choice.mib, false);
|
||||||
nr_rrc_mac_config_req_cg(0, 0, UE_CellGroup);
|
nr_rrc_mac_config_req_cg(0, 0, UE_CellGroup, UE_Capability_nr);
|
||||||
|
|
||||||
asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, UE_CellGroup);
|
asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, UE_CellGroup);
|
||||||
|
|
||||||
|
|||||||
@@ -1928,9 +1928,39 @@ static void configure_BWPs(NR_UE_MAC_INST_t *mac, NR_ServingCellConfig_t *scd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_mac_uecap_info(NR_UE_MAC_INST_t *mac, NR_UE_NR_Capability_t *ue_Capability)
|
||||||
|
{
|
||||||
|
if (ue_Capability->featureSets) {
|
||||||
|
if (ue_Capability->featureSets->featureSetsDownlinkPerCC) {
|
||||||
|
struct NR_FeatureSets__featureSetsDownlinkPerCC *fs_dlcc_list= ue_Capability->featureSets->featureSetsDownlinkPerCC;
|
||||||
|
for (int i = 0; i < fs_dlcc_list->list.count; i++) {
|
||||||
|
NR_FeatureSetDownlinkPerCC_t *fs_dl_cc = fs_dlcc_list->list.array[i];
|
||||||
|
if (mac->current_DL_BWP->scs != fs_dl_cc->supportedSubcarrierSpacingDL)
|
||||||
|
continue;
|
||||||
|
int uecap_bw_index;
|
||||||
|
if (fs_dl_cc->supportedBandwidthDL.present == NR_SupportedBandwidth_PR_fr1) {
|
||||||
|
uecap_bw_index = fs_dl_cc->supportedBandwidthDL.choice.fr1;
|
||||||
|
// 90 MHz option is indicated by a separate pointer in case indicated supported BW is 100MHz
|
||||||
|
// so we need to increase the index by 1 unit to point to 100 MHz if not 90MHz
|
||||||
|
if (uecap_bw_index == NR_SupportedBandwidth__fr1_mhz100 && !fs_dl_cc->channelBW_90mhz)
|
||||||
|
uecap_bw_index++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
uecap_bw_index = fs_dl_cc->supportedBandwidthDL.choice.fr2;
|
||||||
|
int dl_bw_mhz = mac->phy_config.config_req.carrier_config.dl_bandwidth;
|
||||||
|
if (dl_bw_mhz != get_supported_bw_mhz(mac->frequency_range, uecap_bw_index))
|
||||||
|
continue;
|
||||||
|
if (fs_dl_cc->maxNumberMIMO_LayersPDSCH)
|
||||||
|
mac->uecap_maxMIMO_PDSCH_layers = 2 << *fs_dl_cc->maxNumberMIMO_LayersPDSCH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void nr_rrc_mac_config_req_cg(module_id_t module_id,
|
void nr_rrc_mac_config_req_cg(module_id_t module_id,
|
||||||
int cc_idP,
|
int cc_idP,
|
||||||
NR_CellGroupConfig_t *cell_group_config)
|
NR_CellGroupConfig_t *cell_group_config,
|
||||||
|
NR_UE_NR_Capability_t *ue_Capability)
|
||||||
{
|
{
|
||||||
LOG_I(MAC,"Applying CellGroupConfig from gNodeB\n");
|
LOG_I(MAC,"Applying CellGroupConfig from gNodeB\n");
|
||||||
AssertFatal(cell_group_config, "CellGroupConfig should not be NULL\n");
|
AssertFatal(cell_group_config, "CellGroupConfig should not be NULL\n");
|
||||||
@@ -1960,6 +1990,9 @@ void nr_rrc_mac_config_req_cg(module_id_t module_id,
|
|||||||
cell_group_config->rlc_BearerToAddModList,
|
cell_group_config->rlc_BearerToAddModList,
|
||||||
cell_group_config->rlc_BearerToReleaseList);
|
cell_group_config->rlc_BearerToReleaseList);
|
||||||
|
|
||||||
|
if (ue_Capability)
|
||||||
|
handle_mac_uecap_info(mac, ue_Capability);
|
||||||
|
|
||||||
// Setup the SSB to Rach Occasions mapping according to the config
|
// Setup the SSB to Rach Occasions mapping according to the config
|
||||||
// Only if RACH is configured for current BWP
|
// Only if RACH is configured for current BWP
|
||||||
if (mac->current_UL_BWP->rach_ConfigCommon)
|
if (mac->current_UL_BWP->rach_ConfigCommon)
|
||||||
|
|||||||
@@ -474,6 +474,9 @@ typedef struct NR_UE_MAC_INST_s {
|
|||||||
bool harq_ACK_SpatialBundlingPUCCH;
|
bool harq_ACK_SpatialBundlingPUCCH;
|
||||||
bool harq_ACK_SpatialBundlingPUSCH;
|
bool harq_ACK_SpatialBundlingPUSCH;
|
||||||
|
|
||||||
|
uint32_t uecap_maxMIMO_PDSCH_layers;
|
||||||
|
uint32_t uecap_maxMIMO_PUSCH_layers;
|
||||||
|
|
||||||
NR_UL_TIME_ALIGNMENT_t ul_time_alignment;
|
NR_UL_TIME_ALIGNMENT_t ul_time_alignment;
|
||||||
NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon;
|
NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon;
|
||||||
|
|
||||||
|
|||||||
@@ -179,7 +179,8 @@ void nr_release_mac_config_logicalChannelBearer(NR_UE_MAC_INST_t *mac, long chan
|
|||||||
|
|
||||||
void nr_rrc_mac_config_req_cg(module_id_t module_id,
|
void nr_rrc_mac_config_req_cg(module_id_t module_id,
|
||||||
int cc_idP,
|
int cc_idP,
|
||||||
NR_CellGroupConfig_t *cell_group_config);
|
NR_CellGroupConfig_t *cell_group_config,
|
||||||
|
NR_UE_NR_Capability_t *ue_Capability);
|
||||||
|
|
||||||
void nr_rrc_mac_config_req_mib(module_id_t module_id,
|
void nr_rrc_mac_config_req_mib(module_id_t module_id,
|
||||||
int cc_idP,
|
int cc_idP,
|
||||||
|
|||||||
@@ -67,6 +67,8 @@ void nr_ue_init_mac(module_id_t module_idP)
|
|||||||
mac->servCellIndex = 0;
|
mac->servCellIndex = 0;
|
||||||
mac->harq_ACK_SpatialBundlingPUCCH = false;
|
mac->harq_ACK_SpatialBundlingPUCCH = false;
|
||||||
mac->harq_ACK_SpatialBundlingPUSCH = false;
|
mac->harq_ACK_SpatialBundlingPUSCH = false;
|
||||||
|
mac->uecap_maxMIMO_PDSCH_layers = 0;
|
||||||
|
mac->uecap_maxMIMO_PUSCH_layers = 0;
|
||||||
|
|
||||||
memset(&mac->ssb_measurements, 0, sizeof(mac->ssb_measurements));
|
memset(&mac->ssb_measurements, 0, sizeof(mac->ssb_measurements));
|
||||||
memset(&mac->ul_time_alignment, 0, sizeof(mac->ul_time_alignment));
|
memset(&mac->ul_time_alignment, 0, sizeof(mac->ul_time_alignment));
|
||||||
|
|||||||
@@ -1148,8 +1148,13 @@ static int nr_ue_process_dci_dl_11(module_id_t module_id,
|
|||||||
dlsch_pdu->ldpcBaseGraph = get_BG(dlsch_pdu->TBS, dlsch_pdu->targetCodeRate);
|
dlsch_pdu->ldpcBaseGraph = get_BG(dlsch_pdu->TBS, dlsch_pdu->targetCodeRate);
|
||||||
|
|
||||||
// TBS_LBRM according to section 5.4.2.1 of 38.212
|
// TBS_LBRM according to section 5.4.2.1 of 38.212
|
||||||
AssertFatal(sc_info->maxMIMO_Layers_PDSCH != NULL, "Option with max MIMO layers not configured is not supported\n");
|
int max_mimo_layers = 0;
|
||||||
int nl_tbslbrm = *sc_info->maxMIMO_Layers_PDSCH < 4 ? *sc_info->maxMIMO_Layers_PDSCH : 4;
|
if (sc_info->maxMIMO_Layers_PDSCH)
|
||||||
|
max_mimo_layers = *sc_info->maxMIMO_Layers_PDSCH;
|
||||||
|
else
|
||||||
|
max_mimo_layers = mac->uecap_maxMIMO_PDSCH_layers;
|
||||||
|
AssertFatal(max_mimo_layers > 0, "Invalid number of max MIMO layers for PDSCH\n");
|
||||||
|
int nl_tbslbrm = max_mimo_layers < 4 ? max_mimo_layers : 4;
|
||||||
dlsch_pdu->tbslbrm = nr_compute_tbslbrm(dlsch_pdu->mcs_table, sc_info->dl_bw_tbslbrm, nl_tbslbrm);
|
dlsch_pdu->tbslbrm = nr_compute_tbslbrm(dlsch_pdu->mcs_table, sc_info->dl_bw_tbslbrm, nl_tbslbrm);
|
||||||
/*PTRS configuration */
|
/*PTRS configuration */
|
||||||
dlsch_pdu->pduBitmap = 0;
|
dlsch_pdu->pduBitmap = 0;
|
||||||
|
|||||||
+22
-22
@@ -215,8 +215,7 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc,
|
|||||||
nr_rrc_cellgroup_configuration(rrcNB, rrc, cellGroupConfig);
|
nr_rrc_cellgroup_configuration(rrcNB, rrc, cellGroupConfig);
|
||||||
|
|
||||||
AssertFatal(!get_softmodem_params()->sa, "secondaryCellGroup only used in NSA for now\n");
|
AssertFatal(!get_softmodem_params()->sa, "secondaryCellGroup only used in NSA for now\n");
|
||||||
nr_rrc_mac_config_req_cg(rrc->ue_id, 0, cellGroupConfig);
|
nr_rrc_mac_config_req_cg(0, 0, cellGroupConfig, rrc->UECap.UE_NR_Capability);
|
||||||
|
|
||||||
asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, cellGroupConfig);
|
asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, cellGroupConfig);
|
||||||
}
|
}
|
||||||
if (ie->measConfig != NULL) {
|
if (ie->measConfig != NULL) {
|
||||||
@@ -308,7 +307,22 @@ NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int nb_inst)
|
|||||||
rrc->ul_bwp_id = 0;
|
rrc->ul_bwp_id = 0;
|
||||||
rrc->as_security_activated = false;
|
rrc->as_security_activated = false;
|
||||||
rrc->ra_trigger = RA_NOT_RUNNING;
|
rrc->ra_trigger = RA_NOT_RUNNING;
|
||||||
rrc->uecap_file = uecap_file;
|
|
||||||
|
FILE *f = NULL;
|
||||||
|
if (uecap_file)
|
||||||
|
f = fopen(uecap_file, "r");
|
||||||
|
if(f) {
|
||||||
|
char UE_NR_Capability_xer[65536];
|
||||||
|
size_t size = fread(UE_NR_Capability_xer, 1, sizeof UE_NR_Capability_xer, f);
|
||||||
|
if (size == 0 || size == sizeof UE_NR_Capability_xer) {
|
||||||
|
LOG_E(NR_RRC, "UE Capabilities XER file %s is too large (%ld)\n", uecap_file, size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
asn_dec_rval_t dec_rval =
|
||||||
|
xer_decode(0, &asn_DEF_NR_UE_NR_Capability, (void *)&rrc->UECap.UE_NR_Capability, UE_NR_Capability_xer, size);
|
||||||
|
assert(dec_rval.code == RC_OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
memset(&rrc->timers_and_constants, 0, sizeof(rrc->timers_and_constants));
|
memset(&rrc->timers_and_constants, 0, sizeof(rrc->timers_and_constants));
|
||||||
|
|
||||||
@@ -804,8 +818,7 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc,
|
|||||||
nr_rrc_cellgroup_configuration(rrcNB, rrc, cellGroupConfig);
|
nr_rrc_cellgroup_configuration(rrcNB, rrc, cellGroupConfig);
|
||||||
|
|
||||||
LOG_D(RRC,"Sending CellGroupConfig to MAC\n");
|
LOG_D(RRC,"Sending CellGroupConfig to MAC\n");
|
||||||
nr_rrc_mac_config_req_cg(rrc->ue_id, 0, cellGroupConfig);
|
nr_rrc_mac_config_req_cg(rrc->ue_id, 0, cellGroupConfig, rrc->UECap.UE_NR_Capability);
|
||||||
|
|
||||||
asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, cellGroupConfig);
|
asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, cellGroupConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1516,23 +1529,7 @@ static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECa
|
|||||||
info->rrc_TransactionIdentifier = UECapabilityEnquiry->rrc_TransactionIdentifier;
|
info->rrc_TransactionIdentifier = UECapabilityEnquiry->rrc_TransactionIdentifier;
|
||||||
NR_UE_CapabilityRAT_Container_t ue_CapabilityRAT_Container = {.rat_Type = NR_RAT_Type_nr};
|
NR_UE_CapabilityRAT_Container_t ue_CapabilityRAT_Container = {.rat_Type = NR_RAT_Type_nr};
|
||||||
|
|
||||||
char *file_path = rrc->uecap_file;
|
if (!rrc->UECap.UE_NR_Capability) {
|
||||||
|
|
||||||
FILE *f = NULL;
|
|
||||||
if (file_path)
|
|
||||||
f = fopen(file_path, "r");
|
|
||||||
if(f){
|
|
||||||
char UE_NR_Capability_xer[65536];
|
|
||||||
size_t size = fread(UE_NR_Capability_xer, 1, sizeof UE_NR_Capability_xer, f);
|
|
||||||
if (size == 0 || size == sizeof UE_NR_Capability_xer) {
|
|
||||||
LOG_E(NR_RRC, "UE Capabilities XER file %s is too large (%ld)\n", file_path, size);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
asn_dec_rval_t dec_rval =
|
|
||||||
xer_decode(0, &asn_DEF_NR_UE_NR_Capability, (void *)&rrc->UECap.UE_NR_Capability, UE_NR_Capability_xer, size);
|
|
||||||
assert(dec_rval.code == RC_OK);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rrc->UECap.UE_NR_Capability = CALLOC(1, sizeof(NR_UE_NR_Capability_t));
|
rrc->UECap.UE_NR_Capability = CALLOC(1, sizeof(NR_UE_NR_Capability_t));
|
||||||
asn1cSequenceAdd(rrc->UECap.UE_NR_Capability->rf_Parameters.supportedBandListNR.list, NR_BandNR_t, nr_bandnr);
|
asn1cSequenceAdd(rrc->UECap.UE_NR_Capability->rf_Parameters.supportedBandListNR.list, NR_BandNR_t, nr_bandnr);
|
||||||
nr_bandnr->bandNR = 1;
|
nr_bandnr->bandNR = 1;
|
||||||
@@ -1895,6 +1892,9 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc,
|
|||||||
asn1cFreeStruc(asn_DEF_NR_SIB14_r16, SI_info->sib14);
|
asn1cFreeStruc(asn_DEF_NR_SIB14_r16, SI_info->sib14);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rrc->nrRrcState == RRC_STATE_DETACH_NR)
|
||||||
|
asn1cFreeStruc(asn_DEF_NR_UE_NR_Capability, rrc->UECap.UE_NR_Capability);
|
||||||
|
|
||||||
// reset MAC
|
// reset MAC
|
||||||
NR_UE_MAC_reset_cause_t cause = (rrc->nrRrcState == RRC_STATE_DETACH_NR) ? DETACH : GO_TO_IDLE;
|
NR_UE_MAC_reset_cause_t cause = (rrc->nrRrcState == RRC_STATE_DETACH_NR) ? DETACH : GO_TO_IDLE;
|
||||||
nr_rrc_mac_config_req_reset(rrc->ue_id, cause);
|
nr_rrc_mac_config_req_reset(rrc->ue_id, cause);
|
||||||
|
|||||||
@@ -187,8 +187,7 @@ typedef struct NR_UE_RRC_INST_s {
|
|||||||
instance_t ue_id;
|
instance_t ue_id;
|
||||||
rrcPerNB_t perNB[NB_CNX_UE];
|
rrcPerNB_t perNB[NB_CNX_UE];
|
||||||
|
|
||||||
char *uecap_file;
|
rnti_t rnti;
|
||||||
rnti_t rnti;
|
|
||||||
|
|
||||||
OAI_NR_UECapability_t UECap;
|
OAI_NR_UECapability_t UECap;
|
||||||
NR_UE_Timers_Constants_t timers_and_constants;
|
NR_UE_Timers_Constants_t timers_and_constants;
|
||||||
|
|||||||
Reference in New Issue
Block a user