Commit 3972cd44 authored by Raphael Defosseux's avatar Raphael Defosseux

Merge remote-tracking branch 'origin/NR_UE_maxmimo_layers' into integration_2024_w08

parents c599e172 58ea7357
...@@ -698,9 +698,8 @@ int main(int argc, char **argv) ...@@ -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) ...@@ -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);
......
...@@ -1905,9 +1905,64 @@ static void configure_BWPs(NR_UE_MAC_INST_t *mac, NR_ServingCellConfig_t *scd) ...@@ -1905,9 +1905,64 @@ 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)
return;
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;
}
}
if (ue_Capability->featureSets->featureSetsUplinkPerCC) {
struct NR_FeatureSets__featureSetsUplinkPerCC *fs_ulcc_list = ue_Capability->featureSets->featureSetsUplinkPerCC;
for (int i = 0; i < fs_ulcc_list->list.count; i++) {
NR_FeatureSetUplinkPerCC_t *fs_ul_cc = fs_ulcc_list->list.array[i];
if (mac->current_UL_BWP->scs != fs_ul_cc->supportedSubcarrierSpacingUL)
continue;
int uecap_bw_index;
if (fs_ul_cc->supportedBandwidthUL.present == NR_SupportedBandwidth_PR_fr1) {
uecap_bw_index = fs_ul_cc->supportedBandwidthUL.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_ul_cc->channelBW_90mhz)
uecap_bw_index++;
}
else
uecap_bw_index = fs_ul_cc->supportedBandwidthUL.choice.fr2;
int ul_bw_mhz = mac->phy_config.config_req.carrier_config.uplink_bandwidth;
if (ul_bw_mhz != get_supported_bw_mhz(mac->frequency_range, uecap_bw_index))
continue;
if (fs_ul_cc->maxNumberMIMO_LayersNonCB_PUSCH)
mac->uecap_maxMIMO_PUSCH_layers_nocb = 1 << *fs_ul_cc->maxNumberMIMO_LayersNonCB_PUSCH;
if (fs_ul_cc->mimo_CB_PUSCH && fs_ul_cc->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH)
mac->uecap_maxMIMO_PUSCH_layers_cb = 1 << *fs_ul_cc->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH;
}
}
}
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");
...@@ -1937,6 +1992,9 @@ void nr_rrc_mac_config_req_cg(module_id_t module_id, ...@@ -1937,6 +1992,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)
......
...@@ -478,6 +478,10 @@ typedef struct NR_UE_MAC_INST_s { ...@@ -478,6 +478,10 @@ 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_cb;
uint32_t uecap_maxMIMO_PUSCH_layers_nocb;
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 ...@@ -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,
......
...@@ -66,6 +66,9 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac) ...@@ -66,6 +66,9 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac)
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_cb = 0;
mac->uecap_maxMIMO_PUSCH_layers_nocb = 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));
......
...@@ -1190,8 +1190,13 @@ static int nr_ue_process_dci_dl_11(NR_UE_MAC_INST_t *mac, ...@@ -1190,8 +1190,13 @@ static int nr_ue_process_dci_dl_11(NR_UE_MAC_INST_t *mac,
} }
// 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;
......
...@@ -698,16 +698,28 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, ...@@ -698,16 +698,28 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
N_PRB_oh = 0; N_PRB_oh = 0;
if (sc_info->rateMatching_PUSCH) { if (sc_info->rateMatching_PUSCH) {
long *maxMIMO_Layers = sc_info->maxMIMO_Layers_PUSCH; long maxMIMO_Layers = 0;
if (!maxMIMO_Layers) if (sc_info->maxMIMO_Layers_PUSCH)
maxMIMO_Layers = pusch_Config ? pusch_Config->maxRank : NULL; maxMIMO_Layers = *sc_info->maxMIMO_Layers_PUSCH;
AssertFatal (maxMIMO_Layers != NULL,"Option with max MIMO layers not configured is not supported\n"); else if (pusch_Config && pusch_Config->maxRank)
pusch_config_pdu->tbslbrm = nr_compute_tbslbrm(pusch_config_pdu->mcs_table, sc_info->ul_bw_tbslbrm, *maxMIMO_Layers); maxMIMO_Layers = *pusch_Config->maxRank;
else {
if (pusch_Config && pusch_Config->txConfig) {
if (*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook)
maxMIMO_Layers = mac->uecap_maxMIMO_PUSCH_layers_cb;
else
maxMIMO_Layers = mac->uecap_maxMIMO_PUSCH_layers_nocb;
} else
maxMIMO_Layers = 1; // single antenna port
}
AssertFatal (maxMIMO_Layers > 0, "Invalid number of max MIMO layers for PUSCH\n");
pusch_config_pdu->tbslbrm = nr_compute_tbslbrm(pusch_config_pdu->mcs_table, sc_info->ul_bw_tbslbrm, maxMIMO_Layers);
} else } else
pusch_config_pdu->tbslbrm = 0; pusch_config_pdu->tbslbrm = 0;
/* PTRS */ /* PTRS */
if (pusch_Config && pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB && pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS) { if (pusch_Config && pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB &&
pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS) {
if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled) { if (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled) {
nfapi_nr_ue_ptrs_ports_t ptrs_ports_list; nfapi_nr_ue_ptrs_ports_t ptrs_ports_list;
pusch_config_pdu->pusch_ptrs.ptrs_ports_list = &ptrs_ports_list; pusch_config_pdu->pusch_ptrs.ptrs_ports_list = &ptrs_ports_list;
...@@ -724,7 +736,8 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, ...@@ -724,7 +736,8 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
if(valid_ptrs_setup == true) { if(valid_ptrs_setup == true) {
pusch_config_pdu->pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS; pusch_config_pdu->pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS;
} }
LOG_D(NR_MAC, "UL PTRS values: PTRS time den: %d, PTRS freq den: %d\n", pusch_config_pdu->pusch_ptrs.ptrs_time_density, pusch_config_pdu->pusch_ptrs.ptrs_freq_density); LOG_D(NR_MAC, "UL PTRS values: PTRS time den: %d, PTRS freq den: %d\n",
pusch_config_pdu->pusch_ptrs.ptrs_time_density, pusch_config_pdu->pusch_ptrs.ptrs_freq_density);
} }
} }
} }
......
...@@ -215,8 +215,7 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc, ...@@ -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) ...@@ -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));
set_default_timers_and_constants(&rrc->timers_and_constants); set_default_timers_and_constants(&rrc->timers_and_constants);
...@@ -803,8 +817,7 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc, ...@@ -803,8 +817,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);
} }
...@@ -1523,23 +1536,7 @@ static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECa ...@@ -1523,23 +1536,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;
...@@ -1902,6 +1899,9 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, ...@@ -1902,6 +1899,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);
......
...@@ -189,8 +189,7 @@ typedef struct NR_UE_RRC_INST_s { ...@@ -189,8 +189,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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment