[Task-ID: ODUHIGH-455] Changes to support new L1 20.11
[o-du/l2.git] / src / 5gnrmac / mac_slot_ind.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 /* header include files (.h) */
19 #include "common_def.h"
20 #include "lrg.h"
21 #include "lrg.x"
22 #include "du_app_mac_inf.h"
23 #include "mac_sch_interface.h"
24 #include "lwr_mac_upr_inf.h"
25 #include "rlc_mac_inf.h"
26 #include "mac.h"
27 #include "mac_upr_inf_api.h"
28 #include "lwr_mac.h"
29 #include "lwr_mac_fsm.h"
30 #include "mac_utils.h"
31 #include "mac_harq_dl.h"
32 #include "lwr_mac_phy.h"
33
34 /* function pointers for packing slot ind from mac to sch */
35 MacSchSlotIndFunc macSchSlotIndOpts[] =
36 {
37    packMacSchSlotInd,
38    MacSchSlotInd,
39    packMacSchSlotInd
40 };
41
42 /**
43  * @brief process DL allocation from scheduler
44  *
45  * @details
46  *
47  *     Function : MacProcDlAlloc 
48  *      
49  *      This function copied dl sch info in the mac slot info
50  *           
51  *  @param[in]  Pst            *pst
52  *  @param[in]  DL allocation from scheduler
53  *  @return
54  *      -# ROK 
55  *      -# RFAILED 
56  **/
57 uint8_t MacProcDlAlloc(Pst *pst, DlSchedInfo *dlSchedInfo)
58 {
59    uint8_t   schInfoIdx = 0, cwIdx = 0;
60    uint8_t   ueId = 0, ueIdx = 0;
61    uint16_t  cellIdx = 0;
62    uint8_t   *retxTb = NULLP, *txPdu = NULLP;
63    uint16_t  txPduLen = 0;
64    MacDlSlot      *currDlSlot = NULLP;
65    DlMsgSchInfo   schedInfo;
66    DlHarqProcCb   *hqProcCb = NULLP;
67
68 #ifdef CALL_FLOW_DEBUG_LOG
69    DU_LOG("\nCall Flow: ENTSCH -> ENTMAC : EVENT_DL_SCH_INFO\n");
70 #endif
71    if(dlSchedInfo != NULLP)
72    {
73       GET_CELL_IDX(dlSchedInfo->cellId, cellIdx);
74       if(dlSchedInfo->isBroadcastPres)
75       {
76          currDlSlot = &macCb.macCell[cellIdx]->\
77                       dlSlot[dlSchedInfo->schSlotValue.broadcastTime.slot];
78          currDlSlot->dlInfo.isBroadcastPres = true;
79          memcpy(&currDlSlot->dlInfo.brdcstAlloc, &dlSchedInfo->brdcstAlloc, sizeof(DlBrdcstAlloc));
80          currDlSlot->dlInfo.brdcstAlloc.sib1Alloc.sib1PdcchCfg.dci.pdschCfg = \
81                                             &currDlSlot->dlInfo.brdcstAlloc.sib1Alloc.sib1PdschCfg;
82       }
83
84       for(ueIdx=0; ueIdx<MAX_NUM_UE; ueIdx++)
85       {
86          if(dlSchedInfo->rarAlloc[ueIdx] != NULLP)
87          {
88             currDlSlot = &macCb.macCell[cellIdx]->dlSlot[dlSchedInfo->schSlotValue.rarTime.slot];
89             currDlSlot->dlInfo.rarAlloc[ueIdx] = dlSchedInfo->rarAlloc[ueIdx];
90
91             /* MUXing of RAR */
92             fillRarPdu(&currDlSlot->dlInfo.rarAlloc[ueIdx]->rarInfo);
93          }
94
95          if(dlSchedInfo->dlMsgAlloc[ueIdx] != NULLP)
96          {
97             currDlSlot = &macCb.macCell[cellIdx]->\
98                          dlSlot[dlSchedInfo->schSlotValue.dlMsgTime.slot];
99             currDlSlot->dlInfo.dlMsgAlloc[ueIdx] = dlSchedInfo->dlMsgAlloc[ueIdx]; /* copy msg4 alloc pointer in MAC slot info */
100             currDlSlot->dlInfo.cellId = dlSchedInfo->cellId;
101
102             /* Check if the downlink pdu is msg4 */
103             for(schInfoIdx=0; schInfoIdx < dlSchedInfo->dlMsgAlloc[ueIdx]->numSchedInfo; schInfoIdx++)
104             {
105                if(dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgInfo.isMsg4Pdu)
106                {
107                   GET_UE_ID(dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgInfo.crnti, ueId);
108                   ueIdx = ueId -1;
109                   schedInfo = dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx];
110                   hqProcCb = &macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4HqInfo;
111
112                   if(!dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].isRetx)
113                   {
114                      /* First transmission of MSG4 */
115                      hqProcCb->procId = schedInfo.dlMsgInfo.harqProcNum;
116                      for(cwIdx = 0; cwIdx < schedInfo.dlMsgPdschCfg.numCodewords; cwIdx++)
117                      {
118                         memcpy(&hqProcCb->tbInfo[hqProcCb->numTb].txTime, &dlSchedInfo->schSlotValue.dlMsgTime, \
119                               sizeof(SlotTimingInfo));
120                         hqProcCb->tbInfo[hqProcCb->numTb].tbSize = schedInfo.dlMsgPdschCfg.codeword[cwIdx].tbSize;
121                         hqProcCb->numTb++;
122                      }
123                   }
124                   else
125                   {
126                      /* MSG4 retransmission */
127                      if(hqProcCb->procId == schedInfo.dlMsgInfo.harqProcNum)
128                      {
129                         memcpy(&hqProcCb->tbInfo[0].txTime, &dlSchedInfo->schSlotValue.dlMsgTime, \
130                                                      sizeof(SlotTimingInfo));
131                      }
132                   }
133                }
134                else
135                {
136                   memcpy(&currDlSlot->dlInfo.schSlotValue, &dlSchedInfo->schSlotValue, sizeof(SchSlotValue));
137                   
138                   if(!dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].isRetx)
139                   {
140                      /* If new data transmission is scheduled, send schedule results to RLC */
141                      if((dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].pduPres == PDSCH_PDU) ||
142                            (dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].pduPres == BOTH))
143                      {
144                         sendSchedRptToRlc(currDlSlot->dlInfo, dlSchedInfo->schSlotValue.dlMsgTime, ueIdx, schInfoIdx);
145
146                         /* Add HARQ Proc to DL HARQ Proc Entity in UE */
147                         addDlHqProcInUe(currDlSlot->dlInfo.schSlotValue.dlMsgTime, &macCb.macCell[cellIdx]->ueCb[ueIdx], \
148                            dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx]);
149                      }
150                   }
151                   else
152                   {
153                      /* For retransmission, fetch PDU to be retransmitted from DL HARQ entity and schedule on corresponding slot */
154                      
155                      /* As of now this loop will run only once for one TB. 
156                       * TODO : update handling of fetched TB appropriately when support for two TB is added 
157                       */
158                      for(cwIdx = 0; \
159                            cwIdx < dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgPdschCfg.numCodewords;\
160                            cwIdx++)
161                      {
162                         /* Fetch TB to be retransmitted */
163                         txPduLen = dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgPdschCfg.codeword[cwIdx].tbSize;
164                         retxTb = fetchTbfromDlHarqProc(currDlSlot->dlInfo.schSlotValue.dlMsgTime, \
165                               &macCb.macCell[cellIdx]->ueCb[ueIdx], \
166                               dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgInfo.harqProcNum, txPduLen);
167
168                         /* Store PDU in corresponding DL slot */
169                         MAC_ALLOC(txPdu, txPduLen);
170                         if(!txPdu)
171                         {
172                            DU_LOG("\nERROR  -->  MAC : Memory allocation failed in MacProcRlcDlData");
173                            return RFAILED;
174                         }   
175                         memcpy(txPdu, retxTb,  txPduLen);
176
177                         currDlSlot->dlInfo.dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgInfo.dlMsgPduLen = txPduLen;
178                         currDlSlot->dlInfo.dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgInfo.dlMsgPdu = txPdu;
179                      }
180                   }
181                }
182             }
183          }
184       }
185
186       if(dlSchedInfo->ulGrant != NULLP)
187       {
188          currDlSlot = &macCb.macCell[cellIdx]->dlSlot[dlSchedInfo->schSlotValue.ulDciTime.slot];
189          currDlSlot->dlInfo.ulGrant = dlSchedInfo->ulGrant;
190       }
191    }
192    return ROK;
193 }
194
195 /**
196  * @brief process DL Paging allocation from scheduler
197  *
198  * @details
199  *
200  *     Function : MacProcDlPageAlloc 
201  *      
202  *      This function copied dl Pag info in the mac slot info
203  *           
204  *  @param[in]  Pst            *pst
205  *  @param[in]  DL Paging allocation from scheduler
206  *  @return
207  *      -# ROK 
208  *      -# RFAILED 
209  **/
210 uint8_t MacProcDlPageAlloc(Pst *pst, DlPageAlloc *dlPageAlloc)
211 {
212    uint16_t  cellIdx = 0;
213    MacDlSlot *currDlSlot = NULLP;
214
215 #ifdef CALL_FLOW_DEBUG_LOG
216    DU_LOG("\nCall Flow: ENTSCH -> ENTMAC : EVENT_DL_PAGING_ALLOC\n");
217 #endif
218    if(dlPageAlloc != NULLP)
219    {
220       GET_CELL_IDX(dlPageAlloc->cellId, cellIdx);
221
222       currDlSlot = &macCb.macCell[cellIdx]->dlSlot[dlPageAlloc->dlPageTime.slot];
223       MAC_ALLOC(currDlSlot->pageAllocInfo, sizeof(DlPageAlloc));
224       if(currDlSlot->pageAllocInfo == NULLP)
225       {
226          DU_LOG("\nERROR  --> MAC : MacProcDlPageAlloc : Memory Allocation is failed!");
227          return RFAILED;
228       }
229       memcpy(currDlSlot->pageAllocInfo, dlPageAlloc, sizeof(DlPageAlloc));
230       currDlSlot->pageAllocInfo->pagePdcchCfg.dci.pdschCfg = \
231                                                              &currDlSlot->pageAllocInfo->pagePdschCfg;
232    }
233    else
234    {
235       DU_LOG("\nERROR  --> MAC : DL Paging Allocation is failed!");
236       return RFAILED;
237    }
238    return ROK;
239 }
240
241 /**
242  * @brief Forming and filling the MUX Pdu
243  * @details
244  *
245  *     Function : fillMsg4Pdu
246  * 
247  *      Forming and filling of Msg4Pdu
248  *           
249  *  @param[in]  DlMsgAlloc  *msg4Alloc
250  *  @return  void
251  **/
252 void fillMsg4Pdu(uint16_t cellId, DlMsgSchInfo *msg4SchInfo)
253 {
254    uint8_t   ueId = 0, ueIdx = 0;
255    uint16_t  cellIdx;
256    uint16_t  msg4TxPduLen;
257    MacDlData msg4DlData;
258    MacCeInfo  macCeData;
259    DlHarqProcCb *hqProcCb;
260
261    GET_CELL_IDX(cellId, cellIdx);
262
263    memset(&msg4DlData, 0, sizeof(MacDlData));
264    memset(&macCeData, 0, sizeof(MacCeInfo));
265
266    GET_UE_ID(msg4SchInfo->dlMsgInfo.crnti, ueId);
267    ueIdx = ueId -1;
268
269    if(macCb.macCell[cellIdx] == NULLP)
270    {
271       DU_LOG("\nERROR -->  MAC: Cell Id[%d] not found", cellId);
272       return;
273    }
274
275    hqProcCb = &macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4HqInfo;
276    msg4TxPduLen = hqProcCb->tbInfo[0].tbSize - TX_PAYLOAD_HDR_LEN;
277
278    if(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4Pdu != NULLP)
279    {
280       MAC_ALLOC(msg4DlData.pduInfo[msg4DlData.numPdu].dlPdu, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen);
281       if(msg4DlData.pduInfo[msg4DlData.numPdu].dlPdu != NULLP)
282       {
283          fillMsg4DlData(&msg4DlData, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen, \
284             macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4Pdu);
285          fillMacCe(&macCeData, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg3Pdu);
286
287          /* Forming Mux Pdu */
288          hqProcCb->tbInfo[0].tb = NULLP;
289          MAC_ALLOC(hqProcCb->tbInfo[0].tb, msg4TxPduLen);
290          if(hqProcCb->tbInfo[0].tb != NULLP)
291          {
292             memset(hqProcCb->tbInfo[0].tb, 0, msg4TxPduLen);
293             macMuxPdu(&msg4DlData, &macCeData, hqProcCb->tbInfo[0].tb, msg4TxPduLen);
294          }
295          else
296          {
297             DU_LOG("\nERROR  -->  MAC: Failed allocating memory for msg4TxPdu");
298          }
299          /* Free memory allocated */
300          MAC_FREE(msg4DlData.pduInfo[msg4DlData.numPdu-1].dlPdu, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen);
301          MAC_FREE(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4Pdu, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen);
302          macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4Pdu = NULLP;
303          macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen = 0;
304          msg4DlData.numPdu--;
305
306       }
307    }
308
309    /* storing msg4 Pdu in macDlSlot */
310    if(hqProcCb->tbInfo[0].tb)
311    {
312       msg4SchInfo->dlMsgInfo.dlMsgPduLen = msg4TxPduLen;
313       MAC_ALLOC(msg4SchInfo->dlMsgInfo.dlMsgPdu, msg4SchInfo->dlMsgInfo.dlMsgPduLen);
314       if(msg4SchInfo->dlMsgInfo.dlMsgPdu != NULLP)
315       {
316          memcpy(msg4SchInfo->dlMsgInfo.dlMsgPdu, hqProcCb->tbInfo[0].tb, \
317                msg4SchInfo->dlMsgInfo.dlMsgPduLen);
318       }
319    }
320    else
321    {
322       DU_LOG("\nERROR  -->  MAC: Failed at fillMsg4Pdu()");
323    }
324 }
325
326 /**
327  * @brief Builds and Send the Muxed Pdu to Lower MAC
328  *
329  * @details
330  *
331  *     Function : buildAndSendMuxPdu
332  * 
333  *      Build and Sends the Muxed Pdu to Lower MAC.
334  *           
335  *  @param[in]  SlotTimingInfo    *slotInd
336  *  @return  void
337  **/
338
339 void buildAndSendMuxPdu(SlotTimingInfo currTimingInfo)
340 {
341    uint8_t   ueIdx;
342    uint8_t   schInfoIdx;
343    uint16_t  cellIdx;
344    MacDlSlot *currDlSlot = NULLP;
345    SlotTimingInfo muxTimingInfo;
346    memset(&muxTimingInfo, 0, sizeof(SlotTimingInfo));
347
348    GET_CELL_IDX(currTimingInfo.cellId, cellIdx);
349
350    ADD_DELTA_TO_TIME(currTimingInfo, muxTimingInfo, PHY_DELTA_DL);
351    currDlSlot = &macCb.macCell[cellIdx]->dlSlot[muxTimingInfo.slot];
352
353    for(ueIdx=0; ueIdx<MAX_NUM_UE; ueIdx++)
354    {
355       if(currDlSlot->dlInfo.dlMsgAlloc[ueIdx])
356       {
357          for(schInfoIdx=0; schInfoIdx<currDlSlot->dlInfo.dlMsgAlloc[ueIdx]->numSchedInfo; schInfoIdx++)
358          {
359             if((currDlSlot->dlInfo.dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgInfo.isMsg4Pdu) &&
360                   ((currDlSlot->dlInfo.dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].pduPres == PDSCH_PDU) ||
361                    (currDlSlot->dlInfo.dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].pduPres == BOTH)))
362             {
363                fillMsg4Pdu(currTimingInfo.cellId, &currDlSlot->dlInfo.dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx]);
364             }
365          }
366       }
367    }
368 }
369
370 /**
371  * @brief Transmission time interval indication from PHY.
372  *
373  * @details
374  *
375  *     Function : sendSlotIndMacToSch
376  * 
377  *      This API is invoked by MAC to send slot ind to scheduler.
378  *           
379  *  @param[in]  SlotTimingInfo    *slotInd
380  *  @return  
381  *      -# ROK 
382  *      -# RFAILED 
383  **/
384 int sendSlotIndMacToSch(SlotTimingInfo *slotInd)
385 {
386    /* fill Pst structure to send to lwr_mac to MAC */
387    Pst pst;
388
389    FILL_PST_MAC_TO_SCH(pst, EVENT_SLOT_IND_TO_SCH);
390    return(*macSchSlotIndOpts[pst.selector])(&pst,slotInd);
391 }
392
393 /*******************************************************************
394  *
395  * @brief Send cell up indication to DU APP
396  *
397  * @details
398  *
399  *    Function : sendCellUpIndMacToDuApp
400  *
401  *    Functionality:
402  *       Send cell up indication to DU APP
403  *
404  * @params[in] Cell Up indication info 
405  * @return ROK     - success
406  *         RFAILED - failure
407  *
408  * ****************************************************************/
409 int sendCellUpIndMacToDuApp(uint16_t cellId)
410 {
411    Pst pst;
412    uint16_t ret;
413    OduCellId *oduCellId;
414
415    /*  Allocate sharable memory */
416    MAC_ALLOC_SHRABL_BUF(oduCellId, sizeof(OduCellId));
417    if(!oduCellId)
418    {
419       DU_LOG("\nERROR  -->  MAC : Memory allocation failed for cell up indication");
420       return RFAILED;
421    }
422    oduCellId->cellId = cellId;
423
424    /* Fill Pst */
425    FILL_PST_MAC_TO_DUAPP(pst, EVENT_MAC_CELL_UP_IND);
426
427    ret = MacDuAppCellUpInd(&pst, oduCellId);
428    if(ret != ROK)
429    {
430       DU_LOG("\nERROR  -->  MAC: Failed to send cell up indication to DU APP");
431       MAC_FREE_SHRABL_BUF(MAC_MEM_REGION, MAC_POOL, oduCellId, sizeof(OduCellId));
432    }
433
434    return ret;
435 } /* sendCellUpIndMacToDuApp */
436
437 /*******************************************************************
438  *
439  * @brief Send slot indication to DU APP
440  *
441  * @details
442  *
443  *    Function : sendSlotIndToDuApp
444  *
445  *    Functionality:
446  *       Send cell up indication to DU APP
447  *
448  * @params[in] Cell Up indication info 
449  * @return ROK     - success
450  *         RFAILED - failure
451  *
452  * ****************************************************************/
453 uint8_t sendSlotIndToDuApp(SlotTimingInfo *slotInd)
454 {
455    Pst pst;
456    uint16_t ret;
457    SlotTimingInfo *slotIndInfo;
458
459    /*  Allocate sharable memory */
460    MAC_ALLOC_SHRABL_BUF(slotIndInfo, sizeof(SlotTimingInfo));
461    if(!slotIndInfo)
462    {
463       DU_LOG("\nERROR  -->  MAC : Memory allocation failed for slot indication");
464       return RFAILED;
465    }
466    memcpy(slotIndInfo, slotInd,sizeof(SlotTimingInfo));
467
468    /* Fill Pst */
469    FILL_PST_MAC_TO_DUAPP(pst, EVENT_MAC_SLOT_IND);
470
471    ret = MacDuAppSlotInd(&pst, slotIndInfo);
472    if(ret != ROK)
473    {
474       DU_LOG("\nERROR  -->  MAC: Failed to send slot up indication to DU APP");
475       MAC_FREE_SHRABL_BUF(MAC_MEM_REGION, MAC_POOL, slotIndInfo, sizeof(SlotTimingInfo));
476    }
477
478    return ret;
479 }
480 /*******************************************************************
481  *
482  * @brief Process slot indication at MAC
483  *
484  * @details
485  *
486  *    Function : macProcSlotInd
487  *
488  *    Functionality: Process slot indication at MAC
489  *
490  * @params[in] Slot indication info
491  * @return ROK     - success
492  *         RFAILED - failure
493  *
494  * ****************************************************************/
495 uint8_t macProcSlotInd(SlotTimingInfo slotInd)
496 {
497    uint16_t  cellIdx = 0;
498
499    GET_CELL_IDX(slotInd.cellId, cellIdx);
500    
501    if(macCb.macCell[cellIdx] == NULLP)
502    {
503       DU_LOG("ERROR  --> MAC : macProcSlotInd(): CellId[%d] does not exist. Error occurred at SFN [%d] Slot [%d]",\
504       slotInd.cellId, slotInd.sfn, slotInd.slot);
505       return RFAILED;
506    }
507    /* Store current time info */
508    macCb.macCell[cellIdx]->currTime.cellId = slotInd.cellId;
509    macCb.macCell[cellIdx]->currTime.slot = slotInd.slot;
510    macCb.macCell[cellIdx]->currTime.sfn = slotInd.sfn;
511
512    /* Mux Pdu for Msg4 */
513    buildAndSendMuxPdu(slotInd);
514
515    /* Trigger for DL TTI REQ */
516    fillDlTtiReq(slotInd);
517
518    return ROK;
519 }  /* macProcSlotInd */
520
521 /**
522  * @brief Transmission time interval indication from PHY.
523  *
524  * @details
525  *
526  *     Function : fapiMacSlotInd 
527  *      
528  *      This API is invoked by PHY to indicate TTI indication to MAC for a cell.
529  *           
530  *  @param[in]  Pst            *pst
531  *  @param[in]  SuId           suId 
532  *  @param[in]  SlotTimingInfo    *slotInd
533  *  @return  
534  *      -# ROK 
535  *      -# RFAILED 
536  **/
537 uint8_t fapiMacSlotInd(Pst *pst, SlotTimingInfo *slotInd)
538 {
539    uint8_t               ret = ROK;
540    uint16_t              cellIdx;
541    volatile uint32_t     startTime=0;
542
543 #ifdef ODU_SLOT_IND_DEBUG_LOG
544    DU_LOG("\nDEBUG  -->  MAC : Slot Indication received. [%d : %d]", slotInd->sfn, slotInd->slot);
545 #endif
546    /*starting Task*/
547    ODU_START_TASK(&startTime, PID_MAC_TTI_IND);
548    gSlotCount++;
549
550    if(gSlotCount == 1)
551    {
552            GET_CELL_IDX(slotInd->cellId, cellIdx);
553            macCb.macCell[cellIdx]->state = CELL_STATE_UP;
554    }
555
556 /* When testing L2 with Intel-L1, any changes specific to 
557  * timer mode testing must be guarded under INTEL_TIMER_MODE*/
558 #ifndef INTEL_TIMER_MODE
559    /* send slot indication to scheduler */
560    ret = sendSlotIndMacToSch(slotInd);
561    if(ret != ROK)
562    {
563       DU_LOG("\nERROR  -->  MAC : Sending of slot ind msg from MAC to SCH failed");
564       MAC_FREE_SHRABL_BUF(pst->region, pst->pool, slotInd, sizeof(SlotTimingInfo));
565       return ret;
566    }
567
568    ret = macProcSlotInd(*slotInd);
569    if(ret != ROK)
570    {
571       DU_LOG("\nERROR  -->  MAC : macProcSlotInd failed");
572       MAC_FREE_SHRABL_BUF(pst->region, pst->pool, slotInd, sizeof(SlotTimingInfo));
573       return ret;
574    }
575 #endif
576
577    /*First Slot Ind is for CellUp. Any other Slot, will be notified to DUAPP as
578     * SLOT_IND*/
579    if(gSlotCount == 1)   
580    {
581       /* send cell up indication to du app */
582       ret = sendCellUpIndMacToDuApp(slotInd->cellId);
583
584    }
585    else
586    {
587       /* send slot indication to du app */
588       ret = sendSlotIndToDuApp(slotInd);
589    }
590    
591    if(ret != ROK)
592    {
593       DU_LOG("\nERROR  -->  MAC :Sending of slot ind msg from MAC to DU APP failed");
594       MAC_FREE_SHRABL_BUF(pst->region, pst->pool, slotInd, sizeof(SlotTimingInfo));
595       return ret;
596    }
597
598    /*stoping Task*/
599    ODU_STOP_TASK(startTime, PID_MAC_TTI_IND);
600    MAC_FREE_SHRABL_BUF(pst->region, pst->pool, slotInd, sizeof(SlotTimingInfo));
601
602 #ifdef INTEL_WLS_MEM
603    lwrMacCb.phySlotIndCntr++;
604    if(lwrMacCb.phySlotIndCntr > WLS_MEM_FREE_PRD)
605    {
606       lwrMacCb.phySlotIndCntr = 1;
607    }
608    freeWlsBlockList(lwrMacCb.phySlotIndCntr - 1);
609 #endif
610
611    return ret;
612 }  /* fapiMacSlotInd */
613
614 /**********************************************************************
615   End of file
616  **********************************************************************/
617