1 /******************************************************************************
3 * Copyright (c) 2021 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 "nr5g_fapi_dpdk.h"
27 #include "nr5g_fapi_fapi2mac_api.h"
28 #include "nr5g_fapi_fapi2phy_api.h"
29 #include "nr5g_fapi_fapi2phy_p7_proc.h"
30 #include "nr5g_fapi_fapi2phy_p7_pvt_proc.h"
31 #include "nr5g_fapi_memory.h"
33 /** @ingroup group_source_api_p5_fapi2phy_proc
35 * @param[in] p_phy_instance Pointer to PHY instance.
36 * @param[in] p_fapi_req Pointer to FAPI DL_TTI.request message structure.
38 * @return Returns ::SUCCESS and ::FAILURE.
41 * This message indicates the control information for a downlink slot.
44 uint8_t nr5g_fapi_dl_tti_request(
46 p_nr5g_fapi_phy_instance_t p_phy_instance,
47 fapi_dl_tti_req_t * p_fapi_req,
48 fapi_vendor_msg_t * p_fapi_vendor_msg)
50 PDLConfigRequestStruct p_ia_dl_config_req;
51 PMAC2PHY_QUEUE_EL p_list_elem;
52 nr5g_fapi_stats_t *p_stats;
54 if (NULL == p_phy_instance) {
55 NR5G_FAPI_LOG(ERROR_LOG, ("[DL_TTI.request] Invalid " "Phy Instance"));
59 p_stats = &p_phy_instance->stats;
60 p_stats->fapi_stats.fapi_dl_tti_req++;
62 if (NULL == p_fapi_req) {
63 NR5G_FAPI_LOG(ERROR_LOG, ("[DL_TTI.request] Invalid fapi " "message"));
67 p_list_elem = nr5g_fapi_fapi2phy_create_api_list_elem((uint8_t)
68 MSG_TYPE_PHY_DL_CONFIG_REQ, 1,
69 (uint32_t) sizeof(DLConfigRequestStruct));
71 NR5G_FAPI_LOG(ERROR_LOG, ("[DL_TTI.request] Unable to create "
72 "list element. Out of memory!!!"));
76 p_ia_dl_config_req = (PDLConfigRequestStruct) (p_list_elem + 1);
77 if (FAILURE == nr5g_fapi_dl_tti_req_to_phy_translation(p_phy_instance,
78 p_fapi_req, p_fapi_vendor_msg, p_ia_dl_config_req)) {
79 nr5g_fapi_fapi2phy_destroy_api_list_elem(p_list_elem);
80 NR5G_FAPI_LOG(DEBUG_LOG, ("[DL_TTI.request][%d][%d,%d] Not Sent",
81 p_phy_instance->phy_id, p_ia_dl_config_req->sSFN_Slot.nSFN,
82 p_ia_dl_config_req->sSFN_Slot.nSlot));
85 /* Add element to send list */
86 nr5g_fapi_fapi2phy_add_to_api_list(is_urllc, p_list_elem);
88 p_stats->iapi_stats.iapi_dl_config_req++;
89 NR5G_FAPI_LOG(DEBUG_LOG, ("[DL_TTI.request][%u][%u,%u,%u] is_urllc %u",
90 p_phy_instance->phy_id,
91 p_ia_dl_config_req->sSFN_Slot.nSFN, p_ia_dl_config_req->sSFN_Slot.nSlot,
92 p_ia_dl_config_req->sSFN_Slot.nSym, is_urllc));
97 /** @ingroup group_source_api_p7_fapi2phy_proc
99 * @param[in] p_fapi_req Pointer to FAPI DL_TTI.request structure.
100 * @param[out] p_ia_dl_config_req Pointer to IAPI DL_TTI.request structure.
102 * @return Returns ::SUCCESS and ::FAILURE.
105 * This function converts FAPI DL_TTI.request to IAPI DL_Config.request
109 uint8_t nr5g_fapi_dl_tti_req_to_phy_translation(
110 p_nr5g_fapi_phy_instance_t p_phy_instance,
111 fapi_dl_tti_req_t * p_fapi_req,
112 fapi_vendor_msg_t * p_fapi_vendor_msg,
113 PDLConfigRequestStruct p_phy_req)
115 int idx = 0, nDCI = 0, jdx = 0;
116 uint32_t pdsch_size, pdcch_size, pbch_size, csirs_size, total_size;
117 nr5g_fapi_stats_t *p_stats;
119 fapi_dl_tti_req_pdu_t *p_fapi_dl_tti_req_pdu = NULL;
120 fapi_dl_pdcch_pdu_t *p_pdcch_pdu = NULL;
121 fapi_dl_pdsch_pdu_t *p_pdsch_pdu = NULL;
122 fapi_dl_csi_rs_pdu_t *p_csi_rs_pdu = NULL;
123 fapi_dl_ssb_pdu_t *p_ssb_pdu = NULL;
124 fapi_ue_info_t *p_ueGrpInfo = NULL;
126 PPDUStruct pPduStruct = NULL;
127 PDLSCHPDUStruct p_dlsch_pdu = NULL;
128 PDCIPDUStruct p_dci_pdu = NULL;
129 PBCHPDUStruct p_bch_pdu = NULL;
130 PCSIRSPDUStruct pCSIRSPdu = NULL;
131 PPDSCHGroupInfoStruct pPDSCHGroupInfoStruct = NULL;
133 total_size = sizeof(DLConfigRequestStruct);
134 pdsch_size = RUP32B(sizeof(DLSCHPDUStruct));
135 pdcch_size = RUP32B(sizeof(DCIPDUStruct));
136 pbch_size = RUP32B(sizeof(BCHPDUStruct));
137 csirs_size = RUP32B(sizeof(CSIRSPDUStruct));
139 p_stats = &p_phy_instance->stats;
140 NR5G_FAPI_MEMSET(p_phy_req, sizeof(DLConfigRequestStruct), 0, total_size);
141 p_phy_req->sMsgHdr.nMessageType = MSG_TYPE_PHY_DL_CONFIG_REQ;
142 p_phy_req->sSFN_Slot.nCarrierIdx = p_phy_instance->phy_id;
143 p_phy_req->nGroup = p_fapi_req->nGroup;
144 p_phy_req->nPDU = p_fapi_req->nPdus;
145 p_phy_req->sSFN_Slot.nSFN = p_fapi_req->sfn;
146 p_phy_req->sSFN_Slot.nSlot = p_fapi_req->slot;
148 for (idx = 0; idx < p_phy_req->nGroup; ++idx) {
149 p_ueGrpInfo = &p_fapi_req->ue_grp_info[idx];
150 pPDSCHGroupInfoStruct = &p_phy_req->sPDSCHGroupInfoStruct[idx];
151 pPDSCHGroupInfoStruct->nUE = p_ueGrpInfo->nUe;
152 pPDSCHGroupInfoStruct->rsv1[0] = 0;
153 pPDSCHGroupInfoStruct->rsv1[1] = 0;
154 pPDSCHGroupInfoStruct->rsv1[2] = 0;
155 for (jdx = 0; jdx < p_ueGrpInfo->nUe; ++jdx) {
156 pPDSCHGroupInfoStruct->nPduIdx[jdx] = p_ueGrpInfo->pduIdx[jdx];
160 pPduStruct = p_phy_req->sDLPDU;
161 for (idx = 0; idx < p_phy_req->nPDU; ++idx) {
162 p_stats->fapi_stats.fapi_dl_tti_pdus++;
163 p_fapi_dl_tti_req_pdu = &p_fapi_req->pdus[idx];
164 switch (p_fapi_dl_tti_req_pdu->pduType) {
165 case FAPI_PDCCH_PDU_TYPE:
167 p_dci_pdu = (PDCIPDUStruct) pPduStruct;
168 NR5G_FAPI_MEMSET(p_dci_pdu, RUP32B(sizeof(DCIPDUStruct)), 0,
170 p_pdcch_pdu = &p_fapi_dl_tti_req_pdu->pdu.pdcch_pdu;
171 p_dci_pdu->sPDUHdr.nPDUType = DL_PDU_TYPE_DCI;
172 p_dci_pdu->sPDUHdr.nPDUSize = pdcch_size;
173 total_size += pdcch_size;
174 nr5g_fapi_fill_dci_pdu(p_phy_instance, p_pdcch_pdu, p_dci_pdu);
177 case FAPI_PDSCH_PDU_TYPE:
178 p_dlsch_pdu = (PDLSCHPDUStruct) pPduStruct;
179 p_pdsch_pdu = &p_fapi_dl_tti_req_pdu->pdu.pdsch_pdu;
180 NR5G_FAPI_MEMSET(p_dlsch_pdu, RUP32B(sizeof(DLSCHPDUStruct)), 0,
182 p_dlsch_pdu->sPDUHdr.nPDUType = DL_PDU_TYPE_DLSCH;
183 p_dlsch_pdu->sPDUHdr.nPDUSize = pdsch_size;
184 total_size += pdsch_size;
185 nr5g_fapi_fill_pdsch_pdu(p_phy_instance, p_pdsch_pdu, p_dlsch_pdu);
188 case FAPI_PBCH_PDU_TYPE:
189 p_bch_pdu = (PBCHPDUStruct) pPduStruct;
190 p_ssb_pdu = &p_fapi_dl_tti_req_pdu->pdu.ssb_pdu;
191 NR5G_FAPI_MEMSET(p_bch_pdu, RUP32B(sizeof(BCHPDUStruct)), 0,
193 p_bch_pdu->sPDUHdr.nPDUType = DL_PDU_TYPE_PBCH;
194 p_bch_pdu->sPDUHdr.nPDUSize = pbch_size;
195 total_size += pbch_size;
196 nr5g_fapi_fill_ssb_pdu(p_phy_instance, p_bch_pdu, p_ssb_pdu);
199 case FAPI_CSIRS_PDU_TYPE:
200 pCSIRSPdu = (PCSIRSPDUStruct) pPduStruct;
201 p_csi_rs_pdu = &p_fapi_dl_tti_req_pdu->pdu.csi_rs_pdu;
202 NR5G_FAPI_MEMSET(pCSIRSPdu, RUP32B(sizeof(CSIRSPDUStruct)), 0,
204 pCSIRSPdu->sPDUHdr.nPDUType = DL_PDU_TYPE_CSIRS;
205 pCSIRSPdu->sPDUHdr.nPDUSize = csirs_size;
206 total_size += csirs_size;
207 nr5g_fapi_fill_csi_rs_pdu(p_phy_instance, p_csi_rs_pdu, pCSIRSPdu);
211 NR5G_FAPI_LOG(ERROR_LOG, ("[DL_TTI] Invalid Pdu Type: %d",
212 pPduStruct->nPDUType));
216 (PDUStruct *) ((uint8_t *) pPduStruct + pPduStruct->nPDUSize);
217 p_stats->iapi_stats.iapi_dl_tti_pdus++;
220 p_phy_req->nDCI = nDCI;
221 p_phy_req->sMsgHdr.nMessageLen = total_size;
223 if (NULL != p_fapi_vendor_msg)
225 nr5g_fapi_dl_tti_req_to_phy_translation_vendor_ext(p_phy_instance,
233 /** @ingroup group_source_api_p5_fapi2phy_proc
235 * @param[in] p_fapi_vendor_msg Pointer to FAPI DL_TTI.request vendor message.
236 * @param[out] p_ia_dl_config_req Pointer to IAPI DL_TTI.request structure.
241 * This function fills fields for DL_TTI.request structure that come from
242 * a vendor extension.
245 void nr5g_fapi_dl_tti_req_to_phy_translation_vendor_ext(
246 p_nr5g_fapi_phy_instance_t p_phy_instance,
247 fapi_vendor_msg_t * p_fapi_vendor_msg,
248 PDLConfigRequestStruct p_phy_req)
252 fapi_vendor_dl_tti_req_t *p_vendor_dl_tti_req = NULL;
253 fapi_vendor_dl_pdcch_pdu_t *p_vendor_pdcch_pdu = NULL;
254 fapi_vendor_dl_pdsch_pdu_t *p_vendor_pdsch_pdu = NULL;
255 fapi_vendor_csi_rs_pdu_t *p_vendor_csi_rs_pdu = NULL;
257 PPDUStruct pPduStruct = NULL;
258 PDCIPDUStruct p_dci_pdu = NULL;
259 PDLSCHPDUStruct p_dlsch_pdu = NULL;
260 PCSIRSPDUStruct p_CSIRS_pdu = NULL;
262 p_vendor_dl_tti_req = &p_fapi_vendor_msg->p7_req_vendor.dl_tti_req;
264 p_phy_req->sSFN_Slot.nSym = p_fapi_vendor_msg->p7_req_vendor.dl_tti_req.sym;
266 p_phy_req->nLte_CRS_Present = p_fapi_vendor_msg->p7_req_vendor.dl_tti_req.lte_crs_present;
267 p_phy_req->nLte_CRS_carrierFreqDL = p_fapi_vendor_msg->p7_req_vendor.dl_tti_req.lte_crs_carrier_freq_dl;
268 p_phy_req->nLte_CRS_carrierBandwidthDL = p_fapi_vendor_msg->p7_req_vendor.dl_tti_req.lte_crs_carrier_bandwidth_dl;
269 p_phy_req->nLte_CRS_nrofCRS_Ports = p_fapi_vendor_msg->p7_req_vendor.dl_tti_req.lte_crs_nr_of_crs_ports;
270 p_phy_req->nLte_CRS_v_shift = p_fapi_vendor_msg->p7_req_vendor.dl_tti_req.lte_crs_v_shift;
271 p_phy_req->nPdcchPrecoderEn = p_fapi_vendor_msg->p7_req_vendor.dl_tti_req.pdcch_precoder_en;
272 p_phy_req->nSSBPrecoderEn = p_fapi_vendor_msg->p7_req_vendor.dl_tti_req.ssb_precoder_en;
274 pPduStruct = p_phy_req->sDLPDU;
275 for (idx = 0; idx < p_phy_req->nPDU; ++idx) {
276 switch (pPduStruct->nPDUType) {
277 case DL_PDU_TYPE_DCI:
278 p_dci_pdu = (PDCIPDUStruct) pPduStruct;
280 &p_vendor_dl_tti_req->pdus[idx].pdu.pdcch_pdu;
282 if (USE_VENDOR_EPREXSSB == p_phy_instance->phy_config.use_vendor_EpreXSSB)
284 p_dci_pdu->nEpreRatioOfPDCCHToSSB =
285 p_vendor_pdcch_pdu->dl_dci[0].epre_ratio_of_pdcch_to_ssb;
286 p_dci_pdu->nEpreRatioOfDmrsToSSB =
287 p_vendor_pdcch_pdu->dl_dci[0].epre_ratio_of_dmrs_to_ssb;
291 case DL_PDU_TYPE_DLSCH:
292 p_dlsch_pdu = (PDLSCHPDUStruct) pPduStruct;
294 &p_vendor_dl_tti_req->pdus[idx].pdu.pdsch_pdu;
296 p_dlsch_pdu->nNrOfAntennaPorts = p_vendor_pdsch_pdu->nr_of_antenna_ports;
298 if (USE_VENDOR_EPREXSSB == p_phy_instance->phy_config.use_vendor_EpreXSSB)
300 p_dlsch_pdu->nEpreRatioOfDmrsToSSB =
301 p_vendor_pdsch_pdu->epre_ratio_of_dmrs_to_ssb;
302 p_dlsch_pdu->nEpreRatioOfPDSCHToSSB =
303 p_vendor_pdsch_pdu->epre_ratio_of_pdsch_to_ssb;
306 NR5G_FAPI_MEMCPY(p_dlsch_pdu->nTxRUIdx, sizeof(p_dlsch_pdu->nTxRUIdx),
307 p_vendor_pdsch_pdu->tx_ru_idx, sizeof(p_vendor_pdsch_pdu->tx_ru_idx));
310 case DL_PDU_TYPE_PBCH:
314 case DL_PDU_TYPE_CSIRS:
315 p_CSIRS_pdu = (PCSIRSPDUStruct) pPduStruct;
316 p_vendor_csi_rs_pdu = &p_vendor_dl_tti_req->pdus[idx].pdu.csi_rs_pdu;
318 if (USE_VENDOR_EPREXSSB == p_phy_instance->phy_config.use_vendor_EpreXSSB)
320 p_CSIRS_pdu->nEpreRatioToSSB = p_vendor_csi_rs_pdu->epre_ratio_to_ssb;
325 NR5G_FAPI_LOG(ERROR_LOG, ("[DL_TTI] Invalid Pdu Type: %d",
326 pPduStruct->nPDUType));
330 (PDUStruct *) ((uint8_t *) pPduStruct + pPduStruct->nPDUSize);
334 /** @ingroup group_nr5g_test_config
336 * @param[in] p_pdcch_pdu
337 * @param[out] p_dci_pdu
342 * This function fills IAPI DCIPdu from FAPI PDCCH Pdu
345 void nr5g_fapi_fill_dci_pdu(
346 p_nr5g_fapi_phy_instance_t p_phy_instance,
347 fapi_dl_pdcch_pdu_t * p_pdcch_pdu,
348 PDCIPDUStruct p_dci_pdu)
350 nr5g_fapi_stats_t *p_stats = NULL;
352 p_stats = &p_phy_instance->stats;
353 p_stats->fapi_stats.fapi_dl_tti_pdcch_pdus++;
355 p_dci_pdu->nBWPSize = p_pdcch_pdu->bwpSize;
356 p_dci_pdu->nBWPStart = p_pdcch_pdu->bwpStart;
357 p_dci_pdu->nSubcSpacing = p_pdcch_pdu->subCarrierSpacing;
358 p_dci_pdu->nCpType = p_pdcch_pdu->cyclicPrefix;
359 p_dci_pdu->nCCEStartIndex = p_pdcch_pdu->startSymbolIndex;
360 p_dci_pdu->nNrOfSymbols = p_pdcch_pdu->durationSymbols;
361 p_dci_pdu->nStartSymbolIndex = p_pdcch_pdu->startSymbolIndex;
362 p_dci_pdu->nFreqDomain[0] = ((uint32_t) p_pdcch_pdu->freqDomainResource[0] |
363 (((uint32_t) p_pdcch_pdu->freqDomainResource[1]) << 8) |
364 (((uint32_t) p_pdcch_pdu->freqDomainResource[2]) << 16) |
365 (((uint32_t) p_pdcch_pdu->freqDomainResource[3]) << 24));
366 p_dci_pdu->nFreqDomain[1] = ((uint32_t) p_pdcch_pdu->freqDomainResource[4] |
367 (((uint32_t) p_pdcch_pdu->freqDomainResource[5]) << 8));
368 p_dci_pdu->nCCEToREGType = p_pdcch_pdu->cceRegMappingType;
369 p_dci_pdu->nREGBundleSize = p_pdcch_pdu->regBundleSize;
370 p_dci_pdu->nInterleaveSize = p_pdcch_pdu->interleaverSize;
371 p_dci_pdu->nShift = p_pdcch_pdu->shiftIndex;
372 p_dci_pdu->nCoreSetType = p_pdcch_pdu->coreSetType;
373 p_dci_pdu->nCCEStartIndex = p_pdcch_pdu->dlDci[0].cceIndex;
374 p_dci_pdu->nAggrLvl = p_pdcch_pdu->dlDci[0].aggregationLevel;
375 p_dci_pdu->nScid = p_pdcch_pdu->dlDci[0].scramblingId;
376 p_dci_pdu->nID = p_pdcch_pdu->dlDci[0].scramblingId;
377 p_dci_pdu->nRNTIScramb = p_pdcch_pdu->dlDci[0].scramblingRnti;
378 p_dci_pdu->nRNTI = p_pdcch_pdu->dlDci[0].rnti;
379 p_dci_pdu->nTotalBits = p_pdcch_pdu->dlDci[0].payloadSizeBits;
381 if (USE_VENDOR_EPREXSSB != p_phy_instance->phy_config.use_vendor_EpreXSSB) {
382 p_dci_pdu->nEpreRatioOfPDCCHToSSB =
383 nr5g_fapi_calculate_nEpreRatioOfPDCCHToSSB(p_pdcch_pdu->
384 dlDci[0].beta_pdcch_1_0);
385 p_dci_pdu->nEpreRatioOfDmrsToSSB =
386 nr5g_fapi_calculate_nEpreRatioOfDmrsToSSB(p_pdcch_pdu->
387 dlDci[0].powerControlOffsetSS);
390 if (FAILURE == NR5G_FAPI_MEMCPY(p_dci_pdu->nDciBits,
391 sizeof(uint8_t) * MAX_DCI_BIT_BYTE_LEN,
392 p_pdcch_pdu->dlDci[0].payload,
393 sizeof(uint8_t) * MAX_DCI_BIT_BYTE_LEN)) {
394 NR5G_FAPI_LOG(ERROR_LOG, ("PDCCH: RNTI: %d -- DCI Bits copy error.",
395 p_pdcch_pdu->dlDci[0].rnti));
397 p_stats->iapi_stats.iapi_dl_tti_pdcch_pdus++;
400 static uint32_t get_rbg_index_mask_from_MSB(uint32_t nth_bit) {
401 #define DLSCH_RBG_INDEX_MSB 0x80000000u
402 return DLSCH_RBG_INDEX_MSB >> nth_bit;
405 /** @ingroup group_source_api_p7_fapi2phy_proc
407 * @param[in] rb_bitmap Pointer to FAPI DL resource block bitmap.
408 * @param[in] rbg_size Size of resource block group.
410 * @return Returns IAPI nRBGIndex
413 * Maps rbBitmap into nRBGIndex bits for pdsch.
416 uint32_t nr5g_fapi_calc_pdsch_rbg_index(
417 const uint8_t rb_bitmap[FAPI_RB_BITMAP_SIZE],
422 return nr5g_fapi_calc_rbg_index(
423 rb_bitmap, bwp_start, bwp_size, get_rbg_index_mask_from_MSB);
426 /** @ingroup group_nr5g_test_config
428 * @param[in] p_pdsch_pdu
429 * @param[out] p_dlsch_pdu
434 * This function fills FAPI PDSCH Pdu from IAPI DLSCHPDU
437 void nr5g_fapi_fill_pdsch_pdu(
438 p_nr5g_fapi_phy_instance_t p_phy_instance,
439 fapi_dl_pdsch_pdu_t * p_pdsch_pdu,
440 PDLSCHPDUStruct p_dlsch_pdu)
442 uint8_t resource_alloc_type, idx, port_index = 0u;
443 nr5g_fapi_stats_t *p_stats;
444 uint16_t bwp_start, bwp_size;
446 p_stats = &p_phy_instance->stats;
447 p_stats->fapi_stats.fapi_dl_tti_pdsch_pdus++;
449 bwp_size = p_dlsch_pdu->nBWPSize = p_pdsch_pdu->bwpSize;
450 bwp_start = p_dlsch_pdu->nBWPStart = p_pdsch_pdu->bwpStart;
451 p_dlsch_pdu->nSubcSpacing = p_pdsch_pdu->subCarrierSpacing;
452 p_dlsch_pdu->nCpType = p_pdsch_pdu->cyclicPrefix;
453 p_dlsch_pdu->nRNTI = p_pdsch_pdu->rnti;
454 p_dlsch_pdu->nUEId = p_pdsch_pdu->pdu_index;
456 // Codeword Information
457 p_dlsch_pdu->nNrOfCodeWords = p_pdsch_pdu->nrOfCodeWords;
458 p_dlsch_pdu->nMCS[0] = p_pdsch_pdu->cwInfo[0].mcsIndex;
459 p_dlsch_pdu->nMcsTable = p_pdsch_pdu->cwInfo[0].mcsTable;
460 p_dlsch_pdu->nRV[0] = p_pdsch_pdu->cwInfo[0].rvIndex;
461 p_dlsch_pdu->nTBSize[0] = p_pdsch_pdu->cwInfo[0].tbSize;
462 if (p_pdsch_pdu->nrOfCodeWords == 2) {
463 p_dlsch_pdu->nMCS[1] = p_pdsch_pdu->cwInfo[1].mcsIndex;
464 p_dlsch_pdu->nRV[1] = p_pdsch_pdu->cwInfo[1].rvIndex;
465 p_dlsch_pdu->nTBSize[1] = p_pdsch_pdu->cwInfo[1].tbSize;
467 //p_dlsch_pdu->nNrOfAntennaPorts = p_phy_instance->phy_config.n_nr_of_rx_ant;
468 p_dlsch_pdu->nNrOfLayers = p_pdsch_pdu->nrOfLayers;
469 p_dlsch_pdu->nNrOfAntennaPorts = p_dlsch_pdu->nNrOfLayers;
470 p_dlsch_pdu->nTransmissionScheme = p_pdsch_pdu->transmissionScheme;
471 p_dlsch_pdu->nDMRSConfigType = p_pdsch_pdu->dmrsConfigType;
472 p_dlsch_pdu->nNIDnSCID = p_pdsch_pdu->dlDmrsScramblingId;
473 p_dlsch_pdu->nNid = p_pdsch_pdu->dataScramblingId;
474 p_dlsch_pdu->nSCID = p_pdsch_pdu->scid;
477 (idx < FAPI_MAX_DMRS_PORTS && port_index < p_dlsch_pdu->nNrOfLayers);
479 if ((p_pdsch_pdu->dmrsPorts >> idx) && 0x0001) {
480 p_dlsch_pdu->nPortIndex[port_index++] = idx;
484 // Resource Allocation Information
485 resource_alloc_type =
486 p_dlsch_pdu->nResourceAllocType = p_pdsch_pdu->resourceAlloc;
487 if(FAPI_DL_RESOURCE_ALLOC_TYPE_0 == resource_alloc_type) {
488 p_dlsch_pdu->nRBGSize = nr5g_fapi_calc_n_rbg_size(bwp_size);
489 p_dlsch_pdu->nRBGIndex = nr5g_fapi_calc_pdsch_rbg_index(
490 p_pdsch_pdu->rbBitmap, bwp_start, bwp_size);
493 p_dlsch_pdu->nRBStart = p_pdsch_pdu->rbStart;
494 p_dlsch_pdu->nRBSize = p_pdsch_pdu->rbSize;
495 p_dlsch_pdu->nPMI = (p_pdsch_pdu->preCodingAndBeamforming.numPrgs > 0)
496 ? p_pdsch_pdu->preCodingAndBeamforming.pmi_bfi[0].pmIdx
498 p_dlsch_pdu->nVRBtoPRB = p_pdsch_pdu->vrbToPrbMapping;
499 p_dlsch_pdu->nStartSymbolIndex = p_pdsch_pdu->startSymbIndex;
500 p_dlsch_pdu->nNrOfSymbols = p_pdsch_pdu->nrOfSymbols;
501 p_dlsch_pdu->nNrOfCDMs = p_pdsch_pdu->numDmrsCdmGrpsNoData;
502 p_dlsch_pdu->nMappingType = p_pdsch_pdu->mappingType;
503 p_dlsch_pdu->nNrOfDMRSSymbols = p_pdsch_pdu->nrOfDmrsSymbols;
504 p_dlsch_pdu->nDMRSAddPos = p_pdsch_pdu->dmrsAddPos;
507 p_dlsch_pdu->nPTRSTimeDensity = p_pdsch_pdu->ptrsTimeDensity;
508 p_dlsch_pdu->nPTRSFreqDensity = p_pdsch_pdu->ptrsFreqDensity;
509 p_dlsch_pdu->nPTRSReOffset = p_pdsch_pdu->ptrsReOffset;
510 p_dlsch_pdu->nEpreRatioOfPDSCHToPTRS = p_pdsch_pdu->nEpreRatioOfPdschToPtrs;
512 if (USE_VENDOR_EPREXSSB != p_phy_instance->phy_config.use_vendor_EpreXSSB) {
513 p_dlsch_pdu->nEpreRatioOfDmrsToSSB =
514 nr5g_fapi_calculate_nEpreRatioOfDmrsToSSB(
515 p_pdsch_pdu->powerControlOffsetSS);
516 p_dlsch_pdu->nEpreRatioOfPDSCHToSSB =
517 nr5g_fapi_calculate_nEpreRatioOfPDSCHToSSB(
518 p_pdsch_pdu->powerControlOffset);
522 p_dlsch_pdu->nPTRSPresent = p_pdsch_pdu->pduBitMap & 0x0001;
523 p_dlsch_pdu->nNrOfPTRSPorts =
524 __builtin_popcount(p_pdsch_pdu->ptrsPortIndex);
525 for (idx = 0; idx < p_dlsch_pdu->nNrOfPTRSPorts &&
526 idx < MAX_DL_PER_UE_PTRS_PORT_NUM; idx++) {
527 p_dlsch_pdu->nPTRSPortIndex[idx] = idx;
531 p_dlsch_pdu->nNrOfDMRSAssPTRS[0] = 0x1;
532 p_dlsch_pdu->nNrOfDMRSAssPTRS[1] = 0x1;
533 p_dlsch_pdu->n1n2 = 0x201;
535 p_dlsch_pdu->nNrofTxRU = port_index;
537 p_stats->iapi_stats.iapi_dl_tti_pdsch_pdus++;
540 /** @ingroup group_nr5g_test_config
542 * @param[in] beta_pdcch_1_0
544 * @return uint16_t mapping
547 * This function maps FAPI to IAPI value range.
550 * Please refer 5G FAPI-IAPI Translator Module SW Design Document for details on
553 * |-----------------------------------------|
554 * | nEpreRatioOfPDCCHToSSb | beta_PDCCH_1_0 |
555 * |-----------------------------------------|
572 * |-----------------------------------------|
575 uint16_t nr5g_fapi_calculate_nEpreRatioOfPDCCHToSSB(
576 uint8_t beta_pdcch_1_0)
578 if (beta_pdcch_1_0 > 0 && beta_pdcch_1_0 <= 2) {
580 } else if (beta_pdcch_1_0 > 1 && beta_pdcch_1_0 < 17) {
581 return ((beta_pdcch_1_0 - 2) * 1000);
582 } else if (beta_pdcch_1_0 == 17) {
583 return ((beta_pdcch_1_0 - 3) * 1000);
589 /** @ingroup group_nr5g_test_config
591 * @param[in] power_control_offset_ss
593 * @return uint16_t mapping
596 * This function maps FAPI to IAPI value range.
599 * nEpreRatioOfDmrsToSSB: 1->20000, 0.001dB step, -6dB to 14dB
600 * powerControlOffsetSS: 0->3, 3dB step, -3dB to 6dB
601 * |----------------------------------------------|
602 * | nEpreRatioOfDmrsToSSB | powerControlOffsetSS |
603 * |----------------------------------------------|
608 * |----------------------------------------------|
611 uint16_t nr5g_fapi_calculate_nEpreRatioOfDmrsToSSB(
612 uint8_t power_control_offset_ss)
614 switch(power_control_offset_ss)
625 NR5G_FAPI_LOG(ERROR_LOG,
626 ("Unsupported value of power_control_offset_ss."));
632 /** @ingroup group_nr5g_test_config
634 * @param[in] power_control_offset
636 * @return uint16_t mapping
639 * This function maps FAPI to IAPI value range.
642 * nEpreRatioOfPDSCHToSSB: 1->20000, 0.001dB step, -6dB to 14dB
643 * powerControlOffset: 0->23, 1dB step, -8dB to 15dB
644 * |----------------------------------------------|
645 * | nEpreRatioOfPDSCHToSSB | powerControlOffset |
646 * |----------------------------------------------|
668 * |----------------------------------------------|
671 uint16_t nr5g_fapi_calculate_nEpreRatioOfPDSCHToSSB(uint8_t power_control_offset)
673 #define MAPPING_SIZE 24U
675 static const uint16_t power_control_offset_to_epre_ratio[MAPPING_SIZE] = {
677 1, 1, 1, 1000, 2000, 3000, 4000, 5000,
678 // 8 9 10 11 12 13 14 15
679 6000, 7000, 8000, 9000, 10000, 11000, 12000, 13000,
680 // 16 17 18 19 20 21 22 23
681 14000, 15000, 16000, 17000, 18000, 19000, 20000, 20000
684 if(MAPPING_SIZE > power_control_offset)
686 return power_control_offset_to_epre_ratio[power_control_offset];
690 NR5G_FAPI_LOG(ERROR_LOG,
691 ("Unsupported value of power_control_offset=%u.",
692 power_control_offset));
697 /** @ingroup group_nr5g_test_config
699 * @param[in] ssb_offset_point_a
700 * @param[in] sub_c_common
702 * @return uint8_t nSSBPrbOffset
705 * This function maps FAPI to IAPI value range.
707 * Please refer 5G FAPI-IAPI Translator Module SW Design Document for details on
711 uint8_t nr5g_fapi_calculate_nSSBPrbOffset(
712 uint16_t ssb_offset_point_a, uint8_t sub_c_common)
714 return ssb_offset_point_a/pow(2, sub_c_common);
717 /** @ingroup group_nr5g_test_config
719 * @param[in] p_dlsch_pdu
720 * @param[out] p_pdsch_pdu
725 * This function fills FAPI PDSCH Pdu from IAPI DLSCHPDU
728 void nr5g_fapi_fill_ssb_pdu(
729 p_nr5g_fapi_phy_instance_t p_phy_instance,
730 PBCHPDUStruct p_bch_pdu,
731 fapi_dl_ssb_pdu_t * p_ssb_pdu)
733 uint8_t *p_mib = (uint8_t *) & p_bch_pdu->nMIB[0];
734 uint8_t *payload = (uint8_t *) & p_ssb_pdu->bchPayload.bchPayload;
735 nr5g_fapi_stats_t *p_stats;
737 p_mib[0] = payload[0];
738 p_mib[1] = payload[1];
739 p_mib[2] = payload[2];
740 p_stats = &p_phy_instance->stats;
741 p_stats->fapi_stats.fapi_dl_tti_ssb_pdus++;
742 p_bch_pdu->nSSBSubcOffset = p_ssb_pdu->ssbSubCarrierOffset;
743 p_bch_pdu->nSSBPrbOffset =
744 nr5g_fapi_calculate_nSSBPrbOffset(p_ssb_pdu->ssbOffsetPointA,
745 p_phy_instance->phy_config.sub_c_common);
746 p_stats->iapi_stats.iapi_dl_tti_ssb_pdus++;
749 /** @ingroup group_nr5g_test_config
751 * @param[in] p_dlsch_pdu
752 * @param[out] p_pdsch_pdu
757 * This function fills FAPI PDSCH Pdu from IAPI DLSCHPDU
760 void nr5g_fapi_fill_csi_rs_pdu(
761 p_nr5g_fapi_phy_instance_t p_phy_instance,
762 fapi_dl_csi_rs_pdu_t * p_csi_rs_pdu,
763 PCSIRSPDUStruct p_CSIRS_pdu)
765 nr5g_fapi_stats_t *p_stats;
767 p_stats = &p_phy_instance->stats;
768 p_stats->fapi_stats.fapi_dl_tti_csi_rs_pdus++;
770 p_CSIRS_pdu->nBWPSize = p_csi_rs_pdu->bwpSize;
771 p_CSIRS_pdu->nBWPStart = p_csi_rs_pdu->bwpStart;
772 p_CSIRS_pdu->nCDMType = p_csi_rs_pdu->cdmType;
773 p_CSIRS_pdu->nCSIType = p_csi_rs_pdu->csiType;
774 p_CSIRS_pdu->nCpType = p_csi_rs_pdu->cyclicPrefix;
775 p_CSIRS_pdu->nFreqDensity = p_csi_rs_pdu->freqDensity;
776 p_CSIRS_pdu->nFreqDomain = p_csi_rs_pdu->freqDomain;
777 p_CSIRS_pdu->nNrOfRBs = p_csi_rs_pdu->nrOfRbs;
778 p_CSIRS_pdu->nScrambId = p_csi_rs_pdu->scramId;
779 p_CSIRS_pdu->nStartRB = p_csi_rs_pdu->startRb;
780 p_CSIRS_pdu->nSubcSpacing = p_csi_rs_pdu->subCarrierSpacing;
781 p_CSIRS_pdu->nSymbL0 = p_csi_rs_pdu->symbL0;
782 p_CSIRS_pdu->nSymbL1 = p_csi_rs_pdu->symbL1;
783 p_CSIRS_pdu->nRow = p_csi_rs_pdu->row;
784 // Not mapping the beamforming parameters
785 // p_CSIRS_pdu->powerControlOffset = p_csi_rs_pdu->powerControlOffset;
787 if (USE_VENDOR_EPREXSSB != p_phy_instance->phy_config.use_vendor_EpreXSSB) {
788 p_CSIRS_pdu->nEpreRatioToSSB = nr5g_fapi_calculate_nEpreRatioOfDmrsToSSB(p_csi_rs_pdu->powerControlOffsetSs);
791 p_stats->iapi_stats.iapi_dl_tti_csi_rs_pdus++;