7b7e68ad2ae6cc7c6f6b2795df63dad9220dbe77
[o-du/phy.git] / fapi_5g / source / api / fapi2phy / p5 / nr5g_fapi_proc_config_req.c
1 /******************************************************************************
2  << 3)*
3 *   Copyright (c) 2019 Intel.
4 *
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
8 *
9 *       http://www.apache.org/licenses/LICENSE-2.0
10 *
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.
16 *
17 *******************************************************************************/
18
19 /**
20  * @file
21  * This file consist of implementation of FAPI CONFIG.request message.
22  *
23  **/
24
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"
32
33  /** @ingroup group_source_api_p5_fapi2phy_proc
34  *
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.
39  *
40  *  @description
41  *  This message instructs how the PHY should be configured.
42  *
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 
46  *
47 **/
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)
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     }
115
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;
123
124     /* Add element to send list */
125     nr5g_fapi_fapi2phy_add_to_api_list(p_list_elem);
126
127     p_stats->iapi_stats.iapi_config_req++;
128     NR5G_FAPI_LOG(INFO_LOG, ("[CONFIG.request][%d]", p_phy_instance->phy_id));
129     return SUCCESS;
130 }
131
132  /** @ingroup group_source_api_p5_fapi2phy_proc
133  *
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.
137  *  
138  *  @return     Returns ::SUCCESS and ::FAILURE.
139  *
140  *  @description
141  *  This function converts FAPI CONFIG.request TLVs to IAPI Config.request
142  *  structure.
143  *
144 **/
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)
149 {
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;
153     uint32_t mib = 0;
154     uint32_t n_ssb_mask_idx = 0;
155     uint32_t n_beamid_idx = 0;
156     SLOTCONFIGStruct *p_sslot_Config = NULL;
157
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);
164                 break;
165
166             case FAPI_DL_FREQUENCY_TAG:
167                 p_ia_config_req->nDLAbsFrePointA = tlvs[i++].value;
168                 break;
169
170                 /* FAPI_DL_K0_TAG - NA */
171                 /* FAPI_DL_GRIDSIZE_TAG - NA */
172
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);
178                 break;
179
180             case FAPI_UPLINK_BANDWIDTH_TAG:
181                 p_ia_config_req->nULBandwidth =
182                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
183                 break;
184
185             case FAPI_UPLINK_FREQUENCY_TAG:
186                 p_ia_config_req->nULAbsFrePointA = tlvs[i++].value;
187                 break;
188
189                 /* FAPI_UL_K0_TAG - NA */
190                 /* FAPI_UL_GRIDSIZE_TAG - NA */
191
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);
198                 break;
199
200                 /* FAPI_FREQUENCY_SHIFT_7P5_KHZ_TAG - NA */
201
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);
207                 break;
208
209             case FAPI_FRAME_DUPLEX_TYPE_TAG:
210                 p_ia_config_req->nFrameDuplexType =
211                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
212                 break;
213
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;
221                 } else {
222                     p_ia_config_req->nSSBPwr = ss_pbch_power - 54000;
223                 }
224                 break;
225
226                 /* FAPI_BCH_PAYLOAD_TAG - NA */
227
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;
232                 break;
233
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);
238                 break;
239
240             case FAPI_RESTRICTED_SET_CONFIG_TAG:
241                 p_ia_config_req->nPrachRestrictSet =
242                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
243                 break;
244
245             case FAPI_NUM_PRACH_FD_OCCASIONS_TAG:
246                 p_ia_config_req->nPrachFdm =
247                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
248                 break;
249
250             case FAPI_PRACH_CONFIG_INDEX_TAG:
251                 p_ia_config_req->nPrachConfIdx =
252                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
253                 break;
254
255             case FAPI_PRACH_ROOT_SEQUENCE_INDEX_TAG:
256                 p_ia_config_req->nPrachRootSeqIdx =
257                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
258                 break;
259
260             case FAPI_K1_TAG:
261                 p_ia_config_req->nPrachFreqStart =
262                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
263                 break;
264
265             case FAPI_PRACH_ZERO_CORR_CONF_TAG:
266                 p_ia_config_req->nPrachZeroCorrConf =
267                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
268                 break;
269
270             case FAPI_SSB_PER_RACH_TAG:
271                 p_ia_config_req->nPrachSsbRach =
272                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
273                 break;
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));
279                 break;
280
281             case FAPI_SSB_PERIOD_TAG:
282                 p_ia_config_req->nSSBPeriod =
283                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
284                 break;
285
286             case FAPI_SSB_SUBCARRIER_OFFSET_TAG:
287                 p_ia_config_req->nSSBSubcOffset =
288                     (tlvs[i].value >> tlvs[i++].tl.length);
289                 break;
290
291             case FAPI_MIB_TAG:
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);
296                 break;
297
298             case FAPI_DMRS_TYPE_A_POS_TAG:
299                 p_ia_config_req->nDMRSTypeAPos =
300                     GETVLFRM32B(tlvs[i].value, tlvs[i++].tl.length);
301                 break;
302
303             case FAPI_SSB_MASK_TAG:
304                 if (n_ssb_mask_idx < 2) {
305                     p_ia_config_req->nSSBMask[n_ssb_mask_idx++] =
306                         tlvs[i++].value;
307                 }
308                 break;
309
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);
314                 }
315                 break;
316
317                 /* FAPI_SS_PBCH_MULTIPLE_CARRIERS_IN_A_BAND_TAG - NA */
318                 /* FAPI_MULTIPLE_CELLS_SS_PBCH_IN_A_CARRIER_TAG - NA */
319
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);
326                 break;
327
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);
334                     }
335                 }
336                 break;
337
338             /***** Measurement Config *****/
339                 /* FAPI_RSSI_MEASUREMENT_TAG - NA */
340
341             /***** Beamforming Table *****/
342
343             /***** Precoding Table *****/
344             default:
345                 {
346                     NR5G_FAPI_LOG(ERROR_LOG, ("[CONFIG.request] Unsupported "
347                             "TLV tag : 0x%x", tlvs[i].tl.tag));
348                 }
349                 break;
350         }
351     }
352     return SUCCESS;
353 }
354
355  /** @ingroup group_source_api_p5_fapi2phy_proc
356  *
357  *  @param[in]  fapi_tdd_period DL UL Transmission Periodicity. 
358  *  @param[in]  n_subc_common subcarrierSpacing for common.
359  *  
360  *  @return     IAPI *nTddPeriod*.
361  *
362  *  @description
363  *  This function converts FAPI *TddPeriod* to IAPI *nTddPeriod* 
364  *  structure.
365  *
366 **/
367 uint8_t nr5g_fapi_calc_phy_tdd_period(
368     uint8_t fapi_tdd_period,
369     uint8_t n_subc_common)
370 {
371     switch (n_subc_common) {
372         case 0:
373             return
374                 nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_0
375                 (fapi_tdd_period);
376         case 1:
377             return
378                 nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_1
379                 (fapi_tdd_period);
380         case 2:
381             return
382                 nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_2
383                 (fapi_tdd_period);
384         case 3:
385             return
386                 nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_3
387                 (fapi_tdd_period);
388         default:
389             break;
390     }
391
392     return 0;
393 }
394
395  /** @ingroup group_source_api_p5_fapi2phy_proc
396  *
397  *  @param[in]  fapi_tdd_period DL UL Transmission Periodicity. 
398  *  
399  *  @return     IAPI *nTddPeriod*.
400  *
401  *  @description
402  *  This function converts FAPI *TddPeriod* to IAPI *nTddPeriod* 
403  *  structure based on *subCarrierSpacingCommon - 0*.
404  *
405 **/
406 uint8_t nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_0(
407     uint8_t fapi_tdd_period)
408 {
409     if (2 == fapi_tdd_period)
410         return 1;
411     else if (4 == fapi_tdd_period)
412         return 2;
413     else if (6 == fapi_tdd_period)
414         return 5;
415     else if (7 == fapi_tdd_period)
416         return 10;
417     else
418         return 0;
419
420     return 0;
421 }
422
423  /** @ingroup group_source_api_p5_fapi2phy_proc
424  *
425  *  @param[in]  fapi_tdd_period DL UL Transmission Periodicity. 
426  *  
427  *  @return     IAPI *nTddPeriod*.
428  *
429  *  @description
430  *  This function converts FAPI *TddPeriod* to IAPI *nTddPeriod* 
431  *  structure based on *subCarrierSpacingCommon - 1*.
432  *
433 **/
434 uint8_t nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_1(
435     uint8_t fapi_tdd_period)
436 {
437     if (0 == fapi_tdd_period)
438         return 1;
439     else if (2 == fapi_tdd_period)
440         return 2;
441     else if (4 == fapi_tdd_period)
442         return 4;
443     else if (5 == fapi_tdd_period)
444         return 5;
445     else if (6 == fapi_tdd_period)
446         return 10;
447     else if (7 == fapi_tdd_period)
448         return 20;
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 - 2*.
464  *
465 **/
466 uint8_t nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_2(
467     uint8_t fapi_tdd_period)
468 {
469     if (0 == fapi_tdd_period)
470         return 2;
471     else if (2 == fapi_tdd_period)
472         return 4;
473     else if (3 == fapi_tdd_period)
474         return 5;
475     else if (4 == fapi_tdd_period)
476         return 8;
477     else if (5 == fapi_tdd_period)
478         return 10;
479     else if (6 == fapi_tdd_period)
480         return 20;
481     else if (7 == fapi_tdd_period)
482         return 40;
483     else
484         return 0;
485
486     return 0;
487 }
488
489  /** @ingroup group_source_api_p5_fapi2phy_proc
490  *
491  *  @param[in]  fapi_tdd_period DL UL Transmission Periodicity. 
492  *  
493  *  @return     IAPI *nTddPeriod*.
494  *
495  *  @description
496  *  This function converts FAPI *TddPeriod* to IAPI *nTddPeriod* 
497  *  structure based on *subCarrierSpacingCommon - 3*.
498  *
499 **/
500 uint8_t nr5g_fapi_calc_phy_tdd_period_for_n_subc_common_3(
501     uint8_t fapi_tdd_period)
502 {
503     if (0 == fapi_tdd_period)
504         return 4;
505     else if (1 == fapi_tdd_period)
506         return 5;
507     else if (2 == fapi_tdd_period)
508         return 8;
509     else if (3 == fapi_tdd_period)
510         return 10;
511     else if (4 == fapi_tdd_period)
512         return 16;
513     else if (5 == fapi_tdd_period)
514         return 20;
515     else if (6 == fapi_tdd_period)
516         return 40;
517     else if (7 == fapi_tdd_period)
518         return 80;
519     else
520         return 0;
521
522     return 0;
523 }
524
525  /** @ingroup group_source_api_p5_fapi2phy_proc
526  *
527  *  @param[in]  nSubcCommon  Sub carrier spacing
528  *  @param[in]  nDLBandwidth/ nULBandwidth  Sub carrier spacing
529  *  
530  *  
531  *  @return     IAPI FFT size for DL UL
532  *
533  *  @description
534  *  This function converts FAPI *TddPeriod* to IAPI *nTddPeriod* 
535  *  structure based on *subCarrierSpacingCommon - 3*.
536  *
537 **/
538 uint16_t nr5g_fapi_calc_fft_size(
539     uint8_t sub_carrier_common,
540     uint16_t bw)
541 {
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;
586     } else {
587     }
588
589     return 0;
590 }