O-RAN E Maintenance Release contribution for ODULOW
[o-du/phy.git] / fapi_5g / source / api / fapi2phy / p5 / nr5g_fapi_proc_config_req.c
1 /******************************************************************************
2 *   Copyright (c) 2019 Intel.
3 *
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
7 *
8 *       http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 *
16 *******************************************************************************/
17
18 /**
19  * @file
20  * This file consist of implementation of FAPI CONFIG.request message.
21  *
22  **/
23
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"
31
32  /** @ingroup group_source_api_p5_fapi2phy_proc
33  *
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.
38  *
39  *  @description
40  *  This message instructs how the PHY should be configured.
41  *
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 
45  *
46 **/
47 uint8_t nr5g_fapi_config_request(
48     bool is_urllc,
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)
52 {
53     PCONFIGREQUESTStruct p_ia_config_req;
54     PMAC2PHY_QUEUE_EL p_list_elem;
55     nr5g_fapi_stats_t *p_stats;
56
57 #ifndef DEBUG_MODE
58     /* Below print is for better logging on console in radio mode. */
59     NR5G_FAPI_LOG(INFO_LOG, (""));
60 #endif
61
62     if (NULL == p_phy_instance) {
63         NR5G_FAPI_LOG(ERROR_LOG, ("[CONFIG.request] Invalid " "phy instance"));
64         return FAILURE;
65     }
66     p_stats = &p_phy_instance->stats;
67     p_stats->fapi_stats.fapi_config_req++;
68
69     if (NULL == p_fapi_req) {
70         NR5G_FAPI_LOG(ERROR_LOG, ("[CONFIG.request] Invalid fapi " "message"));
71         return FAILURE;
72     }
73
74     if (NULL == p_fapi_vendor_msg) {
75         NR5G_FAPI_LOG(ERROR_LOG, ("[CONFIG.request] Invalid fapi "
76                 "vendor message"));
77         return FAILURE;
78     }
79
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"));
83         return FAILURE;
84     }
85
86     p_list_elem = nr5g_fapi_fapi2phy_create_api_list_elem((uint8_t)
87         MSG_TYPE_PHY_CONFIG_REQ, 1, (uint32_t) sizeof(CONFIGREQUESTStruct));
88     if (!p_list_elem) {
89         NR5G_FAPI_LOG(ERROR_LOG, ("[CONFIG.request] Unable to create "
90                 "list element. Out of memory!!!"));
91         return FAILURE;
92     }
93
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;
101
102     nr5g_fapi_config_req_to_phy_translation(p_phy_instance, p_fapi_req,
103         p_ia_config_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;
128     }
129
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);
136
137     /* Add element to send list */
138     nr5g_fapi_fapi2phy_add_to_api_list(is_urllc, p_list_elem);
139
140     p_stats->iapi_stats.iapi_config_req++;
141     NR5G_FAPI_LOG(INFO_LOG, ("[CONFIG.request][%d]", p_phy_instance->phy_id));
142     return SUCCESS;
143 }
144
145  /** @ingroup group_source_api_p5_fapi2phy_proc
146  *
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.
150  *  
151  *  @return     Returns ::SUCCESS and ::FAILURE.
152  *
153  *  @description
154  *  This function converts FAPI CONFIG.request TLVs to IAPI Config.request
155  *  structure.
156  *
157 **/
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)
162 {
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;
166     uint32_t mib = 0;
167     uint32_t n_ssb_mask_idx = 0;
168     uint32_t n_beamid_idx = 0;
169     SLOTCONFIGStruct *p_sslot_Config = NULL;
170
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);
177                 break;
178
179             case FAPI_DL_FREQUENCY_TAG:
180                 p_ia_config_req->nDLAbsFrePointA = tlvs[i++].value;
181                 break;
182
183                 /* FAPI_DL_K0_TAG - NA */
184                 /* FAPI_DL_GRIDSIZE_TAG - NA */
185
186             case FAPI_NUM_TX_ANT_TAG:
187                 p_ia_config_req->nNrOfTxAnt =
188                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
189                 break;
190
191             case FAPI_UPLINK_BANDWIDTH_TAG:
192                 p_ia_config_req->nULBandwidth =
193                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
194                 break;
195
196             case FAPI_UPLINK_FREQUENCY_TAG:
197                 p_ia_config_req->nULAbsFrePointA = tlvs[i++].value;
198                 break;
199
200                 /* FAPI_UL_K0_TAG - NA */
201                 /* FAPI_UL_GRIDSIZE_TAG - NA */
202
203             case FAPI_NUM_RX_ANT_TAG:
204                 p_phy_instance->phy_config.n_nr_of_rx_ant =
205                     p_ia_config_req->nNrOfRxAnt =
206                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
207                 break;
208
209                 /* FAPI_FREQUENCY_SHIFT_7P5_KHZ_TAG - NA */
210
211             /***** Cell Config *****/
212             case FAPI_PHY_CELL_ID_TAG:
213                 p_phy_instance->phy_config.phy_cell_id =
214                     p_ia_config_req->nPhyCellId =
215                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
216                 break;
217
218             case FAPI_FRAME_DUPLEX_TYPE_TAG:
219                 p_ia_config_req->nFrameDuplexType =
220                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
221                 break;
222
223             /***** SSB Config *****/
224             case FAPI_SS_PBCH_POWER_TAG:
225                 ss_pbch_power = tlvs[i++].value;
226                 if (0 == ss_pbch_power) {
227                     p_ia_config_req->nSSBPwr = 1;
228                 } else if (54002 == ss_pbch_power) {
229                     p_ia_config_req->nSSBPwr = 20000;
230                 } else {
231                     p_ia_config_req->nSSBPwr = ss_pbch_power - 54000;
232                 }
233                 break;
234
235                 /* FAPI_BCH_PAYLOAD_TAG - NA */
236
237             case FAPI_SCS_COMMON_TAG:
238                 p_ia_config_req->nSubcCommon =
239                     p_ia_config_req->nSSBSubcSpacing =
240                     p_phy_instance->phy_config.sub_c_common =
241                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
242                 break;
243
244             /***** PRACH Config *****/
245             case FAPI_PRACH_SUBC_SPACING_TAG:
246                 p_ia_config_req->nPrachSubcSpacing =
247                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
248                 break;
249
250             case FAPI_RESTRICTED_SET_CONFIG_TAG:
251                 p_ia_config_req->nPrachRestrictSet =
252                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
253                 break;
254
255             case FAPI_NUM_PRACH_FD_OCCASIONS_TAG:
256                 p_ia_config_req->nPrachFdm =
257                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
258                 break;
259
260             case FAPI_PRACH_CONFIG_INDEX_TAG:
261                 p_ia_config_req->nPrachConfIdx =
262                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
263                 break;
264
265             case FAPI_PRACH_ROOT_SEQUENCE_INDEX_TAG:
266                 p_ia_config_req->nPrachRootSeqIdx =
267                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
268                 break;
269
270             case FAPI_K1_TAG:
271                 p_ia_config_req->nPrachFreqStart =
272                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
273                 break;
274
275             case FAPI_PRACH_ZERO_CORR_CONF_TAG:
276                 p_ia_config_req->nPrachZeroCorrConf =
277                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
278                 break;
279
280             case FAPI_SSB_PER_RACH_TAG:
281                 p_ia_config_req->nPrachSsbRach =
282                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
283                 break;
284             /***** SSB Table *****/
285             case FAPI_SSB_OFFSET_POINT_A_TAG:
286                 p_ia_config_req->nSSBPrbOffset =
287                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length) / (pow(2,
288                         p_ia_config_req->nSubcCommon));
289                 break;
290
291             case FAPI_SSB_PERIOD_TAG:
292                 p_ia_config_req->nSSBPeriod =
293                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
294                 break;
295
296             case FAPI_SSB_SUBCARRIER_OFFSET_TAG:
297                 p_ia_config_req->nSSBSubcOffset =
298                     (tlvs[i].value >> tlvs[i++].tl.length);
299                 break;
300
301             case FAPI_MIB_TAG:
302                 mib = tlvs[i++].value;
303                 p_ia_config_req->nMIB[0] = (uint8_t) (mib >> 24);
304                 p_ia_config_req->nMIB[1] = (uint8_t) (mib >> 16);
305                 p_ia_config_req->nMIB[2] = (uint8_t) (mib >> 8);
306                 break;
307
308             case FAPI_DMRS_TYPE_A_POS_TAG:
309                 p_ia_config_req->nDMRSTypeAPos =
310                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
311                 break;
312
313             case FAPI_SSB_MASK_TAG:
314                 if (n_ssb_mask_idx < 2) {
315                     p_ia_config_req->nSSBMask[n_ssb_mask_idx++] =
316                         tlvs[i++].value;
317                 }
318                 break;
319
320             case FAPI_BEAM_ID_TAG:
321                 if (n_beamid_idx < MAX_NUM_ANT) {
322                     p_ia_config_req->nBeamId[n_beamid_idx++] =
323                         GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
324                 }
325                 break;
326
327                 /* FAPI_SS_PBCH_MULTIPLE_CARRIERS_IN_A_BAND_TAG - NA */
328                 /* FAPI_MULTIPLE_CELLS_SS_PBCH_IN_A_CARRIER_TAG - NA */
329
330             /***** TDD Table *****/
331             case FAPI_TDD_PERIOD_TAG:
332                 p_ia_config_req->nTddPeriod =
333                     nr5g_fapi_calc_phy_tdd_period((uint8_t)
334                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length),
335                     p_ia_config_req->nSubcCommon);
336                 break;
337
338             case FAPI_SLOT_CONFIG_TAG:
339                 for (j = 0; j < p_ia_config_req->nTddPeriod; j++) {
340                     p_sslot_Config = &p_ia_config_req->sSlotConfig[j];
341                     for (k = 0; k < MAX_NUM_OF_SYMBOL_PER_SLOT; k++) {
342                         p_sslot_Config->nSymbolType[k] =
343                             GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
344                     }
345                 }
346                 break;
347
348             /***** Measurement Config *****/
349                 /* FAPI_RSSI_MEASUREMENT_TAG - NA */
350
351             /***** Beamforming Table *****/
352
353             /***** Precoding Table *****/
354             default:
355                 {
356                     NR5G_FAPI_LOG(ERROR_LOG, ("[CONFIG.request] Unsupported "
357                             "TLV tag : 0x%x", tlvs[i].tl.tag));
358                 }
359                 break;
360         }
361     }
362     nr5g_fapi_config_req_fill_dependent_fields(p_ia_config_req);
363     return SUCCESS;
364 }
365
366  /** @ingroup group_source_api_p5_fapi2phy_proc
367  *
368  *  @param[in,out]  p_ia_config_req Pointer to IAPI CONFIG.request structure.
369  *
370  *  @return     Returns ::SUCCESS and ::FAILURE.
371  *
372  *  @description
373  *  This function converts IAPI Config.request structure fields that depend on
374  *  others. The order ofLV 5G FAPI 222.10.02 - 3.3.2.1
375  *
376 **/
377 uint8_t nr5g_fapi_config_req_fill_dependent_fields(
378     PCONFIGREQUESTStruct p_ia_config_req)
379 {
380     if (0 == p_ia_config_req->nFrameDuplexType) { // FDD
381         p_ia_config_req->nTddPeriod = 0;
382     }
383
384     return SUCCESS;
385 }
386
387  /** @ingroup group_source_api_p5_fapi2phy_proc
388  *
389  *  @param[in]  fapi_tdd_period DL UL Transmission Periodicity. 
390  *  @param[in]  n_subc_common subcarrierSpacing for common.
391  *  
392  *  @return     IAPI *nTddPeriod*.
393  *
394  *  @description
395  *  This function converts FAPI *TddPeriod* to IAPI *nTddPeriod* 
396  *  structure.
397  *
398 **/
399 uint8_t nr5g_fapi_calc_phy_tdd_period(
400     uint8_t fapi_tdd_period,
401     uint8_t n_subc_common)
402 {
403     switch (n_subc_common) {
404         case 0:
405             return
406                 nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_0
407                 (fapi_tdd_period);
408         case 1:
409             return
410                 nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_1
411                 (fapi_tdd_period);
412         case 2:
413             return
414                 nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_2
415                 (fapi_tdd_period);
416         case 3:
417             return
418                 nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_3
419                 (fapi_tdd_period);
420         default:
421             break;
422     }
423
424     return 0;
425 }
426
427  /** @ingroup group_source_api_p5_fapi2phy_proc
428  *
429  *  @param[in]  fapi_tdd_period DL UL Transmission Periodicity. 
430  *  
431  *  @return     IAPI *nTddPeriod*.
432  *
433  *  @description
434  *  This function converts FAPI *TddPeriod* to IAPI *nTddPeriod* 
435  *  structure based on *subCarrierSpacingCommon - 0*.
436  *
437 **/
438 uint8_t nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_0(
439     uint8_t fapi_tdd_period)
440 {
441     if (2 == fapi_tdd_period)
442         return 1;
443     else if (4 == fapi_tdd_period)
444         return 2;
445     else if (6 == fapi_tdd_period)
446         return 5;
447     else if (7 == fapi_tdd_period)
448         return 10;
449     else
450         return 0;
451
452     return 0;
453 }
454
455  /** @ingroup group_source_api_p5_fapi2phy_proc
456  *
457  *  @param[in]  fapi_tdd_period DL UL Transmission Periodicity. 
458  *  
459  *  @return     IAPI *nTddPeriod*.
460  *
461  *  @description
462  *  This function converts FAPI *TddPeriod* to IAPI *nTddPeriod* 
463  *  structure based on *subCarrierSpacingCommon - 1*.
464  *
465 **/
466 uint8_t nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_1(
467     uint8_t fapi_tdd_period)
468 {
469     if (0 == fapi_tdd_period)
470         return 1;
471     else if (2 == fapi_tdd_period)
472         return 2;
473     else if (4 == fapi_tdd_period)
474         return 4;
475     else if (5 == fapi_tdd_period)
476         return 5;
477     else if (6 == fapi_tdd_period)
478         return 10;
479     else if (7 == fapi_tdd_period)
480         return 20;
481     else
482         return 0;
483
484     return 0;
485 }
486
487  /** @ingroup group_source_api_p5_fapi2phy_proc
488  *
489  *  @param[in]  fapi_tdd_period DL UL Transmission Periodicity. 
490  *  
491  *  @return     IAPI *nTddPeriod*.
492  *
493  *  @description
494  *  This function converts FAPI *TddPeriod* to IAPI *nTddPeriod* 
495  *  structure based on *subCarrierSpacingCommon - 2*.
496  *
497 **/
498 uint8_t nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_2(
499     uint8_t fapi_tdd_period)
500 {
501     if (0 == fapi_tdd_period)
502         return 2;
503     else if (2 == fapi_tdd_period)
504         return 4;
505     else if (3 == fapi_tdd_period)
506         return 5;
507     else if (4 == fapi_tdd_period)
508         return 8;
509     else if (5 == fapi_tdd_period)
510         return 10;
511     else if (6 == fapi_tdd_period)
512         return 20;
513     else if (7 == fapi_tdd_period)
514         return 40;
515     else
516         return 0;
517
518     return 0;
519 }
520
521  /** @ingroup group_source_api_p5_fapi2phy_proc
522  *
523  *  @param[in]  fapi_tdd_period DL UL Transmission Periodicity. 
524  *  
525  *  @return     IAPI *nTddPeriod*.
526  *
527  *  @description
528  *  This function converts FAPI *TddPeriod* to IAPI *nTddPeriod* 
529  *  structure based on *subCarrierSpacingCommon - 3*.
530  *
531 **/
532 uint8_t nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_3(
533     uint8_t fapi_tdd_period)
534 {
535     if (0 == fapi_tdd_period)
536         return 4;
537     else if (1 == fapi_tdd_period)
538         return 5;
539     else if (2 == fapi_tdd_period)
540         return 8;
541     else if (3 == fapi_tdd_period)
542         return 10;
543     else if (4 == fapi_tdd_period)
544         return 16;
545     else if (5 == fapi_tdd_period)
546         return 20;
547     else if (6 == fapi_tdd_period)
548         return 40;
549     else if (7 == fapi_tdd_period)
550         return 80;
551     else
552         return 0;
553
554     return 0;
555 }
556
557  /** @ingroup group_source_api_p5_fapi2phy_proc
558  *
559  *  @param[in]  nSubcCommon  Sub carrier spacing
560  *  @param[in]  nDLBandwidth/ nULBandwidth  Sub carrier spacing
561  *  
562  *  
563  *  @return     IAPI FFT size for DL UL
564  *
565  *  @description
566  *  This function converts FAPI *TddPeriod* to IAPI *nTddPeriod* 
567  *  structure based on *subCarrierSpacingCommon - 3*.
568  *
569 **/
570 uint16_t nr5g_fapi_calc_fft_size(
571     uint8_t sub_carrier_common,
572     uint16_t bw)
573 {
574     if (FAPI_SUBCARRIER_SPACING_15 == sub_carrier_common) {
575         if (FAPI_BANDWIDTH_5_MHZ == bw)
576             return FAPI_FFT_SIZE_512;
577         else if (FAPI_BANDWIDTH_10_MHZ == bw)
578             return FAPI_FFT_SIZE_1024;
579         else if ((FAPI_BANDWIDTH_15_MHZ == bw) || (FAPI_BANDWIDTH_20_MHZ == bw))
580             return FAPI_FFT_SIZE_2048;
581         else if ((FAPI_BANDWIDTH_25_MHZ == bw) || (FAPI_BANDWIDTH_30_MHZ == bw)
582             || (FAPI_BANDWIDTH_40_MHZ == bw) || (FAPI_BANDWIDTH_50_MHZ == bw))
583             return FAPI_FFT_SIZE_4096;
584     } else if (FAPI_SUBCARRIER_SPACING_30 == sub_carrier_common) {
585         if ((FAPI_BANDWIDTH_5_MHZ == bw) || (FAPI_BANDWIDTH_10_MHZ == bw))
586             return FAPI_FFT_SIZE_512;
587         else if ((FAPI_BANDWIDTH_15_MHZ == bw) || (FAPI_BANDWIDTH_20_MHZ == bw))
588             return FAPI_FFT_SIZE_1024;
589         else if ((FAPI_BANDWIDTH_25_MHZ == bw) || (FAPI_BANDWIDTH_30_MHZ == bw)
590             || (FAPI_BANDWIDTH_40_MHZ == bw) || (FAPI_BANDWIDTH_50_MHZ == bw))
591             return FAPI_FFT_SIZE_2048;
592         else if ((FAPI_BANDWIDTH_60_MHZ == bw) || (FAPI_BANDWIDTH_70_MHZ == bw)
593             || (FAPI_BANDWIDTH_80_MHZ == bw) || ((FAPI_BANDWIDTH_90_MHZ == bw))
594             || (FAPI_BANDWIDTH_100_MHZ == bw))
595             return FAPI_FFT_SIZE_4096;
596     } else if (FAPI_SUBCARRIER_SPACING_60 == sub_carrier_common) {
597         if ((FAPI_BANDWIDTH_10_MHZ == bw) || (FAPI_BANDWIDTH_15_MHZ == bw) ||
598             (FAPI_BANDWIDTH_20_MHZ == bw) || (FAPI_BANDWIDTH_25_MHZ == bw))
599             return FAPI_FFT_SIZE_512;
600         else if ((FAPI_BANDWIDTH_30_MHZ == bw) || (FAPI_BANDWIDTH_40_MHZ == bw)
601             || (FAPI_BANDWIDTH_50_MHZ == bw))
602             return FAPI_FFT_SIZE_1024;
603         else if ((FAPI_BANDWIDTH_60_MHZ == bw) || (FAPI_BANDWIDTH_70_MHZ == bw)
604             || (FAPI_BANDWIDTH_80_MHZ == bw) || (FAPI_BANDWIDTH_90_MHZ == bw) ||
605             (FAPI_BANDWIDTH_100_MHZ == bw))
606             return FAPI_FFT_SIZE_2048;
607         else if (FAPI_BANDWIDTH_200_MHZ == bw)
608             return FAPI_FFT_SIZE_4096;
609     } else if (FAPI_SUBCARRIER_SPACING_120 == sub_carrier_common) {
610         if (FAPI_BANDWIDTH_50_MHZ == bw)
611             return FAPI_FFT_SIZE_512;
612         else if (FAPI_BANDWIDTH_100_MHZ == bw)
613             return FAPI_FFT_SIZE_1024;
614         else if (FAPI_BANDWIDTH_200_MHZ == bw)
615             return FAPI_FFT_SIZE_2048;
616         else if (FAPI_BANDWIDTH_400_MHZ == bw)
617             return FAPI_FFT_SIZE_4096;
618     } else {
619     }
620
621     return 0;
622 }