1 /******************************************************************************
3 * Copyright (c) 2019 Intel.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 *******************************************************************************/
21 * This file consist of implementation of FAPI DL_TTI.request message.
24 #include <rte_memcpy.h>
25 #include "nr5g_fapi_framework.h"
26 #include "gnb_l1_l2_api.h"
27 #include "nr5g_fapi_dpdk.h"
28 #include "nr5g_fapi_fapi2mac_api.h"
29 #include "nr5g_fapi_fapi2phy_api.h"
30 #include "nr5g_fapi_fapi2phy_p7_proc.h"
31 #include "nr5g_fapi_fapi2phy_p7_pvt_proc.h"
32 #include "nr5g_fapi_memory.h"
34 /** @ingroup group_source_api_p5_fapi2phy_proc
36 * @param[in] p_phy_instance Pointer to PHY instance.
37 * @param[in] p_fapi_req Pointer to FAPI DL_TTI.request message structure.
39 * @return Returns ::SUCCESS and ::FAILURE.
42 * This message indicates the control information for a downlink slot.
45 uint8_t nr5g_fapi_dl_tti_request(
47 p_nr5g_fapi_phy_instance_t p_phy_instance,
48 fapi_dl_tti_req_t * p_fapi_req,
49 fapi_vendor_msg_t * p_fapi_vendor_msg)
51 PDLConfigRequestStruct p_ia_dl_config_req;
52 PMAC2PHY_QUEUE_EL p_list_elem;
53 nr5g_fapi_stats_t *p_stats;
55 if (NULL == p_phy_instance) {
56 NR5G_FAPI_LOG(ERROR_LOG, ("[DL_TTI.request] Invalid " "Phy Instance"));
60 p_stats = &p_phy_instance->stats;
61 p_stats->fapi_stats.fapi_dl_tti_req++;
63 if (NULL == p_fapi_req) {
64 NR5G_FAPI_LOG(ERROR_LOG, ("[DL_TTI.request] Invalid fapi " "message"));
68 p_list_elem = nr5g_fapi_fapi2phy_create_api_list_elem((uint8_t)
69 MSG_TYPE_PHY_DL_CONFIG_REQ, 1,
70 (uint32_t) sizeof(DLConfigRequestStruct));
72 NR5G_FAPI_LOG(ERROR_LOG, ("[DL_TTI.request] Unable to create "
73 "list element. Out of memory!!!"));
77 p_ia_dl_config_req = (PDLConfigRequestStruct) (p_list_elem + 1);
78 if (FAILURE == nr5g_fapi_dl_tti_req_to_phy_translation(p_phy_instance,
79 p_fapi_req, p_fapi_vendor_msg, p_ia_dl_config_req)) {
80 nr5g_fapi_fapi2phy_destroy_api_list_elem(p_list_elem);
81 NR5G_FAPI_LOG(DEBUG_LOG, ("[DL_TTI.request][%d][%d,%d] Not Sent",
82 p_phy_instance->phy_id, p_ia_dl_config_req->sSFN_Slot.nSFN,
83 p_ia_dl_config_req->sSFN_Slot.nSlot));
86 /* Add element to send list */
87 nr5g_fapi_fapi2phy_add_to_api_list(is_urllc, p_list_elem);
89 p_stats->iapi_stats.iapi_dl_config_req++;
90 NR5G_FAPI_LOG(DEBUG_LOG, ("[DL_TTI.request][%u][%u,%u,%u] is_urllc %u",
91 p_phy_instance->phy_id,
92 p_ia_dl_config_req->sSFN_Slot.nSFN, p_ia_dl_config_req->sSFN_Slot.nSlot,
93 p_ia_dl_config_req->sSFN_Slot.nSym, is_urllc));
98 /** @ingroup group_source_api_p7_fapi2phy_proc
100 * @param[in] p_fapi_req Pointer to FAPI DL_TTI.request structure.
101 * @param[out] p_ia_dl_config_req Pointer to IAPI DL_TTI.request structure.
103 * @return Returns ::SUCCESS and ::FAILURE.
106 * This function converts FAPI DL_TTI.request to IAPI DL_Config.request
110 uint8_t nr5g_fapi_dl_tti_req_to_phy_translation(
111 p_nr5g_fapi_phy_instance_t p_phy_instance,
112 fapi_dl_tti_req_t * p_fapi_req,
113 fapi_vendor_msg_t * p_fapi_vendor_msg,
114 PDLConfigRequestStruct p_phy_req)
116 int idx = 0, nDCI = 0, jdx = 0;
117 uint32_t pdsch_size, pdcch_size, pbch_size, csirs_size, total_size;
118 nr5g_fapi_stats_t *p_stats;
120 fapi_dl_tti_req_pdu_t *p_fapi_dl_tti_req_pdu = NULL;
121 fapi_dl_pdcch_pdu_t *p_pdcch_pdu = NULL;
122 fapi_dl_pdsch_pdu_t *p_pdsch_pdu = NULL;
123 fapi_dl_csi_rs_pdu_t *p_csi_rs_pdu = NULL;
124 fapi_dl_ssb_pdu_t *p_ssb_pdu = NULL;
125 fapi_ue_info_t *p_ueGrpInfo = NULL;
127 PPDUStruct pPduStruct = NULL;
128 PDLSCHPDUStruct p_dlsch_pdu = NULL;
129 PDCIPDUStruct p_dci_pdu = NULL;
130 PBCHPDUStruct p_bch_pdu = NULL;
131 PCSIRSPDUStruct pCSIRSPdu = NULL;
132 PPDSCHGroupInfoStruct pPDSCHGroupInfoStruct = NULL;
134 total_size = sizeof(DLConfigRequestStruct);
135 pdsch_size = RUP32B(sizeof(DLSCHPDUStruct));
136 pdcch_size = RUP32B(sizeof(DCIPDUStruct));
137 pbch_size = RUP32B(sizeof(BCHPDUStruct));
138 csirs_size = RUP32B(sizeof(CSIRSPDUStruct));
140 p_stats = &p_phy_instance->stats;
141 NR5G_FAPI_MEMSET(p_phy_req, sizeof(DLConfigRequestStruct), 0, total_size);
142 p_phy_req->sMsgHdr.nMessageType = MSG_TYPE_PHY_DL_CONFIG_REQ;
143 p_phy_req->sSFN_Slot.nCarrierIdx = p_phy_instance->phy_id;
144 p_phy_req->nGroup = p_fapi_req->nGroup;
145 p_phy_req->nPDU = p_fapi_req->nPdus;
146 p_phy_req->sSFN_Slot.nSFN = p_fapi_req->sfn;
147 p_phy_req->sSFN_Slot.nSlot = p_fapi_req->slot;
149 for (idx = 0; idx < p_phy_req->nGroup; ++idx) {
150 p_ueGrpInfo = &p_fapi_req->ue_grp_info[idx];
151 pPDSCHGroupInfoStruct = &p_phy_req->sPDSCHGroupInfoStruct[idx];
152 pPDSCHGroupInfoStruct->nUE = p_ueGrpInfo->nUe;
153 pPDSCHGroupInfoStruct->rsv1[0] = 0;
154 pPDSCHGroupInfoStruct->rsv1[1] = 0;
155 pPDSCHGroupInfoStruct->rsv1[2] = 0;
156 for (jdx = 0; jdx < p_ueGrpInfo->nUe; ++jdx) {
157 pPDSCHGroupInfoStruct->nPduIdx[jdx] = p_ueGrpInfo->pduIdx[jdx];
161 pPduStruct = p_phy_req->sDLPDU;
162 for (idx = 0; idx < p_phy_req->nPDU; ++idx) {
163 p_stats->fapi_stats.fapi_dl_tti_pdus++;
164 p_fapi_dl_tti_req_pdu = &p_fapi_req->pdus[idx];
165 switch (p_fapi_dl_tti_req_pdu->pduType) {
166 case FAPI_PDCCH_PDU_TYPE:
168 p_dci_pdu = (PDCIPDUStruct) pPduStruct;
169 NR5G_FAPI_MEMSET(p_dci_pdu, RUP32B(sizeof(DCIPDUStruct)), 0,
171 p_pdcch_pdu = &p_fapi_dl_tti_req_pdu->pdu.pdcch_pdu;
172 p_dci_pdu->sPDUHdr.nPDUType = DL_PDU_TYPE_DCI;
173 p_dci_pdu->sPDUHdr.nPDUSize = pdcch_size;
174 total_size += pdcch_size;
175 nr5g_fapi_fill_dci_pdu(p_phy_instance, p_pdcch_pdu, p_dci_pdu);
178 case FAPI_PDSCH_PDU_TYPE:
179 p_dlsch_pdu = (PDLSCHPDUStruct) pPduStruct;
180 p_pdsch_pdu = &p_fapi_dl_tti_req_pdu->pdu.pdsch_pdu;
181 NR5G_FAPI_MEMSET(p_dlsch_pdu, RUP32B(sizeof(DLSCHPDUStruct)), 0,
183 p_dlsch_pdu->sPDUHdr.nPDUType = DL_PDU_TYPE_DLSCH;
184 p_dlsch_pdu->sPDUHdr.nPDUSize = pdsch_size;
185 total_size += pdsch_size;
186 nr5g_fapi_fill_pdsch_pdu(p_phy_instance, p_pdsch_pdu, p_dlsch_pdu);
189 case FAPI_PBCH_PDU_TYPE:
190 p_bch_pdu = (PBCHPDUStruct) pPduStruct;
191 p_ssb_pdu = &p_fapi_dl_tti_req_pdu->pdu.ssb_pdu;
192 NR5G_FAPI_MEMSET(p_bch_pdu, RUP32B(sizeof(BCHPDUStruct)), 0,
194 p_bch_pdu->sPDUHdr.nPDUType = DL_PDU_TYPE_PBCH;
195 p_bch_pdu->sPDUHdr.nPDUSize = pbch_size;
196 total_size += pbch_size;
197 nr5g_fapi_fill_ssb_pdu(p_phy_instance, p_bch_pdu, p_ssb_pdu);
200 case FAPI_CSIRS_PDU_TYPE:
201 pCSIRSPdu = (PCSIRSPDUStruct) pPduStruct;
202 p_csi_rs_pdu = &p_fapi_dl_tti_req_pdu->pdu.csi_rs_pdu;
203 NR5G_FAPI_MEMSET(pCSIRSPdu, RUP32B(sizeof(CSIRSPDUStruct)), 0,
205 pCSIRSPdu->sPDUHdr.nPDUType = DL_PDU_TYPE_CSIRS;
206 pCSIRSPdu->sPDUHdr.nPDUSize = csirs_size;
207 total_size += csirs_size;
208 nr5g_fapi_fill_csi_rs_pdu(p_phy_instance, p_csi_rs_pdu, pCSIRSPdu);
212 NR5G_FAPI_LOG(ERROR_LOG, ("[DL_TTI] Invalid Pdu Type: %d",
213 pPduStruct->nPDUType));
217 (PDUStruct *) ((uint8_t *) pPduStruct + pPduStruct->nPDUSize);
218 p_stats->iapi_stats.iapi_dl_tti_pdus++;
221 p_phy_req->nDCI = nDCI;
222 p_phy_req->sMsgHdr.nMessageLen = total_size;
224 if (NULL != p_fapi_vendor_msg)
226 nr5g_fapi_dl_tti_req_to_phy_translation_vendor_ext(p_phy_instance,
234 /** @ingroup group_source_api_p5_fapi2phy_proc
236 * @param[in] p_fapi_vendor_msg Pointer to FAPI DL_TTI.request vendor message.
237 * @param[out] p_ia_dl_config_req Pointer to IAPI DL_TTI.request structure.
242 * This function fills fields for DL_TTI.request structure that come from
243 * a vendor extension.
246 void nr5g_fapi_dl_tti_req_to_phy_translation_vendor_ext(
247 p_nr5g_fapi_phy_instance_t p_phy_instance,
248 fapi_vendor_msg_t * p_fapi_vendor_msg,
249 PDLConfigRequestStruct p_phy_req)
253 fapi_vendor_dl_tti_req_t *p_vendor_dl_tti_req = NULL;
254 fapi_vendor_dl_pdcch_pdu_t *p_vendor_pdcch_pdu = NULL;
255 fapi_vendor_dl_pdsch_pdu_t *p_vendor_pdsch_pdu = NULL;
256 fapi_vendor_csi_rs_pdu_t *p_vendor_csi_rs_pdu = NULL;
258 PPDUStruct pPduStruct = NULL;
259 PDCIPDUStruct p_dci_pdu = NULL;
260 PDLSCHPDUStruct p_dlsch_pdu = NULL;
261 PCSIRSPDUStruct p_CSIRS_pdu = NULL;
263 p_vendor_dl_tti_req = &p_fapi_vendor_msg->p7_req_vendor.dl_tti_req;
265 p_phy_req->sSFN_Slot.nSym = p_fapi_vendor_msg->p7_req_vendor.dl_tti_req.sym;
267 p_phy_req->nLte_CRS_Present = p_fapi_vendor_msg->p7_req_vendor.dl_tti_req.lte_crs_present;
268 p_phy_req->nLte_CRS_carrierFreqDL = p_fapi_vendor_msg->p7_req_vendor.dl_tti_req.lte_crs_carrier_freq_dl;
269 p_phy_req->nLte_CRS_carrierBandwidthDL = p_fapi_vendor_msg->p7_req_vendor.dl_tti_req.lte_crs_carrier_bandwidth_dl;
270 p_phy_req->nLte_CRS_nrofCRS_Ports = p_fapi_vendor_msg->p7_req_vendor.dl_tti_req.lte_crs_nr_of_crs_ports;
271 p_phy_req->nLte_CRS_v_shift = p_fapi_vendor_msg->p7_req_vendor.dl_tti_req.lte_crs_v_shift;
272 p_phy_req->nPdcchPrecoderEn = p_fapi_vendor_msg->p7_req_vendor.dl_tti_req.pdcch_precoder_en;
273 p_phy_req->nSSBPrecoderEn = p_fapi_vendor_msg->p7_req_vendor.dl_tti_req.ssb_precoder_en;
275 pPduStruct = p_phy_req->sDLPDU;
276 for (idx = 0; idx < p_phy_req->nPDU; ++idx) {
277 switch (pPduStruct->nPDUType) {
278 case DL_PDU_TYPE_DCI:
279 p_dci_pdu = (PDCIPDUStruct) pPduStruct;
281 &p_vendor_dl_tti_req->pdus[idx].pdu.pdcch_pdu;
283 if (USE_VENDOR_EPREXSSB == p_phy_instance->phy_config.use_vendor_EpreXSSB)
285 p_dci_pdu->nEpreRatioOfPDCCHToSSB =
286 p_vendor_pdcch_pdu->dl_dci[0].epre_ratio_of_pdcch_to_ssb;
287 p_dci_pdu->nEpreRatioOfDmrsToSSB =
288 p_vendor_pdcch_pdu->dl_dci[0].epre_ratio_of_dmrs_to_ssb;
292 case DL_PDU_TYPE_DLSCH:
293 p_dlsch_pdu = (PDLSCHPDUStruct) pPduStruct;
295 &p_vendor_dl_tti_req->pdus[idx].pdu.pdsch_pdu;
297 p_dlsch_pdu->nNrOfAntennaPorts = p_vendor_pdsch_pdu->nr_of_antenna_ports;
299 if (USE_VENDOR_EPREXSSB == p_phy_instance->phy_config.use_vendor_EpreXSSB)
301 p_dlsch_pdu->nEpreRatioOfDmrsToSSB =
302 p_vendor_pdsch_pdu->epre_ratio_of_dmrs_to_ssb;
303 p_dlsch_pdu->nEpreRatioOfPDSCHToSSB =
304 p_vendor_pdsch_pdu->epre_ratio_of_pdsch_to_ssb;
307 NR5G_FAPI_MEMCPY(p_dlsch_pdu->nTxRUIdx, sizeof(p_dlsch_pdu->nTxRUIdx),
308 p_vendor_pdsch_pdu->tx_ru_idx, sizeof(p_vendor_pdsch_pdu->tx_ru_idx));
311 case DL_PDU_TYPE_PBCH:
315 case DL_PDU_TYPE_CSIRS:
316 p_CSIRS_pdu = (PCSIRSPDUStruct) pPduStruct;
317 p_vendor_csi_rs_pdu = &p_vendor_dl_tti_req->pdus[idx].pdu.csi_rs_pdu;
319 if (USE_VENDOR_EPREXSSB == p_phy_instance->phy_config.use_vendor_EpreXSSB)
321 p_CSIRS_pdu->nEpreRatioToSSB = p_vendor_csi_rs_pdu->epre_ratio_to_ssb;
326 NR5G_FAPI_LOG(ERROR_LOG, ("[DL_TTI] Invalid Pdu Type: %d",
327 pPduStruct->nPDUType));
331 (PDUStruct *) ((uint8_t *) pPduStruct + pPduStruct->nPDUSize);
335 /** @ingroup group_nr5g_test_config
337 * @param[in] p_pdcch_pdu
338 * @param[out] p_dci_pdu
343 * This function fills IAPI DCIPdu from FAPI PDCCH Pdu
346 void nr5g_fapi_fill_dci_pdu(
347 p_nr5g_fapi_phy_instance_t p_phy_instance,
348 fapi_dl_pdcch_pdu_t * p_pdcch_pdu,
349 PDCIPDUStruct p_dci_pdu)
351 nr5g_fapi_stats_t *p_stats = NULL;
353 p_stats = &p_phy_instance->stats;
354 p_stats->fapi_stats.fapi_dl_tti_pdcch_pdus++;
356 p_dci_pdu->nBWPSize = p_pdcch_pdu->bwpSize;
357 p_dci_pdu->nBWPStart = p_pdcch_pdu->bwpStart;
358 p_dci_pdu->nSubcSpacing = p_pdcch_pdu->subCarrierSpacing;
359 p_dci_pdu->nCpType = p_pdcch_pdu->cyclicPrefix;
360 p_dci_pdu->nCCEStartIndex = p_pdcch_pdu->startSymbolIndex;
361 p_dci_pdu->nNrOfSymbols = p_pdcch_pdu->durationSymbols;
362 p_dci_pdu->nStartSymbolIndex = p_pdcch_pdu->startSymbolIndex;
363 p_dci_pdu->nFreqDomain[0] = ((uint32_t) p_pdcch_pdu->freqDomainResource[0] |
364 (((uint32_t) p_pdcch_pdu->freqDomainResource[1]) << 8) |
365 (((uint32_t) p_pdcch_pdu->freqDomainResource[2]) << 16) |
366 (((uint32_t) p_pdcch_pdu->freqDomainResource[3]) << 24));
367 p_dci_pdu->nFreqDomain[1] = ((uint32_t) p_pdcch_pdu->freqDomainResource[4] |
368 (((uint32_t) p_pdcch_pdu->freqDomainResource[5]) << 8));
369 p_dci_pdu->nCCEToREGType = p_pdcch_pdu->cceRegMappingType;
370 p_dci_pdu->nREGBundleSize = p_pdcch_pdu->regBundleSize;
371 p_dci_pdu->nInterleaveSize = p_pdcch_pdu->interleaverSize;
372 p_dci_pdu->nShift = p_pdcch_pdu->shiftIndex;
373 p_dci_pdu->nCoreSetType = p_pdcch_pdu->coreSetType;
374 p_dci_pdu->nCCEStartIndex = p_pdcch_pdu->dlDci[0].cceIndex;
375 p_dci_pdu->nAggrLvl = p_pdcch_pdu->dlDci[0].aggregationLevel;
376 p_dci_pdu->nScid = p_pdcch_pdu->dlDci[0].scramblingId;
377 p_dci_pdu->nID = p_pdcch_pdu->dlDci[0].scramblingId;
378 p_dci_pdu->nRNTIScramb = p_pdcch_pdu->dlDci[0].scramblingRnti;
379 p_dci_pdu->nRNTI = p_pdcch_pdu->dlDci[0].rnti;
380 p_dci_pdu->nTotalBits = p_pdcch_pdu->dlDci[0].payloadSizeBits;
382 if (USE_VENDOR_EPREXSSB != p_phy_instance->phy_config.use_vendor_EpreXSSB) {
383 p_dci_pdu->nEpreRatioOfPDCCHToSSB =
384 nr5g_fapi_calculate_nEpreRatioOfPDCCHToSSB(p_pdcch_pdu->
385 dlDci[0].beta_pdcch_1_0);
386 p_dci_pdu->nEpreRatioOfDmrsToSSB =
387 nr5g_fapi_calculate_nEpreRatioOfDmrsToSSB(p_pdcch_pdu->
388 dlDci[0].powerControlOffsetSS);
391 if (FAILURE == NR5G_FAPI_MEMCPY(p_dci_pdu->nDciBits,
392 sizeof(uint8_t) * MAX_DCI_BIT_BYTE_LEN,
393 p_pdcch_pdu->dlDci[0].payload,
394 sizeof(uint8_t) * MAX_DCI_BIT_BYTE_LEN)) {
395 NR5G_FAPI_LOG(ERROR_LOG, ("PDCCH: RNTI: %d -- DCI Bits copy error.",
396 p_pdcch_pdu->dlDci[0].rnti));
398 p_stats->iapi_stats.iapi_dl_tti_pdcch_pdus++;
401 /** @ingroup group_nr5g_test_config
403 * @param[in] p_pdsch_pdu
404 * @param[out] p_dlsch_pdu
409 * This function fills FAPI PDSCH Pdu from IAPI DLSCHPDU
412 void nr5g_fapi_fill_pdsch_pdu(
413 p_nr5g_fapi_phy_instance_t p_phy_instance,
414 fapi_dl_pdsch_pdu_t * p_pdsch_pdu,
415 PDLSCHPDUStruct p_dlsch_pdu)
417 uint8_t idx, port_index = 0;
418 nr5g_fapi_stats_t *p_stats;
420 p_stats = &p_phy_instance->stats;
421 p_stats->fapi_stats.fapi_dl_tti_pdsch_pdus++;
423 p_dlsch_pdu->nBWPSize = p_pdsch_pdu->bwpSize;
424 p_dlsch_pdu->nBWPStart = p_pdsch_pdu->bwpStart;
425 p_dlsch_pdu->nSubcSpacing = p_pdsch_pdu->subCarrierSpacing;
426 p_dlsch_pdu->nCpType = p_pdsch_pdu->cyclicPrefix;
427 p_dlsch_pdu->nRNTI = p_pdsch_pdu->rnti;
428 p_dlsch_pdu->nUEId = p_pdsch_pdu->pdu_index;
430 // Codeword Information
431 p_dlsch_pdu->nNrOfCodeWords = p_pdsch_pdu->nrOfCodeWords;
432 p_dlsch_pdu->nMCS[0] = p_pdsch_pdu->cwInfo[0].mcsIndex;
433 p_dlsch_pdu->nMcsTable = p_pdsch_pdu->cwInfo[0].mcsTable;
434 p_dlsch_pdu->nRV[0] = p_pdsch_pdu->cwInfo[0].rvIndex;
435 p_dlsch_pdu->nTBSize[0] = p_pdsch_pdu->cwInfo[0].tbSize;
436 if (p_pdsch_pdu->nrOfCodeWords == 2) {
437 p_dlsch_pdu->nMCS[1] = p_pdsch_pdu->cwInfo[1].mcsIndex;
438 p_dlsch_pdu->nRV[1] = p_pdsch_pdu->cwInfo[1].rvIndex;
439 p_dlsch_pdu->nTBSize[1] = p_pdsch_pdu->cwInfo[1].tbSize;
441 //p_dlsch_pdu->nNrOfAntennaPorts = p_phy_instance->phy_config.n_nr_of_rx_ant;
442 p_dlsch_pdu->nNrOfLayers = p_pdsch_pdu->nrOfLayers;
443 p_dlsch_pdu->nNrOfAntennaPorts = p_dlsch_pdu->nNrOfLayers;
444 p_dlsch_pdu->nTransmissionScheme = p_pdsch_pdu->transmissionScheme;
445 p_dlsch_pdu->nDMRSConfigType = p_pdsch_pdu->dmrsConfigType;
446 p_dlsch_pdu->nNIDnSCID = p_pdsch_pdu->dlDmrsScramblingId;
447 p_dlsch_pdu->nNid = p_pdsch_pdu->dataScramblingId;
448 p_dlsch_pdu->nSCID = p_pdsch_pdu->scid;
451 (idx < FAPI_MAX_DMRS_PORTS && port_index < p_dlsch_pdu->nNrOfLayers);
453 if ((p_pdsch_pdu->dmrsPorts >> idx) && 0x0001) {
454 p_dlsch_pdu->nPortIndex[port_index++] = idx;
458 // Resource Allocation Information
459 if (FAILURE == NR5G_FAPI_MEMCPY(p_dlsch_pdu->nRBGIndex,
460 sizeof(uint32_t) * MAX_DL_RBG_BIT_NUM,
461 p_pdsch_pdu->rbBitmap, sizeof(uint32_t) * MAX_DL_RBG_BIT_NUM)) {
462 NR5G_FAPI_LOG(ERROR_LOG, ("PDSCH: RNTI: %d Pdu Index: %d -- RB Bitmap"
463 "cpy error.", p_pdsch_pdu->rnti, p_pdsch_pdu->pdu_index));
465 p_dlsch_pdu->nResourceAllocType = p_pdsch_pdu->resourceAlloc;
466 p_dlsch_pdu->nRBStart = p_pdsch_pdu->rbStart;
467 p_dlsch_pdu->nRBSize = p_pdsch_pdu->rbSize;
468 p_dlsch_pdu->nPMI = (p_pdsch_pdu->preCodingAndBeamforming.numPrgs > 0)
469 ? p_pdsch_pdu->preCodingAndBeamforming.pmi_bfi[0].pmIdx
471 p_dlsch_pdu->nVRBtoPRB = p_pdsch_pdu->vrbToPrbMapping;
472 p_dlsch_pdu->nStartSymbolIndex = p_pdsch_pdu->startSymbIndex;
473 p_dlsch_pdu->nNrOfSymbols = p_pdsch_pdu->nrOfSymbols;
474 p_dlsch_pdu->nNrOfCDMs = p_pdsch_pdu->numDmrsCdmGrpsNoData;
475 p_dlsch_pdu->nMappingType = p_pdsch_pdu->mappingType;
476 p_dlsch_pdu->nNrOfDMRSSymbols = p_pdsch_pdu->nrOfDmrsSymbols;
477 p_dlsch_pdu->nDMRSAddPos = p_pdsch_pdu->dmrsAddPos;
480 p_dlsch_pdu->nPTRSTimeDensity = p_pdsch_pdu->ptrsTimeDensity;
481 p_dlsch_pdu->nPTRSFreqDensity = p_pdsch_pdu->ptrsFreqDensity;
482 p_dlsch_pdu->nPTRSReOffset = p_pdsch_pdu->ptrsReOffset;
483 p_dlsch_pdu->nEpreRatioOfPDSCHToPTRS = p_pdsch_pdu->nEpreRatioOfPdschToPtrs;
485 if (USE_VENDOR_EPREXSSB != p_phy_instance->phy_config.use_vendor_EpreXSSB) {
486 p_dlsch_pdu->nEpreRatioOfDmrsToSSB =
487 nr5g_fapi_calculate_nEpreRatioOfDmrsToSSB(
488 p_pdsch_pdu->powerControlOffsetSS);
489 p_dlsch_pdu->nEpreRatioOfPDSCHToSSB =
490 nr5g_fapi_calculate_nEpreRatioOfPDSCHToSSB(
491 p_pdsch_pdu->powerControlOffset);
495 p_dlsch_pdu->nPTRSPresent = p_pdsch_pdu->pduBitMap & 0x0001;
496 p_dlsch_pdu->nNrOfPTRSPorts =
497 __builtin_popcount(p_pdsch_pdu->ptrsPortIndex);
498 for (idx = 0; idx < p_dlsch_pdu->nNrOfPTRSPorts &&
499 idx < MAX_DL_PER_UE_PTRS_PORT_NUM; idx++) {
500 p_dlsch_pdu->nPTRSPortIndex[idx] = idx;
504 p_dlsch_pdu->nNrOfDMRSAssPTRS[0] = 0x1;
505 p_dlsch_pdu->nNrOfDMRSAssPTRS[1] = 0x1;
506 p_dlsch_pdu->n1n2 = 0x201;
508 p_dlsch_pdu->nNrofTxRU = port_index;
510 p_stats->iapi_stats.iapi_dl_tti_pdsch_pdus++;
513 /** @ingroup group_nr5g_test_config
515 * @param[in] beta_pdcch_1_0
517 * @return uint16_t mapping
520 * This function maps FAPI to IAPI value range.
523 * Please refer 5G FAPI-IAPI Translator Module SW Design Document for details on
526 * |-----------------------------------------|
527 * | nEpreRatioOfPDCCHToSSb | beta_PDCCH_1_0 |
528 * |-----------------------------------------|
545 * |-----------------------------------------|
548 uint16_t nr5g_fapi_calculate_nEpreRatioOfPDCCHToSSB(
549 uint8_t beta_pdcch_1_0)
551 if (beta_pdcch_1_0 > 0 && beta_pdcch_1_0 <= 2) {
553 } else if (beta_pdcch_1_0 > 1 && beta_pdcch_1_0 < 17) {
554 return ((beta_pdcch_1_0 - 2) * 1000);
555 } else if (beta_pdcch_1_0 == 17) {
556 return ((beta_pdcch_1_0 - 3) * 1000);
562 /** @ingroup group_nr5g_test_config
564 * @param[in] power_control_offset_ss
566 * @return uint16_t mapping
569 * This function maps FAPI to IAPI value range.
572 * nEpreRatioOfDmrsToSSB: 1->20000, 0.001dB step, -6dB to 14dB
573 * powerControlOffsetSS: 0->3, 3dB step, -3dB to 6dB
574 * |----------------------------------------------|
575 * | nEpreRatioOfDmrsToSSB | powerControlOffsetSS |
576 * |----------------------------------------------|
581 * |----------------------------------------------|
584 uint16_t nr5g_fapi_calculate_nEpreRatioOfDmrsToSSB(
585 uint8_t power_control_offset_ss)
587 switch(power_control_offset_ss)
598 NR5G_FAPI_LOG(ERROR_LOG,
599 ("Unsupported value of power_control_offset_ss."));
605 /** @ingroup group_nr5g_test_config
607 * @param[in] power_control_offset
609 * @return uint16_t mapping
612 * This function maps FAPI to IAPI value range.
615 * nEpreRatioOfPDSCHToSSB: 1->20000, 0.001dB step, -6dB to 14dB
616 * powerControlOffset: 0->23, 1dB step, -8dB to 15dB
617 * |----------------------------------------------|
618 * | nEpreRatioOfPDSCHToSSB | powerControlOffset |
619 * |----------------------------------------------|
641 * |----------------------------------------------|
644 uint16_t nr5g_fapi_calculate_nEpreRatioOfPDSCHToSSB(uint8_t power_control_offset)
646 static const uint8_t MAPPING_SIZE = 24;
647 static const uint16_t power_control_offset_to_epre_ratio[MAPPING_SIZE] = {
649 1, 1, 1, 1000, 2000, 3000, 4000, 5000,
650 // 8 9 10 11 12 13 14 15
651 6000, 7000, 8000, 9000, 10000, 11000, 12000, 13000,
652 // 16 17 18 19 20 21 22 23
653 14000, 15000, 16000, 17000, 18000, 19000, 20000, 20000
656 if(MAPPING_SIZE > power_control_offset)
658 return power_control_offset_to_epre_ratio[power_control_offset];
662 NR5G_FAPI_LOG(ERROR_LOG,
663 ("Unsupported value of power_control_offset=%u.",
664 power_control_offset));
669 /** @ingroup group_nr5g_test_config
671 * @param[in] ssb_offset_point_a
672 * @param[in] sub_c_common
674 * @return uint8_t nSSBPrbOffset
677 * This function maps FAPI to IAPI value range.
679 * Please refer 5G FAPI-IAPI Translator Module SW Design Document for details on
683 uint8_t nr5g_fapi_calculate_nSSBPrbOffset(
684 uint16_t ssb_offset_point_a, uint8_t sub_c_common)
686 return ssb_offset_point_a/pow(2, sub_c_common);
689 /** @ingroup group_nr5g_test_config
691 * @param[in] p_dlsch_pdu
692 * @param[out] p_pdsch_pdu
697 * This function fills FAPI PDSCH Pdu from IAPI DLSCHPDU
700 void nr5g_fapi_fill_ssb_pdu(
701 p_nr5g_fapi_phy_instance_t p_phy_instance,
702 PBCHPDUStruct p_bch_pdu,
703 fapi_dl_ssb_pdu_t * p_ssb_pdu)
705 uint8_t *p_mib = (uint8_t *) & p_bch_pdu->nMIB[0];
706 uint8_t *payload = (uint8_t *) & p_ssb_pdu->bchPayload.bchPayload;
707 nr5g_fapi_stats_t *p_stats;
709 p_mib[0] = payload[0];
710 p_mib[1] = payload[1];
711 p_mib[2] = payload[2];
712 p_stats = &p_phy_instance->stats;
713 p_stats->fapi_stats.fapi_dl_tti_ssb_pdus++;
714 p_bch_pdu->nSSBSubcOffset = p_ssb_pdu->ssbSubCarrierOffset;
715 p_bch_pdu->nSSBPrbOffset =
716 nr5g_fapi_calculate_nSSBPrbOffset(p_ssb_pdu->ssbOffsetPointA,
717 p_phy_instance->phy_config.sub_c_common);
718 p_stats->iapi_stats.iapi_dl_tti_ssb_pdus++;
721 /** @ingroup group_nr5g_test_config
723 * @param[in] p_dlsch_pdu
724 * @param[out] p_pdsch_pdu
729 * This function fills FAPI PDSCH Pdu from IAPI DLSCHPDU
732 void nr5g_fapi_fill_csi_rs_pdu(
733 p_nr5g_fapi_phy_instance_t p_phy_instance,
734 fapi_dl_csi_rs_pdu_t * p_csi_rs_pdu,
735 PCSIRSPDUStruct p_CSIRS_pdu)
737 nr5g_fapi_stats_t *p_stats;
739 p_stats = &p_phy_instance->stats;
740 p_stats->fapi_stats.fapi_dl_tti_csi_rs_pdus++;
742 p_CSIRS_pdu->nBWPSize = p_csi_rs_pdu->bwpSize;
743 p_CSIRS_pdu->nBWPStart = p_csi_rs_pdu->bwpStart;
744 p_CSIRS_pdu->nCDMType = p_csi_rs_pdu->cdmType;
745 p_CSIRS_pdu->nCSIType = p_csi_rs_pdu->csiType;
746 p_CSIRS_pdu->nCpType = p_csi_rs_pdu->cyclicPrefix;
747 p_CSIRS_pdu->nFreqDensity = p_csi_rs_pdu->freqDensity;
748 p_CSIRS_pdu->nFreqDomain = p_csi_rs_pdu->freqDomain;
749 p_CSIRS_pdu->nNrOfRBs = p_csi_rs_pdu->nrOfRbs;
750 p_CSIRS_pdu->nScrambId = p_csi_rs_pdu->scramId;
751 p_CSIRS_pdu->nStartRB = p_csi_rs_pdu->startRb;
752 p_CSIRS_pdu->nSubcSpacing = p_csi_rs_pdu->subCarrierSpacing;
753 p_CSIRS_pdu->nSymbL0 = p_csi_rs_pdu->symbL0;
754 p_CSIRS_pdu->nSymbL1 = p_csi_rs_pdu->symbL1;
755 p_CSIRS_pdu->nRow = p_csi_rs_pdu->row;
756 // Not mapping the beamforming parameters
757 // p_CSIRS_pdu->powerControlOffset = p_csi_rs_pdu->powerControlOffset;
759 if (USE_VENDOR_EPREXSSB != p_phy_instance->phy_config.use_vendor_EpreXSSB) {
760 p_CSIRS_pdu->nEpreRatioToSSB = nr5g_fapi_calculate_nEpreRatioOfDmrsToSSB(p_csi_rs_pdu->powerControlOffsetSs);
763 p_stats->iapi_stats.iapi_dl_tti_csi_rs_pdus++;