Addressing flow wise comments
[o-du/l2.git] / src / 5gnrmac / lwr_mac_fsm.c
1  /*******************************************************************************
2  ################################################################################
3  #   Copyright (c) [2017-2019] [Radisys]                                        #
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 #include <stdlib.h>
20 #include <stdint.h>
21 #include <stdbool.h>
22
23 /* header include files -- defines (.h) */
24 #include "envopt.h"        /* environment options */
25 #include "envdep.h"        /* environment dependent */
26 #include "envind.h"        /* environment independent */
27 #include "gen.h"           /* general layer */
28 #include "ssi.h"           /* system service interface */
29 #include "cm_hash.h"       /* common hash list */
30 #include "cm_mblk.h"       /* common memory link list library */
31 #include "cm_llist.h"      /* common linked list library */
32 #include "cm_err.h"        /* common error */
33 #include "cm_lte.h"        /* common LTE */
34 #include "lrg.h"           /* Layer manager interface includes*/
35 #include "crg.h"           /* CRG interface includes*/
36 #include "rgu.h"           /* RGU interface includes*/
37 #include "tfu.h"           /* TFU interface includes */
38 #include "rg_sch_inf.h"    /* SCH interface includes */
39 #include "rg_prg.h"       /* PRG (MAC-MAC) interface includes*/
40 #include "rg_env.h"       /* MAC environmental includes*/
41 #include "rg.h"           /* MAC includes*/
42 #include "rg_err.h"       /* MAC error includes*/
43 #include "du_log.h"
44 #include "lwr_mac_fsm.h"
45
46 /* header/extern include files (.x) */
47 #include "gen.x"           /* general layer typedefs */
48 #include "ssi.x"           /* system services typedefs */
49 #include "cm5.x"           /* common timers */
50 #include "cm_hash.x"       /* common hash list */
51 #include "cm_lib.x"        /* common library */
52 #include "cm_llist.x"      /* common linked list */
53 #include "cm_mblk.x"       /* memory management */
54 #include "cm_tkns.x"       /* common tokens */
55 #include "cm_lte.x"       /* common tokens */
56 #include "rgu.x"           /* RGU types */
57 #include "tfu.x"           /* RGU types */
58 #include "lrg.x"           /* layer management typedefs for MAC */
59 #include "crg.x"           /* CRG interface includes */
60 #include "rg_sch_inf.x"    /* SCH interface typedefs */
61 #include "rg_prg.x"        /* PRG (MAC-MAC) Interface typedefs */
62 #include "du_app_mac_inf.h"
63 #include "mac.h"
64 #include "rg.x"            /* typedefs for MAC */
65 #include "lwr_mac_phy.h"
66 #include "common_def.h"
67 #include "math.h"
68
69 #define MIB_SFN_BITMASK 0xFC
70 #define PDCCH_PDU_TYPE 0
71 #define PDSCH_PDU_TYPE 1
72 #define SSB_PDU_TYPE 3
73 #define PRACH_PDU_TYPE 0
74 #define PUSCH_PDU_TYPE 1
75 #define PDU_PRESENT 1
76 #define SET_MSG_LEN(x, size) x += size
77
78 extern void fapiMacConfigRsp();
79 extern uint8_t UnrestrictedSetNcsTable[MAX_ZERO_CORR_CFG_IDX];
80
81 /* Global variables */
82 uint8_t slotIndIdx;
83 uint16_t sendTxDataReq(SlotIndInfo currTimingInfo, DlSchedInfo *dlInfo);
84
85 void lwrMacInit()
86 {
87 #ifdef INTEL_WLS
88    uint8_t  idx;
89
90    /* Initializing WLS free mem list */
91    slotIndIdx = 1;
92    for(idx = 0; idx < WLS_MEM_FREE_PRD; idx++)
93    {
94       cmLListInit(&wlsBlockToFreeList[idx]);
95    }
96 #endif
97 }
98
99  /*******************************************************************
100   *
101   * @brief Handles Invalid Request Event
102   *
103   * @details
104   *
105   *    Function : lwr_mac_handleInvalidEvt
106   *
107   *    Functionality:
108   *         - Displays the PHY state when the invalid event occurs
109   *
110   * @params[in]
111   * @return ROK     - success
112   *         RFAILED - failure
113   *
114   * ****************************************************************/
115 S16 lwr_mac_handleInvalidEvt(void *msg)
116 {
117    printf("\nLWR_MAC: Error Indication Event[%d] received in state [%d]", clGlobalCp.event, clGlobalCp.phyState);
118    RETVALUE(ROK);
119 }
120
121 #ifdef FAPI
122 /*******************************************************************
123   *
124   * @brief Fills FAPI message header
125   *
126   * @details
127   *
128   *    Function : fillMsgHeader
129   *
130   *    Functionality:
131   *         -Fills FAPI message header
132   *
133   * @params[in] Pointer to header
134   *             Number of messages
135   *             Messae Type
136   *             Length of message
137   * @return void
138   *
139   * ****************************************************************/
140 PUBLIC void fillMsgHeader(fapi_msg_t *hdr, uint16_t msgType, uint16_t msgLen)
141 {
142    hdr->message_type_id = msgType;
143    hdr->length = msgLen;
144 }
145
146 /*******************************************************************
147   *
148   * @brief Fills FAPI Config Request message header
149   *
150   * @details
151   *
152   *    Function : fillTlvs
153   *
154   *    Functionality:
155   *         -Fills FAPI Config Request message header
156   *
157   * @params[in] Pointer to TLV
158   *             Tag
159   *             Length
160   *             Value
161   *             MsgLen
162   * @return void
163   *
164   * ****************************************************************/
165 PUBLIC void fillTlvs(fapi_uint16_tlv_t *tlv, uint16_t tag, uint16_t length,
166 uint16_t value, uint32_t *msgLen)
167 {
168    tlv->tl.tag    = tag;
169    tlv->tl.length = length;
170    tlv->value     = value;
171    *msgLen        = *msgLen + sizeof(tag) + sizeof(length) + length;
172 }
173  /*******************************************************************
174   *
175   * @brief fills the cyclic prefix by comparing the bitmask
176   *
177   * @details
178   *
179   *    Function : fillCyclicPrefix
180   *
181   *    Functionality:
182   *         -checks the value with the bitmask and
183   *          fills the cellPtr's cyclic prefix.
184   *
185   * @params[in] Pointer to ClCellParam
186   *             Value to be compared
187   * @return void
188   *
189   ********************************************************************/
190 PUBLIC void fillCyclicPrefix(uint8_t value, ClCellParam **cellPtr)
191 {
192    if((value & FAPI_NORMAL_CYCLIC_PREFIX_MASK) == FAPI_NORMAL_CYCLIC_PREFIX_MASK)
193    {
194       (*cellPtr)->cyclicPrefix   = NORMAL_CYCLIC_PREFIX_MASK;
195    }
196    else if((value & FAPI_EXTENDED_CYCLIC_PREFIX_MASK) == FAPI_EXTENDED_CYCLIC_PREFIX_MASK)
197    {
198       (*cellPtr)->cyclicPrefix   = EXTENDED_CYCLIC_PREFIX_MASK;
199    }
200    else
201    {
202       (*cellPtr)->cyclicPrefix = INVALID_VALUE;
203    }
204 }
205
206  /*******************************************************************
207   *
208   * @brief fills the subcarrier spacing of Downlink by comparing the bitmask
209   *
210   * @details
211   *
212   *    Function : fillSubcarrierSpaceDl
213   *
214   *    Functionality:
215   *         -checks the value with the bitmask and
216   *          fills the cellPtr's subcarrier spacing in DL
217   *
218   * @params[in] Pointer to ClCellParam
219   *             Value to be compared
220   * @return void
221   *
222   * ****************************************************************/
223
224 PUBLIC void fillSubcarrierSpaceDl(uint8_t value, ClCellParam **cellPtr)
225 {
226    if((value & FAPI_15KHZ_MASK) == FAPI_15KHZ_MASK)
227    {
228       (*cellPtr)->supportedSubcarrierSpacingDl = SPACING_15_KHZ;
229    }
230    else if((value & FAPI_30KHZ_MASK) == FAPI_30KHZ_MASK)
231    {
232       (*cellPtr)->supportedSubcarrierSpacingDl = SPACING_30_KHZ;
233    }
234    else if((value & FAPI_60KHZ_MASK) == FAPI_60KHZ_MASK)
235    {
236       (*cellPtr)->supportedSubcarrierSpacingDl = SPACING_60_KHZ;
237    }
238    else if((value & FAPI_120KHZ_MASK) == FAPI_120KHZ_MASK)
239    {
240       (*cellPtr)->supportedSubcarrierSpacingDl = SPACING_120_KHZ;
241    }
242    else
243    {
244       (*cellPtr)->supportedSubcarrierSpacingDl = INVALID_VALUE;
245    }
246 }
247
248  /*******************************************************************
249   *
250   * @brief fills the downlink bandwidth by comparing the bitmask
251   *
252   * @details
253   *
254   *    Function : fillBandwidthDl
255   *
256   *    Functionality:
257   *         -checks the value with the bitmask and
258   *         -fills the cellPtr's DL Bandwidth
259   *
260   * @params[in] Pointer to ClCellParam
261   *             Value to be compared
262   * @return void
263   *
264   * ****************************************************************/
265
266 PUBLIC void fillBandwidthDl(uint16_t value, ClCellParam **cellPtr)
267 {
268    if((value & FAPI_5MHZ_BW_MASK) == FAPI_5MHZ_BW_MASK)
269    {
270       (*cellPtr)->supportedBandwidthDl = BW_5MHZ;
271    }
272    else if((value & FAPI_10MHZ_BW_MASK) == FAPI_10MHZ_BW_MASK)
273    {
274       (*cellPtr)->supportedBandwidthDl = BW_10MHZ;
275    }
276    else if((value & FAPI_15MHZ_BW_MASK) == FAPI_15MHZ_BW_MASK)
277    {
278       (*cellPtr)->supportedBandwidthDl = BW_15MHZ;
279    }
280    else if((value & FAPI_20MHZ_BW_MASK) == FAPI_20MHZ_BW_MASK)
281    {
282       (*cellPtr)->supportedBandwidthDl = BW_20MHZ;
283    }
284    else if((value & FAPI_40MHZ_BW_MASK) == FAPI_40MHZ_BW_MASK)
285    {
286       (*cellPtr)->supportedBandwidthDl = BW_40MHZ;
287    }
288    else if((value & FAPI_50MHZ_BW_MASK) == FAPI_50MHZ_BW_MASK)
289    {
290       (*cellPtr)->supportedBandwidthDl = BW_50MHZ;
291    }
292    else if((value & FAPI_60MHZ_BW_MASK) == FAPI_60MHZ_BW_MASK)
293    {
294       (*cellPtr)->supportedBandwidthDl = BW_60MHZ;
295    }
296    else if((value & FAPI_70MHZ_BW_MASK) == FAPI_70MHZ_BW_MASK)
297    {
298       (*cellPtr)->supportedBandwidthDl = BW_70MHZ;
299    }
300    else if((value & FAPI_80MHZ_BW_MASK) == FAPI_80MHZ_BW_MASK)
301    {
302       (*cellPtr)->supportedBandwidthDl = BW_80MHZ;
303    }
304    else if((value & FAPI_90MHZ_BW_MASK) == FAPI_90MHZ_BW_MASK)
305    {
306       (*cellPtr)->supportedBandwidthDl = BW_90MHZ;
307    }
308    else if((value & FAPI_100MHZ_BW_MASK) == FAPI_100MHZ_BW_MASK)
309    {
310       (*cellPtr)->supportedBandwidthDl = BW_100MHZ;
311    }
312    else if((value & FAPI_200MHZ_BW_MASK) == FAPI_200MHZ_BW_MASK)
313    {
314       (*cellPtr)->supportedBandwidthDl = BW_200MHZ;
315    }
316    else if((value & FAPI_400MHZ_BW_MASK) == FAPI_400MHZ_BW_MASK)
317    {
318       (*cellPtr)->supportedBandwidthDl = BW_400MHZ;
319    }
320    else
321    {
322       (*cellPtr)->supportedBandwidthDl = INVALID_VALUE;
323    }
324 }
325
326  /*******************************************************************
327   *
328   * @brief fills the subcarrier spacing of Uplink by comparing the bitmask
329   *
330   * @details
331   *
332   *    Function : fillSubcarrierSpaceUl
333   *
334   *    Functionality:
335   *         -checks the value with the bitmask and
336   *         -fills cellPtr's subcarrier spacing in UL
337   *
338   * @params[in] Pointer to ClCellParam
339   *             Value to be compared
340   * @return void
341   *
342   * ****************************************************************/
343
344 PUBLIC void fillSubcarrierSpaceUl(uint8_t value, ClCellParam **cellPtr)
345 {
346    if((value & FAPI_15KHZ_MASK) == FAPI_15KHZ_MASK)
347    {
348       (*cellPtr)->supportedSubcarrierSpacingsUl = SPACING_15_KHZ;
349    }
350    else if((value & FAPI_30KHZ_MASK) == FAPI_30KHZ_MASK)
351    {
352       (*cellPtr)->supportedSubcarrierSpacingsUl = SPACING_30_KHZ;
353    }
354    else if((value & FAPI_60KHZ_MASK) == FAPI_60KHZ_MASK)
355    {
356       (*cellPtr)->supportedSubcarrierSpacingsUl = SPACING_60_KHZ;
357    }
358    else if((value & FAPI_120KHZ_MASK) == FAPI_120KHZ_MASK)
359    {
360       (*cellPtr)->supportedSubcarrierSpacingsUl = SPACING_120_KHZ;
361    }
362    else
363    {
364       (*cellPtr)->supportedSubcarrierSpacingsUl = INVALID_VALUE;
365    }
366 }
367
368  /*******************************************************************
369   *
370   * @brief fills the uplink bandwidth by comparing the bitmask
371   *
372   * @details
373   *
374   *    Function : fillBandwidthUl
375   *
376   *    Functionality:
377   *         -checks the value with the bitmask and
378   *          fills the cellPtr's UL Bandwidth
379   *
380   *
381   *
382   * @params[in] Pointer to ClCellParam
383   *             Value to be compared
384   * @return void
385   *
386   *
387   * ****************************************************************/
388
389 PUBLIC void fillBandwidthUl(uint16_t value, ClCellParam **cellPtr)
390 {
391    if((value & FAPI_5MHZ_BW_MASK) == FAPI_5MHZ_BW_MASK)
392    {
393       (*cellPtr)->supportedBandwidthUl = BW_5MHZ;
394    }
395    else if((value & FAPI_10MHZ_BW_MASK) == FAPI_10MHZ_BW_MASK)
396    {
397       (*cellPtr)->supportedBandwidthUl = BW_10MHZ;
398    }
399    else if((value & FAPI_15MHZ_BW_MASK) == FAPI_15MHZ_BW_MASK)
400    {
401       (*cellPtr)->supportedBandwidthUl = BW_15MHZ;
402    }
403    else if((value & FAPI_20MHZ_BW_MASK) == FAPI_20MHZ_BW_MASK)
404    {
405       (*cellPtr)->supportedBandwidthUl = BW_20MHZ;
406    }
407    else if((value & FAPI_40MHZ_BW_MASK) == FAPI_40MHZ_BW_MASK)
408    {
409       (*cellPtr)->supportedBandwidthUl = BW_40MHZ;
410    }
411    else if((value & FAPI_50MHZ_BW_MASK) == FAPI_50MHZ_BW_MASK)
412    {
413       (*cellPtr)->supportedBandwidthUl = BW_50MHZ;
414    }
415    else if((value & FAPI_60MHZ_BW_MASK) == FAPI_60MHZ_BW_MASK)
416    {
417       (*cellPtr)->supportedBandwidthUl = BW_60MHZ;
418    }
419    else if((value & FAPI_70MHZ_BW_MASK) == FAPI_70MHZ_BW_MASK)
420    {
421       (*cellPtr)->supportedBandwidthUl = BW_70MHZ;
422    }
423    else if((value & FAPI_80MHZ_BW_MASK) == FAPI_80MHZ_BW_MASK)
424    {
425       (*cellPtr)->supportedBandwidthUl = BW_80MHZ;
426    }
427    else if((value & FAPI_90MHZ_BW_MASK) == FAPI_90MHZ_BW_MASK)
428    {
429       (*cellPtr)->supportedBandwidthUl = BW_90MHZ;
430    }
431    else if((value & FAPI_100MHZ_BW_MASK) == FAPI_100MHZ_BW_MASK)
432    {
433       (*cellPtr)->supportedBandwidthUl = BW_100MHZ;
434    }
435    else if((value & FAPI_200MHZ_BW_MASK) == FAPI_200MHZ_BW_MASK)
436    {
437       (*cellPtr)->supportedBandwidthUl = BW_200MHZ;
438    }
439    else if((value & FAPI_400MHZ_BW_MASK) == FAPI_400MHZ_BW_MASK)
440    {
441       (*cellPtr)->supportedBandwidthUl = BW_400MHZ;
442    }
443    else
444    {
445       (*cellPtr)->supportedBandwidthUl = INVALID_VALUE;
446    }
447 }
448  /*******************************************************************
449   *
450   * @brief fills the CCE maping by comparing the bitmask
451   *
452   * @details
453   *
454   *    Function : fillCCEmaping
455   *
456   *    Functionality:
457   *         -checks the value with the bitmask and
458   *          fills the cellPtr's CCE Mapping Type
459   *
460   *
461   * @params[in] Pointer to ClCellParam
462   *             Value to be compared
463   * @return void
464   *
465   * ****************************************************************/
466
467 PUBLIC void fillCCEmaping(uint8_t value,  ClCellParam **cellPtr)
468 {
469    if ((value & FAPI_CCE_MAPPING_INTERLEAVED_MASK) == FAPI_CCE_MAPPING_INTERLEAVED_MASK)
470    {
471       (*cellPtr)->cceMappingType = CCE_MAPPING_INTERLEAVED_MASK;
472    }
473    else if((value & FAPI_CCE_MAPPING_INTERLEAVED_MASK) == FAPI_CCE_MAPPING_NONINTERLVD_MASK)
474    {
475       (*cellPtr)->cceMappingType = CCE_MAPPING_NONINTERLVD_MASK;
476    }
477    else
478    {
479       (*cellPtr)->cceMappingType = INVALID_VALUE;
480    }
481 }
482
483  /*******************************************************************
484   *
485   * @brief fills the PUCCH format by comparing the bitmask
486   *
487   * @details
488   *
489   *    Function : fillPucchFormat
490   *
491   *    Functionality:
492   *         -checks the value with the bitmask and
493   *          fills the cellPtr's pucch format
494   *
495   *
496   * @params[in] Pointer to ClCellParam
497   *             Value to be compared
498   * @return void
499   *
500   * ****************************************************************/
501
502 PUBLIC void fillPucchFormat(uint8_t value, ClCellParam **cellPtr)
503 {
504    if((value & FAPI_FORMAT_0_MASK) == FAPI_FORMAT_0_MASK)
505    {
506       (*cellPtr)->pucchFormats    = FORMAT_0;
507    }
508    else if((value & FAPI_FORMAT_1_MASK) == FAPI_FORMAT_1_MASK)
509    {
510       (*cellPtr)->pucchFormats    = FORMAT_1;
511    }
512    else if((value & FAPI_FORMAT_2_MASK) == FAPI_FORMAT_2_MASK)
513    {
514       (*cellPtr)->pucchFormats    = FORMAT_2;
515    }
516    else if((value & FAPI_FORMAT_3_MASK) == FAPI_FORMAT_3_MASK)
517    {
518       (*cellPtr)->pucchFormats    = FORMAT_3;
519    }
520    else if((value & FAPI_FORMAT_4_MASK) == FAPI_FORMAT_4_MASK)
521    {
522       (*cellPtr)->pucchFormats    = FORMAT_4;
523    }
524    else
525    {
526       (*cellPtr)->pucchFormats    = INVALID_VALUE;
527    }
528 }
529
530  /*******************************************************************
531   *
532   * @brief fills the PDSCH Mapping Type by comparing the bitmask
533   *
534   * @details
535   *
536   *    Function : fillPdschMappingType
537   *
538   *    Functionality:
539   *         -checks the value with the bitmask and
540   *          fills the cellPtr's PDSCH MappingType
541   *
542   * @params[in] Pointer to ClCellParam
543   *             Value to be compared
544   * @return void
545   *
546   * ****************************************************************/
547
548 PUBLIC void fillPdschMappingType(uint8_t value, ClCellParam **cellPtr)
549 {
550    if((value & FAPI_PDSCH_MAPPING_TYPE_A_MASK) == FAPI_PDSCH_MAPPING_TYPE_A_MASK)
551    {
552       (*cellPtr)->pdschMappingType = MAPPING_TYPE_A;
553    }
554    else if((value & FAPI_PDSCH_MAPPING_TYPE_B_MASK) == FAPI_PDSCH_MAPPING_TYPE_B_MASK)
555    {
556       (*cellPtr)->pdschMappingType = MAPPING_TYPE_B;
557    }
558    else
559    {
560       (*cellPtr)->pdschMappingType = INVALID_VALUE;
561    }
562 }
563
564 /*******************************************************************
565   *
566   * @brief fills the PDSCH Allocation Type by comparing the bitmask
567   *
568   * @details
569   *
570   *    Function : fillPdschAllocationType
571   *
572   *    Functionality:
573   *         -checks the value with the bitmask and
574   *          fills the cellPtr's PDSCH AllocationType
575   *
576   * @params[in] Pointer to ClCellParam
577   *             Value to be compared
578   * @return void
579   *
580   * ****************************************************************/
581
582 PUBLIC void fillPdschAllocationType(uint8_t value, ClCellParam **cellPtr)
583 {
584    if((value & FAPI_PDSCH_ALLOC_TYPE_0_MASK) == FAPI_PDSCH_ALLOC_TYPE_0_MASK)
585    {
586       (*cellPtr)->pdschAllocationTypes = ALLOCATION_TYPE_0;
587    }
588    else if((value & FAPI_PDSCH_ALLOC_TYPE_1_MASK) == FAPI_PDSCH_ALLOC_TYPE_1_MASK)
589    {
590       (*cellPtr)->pdschAllocationTypes = ALLOCATION_TYPE_1;
591    }
592    else
593    {
594       (*cellPtr)->pdschAllocationTypes = INVALID_VALUE;
595    }
596 }
597
598 /*******************************************************************
599   *
600   * @brief fills the PDSCH PRB Mapping Type by comparing the bitmask
601   *
602   * @details
603   *
604   *    Function : fillPrbMappingType
605   *
606   *    Functionality:
607   *         -checks the value with the bitmask and
608   *          fills the cellPtr's PRB Mapping Type
609   *
610   * @params[in] Pointer to ClCellParam
611   *             Value to be compared
612   * @return void
613   *
614   ******************************************************************/
615 PUBLIC void fillPrbMappingType(uint8_t value, ClCellParam **cellPtr)
616 {
617    if((value & FAPI_PDSCH_VRB_TO_PRB_MAP_NON_INTLV_MASK) == FAPI_PDSCH_VRB_TO_PRB_MAP_NON_INTLV_MASK)
618    {
619       (*cellPtr)->pdschVrbToPrbMapping = VRB_TO_PRB_MAP_NON_INTLV;
620    }
621    else if((value & FAPI_PDSCH_VRB_TO_PRB_MAP_INTLVD_MASK) == FAPI_PDSCH_VRB_TO_PRB_MAP_INTLVD_MASK)
622    {
623       (*cellPtr)->pdschVrbToPrbMapping = VRB_TO_PRB_MAP_INTLVD;
624    }
625    else
626    {
627       (*cellPtr)->pdschVrbToPrbMapping = INVALID_VALUE;
628    }
629 }
630
631 /*******************************************************************
632   *
633   * @brief fills the PDSCH DmrsConfig Type by comparing the bitmask
634   *
635   * @details
636   *
637   *    Function : fillPdschDmrsConfigType
638   *
639   *    Functionality:
640   *         -checks the value with the bitmask and
641   *          fills the cellPtr's DmrsConfig Type
642   *
643   * @params[in] Pointer to ClCellParam
644   *             Value to be compared
645   * @return void
646   *
647   ******************************************************************/
648
649 PUBLIC void fillPdschDmrsConfigType(uint8_t value, ClCellParam **cellPtr)
650 {
651    if((value & FAPI_PDSCH_DMRS_CONFIG_TYPE_1_MASK) == FAPI_PDSCH_DMRS_CONFIG_TYPE_1_MASK)
652    {
653       (*cellPtr)->pdschDmrsConfigTypes = DMRS_CONFIG_TYPE_1;
654    }
655    else if((value & FAPI_PDSCH_DMRS_CONFIG_TYPE_2_MASK) == FAPI_PDSCH_DMRS_CONFIG_TYPE_2_MASK)
656    {
657       (*cellPtr)->pdschDmrsConfigTypes = DMRS_CONFIG_TYPE_2;
658    }
659    else
660    {
661       (*cellPtr)->pdschDmrsConfigTypes = INVALID_VALUE;
662    }
663 }
664
665 /*******************************************************************
666   *
667   * @brief fills the PDSCH DmrsLength by comparing the bitmask
668   *
669   * @details
670   *
671   *    Function : fillPdschDmrsLength
672   *
673   *    Functionality:
674   *         -checks the value with the bitmask and
675   *          fills the cellPtr's PdschDmrsLength
676   *
677   * @params[in] Pointer to ClCellParam
678   *             Value to be compared
679   * @return void
680   *
681   ******************************************************************/
682 PUBLIC void fillPdschDmrsLength(uint8_t value, ClCellParam **cellPtr)
683 {
684    if(value == FAPI_PDSCH_DMRS_MAX_LENGTH_1)
685    {
686       (*cellPtr)->pdschDmrsMaxLength = DMRS_MAX_LENGTH_1;
687    }
688    else if(value == FAPI_PDSCH_DMRS_MAX_LENGTH_2)
689    {
690       (*cellPtr)->pdschDmrsMaxLength = DMRS_MAX_LENGTH_2;
691    }
692    else
693    {
694       (*cellPtr)->pdschDmrsMaxLength = INVALID_VALUE;
695    }
696 }
697
698 /*******************************************************************
699   *
700   * @brief fills the PDSCH Dmrs Additional Pos by comparing the bitmask
701   *
702   * @details
703   *
704   *    Function : fillPdschDmrsAddPos
705   *
706   *    Functionality:
707   *         -checks the value with the bitmask and
708   *          fills the cellPtr's Pdsch DmrsAddPos
709   *
710   * @params[in] Pointer to ClCellParam
711   *             Value to be compared
712   * @return void
713   *
714   ******************************************************************/
715
716 PUBLIC void fillPdschDmrsAddPos(uint8_t value, ClCellParam **cellPtr)
717 {
718    if((value & FAPI_DMRS_ADDITIONAL_POS_0_MASK) == FAPI_DMRS_ADDITIONAL_POS_0_MASK)
719    {
720       (*cellPtr)->pdschDmrsAdditionalPos = DMRS_ADDITIONAL_POS_0;
721    }
722    else if((value & FAPI_DMRS_ADDITIONAL_POS_1_MASK) == FAPI_DMRS_ADDITIONAL_POS_1_MASK)
723    {
724       (*cellPtr)->pdschDmrsAdditionalPos = DMRS_ADDITIONAL_POS_1;
725    }
726    else if((value & FAPI_DMRS_ADDITIONAL_POS_2_MASK) == FAPI_DMRS_ADDITIONAL_POS_2_MASK)
727    {
728       (*cellPtr)->pdschDmrsAdditionalPos = DMRS_ADDITIONAL_POS_2;
729    }
730    else if((value & FAPI_DMRS_ADDITIONAL_POS_3_MASK) == FAPI_DMRS_ADDITIONAL_POS_3_MASK)
731    {
732       (*cellPtr)->pdschDmrsAdditionalPos = DMRS_ADDITIONAL_POS_3;
733    }
734    else
735    {
736       (*cellPtr)->pdschDmrsAdditionalPos = INVALID_VALUE;
737    }
738 }
739
740 /*******************************************************************
741   *
742   * @brief fills the Modulation Order in DL by comparing the bitmask
743   *
744   * @details
745   *
746   *    Function : fillModulationOrderDl
747   *
748   *    Functionality:
749   *         -checks the value with the bitmask and
750   *          fills the cellPtr's ModulationOrder in DL.
751   *
752   * @params[in] Pointer to ClCellParam
753   *             Value to be compared
754   * @return void
755   *
756   ******************************************************************/
757 PUBLIC void fillModulationOrderDl(uint8_t value, ClCellParam **cellPtr)
758 {
759    if(value == 0 )
760    {
761       (*cellPtr)->supportedMaxModulationOrderDl = MOD_QPSK;
762    }
763    else if(value == 1)
764    {
765       (*cellPtr)->supportedMaxModulationOrderDl = MOD_16QAM;
766    }
767    else if(value == 2)
768    {
769       (*cellPtr)->supportedMaxModulationOrderDl = MOD_64QAM;
770    }
771    else if(value == 3)
772    {
773       (*cellPtr)->supportedMaxModulationOrderDl = MOD_256QAM;
774    }
775    else
776    {
777       (*cellPtr)->supportedMaxModulationOrderDl = INVALID_VALUE;
778    }
779 }
780
781 /*******************************************************************
782   *
783   * @brief fills the PUSCH DmrsConfig Type by comparing the bitmask
784   *
785   * @details
786   *
787   *    Function : fillPuschDmrsConfigType
788   *
789   *    Functionality:
790   *         -checks the value with the bitmask and
791   *          fills the cellPtr's PUSCH DmrsConfigType
792   *
793   * @params[in] Pointer to ClCellParam
794   *             Value to be compared
795   * @return void
796   *
797   ******************************************************************/
798
799 PUBLIC void fillPuschDmrsConfig(uint8_t value, ClCellParam **cellPtr)
800 {
801    if((value & FAPI_PUSCH_DMRS_CONFIG_TYPE_1_MASK) == FAPI_PUSCH_DMRS_CONFIG_TYPE_1_MASK)
802    {
803       (*cellPtr)->puschDmrsConfigTypes = DMRS_CONFIG_TYPE_1;
804    }
805    else if((value & FAPI_PUSCH_DMRS_CONFIG_TYPE_2_MASK) == FAPI_PUSCH_DMRS_CONFIG_TYPE_2_MASK)
806    {
807       (*cellPtr)->puschDmrsConfigTypes = DMRS_CONFIG_TYPE_2;
808    }
809    else
810    {
811       (*cellPtr)->puschDmrsConfigTypes = INVALID_VALUE;
812    }
813 }
814
815 /*******************************************************************
816   *
817   * @brief fills the PUSCH DmrsLength by comparing the bitmask
818   *
819   * @details
820   *
821   *    Function : fillPuschDmrsLength
822   *
823   *    Functionality:
824   *         -checks the value with the bitmask and
825   *          fills the cellPtr's PUSCH DmrsLength
826   *
827   * @params[in] Pointer to ClCellParam
828   *             Value to be compared
829   * @return void
830   *
831   ******************************************************************/
832
833 PUBLIC void fillPuschDmrsLength(uint8_t value, ClCellParam **cellPtr)
834 {
835    if(value  == FAPI_PUSCH_DMRS_MAX_LENGTH_1)
836    {
837       (*cellPtr)->puschDmrsMaxLength = DMRS_MAX_LENGTH_1;
838    }
839    else if(value  == FAPI_PUSCH_DMRS_MAX_LENGTH_2)
840    {
841       (*cellPtr)->puschDmrsMaxLength = DMRS_MAX_LENGTH_2;
842    }
843    else
844    {
845       (*cellPtr)->puschDmrsMaxLength = INVALID_VALUE;
846    }
847 }
848
849 /*******************************************************************
850   *
851   * @brief fills the PUSCH Dmrs Additional position by comparing the bitmask
852   *
853   * @details
854   *
855   *    Function : fillPuschDmrsAddPos
856   *
857   *    Functionality:
858   *         -checks the value with the bitmask and
859   *          fills the cellPtr's PUSCH DmrsAddPos
860   *
861   * @params[in] Pointer to ClCellParam
862   *             Value to be compared
863   * @return void
864   *
865   ******************************************************************/
866
867 PUBLIC void fillPuschDmrsAddPos(uint8_t value, ClCellParam **cellPtr)
868 {
869    if((value & FAPI_DMRS_ADDITIONAL_POS_0_MASK) == FAPI_DMRS_ADDITIONAL_POS_0_MASK)
870    {
871       (*cellPtr)->puschDmrsAdditionalPos = DMRS_ADDITIONAL_POS_0;
872    }
873    else if((value & FAPI_DMRS_ADDITIONAL_POS_1_MASK) == FAPI_DMRS_ADDITIONAL_POS_1_MASK)
874    {
875       (*cellPtr)->puschDmrsAdditionalPos = DMRS_ADDITIONAL_POS_1;
876    }
877    else if((value & FAPI_DMRS_ADDITIONAL_POS_2_MASK) == FAPI_DMRS_ADDITIONAL_POS_2_MASK)
878    {
879       (*cellPtr)->puschDmrsAdditionalPos = DMRS_ADDITIONAL_POS_2;
880    }
881    else if((value & FAPI_DMRS_ADDITIONAL_POS_3_MASK) == FAPI_DMRS_ADDITIONAL_POS_3_MASK)
882    {
883       (*cellPtr)->puschDmrsAdditionalPos = DMRS_ADDITIONAL_POS_3;
884    }
885    else
886    {
887       (*cellPtr)->puschDmrsAdditionalPos = INVALID_VALUE;
888    }
889 }
890
891 /*******************************************************************
892   *
893   * @brief fills the PUSCH Mapping Type by comparing the bitmask
894   *
895   * @details
896   *
897   *    Function : fillPuschMappingType
898   *
899   *    Functionality:
900   *         -checks the value with the bitmask and
901   *          fills the cellPtr's PUSCH MappingType
902   *
903   * @params[in] Pointer to ClCellParam
904   *             Value to be compared
905   * @return void
906   *
907   ******************************************************************/
908
909 PUBLIC void fillPuschMappingType(uint8_t value, ClCellParam **cellPtr)
910 {
911    if((value & FAPI_PUSCH_MAPPING_TYPE_A_MASK) == FAPI_PUSCH_MAPPING_TYPE_A_MASK)
912    {
913       (*cellPtr)->puschMappingType = MAPPING_TYPE_A;
914    }
915    else if((value & FAPI_PUSCH_MAPPING_TYPE_B_MASK) == FAPI_PUSCH_MAPPING_TYPE_B_MASK)
916    {
917       (*cellPtr)->puschMappingType = MAPPING_TYPE_B;
918    }
919    else
920    {
921       (*cellPtr)->puschMappingType = INVALID_VALUE;
922    }
923 }
924
925 /*******************************************************************
926   *
927   * @brief fills the PUSCH Allocation Type by comparing the bitmask
928   *
929   * @details
930   *
931   *    Function : fillPuschAllocationType
932   *
933   *    Functionality:
934   *         -checks the value with the bitmask and
935   *          fills the cellPtr's PUSCH AllocationType
936   *
937   * @params[in] Pointer to ClCellParam
938   *             Value to be compared
939   * @return void
940   *
941   ******************************************************************/
942
943 PUBLIC void fillPuschAllocationType(uint8_t value, ClCellParam **cellPtr)
944 {
945    if((value & FAPI_PUSCH_ALLOC_TYPE_0_MASK) == FAPI_PUSCH_ALLOC_TYPE_0_MASK)
946    {
947       (*cellPtr)->puschAllocationTypes = ALLOCATION_TYPE_0;
948    }
949    else if((value & FAPI_PUSCH_ALLOC_TYPE_0_MASK) == FAPI_PUSCH_ALLOC_TYPE_0_MASK)
950    {
951       (*cellPtr)->puschAllocationTypes = ALLOCATION_TYPE_1;
952    }
953    else
954    {
955       (*cellPtr)->puschAllocationTypes = INVALID_VALUE;
956    }
957 }
958
959 /*******************************************************************
960   *
961   * @brief fills the PUSCH PRB Mapping Type by comparing the bitmask
962   *
963   * @details
964   *
965   *    Function : fillPuschPrbMappingType
966   *
967   *    Functionality:
968   *         -checks the value with the bitmask and
969   *          fills the cellPtr's PUSCH PRB MApping Type
970   *
971   * @params[in] Pointer to ClCellParam
972   *             Value to be compared
973   * @return void
974   *
975   ******************************************************************/
976
977 PUBLIC void fillPuschPrbMappingType(uint8_t value, ClCellParam **cellPtr)
978 {
979    if((value & FAPI_PUSCH_VRB_TO_PRB_MAP_NON_INTLV_MASK) == FAPI_PUSCH_VRB_TO_PRB_MAP_NON_INTLV_MASK)
980    {
981       (*cellPtr)->puschVrbToPrbMapping = VRB_TO_PRB_MAP_NON_INTLV;
982    }
983    else if((value & FAPI_PUSCH_VRB_TO_PRB_MAP_INTLVD_MASK) == FAPI_PUSCH_VRB_TO_PRB_MAP_INTLVD_MASK)
984    {
985       (*cellPtr)->puschVrbToPrbMapping = VRB_TO_PRB_MAP_INTLVD;
986    }
987    else
988    {
989       (*cellPtr)->puschVrbToPrbMapping = INVALID_VALUE;
990    }
991 }
992
993 /*******************************************************************
994   *
995   * @brief fills the Modulation Order in Ul by comparing the bitmask
996   *
997   * @details
998   *
999   *    Function : fillModulationOrderUl
1000   *
1001   *    Functionality:
1002   *         -checks the value with the bitmask and
1003   *          fills the cellPtr's Modualtsion Order in UL.
1004   *
1005   * @params[in] Pointer to ClCellParam
1006   *             Value to be compared
1007   * @return void
1008   *
1009   ******************************************************************/
1010
1011 PUBLIC void fillModulationOrderUl(uint8_t value, ClCellParam **cellPtr)
1012 {
1013    if(value == 0)
1014    {
1015       (*cellPtr)->supportedModulationOrderUl = MOD_QPSK;
1016    }
1017    else if(value == 1)
1018    {
1019       (*cellPtr)->supportedModulationOrderUl = MOD_16QAM;
1020    }
1021    else if(value == 2)
1022    {
1023       (*cellPtr)->supportedModulationOrderUl = MOD_64QAM;
1024    }
1025    else if(value == 3)
1026    {
1027       (*cellPtr)->supportedModulationOrderUl = MOD_256QAM;
1028    }
1029    else
1030    {
1031       (*cellPtr)->supportedModulationOrderUl = INVALID_VALUE;
1032    }
1033 }
1034
1035 /*******************************************************************
1036   *
1037   * @brief fills the PUSCH Aggregation Factor by comparing the bitmask
1038   *
1039   * @details
1040   *
1041   *    Function : fillPuschAggregationFactor
1042   *
1043   *    Functionality:
1044   *         -checks the value with the bitmask and
1045   *          fills the cellPtr's PUSCH Aggregation Factor
1046   *
1047   * @params[in] Pointer to ClCellParam
1048   *             Value to be compared
1049   * @return void
1050   *
1051   ******************************************************************/
1052
1053 PUBLIC void fillPuschAggregationFactor(uint8_t value, ClCellParam **cellPtr)
1054 {
1055    if((value & FAPI_FORMAT_0_MASK) == FAPI_FORMAT_0_MASK)
1056    {
1057       (*cellPtr)->puschAggregationFactor    = AGG_FACTOR_1;
1058    }
1059    else if((value & FAPI_FORMAT_1_MASK) == FAPI_FORMAT_1_MASK)
1060    {
1061       (*cellPtr)->puschAggregationFactor    = AGG_FACTOR_2;
1062    }
1063    else if((value & FAPI_FORMAT_2_MASK) == FAPI_FORMAT_2_MASK)
1064    {
1065       (*cellPtr)->puschAggregationFactor    = AGG_FACTOR_4;
1066    }
1067    else if((value & FAPI_FORMAT_3_MASK) == FAPI_FORMAT_3_MASK)
1068    {
1069       (*cellPtr)->puschAggregationFactor    = AGG_FACTOR_8;
1070    }
1071    else
1072    {
1073       (*cellPtr)->puschAggregationFactor    = INVALID_VALUE;
1074    }
1075 }
1076
1077 /*******************************************************************
1078   *
1079   * @brief fills the PRACH Long Format by comparing the bitmask
1080   *
1081   * @details
1082   *
1083   *    Function : fillPrachLongFormat
1084   *
1085   *    Functionality:
1086   *         -checks the value with the bitmask and
1087   *          fills the cellPtr's PRACH Long Format
1088   *
1089   * @params[in] Pointer to ClCellParam
1090   *             Value to be compared
1091   * @return void
1092   *
1093   ******************************************************************/
1094
1095 PUBLIC void fillPrachLongFormat(uint8_t value, ClCellParam **cellPtr)
1096 {
1097    if((value & FAPI_PRACH_LF_FORMAT_0_MASK) == FAPI_PRACH_LF_FORMAT_0_MASK)
1098    {
1099       (*cellPtr)->prachLongFormats    = FORMAT_0;
1100    }
1101    else if((value & FAPI_PRACH_LF_FORMAT_1_MASK) == FAPI_PRACH_LF_FORMAT_1_MASK)
1102    {
1103       (*cellPtr)->prachLongFormats    = FORMAT_1;
1104    }
1105    else if((value & FAPI_PRACH_LF_FORMAT_2_MASK) == FAPI_PRACH_LF_FORMAT_2_MASK)
1106    {
1107       (*cellPtr)->prachLongFormats    = FORMAT_2;
1108    }
1109    else if((value & FAPI_PRACH_LF_FORMAT_3_MASK) == FAPI_PRACH_LF_FORMAT_3_MASK)
1110    {
1111       (*cellPtr)->prachLongFormats    = FORMAT_3;
1112    }
1113    else
1114    {
1115       (*cellPtr)->prachLongFormats    = INVALID_VALUE;
1116    }
1117 }
1118
1119 /*******************************************************************
1120   *
1121   * @brief fills the PRACH Short Format by comparing the bitmask
1122   *
1123   * @details
1124   *
1125   *    Function : fillPrachShortFormat
1126   *
1127   *    Functionality:
1128   *         -checks the value with the bitmask and
1129   *          fills the cellPtr's PRACH ShortFormat
1130   *
1131   * @params[in] Pointer to ClCellParam
1132   *             Value to be compared
1133   * @return void
1134   *
1135   ******************************************************************/
1136
1137 PUBLIC void fillPrachShortFormat(uint8_t value, ClCellParam **cellPtr)
1138 {
1139    if((value & FAPI_PRACH_SF_FORMAT_A1_MASK) == FAPI_PRACH_SF_FORMAT_A1_MASK)
1140    {
1141       (*cellPtr)->prachShortFormats    = SF_FORMAT_A1;
1142    }
1143    else if((value & FAPI_PRACH_SF_FORMAT_A2_MASK) == FAPI_PRACH_SF_FORMAT_A2_MASK)
1144    {
1145       (*cellPtr)->prachShortFormats    = SF_FORMAT_A2;
1146    }
1147    else if((value & FAPI_PRACH_SF_FORMAT_A3_MASK) == FAPI_PRACH_SF_FORMAT_A3_MASK)
1148    {
1149       (*cellPtr)->prachShortFormats    = SF_FORMAT_A3;
1150    }
1151    else if((value & FAPI_PRACH_SF_FORMAT_B1_MASK) == FAPI_PRACH_SF_FORMAT_B1_MASK)
1152    {
1153       (*cellPtr)->prachShortFormats    = SF_FORMAT_B1;
1154    }
1155    else if((value & FAPI_PRACH_SF_FORMAT_B2_MASK) == FAPI_PRACH_SF_FORMAT_B2_MASK)
1156    {
1157       (*cellPtr)->prachShortFormats    = SF_FORMAT_B2;
1158    }
1159    else if((value & FAPI_PRACH_SF_FORMAT_B3_MASK) == FAPI_PRACH_SF_FORMAT_B3_MASK)
1160    {
1161       (*cellPtr)->prachShortFormats    = SF_FORMAT_B3;
1162    }
1163    else if((value & FAPI_PRACH_SF_FORMAT_B4_MASK) == FAPI_PRACH_SF_FORMAT_B4_MASK)
1164    {
1165       (*cellPtr)->prachShortFormats    = SF_FORMAT_B4;
1166    }
1167    else if((value & FAPI_PRACH_SF_FORMAT_C0_MASK) == FAPI_PRACH_SF_FORMAT_C0_MASK)
1168    {
1169       (*cellPtr)->prachShortFormats    = SF_FORMAT_C0;
1170    }
1171    else if((value & FAPI_PRACH_SF_FORMAT_C2_MASK) == FAPI_PRACH_SF_FORMAT_C2_MASK)
1172    {
1173       (*cellPtr)->prachShortFormats    = SF_FORMAT_C2;
1174    }
1175    else
1176    {
1177       (*cellPtr)->prachShortFormats    = INVALID_VALUE;
1178    }
1179 }
1180
1181 /*******************************************************************
1182   *
1183   * @brief fills the Fd Occasions Type by comparing the bitmask
1184   *
1185   * @details
1186   *
1187   *    Function : fillFdOccasions
1188   *
1189   *    Functionality:
1190   *         -checks the value with the bitmask and
1191   *          fills the cellPtr's Fd Occasions
1192   *
1193   * @params[in] Pointer to ClCellParam
1194   *             Value to be compared
1195   * @return void
1196   *
1197   ******************************************************************/
1198
1199 PUBLIC void fillFdOccasions(uint8_t value, ClCellParam **cellPtr)
1200 {
1201    if(value == 0)
1202    {
1203       (*cellPtr)->maxPrachFdOccasionsInASlot = PRACH_FD_OCC_IN_A_SLOT_1;
1204    }
1205    else if(value == 1)
1206    {
1207       (*cellPtr)->maxPrachFdOccasionsInASlot = PRACH_FD_OCC_IN_A_SLOT_2;
1208    }
1209    else if(value == 3)
1210    {
1211       (*cellPtr)->maxPrachFdOccasionsInASlot = PRACH_FD_OCC_IN_A_SLOT_4;
1212    }
1213    else if(value == 4)
1214    {
1215       (*cellPtr)->maxPrachFdOccasionsInASlot = PRACH_FD_OCC_IN_A_SLOT_8;
1216    }
1217    else
1218    {
1219       (*cellPtr)->maxPrachFdOccasionsInASlot = INVALID_VALUE;
1220    }
1221 }
1222
1223 /*******************************************************************
1224   *
1225   * @brief fills the RSSI Measurement by comparing the bitmask
1226   *
1227   * @details
1228   *
1229   *    Function : fillRssiMeas
1230   *
1231   *    Functionality:
1232   *         -checks the value with the bitmask and
1233   *          fills the cellPtr's RSSI Measurement report
1234   *
1235   * @params[in] Pointer to ClCellParam
1236   *             Value to be compared
1237   * @return void
1238   *
1239   ******************************************************************/
1240
1241 PUBLIC void fillRssiMeas(uint8_t value, ClCellParam **cellPtr)
1242 {
1243    if((value & FAPI_RSSI_REPORT_IN_DBM_MASK) == FAPI_RSSI_REPORT_IN_DBM_MASK)
1244    {
1245       (*cellPtr)->rssiMeasurementSupport    = RSSI_REPORT_DBM;
1246    }
1247    else if((value & FAPI_RSSI_REPORT_IN_DBFS_MASK) == FAPI_RSSI_REPORT_IN_DBFS_MASK)
1248    {
1249       (*cellPtr)->rssiMeasurementSupport    = RSSI_REPORT_DBFS;
1250    }
1251    else
1252    {
1253       (*cellPtr)->rssiMeasurementSupport    = INVALID_VALUE;
1254    }
1255 }
1256
1257  /*******************************************************************
1258   *
1259   * @brief Returns the TLVs value
1260   *
1261   * @details
1262   *
1263   *    Function : getParamValue
1264   *
1265   *    Functionality:
1266   *         -return TLVs value
1267   *
1268   * @params[in]
1269   * @return ROK     - temp
1270   *         RFAILED - failure
1271   *
1272   * ****************************************************************/
1273
1274 uint32_t getParamValue(fapi_uint16_tlv_t *tlv, uint16_t type)
1275 {
1276    //uint16_t valueLen;
1277    void *posPtr;
1278    //valueLen = tlv->tl.length;
1279    posPtr   = &tlv->tl.tag;
1280    posPtr   += sizeof(tlv->tl.tag);
1281    posPtr   += sizeof(tlv->tl.length);
1282    /*TO DO: malloc to SSI memory */
1283    if(type == FAPI_UINT_8)
1284    {
1285       //temp = (uint8_t *)malloc(valueLen * sizeof(U8));
1286       //memcpy(temp, posPtr, valueLen);
1287       return(*(uint8_t *)posPtr);
1288    }
1289    else if(type == FAPI_UINT_16)
1290    {
1291       return(*(uint16_t *)posPtr);
1292    }
1293    else if(type == FAPI_UINT_32)
1294    {
1295       return(*(uint32_t *)posPtr);
1296    }
1297    else
1298    {
1299      DU_LOG("\nLWR_MAC: Value Extraction failed" );
1300      return RFAILED;
1301    }
1302 }
1303 #endif /* FAPI */
1304  /*******************************************************************
1305   *
1306   * @brief Sends FAPI Param req to PHY
1307   *
1308   * @details
1309   *
1310   *    Function : lwr_mac_handleParamReqEvt
1311   *
1312   *    Functionality:
1313   *         -Sends FAPI Param req to PHY
1314   *
1315   * @params[in]
1316   * @return ROK     - success
1317   *         RFAILED - failure
1318   *
1319   * ****************************************************************/
1320
1321 S16 lwr_mac_handleParamReqEvt(void *msg)
1322 {
1323 #ifdef FAPI
1324    /* startGuardTimer(); */
1325    uint32_t msgLen = 0;             //Length of message Body
1326    fapi_param_req_t *paramReq = NULL;
1327
1328    LWR_MAC_ALLOC(paramReq, sizeof(fapi_param_req_t));
1329    if(paramReq != NULL)
1330    {
1331       fillMsgHeader(&paramReq->header, FAPI_PARAM_REQUEST, msgLen);
1332
1333       DU_LOG("\nLWR_MAC: Sending Param Request to Phy");
1334       LwrMacSendToPhy(paramReq->header.message_type_id, \
1335          sizeof(fapi_param_req_t), (void *)paramReq);
1336    }
1337    else
1338    {
1339       DU_LOG("\nLWR_MAC: Failed to allocate memory for Param Request");
1340       return RFAILED;
1341    }
1342 #endif
1343    return ROK;
1344 }
1345
1346  /*******************************************************************
1347   *
1348   * @brief Sends FAPI Param Response to MAC via PHY
1349   *
1350   * @details
1351   *
1352   *    Function : lwr_mac_handleParamRspEvt
1353   *
1354   *    Functionality:
1355   *         -Sends FAPI Param rsp to MAC via PHY
1356   *
1357   * @params[in]
1358   * @return ROK     - success
1359   *         RFAILED - failure
1360   *
1361   * ****************************************************************/
1362
1363 S16 lwr_mac_handleParamRspEvt(void *msg)
1364 {
1365 #ifdef FAPI
1366   /* stopGuardTimer(); */
1367    uint8_t index;
1368    uint32_t encodedVal;
1369    fapi_param_resp_t *paramRsp;
1370    ClCellParam *cellParam = NULLP;
1371
1372    paramRsp = (fapi_param_resp_t *)msg;
1373    DU_LOG("\nLWR_MAC: Received EVENT[%d] at STATE[%d]", clGlobalCp.event, clGlobalCp.phyState);
1374
1375    if(paramRsp != NULLP)
1376    {
1377       MAC_ALLOC(cellParam, sizeof(ClCellParam));
1378       if(cellParam != NULLP)
1379       {
1380          DU_LOG("\n LWR_MAC: Filling TLVS into MAC API");
1381          if(paramRsp->error_code == MSG_OK)
1382          {
1383             for(index = 0; index < paramRsp->number_of_tlvs; index++)
1384             {
1385                switch(paramRsp->tlvs[index].tl.tag)
1386                {
1387                   case FAPI_RELEASE_CAPABILITY_TAG:
1388                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_16);
1389                      if(encodedVal != RFAILED && (encodedVal & RELEASE_15) == RELEASE_15)
1390                      {
1391                         cellParam->releaseCapability = RELEASE_15;
1392                      }
1393                      break;
1394
1395                   case FAPI_PHY_STATE_TAG:
1396                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1397                      if(encodedVal != RFAILED && encodedVal != clGlobalCp.phyState)
1398                      {
1399                         printf("\n PhyState mismatch [%d][%d]", clGlobalCp.phyState, clGlobalCp.event);
1400                         RETVALUE(RFAILED);
1401                      }
1402                      break;
1403
1404                   case FAPI_SKIP_BLANK_DL_CONFIG_TAG:
1405                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1406                      if(encodedVal != RFAILED && encodedVal != 0)
1407                      {
1408                         cellParam->skipBlankDlConfig = SUPPORTED;
1409                      }
1410                      else
1411                      {
1412                         cellParam->skipBlankDlConfig = NOT_SUPPORTED;
1413                      }
1414                      break;
1415
1416                   case FAPI_SKIP_BLANK_UL_CONFIG_TAG:
1417                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1418                      if(encodedVal != RFAILED && encodedVal != 0)
1419                      {
1420                         cellParam->skipBlankUlConfig = SUPPORTED;
1421                      }
1422                      else
1423                      {
1424                         cellParam->skipBlankUlConfig = NOT_SUPPORTED;
1425                      }
1426                      break;
1427
1428                   case FAPI_NUM_CONFIG_TLVS_TO_REPORT_TYPE_TAG:
1429                      cellParam->numTlvsToReport = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_16);
1430                      break;
1431
1432                   case FAPI_CYCLIC_PREFIX_TAG:
1433                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1434                      if(encodedVal != RFAILED)
1435                      {
1436                         fillCyclicPrefix(encodedVal, &cellParam);
1437                      }
1438                      break;
1439
1440                   case FAPI_SUPPORTED_SUBCARRIER_SPACING_DL_TAG:
1441                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1442                      if(encodedVal != RFAILED)
1443                      {
1444                         fillSubcarrierSpaceDl(encodedVal, &cellParam);
1445                      }
1446                      break;
1447
1448                   case FAPI_SUPPORTED_BANDWIDTH_DL_TAG:
1449                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_16);
1450                      if(encodedVal != RFAILED)
1451                      {
1452                         fillBandwidthDl(encodedVal, &cellParam);
1453                      }
1454                      break;
1455
1456                   case FAPI_SUPPORTED_SUBCARRIER_SPACING_UL_TAG:
1457                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1458                      if(encodedVal != RFAILED)
1459                      {
1460                         fillSubcarrierSpaceUl(encodedVal, &cellParam);
1461                      }
1462                      break;
1463
1464                   case FAPI_SUPPORTED_BANDWIDTH_UL_TAG:
1465                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_16);
1466                      if(encodedVal != RFAILED)
1467                      {
1468                         fillBandwidthUl(encodedVal, &cellParam);
1469                      }
1470                      break;
1471
1472                   case FAPI_CCE_MAPPING_TYPE_TAG:
1473                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1474                      if(encodedVal != RFAILED)
1475                      {
1476                         fillCCEmaping(encodedVal, &cellParam);
1477                      }
1478                      break;
1479
1480                   case FAPI_CORESET_OUTSIDE_FIRST_3_OFDM_SYMS_OF_SLOT_TAG:
1481                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1482                      if(encodedVal != RFAILED && encodedVal != 0)
1483                      {
1484                         cellParam->coresetOutsideFirst3OfdmSymsOfSlot = SUPPORTED;
1485                      }
1486                      else
1487                      {
1488                         cellParam->coresetOutsideFirst3OfdmSymsOfSlot = NOT_SUPPORTED;
1489                      }
1490                      break;
1491
1492                   case FAPI_PRECODER_GRANULARITY_CORESET_TAG:
1493                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1494                      if(encodedVal != RFAILED && encodedVal != 0)
1495                      {
1496                         cellParam->precoderGranularityCoreset = SUPPORTED;
1497                      }
1498                      else
1499                      {
1500                         cellParam->precoderGranularityCoreset = NOT_SUPPORTED;
1501                      }
1502                      break;
1503
1504                   case FAPI_PDCCH_MU_MIMO_TAG:
1505                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1506                      if(encodedVal != RFAILED && encodedVal != 0)
1507                      {
1508                         cellParam->pdcchMuMimo = SUPPORTED;
1509                      }
1510                      else
1511                      {
1512                         cellParam->pdcchMuMimo = NOT_SUPPORTED;
1513                      }
1514                      break;
1515
1516                   case FAPI_PDCCH_PRECODER_CYCLING_TAG:
1517                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1518                      if(encodedVal != RFAILED && encodedVal != 0)
1519                      {
1520                         cellParam->pdcchPrecoderCycling = SUPPORTED;
1521                      }
1522                      else
1523                      {
1524                         cellParam->pdcchPrecoderCycling = NOT_SUPPORTED;
1525                      }
1526                      break;
1527
1528                   case FAPI_MAX_PDCCHS_PER_SLOT_TAG:
1529                      cellParam->maxPdcchsPerSlot = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1530                      break;
1531
1532                   case FAPI_PUCCH_FORMATS_TAG:
1533                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1534                      if(encodedVal != RFAILED)
1535                      {
1536                         fillPucchFormat(encodedVal, &cellParam);
1537                      }
1538                      break;
1539
1540                   case FAPI_MAX_PUCCHS_PER_SLOT_TAG:
1541                    cellParam->maxPucchsPerSlot   = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1542                      break;
1543
1544                   case FAPI_PDSCH_MAPPING_TYPE_TAG:
1545                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1546                      if(encodedVal != RFAILED)
1547                      {
1548                         fillPdschMappingType(encodedVal, &cellParam);
1549                      }
1550                      break;
1551
1552                   case FAPI_PDSCH_ALLOCATION_TYPES_TAG:
1553                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1554                      if(encodedVal != RFAILED)
1555                      {
1556                         fillPdschAllocationType(encodedVal, &cellParam);
1557                      }
1558                      break;
1559
1560                   case FAPI_PDSCH_VRB_TO_PRB_MAPPING_TAG:
1561                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1562                      if(encodedVal != RFAILED)
1563                      {
1564                         fillPrbMappingType(encodedVal, &cellParam);
1565                      }
1566                      break;
1567
1568                   case FAPI_PDSCH_CBG_TAG:
1569                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1570                      if(encodedVal != RFAILED && encodedVal != 0)
1571                      {
1572                         cellParam->pdschCbg = SUPPORTED;
1573                      }
1574                      else
1575                      {
1576                         cellParam->pdschCbg = NOT_SUPPORTED;
1577                      }
1578                      break;
1579
1580                   case FAPI_PDSCH_DMRS_CONFIG_TYPES_TAG:
1581                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1582                      if(encodedVal != RFAILED)
1583                      {
1584                         fillPdschDmrsConfigType(encodedVal, &cellParam);
1585                      }
1586                      break;
1587
1588                   case FAPI_PDSCH_DMRS_MAX_LENGTH_TAG:
1589                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1590                      if(encodedVal != RFAILED)
1591                      {
1592                         fillPdschDmrsLength(encodedVal, &cellParam);
1593                      }
1594                      break;
1595
1596                   case FAPI_PDSCH_DMRS_ADDITIONAL_POS_TAG:
1597                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1598                      if(encodedVal != RFAILED)
1599                      {
1600                         fillPdschDmrsAddPos(encodedVal, &cellParam);
1601                      }
1602                      break;
1603
1604                   case FAPI_MAX_PDSCHS_TBS_PER_SLOT_TAG:
1605                      cellParam->maxPdschsTBsPerSlot = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1606                      break;
1607
1608                   case FAPI_MAX_NUMBER_MIMO_LAYERS_PDSCH_TAG:
1609                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1610                      if(encodedVal != RFAILED && encodedVal < FAPI_MAX_NUMBERMIMO_LAYERS_PDSCH)
1611                      {
1612                         cellParam->maxNumberMimoLayersPdsch   = encodedVal;
1613                      }
1614                      break;
1615
1616                   case FAPI_SUPPORTED_MAX_MODULATION_ORDER_DL_TAG:
1617                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1618                      if(encodedVal != RFAILED)
1619                      {
1620                         fillModulationOrderDl(encodedVal, &cellParam);
1621                      }
1622                      break;
1623
1624                   case FAPI_MAX_MU_MIMO_USERS_DL_TAG:
1625                      cellParam->maxMuMimoUsersDl         = \
1626                                                            getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1627                      break;
1628
1629                   case FAPI_PDSCH_DATA_IN_DMRS_SYMBOLS_TAG:
1630                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1631                      if(encodedVal != RFAILED && encodedVal != 0)
1632                      {
1633                         cellParam->pdschDataInDmrsSymbols = SUPPORTED;
1634                      }
1635                      else
1636                      {
1637                         cellParam->pdschDataInDmrsSymbols = NOT_SUPPORTED;
1638                      }
1639                      break;
1640
1641                   case FAPI_PREMPTIONSUPPORT_TAG:
1642                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1643                      if(encodedVal != RFAILED && encodedVal != 0)
1644                      {
1645                         cellParam->premptionSupport = SUPPORTED;
1646                      }
1647                      else
1648                      {
1649                         cellParam->premptionSupport = NOT_SUPPORTED;
1650                      }
1651                      break;
1652
1653                   case FAPI_PDSCH_NON_SLOT_SUPPORT_TAG:
1654                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1655                      if(encodedVal != RFAILED && encodedVal != 0)
1656                      {
1657                         cellParam->pdschNonSlotSupport = SUPPORTED;
1658                      }
1659                      else
1660                      {
1661                         cellParam->pdschNonSlotSupport = NOT_SUPPORTED;
1662                      }
1663                      break;
1664
1665                   case FAPI_UCI_MUX_ULSCH_IN_PUSCH_TAG:
1666                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1667                      if(encodedVal != RFAILED && encodedVal != 0)
1668                      {
1669                         cellParam->uciMuxUlschInPusch = SUPPORTED;
1670                      }
1671                      else
1672                      {
1673                         cellParam->uciMuxUlschInPusch = NOT_SUPPORTED;
1674                      }
1675                      break;
1676
1677                   case FAPI_UCI_ONLY_PUSCH_TAG:
1678                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1679                      if(encodedVal != RFAILED && encodedVal != 0)
1680                      {
1681                         cellParam->uciOnlyPusch = SUPPORTED;
1682                      }
1683                      else
1684                      {
1685                         cellParam->uciOnlyPusch = NOT_SUPPORTED;
1686                      }
1687                      break;
1688
1689                   case FAPI_PUSCH_FREQUENCY_HOPPING_TAG:
1690                      encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1691                      if(encodedVal != RFAILED && encodedVal != 0)
1692                      {
1693                         cellParam->puschFrequencyHopping = SUPPORTED;
1694                      }
1695                      else
1696                      {
1697                         cellParam->puschFrequencyHopping = NOT_SUPPORTED;
1698                      }
1699                      break;
1700
1701                  case FAPI_PUSCH_DMRS_CONFIG_TYPES_TAG:
1702                     encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1703                     if(encodedVal != RFAILED)
1704                     {
1705                        fillPuschDmrsConfig(encodedVal, &cellParam);
1706                     }
1707                     break;
1708
1709                  case FAPI_PUSCH_DMRS_MAX_LEN_TAG:
1710                     encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1711                     if(encodedVal != RFAILED)
1712                     {
1713                        fillPuschDmrsLength(encodedVal, &cellParam);
1714                     }
1715                     break;
1716
1717                  case FAPI_PUSCH_DMRS_ADDITIONAL_POS_TAG:
1718                     encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1719                     if(encodedVal != RFAILED)
1720                     {
1721                        fillPuschDmrsAddPos(encodedVal, &cellParam);
1722                     }
1723                     break;
1724
1725                  case FAPI_PUSCH_CBG_TAG:
1726                     encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1727                     if(encodedVal != RFAILED && encodedVal != 0)
1728                     {
1729                        cellParam->puschCbg = SUPPORTED;
1730                     }
1731                     else
1732                     {
1733                        cellParam->puschCbg = NOT_SUPPORTED;
1734                     }
1735                     break;
1736
1737                 case FAPI_PUSCH_MAPPING_TYPE_TAG:
1738                    encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1739                    if(encodedVal != RFAILED)
1740                    {
1741                       fillPuschMappingType(encodedVal, &cellParam);
1742                    }
1743                    break;
1744
1745                 case FAPI_PUSCH_ALLOCATION_TYPES_TAG:
1746                    encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1747                    if(encodedVal != RFAILED)
1748                    {
1749                       fillPuschAllocationType(encodedVal, &cellParam);
1750                    }
1751                    break;
1752
1753                 case FAPI_PUSCH_VRB_TO_PRB_MAPPING_TAG:
1754                    encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1755                    if(encodedVal != RFAILED)
1756                    {
1757                       fillPuschPrbMappingType(encodedVal, &cellParam);
1758                    }
1759                    break;
1760
1761                 case FAPI_PUSCH_MAX_PTRS_PORTS_TAG:
1762                    encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1763                    if(encodedVal != RFAILED && encodedVal < FAPI_PUSCH_MAX_PTRS_PORTS_UB)
1764                    {
1765                       cellParam->puschMaxPtrsPorts = encodedVal;
1766                    }
1767                    break;
1768
1769                 case FAPI_MAX_PDUSCHS_TBS_PER_SLOT_TAG:
1770                    cellParam->maxPduschsTBsPerSlot = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1771                    break;
1772
1773                 case FAPI_MAX_NUMBER_MIMO_LAYERS_NON_CB_PUSCH_TAG:
1774                    cellParam->maxNumberMimoLayersNonCbPusch = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1775                    break;
1776
1777                 case FAPI_SUPPORTED_MODULATION_ORDER_UL_TAG:
1778                    encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1779                    if(encodedVal != RFAILED)
1780                    {
1781                       fillModulationOrderUl(encodedVal, &cellParam);
1782                    }
1783                    break;
1784
1785                 case FAPI_MAX_MU_MIMO_USERS_UL_TAG:
1786                    cellParam->maxMuMimoUsersUl = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1787                    break;
1788
1789                 case FAPI_DFTS_OFDM_SUPPORT_TAG:
1790                    encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1791                    if(encodedVal != RFAILED && encodedVal != 0)
1792                    {
1793                       cellParam->dftsOfdmSupport = SUPPORTED;
1794                    }
1795                    else
1796                    {
1797                       cellParam->dftsOfdmSupport = NOT_SUPPORTED;
1798                    }
1799                    break;
1800
1801                 case FAPI_PUSCH_AGGREGATION_FACTOR_TAG:
1802                    encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1803                    if(encodedVal != RFAILED)
1804                    {
1805                       fillPuschAggregationFactor(encodedVal, &cellParam);
1806                    }
1807                    break;
1808
1809                 case FAPI_PRACH_LONG_FORMATS_TAG:
1810                    encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1811                    if(encodedVal != RFAILED)
1812                    {
1813                       fillPrachLongFormat(encodedVal, &cellParam);
1814                    }
1815                    break;
1816
1817                 case FAPI_PRACH_SHORT_FORMATS_TAG:
1818                    encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1819                    if(encodedVal != RFAILED)
1820                    {
1821                       fillPrachShortFormat(encodedVal, &cellParam);
1822                    }
1823                    break;
1824
1825                 case FAPI_PRACH_RESTRICTED_SETS_TAG:
1826                    encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1827                    if(encodedVal != RFAILED && encodedVal != 0)
1828                    {
1829                       cellParam->prachRestrictedSets = SUPPORTED;
1830                    }
1831                    else
1832                    {
1833                       cellParam->prachRestrictedSets = NOT_SUPPORTED;
1834                    }
1835                    break;
1836
1837                case FAPI_MAX_PRACH_FD_OCCASIONS_IN_A_SLOT_TAG:
1838                   encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1839                   if(encodedVal != RFAILED)
1840                   {
1841                      fillFdOccasions(encodedVal, &cellParam);
1842                   }
1843                   break;
1844
1845                case FAPI_RSSI_MEASUREMENT_SUPPORT_TAG:
1846                   encodedVal = getParamValue(&paramRsp->tlvs[index], FAPI_UINT_8);
1847                   if(encodedVal != RFAILED)
1848                   {
1849                      fillRssiMeas(encodedVal, &cellParam);
1850                   }
1851                   break;
1852                default:
1853                //printf("\n Invalid value for TLV[%x] at index[%d]", paramRsp->tlvs[index].tl.tag, index);
1854                break;
1855               }
1856            }
1857            MAC_FREE(cellParam, sizeof(ClCellParam));
1858            sendToLowerMac(FAPI_CONFIG_REQUEST, 0, (void *)NULL);
1859            return ROK;
1860          }
1861          else
1862          {
1863             DU_LOG("\n LWR_MAC: Invalid error code %d", paramRsp->error_code);
1864             return RFAILED;
1865          }
1866      }
1867      else
1868      {
1869         DU_LOG("\nLWR_MAC: Failed to allocate memory for cell param");
1870         return RFAILED;
1871      }
1872    }
1873    else
1874    {
1875        DU_LOG("\nLWR_MAC:  Param Response received from PHY is NULL");
1876        return RFAILED;
1877    }
1878 #else
1879    return ROK;
1880 #endif
1881 }
1882
1883  /*******************************************************************
1884   *
1885   * @brief Sends FAPI Config req to PHY
1886   *
1887   * @details
1888   *
1889   *    Function : lwr_mac_handleConfigReqEvt
1890   *
1891   *    Functionality:
1892   *         -Sends FAPI Config Req to PHY
1893   *
1894   * @params[in]
1895   * @return ROK     - success
1896   *         RFAILED - failure
1897   *
1898   * ****************************************************************/
1899
1900 S16 lwr_mac_handleConfigReqEvt(void *msg)
1901 {
1902 #ifdef FAPI
1903    Inst inst = 0;
1904    uint8_t idx = 0;
1905    uint8_t index = 0;
1906    uint32_t msgLen = 0;
1907    uint32_t configReqSize;
1908    RgCellCb  *cellParams;
1909    MacCellCfg macCfgParams;
1910    fapi_config_req_t *configReq;
1911
1912    DU_LOG("\nLWR_MAC: Received EVENT[%d] at STATE[%d]", clGlobalCp.event, \
1913       clGlobalCp.phyState);
1914
1915    cellParams = rgCb[inst].cell;
1916    macCfgParams = cellParams->macCellCfg;
1917
1918    configReqSize = sizeof(fapi_config_req_t);
1919    LWR_MAC_ALLOC(configReq, configReqSize);
1920    if(configReq != NULL)
1921    {
1922       msgLen = sizeof(macCfgParams.numTlv);
1923       configReq->number_of_tlvs = macCfgParams.numTlv;
1924
1925       if(macCfgParams.dlCarrCfg.pres)
1926       {
1927          fillTlvs(&configReq->tlvs[index++], FAPI_DL_BANDWIDTH_TAG,           \
1928             sizeof(uint16_t), macCfgParams.dlCarrCfg.bw, &msgLen);
1929          fillTlvs(&configReq->tlvs[index++], FAPI_DL_FREQUENCY_TAG,           \
1930             sizeof(uint32_t), macCfgParams.dlCarrCfg.freq, &msgLen);
1931          fillTlvs(&configReq->tlvs[index++], FAPI_DL_K0_TAG,                  \
1932             sizeof(uint16_t), macCfgParams.dlCarrCfg.k0[0], &msgLen);
1933          fillTlvs(&configReq->tlvs[index++], FAPI_DL_GRIDSIZE_TAG,            \
1934             sizeof(uint16_t), macCfgParams.dlCarrCfg.gridSize[0], &msgLen);
1935          fillTlvs(&configReq->tlvs[index++], FAPI_NUM_TX_ANT_TAG,             \
1936             sizeof(uint16_t), macCfgParams.dlCarrCfg.numAnt, &msgLen);
1937       }
1938       if(macCfgParams.ulCarrCfg.pres)
1939       {
1940          fillTlvs(&configReq->tlvs[index++], FAPI_UPLINK_BANDWIDTH_TAG,       \
1941             sizeof(uint16_t), macCfgParams.ulCarrCfg.bw, &msgLen);
1942          fillTlvs(&configReq->tlvs[index++], FAPI_UPLINK_FREQUENCY_TAG,       \
1943             sizeof(uint32_t), macCfgParams.ulCarrCfg.freq, &msgLen);
1944          fillTlvs(&configReq->tlvs[index++], FAPI_UL_K0_TAG,                  \
1945             sizeof(uint16_t), macCfgParams.ulCarrCfg.k0[0], &msgLen);
1946          fillTlvs(&configReq->tlvs[index++], FAPI_UL_GRID_SIZE_TAG,           \
1947             sizeof(uint16_t), macCfgParams.ulCarrCfg.gridSize[0], &msgLen);
1948          fillTlvs(&configReq->tlvs[index++], FAPI_NUM_RX_ANT_TAG,             \
1949             sizeof(uint16_t), macCfgParams.ulCarrCfg.numAnt, &msgLen);
1950       }
1951       fillTlvs(&configReq->tlvs[index++], FAPI_FREQUENCY_SHIFT_7P5_KHZ_TAG,   \
1952          sizeof(uint8_t), macCfgParams.freqShft, &msgLen);
1953
1954       /* fill cell config */
1955       fillTlvs(&configReq->tlvs[index++], FAPI_PHY_CELL_ID_TAG,               \
1956          sizeof(uint8_t), macCfgParams.phyCellId, &msgLen);
1957       fillTlvs(&configReq->tlvs[index++], FAPI_FRAME_DUPLEX_TYPE_TAG,         \
1958          sizeof(uint8_t), macCfgParams.dupType, &msgLen);
1959
1960       /* fill SSB configuration */
1961       fillTlvs(&configReq->tlvs[index++], FAPI_SS_PBCH_POWER_TAG,             \
1962          sizeof(uint32_t), macCfgParams.ssbCfg.ssbPbchPwr, &msgLen);
1963       fillTlvs(&configReq->tlvs[index++], FAPI_BCH_PAYLOAD_TAG,               \
1964          sizeof(uint8_t), macCfgParams.ssbCfg.bchPayloadFlag, &msgLen);
1965       fillTlvs(&configReq->tlvs[index++], FAPI_SCS_COMMON_TAG,                \
1966          sizeof(uint8_t), macCfgParams.ssbCfg.scsCmn, &msgLen);
1967
1968       /* fill PRACH configuration */
1969       fillTlvs(&configReq->tlvs[index++], FAPI_PRACH_SEQUENCE_LENGTH_TAG,     \
1970          sizeof(uint8_t), macCfgParams.prachCfg.prachSeqLen, &msgLen);
1971       fillTlvs(&configReq->tlvs[index++], FAPI_PRACH_SUBC_SPACING_TAG,        \
1972          sizeof(uint8_t), macCfgParams.prachCfg.prachSubcSpacing, &msgLen);
1973       fillTlvs(&configReq->tlvs[index++], FAPI_RESTRICTED_SET_CONFIG_TAG,     \
1974          sizeof(uint8_t), macCfgParams.prachCfg.prachRstSetCfg, &msgLen);
1975       fillTlvs(&configReq->tlvs[index++], FAPI_NUM_PRACH_FD_OCCASIONS_TAG,
1976          sizeof(uint8_t), macCfgParams.prachCfg.msg1Fdm, &msgLen);
1977       fillTlvs(&configReq->tlvs[index++], FAPI_PRACH_ROOT_SEQUENCE_INDEX_TAG, \
1978          sizeof(uint16_t), macCfgParams.prachCfg.fdm[0].rootSeqIdx, &msgLen);
1979       fillTlvs(&configReq->tlvs[index++], FAPI_NUM_ROOT_SEQUENCES_TAG,        \
1980          sizeof(uint8_t), macCfgParams.prachCfg.fdm[0].numRootSeq, &msgLen);
1981       fillTlvs(&configReq->tlvs[index++], FAPI_K1_TAG,                        \
1982          sizeof(uint16_t), macCfgParams.prachCfg.fdm[0].k1, &msgLen);
1983       fillTlvs(&configReq->tlvs[index++], FAPI_PRACH_ZERO_CORR_CONF_TAG ,     \
1984          sizeof(uint8_t), macCfgParams.prachCfg.fdm[0].zeroCorrZoneCfg, &msgLen);
1985       fillTlvs(&configReq->tlvs[index++], FAPI_NUM_UNUSED_ROOT_SEQUENCES_TAG, \
1986          sizeof(uint8_t), macCfgParams.prachCfg.fdm[0].numUnusedRootSeq, &msgLen);
1987       if(macCfgParams.prachCfg.fdm[0].numUnusedRootSeq)
1988       {
1989          for(idx = 0; idx < macCfgParams.prachCfg.fdm[0].numUnusedRootSeq; idx++)
1990             fillTlvs(&configReq->tlvs[index++], FAPI_UNUSED_ROOT_SEQUENCES_TAG,   \
1991                sizeof(uint8_t), macCfgParams.prachCfg.fdm[0].unsuedRootSeq[idx], \
1992                &msgLen);
1993       }
1994       else
1995       {
1996          macCfgParams.prachCfg.fdm[0].unsuedRootSeq = NULL;
1997       }
1998
1999       fillTlvs(&configReq->tlvs[index++], FAPI_SSB_PER_RACH_TAG,              \
2000          sizeof(uint8_t), macCfgParams.prachCfg.ssbPerRach, &msgLen);
2001       fillTlvs(&configReq->tlvs[index++], FAPI_PRACH_MULTIPLE_CARRIERS_IN_A_BAND_TAG,  \
2002          sizeof(uint8_t), macCfgParams.prachCfg.prachMultCarrBand, &msgLen);
2003
2004       /* fill SSB table */
2005       fillTlvs(&configReq->tlvs[index++], FAPI_SSB_OFFSET_POINT_A_TAG,        \
2006          sizeof(uint16_t), macCfgParams.ssbCfg.ssbOffsetPointA, &msgLen);
2007       fillTlvs(&configReq->tlvs[index++], FAPI_BETA_PSS_TAG,                  \
2008          sizeof(uint8_t),  macCfgParams.ssbCfg.betaPss, &msgLen);
2009       fillTlvs(&configReq->tlvs[index++], FAPI_SSB_PERIOD_TAG,                \
2010          sizeof(uint8_t),  macCfgParams.ssbCfg.ssbPeriod, &msgLen);
2011       fillTlvs(&configReq->tlvs[index++], FAPI_SSB_SUBCARRIER_OFFSET_TAG,     \
2012          sizeof(uint8_t),  macCfgParams.ssbCfg.ssbScOffset, &msgLen);
2013       fillTlvs(&configReq->tlvs[index++], FAPI_MIB_TAG ,                      \
2014          sizeof(uint32_t), macCfgParams.ssbCfg.mibPdu[0], &msgLen);
2015       fillTlvs(&configReq->tlvs[index++], FAPI_SSB_MASK_TAG,                  \
2016          sizeof(uint32_t), macCfgParams.ssbCfg.ssbMask[0], &msgLen);
2017       fillTlvs(&configReq->tlvs[index++], FAPI_BEAM_ID_TAG,                   \
2018          sizeof(uint8_t),  macCfgParams.ssbCfg.beamId[0], &msgLen);
2019       fillTlvs(&configReq->tlvs[index++], FAPI_SS_PBCH_MULTIPLE_CARRIERS_IN_A_BAND_TAG, \
2020          sizeof(uint8_t), macCfgParams.ssbCfg.multCarrBand, &msgLen);
2021       fillTlvs(&configReq->tlvs[index++], FAPI_MULTIPLE_CELLS_SS_PBCH_IN_A_CARRIER_TAG, \
2022          sizeof(uint8_t), macCfgParams.ssbCfg.multCellCarr, &msgLen);
2023
2024       /* fill TDD table */
2025       fillTlvs(&configReq->tlvs[index++], FAPI_TDD_PERIOD_TAG,                \
2026          sizeof(uint8_t), macCfgParams.tddCfg.tddPeriod, &msgLen);
2027       fillTlvs(&configReq->tlvs[index++], FAPI_SLOT_CONFIG_TAG,               \
2028          sizeof(uint8_t), macCfgParams.tddCfg.slotCfg[0][0], &msgLen);
2029
2030       /* fill measurement config */
2031       fillTlvs(&configReq->tlvs[index++], FAPI_RSSI_MESUREMENT_TAG,           \
2032          sizeof(uint8_t), macCfgParams.rssiUnit, &msgLen);
2033
2034       fillMsgHeader(&configReq->header, FAPI_CONFIG_REQUEST, msgLen);
2035
2036       DU_LOG("\nLWR_MAC: Sending Config Request to Phy");
2037       LwrMacSendToPhy(configReq->header.message_type_id, configReqSize, (void *)configReq);
2038    }
2039    else
2040    {
2041       DU_LOG("\nLWR_MAC: Failed to allocate memory for config Request");
2042       return RFAILED;
2043    }
2044 #endif
2045
2046    return ROK;
2047 } /* lwr_mac_handleConfigReqEvt */
2048
2049 /*******************************************************************
2050  *
2051  * @brief Processes config response from phy
2052  *
2053  * @details
2054  *
2055  *    Function : lwr_mac_handleConfigRspEvt
2056  *
2057  *    Functionality:
2058  *          Processes config response from phy
2059  *
2060  * @params[in] FAPI message pointer 
2061  * @return ROK     - success
2062  *         RFAILED - failure
2063  *
2064  * ****************************************************************/
2065
2066 S16 lwr_mac_handleConfigRspEvt(void *msg)
2067 {
2068 #ifdef FAPI
2069    fapi_config_resp_t *configRsp;
2070    configRsp = (fapi_config_resp_t *)msg;
2071
2072    DU_LOG("\nLWR_MAC: Received EVENT[%d] at STATE[%d]", clGlobalCp.event, \
2073       clGlobalCp.phyState);
2074
2075    if(configRsp != NULL)
2076    {
2077       if(configRsp->error_code == MSG_OK)
2078       {
2079          DU_LOG("\nLWR_MAC: PHY has moved to Configured state \n");
2080          clGlobalCp.phyState = PHY_STATE_CONFIGURED;
2081          /* TODO : 
2082           * Store config response into an intermediate struture and send to MAC
2083           * Support LC and LWLC for sending config rsp to MAC 
2084           */
2085          fapiMacConfigRsp();
2086       }
2087       else
2088       {
2089          DU_LOG("\n LWR_MAC: Invalid error code %d", configRsp->error_code);
2090          return RFAILED;
2091       }
2092    }
2093    else
2094    {
2095       DU_LOG("\nLWR_MAC: Config Response received from PHY is NULL");
2096       return RFAILED;
2097    }
2098 #endif
2099
2100    return ROK;
2101 } /* lwr_mac_handleConfigRspEvt */
2102
2103 /*******************************************************************
2104  *
2105  * @brief Build and send start request to phy
2106  *
2107  * @details
2108  *
2109  *    Function : lwr_mac_handleStartReqEvt
2110  *
2111  *    Functionality:
2112  *       Build and send start request to phy
2113  *
2114  * @params[in] FAPI message pointer
2115  * @return ROK     - success
2116  *         RFAILED - failure
2117  *
2118  * ****************************************************************/
2119 S16 lwr_mac_handleStartReqEvt(void *msg)
2120 {
2121 #ifdef FAPI
2122    uint32_t msgLen = 0;
2123    fapi_start_req_t *startReq;
2124
2125    LWR_MAC_ALLOC(startReq, sizeof(fapi_start_req_t));
2126    if(startReq != NULL)
2127    {
2128       fillMsgHeader(&startReq->header, FAPI_START_REQUEST, msgLen);
2129
2130       DU_LOG("\nLWR_MAC: Sending Start Request to PHY");
2131       LwrMacSendToPhy(startReq->header.message_type_id, sizeof(fapi_start_req_t),\
2132          (void *)startReq);
2133    }
2134    else
2135    {
2136       DU_LOG("\nLWR_MAC: Failed to allocate memory for Start Request");
2137       return RFAILED;
2138    }
2139 #endif
2140    return ROK;
2141 } /* lwr_mac_handleStartReqEvt */
2142
2143  /*******************************************************************
2144   *
2145   * @brief Sends FAPI Stop Req to PHY
2146   *
2147   * @details
2148   *
2149   *    Function : lwr_mac_handleStopReqEvt
2150   *
2151   *    Functionality:
2152   *         -Sends FAPI Stop Req to PHY
2153   *
2154   * @params[in]
2155   * @return ROK     - success
2156   *         RFAILED - failure
2157   *
2158   ********************************************************************/
2159
2160 S16 lwr_mac_handleStopReqEvt(void *msg)
2161 {
2162 #ifdef FAPI
2163    uint32_t msgLen = 0;
2164    fapi_stop_req_t *stopReq = NULLP;
2165    LWR_MAC_ALLOC(stopReq, sizeof(fapi_stop_req_t));
2166    if(stopReq != NULLP)
2167    {
2168       fillMsgHeader(&stopReq->header, FAPI_STOP_REQUEST, msgLen);
2169       DU_LOG("\nLOWER MAC: Sending Stop Request to PHY");
2170       LwrMacSendToPhy(stopReq->header.message_type_id, sizeof(fapi_stop_req_t), (void *)stopReq);
2171    }
2172    else
2173    {
2174       DU_LOG("\nLOWER MAC: Failed to allocate memory for Stop Request");
2175       return RFAILED;
2176    }
2177 #endif
2178    return ROK;
2179 }
2180
2181 /*******************************************************************
2182  *
2183  * @brief Modifes the received mibPdu to uint32 bit
2184  *        and stores it in MacCellCfg
2185  *
2186  * @details
2187  *
2188  *    Function : setMibPdu
2189  *
2190  *    Functionality:
2191  *         -Sets the MibPdu
2192  *
2193  * @params[in] Pointer to mibPdu
2194  *             pointer to modified value
2195  ******************************************************************/
2196
2197 PUBLIC void setMibPdu(uint8_t *mibPdu, uint32_t *val, uint16_t sfn)
2198 {
2199    *mibPdu |= (((uint8_t)(sfn >> 2)) & MIB_SFN_BITMASK);
2200    *val = (mibPdu[0] << 24 | mibPdu[1] << 16 | mibPdu[2] << 8);
2201     DU_LOG("\nLWR_MAC: MIB PDU %x", *val);
2202 }
2203
2204 #ifdef FAPI
2205 /*******************************************************************
2206  *
2207  * @brief fills SSB PDU required for DL TTI info in MAC
2208  *
2209  * @details
2210  *
2211  *    Function : fillSsbPdu
2212  *
2213  *    Functionality:
2214  *         -Fills the SSB PDU info
2215  *          stored in MAC
2216  *
2217  * @params[in] Pointer to FAPI DL TTI Req
2218  *             Pointer to RgCellCb
2219  *             Pointer to msgLen of DL TTI Info
2220  * @return ROK
2221  *
2222  ******************************************************************/
2223
2224 S16 fillSsbPdu(fapi_dl_tti_req_pdu_t *dlTtiReqPdu, MacCellCfg *macCellCfg,
2225    MacDlSlot *currDlSlot, uint32_t *msgLen, uint8_t ssbIdxCount, uint16_t sfn)
2226 {
2227    uint32_t mibPayload = 0;
2228    if(dlTtiReqPdu != NULL)
2229    {
2230       dlTtiReqPdu->pduType = SSB_PDU_TYPE;     /* SSB PDU */
2231       dlTtiReqPdu->u.ssb_pdu.physCellId = macCellCfg->phyCellId;
2232       dlTtiReqPdu->u.ssb_pdu.betaPss = macCellCfg->ssbCfg.betaPss;
2233       dlTtiReqPdu->u.ssb_pdu.ssbBlockIndex = currDlSlot->dlInfo.brdcstAlloc.ssbInfo[ssbIdxCount].ssbIdx;
2234       dlTtiReqPdu->u.ssb_pdu.ssbSubCarrierOffset = macCellCfg->ssbCfg.ssbScOffset;
2235       /* ssbOfPdufstA to be filled in ssbCfg */
2236       dlTtiReqPdu->u.ssb_pdu.ssbOffsetPointA = macCellCfg->ssbCfg.ssbOffsetPointA;
2237       dlTtiReqPdu->u.ssb_pdu.bchPayloadFlag = macCellCfg->ssbCfg.bchPayloadFlag;
2238       /* Bit manipulation for SFN */
2239       setMibPdu(macCellCfg->ssbCfg.mibPdu, &mibPayload, sfn);
2240       dlTtiReqPdu->u.ssb_pdu.bchPayload.v.bchPayload = mibPayload;
2241       dlTtiReqPdu->u.ssb_pdu.preCodingAndBeamforming.numPrgs = 0;
2242       dlTtiReqPdu->u.ssb_pdu.preCodingAndBeamforming.prgSize = 0;
2243       dlTtiReqPdu->u.ssb_pdu.preCodingAndBeamforming.digBfInterfaces = 0;
2244       dlTtiReqPdu->u.ssb_pdu.preCodingAndBeamforming.pmi_bfi[0].pmIdx = 0;
2245       dlTtiReqPdu->u.ssb_pdu.preCodingAndBeamforming. \
2246          pmi_bfi[0].beamIdx[0].beamidx = macCellCfg->ssbCfg.beamId[0];
2247       dlTtiReqPdu->pduSize = sizeof(fapi_dl_ssb_pdu_t);  /* Size of SSB PDU */
2248       SET_MSG_LEN(*msgLen, (sizeof(dlTtiReqPdu->pduType) + \
2249          sizeof(dlTtiReqPdu->pduSize) + sizeof(fapi_dl_ssb_pdu_t)));
2250       return ROK;
2251     }
2252     else
2253     {
2254        return RFAILED;
2255     }
2256 }
2257
2258 /*******************************************************************
2259  *
2260  * @brief fills Dl DCI PDU required for DL TTI info in MAC
2261  *
2262  * @details
2263  *
2264  *    Function : fillSib1DlDciPdu
2265  *
2266  *    Functionality:
2267  *         -Fills the Dl DCI PDU
2268  *
2269  * @params[in] Pointer to fapi_dl_dci_t
2270  *             Pointer to PdcchCfg
2271  * @return ROK
2272  *
2273  ******************************************************************/
2274
2275 void fillSib1DlDciPdu(fapi_dl_dci_t *dlDciPtr, PdcchCfg *sib1PdcchInfo)
2276 {
2277    if(dlDciPtr != NULLP)
2278    {
2279       uint8_t numBytes;
2280       uint8_t bytePos;
2281       uint8_t bitPos;
2282       
2283       uint16_t coreset0Size;
2284       uint16_t rbStart;
2285       uint16_t rbLen;
2286       uint32_t freqDomResAssign;
2287       uint32_t timeDomResAssign;
2288       uint8_t  VRB2PRBMap;
2289       uint32_t modNCodScheme;
2290       uint8_t  redundancyVer;
2291       uint32_t sysInfoInd;
2292       uint32_t reserved;
2293
2294       /* Size(in bits) of each field in DCI format 0_1 
2295        * as mentioned in spec 38.214 */
2296       uint8_t freqDomResAssignSize;
2297       uint8_t timeDomResAssignSize = 4;
2298       uint8_t VRB2PRBMapSize       = 1;
2299       uint8_t modNCodSchemeSize    = 5;
2300       uint8_t redundancyVerSize    = 2;
2301       uint8_t sysInfoIndSize       = 1;
2302       uint8_t reservedSize         = 15;
2303
2304       dlDciPtr->rnti = sib1PdcchInfo->dci.rnti;
2305       dlDciPtr->scramblingId = sib1PdcchInfo->dci.scramblingId;    
2306       dlDciPtr->scramblingRnti = sib1PdcchInfo->dci.scramblingRnti;
2307       dlDciPtr->cceIndex = sib1PdcchInfo->dci.cceIndex;
2308       dlDciPtr->aggregationLevel = sib1PdcchInfo->dci.aggregLevel;
2309       dlDciPtr->pc_and_bform.numPrgs = sib1PdcchInfo->dci.beamPdcchInfo.numPrgs;
2310       dlDciPtr->pc_and_bform.prgSize = sib1PdcchInfo->dci.beamPdcchInfo.prgSize;
2311       dlDciPtr->pc_and_bform.digBfInterfaces = sib1PdcchInfo->dci.beamPdcchInfo.digBfInterfaces;
2312       dlDciPtr->pc_and_bform.pmi_bfi[0].pmIdx = sib1PdcchInfo->dci.beamPdcchInfo.prg[0].pmIdx;
2313       dlDciPtr->pc_and_bform.pmi_bfi[0].beamIdx[0].beamidx = sib1PdcchInfo->dci.beamPdcchInfo.prg[0].beamIdx[0];
2314       dlDciPtr->beta_pdcch_1_0 = sib1PdcchInfo->dci.txPdcchPower.powerValue;           
2315       dlDciPtr->powerControlOfssetSS = sib1PdcchInfo->dci.txPdcchPower.powerControlOffsetSS;
2316
2317       /* Calculating freq domain resource allocation field value and size
2318        * coreset0Size = Size of coreset 0
2319        * RBStart = Starting Virtual Rsource block
2320        * RBLen = length of contiguously allocted RBs
2321        * Spec 38.214 Sec 5.1.2.2.2
2322        */
2323       coreset0Size= sib1PdcchInfo->coreset0Cfg.coreSet0Size;
2324       rbStart = 0;              /* For SIB1 */
2325       //rbStart = sib1PdcchInfo->dci.pdschCfg->pdschFreqAlloc.freqAlloc.startPrb;
2326       rbLen = sib1PdcchInfo->dci.pdschCfg->pdschFreqAlloc.freqAlloc.numPrb;
2327
2328       if((rbLen >=1) && (rbLen <= coreset0Size - rbStart))
2329       {
2330          if((rbLen - 1) <= floor(coreset0Size / 2))
2331             freqDomResAssign = (coreset0Size * (rbLen-1)) + rbStart;
2332          else
2333             freqDomResAssign = (coreset0Size * (coreset0Size - rbLen + 1)) \
2334                + (coreset0Size - 1 - rbStart);
2335
2336          freqDomResAssignSize = ceil(log2(coreset0Size * (coreset0Size + 1) / 2));
2337       }
2338
2339       /* Fetching DCI field values */
2340       timeDomResAssign = sib1PdcchInfo->dci.pdschCfg->pdschTimeAlloc.
2341                          rowIndex -1;
2342       VRB2PRBMap       = sib1PdcchInfo->dci.pdschCfg->pdschFreqAlloc.\
2343                          vrbPrbMapping;
2344       modNCodScheme    = sib1PdcchInfo->dci.pdschCfg->codeword[0].mcsIndex;
2345       redundancyVer    = sib1PdcchInfo->dci.pdschCfg->codeword[0].rvIndex;
2346       sysInfoInd       = 0;           /* 0 for SIB1; 1 for SI messages */
2347       reserved         = 0;
2348
2349       /* Reversing bits in each DCI field */
2350       freqDomResAssign = reverseBits(freqDomResAssign, freqDomResAssignSize);
2351       timeDomResAssign = reverseBits(timeDomResAssign, timeDomResAssignSize);
2352       VRB2PRBMap       = reverseBits(VRB2PRBMap, VRB2PRBMapSize);
2353       modNCodScheme    = reverseBits(modNCodScheme, modNCodSchemeSize);
2354       redundancyVer    = reverseBits(redundancyVer, redundancyVerSize);
2355       sysInfoInd       = reverseBits(sysInfoInd, sysInfoIndSize);
2356
2357      /* Calulating total number of bytes in buffer */
2358      dlDciPtr->payloadSizeBits = freqDomResAssignSize + timeDomResAssignSize\
2359               + VRB2PRBMapSize + modNCodSchemeSize + redundancyVerSize\
2360               + sysInfoIndSize + reservedSize;
2361
2362      numBytes = dlDciPtr->payloadSizeBits / 8;
2363      if(dlDciPtr->payloadSizeBits % 8)
2364         numBytes += 1;
2365
2366      if(numBytes > DCI_PAYLOAD_BYTE_LEN)
2367      {
2368         DU_LOG("\nLWR_MAC : Total bytes for DCI is more than expected");
2369         return;
2370      }
2371
2372      /* Initialize buffer */
2373      for(bytePos = 0; bytePos < numBytes; bytePos++)
2374         dlDciPtr->payload[bytePos] = 0;
2375
2376      bytePos = numBytes - 1;
2377      bitPos = 0;
2378
2379      /* Packing DCI format fields */
2380      fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2381         freqDomResAssign, freqDomResAssignSize);
2382      fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2383         timeDomResAssign, timeDomResAssignSize);
2384      fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2385         VRB2PRBMap, VRB2PRBMapSize);
2386      fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2387         modNCodScheme, modNCodSchemeSize);
2388      fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2389         redundancyVer, redundancyVerSize);
2390      fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2391         sysInfoInd, sysInfoIndSize);
2392      fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2393         reserved, reservedSize);
2394
2395    }
2396 } /* fillSib1DlDciPdu */
2397
2398 /*******************************************************************
2399  *
2400  * @brief fills Dl DCI PDU required for DL TTI info in MAC
2401  *
2402  * @details
2403  *
2404  *    Function : fillRarDlDciPdu
2405  *
2406  *    Functionality:
2407  *         -Fills the Dl DCI PDU
2408  *
2409  * @params[in] Pointer to fapi_dl_dci_t
2410  *             Pointer to PdcchCfg
2411  * @return ROK
2412  *
2413  ******************************************************************/
2414
2415 void fillRarDlDciPdu(fapi_dl_dci_t *dlDciPtr, PdcchCfg *rarPdcchInfo)
2416 {
2417    if(dlDciPtr != NULLP)
2418    {
2419       uint8_t numBytes;
2420       uint8_t bytePos;
2421       uint8_t bitPos;
2422
2423       uint16_t coreset0Size;
2424       uint16_t rbStart;
2425       uint16_t rbLen;
2426       uint32_t freqDomResAssign;
2427       uint8_t timeDomResAssign;
2428       uint8_t  VRB2PRBMap;
2429       uint8_t modNCodScheme;
2430       uint8_t tbScaling;
2431       uint32_t reserved;
2432
2433       /* Size(in bits) of each field in DCI format 1_0 */
2434       uint8_t freqDomResAssignSize;
2435       uint8_t timeDomResAssignSize = 4;
2436       uint8_t VRB2PRBMapSize       = 1;
2437       uint8_t modNCodSchemeSize    = 5;
2438       uint8_t tbScalingSize        = 2;
2439       uint8_t reservedSize         = 16;
2440
2441       dlDciPtr->rnti = rarPdcchInfo->dci.rnti;
2442       dlDciPtr->scramblingId = rarPdcchInfo->dci.scramblingId;    
2443       dlDciPtr->scramblingRnti = rarPdcchInfo->dci.scramblingRnti;
2444       dlDciPtr->cceIndex = rarPdcchInfo->dci.cceIndex;
2445       dlDciPtr->aggregationLevel = rarPdcchInfo->dci.aggregLevel;
2446       dlDciPtr->pc_and_bform.numPrgs = rarPdcchInfo->dci.beamPdcchInfo.numPrgs;
2447       dlDciPtr->pc_and_bform.prgSize = rarPdcchInfo->dci.beamPdcchInfo.prgSize;
2448       dlDciPtr->pc_and_bform.digBfInterfaces = rarPdcchInfo->dci.beamPdcchInfo.digBfInterfaces;
2449       dlDciPtr->pc_and_bform.pmi_bfi[0].pmIdx = rarPdcchInfo->dci.beamPdcchInfo.prg[0].pmIdx;
2450       dlDciPtr->pc_and_bform.pmi_bfi[0].beamIdx[0].beamidx = rarPdcchInfo->dci.beamPdcchInfo.prg[0].beamIdx[0];
2451       dlDciPtr->beta_pdcch_1_0 = rarPdcchInfo->dci.txPdcchPower.powerValue;           
2452       dlDciPtr->powerControlOfssetSS = rarPdcchInfo->dci.txPdcchPower.powerControlOffsetSS;
2453
2454       /* Calculating freq domain resource allocation field value and size
2455        * coreset0Size = Size of coreset 0
2456        * RBStart = Starting Virtual Rsource block
2457        * RBLen = length of contiguously allocted RBs
2458        * Spec 38.214 Sec 5.1.2.2.2
2459        */
2460
2461       /* TODO: Fill values of coreset0Size, rbStart and rbLen */
2462       coreset0Size= rarPdcchInfo->coreset0Cfg.coreSet0Size;
2463       rbStart = 0;              /* For SIB1 */
2464       //rbStart = rarPdcchInfo->dci.pdschCfg->freqAlloc.rbStart;
2465       rbLen = rarPdcchInfo->dci.pdschCfg->pdschFreqAlloc.freqAlloc.numPrb;
2466
2467       if((rbLen >=1) && (rbLen <= coreset0Size - rbStart))
2468       {
2469          if((rbLen - 1) <= floor(coreset0Size / 2))
2470             freqDomResAssign = (coreset0Size * (rbLen-1)) + rbStart;
2471          else
2472             freqDomResAssign = (coreset0Size * (coreset0Size - rbLen + 1)) \
2473                                + (coreset0Size - 1 - rbStart);
2474
2475          freqDomResAssignSize = ceil(log2(coreset0Size * (coreset0Size + 1) / 2));
2476       }
2477
2478       /* Fetching DCI field values */
2479       timeDomResAssign = rarPdcchInfo->dci.pdschCfg->pdschTimeAlloc.rowIndex -1;
2480       VRB2PRBMap       = rarPdcchInfo->dci.pdschCfg->pdschFreqAlloc.vrbPrbMapping;
2481       modNCodScheme    = rarPdcchInfo->dci.pdschCfg->codeword[0].mcsIndex;
2482       tbScaling        = 0; /* configured to 0 scaling */
2483       reserved         = 0;
2484
2485       /* Reversing bits in each DCI field */
2486       freqDomResAssign = reverseBits(freqDomResAssign, freqDomResAssignSize);
2487       timeDomResAssign = reverseBits(timeDomResAssign, timeDomResAssignSize);
2488       VRB2PRBMap       = reverseBits(VRB2PRBMap, VRB2PRBMapSize);
2489       modNCodScheme    = reverseBits(modNCodScheme, modNCodSchemeSize);
2490       tbScaling        = reverseBits(tbScaling, tbScalingSize); 
2491
2492       /* Calulating total number of bytes in buffer */
2493       dlDciPtr->payloadSizeBits = freqDomResAssignSize + timeDomResAssignSize\
2494                                   + VRB2PRBMapSize + modNCodSchemeSize + tbScalingSize + reservedSize;
2495
2496       numBytes = dlDciPtr->payloadSizeBits / 8;
2497       if(dlDciPtr->payloadSizeBits % 8)
2498          numBytes += 1;
2499
2500       if(numBytes > DCI_PAYLOAD_BYTE_LEN)
2501       {
2502          DU_LOG("\nLWR_MAC : Total bytes for DCI is more than expected");
2503          return;
2504       }
2505
2506       /* Initialize buffer */
2507       for(bytePos = 0; bytePos < numBytes; bytePos++)
2508          dlDciPtr->payload[bytePos] = 0;
2509
2510       bytePos = numBytes - 1;
2511       bitPos = 0;
2512
2513       /* Packing DCI format fields */
2514       fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2515             freqDomResAssign, freqDomResAssignSize);
2516       fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2517             timeDomResAssign, timeDomResAssignSize);
2518       fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2519             VRB2PRBMap, VRB2PRBMapSize);
2520       fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2521             modNCodScheme, modNCodSchemeSize);
2522       fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2523             tbScaling, tbScalingSize);
2524       fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2525             reserved, reservedSize);
2526    }
2527 } /* fillRarDlDciPdu */
2528
2529 /*******************************************************************
2530  *
2531  * @brief fills msg4 Dl DCI PDU required for DL TTI info in MAC
2532  *
2533  * @details
2534  *
2535  *    Function : fillMsg4DlDciPdu
2536  *
2537  *    Functionality:
2538  *         -Fills the Msg4 Dl DCI PDU
2539  *
2540  * @params[in] Pointer to fapi_dl_dci_t
2541  *             Pointer to PdcchCfg
2542  * @return ROK
2543  *
2544  ******************************************************************/
2545 void fillMsg4DlDciPdu(fapi_dl_dci_t *dlDciPtr, PdcchCfg *msg4PdcchInfo,\
2546 Msg4Info *msg4Info)
2547 {
2548    if(dlDciPtr != NULLP)
2549    {
2550       uint8_t numBytes;
2551       uint8_t bytePos;
2552       uint8_t bitPos;
2553
2554       uint16_t coreset0Size = 0;
2555       uint16_t rbStart = 0;
2556       uint16_t rbLen = 0;
2557       uint8_t  dciFormatId;
2558       uint32_t freqDomResAssign;
2559       uint8_t  timeDomResAssign;
2560       uint8_t  VRB2PRBMap;
2561       uint8_t  modNCodScheme;
2562       uint8_t  ndi = 0;
2563       uint8_t  redundancyVer = 0;
2564       uint8_t  harqProcessNum = 0;
2565       uint8_t  dlAssignmentIdx = 0;
2566       uint8_t  pucchTpc = 0;
2567       uint8_t  pucchResoInd = 0;
2568       uint8_t  harqFeedbackInd = 0;
2569
2570       /* Size(in bits) of each field in DCI format 1_0 */
2571       uint8_t dciFormatIdSize    = 1;
2572       uint8_t freqDomResAssignSize;
2573       uint8_t timeDomResAssignSize = 4;
2574       uint8_t VRB2PRBMapSize       = 1;
2575       uint8_t modNCodSchemeSize    = 5;
2576       uint8_t ndiSize              = 1;
2577       uint8_t redundancyVerSize    = 2;
2578       uint8_t harqProcessNumSize   = 4;
2579       uint8_t dlAssignmentIdxSize  = 2;
2580       uint8_t pucchTpcSize         = 2;
2581       uint8_t pucchResoIndSize     = 3;
2582       uint8_t harqFeedbackIndSize  = 3;
2583
2584       dlDciPtr->rnti = msg4PdcchInfo->dci.rnti;
2585       dlDciPtr->scramblingId = msg4PdcchInfo->dci.scramblingId;    
2586       dlDciPtr->scramblingRnti = msg4PdcchInfo->dci.scramblingRnti;
2587       dlDciPtr->cceIndex = msg4PdcchInfo->dci.cceIndex;
2588       dlDciPtr->aggregationLevel = msg4PdcchInfo->dci.aggregLevel;
2589       dlDciPtr->pc_and_bform.numPrgs = msg4PdcchInfo->dci.beamPdcchInfo.numPrgs;
2590       dlDciPtr->pc_and_bform.prgSize = msg4PdcchInfo->dci.beamPdcchInfo.prgSize;
2591       dlDciPtr->pc_and_bform.digBfInterfaces = msg4PdcchInfo->dci.beamPdcchInfo.digBfInterfaces;
2592       dlDciPtr->pc_and_bform.pmi_bfi[0].pmIdx = msg4PdcchInfo->dci.beamPdcchInfo.prg[0].pmIdx;
2593       dlDciPtr->pc_and_bform.pmi_bfi[0].beamIdx[0].beamidx = msg4PdcchInfo->dci.beamPdcchInfo.prg[0].beamIdx[0];
2594       dlDciPtr->beta_pdcch_1_0 = msg4PdcchInfo->dci.txPdcchPower.powerValue;           
2595       dlDciPtr->powerControlOfssetSS = msg4PdcchInfo->dci.txPdcchPower.powerControlOffsetSS;
2596
2597       /* Calculating freq domain resource allocation field value and size
2598        * coreset0Size = Size of coreset 0
2599        * RBStart = Starting Virtual Rsource block
2600        * RBLen = length of contiguously allocted RBs
2601        * Spec 38.214 Sec 5.1.2.2.2
2602        */
2603
2604       /* TODO: Fill values of coreset0Size, rbStart and rbLen */
2605       coreset0Size = msg4PdcchInfo->coreset0Cfg.coreSet0Size;
2606       //rbStart = msg4PdcchInfo->dci.pdschCfg->freqAlloc.rbStart;
2607       rbLen = msg4PdcchInfo->dci.pdschCfg->pdschFreqAlloc.freqAlloc.numPrb;
2608
2609       if((rbLen >=1) && (rbLen <= coreset0Size - rbStart))
2610       {
2611          if((rbLen - 1) <= floor(coreset0Size / 2))
2612             freqDomResAssign = (coreset0Size * (rbLen-1)) + rbStart;
2613          else
2614             freqDomResAssign = (coreset0Size * (coreset0Size - rbLen + 1)) \
2615                                + (coreset0Size - 1 - rbStart);
2616
2617          freqDomResAssignSize = ceil(log2(coreset0Size * (coreset0Size + 1) / 2));
2618       }
2619
2620       /* Fetching DCI field values */
2621       dciFormatId      = msg4Info->dciFormatId; /* DCI indentifier for DL */
2622       timeDomResAssign = msg4PdcchInfo->dci.pdschCfg->pdschTimeAlloc.rowIndex -1;
2623       VRB2PRBMap       = msg4PdcchInfo->dci.pdschCfg->pdschFreqAlloc.vrbPrbMapping;
2624       modNCodScheme    = msg4PdcchInfo->dci.pdschCfg->codeword[0].mcsIndex;
2625       ndi              = msg4Info->ndi;      
2626       redundancyVer    = msg4PdcchInfo->dci.pdschCfg->codeword[0].rvIndex;
2627       harqProcessNum   = msg4Info->harqProcNum; 
2628       dlAssignmentIdx  = msg4Info->dlAssignIdx;
2629       pucchTpc         = msg4Info->pucchTpc;
2630       pucchResoInd     = msg4Info->pucchResInd;
2631       harqFeedbackInd  = msg4Info->harqFeedbackInd;
2632
2633       /* Reversing bits in each DCI field */
2634       dciFormatId      = reverseBits(dciFormatId, dciFormatIdSize);
2635       freqDomResAssign = reverseBits(freqDomResAssign, freqDomResAssignSize);
2636       timeDomResAssign = reverseBits(timeDomResAssign, timeDomResAssignSize);
2637       VRB2PRBMap       = reverseBits(VRB2PRBMap, VRB2PRBMapSize);
2638       modNCodScheme    = reverseBits(modNCodScheme, modNCodSchemeSize);
2639       ndi              = reverseBits(ndi, ndiSize);
2640       redundancyVer    = reverseBits(redundancyVer, redundancyVerSize);
2641       harqProcessNum   = reverseBits(harqProcessNum, harqProcessNumSize);
2642       dlAssignmentIdx  = reverseBits(dlAssignmentIdx , dlAssignmentIdxSize);
2643       pucchTpc         = reverseBits(pucchTpc, pucchTpcSize);
2644       pucchResoInd     = reverseBits(pucchResoInd, pucchResoIndSize);
2645       harqFeedbackInd  = reverseBits(harqFeedbackInd, harqFeedbackIndSize);
2646
2647
2648       /* Calulating total number of bytes in buffer */
2649       dlDciPtr->payloadSizeBits = (dciFormatIdSize + freqDomResAssignSize\
2650       + timeDomResAssignSize + VRB2PRBMapSize + modNCodSchemeSize\
2651       + ndiSize + redundancyVerSize + harqProcessNumSize + dlAssignmentIdxSize\
2652       + pucchTpcSize + pucchResoIndSize + harqFeedbackIndSize);
2653
2654       numBytes = dlDciPtr->payloadSizeBits / 8;
2655       if(dlDciPtr->payloadSizeBits % 8)
2656          numBytes += 1;
2657
2658       if(numBytes > DCI_PAYLOAD_BYTE_LEN)
2659       {
2660          DU_LOG("\nLWR_MAC : Total bytes for DCI is more than expected");
2661          return;
2662       }
2663
2664       /* Initialize buffer */
2665       for(bytePos = 0; bytePos < numBytes; bytePos++)
2666          dlDciPtr->payload[bytePos] = 0;
2667
2668       bytePos = numBytes - 1;
2669       bitPos = 0;
2670
2671       /* Packing DCI format fields */
2672       fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2673             dciFormatId, dciFormatIdSize);
2674       fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2675             freqDomResAssign, freqDomResAssignSize);
2676       fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2677             timeDomResAssign, timeDomResAssignSize);
2678       fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2679             VRB2PRBMap, VRB2PRBMapSize);
2680       fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2681             modNCodScheme, modNCodSchemeSize);
2682       fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2683             ndi, ndiSize);
2684       fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2685             redundancyVer, redundancyVerSize);
2686       fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2687             redundancyVer, redundancyVerSize);
2688       fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2689             harqProcessNum, harqProcessNumSize);
2690       fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2691             dlAssignmentIdx, dlAssignmentIdxSize);
2692       fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2693             pucchTpc, pucchTpcSize);
2694       fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2695             pucchResoInd, pucchResoIndSize);
2696       fillDlDciPayload(dlDciPtr->payload, &bytePos, &bitPos,\
2697             harqFeedbackInd, harqFeedbackIndSize);
2698    }
2699 } /* fillMsg4DlDciPdu */
2700
2701 /*******************************************************************
2702  *
2703  * @brief fills PDCCH PDU required for DL TTI info in MAC
2704  *
2705  * @details
2706  *
2707  *    Function : fillPdcchPdu
2708  *
2709  *    Functionality:
2710  *         -Fills the Pdcch PDU info
2711  *          stored in MAC
2712  *
2713  * @params[in] Pointer to FAPI DL TTI Req
2714  *             Pointer to PdcchCfg
2715  *             Pointer to msgLen of DL TTI Info
2716  * @return ROK
2717  *
2718  ******************************************************************/
2719 S16 fillPdcchPdu(fapi_dl_tti_req_pdu_t *dlTtiReqPdu, DlSchedInfo *dlInfo, uint32_t *msgLen, RntiType rntiType)
2720 {
2721    if(dlTtiReqPdu != NULLP)
2722    {
2723       PdcchCfg *pdcchInfo = NULLP;
2724       BwpCfg *bwp = NULLP;
2725
2726       dlTtiReqPdu->u.pdcch_pdu.dlDci = (fapi_dl_dci_t *)(dlTtiReqPdu + \
2727          (sizeof(fapi_dl_tti_req_pdu_t) - sizeof(dlTtiReqPdu->u)) + \
2728          (sizeof(fapi_dl_pdcch_pdu_t) - sizeof(fapi_dl_dci_t*)));
2729
2730       if(rntiType == SI_RNTI_TYPE)
2731       {
2732          pdcchInfo = &dlInfo->brdcstAlloc.sib1Alloc.sib1PdcchCfg;
2733          bwp = &dlInfo->brdcstAlloc.sib1Alloc.bwp;
2734          fillSib1DlDciPdu(dlTtiReqPdu->u.pdcch_pdu.dlDci, pdcchInfo);
2735       }
2736       else if(rntiType == RA_RNTI_TYPE)
2737       {
2738          pdcchInfo = &dlInfo->rarAlloc->rarPdcchCfg;
2739          bwp = &dlInfo->rarAlloc->bwp;
2740          fillRarDlDciPdu(dlTtiReqPdu->u.pdcch_pdu.dlDci, pdcchInfo);
2741       }
2742       else if(rntiType == TC_RNTI_TYPE)
2743       {
2744          pdcchInfo = &dlInfo->msg4Alloc->msg4PdcchCfg;
2745          bwp = &dlInfo->msg4Alloc->bwp;
2746          fillMsg4DlDciPdu(dlTtiReqPdu->u.pdcch_pdu.dlDci, pdcchInfo,\
2747             &dlInfo->msg4Alloc->msg4Info);
2748       }
2749       else
2750       {
2751          DU_LOG("\nLWR_MAC: Failed filling PDCCH Pdu");
2752          return RFAILED;;
2753       }
2754       dlTtiReqPdu->pduType = PDCCH_PDU_TYPE;
2755       dlTtiReqPdu->u.pdcch_pdu.bwpSize = bwp->freqAlloc.numPrb;
2756       dlTtiReqPdu->u.pdcch_pdu.bwpPart = bwp->freqAlloc.startPrb;
2757       dlTtiReqPdu->u.pdcch_pdu.subCarrierSpacing = bwp->subcarrierSpacing; 
2758       dlTtiReqPdu->u.pdcch_pdu.cyclicPrefix = bwp->cyclicPrefix; 
2759       dlTtiReqPdu->u.pdcch_pdu.startSymbolIndex = pdcchInfo->coreset0Cfg.startSymbolIndex;
2760       dlTtiReqPdu->u.pdcch_pdu.durationSymbols = pdcchInfo->coreset0Cfg.durationSymbols;
2761       memcpy(dlTtiReqPdu->u.pdcch_pdu.freqDomainResource, pdcchInfo->coreset0Cfg.freqDomainResource, 6);
2762       dlTtiReqPdu->u.pdcch_pdu.cceRegMappingType = pdcchInfo->coreset0Cfg.cceRegMappingType;
2763       dlTtiReqPdu->u.pdcch_pdu.regBundleSize = pdcchInfo->coreset0Cfg.regBundleSize;
2764       dlTtiReqPdu->u.pdcch_pdu.interleaverSize = pdcchInfo->coreset0Cfg.interleaverSize;
2765       dlTtiReqPdu->u.pdcch_pdu.coreSetSize = pdcchInfo->coreset0Cfg.coreSetType;
2766       dlTtiReqPdu->u.pdcch_pdu.shiftIndex =  pdcchInfo->coreset0Cfg.shiftIndex;
2767       dlTtiReqPdu->u.pdcch_pdu.precoderGranularity = pdcchInfo->coreset0Cfg.precoderGranularity;
2768       dlTtiReqPdu->u.pdcch_pdu.numDlDci = pdcchInfo->numDlDci;
2769
2770       /* Calculating PDU length. Considering only one dl dci pdu for now */
2771       dlTtiReqPdu->pduSize = sizeof(fapi_dl_pdcch_pdu_t) + sizeof(fapi_dl_dci_t);
2772       SET_MSG_LEN(*msgLen, (sizeof(dlTtiReqPdu->pduType) + \
2773          sizeof(dlTtiReqPdu->pduSize) + dlTtiReqPdu->pduSize));
2774
2775     }
2776
2777     return ROK;
2778 }
2779
2780 /*******************************************************************
2781  *
2782  * @brief fills PDSCH PDU required for DL TTI info in MAC
2783  *
2784  * @details
2785  *
2786  *    Function : fillPdschPdu
2787  *
2788  *    Functionality:
2789  *         -Fills the Pdsch PDU info
2790  *          stored in MAC
2791  *
2792  * @params[in] Pointer to FAPI DL TTI Req
2793  *             Pointer to PdschCfg
2794  *             Pointer to msgLen of DL TTI Info
2795  * @return ROK
2796  *
2797  ******************************************************************/
2798
2799 void fillPdschPdu(fapi_dl_tti_req_pdu_t *dlTtiReqPdu, PdschCfg *pdschInfo,
2800    BwpCfg bwp,uint32_t *msgLen, uint16_t pduIndex)
2801 {
2802     uint8_t idx;
2803
2804     if(dlTtiReqPdu != NULLP)
2805     {
2806        dlTtiReqPdu->pduType = PDSCH_PDU_TYPE;
2807        dlTtiReqPdu->u.pdsch_pdu.pduBitMap = pdschInfo->pduBitmap;
2808        dlTtiReqPdu->u.pdsch_pdu.rnti = pdschInfo->rnti;         
2809        dlTtiReqPdu->u.pdsch_pdu.pduIndex = pduIndex;
2810        dlTtiReqPdu->u.pdsch_pdu.bwpSize = bwp.freqAlloc.numPrb;       
2811        dlTtiReqPdu->u.pdsch_pdu.bwpStart = bwp.freqAlloc.startPrb;
2812        dlTtiReqPdu->u.pdsch_pdu.subCarrierSpacing = bwp.subcarrierSpacing;
2813        dlTtiReqPdu->u.pdsch_pdu.cyclicPrefix = bwp.cyclicPrefix;
2814        dlTtiReqPdu->u.pdsch_pdu.nrOfCodeWords = pdschInfo->numCodewords;
2815        for(idx = 0; idx < MAX_CODEWORDS ; idx++)
2816        { 
2817           dlTtiReqPdu->u.pdsch_pdu.cwInfo[idx].targetCodeRate = pdschInfo->codeword[idx].targetCodeRate;
2818           dlTtiReqPdu->u.pdsch_pdu.cwInfo[idx].qamModOrder = pdschInfo->codeword[idx].qamModOrder;
2819           dlTtiReqPdu->u.pdsch_pdu.cwInfo[idx].mcsIndex = pdschInfo->codeword[idx].mcsIndex;
2820           dlTtiReqPdu->u.pdsch_pdu.cwInfo[idx].mcsTable = pdschInfo->codeword[idx].mcsTable;
2821           dlTtiReqPdu->u.pdsch_pdu.cwInfo[idx].rvIndex = pdschInfo->codeword[idx].rvIndex;
2822           dlTtiReqPdu->u.pdsch_pdu.cwInfo[idx].tbSize = pdschInfo->codeword[idx].tbSize;
2823        }
2824        dlTtiReqPdu->u.pdsch_pdu.dataScramblingId = pdschInfo->dataScramblingId;       
2825        dlTtiReqPdu->u.pdsch_pdu.nrOfLayers = pdschInfo->numLayers;
2826        dlTtiReqPdu->u.pdsch_pdu.transmissionScheme = pdschInfo->transmissionScheme;
2827        dlTtiReqPdu->u.pdsch_pdu.refPoint = pdschInfo->refPoint;
2828        dlTtiReqPdu->u.pdsch_pdu.dlDmrsSymbPos = pdschInfo->dmrs.dlDmrsSymbPos;
2829        dlTtiReqPdu->u.pdsch_pdu.dmrsConfigType = pdschInfo->dmrs.dmrsConfigType;
2830        dlTtiReqPdu->u.pdsch_pdu.dlDmrsScramblingId = pdschInfo->dmrs.dlDmrsScramblingId;
2831        dlTtiReqPdu->u.pdsch_pdu.scid = pdschInfo->dmrs.scid;
2832        dlTtiReqPdu->u.pdsch_pdu.numDmrsCdmGrpsNoData = pdschInfo->dmrs.numDmrsCdmGrpsNoData;
2833        dlTtiReqPdu->u.pdsch_pdu.dmrsPorts = pdschInfo->dmrs.dmrsPorts;
2834        dlTtiReqPdu->u.pdsch_pdu.resourceAlloc = pdschInfo->pdschFreqAlloc.resourceAllocType;
2835        /* since we are using type-1, hence rbBitmap excluded */
2836        dlTtiReqPdu->u.pdsch_pdu.rbStart = pdschInfo->pdschFreqAlloc.freqAlloc.startPrb;
2837        dlTtiReqPdu->u.pdsch_pdu.rbSize = pdschInfo->pdschFreqAlloc.freqAlloc.numPrb;
2838        dlTtiReqPdu->u.pdsch_pdu.vrbToPrbMapping = pdschInfo->pdschFreqAlloc.vrbPrbMapping;
2839        dlTtiReqPdu->u.pdsch_pdu.startSymbIndex = pdschInfo->pdschTimeAlloc.timeAlloc.startSymb;
2840        dlTtiReqPdu->u.pdsch_pdu.nrOfSymbols = pdschInfo->pdschTimeAlloc.timeAlloc.numSymb;
2841        dlTtiReqPdu->u.pdsch_pdu.preCodingAndBeamforming.numPrgs = pdschInfo->beamPdschInfo.numPrgs;
2842        dlTtiReqPdu->u.pdsch_pdu.preCodingAndBeamforming.prgSize = pdschInfo->beamPdschInfo.prgSize;
2843        dlTtiReqPdu->u.pdsch_pdu.preCodingAndBeamforming.digBfInterfaces = pdschInfo->beamPdschInfo.digBfInterfaces;
2844        dlTtiReqPdu->u.pdsch_pdu.preCodingAndBeamforming.pmi_bfi[0]. \
2845           pmIdx = pdschInfo->beamPdschInfo.prg[0].pmIdx;
2846        dlTtiReqPdu->u.pdsch_pdu.preCodingAndBeamforming.pmi_bfi[0]. \
2847           beamIdx[0].beamidx = pdschInfo->beamPdschInfo.prg[0].beamIdx[0];
2848        dlTtiReqPdu->u.pdsch_pdu.powerControlOffset = pdschInfo->txPdschPower.powerControlOffset;  
2849        dlTtiReqPdu->u.pdsch_pdu.powerControlOffsetSS = pdschInfo->txPdschPower.powerControlOffsetSS;
2850        dlTtiReqPdu->pduSize = sizeof(fapi_dl_pdsch_pdu_t);
2851
2852        SET_MSG_LEN(*msgLen, (sizeof(dlTtiReqPdu->pduType) + \
2853           sizeof(dlTtiReqPdu->pduSize) + sizeof(fapi_dl_pdsch_pdu_t)));
2854
2855     }
2856
2857 }
2858
2859 /***********************************************************************
2860  *
2861  * @brief calculates the total size to be allocated for DL TTI Req
2862  *
2863  * @details
2864  *
2865  *    Function : calcDlTtiReqPduCount
2866  *
2867  *    Functionality:
2868  *         -calculates the total pdu count to be allocated for DL TTI Req
2869  *
2870  * @params[in]    DlBrdcstAlloc *cellBroadcastInfo
2871  * @return count
2872  *
2873  * ********************************************************************/
2874 uint8_t calcDlTtiReqPduCount(DlSchedInfo *dlInfo)
2875 {
2876    uint8_t count = 0;
2877    uint8_t idx = 0;
2878
2879    if(dlInfo->isBroadcastPres)
2880    {
2881       if(dlInfo->brdcstAlloc.ssbTrans)
2882       {
2883          for(idx = 0; idx < dlInfo->brdcstAlloc.ssbIdxSupported; idx++)
2884          {
2885             /* SSB PDU is filled */
2886             count++;
2887          }
2888       }
2889       if(dlInfo->brdcstAlloc.sib1Trans)
2890       {
2891          /* PDCCH and PDSCH PDU is filled */
2892          count += 2;
2893       }
2894    }
2895    if(dlInfo->rarAlloc != NULLP)
2896    {
2897       /* PDCCH and PDSCH PDU is filled */
2898       count += 2;
2899    }
2900    if(dlInfo->msg4Alloc != NULLP)
2901    {
2902       /* PDCCH and PDSCH PDU is filled */
2903       count += 2;
2904    }
2905
2906    return count;
2907 }
2908
2909 /***********************************************************************
2910  *
2911  * @brief calculates the total size to be allocated for DL TTI Req
2912  *
2913  * @details
2914  *
2915  *    Function : calcTxDataReqPduCount
2916  *
2917  *    Functionality:
2918  *         -calculates the total pdu count to be allocated for DL TTI Req
2919  *
2920  * @params[in]    DlBrdcstAlloc *cellBroadcastInfo
2921  * @return count
2922  *
2923  * ********************************************************************/
2924 uint8_t calcTxDataReqPduCount(DlSchedInfo *dlInfo)
2925 {
2926    uint8_t count = 0;
2927
2928    if(dlInfo->isBroadcastPres && dlInfo->brdcstAlloc.sib1Trans)
2929    {
2930       count++;
2931    }
2932    if(dlInfo->rarAlloc != NULLP)
2933    {
2934       count++;
2935    }
2936    if(dlInfo->msg4Alloc != NULLP)
2937    {
2938       count++;
2939    }
2940
2941    return count;
2942 }
2943 /***********************************************************************
2944  *
2945  * @brief fills the SIB1 TX-DATA request message
2946  *
2947  * @details
2948  *
2949  *    Function : fillSib1TxDataReq
2950  *
2951  *    Functionality:
2952  *         - fills the SIB1 TX-DATA request message
2953  *
2954  * @params[in]    fapi_tx_pdu_desc_t *pduDesc
2955  * @params[in]    macCellCfg consist of SIB1 pdu
2956  * @params[in]    uint32_t *msgLen
2957  * @params[in]    uint16_t pduIndex
2958  * @return ROK
2959  *
2960  * ********************************************************************/
2961 uint8_t fillSib1TxDataReq(fapi_tx_pdu_desc_t *pduDesc,MacCellCfg *macCellCfg,
2962    uint32_t *msgLen, uint16_t pduIndex)
2963 {
2964    uint32_t pduLen = 0;
2965    uint32_t *sib1TxdataValue = NULLP;
2966
2967    pduDesc[pduIndex].pduIndex = pduIndex;
2968    pduDesc[pduIndex].numTlvs = 1;
2969
2970    /* fill the TLV */
2971    /* as of now, memory is allocated from SSI, later WLS memory needs to be taken */
2972    pduDesc[pduIndex].tlvs[0].tl.tag = 1; /* pointer to be sent */
2973    pduDesc[pduIndex].tlvs[0].tl.length = macCellCfg->sib1Cfg.sib1PduLen;
2974    LWR_MAC_ALLOC(sib1TxdataValue,macCellCfg->sib1Cfg.sib1PduLen);
2975    if(sib1TxdataValue == NULLP)
2976    {
2977       return RFAILED;
2978    }
2979    memcpy(sib1TxdataValue,macCellCfg->sib1Cfg.sib1Pdu,
2980       macCellCfg->sib1Cfg.sib1PduLen);
2981    pduDesc[pduIndex].tlvs[0].value = sib1TxdataValue;
2982
2983    /* The total length of the PDU description and   PDU data */
2984    pduLen += 8; /* size of PDU length 2 bytes, PDU index 2 bytes, numTLV 4 bytes */
2985    pduLen += sizeof(fapi_uint32_tlv_t); /* only 1 TLV is present */
2986    pduDesc[pduIndex].pduLength = pduLen; 
2987    msgLen += pduLen;
2988
2989 #ifndef INTEL_WLS   
2990    MAC_FREE(sib1TxdataValue,macCellCfg->sib1Cfg.sib1PduLen);
2991 #endif
2992
2993    return ROK;
2994 }
2995
2996 /***********************************************************************
2997  *
2998  * @brief fills the RAR TX-DATA request message
2999  *
3000  * @details
3001  *
3002  *    Function : fillRarTxDataReq
3003  *
3004  *    Functionality:
3005  *         - fills the RAR TX-DATA request message
3006  *
3007  * @params[in]    fapi_tx_pdu_desc_t *pduDesc
3008  * @params[in]    RarInfo *rarInfo
3009  * @params[in]    uint32_t *msgLen
3010  * @params[in]    uint16_t pduIndex
3011  * @return ROK
3012  *
3013  * ********************************************************************/
3014 uint8_t fillRarTxDataReq(fapi_tx_pdu_desc_t *pduDesc, RarInfo *rarInfo,
3015    uint32_t *msgLen, uint16_t pduIndex)
3016 {
3017    uint32_t pduLen = 0;
3018    uint32_t *rarTxdataValue = NULLP;
3019
3020    pduDesc[pduIndex].pduIndex = pduIndex;
3021    pduDesc[pduIndex].numTlvs = 1;
3022
3023    /* fill the TLV */
3024    /* as of now, memory is allocated from SSI, later WLS memory needs to be taken */
3025    pduDesc[pduIndex].tlvs[0].tl.tag = 1; /* pointer to be sent */
3026    pduDesc[pduIndex].tlvs[0].tl.length = rarInfo->rarPduLen;
3027    LWR_MAC_ALLOC(rarTxdataValue,rarInfo->rarPduLen);
3028    if(rarTxdataValue == NULLP)
3029    {
3030       return RFAILED;
3031    }
3032    memcpy(rarTxdataValue,rarInfo->rarPdu,rarInfo->rarPduLen);
3033    pduDesc[pduIndex].tlvs[0].value = (uint32_t)rarTxdataValue;
3034
3035    /* The total length of the PDU description and   PDU data */
3036    pduLen += 8; /* size of PDU length 2 bytes, PDU index 2 bytes, numTLV 4 bytes */
3037    pduLen += sizeof(fapi_uint32_tlv_t); /* only 1 TLV is present */
3038    pduDesc[pduIndex].pduLength = pduLen; 
3039    msgLen += pduLen;
3040
3041 /* TODO: The pointer value which was stored, needs to be free-ed at PHY *
3042  * But since we did not implement WLS, this has to be done here
3043  */
3044 #ifndef INTEL_WLS   
3045    MAC_FREE(rarTxdataValue,rarInfo->rarPduLen);
3046 #endif
3047
3048    return ROK;
3049 }
3050
3051 /***********************************************************************
3052  *
3053  * @brief fills the Msg4 TX-DATA request message
3054  *
3055  * @details
3056  *
3057  *    Function : fillMsg4TxDataReq
3058  *
3059  *    Functionality:
3060  *         - fills the Msg4 TX-DATA request message
3061  *
3062  * @params[in]    fapi_tx_pdu_desc_t *pduDesc
3063  * @params[in]    Msg4Info *msg4Info
3064  * @params[in]    uint32_t *msgLen
3065  * @params[in]    uint16_t pduIndex
3066  * @return ROK
3067  *
3068  * ********************************************************************/
3069 uint8_t fillMsg4TxDataReq(fapi_tx_pdu_desc_t *pduDesc, Msg4Info *msg4Info,
3070    uint32_t *msgLen, uint16_t pduIndex)
3071 {
3072    uint32_t pduLen = 0;
3073    uint32_t *msg4TxDataValue = NULLP;
3074
3075    pduDesc[pduIndex].pduIndex = pduIndex;
3076    pduDesc[pduIndex].numTlvs = 1;
3077    
3078    /* fill the TLV */
3079    /* as of now, memory is allocated from SSI, later WLS memory needs to be taken */
3080    pduDesc[pduIndex].tlvs[0].tl.tag = 1; /* pointer to be sent */
3081    pduDesc[pduIndex].tlvs[0].tl.length = msg4Info->msg4PduLen;
3082    LWR_MAC_ALLOC(msg4TxDataValue, msg4Info->msg4PduLen);
3083    if(msg4TxDataValue == NULLP)
3084    {
3085       return RFAILED;
3086    }
3087    memcpy(msg4TxDataValue, msg4Info->msg4Pdu, msg4Info->msg4PduLen);
3088    pduDesc[pduIndex].tlvs[0].value = (uint32_t)msg4TxDataValue;
3089
3090    /* The total length of the PDU description and PDU data */
3091    pduLen += 8; /* size of PDU length 2 bytes, PDU index 2 bytes, numTLV 4 bytes */
3092    pduLen += sizeof(fapi_uint32_tlv_t); /* only 1 TLV is present */
3093    pduDesc[pduIndex].pduLength = pduLen; 
3094    msgLen += pduLen;
3095
3096    /* TODO: The pointer value which was stored, needs to be free-ed at PHY *
3097     * But since we did not implement WLS, this has to be done here
3098     */
3099    #ifndef INTEL_WLS   
3100       MAC_FREE(msg4TxDataValue, msg4Info->msg4PduLen);
3101    #endif
3102
3103    return ROK;
3104 }
3105
3106 #endif /* FAPI */
3107 /*******************************************************************
3108  *
3109  * @brief Sends DL TTI Request to PHY
3110  *
3111  * @details
3112  *
3113  *    Function : handleDlTtiReq
3114  *
3115  *    Functionality:
3116  *         -Sends FAPI DL TTI req to PHY
3117  *
3118  * @params[in]    timing info
3119  * @return ROK     - success
3120  *         RFAILED - failure
3121  *
3122  * ****************************************************************/
3123 uint16_t handleDlTtiReq(SlotIndInfo currTimingInfo)
3124 {
3125 #ifdef FAPI
3126    uint8_t idx;
3127    uint8_t nPdu = 0;
3128    uint8_t numPduEncoded = 0;
3129    uint16_t pduIndex = 0;
3130    uint32_t msgLen = 0;
3131    uint32_t dlTtiReqMsgSize = 0;
3132
3133    fapi_dl_tti_req_t *dlTtiReq = NULLP;
3134    SlotIndInfo dlTtiReqTimingInfo;
3135
3136    RgCellCb  *cellCbParams = NULLP;
3137    MacDlSlot *currDlSlot = NULLP;
3138    MacCellCfg macCellCfg;
3139    memset(&macCellCfg, 0, sizeof(MacCellCfg));
3140    Inst inst = 0;
3141    RntiType rntiType;
3142    
3143    if(clGlobalCp.phyState == PHY_STATE_RUNNING)
3144    {
3145       /* consider phy delay */
3146       ADD_DELTA_TO_TIME(currTimingInfo,dlTtiReqTimingInfo,PHY_DELTA);
3147
3148       cellCbParams = rgCb[inst].cell;
3149                 macCellCfg = cellCbParams->macCellCfg;
3150
3151                 currDlSlot = &macCb.macCell->dlSlot[dlTtiReqTimingInfo.slot]; 
3152                 nPdu = calcDlTtiReqPduCount(&currDlSlot->dlInfo);
3153                 dlTtiReqMsgSize = sizeof(fapi_dl_tti_req_t) + (nPdu * \
3154                                 sizeof(fapi_dl_tti_req_pdu_t));
3155                 if(nPdu > 0)
3156                 {
3157                         if(currDlSlot->dlInfo.isBroadcastPres)
3158                         {
3159                                 if(currDlSlot->dlInfo.brdcstAlloc.sib1Trans)
3160                                 {
3161                                         dlTtiReqMsgSize += sizeof(fapi_dl_dci_t);
3162                                 }
3163                         }
3164                         if(currDlSlot->dlInfo.rarAlloc != NULLP)
3165                         {
3166                                 dlTtiReqMsgSize += sizeof(fapi_dl_dci_t);
3167                         }
3168                         if(currDlSlot->dlInfo.msg4Alloc != NULLP)
3169                         {
3170                                 dlTtiReqMsgSize += sizeof(fapi_dl_dci_t);
3171                         }
3172                 }
3173                 LWR_MAC_ALLOC(dlTtiReq, dlTtiReqMsgSize);
3174                 if(dlTtiReq != NULLP)
3175                 {
3176                         memset(dlTtiReq, 0, dlTtiReqMsgSize);
3177                         dlTtiReq->sfn  = dlTtiReqTimingInfo.sfn;
3178                         dlTtiReq->slot = dlTtiReqTimingInfo.slot;
3179                         dlTtiReq->nPdus = calcDlTtiReqPduCount(&currDlSlot->dlInfo);  /* get total Pdus */
3180                         nPdu = dlTtiReq->nPdus;
3181                         dlTtiReq->nGroup = 0;
3182
3183                         if(dlTtiReq->nPdus > 0)
3184                         {
3185                                 dlTtiReq->pdus = (fapi_dl_tti_req_pdu_t*)(dlTtiReq + \
3186                                                 (sizeof(fapi_dl_tti_req_t) - sizeof(fapi_dl_tti_req_pdu_t*)));
3187                                 if(!dlTtiReq->pdus)
3188                                 {
3189                                         DU_LOG("\nLWR_MAC: Memory allocation failed");
3190                                         return RFAILED;
3191                                 }
3192
3193                                 if(currDlSlot->dlInfo.isBroadcastPres)
3194                                 {
3195                                         if(currDlSlot->dlInfo.brdcstAlloc.ssbTrans)
3196                                         {
3197                                                 if(dlTtiReq->pdus != NULLP)
3198                                                 {
3199                                                         for(idx = 0; idx < currDlSlot->dlInfo.brdcstAlloc.ssbIdxSupported; idx++)
3200                                                         {
3201                                                                 fillSsbPdu(&dlTtiReq->pdus[numPduEncoded], &macCellCfg,\
3202                                                                                 currDlSlot, &msgLen, idx, dlTtiReq->sfn);
3203                                                                 numPduEncoded++;
3204                                                         }
3205                                                 }
3206                                                 printf("\033[1;31m");
3207                                                 DU_LOG("\nLWR_MAC: MIB sent..");
3208                                                 printf("\033[0m");
3209                                         }
3210                                         if(currDlSlot->dlInfo.brdcstAlloc.sib1Trans)
3211                                         {
3212                                                 /* Filling SIB1 param */
3213                                                 if(numPduEncoded != nPdu)
3214                                                 {
3215                                                         rntiType = SI_RNTI_TYPE;
3216                                                         fillPdcchPdu(&dlTtiReq->pdus[numPduEncoded],&currDlSlot->dlInfo,\
3217                                                                         &msgLen, rntiType);
3218                                                         numPduEncoded++;
3219                                                         fillPdschPdu(&dlTtiReq->pdus[numPduEncoded],
3220                                                                         &currDlSlot->dlInfo.brdcstAlloc.sib1Alloc.sib1PdschCfg,
3221                                                                         currDlSlot->dlInfo.brdcstAlloc.sib1Alloc.bwp,
3222                                                                         &msgLen, pduIndex);
3223                                                         pduIndex++;
3224                                                         numPduEncoded++;
3225                                                 }
3226                                                 printf("\033[1;34m");
3227                                                 DU_LOG("\nLWR_MAC: SIB1 sent...");
3228                                                 printf("\033[0m");
3229                                         }
3230                                 }
3231                                 if(currDlSlot->dlInfo.rarAlloc != NULLP)
3232                                 {
3233                                         /* Filling RAR param */
3234                                         rntiType = RA_RNTI_TYPE;
3235                                         fillPdcchPdu(&dlTtiReq->pdus[numPduEncoded], \
3236                                                         &currDlSlot->dlInfo, &msgLen, rntiType);
3237                                         numPduEncoded++;
3238                                         fillPdschPdu(&dlTtiReq->pdus[numPduEncoded],
3239                                                         &currDlSlot->dlInfo.rarAlloc->rarPdschCfg,
3240                                                         currDlSlot->dlInfo.rarAlloc->bwp,
3241                                                         &msgLen, pduIndex);
3242                                         numPduEncoded++;
3243                                         pduIndex++;
3244
3245                                         printf("\033[1;32m");
3246                                         DU_LOG("\nLWR_MAC: RAR sent...");
3247                                         printf("\033[0m");
3248                                 }
3249                                 if(currDlSlot->dlInfo.msg4Alloc != NULLP)
3250                                 {
3251                                         /* Filling Msg4 param */
3252                                         rntiType = TC_RNTI_TYPE;
3253                                         fillPdcchPdu(&dlTtiReq->pdus[numPduEncoded], \
3254                                                         &currDlSlot->dlInfo, &msgLen, rntiType);
3255                                         numPduEncoded++;
3256                                         fillPdschPdu(&dlTtiReq->pdus[numPduEncoded],
3257                                                         &currDlSlot->dlInfo.msg4Alloc->msg4PdschCfg,
3258                                                         currDlSlot->dlInfo.msg4Alloc->bwp,
3259                                                         &msgLen, pduIndex);
3260                                         numPduEncoded++;
3261                                         pduIndex++;
3262
3263                                         printf("\033[1;32m");
3264                                         DU_LOG("\nLWR_MAC: MSG4 sent...");
3265                                         printf("\033[0m");
3266                                 }
3267                                 msgLen += sizeof(fapi_dl_tti_req_t) - sizeof(fapi_msg_t);
3268                                 fillMsgHeader(&dlTtiReq->header, FAPI_DL_TTI_REQUEST, msgLen);
3269                                 LwrMacSendToPhy(dlTtiReq->header.message_type_id, dlTtiReqMsgSize, \
3270                                                 (void *)dlTtiReq);
3271
3272                                 /* send Tx-DATA req message */
3273                                 sendTxDataReq(currTimingInfo, &currDlSlot->dlInfo);
3274                         }
3275                         else
3276                         {
3277                                 msgLen = sizeof(fapi_dl_tti_req_t) - sizeof(fapi_msg_t);
3278                                 fillMsgHeader(&dlTtiReq->header, FAPI_DL_TTI_REQUEST, msgLen);
3279                                 LwrMacSendToPhy(dlTtiReq->header.message_type_id, dlTtiReqMsgSize, (void *)dlTtiReq);
3280                         }
3281                         return ROK;
3282                 }
3283                 else
3284                 {
3285                         DU_LOG("\nLWR_MAC: Failed to allocate memory for DL TTI Request");
3286                         return RFAILED;
3287                 }
3288         }
3289    else
3290    {
3291        lwr_mac_handleInvalidEvt(&currTimingInfo);
3292        return RFAILED;
3293    }
3294 #endif
3295    return ROK;
3296 }
3297
3298 /*******************************************************************
3299  *
3300  * @brief Sends TX data Request to PHY
3301  *
3302  * @details
3303  *
3304  *    Function : sendTxDataReq
3305  *
3306  *    Functionality:
3307  *         -Sends FAPI TX data req to PHY
3308  *
3309  * @params[in]    timing info
3310  * @return ROK     - success
3311  *         RFAILED - failure
3312  *
3313  * ****************************************************************/
3314 uint16_t sendTxDataReq(SlotIndInfo currTimingInfo, DlSchedInfo *dlInfo)
3315 {
3316 #ifdef FAPI
3317    uint8_t nPdu = 0;
3318    uint32_t msgLen = 0;
3319    uint16_t pduIndex = 0;
3320    uint32_t txDataReqMsgSize = 0;
3321    fapi_tx_data_req_t *txDataReq = NULLP;
3322    Inst inst = 0;
3323
3324    /* send TX_Data request message */
3325    nPdu = calcTxDataReqPduCount(dlInfo);
3326    if(nPdu > 0)
3327    {
3328       txDataReqMsgSize = sizeof(fapi_tx_data_req_t) + \
3329          (nPdu * sizeof(fapi_tx_pdu_desc_t));
3330       if(dlInfo->brdcstAlloc.sib1Trans)
3331       {
3332          txDataReqMsgSize += rgCb[inst].cell->macCellCfg.sib1Cfg.sib1PduLen;
3333       }
3334       if(dlInfo->rarAlloc != NULLP)
3335       {
3336          txDataReqMsgSize += dlInfo->rarAlloc->rarInfo.rarPduLen;
3337       }
3338       if(dlInfo->msg4Alloc != NULLP)
3339       {
3340          txDataReqMsgSize += dlInfo->msg4Alloc->msg4Info.msg4PduLen;
3341       }
3342
3343       LWR_MAC_ALLOC(txDataReq, txDataReqMsgSize);
3344       if(txDataReq == NULLP)
3345       {
3346          DU_LOG("\nLWR_MAC: Failed to allocate memory for TX data Request");
3347          return RFAILED;
3348       }
3349
3350       memset(txDataReq, 0, txDataReqMsgSize);
3351                 txDataReq->sfn  = currTimingInfo.sfn;
3352                 txDataReq->slot = currTimingInfo.slot;
3353       txDataReq->pduDesc = (fapi_tx_pdu_desc_t *)(txDataReq + \
3354          (sizeof(fapi_tx_data_req_t) - sizeof(fapi_tx_pdu_desc_t *)));
3355
3356       if(dlInfo->brdcstAlloc.sib1Trans)
3357       {
3358          fillSib1TxDataReq(txDataReq->pduDesc,
3359                &rgCb[inst].cell->macCellCfg, &msgLen, pduIndex);
3360          pduIndex++;
3361          txDataReq->numPdus++;
3362       }
3363       if(dlInfo->rarAlloc != NULLP)
3364       {
3365          fillRarTxDataReq(txDataReq->pduDesc, &dlInfo->rarAlloc->rarInfo, &msgLen, pduIndex);
3366          pduIndex++;
3367          txDataReq->numPdus++;
3368
3369          MAC_FREE(dlInfo->rarAlloc,sizeof(RarAlloc));
3370          dlInfo->rarAlloc = NULLP;
3371       }
3372       if(dlInfo->msg4Alloc != NULLP)
3373       {
3374          fillMsg4TxDataReq(txDataReq->pduDesc, &dlInfo->msg4Alloc->\
3375              msg4Info, &msgLen, pduIndex);
3376          pduIndex++;
3377          txDataReq->numPdus++;
3378
3379          MAC_FREE(dlInfo->msg4Alloc,sizeof(Msg4Alloc));
3380          dlInfo->msg4Alloc = NULLP;
3381       }
3382       msgLen += sizeof(fapi_tx_data_req_t) - sizeof(fapi_msg_t);
3383       fillMsgHeader(&txDataReq->header, FAPI_TX_DATA_REQUEST, msgLen);
3384       LwrMacSendToPhy(txDataReq->header.message_type_id, txDataReqMsgSize, \
3385          (void *)txDataReq);
3386    }
3387 #endif
3388    return ROK;
3389 }
3390
3391 /***********************************************************************
3392  *
3393  * @brief calculates the total size to be allocated for UL TTI Req
3394  *
3395  * @details
3396  *
3397  *    Function : getnPdus
3398  *
3399  *    Functionality:
3400  *         -calculates the total pdu count to be allocated for UL TTI Req
3401  *
3402  * @params[in] Pointer to fapi Ul TTI Req
3403  *             Pointer to CurrUlSlot
3404  * @return count
3405  * ********************************************************************/
3406 #ifdef FAPI
3407 uint8_t getnPdus(fapi_ul_tti_req_t *ulTtiReq, MacUlSlot *currUlSlot)
3408 {
3409    uint8_t pduCount = 0;
3410
3411    if(ulTtiReq && currUlSlot)
3412         {
3413                 if(currUlSlot->ulInfo.dataType & SCH_DATATYPE_PRACH)
3414                 {
3415                         pduCount++;
3416                         ulTtiReq->rachPresent = PDU_PRESENT;
3417                 }
3418                 if(currUlSlot->ulInfo.dataType & SCH_DATATYPE_PUSCH)
3419                 {
3420                         pduCount++;
3421                         ulTtiReq->nUlsch++;
3422                 }
3423                 if(currUlSlot->ulInfo.dataType & SCH_DATATYPE_PUSCH_UCI)
3424                 {
3425                         pduCount++;
3426                         ulTtiReq->nUlsch++;
3427                         ulTtiReq->nUlsch = PDU_PRESENT;
3428                 }
3429                 if(currUlSlot->ulInfo.dataType & SCH_DATATYPE_UCI)
3430                 {
3431                         pduCount++;
3432                         ulTtiReq->nUlcch = PDU_PRESENT;
3433                 }
3434                 if(currUlSlot->ulInfo.dataType & SCH_DATATYPE_SRS)
3435                 {
3436                         pduCount++;
3437                 }
3438         }
3439    return pduCount;
3440 }
3441 #endif
3442
3443 /***********************************************************************
3444  *
3445  * @brief Set the value of zero correlation config in PRACH PDU
3446  *
3447  * @details
3448  *
3449  *    Function : setNumCs
3450  *
3451  *    Functionality:
3452  *         -Set the value of zero correlation config in PRACH PDU
3453  *
3454  * @params[in] Pointer to zero correlation config
3455  *             Pointer to MacCellCfg
3456  * ********************************************************************/
3457
3458 void setNumCs(uint8_t *numCs, MacCellCfg *macCellCfg)
3459 {
3460 #ifdef FAPI
3461    uint8_t idx;
3462    if(macCellCfg != NULLP)
3463    {
3464       idx = macCellCfg->prachCfg.fdm[0].zeroCorrZoneCfg; 
3465       *numCs = UnrestrictedSetNcsTable[idx];
3466    }
3467 #endif
3468 }
3469
3470 /***********************************************************************
3471  *
3472  * @brief Fills the PRACH PDU in UL TTI Request
3473  *
3474  * @details
3475  *
3476  *    Function : fillPrachPdu
3477  *
3478  *    Functionality:
3479  *         -Fills the PRACH PDU in UL TTI Request
3480  *
3481  * @params[in] Pointer to Prach Pdu
3482  *             Pointer to CurrUlSlot
3483  *             Pointer to macCellCfg
3484  *             Pointer to msgLen
3485  * ********************************************************************/
3486
3487 #ifdef FAPI
3488 void fillPrachPdu(fapi_ul_tti_req_pdu_t *ulTtiReqPdu, MacCellCfg *macCellCfg, MacUlSlot *currUlSlot, uint32_t *msgLen)
3489 {
3490    if(ulTtiReqPdu != NULLP)
3491    {
3492       ulTtiReqPdu->pduType = PRACH_PDU_TYPE; 
3493       ulTtiReqPdu->u.prach_pdu.physCellId = macCellCfg->phyCellId;
3494       ulTtiReqPdu->u.prach_pdu.numPrachOcas = currUlSlot->ulInfo.prachSchInfo.numPrachOcas;
3495       ulTtiReqPdu->u.prach_pdu.prachFormat = \
3496       currUlSlot->ulInfo.prachSchInfo.prachFormat;
3497       ulTtiReqPdu->u.prach_pdu.numRa = currUlSlot->ulInfo.prachSchInfo.numRa;
3498       ulTtiReqPdu->u.prach_pdu.prachStartSymbol = \
3499       currUlSlot->ulInfo.prachSchInfo.prachStartSymb;
3500       setNumCs(&ulTtiReqPdu->u.prach_pdu.numCs, macCellCfg);
3501       ulTtiReqPdu->u.prach_pdu.beamforming.numPrgs = 0;
3502       ulTtiReqPdu->u.prach_pdu.beamforming.prgSize = 0;
3503       ulTtiReqPdu->u.prach_pdu.beamforming.digBfInterfaces = 0;
3504       ulTtiReqPdu->u.prach_pdu.beamforming.pmi_bfi[0].pmIdx = 0;
3505       ulTtiReqPdu->u.prach_pdu.beamforming.pmi_bfi[0].beamIdx[0].beamidx = 0;
3506       ulTtiReqPdu->pduSize = sizeof(fapi_ul_prach_pdu_t); 
3507
3508       SET_MSG_LEN(*msgLen, (sizeof(ulTtiReqPdu->pduType) + \
3509          sizeof(ulTtiReqPdu->pduSize) + sizeof(fapi_ul_prach_pdu_t)));
3510    }
3511 }
3512
3513 void fillPuschPdu(fapi_ul_tti_req_pdu_t *ulTtiReqPdu, MacCellCfg *macCellCfg, MacUlSlot *currUlSlot, uint32_t *msgLen)
3514 {
3515    if(ulTtiReqPdu != NULLP)
3516    {
3517       ulTtiReqPdu->pduType = PUSCH_PDU_TYPE;
3518       ulTtiReqPdu->u.pusch_pdu.pduBitMap = 1;
3519       ulTtiReqPdu->u.pusch_pdu.rnti = currUlSlot->ulInfo.crnti;
3520                 /* TODO : Fill handle in raCb when scheduling pusch and access here */
3521       ulTtiReqPdu->u.pusch_pdu.handle = 100;
3522       ulTtiReqPdu->u.pusch_pdu.bwpSize = macCellCfg->initialUlBwp.bwp.numPrb;
3523       ulTtiReqPdu->u.pusch_pdu.bwpStart = macCellCfg->initialUlBwp.bwp.firstPrb;
3524       ulTtiReqPdu->u.pusch_pdu.subCarrierSpacing = \
3525                    macCellCfg->initialUlBwp.bwp.scs;
3526       ulTtiReqPdu->u.pusch_pdu.cyclicPrefix = \
3527                    macCellCfg->initialUlBwp.bwp.cyclicPrefix;
3528       ulTtiReqPdu->u.pusch_pdu.targetCodeRate = 308;
3529       ulTtiReqPdu->u.pusch_pdu.qamModOrder = 2;
3530       ulTtiReqPdu->u.pusch_pdu.mcsIndex = \
3531                    currUlSlot->ulInfo.schPuschInfo.tbInfo.mcs;
3532       ulTtiReqPdu->u.pusch_pdu.mcsTable = 0;
3533       ulTtiReqPdu->u.pusch_pdu.transformPrecoding = 1;
3534       ulTtiReqPdu->u.pusch_pdu.dataScramblingId = currUlSlot->ulInfo.cellId;
3535       ulTtiReqPdu->u.pusch_pdu.nrOfLayers = 1;
3536       ulTtiReqPdu->u.pusch_pdu.ulDmrsSymbPos = 4;
3537       ulTtiReqPdu->u.pusch_pdu.dmrsConfigType = 0;
3538       ulTtiReqPdu->u.pusch_pdu.ulDmrsScramblingId = currUlSlot->ulInfo.cellId;
3539       ulTtiReqPdu->u.pusch_pdu.scid = 0;
3540       ulTtiReqPdu->u.pusch_pdu.numDmrsCdmGrpsNoData = 1;
3541       ulTtiReqPdu->u.pusch_pdu.dmrsPorts = 0;
3542       ulTtiReqPdu->u.pusch_pdu.resourceAlloc = \
3543                    currUlSlot->ulInfo.schPuschInfo.resAllocType;
3544       ulTtiReqPdu->u.pusch_pdu.rbStart = \
3545                    currUlSlot->ulInfo.schPuschInfo.fdAlloc.startPrb;
3546       ulTtiReqPdu->u.pusch_pdu.rbSize = \
3547                    currUlSlot->ulInfo.schPuschInfo.fdAlloc.numPrb;
3548       ulTtiReqPdu->u.pusch_pdu.vrbToPrbMapping = 0;
3549       ulTtiReqPdu->u.pusch_pdu.frequencyHopping = 0;
3550       ulTtiReqPdu->u.pusch_pdu.txDirectCurrentLocation = 0;
3551       ulTtiReqPdu->u.pusch_pdu.uplinkFrequencyShift7p5khz = 0;
3552       ulTtiReqPdu->u.pusch_pdu.startSymbIndex = \
3553                    currUlSlot->ulInfo.schPuschInfo.tdAlloc.startSymb;
3554       ulTtiReqPdu->u.pusch_pdu.nrOfSymbols = \
3555                    currUlSlot->ulInfo.schPuschInfo.tdAlloc.numSymb;
3556       ulTtiReqPdu->u.pusch_pdu.puschData.rvIndex = \
3557                    currUlSlot->ulInfo.schPuschInfo.tbInfo.rv;
3558       ulTtiReqPdu->u.pusch_pdu.puschData.harqProcessId = \
3559                    currUlSlot->ulInfo.schPuschInfo.harqProcId;
3560       ulTtiReqPdu->u.pusch_pdu.puschData.newDataIndicator = \
3561                    currUlSlot->ulInfo.schPuschInfo.tbInfo.ndi;
3562       ulTtiReqPdu->u.pusch_pdu.puschData.tbSize = \
3563                    currUlSlot->ulInfo.schPuschInfo.tbInfo.tbSize;
3564                 /* numCb is 0 for new transmission */
3565       ulTtiReqPdu->u.pusch_pdu.puschData.numCb = 0;
3566
3567       ulTtiReqPdu->pduSize = sizeof(fapi_ul_pusch_pdu_t);
3568        
3569       SET_MSG_LEN(*msgLen, (sizeof(ulTtiReqPdu->pduType) + \
3570          sizeof(ulTtiReqPdu->pduSize) + sizeof(fapi_ul_pusch_pdu_t)));
3571    }
3572 }
3573 #endif
3574
3575 /*******************************************************************
3576  *
3577  * @brief Sends UL TTI Request to PHY
3578  *
3579  * @details
3580  *
3581  *    Function : handleUlTtiReq
3582  *
3583  *    Functionality:
3584  *         -Sends FAPI Param req to PHY
3585  *
3586  * @params[in]  Pointer to CmLteTimingInfo
3587  * @return ROK     - success
3588  *         RFAILED - failure
3589  *
3590  ******************************************************************/
3591 uint16_t handleUlTtiReq(SlotIndInfo currTimingInfo)
3592 {
3593 #ifdef FAPI
3594    uint8_t    pduIdx = -1;
3595    uint8_t    numPdu = 0;
3596    uint32_t   msgLen = 0;
3597    uint32_t   msgSize = 0;
3598
3599    fapi_ul_tti_req_t *ulTtiReq = NULLP;
3600    SlotIndInfo ulTtiReqTimingInfo;
3601
3602    RgCellCb  *cellCbParams = NULLP;
3603    MacUlSlot *currUlSlot = NULLP;
3604    MacCellCfg macCellCfg;
3605    Inst inst = 0;
3606
3607    if(clGlobalCp.phyState == PHY_STATE_RUNNING)
3608         {
3609                 cellCbParams = rgCb[inst].cell;
3610                 macCellCfg = cellCbParams->macCellCfg;
3611
3612                 /* add PHY delta */
3613                 ADD_DELTA_TO_TIME(currTimingInfo,ulTtiReqTimingInfo,PHY_DELTA);
3614
3615                 currUlSlot = &macCb.macCell->ulSlot[ulTtiReqTimingInfo.slot % MAX_SLOT_SUPPORTED];
3616                 numPdu = getnPdus(NULL, currUlSlot);
3617                 msgSize = sizeof(fapi_ul_tti_req_t) + (numPdu*sizeof(fapi_ul_tti_req_pdu_t));
3618                 LWR_MAC_ALLOC(ulTtiReq, msgSize);
3619
3620                 if(ulTtiReq != NULLP)
3621                 {
3622                         memset(ulTtiReq, 0, msgSize);
3623                         ulTtiReq->sfn  = currTimingInfo.sfn;
3624                         ulTtiReq->slot = currTimingInfo.slot;
3625                         ulTtiReq->nPdus = getnPdus(ulTtiReq, currUlSlot);
3626                         ulTtiReq->nGroup = 0;
3627                         if(ulTtiReq->nPdus > 0)
3628                         {
3629                                 ulTtiReq->pdus = (fapi_ul_tti_req_pdu_t *)(ulTtiReq + \
3630                                                 (sizeof(fapi_ul_tti_req_t) - sizeof(fapi_ul_tti_req_pdu_t*)));
3631                                 /* Fill Prach Pdu */
3632                                 if(currUlSlot->ulInfo.dataType & SCH_DATATYPE_PRACH)
3633                                 {
3634                                         pduIdx++;
3635                                         fillPrachPdu(&ulTtiReq->pdus[pduIdx], &macCellCfg, currUlSlot, &msgLen);
3636                                 }
3637
3638                                 /* Fill PUSCH PDU */
3639                                 if(currUlSlot->ulInfo.dataType & SCH_DATATYPE_PUSCH)
3640                                 {
3641                                         pduIdx++;
3642                                         fillPuschPdu(&ulTtiReq->pdus[pduIdx], &macCellCfg, currUlSlot, &msgLen);
3643                                 }
3644
3645                                 if((currUlSlot->ulInfo.dataType & SCH_DATATYPE_PRACH) || \
3646                                                 (currUlSlot->ulInfo.dataType & SCH_DATATYPE_PUSCH))
3647                                 {
3648                                         msgLen += (sizeof(fapi_ul_tti_req_t) - sizeof(fapi_msg_t));
3649                                         fillMsgHeader(&ulTtiReq->header, FAPI_UL_TTI_REQUEST, msgLen);
3650
3651                                         DU_LOG("\nLWR_MAC: Sending UL TTI Request");
3652                                         LwrMacSendToPhy(ulTtiReq->header.message_type_id, msgSize, (void *)ulTtiReq);
3653                                 }   
3654                         } 
3655                         else
3656                         {
3657                                 msgLen = sizeof(fapi_ul_tti_req_t) - sizeof(fapi_msg_t);
3658                                 fillMsgHeader(&ulTtiReq->header, FAPI_UL_TTI_REQUEST, msgLen);
3659
3660                                 DU_LOG("\nLWR_MAC: Sending UL TTI Request");
3661                                 LwrMacSendToPhy(ulTtiReq->header.message_type_id, msgSize, (void *)ulTtiReq);
3662                         }
3663                         memset(&currUlSlot, 0, sizeof(MacUlSlot));
3664                         return ROK;
3665                 }
3666                 else
3667                 {
3668                         DU_LOG("\nLWR_MAC: Failed to allocate memory for UL TTI Request");
3669                         memset(&currUlSlot, 0, sizeof(MacUlSlot));
3670                         return RFAILED;
3671                 }
3672         }
3673    else
3674    {
3675        lwr_mac_handleInvalidEvt(&currTimingInfo);
3676    }
3677 #endif
3678    return ROK;
3679 }
3680
3681 lwrMacFsmHdlr fapiEvtHdlr[MAX_STATE][MAX_EVENT] =
3682 {
3683    {
3684       /* PHY_STATE_IDLE */
3685        lwr_mac_handleParamReqEvt,
3686        lwr_mac_handleParamRspEvt,
3687        lwr_mac_handleConfigReqEvt,
3688        lwr_mac_handleConfigRspEvt,
3689        lwr_mac_handleInvalidEvt,
3690        lwr_mac_handleInvalidEvt,
3691    },
3692    {
3693        /* PHY_STATE_CONFIGURED */
3694        lwr_mac_handleParamReqEvt,
3695        lwr_mac_handleParamRspEvt,
3696        lwr_mac_handleConfigReqEvt,
3697        lwr_mac_handleConfigRspEvt,
3698        lwr_mac_handleStartReqEvt,
3699        lwr_mac_handleInvalidEvt,
3700    },
3701    {
3702        /* PHY_STATE_RUNNING */
3703        lwr_mac_handleInvalidEvt,
3704        lwr_mac_handleInvalidEvt,
3705        lwr_mac_handleConfigReqEvt,
3706        lwr_mac_handleConfigRspEvt,
3707        lwr_mac_handleInvalidEvt,
3708        lwr_mac_handleStopReqEvt,
3709    }
3710 };
3711
3712 /*******************************************************************
3713  *
3714  * @brief Sends message to LWR_MAC Fsm Event Handler
3715  *
3716  * @details
3717  *
3718  *    Function : sendToLowerMac
3719  *
3720  *    Functionality:
3721  *         -Sends message to LowerMac
3722  *
3723  * @params[in] Message Type
3724  *             Message Length
3725  *             Messaga Pointer
3726  *
3727  * @return void
3728  *
3729 ******************************************************************/
3730 void sendToLowerMac(uint16_t msgType, uint32_t msgLen, void *msg)
3731 {
3732    clGlobalCp.event = msgType;
3733    fapiEvtHdlr[clGlobalCp.phyState][clGlobalCp.event](msg);
3734 }
3735 /**********************************************************************
3736          End of file
3737 **********************************************************************/