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