1 /******************************************************************************
2 * Copyright (c) 2021 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_mac_phy_api.h"
25 #include "nr5g_fapi_framework.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(
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;
114 p_ia_config_req->nUrllcCapable =
115 p_fapi_vendor_msg->config_req_vendor.urllc_capable;
116 p_ia_config_req->nUrllcMiniSlotMask =
117 p_fapi_vendor_msg->config_req_vendor.urllc_mini_slot_mask;
118 p_ia_config_req->nPrachNrofRxRU =
119 p_fapi_vendor_msg->config_req_vendor.prach_nr_of_rx_ru;
120 p_ia_config_req->nNrOfDLPorts =
121 p_fapi_vendor_msg->config_req_vendor.nr_of_dl_ports;
122 p_ia_config_req->nNrOfULPorts =
123 p_fapi_vendor_msg->config_req_vendor.nr_of_ul_ports;
124 p_ia_config_req->nSSBSubcSpacing =
125 p_fapi_vendor_msg->config_req_vendor.ssb_subc_spacing;
126 p_phy_instance->phy_config.use_vendor_EpreXSSB =
127 p_fapi_vendor_msg->config_req_vendor.use_vendor_EpreXSSB;
130 p_ia_config_req->nDLFftSize =
131 nr5g_fapi_calc_fft_size(p_ia_config_req->nSubcCommon,
132 p_ia_config_req->nDLBandwidth);
133 p_ia_config_req->nULFftSize =
134 nr5g_fapi_calc_fft_size(p_ia_config_req->nSubcCommon,
135 p_ia_config_req->nULBandwidth);
137 /* Add element to send list */
138 nr5g_fapi_fapi2phy_add_to_api_list(is_urllc, p_list_elem);
140 p_stats->iapi_stats.iapi_config_req++;
141 NR5G_FAPI_LOG(INFO_LOG, ("[CONFIG.request][%d]", p_phy_instance->phy_id));
145 /** @ingroup group_source_api_p5_fapi2phy_proc
147 * @param[in] p_phy_instance Pointer to PHY instance.
148 * @param[in] p_fapi_req Pointer to FAPI CONFIG.request structure.
149 * @param[in] p_ia_config_req Pointer to IAPI CONFIG.request structure.
151 * @return Returns ::SUCCESS and ::FAILURE.
154 * This function converts FAPI CONFIG.request TLVs to IAPI Config.request
158 uint8_t nr5g_fapi_config_req_to_phy_translation(
159 p_nr5g_fapi_phy_instance_t p_phy_instance,
160 fapi_config_req_t * p_fapi_req,
161 PCONFIGREQUESTStruct p_ia_config_req)
163 fapi_uint32_tlv_t *tlvs = p_fapi_req->tlvs;
164 uint32_t i = 0, j = 0, k = 0;
165 uint32_t ss_pbch_power = 0;
167 uint32_t n_ssb_mask_idx = 0;
168 uint32_t n_beamid_idx = 0;
169 SLOTCONFIGStruct *p_sslot_Config = NULL;
171 while (i < p_fapi_req->number_of_tlvs) {
172 switch (tlvs[i].tl.tag) {
173 /***** Carrier Config *****/
174 case FAPI_DL_BANDWIDTH_TAG:
175 p_ia_config_req->nDLBandwidth =
176 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length);
180 case FAPI_DL_FREQUENCY_TAG:
181 p_ia_config_req->nDLAbsFrePointA = tlvs[i].value;
185 /* FAPI_DL_K0_TAG - NA */
186 /* FAPI_DL_GRIDSIZE_TAG - NA */
188 case FAPI_NUM_TX_ANT_TAG:
189 p_ia_config_req->nNrOfTxAnt =
190 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length);
194 case FAPI_UPLINK_BANDWIDTH_TAG:
195 p_ia_config_req->nULBandwidth =
196 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length);
200 case FAPI_UPLINK_FREQUENCY_TAG:
201 p_ia_config_req->nULAbsFrePointA = tlvs[i].value;
205 /* FAPI_UL_K0_TAG - NA */
206 /* FAPI_UL_GRIDSIZE_TAG - NA */
208 case FAPI_NUM_RX_ANT_TAG:
209 p_phy_instance->phy_config.n_nr_of_rx_ant =
210 p_ia_config_req->nNrOfRxAnt =
211 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length);
215 /* FAPI_FREQUENCY_SHIFT_7P5_KHZ_TAG - NA */
217 /***** Cell Config *****/
218 case FAPI_PHY_CELL_ID_TAG:
219 p_phy_instance->phy_config.phy_cell_id =
220 p_ia_config_req->nPhyCellId =
221 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length);
225 case FAPI_FRAME_DUPLEX_TYPE_TAG:
226 p_ia_config_req->nFrameDuplexType =
227 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length);
231 /***** SSB Config *****/
232 case FAPI_SS_PBCH_POWER_TAG:
233 ss_pbch_power = tlvs[i++].value;
234 if (0 == ss_pbch_power) {
235 p_ia_config_req->nSSBPwr = 1;
236 } else if (54002 == ss_pbch_power) {
237 p_ia_config_req->nSSBPwr = 20000;
239 p_ia_config_req->nSSBPwr = ss_pbch_power - 54000;
243 /* FAPI_BCH_PAYLOAD_TAG - NA */
245 case FAPI_SCS_COMMON_TAG:
246 p_ia_config_req->nSubcCommon =
247 p_ia_config_req->nSSBSubcSpacing =
248 p_phy_instance->phy_config.sub_c_common =
249 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length);
253 /***** PRACH Config *****/
254 case FAPI_PRACH_SUBC_SPACING_TAG:
255 p_ia_config_req->nPrachSubcSpacing =
256 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length);
260 case FAPI_RESTRICTED_SET_CONFIG_TAG:
261 p_ia_config_req->nPrachRestrictSet =
262 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length);
266 case FAPI_NUM_PRACH_FD_OCCASIONS_TAG:
267 p_ia_config_req->nPrachFdm =
268 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length);
272 case FAPI_PRACH_CONFIG_INDEX_TAG:
273 p_ia_config_req->nPrachConfIdx =
274 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length);
278 case FAPI_PRACH_ROOT_SEQUENCE_INDEX_TAG:
279 p_ia_config_req->nPrachRootSeqIdx =
280 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length);
285 p_ia_config_req->nPrachFreqStart =
286 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length);
290 case FAPI_PRACH_ZERO_CORR_CONF_TAG:
291 p_ia_config_req->nPrachZeroCorrConf =
292 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length);
296 case FAPI_SSB_PER_RACH_TAG:
297 p_ia_config_req->nPrachSsbRach =
298 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length);
301 /***** SSB Table *****/
302 case FAPI_SSB_OFFSET_POINT_A_TAG:
303 p_ia_config_req->nSSBPrbOffset =
304 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length) /
305 (pow(2, p_ia_config_req->nSubcCommon));
309 case FAPI_SSB_PERIOD_TAG:
310 p_ia_config_req->nSSBPeriod =
311 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length);
315 case FAPI_SSB_SUBCARRIER_OFFSET_TAG:
316 p_ia_config_req->nSSBSubcOffset =
317 (tlvs[i].value >> tlvs[i].tl.length);
322 mib = tlvs[i++].value;
323 p_ia_config_req->nMIB[0] = (uint8_t) (mib >> 24);
324 p_ia_config_req->nMIB[1] = (uint8_t) (mib >> 16);
325 p_ia_config_req->nMIB[2] = (uint8_t) (mib >> 8);
328 case FAPI_DMRS_TYPE_A_POS_TAG:
329 p_ia_config_req->nDMRSTypeAPos =
330 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length);
334 case FAPI_SSB_MASK_TAG:
335 if (n_ssb_mask_idx < 2) {
336 p_ia_config_req->nSSBMask[n_ssb_mask_idx++] =
342 case FAPI_BEAM_ID_TAG:
343 if (n_beamid_idx < MAX_NUM_ANT_NR5G) {
344 p_ia_config_req->nBeamId[n_beamid_idx++] =
345 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length);
350 /* FAPI_SS_PBCH_MULTIPLE_CARRIERS_IN_A_BAND_TAG - NA */
351 /* FAPI_MULTIPLE_CELLS_SS_PBCH_IN_A_CARRIER_TAG - NA */
353 /***** TDD Table *****/
354 case FAPI_TDD_PERIOD_TAG:
355 p_ia_config_req->nTddPeriod =
356 nr5g_fapi_calc_phy_tdd_period((uint8_t)
357 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length),
358 p_ia_config_req->nSubcCommon);
362 case FAPI_SLOT_CONFIG_TAG:
363 for (j = 0; j < p_ia_config_req->nTddPeriod; j++) {
364 p_sslot_Config = &p_ia_config_req->sSlotConfig[j];
365 for (k = 0; k < MAX_NUM_OF_SYMBOL_PER_SLOT; k++, i++) {
366 p_sslot_Config->nSymbolType[k] =
367 GETVLFRM32B(tlvs[i].value, tlvs[i].tl.length);
372 /***** Measurement Config *****/
373 /* FAPI_RSSI_MEASUREMENT_TAG - NA */
375 /***** Beamforming Table *****/
377 /***** Precoding Table *****/
380 NR5G_FAPI_LOG(ERROR_LOG, ("[CONFIG.request] Unsupported "
381 "TLV tag : 0x%x", tlvs[i].tl.tag));
386 nr5g_fapi_config_req_fill_dependent_fields(p_ia_config_req);
390 /** @ingroup group_source_api_p5_fapi2phy_proc
392 * @param[in,out] p_ia_config_req Pointer to IAPI CONFIG.request structure.
394 * @return Returns ::SUCCESS and ::FAILURE.
397 * This function converts IAPI Config.request structure fields that depend on
398 * others. The order ofLV 5G FAPI 222.10.02 - 3.3.2.1
401 uint8_t nr5g_fapi_config_req_fill_dependent_fields(
402 PCONFIGREQUESTStruct p_ia_config_req)
404 if (0 == p_ia_config_req->nFrameDuplexType) { // FDD
405 p_ia_config_req->nTddPeriod = 0;
411 /** @ingroup group_source_api_p5_fapi2phy_proc
413 * @param[in] fapi_tdd_period DL UL Transmission Periodicity.
414 * @param[in] n_subc_common subcarrierSpacing for common.
416 * @return IAPI *nTddPeriod*.
419 * This function converts FAPI *TddPeriod* to IAPI *nTddPeriod*
423 uint8_t nr5g_fapi_calc_phy_tdd_period(
424 uint8_t fapi_tdd_period,
425 uint8_t n_subc_common)
427 switch (n_subc_common) {
430 nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_0
434 nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_1
438 nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_2
442 nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_3
451 /** @ingroup group_source_api_p5_fapi2phy_proc
453 * @param[in] fapi_tdd_period DL UL Transmission Periodicity.
455 * @return IAPI *nTddPeriod*.
458 * This function converts FAPI *TddPeriod* to IAPI *nTddPeriod*
459 * structure based on *subCarrierSpacingCommon - 0*.
462 uint8_t nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_0(
463 uint8_t fapi_tdd_period)
465 if (2 == fapi_tdd_period)
467 else if (4 == fapi_tdd_period)
469 else if (6 == fapi_tdd_period)
471 else if (7 == fapi_tdd_period)
479 /** @ingroup group_source_api_p5_fapi2phy_proc
481 * @param[in] fapi_tdd_period DL UL Transmission Periodicity.
483 * @return IAPI *nTddPeriod*.
486 * This function converts FAPI *TddPeriod* to IAPI *nTddPeriod*
487 * structure based on *subCarrierSpacingCommon - 1*.
490 uint8_t nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_1(
491 uint8_t fapi_tdd_period)
493 if (0 == fapi_tdd_period)
495 else if (2 == fapi_tdd_period)
497 else if (4 == fapi_tdd_period)
499 else if (5 == fapi_tdd_period)
501 else if (6 == fapi_tdd_period)
503 else if (7 == fapi_tdd_period)
511 /** @ingroup group_source_api_p5_fapi2phy_proc
513 * @param[in] fapi_tdd_period DL UL Transmission Periodicity.
515 * @return IAPI *nTddPeriod*.
518 * This function converts FAPI *TddPeriod* to IAPI *nTddPeriod*
519 * structure based on *subCarrierSpacingCommon - 2*.
522 uint8_t nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_2(
523 uint8_t fapi_tdd_period)
525 if (0 == fapi_tdd_period)
527 else if (2 == fapi_tdd_period)
529 else if (3 == fapi_tdd_period)
531 else if (4 == fapi_tdd_period)
533 else if (5 == fapi_tdd_period)
535 else if (6 == fapi_tdd_period)
537 else if (7 == fapi_tdd_period)
545 /** @ingroup group_source_api_p5_fapi2phy_proc
547 * @param[in] fapi_tdd_period DL UL Transmission Periodicity.
549 * @return IAPI *nTddPeriod*.
552 * This function converts FAPI *TddPeriod* to IAPI *nTddPeriod*
553 * structure based on *subCarrierSpacingCommon - 3*.
556 uint8_t nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_3(
557 uint8_t fapi_tdd_period)
559 if (0 == fapi_tdd_period)
561 else if (1 == fapi_tdd_period)
563 else if (2 == fapi_tdd_period)
565 else if (3 == fapi_tdd_period)
567 else if (4 == fapi_tdd_period)
569 else if (5 == fapi_tdd_period)
571 else if (6 == fapi_tdd_period)
573 else if (7 == fapi_tdd_period)
581 /** @ingroup group_source_api_p5_fapi2phy_proc
583 * @param[in] nSubcCommon Sub carrier spacing
584 * @param[in] nDLBandwidth/ nULBandwidth Sub carrier spacing
587 * @return IAPI FFT size for DL UL
590 * This function converts FAPI *TddPeriod* to IAPI *nTddPeriod*
591 * structure based on *subCarrierSpacingCommon - 3*.
594 uint16_t nr5g_fapi_calc_fft_size(
595 uint8_t sub_carrier_common,
598 if (FAPI_SUBCARRIER_SPACING_15 == sub_carrier_common) {
599 if (FAPI_BANDWIDTH_5_MHZ == bw)
600 return FAPI_FFT_SIZE_512;
601 else if (FAPI_BANDWIDTH_10_MHZ == bw)
602 return FAPI_FFT_SIZE_1024;
603 else if ((FAPI_BANDWIDTH_15_MHZ == bw) || (FAPI_BANDWIDTH_20_MHZ == bw))
604 return FAPI_FFT_SIZE_2048;
605 else if ((FAPI_BANDWIDTH_25_MHZ == bw) || (FAPI_BANDWIDTH_30_MHZ == bw)
606 || (FAPI_BANDWIDTH_40_MHZ == bw) || (FAPI_BANDWIDTH_50_MHZ == bw))
607 return FAPI_FFT_SIZE_4096;
608 } else if (FAPI_SUBCARRIER_SPACING_30 == sub_carrier_common) {
609 if ((FAPI_BANDWIDTH_5_MHZ == bw) || (FAPI_BANDWIDTH_10_MHZ == bw))
610 return FAPI_FFT_SIZE_512;
611 else if ((FAPI_BANDWIDTH_15_MHZ == bw) || (FAPI_BANDWIDTH_20_MHZ == bw))
612 return FAPI_FFT_SIZE_1024;
613 else if ((FAPI_BANDWIDTH_25_MHZ == bw) || (FAPI_BANDWIDTH_30_MHZ == bw)
614 || (FAPI_BANDWIDTH_40_MHZ == bw) || (FAPI_BANDWIDTH_50_MHZ == bw))
615 return FAPI_FFT_SIZE_2048;
616 else if ((FAPI_BANDWIDTH_60_MHZ == bw) || (FAPI_BANDWIDTH_70_MHZ == bw)
617 || (FAPI_BANDWIDTH_80_MHZ == bw) || ((FAPI_BANDWIDTH_90_MHZ == bw))
618 || (FAPI_BANDWIDTH_100_MHZ == bw))
619 return FAPI_FFT_SIZE_4096;
620 } else if (FAPI_SUBCARRIER_SPACING_60 == sub_carrier_common) {
621 if ((FAPI_BANDWIDTH_10_MHZ == bw) || (FAPI_BANDWIDTH_15_MHZ == bw) ||
622 (FAPI_BANDWIDTH_20_MHZ == bw) || (FAPI_BANDWIDTH_25_MHZ == bw))
623 return FAPI_FFT_SIZE_512;
624 else if ((FAPI_BANDWIDTH_30_MHZ == bw) || (FAPI_BANDWIDTH_40_MHZ == bw)
625 || (FAPI_BANDWIDTH_50_MHZ == bw))
626 return FAPI_FFT_SIZE_1024;
627 else if ((FAPI_BANDWIDTH_60_MHZ == bw) || (FAPI_BANDWIDTH_70_MHZ == bw)
628 || (FAPI_BANDWIDTH_80_MHZ == bw) || (FAPI_BANDWIDTH_90_MHZ == bw) ||
629 (FAPI_BANDWIDTH_100_MHZ == bw))
630 return FAPI_FFT_SIZE_2048;
631 else if (FAPI_BANDWIDTH_200_MHZ == bw)
632 return FAPI_FFT_SIZE_4096;
633 } else if (FAPI_SUBCARRIER_SPACING_120 == sub_carrier_common) {
634 if (FAPI_BANDWIDTH_50_MHZ == bw)
635 return FAPI_FFT_SIZE_512;
636 else if (FAPI_BANDWIDTH_100_MHZ == bw)
637 return FAPI_FFT_SIZE_1024;
638 else if (FAPI_BANDWIDTH_200_MHZ == bw)
639 return FAPI_FFT_SIZE_2048;
640 else if (FAPI_BANDWIDTH_400_MHZ == bw)
641 return FAPI_FFT_SIZE_4096;