Commit d8f2dd81 authored by Robert Schmidt's avatar Robert Schmidt

nr_csi_meas_reporting() for multiple UEs

parent 3b92a3b4
...@@ -411,8 +411,8 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, ...@@ -411,8 +411,8 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
// TODO // TODO
// Schedule CSI measurement reporting: check in slot 0 for the whole frame // Schedule CSI measurement reporting: check in slot 0 for the whole frame
if (slot == 0 && UE_info->active[UE_id]) if (slot == 0)
nr_csi_meas_reporting(module_idP, UE_id, frame, slot); nr_csi_meas_reporting(module_idP, frame, slot);
// This schedule RA procedure if not in phy_test mode // This schedule RA procedure if not in phy_test mode
// Otherwise already consider 5G already connected // Otherwise already consider 5G already connected
......
...@@ -179,76 +179,104 @@ uint16_t nr_get_csi_bitlen(const nr_csi_report_t *csi_report) ...@@ -179,76 +179,104 @@ uint16_t nr_get_csi_bitlen(const nr_csi_report_t *csi_report)
void nr_csi_meas_reporting(int Mod_idP, void nr_csi_meas_reporting(int Mod_idP,
int UE_id,
frame_t frame, frame_t frame,
sub_frame_t slot) sub_frame_t slot)
{ {
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
const NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id];
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
const NR_CSI_MeasConfig_t *csi_measconfig = secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup;
AssertFatal(csi_measconfig->csi_ReportConfigToAddModList->list.count > 0,
"NO CSI report configuration available");
NR_PUCCH_Config_t *pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup;
NR_ServingCellConfigCommon_t *scc = NR_ServingCellConfigCommon_t *scc =
RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon; RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
for (int csi_report_id = 0; csi_report_id < csi_measconfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){ NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
const NR_CSI_ReportConfig_t *csirep = csi_measconfig->csi_ReportConfigToAddModList->list.array[csi_report_id]; NR_UE_list_t *UE_list = &UE_info->list;
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
AssertFatal(csirep->reportConfigType.choice.periodic, const NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id];
"Only periodic CSI reporting is implemented currently\n"); NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
int period, offset; const NR_CSI_MeasConfig_t *csi_measconfig = secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup;
csi_period_offset(csirep, &period, &offset); AssertFatal(csi_measconfig->csi_ReportConfigToAddModList->list.count > 0,
const int sched_slot = (period + offset) % n_slots_frame; "NO CSI report configuration available");
// prepare to schedule csi measurement reception according to 5.2.1.4 in 38.214 NR_PUCCH_Config_t *pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup;
// preparation is done in first slot of tdd period
if (frame % (period / n_slots_frame) != offset / n_slots_frame) for (int csi_report_id = 0; csi_report_id < csi_measconfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){
continue; const NR_CSI_ReportConfig_t *csirep = csi_measconfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
LOG_D(MAC, "CSI in frame %d slot %d\n", frame, sched_slot);
AssertFatal(csirep->reportConfigType.choice.periodic,
// we are scheduling pucch for csi in the first pucch occasion (this comes before ack/nack) "Only periodic CSI reporting is implemented currently\n");
// FIXME: for the moment, we statically put it into the second sched_pucch! int period, offset;
NR_sched_pucch_t *curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[2]; csi_period_offset(csirep, &period, &offset);
const int sched_slot = (period + offset) % n_slots_frame;
const NR_PUCCH_CSI_Resource_t *pucchcsires = csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.array[0]; // prepare to schedule csi measurement reception according to 5.2.1.4 in 38.214
const NR_PUCCH_ResourceSet_t *pucchresset = pucch_Config->resourceSetToAddModList->list.array[1]; // set with formats >1 // preparation is done in first slot of tdd period
const int n = pucchresset->resourceList.list.count; if (frame % (period / n_slots_frame) != offset / n_slots_frame)
int res_index = 0;
for (; res_index < n; res_index++)
if (*pucchresset->resourceList.list.array[res_index] == pucchcsires->pucch_Resource)
break;
AssertFatal(res_index < n,
"CSI resource not found among PUCCH resources\n");
curr_pucch->resource_indicator = res_index;
// going through the list of PUCCH resources to find the one indexed by resource_id
const int m = pucch_Config->resourceToAddModList->list.count;
for (int j = 0; j < m; j++) {
NR_PUCCH_Resource_t *pucchres = pucch_Config->resourceToAddModList->list.array[j];
if (pucchres->pucch_ResourceId != *pucchresset->resourceList.list.array[res_index])
continue; continue;
switch(pucchres->format.present){ LOG_D(MAC, "CSI in frame %d slot %d\n", frame, sched_slot);
case NR_PUCCH_Resource__format_PR_format2:
curr_pucch->simultaneous_harqcsi = pucch_Config->format2->choice.setup->simultaneousHARQ_ACK_CSI; const NR_PUCCH_CSI_Resource_t *pucchcsires = csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.array[0];
break; const NR_PUCCH_ResourceSet_t *pucchresset = pucch_Config->resourceSetToAddModList->list.array[1]; // set with formats >1
case NR_PUCCH_Resource__format_PR_format3: const int n = pucchresset->resourceList.list.count;
curr_pucch->simultaneous_harqcsi = pucch_Config->format3->choice.setup->simultaneousHARQ_ACK_CSI; int res_index = 0;
break; for (; res_index < n; res_index++)
case NR_PUCCH_Resource__format_PR_format4: if (*pucchresset->resourceList.list.array[res_index] == pucchcsires->pucch_Resource)
curr_pucch->simultaneous_harqcsi = pucch_Config->format4->choice.setup->simultaneousHARQ_ACK_CSI;
break; break;
default: AssertFatal(res_index < n,
AssertFatal(0, "Invalid PUCCH format type\n"); "CSI resource not found among PUCCH resources\n");
// find free PUCCH that is in order with possibly existing PUCCH
// schedulings (other CSI, SR)
NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[2];
AssertFatal(curr_pucch->csi_bits == 0
&& !curr_pucch->sr_flag
&& curr_pucch->dai_c == 0,
"PUCCH not free at index 2 for UE %04x\n",
UE_info->rnti[UE_id]);
curr_pucch->frame = frame;
curr_pucch->ul_slot = sched_slot;
curr_pucch->resource_indicator = res_index;
curr_pucch->csi_bits +=
nr_get_csi_bitlen(&UE_info->csi_report_template[UE_id][csi_report_id]);
// going through the list of PUCCH resources to find the one indexed by resource_id
uint16_t *vrb_map_UL =
&RC.nrmac[Mod_idP]->common_channels[0].vrb_map_UL[sched_slot * 275];
const int m = pucch_Config->resourceToAddModList->list.count;
for (int j = 0; j < m; j++) {
NR_PUCCH_Resource_t *pucchres = pucch_Config->resourceToAddModList->list.array[j];
if (pucchres->pucch_ResourceId != *pucchresset->resourceList.list.array[res_index])
continue;
int start = pucchres->startingPRB;
int len = 1;
uint64_t mask = 0;
switch(pucchres->format.present){
case NR_PUCCH_Resource__format_PR_format2:
len = pucchres->format.choice.format2->nrofPRBs;
mask = ((1 << pucchres->format.choice.format2->nrofSymbols) - 1) << pucchres->format.choice.format2->startingSymbolIndex;
curr_pucch->simultaneous_harqcsi = pucch_Config->format2->choice.setup->simultaneousHARQ_ACK_CSI;
break;
case NR_PUCCH_Resource__format_PR_format3:
len = pucchres->format.choice.format3->nrofPRBs;
mask = ((1 << pucchres->format.choice.format3->nrofSymbols) - 1) << pucchres->format.choice.format3->startingSymbolIndex;
curr_pucch->simultaneous_harqcsi = pucch_Config->format3->choice.setup->simultaneousHARQ_ACK_CSI;
break;
case NR_PUCCH_Resource__format_PR_format4:
mask = ((1 << pucchres->format.choice.format4->nrofSymbols) - 1) << pucchres->format.choice.format4->startingSymbolIndex;
curr_pucch->simultaneous_harqcsi = pucch_Config->format4->choice.setup->simultaneousHARQ_ACK_CSI;
break;
default:
AssertFatal(0, "Invalid PUCCH format type\n");
}
// verify resources are free
for (int i = start; i < start + len; ++i) {
AssertFatal((vrb_map_UL[i] & mask) == 0,
"cannot allocate CSI PUCCH for UE %04x: PRB %d used in symbs %lx\n",
UE_info->rnti[UE_id],
i,
mask);
vrb_map_UL[i] |= mask;
}
AssertFatal(!curr_pucch->simultaneous_harqcsi,
"UE %04x has simultaneous HARQ/CSI configured, but we don't support that\n",
UE_info->rnti[UE_id]);
} }
} }
curr_pucch->csi_bits +=
nr_get_csi_bitlen(&UE_info->csi_report_template[UE_id][csi_report_id]);
curr_pucch->frame = frame;
curr_pucch->ul_slot = sched_slot;
} }
} }
......
...@@ -217,7 +217,6 @@ void csi_period_offset(const NR_CSI_ReportConfig_t *csirep, ...@@ -217,7 +217,6 @@ void csi_period_offset(const NR_CSI_ReportConfig_t *csirep,
int *period, int *offset); int *period, int *offset);
void nr_csi_meas_reporting(int Mod_idP, void nr_csi_meas_reporting(int Mod_idP,
int UE_id,
frame_t frameP, frame_t frameP,
sub_frame_t slotP); sub_frame_t slotP);
......
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