1 /******************************************************************************
2 * Copyright (c) 2019 Intel.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 *******************************************************************************/
20 * This file consist of implementation of FAPI CONFIG.request message.
24 #include "nr5g_fapi_framework.h"
25 #include "gnb_l1_l2_api.h"
26 #include "nr5g_fapi_fapi2mac_api.h"
27 #include "nr5g_fapi_fapi2phy_api.h"
28 #include "nr5g_fapi_fapi2phy_p5_proc.h"
29 #include "nr5g_fapi_fapi2phy_p5_pvt_proc.h"
30 #include "nr5g_fapi_memory.h"
32 /** @ingroup group_source_api_p5_fapi2phy_proc
34 * @param[in] p_phy_instance Pointer to PHY instance.
35 * @param[in] p_fapi_req Pointer to FAPI CONFIG.request message structure.
36 * @param[in] p_fapi_vendor_msg Pointer to FAPI vendor message structure.
37 * @return Returns ::SUCCESS and ::FAILURE.
40 * This message instructs how the PHY should be configured.
42 * The *carrier_aggregation_level* parameter is a vendor specific
43 * configuration and programmed through Vendor Specific Message structure
44 * ::fapi_config_req_vendor_msg_t
47 uint8_t nr5g_fapi_config_request(
48 p_nr5g_fapi_phy_instance_t p_phy_instance,
49 fapi_config_req_t * p_fapi_req,
50 fapi_vendor_msg_t * p_fapi_vendor_msg)
52 PCONFIGREQUESTStruct p_ia_config_req;
53 PMAC2PHY_QUEUE_EL p_list_elem;
54 nr5g_fapi_stats_t *p_stats;
57 /* Below print is for better logging on console in radio mode. */
58 NR5G_FAPI_LOG(INFO_LOG, (""));
61 if (NULL == p_phy_instance) {
62 NR5G_FAPI_LOG(ERROR_LOG, ("[CONFIG.request] Invalid " "phy instance"));
65 p_stats = &p_phy_instance->stats;
66 p_stats->fapi_stats.fapi_config_req++;
68 if (NULL == p_fapi_req) {
69 NR5G_FAPI_LOG(ERROR_LOG, ("[CONFIG.request] Invalid fapi " "message"));
73 if (NULL == p_fapi_vendor_msg) {
74 NR5G_FAPI_LOG(ERROR_LOG, ("[CONFIG.request] Invalid fapi "
79 if (FAPI_STATE_RUNNING == p_phy_instance->state) {
80 NR5G_FAPI_LOG(ERROR_LOG, ("[CONFIG.request] Message not "
81 "supported by PHY in Running State"));
85 p_list_elem = nr5g_fapi_fapi2phy_create_api_list_elem((uint8_t)
86 MSG_TYPE_PHY_CONFIG_REQ, 1, (uint32_t) sizeof(CONFIGREQUESTStruct));
88 NR5G_FAPI_LOG(ERROR_LOG, ("[CONFIG.request] Unable to create "
89 "list element. Out of memory!!!"));
93 p_ia_config_req = (PCONFIGREQUESTStruct) (p_list_elem + 1);
94 NR5G_FAPI_MEMSET(p_ia_config_req, sizeof(CONFIGREQUESTStruct), 0,
95 sizeof(CONFIGREQUESTStruct));
96 p_ia_config_req->sMsgHdr.nMessageType = MSG_TYPE_PHY_CONFIG_REQ;
97 p_ia_config_req->sMsgHdr.nMessageLen =
98 (uint16_t) sizeof(CONFIGREQUESTStruct);
99 p_ia_config_req->nCarrierIdx = p_phy_instance->phy_id;
101 nr5g_fapi_config_req_to_phy_translation(p_phy_instance, p_fapi_req,
103 /* Vendor Parameters */
104 if (p_fapi_vendor_msg) {
105 p_ia_config_req->nCarrierAggregationLevel =
106 p_fapi_vendor_msg->config_req_vendor.carrier_aggregation_level;
107 p_ia_config_req->nGroupHopFlag =
108 p_fapi_vendor_msg->config_req_vendor.group_hop_flag;
109 p_ia_config_req->nSequenceHopFlag =
110 p_fapi_vendor_msg->config_req_vendor.sequence_hop_flag;
111 p_ia_config_req->nHoppingId =
112 p_fapi_vendor_msg->config_req_vendor.hopping_id;
115 p_ia_config_req->nDLFftSize =
116 nr5g_fapi_calc_fft_size(p_ia_config_req->nSubcCommon,
117 p_ia_config_req->nDLBandwidth);
118 p_ia_config_req->nULFftSize =
119 nr5g_fapi_calc_fft_size(p_ia_config_req->nSubcCommon,
120 p_ia_config_req->nULBandwidth);
121 p_ia_config_req->nPrachNrofRxRU = p_ia_config_req->nNrOfRxAnt;
123 /* Add element to send list */
124 nr5g_fapi_fapi2phy_add_to_api_list(p_list_elem);
126 p_stats->iapi_stats.iapi_config_req++;
127 NR5G_FAPI_LOG(INFO_LOG, ("[CONFIG.request][%d]", p_phy_instance->phy_id));
131 /** @ingroup group_source_api_p5_fapi2phy_proc
133 * @param[in] p_phy_instance Pointer to PHY instance.
134 * @param[in] p_fapi_req Pointer to FAPI CONFIG.request structure.
135 * @param[in] p_ia_config_req Pointer to IAPI CONFIG.request structure.
137 * @return Returns ::SUCCESS and ::FAILURE.
140 * This function converts FAPI CONFIG.request TLVs to IAPI Config.request
144 uint8_t nr5g_fapi_config_req_to_phy_translation(
145 p_nr5g_fapi_phy_instance_t p_phy_instance,
146 fapi_config_req_t * p_fapi_req,
147 PCONFIGREQUESTStruct p_ia_config_req)
149 fapi_uint32_tlv_t *tlvs = p_fapi_req->tlvs;
150 uint32_t i = 0, j = 0, k = 0;
151 uint32_t ss_pbch_power = 0;
153 uint32_t n_ssb_mask_idx = 0;
154 uint32_t n_beamid_idx = 0;
155 SLOTCONFIGStruct *p_sslot_Config = NULL;
157 while (i < p_fapi_req->number_of_tlvs) {
158 switch (tlvs[i].tl.tag) {
159 /***** Carrier Config *****/
160 case FAPI_DL_BANDWIDTH_TAG:
161 p_ia_config_req->nDLBandwidth =
162 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
165 case FAPI_DL_FREQUENCY_TAG:
166 p_ia_config_req->nDLAbsFrePointA = tlvs[i++].value;
169 /* FAPI_DL_K0_TAG - NA */
170 /* FAPI_DL_GRIDSIZE_TAG - NA */
172 case FAPI_NUM_TX_ANT_TAG:
173 p_ia_config_req->nNrOfTxAnt =
174 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length);
175 p_ia_config_req->nNrOfDLPorts =
176 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
179 case FAPI_UPLINK_BANDWIDTH_TAG:
180 p_ia_config_req->nULBandwidth =
181 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
184 case FAPI_UPLINK_FREQUENCY_TAG:
185 p_ia_config_req->nULAbsFrePointA = tlvs[i++].value;
188 /* FAPI_UL_K0_TAG - NA */
189 /* FAPI_UL_GRIDSIZE_TAG - NA */
191 case FAPI_NUM_RX_ANT_TAG:
192 p_phy_instance->phy_config.n_nr_of_rx_ant =
193 p_ia_config_req->nNrOfRxAnt =
194 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length);
195 p_ia_config_req->nNrOfULPorts =
196 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
199 /* FAPI_FREQUENCY_SHIFT_7P5_KHZ_TAG - NA */
201 /***** Cell Config *****/
202 case FAPI_PHY_CELL_ID_TAG:
203 p_phy_instance->phy_config.phy_cell_id =
204 p_ia_config_req->nPhyCellId =
205 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
208 case FAPI_FRAME_DUPLEX_TYPE_TAG:
209 p_ia_config_req->nFrameDuplexType =
210 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
213 /***** SSB Config *****/
214 case FAPI_SS_PBCH_POWER_TAG:
215 ss_pbch_power = tlvs[i++].value;
216 if (0 == ss_pbch_power) {
217 p_ia_config_req->nSSBPwr = 1;
218 } else if (54002 == ss_pbch_power) {
219 p_ia_config_req->nSSBPwr = 20000;
221 p_ia_config_req->nSSBPwr = ss_pbch_power - 54000;
225 /* FAPI_BCH_PAYLOAD_TAG - NA */
227 case FAPI_SCS_COMMON_TAG:
228 p_ia_config_req->nSubcCommon =
229 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
230 p_ia_config_req->nSSBSubcSpacing = p_ia_config_req->nSubcCommon;
233 /***** PRACH Config *****/
234 case FAPI_PRACH_SUBC_SPACING_TAG:
235 p_ia_config_req->nPrachSubcSpacing =
236 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
239 case FAPI_RESTRICTED_SET_CONFIG_TAG:
240 p_ia_config_req->nPrachRestrictSet =
241 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
244 case FAPI_NUM_PRACH_FD_OCCASIONS_TAG:
245 p_ia_config_req->nPrachFdm =
246 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
249 case FAPI_PRACH_CONFIG_INDEX_TAG:
250 p_ia_config_req->nPrachConfIdx =
251 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
254 case FAPI_PRACH_ROOT_SEQUENCE_INDEX_TAG:
255 p_ia_config_req->nPrachRootSeqIdx =
256 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
260 p_ia_config_req->nPrachFreqStart =
261 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
264 case FAPI_PRACH_ZERO_CORR_CONF_TAG:
265 p_ia_config_req->nPrachZeroCorrConf =
266 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
269 case FAPI_SSB_PER_RACH_TAG:
270 p_ia_config_req->nPrachSsbRach =
271 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
273 /***** SSB Table *****/
274 case FAPI_SSB_OFFSET_POINT_A_TAG:
275 p_ia_config_req->nSSBPrbOffset =
276 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length) / (pow(2,
277 p_ia_config_req->nSubcCommon));
278 p_phy_instance->phy_config.nSSBPrbOffset =
279 p_ia_config_req->nSSBPrbOffset;
282 case FAPI_SSB_PERIOD_TAG:
283 p_ia_config_req->nSSBPeriod =
284 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
287 case FAPI_SSB_SUBCARRIER_OFFSET_TAG:
288 p_ia_config_req->nSSBSubcOffset =
289 (tlvs[i].value >> tlvs[i++].tl.length);
293 mib = tlvs[i++].value;
294 p_ia_config_req->nMIB[0] = (uint8_t) (mib >> 24);
295 p_ia_config_req->nMIB[1] = (uint8_t) (mib >> 16);
296 p_ia_config_req->nMIB[2] = (uint8_t) (mib >> 8);
299 case FAPI_DMRS_TYPE_A_POS_TAG:
300 p_ia_config_req->nDMRSTypeAPos =
301 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
304 case FAPI_SSB_MASK_TAG:
305 if (n_ssb_mask_idx < 2) {
306 p_ia_config_req->nSSBMask[n_ssb_mask_idx++] =
311 case FAPI_BEAM_ID_TAG:
312 if (n_beamid_idx < 64) {
313 p_ia_config_req->nBeamId[n_beamid_idx++] =
314 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
318 /* FAPI_SS_PBCH_MULTIPLE_CARRIERS_IN_A_BAND_TAG - NA */
319 /* FAPI_MULTIPLE_CELLS_SS_PBCH_IN_A_CARRIER_TAG - NA */
321 /***** TDD Table *****/
322 case FAPI_TDD_PERIOD_TAG:
323 p_ia_config_req->nTddPeriod =
324 nr5g_fapi_calc_phy_tdd_period((uint8_t)
325 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length),
326 p_ia_config_req->nSubcCommon);
329 case FAPI_SLOT_CONFIG_TAG:
330 for (j = 0; j < p_ia_config_req->nTddPeriod; j++) {
331 p_sslot_Config = &p_ia_config_req->sSlotConfig[j];
332 for (k = 0; k < MAX_NUM_OF_SYMBOL_PER_SLOT; k++) {
333 p_sslot_Config->nSymbolType[k] =
334 GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
339 /***** Measurement Config *****/
340 /* FAPI_RSSI_MEASUREMENT_TAG - NA */
342 /***** Beamforming Table *****/
344 /***** Precoding Table *****/
347 NR5G_FAPI_LOG(ERROR_LOG, ("[CONFIG.request] Unsupported "
348 "TLV tag : 0x%x", tlvs[i].tl.tag));
356 /** @ingroup group_source_api_p5_fapi2phy_proc
358 * @param[in] fapi_tdd_period DL UL Transmission Periodicity.
359 * @param[in] n_subc_common subcarrierSpacing for common.
361 * @return IAPI *nTddPeriod*.
364 * This function converts FAPI *TddPeriod* to IAPI *nTddPeriod*
368 uint8_t nr5g_fapi_calc_phy_tdd_period(
369 uint8_t fapi_tdd_period,
370 uint8_t n_subc_common)
372 switch (n_subc_common) {
375 nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_0
379 nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_1
383 nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_2
387 nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_3
396 /** @ingroup group_source_api_p5_fapi2phy_proc
398 * @param[in] fapi_tdd_period DL UL Transmission Periodicity.
400 * @return IAPI *nTddPeriod*.
403 * This function converts FAPI *TddPeriod* to IAPI *nTddPeriod*
404 * structure based on *subCarrierSpacingCommon - 0*.
407 uint8_t nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_0(
408 uint8_t fapi_tdd_period)
410 if (2 == fapi_tdd_period)
412 else if (4 == fapi_tdd_period)
414 else if (6 == fapi_tdd_period)
416 else if (7 == fapi_tdd_period)
424 /** @ingroup group_source_api_p5_fapi2phy_proc
426 * @param[in] fapi_tdd_period DL UL Transmission Periodicity.
428 * @return IAPI *nTddPeriod*.
431 * This function converts FAPI *TddPeriod* to IAPI *nTddPeriod*
432 * structure based on *subCarrierSpacingCommon - 1*.
435 uint8_t nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_1(
436 uint8_t fapi_tdd_period)
438 if (0 == fapi_tdd_period)
440 else if (2 == fapi_tdd_period)
442 else if (4 == fapi_tdd_period)
444 else if (5 == fapi_tdd_period)
446 else if (6 == fapi_tdd_period)
448 else if (7 == fapi_tdd_period)
456 /** @ingroup group_source_api_p5_fapi2phy_proc
458 * @param[in] fapi_tdd_period DL UL Transmission Periodicity.
460 * @return IAPI *nTddPeriod*.
463 * This function converts FAPI *TddPeriod* to IAPI *nTddPeriod*
464 * structure based on *subCarrierSpacingCommon - 2*.
467 uint8_t nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_2(
468 uint8_t fapi_tdd_period)
470 if (0 == fapi_tdd_period)
472 else if (2 == fapi_tdd_period)
474 else if (3 == fapi_tdd_period)
476 else if (4 == fapi_tdd_period)
478 else if (5 == fapi_tdd_period)
480 else if (6 == fapi_tdd_period)
482 else if (7 == fapi_tdd_period)
490 /** @ingroup group_source_api_p5_fapi2phy_proc
492 * @param[in] fapi_tdd_period DL UL Transmission Periodicity.
494 * @return IAPI *nTddPeriod*.
497 * This function converts FAPI *TddPeriod* to IAPI *nTddPeriod*
498 * structure based on *subCarrierSpacingCommon - 3*.
501 uint8_t nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_3(
502 uint8_t fapi_tdd_period)
504 if (0 == fapi_tdd_period)
506 else if (1 == fapi_tdd_period)
508 else if (2 == fapi_tdd_period)
510 else if (3 == fapi_tdd_period)
512 else if (4 == fapi_tdd_period)
514 else if (5 == fapi_tdd_period)
516 else if (6 == fapi_tdd_period)
518 else if (7 == fapi_tdd_period)
526 /** @ingroup group_source_api_p5_fapi2phy_proc
528 * @param[in] nSubcCommon Sub carrier spacing
529 * @param[in] nDLBandwidth/ nULBandwidth Sub carrier spacing
532 * @return IAPI FFT size for DL UL
535 * This function converts FAPI *TddPeriod* to IAPI *nTddPeriod*
536 * structure based on *subCarrierSpacingCommon - 3*.
539 uint16_t nr5g_fapi_calc_fft_size(
540 uint8_t sub_carrier_common,
543 if (FAPI_SUBCARRIER_SPACING_15 == sub_carrier_common) {
544 if (FAPI_BANDWIDTH_5_MHZ == bw)
545 return FAPI_FFT_SIZE_512;
546 else if (FAPI_BANDWIDTH_10_MHZ == bw)
547 return FAPI_FFT_SIZE_1024;
548 else if ((FAPI_BANDWIDTH_15_MHZ == bw) || (FAPI_BANDWIDTH_20_MHZ == bw))
549 return FAPI_FFT_SIZE_2048;
550 else if ((FAPI_BANDWIDTH_25_MHZ == bw) || (FAPI_BANDWIDTH_30_MHZ == bw)
551 || (FAPI_BANDWIDTH_40_MHZ == bw) || (FAPI_BANDWIDTH_50_MHZ == bw))
552 return FAPI_FFT_SIZE_4096;
553 } else if (FAPI_SUBCARRIER_SPACING_30 == sub_carrier_common) {
554 if ((FAPI_BANDWIDTH_5_MHZ == bw) || (FAPI_BANDWIDTH_10_MHZ == bw))
555 return FAPI_FFT_SIZE_512;
556 else if ((FAPI_BANDWIDTH_15_MHZ == bw) || (FAPI_BANDWIDTH_20_MHZ == bw))
557 return FAPI_FFT_SIZE_1024;
558 else if ((FAPI_BANDWIDTH_25_MHZ == bw) || (FAPI_BANDWIDTH_30_MHZ == bw)
559 || (FAPI_BANDWIDTH_40_MHZ == bw) || (FAPI_BANDWIDTH_50_MHZ == bw))
560 return FAPI_FFT_SIZE_2048;
561 else if ((FAPI_BANDWIDTH_60_MHZ == bw) || (FAPI_BANDWIDTH_70_MHZ == bw)
562 || (FAPI_BANDWIDTH_80_MHZ == bw) || ((FAPI_BANDWIDTH_90_MHZ == bw))
563 || (FAPI_BANDWIDTH_100_MHZ == bw))
564 return FAPI_FFT_SIZE_4096;
565 } else if (FAPI_SUBCARRIER_SPACING_60 == sub_carrier_common) {
566 if ((FAPI_BANDWIDTH_10_MHZ == bw) || (FAPI_BANDWIDTH_15_MHZ == bw) ||
567 (FAPI_BANDWIDTH_20_MHZ == bw) || (FAPI_BANDWIDTH_25_MHZ == bw))
568 return FAPI_FFT_SIZE_512;
569 else if ((FAPI_BANDWIDTH_30_MHZ == bw) || (FAPI_BANDWIDTH_40_MHZ == bw)
570 || (FAPI_BANDWIDTH_50_MHZ == bw))
571 return FAPI_FFT_SIZE_1024;
572 else if ((FAPI_BANDWIDTH_60_MHZ == bw) || (FAPI_BANDWIDTH_70_MHZ == bw)
573 || (FAPI_BANDWIDTH_80_MHZ == bw) || (FAPI_BANDWIDTH_90_MHZ == bw) ||
574 (FAPI_BANDWIDTH_100_MHZ == bw))
575 return FAPI_FFT_SIZE_2048;
576 else if (FAPI_BANDWIDTH_200_MHZ == bw)
577 return FAPI_FFT_SIZE_4096;
578 } else if (FAPI_SUBCARRIER_SPACING_120 == sub_carrier_common) {
579 if (FAPI_BANDWIDTH_50_MHZ == bw)
580 return FAPI_FFT_SIZE_512;
581 else if (FAPI_BANDWIDTH_100_MHZ == bw)
582 return FAPI_FFT_SIZE_1024;
583 else if (FAPI_BANDWIDTH_200_MHZ == bw)
584 return FAPI_FFT_SIZE_2048;
585 else if (FAPI_BANDWIDTH_400_MHZ == bw)
586 return FAPI_FFT_SIZE_4096;