Commit 68c95f80 authored by francescomani's avatar francescomani

increase the number of UE supported at gNB by having more than 1 PUCCH2 frequency occasion per slot

parent 03946cd4
......@@ -56,6 +56,7 @@
#include "utils.h"
#include "xer_encoder.h"
#define PUCCH2_SIZE 8
const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
static NR_BWP_t clone_generic_parameters(const NR_BWP_t *gp)
......@@ -187,6 +188,24 @@ static NR_PUSCH_Config_t *clone_pusch_config(const NR_PUSCH_Config_t *pc)
return clone;
}
static int get_nb_pucch2_per_slot(const NR_ServingCellConfigCommon_t *scc, int bwp_size)
{
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
const int n_slots_frame = slotsperframe[*scc->ssbSubcarrierSpacing];
int ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0) : n_slots_frame;
int n_slots_period = tdd ? n_slots_frame/get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame;
int max_meas_report_period = 320; // slots
int max_csi_reports = MAX_MOBILES_PER_GNB << 1; // 2 reports per UE (RSRP and RI-PMI-CQI)
int available_report_occasions = max_meas_report_period * ul_slots_period / n_slots_period;
int nb_pucch2 = (max_csi_reports / (available_report_occasions + 1)) + 1;
// in current implementation we need (nb_pucch2 * PUCCH2_SIZE) prbs for PUCCH2
// and MAX_MOBILES_PER_GNB prbs for PUCCH1
AssertFatal((nb_pucch2 * PUCCH2_SIZE) + MAX_MOBILES_PER_GNB <= bwp_size,
"Cannot allocate all required PUCCH resources for max number of %d UEs in BWP with %d PRBs\n",
MAX_MOBILES_PER_GNB, bwp_size);
return nb_pucch2;
}
NR_SearchSpace_t *rrc_searchspace_config(bool is_common, int searchspaceid, int coresetid)
{
......@@ -295,7 +314,7 @@ static uint64_t get_ssb_bitmap(const NR_ServingCellConfigCommon_t *scc)
static int set_ideal_period(const int n_slots_period, const int n_ul_slots_period)
{
return MAX_MOBILES_PER_GNB * 2 * n_slots_period / n_ul_slots_period; // 2 reports per UE
return MAX_MOBILES_PER_GNB * 2 * n_slots_period / n_ul_slots_period; // 2 reports per UE (RSRP and RI-PMI-CQI)
}
static void set_csirs_periodicity(NR_NZP_CSI_RS_Resource_t *nzpcsi0,
......@@ -307,7 +326,6 @@ static void set_csirs_periodicity(NR_NZP_CSI_RS_Resource_t *nzpcsi0,
nzpcsi0->periodicityAndOffset = calloc(1,sizeof(*nzpcsi0->periodicityAndOffset));
// TODO ideal period to be set according to estimation by the gNB on how fast the channel changes
const int offset = nb_slots_per_period * id;
if (ideal_period < 5) {
nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots4;
nzpcsi0->periodicityAndOffset->choice.slots4 = offset;
......@@ -974,7 +992,11 @@ static void set_dl_DataToUL_ACK(NR_PUCCH_Config_t *pucch_Config, int min_feedbac
}
// PUCCH resource set 0 for configuration with O_uci <= 2 bits and/or a positive or negative SR (section 9.2.1 of 38.213)
static void config_pucch_resset0(NR_PUCCH_Config_t *pucch_Config, int uid, int curr_bwp, const NR_UE_NR_Capability_t *uecap)
static void config_pucch_resset0(NR_PUCCH_Config_t *pucch_Config,
int uid,
int curr_bwp,
int num_pucch2,
const NR_UE_NR_Capability_t *uecap)
{
NR_PUCCH_ResourceSet_t *pucchresset = calloc(1,sizeof(*pucchresset));
pucchresset->pucch_ResourceSetId = 0;
......@@ -990,7 +1012,7 @@ static void config_pucch_resset0(NR_PUCCH_Config_t *pucch_Config, int uid, int c
NR_PUCCH_Resource_t *pucchres0 = calloc(1,sizeof(*pucchres0));
pucchres0->pucch_ResourceId = *pucchid;
pucchres0->startingPRB = 8 + uid;
pucchres0->startingPRB = (PUCCH2_SIZE * num_pucch2) + uid;
AssertFatal(pucchres0->startingPRB < curr_bwp, "Not enough resources in current BWP (size %d) to allocate uid %d\n", curr_bwp, uid);
pucchres0->intraSlotFrequencyHopping = NULL;
pucchres0->secondHopPRB = NULL;
......@@ -1006,7 +1028,10 @@ static void config_pucch_resset0(NR_PUCCH_Config_t *pucch_Config, int uid, int c
// PUCCH resource set 1 for configuration with O_uci > 2 bits (currently format2)
static void config_pucch_resset1(NR_PUCCH_Config_t *pucch_Config, const NR_UE_NR_Capability_t *uecap)
static void config_pucch_resset1(NR_PUCCH_Config_t *pucch_Config,
int uid,
int num_pucch2,
const NR_UE_NR_Capability_t *uecap)
{
NR_PUCCH_ResourceSet_t *pucchresset=calloc(1,sizeof(*pucchresset));
pucchresset->pucch_ResourceSetId = 1;
......@@ -1022,12 +1047,12 @@ static void config_pucch_resset1(NR_PUCCH_Config_t *pucch_Config, const NR_UE_NR
NR_PUCCH_Resource_t *pucchres2 = calloc(1,sizeof(*pucchres2));
pucchres2->pucch_ResourceId = *pucchressetid;
pucchres2->startingPRB = 0;
pucchres2->startingPRB = PUCCH2_SIZE * (uid % num_pucch2);
pucchres2->intraSlotFrequencyHopping = NULL;
pucchres2->secondHopPRB = NULL;
pucchres2->format.present = NR_PUCCH_Resource__format_PR_format2;
pucchres2->format.choice.format2 = calloc(1,sizeof(*pucchres2->format.choice.format2));
pucchres2->format.choice.format2->nrofPRBs = 8;
pucchres2->format.choice.format2->nrofPRBs = PUCCH2_SIZE;
pucchres2->format.choice.format2->nrofSymbols = 1;
pucchres2->format.choice.format2->startingSymbolIndex = 13;
asn1cSeqAdd(&pucch_Config->resourceToAddModList->list,pucchres2);
......@@ -1501,8 +1526,9 @@ static void config_uplinkBWP(NR_BWP_Uplink_t *ubwp,
pucch_Config->resourceSetToReleaseList = NULL;
pucch_Config->resourceToAddModList = calloc(1,sizeof(*pucch_Config->resourceToAddModList));
pucch_Config->resourceToReleaseList = NULL;
config_pucch_resset0(pucch_Config, uid, curr_bwp, uecap);
config_pucch_resset1(pucch_Config, uecap);
int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp);
config_pucch_resset0(pucch_Config, uid, curr_bwp, num_pucch2, uecap);
config_pucch_resset1(pucch_Config, uid, num_pucch2, uecap);
set_pucch_power_config(pucch_Config, configuration->do_CSIRS);
scheduling_request_config(scc, pucch_Config, ubwp->bwp_Common->genericParameters.subcarrierSpacing);
set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME, ubwp->bwp_Common->genericParameters.subcarrierSpacing);
......@@ -1545,7 +1571,11 @@ static void set_phr_config(NR_MAC_CellGroupConfig_t *mac_CellGroupConfig)
mac_CellGroupConfig->phr_Config->choice.setup->phr_Tx_PowerFactorChange = NR_PHR_Config__phr_Tx_PowerFactorChange_dB1;
}
static void set_csi_meas_periodicity(const NR_ServingCellConfigCommon_t *scc, NR_CSI_ReportConfig_t *csirep, int uid, bool is_rsrp)
static void set_csi_meas_periodicity(const NR_ServingCellConfigCommon_t *scc,
NR_CSI_ReportConfig_t *csirep,
int uid,
int curr_bwp,
bool is_rsrp)
{
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
const int n_slots_frame = slotsperframe[*scc->ssbSubcarrierSpacing];
......@@ -1553,7 +1583,8 @@ static void set_csi_meas_periodicity(const NR_ServingCellConfigCommon_t *scc, NR
const int n_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame;
const int ideal_period = set_ideal_period(n_slots_period, n_ul_slots_period);
const int first_ul_slot_period = tdd ? get_first_ul_slot(tdd->nrofDownlinkSlots, tdd->nrofDownlinkSymbols, tdd->nrofUplinkSymbols) : 0;
const int idx = (uid << 1) + is_rsrp;
const int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp);
const int idx = (uid * 2 / num_pucch2) + is_rsrp;
const int offset = first_ul_slot_period + idx % n_ul_slots_period + (idx / n_ul_slots_period) * n_slots_period;
AssertFatal(offset < 320, "Not enough UL slots to accomodate all possible UEs. Need to rework the implementation\n");
......@@ -1703,7 +1734,8 @@ static void config_csi_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
const nr_pdsch_AntennaPorts_t *antennaports,
const int max_layers,
int rep_id,
int uid)
int uid,
int curr_bwp)
{
int resource_id = -1;
int im_id = -1;
......@@ -1732,7 +1764,7 @@ static void config_csi_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
csirep->nzp_CSI_RS_ResourcesForInterference = NULL;
csirep->reportConfigType.present = NR_CSI_ReportConfig__reportConfigType_PR_periodic;
csirep->reportConfigType.choice.periodic = calloc(1, sizeof(*csirep->reportConfigType.choice.periodic));
set_csi_meas_periodicity(servingcellconfigcommon, csirep, uid, false);
set_csi_meas_periodicity(servingcellconfigcommon, csirep, uid, curr_bwp, false);
asn1cSeqAdd(&csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list, pucchcsires);
csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI;
csirep->reportQuantity.choice.cri_RI_PMI_CQI = (NULL_t)0;
......@@ -1767,6 +1799,7 @@ static void config_rsrp_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
int do_csi, // if rsrp is based on CSI or SSB
int rep_id,
int uid,
int curr_bwp,
int num_antenna_ports)
{
int resource_id = -1;
......@@ -1793,7 +1826,7 @@ static void config_rsrp_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
csirep->nzp_CSI_RS_ResourcesForInterference = NULL;
csirep->reportConfigType.present = NR_CSI_ReportConfig__reportConfigType_PR_periodic;
csirep->reportConfigType.choice.periodic = calloc(1, sizeof(*csirep->reportConfigType.choice.periodic));
set_csi_meas_periodicity(servingcellconfigcommon, csirep, uid, true);
set_csi_meas_periodicity(servingcellconfigcommon, csirep, uid, curr_bwp, true);
asn1cSeqAdd(&csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list, pucchcsires);
if (do_csi && num_antenna_ports < 4) {
csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP;
......@@ -2848,8 +2881,9 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid,
pucch_Config->resourceSetToReleaseList = NULL;
pucch_Config->resourceToAddModList = calloc(1, sizeof(*pucch_Config->resourceToAddModList));
pucch_Config->resourceToReleaseList = NULL;
config_pucch_resset0(pucch_Config, uid, curr_bwp, NULL);
config_pucch_resset1(pucch_Config, NULL);
int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp);
config_pucch_resset0(pucch_Config, uid, curr_bwp, num_pucch2, NULL);
config_pucch_resset1(pucch_Config, uid, num_pucch2, NULL);
set_pucch_power_config(pucch_Config, configuration->do_CSIRS);
initialUplinkBWP->pusch_Config = config_pusch(NULL, configuration->use_deltaMCS, scc, NULL);
......@@ -3060,12 +3094,13 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid,
&configuration->pdsch_AntennaPorts,
*pdsch_servingcellconfig->ext1->maxMIMO_Layers,
bwp_id,
uid);
uid,
curr_bwp);
}
NR_PUCCH_CSI_Resource_t *pucchrsrp = calloc(1, sizeof(*pucchrsrp));
pucchrsrp->uplinkBandwidthPartId = bwp_id;
pucchrsrp->pucch_Resource = pucch_Resource;
config_rsrp_meas_report(csi_MeasConfig, scc, pucchrsrp, configuration->do_CSIRS, bwp_id + 10, uid, pdsch_AntennaPorts);
config_rsrp_meas_report(csi_MeasConfig, scc, pucchrsrp, configuration->do_CSIRS, bwp_id + 10, uid, curr_bwp, pdsch_AntennaPorts);
}
fill_harq_IEs(SpCellConfig->spCellConfigDedicated, configuration->num_dlharq, configuration->num_ulharq);
......@@ -3561,8 +3596,23 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC
pucchcsires1->uplinkBandwidthPartId = bwp->bwp_Id;
pucchcsires1->pucch_Resource = 2;
config_csi_meas_report(csi_MeasConfig, servingcellconfigcommon, pucchcsires1, bwp->bwp_Dedicated->pdsch_Config, pdschap, *pdsch_servingcellconfig->ext1->maxMIMO_Layers, bwp->bwp_Id, uid);
config_rsrp_meas_report(csi_MeasConfig, servingcellconfigcommon, pucchcsires1, do_csirs, bwp->bwp_Id + 10, uid, dl_antenna_ports);
config_csi_meas_report(csi_MeasConfig,
servingcellconfigcommon,
pucchcsires1,
bwp->bwp_Dedicated->pdsch_Config,
pdschap,
*pdsch_servingcellconfig->ext1->maxMIMO_Layers,
bwp->bwp_Id,
uid,
curr_bwp);
config_rsrp_meas_report(csi_MeasConfig,
servingcellconfigcommon,
pucchcsires1,
do_csirs,
bwp->bwp_Id + 10,
uid,
curr_bwp,
dl_antenna_ports);
}
secondaryCellGroup->spCellConfig->spCellConfigDedicated->sCellDeactivationTimer = NULL;
secondaryCellGroup->spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig = NULL;
......
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