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 CONFIG.request message.
25 #include "nr5g_fapi_framework.h"
26 #include "gnb_l1_l2_api.h"
27 #include "nr5g_fapi_fapi2mac_api.h"
28 #include "nr5g_fapi_fapi2phy_api.h"
29 #include "nr5g_fapi_fapi2phy_p5_proc.h"
30 #include "nr5g_fapi_fapi2phy_p5_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 CONFIG.request message structure.
37 * @param[in] p_fapi_vendor_msg Pointer to FAPI vendor message structure.
38 * @return Returns ::SUCCESS and ::FAILURE.
41 * This message instructs how the PHY should be configured.
43 * The *carrier_aggregation_level* parameter is a vendor specific
44 * configuration and programmed through Vendor Specific Message structure
45 * ::fapi_config_req_vendor_msg_t
48 uint8_t nr5g_fapi_config_request(
49 p_nr5g_fapi_phy_instance_t p_phy_instance,
50 fapi_config_req_t * p_fapi_req,
51 fapi_vendor_msg_t * p_fapi_vendor_msg)
53 PCONFIGREQUESTStruct p_ia_config_req;
54 PMAC2PHY_QUEUE_EL p_list_elem;
55 nr5g_fapi_stats_t *p_stats;
58 /* Below print is for better logging on console in radio mode. */
59 NR5G_FAPI_LOG(INFO_LOG, (""));
62 if (NULL == p_phy_instance) {
63 NR5G_FAPI_LOG(ERROR_LOG, ("[CONFIG.request] Invalid " "phy instance"));
66 p_stats = &p_phy_instance->stats;
67 p_stats->fapi_stats.fapi_config_req++;
69 if (NULL == p_fapi_req) {
70 NR5G_FAPI_LOG(ERROR_LOG, ("[CONFIG.request] Invalid fapi " "message"));
74 if (NULL == p_fapi_vendor_msg) {
75 NR5G_FAPI_LOG(ERROR_LOG, ("[CONFIG.request] Invalid fapi "
80 if (FAPI_STATE_RUNNING == p_phy_instance->state) {
81 NR5G_FAPI_LOG(ERROR_LOG, ("[CONFIG.request] Message not "
82 "supported by PHY in Running State"));
86 p_list_elem = nr5g_fapi_fapi2phy_create_api_list_elem((uint8_t)
87 MSG_TYPE_PHY_CONFIG_REQ, 1, (uint32_t) sizeof(CONFIGREQUESTStruct));
89 NR5G_FAPI_LOG(ERROR_LOG, ("[CONFIG.request] Unable to create "
90 "list element. Out of memory!!!"));
94 p_ia_config_req = (PCONFIGREQUESTStruct) (p_list_elem + 1);
95 NR5G_FAPI_MEMSET(p_ia_config_req, sizeof(CONFIGREQUESTStruct), 0,
96 sizeof(CONFIGREQUESTStruct));
97 p_ia_config_req->sMsgHdr.nMessageType = MSG_TYPE_PHY_CONFIG_REQ;
98 p_ia_config_req->sMsgHdr.nMessageLen =
99 (uint16_t) sizeof(CONFIGREQUESTStruct);
100 p_ia_config_req->nCarrierIdx = p_phy_instance->phy_id;
102 nr5g_fapi_config_req_to_phy_translation(p_phy_instance, p_fapi_req,
104 /* Vendor Parameters */
105 if (p_fapi_vendor_msg) {
106 p_ia_config_req->nCarrierAggregationLevel =
107 p_fapi_vendor_msg->config_req_vendor.carrier_aggregation_level;
108 p_ia_config_req->nGroupHopFlag =
109 p_fapi_vendor_msg->config_req_vendor.group_hop_flag;
110 p_ia_config_req->nSequenceHopFlag =
111 p_fapi_vendor_msg->config_req_vendor.sequence_hop_flag;
112 p_ia_config_req->nHoppingId =
113 p_fapi_vendor_msg->config_req_vendor.hopping_id;
116 p_ia_config_req->nDLFftSize =
117 nr5g_fapi_calc_fft_size(p_ia_config_req->nSubcCommon,
118 p_ia_config_req->nDLBandwidth);
119 p_ia_config_req->nULFftSize =
120 nr5g_fapi_calc_fft_size(p_ia_config_req->nSubcCommon,
121 p_ia_config_req->nULBandwidth);
122 p_ia_config_req->nPrachNrofRxRU = p_ia_config_req->nNrOfRxAnt;
124 /* Add element to send list */
125 nr5g_fapi_fapi2phy_add_to_api_list(p_list_elem);
127 p_stats->iapi_stats.iapi_config_req++;
128 NR5G_FAPI_LOG(INFO_LOG, ("[CONFIG.request][%d]", p_phy_instance->phy_id));
132 /** @ingroup group_source_api_p5_fapi2phy_proc
134 * @param[in] p_phy_instance Pointer to PHY instance.
135 * @param[in] p_fapi_req Pointer to FAPI CONFIG.request structure.
136 * @param[in] p_ia_config_req Pointer to IAPI CONFIG.request structure.
138 * @return Returns ::SUCCESS and ::FAILURE.
141 * This function converts FAPI CONFIG.request TLVs to IAPI Config.request
145 uint8_t nr5g_fapi_config_req_to_phy_translation(
146 p_nr5g_fapi_phy_instance_t p_phy_instance,
147 fapi_config_req_t * p_fapi_req,
148 PCONFIGREQUESTStruct p_ia_config_req)
150 fapi_uint32_tlv_t *tlvs = p_fapi_req->tlvs;
151 uint32_t i = 0, j = 0, k = 0;
152 uint32_t ss_pbch_power = 0;
154 uint32_t n_ssb_mask_idx = 0;
155 uint32_t n_beamid_idx = 0;
156 SLOTCONFIGStruct *p_sslot_Config = NULL;
158 while (i < p_fapi_req->number_of_tlvs) {
159 switch (tlvs[i].tl.tag) {
160 /***** Carrier Config *****/
161 case FAPI_DL_BANDWIDTH_TAG:
162 p_ia_config_req->nDLBandwidth =
163 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
166 case FAPI_DL_FREQUENCY_TAG:
167 p_ia_config_req->nDLAbsFrePointA = tlvs[i++].value;
170 /* FAPI_DL_K0_TAG - NA */
171 /* FAPI_DL_GRIDSIZE_TAG - NA */
173 case FAPI_NUM_TX_ANT_TAG:
174 p_ia_config_req->nNrOfTxAnt =
175 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length);
176 p_ia_config_req->nNrOfDLPorts =
177 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
180 case FAPI_UPLINK_BANDWIDTH_TAG:
181 p_ia_config_req->nULBandwidth =
182 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
185 case FAPI_UPLINK_FREQUENCY_TAG:
186 p_ia_config_req->nULAbsFrePointA = tlvs[i++].value;
189 /* FAPI_UL_K0_TAG - NA */
190 /* FAPI_UL_GRIDSIZE_TAG - NA */
192 case FAPI_NUM_RX_ANT_TAG:
193 p_phy_instance->phy_config.n_nr_of_rx_ant =
194 p_ia_config_req->nNrOfRxAnt =
195 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length);
196 p_ia_config_req->nNrOfULPorts =
197 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
200 /* FAPI_FREQUENCY_SHIFT_7P5_KHZ_TAG - NA */
202 /***** Cell Config *****/
203 case FAPI_PHY_CELL_ID_TAG:
204 p_phy_instance->phy_config.phy_cell_id =
205 p_ia_config_req->nPhyCellId =
206 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
209 case FAPI_FRAME_DUPLEX_TYPE_TAG:
210 p_ia_config_req->nFrameDuplexType =
211 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
214 /***** SSB Config *****/
215 case FAPI_SS_PBCH_POWER_TAG:
216 ss_pbch_power = tlvs[i++].value;
217 if (0 == ss_pbch_power) {
218 p_ia_config_req->nSSBPwr = 1;
219 } else if (54002 == ss_pbch_power) {
220 p_ia_config_req->nSSBPwr = 20000;
222 p_ia_config_req->nSSBPwr = ss_pbch_power - 54000;
226 /* FAPI_BCH_PAYLOAD_TAG - NA */
228 case FAPI_SCS_COMMON_TAG:
229 p_ia_config_req->nSubcCommon =
230 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
231 p_ia_config_req->nSSBSubcSpacing = p_ia_config_req->nSubcCommon;
234 /***** PRACH Config *****/
235 case FAPI_PRACH_SUBC_SPACING_TAG:
236 p_ia_config_req->nPrachSubcSpacing =
237 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
240 case FAPI_RESTRICTED_SET_CONFIG_TAG:
241 p_ia_config_req->nPrachRestrictSet =
242 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
245 case FAPI_NUM_PRACH_FD_OCCASIONS_TAG:
246 p_ia_config_req->nPrachFdm =
247 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
250 case FAPI_PRACH_CONFIG_INDEX_TAG:
251 p_ia_config_req->nPrachConfIdx =
252 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
255 case FAPI_PRACH_ROOT_SEQUENCE_INDEX_TAG:
256 p_ia_config_req->nPrachRootSeqIdx =
257 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
261 p_ia_config_req->nPrachFreqStart =
262 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
265 case FAPI_PRACH_ZERO_CORR_CONF_TAG:
266 p_ia_config_req->nPrachZeroCorrConf =
267 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
270 case FAPI_SSB_PER_RACH_TAG:
271 p_ia_config_req->nPrachSsbRach =
272 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
274 /***** SSB Table *****/
275 case FAPI_SSB_OFFSET_POINT_A_TAG:
276 p_ia_config_req->nSSBPrbOffset =
277 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length) / (pow(2,
278 p_ia_config_req->nSubcCommon));
281 case FAPI_SSB_PERIOD_TAG:
282 p_ia_config_req->nSSBPeriod =
283 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
286 case FAPI_SSB_SUBCARRIER_OFFSET_TAG:
287 p_ia_config_req->nSSBSubcOffset =
288 (tlvs[i].value >> tlvs[i++].tl.length);
292 mib = tlvs[i++].value;
293 p_ia_config_req->nMIB[0] = (uint8_t) (mib >> 24);
294 p_ia_config_req->nMIB[1] = (uint8_t) (mib >> 16);
295 p_ia_config_req->nMIB[2] = (uint8_t) (mib >> 8);
298 case FAPI_DMRS_TYPE_A_POS_TAG:
299 p_ia_config_req->nDMRSTypeAPos =
300 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
303 case FAPI_SSB_MASK_TAG:
304 if (n_ssb_mask_idx < 2) {
305 p_ia_config_req->nSSBMask[n_ssb_mask_idx++] =
310 case FAPI_BEAM_ID_TAG:
311 if (n_beamid_idx < 64) {
312 p_ia_config_req->nBeamId[n_beamid_idx++] =
313 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
317 /* FAPI_SS_PBCH_MULTIPLE_CARRIERS_IN_A_BAND_TAG - NA */
318 /* FAPI_MULTIPLE_CELLS_SS_PBCH_IN_A_CARRIER_TAG - NA */
320 /***** TDD Table *****/
321 case FAPI_TDD_PERIOD_TAG:
322 p_ia_config_req->nTddPeriod =
323 nr5g_fapi_calc_phy_tdd_period((uint8_t)
324 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length),
325 p_ia_config_req->nSubcCommon);
328 case FAPI_SLOT_CONFIG_TAG:
329 for (j = 0; j < p_ia_config_req->nTddPeriod; j++) {
330 p_sslot_Config = &p_ia_config_req->sSlotConfig[j];
331 for (k = 0; k < MAX_NUM_OF_SYMBOL_PER_SLOT; k++) {
332 p_sslot_Config->nSymbolType[k] =
333 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
338 /***** Measurement Config *****/
339 /* FAPI_RSSI_MEASUREMENT_TAG - NA */
341 /***** Beamforming Table *****/
343 /***** Precoding Table *****/
346 NR5G_FAPI_LOG(ERROR_LOG, ("[CONFIG.request] Unsupported "
347 "TLV tag : 0x%x", tlvs[i].tl.tag));
355 /** @ingroup group_source_api_p5_fapi2phy_proc
357 * @param[in] fapi_tdd_period DL UL Transmission Periodicity.
358 * @param[in] n_subc_common subcarrierSpacing for common.
360 * @return IAPI *nTddPeriod*.
363 * This function converts FAPI *TddPeriod* to IAPI *nTddPeriod*
367 uint8_t nr5g_fapi_calc_phy_tdd_period(
368 uint8_t fapi_tdd_period,
369 uint8_t n_subc_common)
371 switch (n_subc_common) {
374 nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_0
378 nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_1
382 nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_2
386 nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_3
395 /** @ingroup group_source_api_p5_fapi2phy_proc
397 * @param[in] fapi_tdd_period DL UL Transmission Periodicity.
399 * @return IAPI *nTddPeriod*.
402 * This function converts FAPI *TddPeriod* to IAPI *nTddPeriod*
403 * structure based on *subCarrierSpacingCommon - 0*.
406 uint8_t nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_0(
407 uint8_t fapi_tdd_period)
409 if (2 == fapi_tdd_period)
411 else if (4 == fapi_tdd_period)
413 else if (6 == fapi_tdd_period)
415 else if (7 == fapi_tdd_period)
423 /** @ingroup group_source_api_p5_fapi2phy_proc
425 * @param[in] fapi_tdd_period DL UL Transmission Periodicity.
427 * @return IAPI *nTddPeriod*.
430 * This function converts FAPI *TddPeriod* to IAPI *nTddPeriod*
431 * structure based on *subCarrierSpacingCommon - 1*.
434 uint8_t nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_1(
435 uint8_t fapi_tdd_period)
437 if (0 == fapi_tdd_period)
439 else if (2 == fapi_tdd_period)
441 else if (4 == fapi_tdd_period)
443 else if (5 == fapi_tdd_period)
445 else if (6 == fapi_tdd_period)
447 else if (7 == fapi_tdd_period)
455 /** @ingroup group_source_api_p5_fapi2phy_proc
457 * @param[in] fapi_tdd_period DL UL Transmission Periodicity.
459 * @return IAPI *nTddPeriod*.
462 * This function converts FAPI *TddPeriod* to IAPI *nTddPeriod*
463 * structure based on *subCarrierSpacingCommon - 2*.
466 uint8_t nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_2(
467 uint8_t fapi_tdd_period)
469 if (0 == fapi_tdd_period)
471 else if (2 == fapi_tdd_period)
473 else if (3 == fapi_tdd_period)
475 else if (4 == fapi_tdd_period)
477 else if (5 == fapi_tdd_period)
479 else if (6 == fapi_tdd_period)
481 else if (7 == fapi_tdd_period)
489 /** @ingroup group_source_api_p5_fapi2phy_proc
491 * @param[in] fapi_tdd_period DL UL Transmission Periodicity.
493 * @return IAPI *nTddPeriod*.
496 * This function converts FAPI *TddPeriod* to IAPI *nTddPeriod*
497 * structure based on *subCarrierSpacingCommon - 3*.
500 uint8_t nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_3(
501 uint8_t fapi_tdd_period)
503 if (0 == fapi_tdd_period)
505 else if (1 == fapi_tdd_period)
507 else if (2 == fapi_tdd_period)
509 else if (3 == fapi_tdd_period)
511 else if (4 == fapi_tdd_period)
513 else if (5 == fapi_tdd_period)
515 else if (6 == fapi_tdd_period)
517 else if (7 == fapi_tdd_period)
525 /** @ingroup group_source_api_p5_fapi2phy_proc
527 * @param[in] nSubcCommon Sub carrier spacing
528 * @param[in] nDLBandwidth/ nULBandwidth Sub carrier spacing
531 * @return IAPI FFT size for DL UL
534 * This function converts FAPI *TddPeriod* to IAPI *nTddPeriod*
535 * structure based on *subCarrierSpacingCommon - 3*.
538 uint16_t nr5g_fapi_calc_fft_size(
539 uint8_t sub_carrier_common,
542 if (FAPI_SUBCARRIER_SPACING_15 == sub_carrier_common) {
543 if (FAPI_BANDWIDTH_5_MHZ == bw)
544 return FAPI_FFT_SIZE_512;
545 else if (FAPI_BANDWIDTH_10_MHZ == bw)
546 return FAPI_FFT_SIZE_1024;
547 else if ((FAPI_BANDWIDTH_15_MHZ == bw) || (FAPI_BANDWIDTH_20_MHZ == bw))
548 return FAPI_FFT_SIZE_2048;
549 else if ((FAPI_BANDWIDTH_25_MHZ == bw) || (FAPI_BANDWIDTH_30_MHZ == bw)
550 || (FAPI_BANDWIDTH_40_MHZ == bw) || (FAPI_BANDWIDTH_50_MHZ == bw))
551 return FAPI_FFT_SIZE_4096;
552 } else if (FAPI_SUBCARRIER_SPACING_30 == sub_carrier_common) {
553 if ((FAPI_BANDWIDTH_5_MHZ == bw) || (FAPI_BANDWIDTH_10_MHZ == bw))
554 return FAPI_FFT_SIZE_512;
555 else if ((FAPI_BANDWIDTH_15_MHZ == bw) || (FAPI_BANDWIDTH_20_MHZ == bw))
556 return FAPI_FFT_SIZE_1024;
557 else if ((FAPI_BANDWIDTH_25_MHZ == bw) || (FAPI_BANDWIDTH_30_MHZ == bw)
558 || (FAPI_BANDWIDTH_40_MHZ == bw) || (FAPI_BANDWIDTH_50_MHZ == bw))
559 return FAPI_FFT_SIZE_2048;
560 else if ((FAPI_BANDWIDTH_60_MHZ == bw) || (FAPI_BANDWIDTH_70_MHZ == bw)
561 || (FAPI_BANDWIDTH_80_MHZ == bw) || ((FAPI_BANDWIDTH_90_MHZ == bw))
562 || (FAPI_BANDWIDTH_100_MHZ == bw))
563 return FAPI_FFT_SIZE_4096;
564 } else if (FAPI_SUBCARRIER_SPACING_60 == sub_carrier_common) {
565 if ((FAPI_BANDWIDTH_10_MHZ == bw) || (FAPI_BANDWIDTH_15_MHZ == bw) ||
566 (FAPI_BANDWIDTH_20_MHZ == bw) || (FAPI_BANDWIDTH_25_MHZ == bw))
567 return FAPI_FFT_SIZE_512;
568 else if ((FAPI_BANDWIDTH_30_MHZ == bw) || (FAPI_BANDWIDTH_40_MHZ == bw)
569 || (FAPI_BANDWIDTH_50_MHZ == bw))
570 return FAPI_FFT_SIZE_1024;
571 else if ((FAPI_BANDWIDTH_60_MHZ == bw) || (FAPI_BANDWIDTH_70_MHZ == bw)
572 || (FAPI_BANDWIDTH_80_MHZ == bw) || (FAPI_BANDWIDTH_90_MHZ == bw) ||
573 (FAPI_BANDWIDTH_100_MHZ == bw))
574 return FAPI_FFT_SIZE_2048;
575 else if (FAPI_BANDWIDTH_200_MHZ == bw)
576 return FAPI_FFT_SIZE_4096;
577 } else if (FAPI_SUBCARRIER_SPACING_120 == sub_carrier_common) {
578 if (FAPI_BANDWIDTH_50_MHZ == bw)
579 return FAPI_FFT_SIZE_512;
580 else if (FAPI_BANDWIDTH_100_MHZ == bw)
581 return FAPI_FFT_SIZE_1024;
582 else if (FAPI_BANDWIDTH_200_MHZ == bw)
583 return FAPI_FFT_SIZE_2048;
584 else if (FAPI_BANDWIDTH_400_MHZ == bw)
585 return FAPI_FFT_SIZE_4096;