[Epic-ID: ODUHIGH-462][Task-ID: ODUHIGH-472] Changes in handling of slot indication...
[o-du/l2.git] / src / 5gnrmac / rg_dhm.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 /************************************************************************
20  
21      Name:     LTE-MAC layer
22   
23      Type:     C source file
24   
25      Desc:     C source code for Entry point fucntions
26   
27      File:     rg_dhm.c
28   
29 **********************************************************************/
30
31 /** @file rg_dhm.c
32 @brief APIs related to Downlink HARQ.
33 */
34
35 /* header include files -- defines (.h) */
36 #include "common_def.h"
37 #ifdef L2_OPTMZ
38 #include "ss_strm.h"
39 #endif
40 #include "lrg.h"
41 #include "crg.h"
42 #include "tfu.h"
43 #include "rgu.h"
44 #include "rg_sch_inf.h"
45 #include "rg_env.h"
46 #include "rg_err.h"
47 #include "rg.h"
48 #include "du_app_mac_inf.h"
49
50 /* header/extern include files (.x) */
51 #ifdef L2_OPTMZ
52 #include "ss_strm.x"
53 #endif
54 #include "lrg.x"
55 #include "crg.x"
56 #include "tfu.x"
57 #include "rgu.x"
58 #include "rg_sch_inf.x"
59 #include "rg_prg.x"        /* PRG interface typedefs */
60 #include "rg.x"
61
62 #ifdef L2_OPTMZ
63 #include "ss_queue.h"
64 #include "ss_queue.x"
65 #include "ss_task.x"
66 #include "ss_msg.x"            /* MAC includes */
67 /* local defines */
68 // S16 ssGetDBufOfSize(Region region,Size size,Buffer **dBuf);
69 //void prc_trace_format_string(UINT32 group_mask, UINT16 level, const char *format, ...);
70 #endif
71
72 /* local typedefs */
73  
74 /* local externs */
75 S16 SIncMsgRef(Buffer *srcBuf,Region dstRegion, Pool dstPool,Buffer **dstBuf);
76
77 static Void rgDHMBldTfuDatReq ARGS((RgCellCb *cellCb, RgDlSf *dlSf, RgDlHqProcCb *hqP,
78                            RgTfuDatReqPduInfo *datReq));
79
80 #ifdef L2_OPTMZ
81 S16 rgDHMFreeHqProcTB
82 (
83 RgDlHqProcCb *hqP,
84 uint8_t      tbIndex
85 );
86
87 #endif
88
89 /* forward references */
90
91 /**
92  * @brief This function initializes the DL HARQ Entity of UE
93  *
94  * @details
95  *
96  *     Function: rgDHMHqEntInit
97  *     Purpose:  This function initializes the DL HARQ entity of 
98  *               UE control block. This is performed at the time
99  *               of creating UE control block.
100  *     
101  *     Invoked by: configuration module
102  *     
103  *  @param[in]  Inst        inst
104  *  @param[in]  RgCellCb*  cell
105  *  @param[in]  RgUeCb*    ue
106  *  @return  S16
107  *           -# ROK
108  *           -# RFAILED
109  *
110  **/
111 S16 rgDHMHqEntInit(Inst  inst, RgDlHqEnt *hqE, uint8_t maxHqProcs)
112 {
113    uint8_t idx1,idx2;
114 #ifdef L2_OPTMZ
115    Buffer  *hdrDBuf = NULLP;
116    Buffer  *ceDBuf = NULLP;
117 #endif
118
119    hqE->numHqProcs = maxHqProcs;
120    /* for each harq process */
121    for (idx1 = 0; idx1 < hqE->numHqProcs; idx1++)
122    {
123       if (rgAllocSBuf(inst,(Data **)&(hqE->procs[idx1]),sizeof(RgDlHqProcCb)) != ROK) 
124       {
125          while(idx1--)
126          {
127             rgFreeSBuf(inst,(Data **)&(hqE->procs[idx1]), sizeof(RgDlHqProcCb));
128          }
129          DU_LOG("\nERROR  -->  MAC : Memory Alloc Failure for RgDlHqProcCb");        
130          return RFAILED;
131       }
132
133       hqE->procs[idx1]->procId      = idx1;
134       for(idx2 = 0; idx2 < RG_MAX_TB_PER_UE; idx2++)
135       {
136 #ifndef L2_OPTMZ
137          hqE->procs[idx1]->tbInfo[idx2].tb = NULLP;
138 #else
139          Buffer *tmpMBuf;
140          /* L2 optimization for mUe/Tti: Allocating buffers for macHdr, macCes
141           * and macPadding. These buffers shall not be released by MAC/CL.
142           * However, Only rPtr and wPtr will be reset while release of hq proc
143           */
144          tmpMBuf = hqE->procs[idx1]->tbInfo[idx2].tb.macHdr;
145          rgGetMsg(inst, &tmpMBuf);
146          RG_ADD_DBuf(hdrDBuf, RG_MAC_HDR_SIZE, tmpMBuf);
147          hqE->procs[idx1]->tbInfo[idx2].tb.macHdr = tmpMBuf;
148          macHeader[idx2] = MacPtrAddress;
149
150          tmpMBuf = hqE->procs[idx1]->tbInfo[idx2].tb.macCes;
151          rgGetMsg(inst, &tmpMBuf);
152          RG_ADD_DBuf(ceDBuf, RG_MAC_CE_SIZE, tmpMBuf);
153          hqE->procs[idx1]->tbInfo[idx2].tb.macCes = tmpMBuf;
154
155          hqE->procs[idx1]->tbInfo[idx2].tb.padSize = 0;
156 #endif
157 #ifdef LTE_L2_MEAS
158          hqE->procs[idx1]->tbId[idx2] = RGU_INVALID_TBID;
159 #endif
160       }
161
162       cmLListInit(&hqE->savedProcLst[idx1]);
163    }
164
165
166    return ROK;
167 } /* rgDHMHqEntInit */
168
169 /**
170  * @brief This function releases a HARQ process
171  *
172  * @details
173  *
174  *     Function: rgDHMUeReset
175  *     Purpose:  This function resets TB in each HarqProc.
176  *     
177  *     Invoked by: CFG UE Reset 
178  *     
179  *  @param[in]  RgDlHqProc    *hqP
180  *  @return  Void      
181  *
182  **/
183 Void rgDHMUeReset(RgCellCb *cell, RgDlHqEnt  *hqE)
184 {
185    uint8_t       i = 0;
186
187    if(hqE->procs[0])
188    {
189       /* Free all the TB memory associated with HARQ */
190       for (i=0; i < hqE->numHqProcs; i++)
191       {
192          rgDHMRlsHqProcTB(cell, hqE->procs[i], 1);
193          rgDHMRlsHqProcTB(cell, hqE->procs[i], 2);
194
195 #ifdef LTE_ADV
196          rgDHMFreeSavedHqP((cell->macInst - RG_INST_START), hqE, i);
197 #endif
198       }
199    }
200    return;
201 } /* rgDHMUeReset*/
202
203 /**
204  * @brief This function defers shared memory buffer
205  *        freeing out of the critical RT path.
206  *
207  * @details
208  *
209  *     Function: rgDHMHdlBufFree
210  *     Purpose: To defer shared memory freeing post 
211  *              critical path. Defer as many if defer queue 
212  *              is full then release instantly.
213  *     
214  *     Invoked by: HARQ TB Release. 
215  *     
216  *  @return  Void      
217  *
218  **/
219 Void rgDHMHdlBufFree(Inst inst, Buffer **mBuf)
220 {
221    RgCb *rgCbP = &rgCb[inst];
222
223    if (rgCbP->bufCnt < RG_MAX_DFRD_FREE_BUFS)
224    {
225       if (*mBuf)
226       {
227          rgCbP->bufToFree[rgCbP->bufCnt] = *mBuf;
228          rgCbP->bufCnt++;
229          *mBuf = NULLP;
230       }
231    }
232    else
233    {
234       RG_FREE_MSG(*mBuf);
235    }
236    return;
237 }
238 /**
239  * @brief This function is called to release the 
240  *        shared memory of the HARQ TBs outside 
241  *        the critical RT path.
242  *
243  * @details
244  *
245  *     Function: rgDHMFreeTbBufs
246  *     Purpose: This function is called to release the 
247  *        shared memory of the HARQ TBs outside 
248  *        the critical RT path.
249  *     
250  *     1. Job of releasing TBs is shared across TTIs
251  *     Invoked by: MAC every TTI 
252  *     
253  *  @return  Void      
254  *
255  **/
256 Void rgDHMFreeTbBufs(Inst inst)
257 {
258    RgCb *rgCbP = &rgCb[inst];
259    uint8_t start = rgCbP->bufCnt;
260    uint8_t end = 0;
261
262    if (rgCbP->bufCnt < RG_MAX_FREE_BUFS_PERTTI)
263    {
264       end = 0;
265    }
266    else
267    {
268       end = rgCbP->bufCnt - RG_MAX_FREE_BUFS_PERTTI;
269    }
270    while (start != end)
271    {
272       start--;
273       ODU_PUT_MSG_BUF(rgCbP->bufToFree[start]);
274    }
275    rgCbP->bufCnt = end;
276    return;
277 } /* rgDHMFreeTbBufs */
278
279 Void rgDHMFreeAllTbBufs(Inst inst)
280 {
281    RgCb *rgCbP = &rgCb[inst];
282    uint8_t start = rgCbP->bufCnt;
283    uint8_t end = 0;
284
285    while (start != end)
286    {
287       start--;
288       ODU_PUT_MSG_BUF(rgCbP->bufToFree[start]);
289    }
290    rgCbP->bufCnt = end;
291    return;
292 } /* rgDHMFreeTbBufs */
293
294
295 /**
296  * @brief This function releases a HARQ process
297  *
298  * @details
299  *
300  *     Function: rgDHMRlsHqProcTB
301  *     Purpose:  This function returns a HARQ process to HARQ Entity 
302  *               in the DL direction.
303  *     
304  *               1. Add the HARQ process to the free queue.
305  *     Invoked by: scheduler and HARQ processing
306  *     
307  *  @param[in]  RgDlHqProc    *hqP
308  *  @return  Void      
309  *
310  **/
311 S16 rgDHMRlsHqProcTB(RgCellCb  *cell, RgDlHqProcCb *hqP, uint8_t tbIndex)
312 {
313    uint8_t          idx;
314 #ifdef L2_OPTMZ
315    RgTfuDatReqTbInfo     *tb;   /* TB to be sent to CL/PHY*/
316    // uint32_t lchIdx, pduIdx;
317 #endif
318
319    if((tbIndex > RG_MAX_TB_PER_UE) ||
320          (tbIndex == 0))
321    {
322       return RFAILED;
323    }
324
325    hqP->tbInfo[tbIndex-1].numSchLch = 0;
326 #ifndef L2_OPTMZ
327    if (hqP->tbInfo[tbIndex-1].tb)
328    {
329       rgDHMHdlBufFree(cell->macInst - RG_INST_START, &hqP->tbInfo[tbIndex-1].tb);
330    }
331 #else
332    /* L2 Optimization for mUe/Tti:  macHdr, macCes and macPad mBuf pointers
333     * shall not be released. However, Inorder to release harq info/TB info,
334     * just Resetting rPtr and wPtr of these mbufs to db_base
335     */
336    tb = &(hqP->tbInfo[tbIndex-1].tb);
337    if (tb->tbPres == TRUE)
338    {
339       RG_FREE_TB(tb);
340    }
341 #endif
342    hqP->tbInfo[tbIndex-1].schdTa.pres = FALSE;
343 #ifdef LTE_ADV
344    hqP->tbInfo[tbIndex -1].sCellActCe.pres = FALSE;
345 #endif
346
347    /* Decrementing might lead to roundoff error in case of say UE reset
348     * where all the HqProcs irrespective whether in use are called for rls.
349     * Hence to avoid the same shift operator is being used. */
350    hqP->numOfTBs = hqP->numOfTBs >> 1;
351    for(idx = 0; idx < 2; idx++)
352    {
353       if (hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk.node != NULLP)
354       {
355          cmLListDelFrm(&hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sf->tbs,
356                &(hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk));
357          hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk.node  = (PTR)NULLP;
358          DU_LOG("\nINFO  -->  MAC : rgDHMRlsHqProcTB:: hqP %p \n", (Void *)hqP);
359       }
360       hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sf = NULLP;
361    }
362    /* Fix : syed It is better to reset these feilds
363     * corruption avoidance */
364    hqP->tbInfo[tbIndex-1].tbSz = 0;
365    hqP->tbInfo[tbIndex-1].contResCe = NOTPRSNT;
366    hqP->tbInfo[tbIndex-1].contResId = NULLP;
367
368    return ROK;
369 } /* rgDHMRlsHqProc */
370
371 /**
372  * @brief This function gets HARQ process with the given Id
373  *
374  * @details
375  *
376  *     Function: rgDHMGetHqProcFrmId
377  *     Purpose:  This function returns the HARQ process with the given ID.
378  *     Invoked by: ROM
379  *     
380  *  @param[in]  RgUeCb        *ue
381  *  @param[in]  uint8_t            idx
382  *  @param[in]  RgDlHqProc    **hqP
383  *  @return  S16       
384  *         -#   ROK     if successful
385  *         -#   RFAILED otherwise
386  *
387  **/
388 S16 rgDHMGetHqProcFrmId(RgUeCb *ue, uint8_t  idx, RgDlHqProcCb **hqP)
389 {
390    /* Pick the proc based on the index provided */
391    *hqP = (ue->dl.hqEnt.procs[idx]);
392
393    return ROK;
394 } /* rgDHMGetHqProcFrmId */
395
396 /*static uint32_t dataAvl; */
397 /**
398  * @brief Handler for sending data to PHY
399  *
400  * @details
401  *
402  *     Function : rgDHMSndDatReq
403  *     
404  *     This function shall send the MAC PDU built for the UE to TOM
405  *     when invoked as part of TTI processing and keep track of the number of
406  *     transmissions for this TB.
407  *     
408  *           
409  *  @param[in]  RgCellCb      *cell
410  *  @param[in]  RgDlHqProcCb  *hqE 
411  *  @param[out] RgErrInfo     *err 
412  *  @return     S16
413  *      -#ROK 
414  *      -#RFAILED 
415  **/
416    S16 rgDHMSndDatReq
417 (
418  RgCellCb        *cellCb,
419  RgDlSf          *dlSf,
420  RgTfuDatReqInfo *datInfo,
421  RgDlHqProcCb   *hqP,
422  RgErrInfo      *err 
423  )
424 {
425    uint8_t i;
426    Inst    inst = cellCb->macInst - RG_INST_START;
427    RgTfuDatReqPduInfo   *datReq;
428    RgBldPduInfo      bldPdu;
429    /*Added this variable to figure out that whether this UE data
430      has to be inclueded in the TFU Data request.*/
431    Bool  dataAvlblUe;
432
433    dataAvlblUe = TRUE;
434    for(i=0;i< RG_MAX_TB_PER_UE;i++)
435    {
436       /* DU_LOG("\nDHMSndDatReq1: Rnti %d dlSfSchdTime(sfn sf) : (%d %d)\n"
437          "macCell(sfn sf): (%d %d) tbTimingInfo(sfn sf): (%d %d)\n"
438          "dlSf %p dlSf->tbs.count %d hqp %p tb %p\n",
439          hqP->tbInfo[i].pdcch.rnti,
440          dlSf->schdTime.sfn, dlSf->schdTime.slot,
441          cellCb->crntTime.sfn, cellCb->crntTime.slot,
442          hqP->tbInfo[i].timingInfo.sfn, 
443          hqP->tbInfo[i].timingInfo.slot,
444          (Void *)dlSf, dlSf->tbs.count,
445          (Void *)hqP,
446          (Void *)hqP->tbInfo[i].tb);*/
447       /* Mukesh :: in case of rpepetiton this is not rerd*/
448       if (hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf == dlSf)
449       {
450          /* Check if data from RLC had been received and got muxed. */
451 #ifndef L2_OPTMZ
452          if (hqP->tbInfo[i].tb == NULLP) 
453 #else
454             if (!(hqP->tbInfo[i].tb.tbPres)) 
455 #endif
456             {
457 #ifndef LTE_ADV
458                if (hqP->tbInfo[i].schdTa.pres == TRUE ||
459                      hqP->tbInfo[i].contResCe == PRSNT_NODEF)
460 #else
461                   if ((hqP->tbInfo[i].schdTa.pres == TRUE) ||
462                         (hqP->tbInfo[i].contResCe == PRSNT_NODEF) ||
463                         (hqP->tbInfo[i].sCellActCe.pres == TRUE))
464 #endif
465                   {
466                      /* Data not received but ta needs to be sent. */
467                      /* MUX TA and send it */
468                      bldPdu.datReq    =  NULLP;
469                      //bldPdu.reqType   =  EVENT_SLOT_IND_TO_MAC;
470                      bldPdu.schdTbSz  =  hqP->tbInfo[i].tbSz;
471                      bldPdu.ta        =  hqP->tbInfo[i].schdTa;
472 #ifdef LTE_ADV
473                      bldPdu.sCellActCe= hqP->tbInfo[i].sCellActCe;
474 #endif
475                      /* changes for CR timer implementation*/
476                      bldPdu.contResId =  hqP->tbInfo[i].contResId;
477                      if (ROK != rgMUXBldPdu(inst,&bldPdu, &(hqP->tbInfo[i].tb), err))  
478                      {
479                         DU_LOG("\nERROR  -->  MAC : MUXing failed for:  MacInst %d", inst);
480                         DU_LOG("\nERROR  -->  MAC : MUXing failed for:  time: %d/%d\
481                               procId %d ueId %d", hqP->tbInfo[i].timingInfo.sfn,
482                               hqP->tbInfo[i].timingInfo.slot, hqP->procId, 
483                               hqP->tbInfo[i].pdcch.rnti);
484
485                         return RFAILED;
486                      }
487                   }
488                   else   
489                   {
490 #ifdef LTEMAC_RGU_PAD
491                      /* Data not received from RLC. Padding at MAC */
492                      bldPdu.datReq    =  NULLP;
493                      //bldPdu.reqType   =  EVENT_SLOT_IND_TO_MAC;
494                      bldPdu.schdTbSz  =  hqP->tbInfo[i].tbSz;
495                      bldPdu.ta        =  hqP->tbInfo[i].schdTa;
496 #ifdef LTE_ADV
497                      bldPdu.sCellActCe= hqP->tbInfo[i].sCellActCe;
498 #endif
499                      bldPdu.ta.val    =  0;
500                      bldPdu.contResId =  NULLP;
501
502                      if (ROK != rgMUXBldPdu(inst,&bldPdu, &(hqP->tbInfo[i].tb), err))  
503                      {
504                         DU_LOG("\nERROR  -->  MAC : MUXing failed for:  MacInst %d", inst);
505                         DU_LOG("\nERROR  -->  MAC : MUXing failed for:  time: %d/%d\
506                               procId %d ueId %d", hqP->tbInfo[i].timingInfo.sfn,
507                               hqP->tbInfo[i].timingInfo.slot, hqP->procId, 
508                               hqP->tbInfo[i].pdcch.rnti);
509
510                         return RFAILED;
511                      }
512 #else
513                      /*Padding is not done so data for this UE will not be
514                        included.*/
515                      dataAvlblUe = FALSE;
516 #endif
517                   }
518             }
519             else
520             {
521             }
522       }
523       //else
524       {
525       }
526    }
527
528    /*If Data/Padding is not available for UE, then we can not include
529      any Data for this UE in TFU Data Request.*/
530    if(!dataAvlblUe)
531    {
532       /*Free up the HARQ process for this allocation.*/
533       /* Release First TB, as this would be anyway there*/
534       rgDHMRlsHqProcTB(cellCb, hqP, 1);
535       if(2 == hqP->numOfTBs)
536       {
537          rgDHMRlsHqProcTB(cellCb, hqP, 2);
538       }
539
540       return ROK;
541    }
542
543    if (rgGetEventMem(inst,(Ptr *)&datReq, sizeof(TfuDatReqPduInfo),
544             &(datInfo->memCp)) != ROK)
545    {
546       return RFAILED;
547    }
548    /* Fill the TFU Dat Req with information from Harq Proc */
549
550    rgDHMBldTfuDatReq(cellCb, dlSf, hqP, datReq);
551
552    /* MS_WORKAROUND for ccpu00122894 */
553    for(i=0;i< RG_MAX_TB_PER_UE;i++)
554    {
555       if (hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf == dlSf)
556       {
557          cmLListDelFrm(&dlSf->tbs, &(hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk));
558          hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk.node = NULLP;
559
560
561          hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf = NULLP;
562       }
563    }
564    cmLListAdd2Tail(&datInfo->pdus, &(datReq->lnk));
565    datReq->lnk.node = (PTR)datReq;
566
567    return ROK;
568 }  /* rgDHMSndDatReq */
569
570 /**
571  * @brief Function to handle RGU datReq received from ROM
572  *
573  * @details
574  *
575  *     Function : rgDHMHndlDedDatReq
576  *     
577  *     This function shall act on the datReq received on RGU. It shall 
578  *     store the data IDs for all the logical channels and get the MAC 
579  *     PDU built.
580  *     
581  *           
582  *  @param[in]  Inst        inst
583  *  @param[in]  RgDlHqProcCb   *hqProc 
584  *  @param[in]  RgRguDedDatReq *datReq
585  *  @param[out] RgErrInfo      *err
586  *  @return     S16
587  *      -# ROK 
588  *      -# RFAILED 
589  **/
590    S16 rgDHMHndlDedDatReq
591 (
592  Inst           inst,
593  RgDlHqProcCb   *hqProc,
594  RgRguDDatReqPerUe *datReq,
595  RgDlSf            *dlSf,
596  RgErrInfo      *err
597  )
598 {
599    //   uint32_t            len;
600    uint8_t        i;
601    uint8_t        j;
602    RgBldPduInfo   bldPdu;
603    uint8_t        tbIndex;
604 #ifdef L2_OPTMZ
605    RgTfuDatReqTbInfo     *tb;
606 #endif
607
608
609    tbIndex = (uint8_t)(datReq->transId & 0x03);
610    /* Accept all the data requests even if delayed in case nothing
611     * has been sent earlier on the harq proc.
612     */
613    if((datReq->nmbOfTbs > RG_MAX_TB_PER_UE) ||
614          (tbIndex == 0))
615    {
616       /* release corresponding TBs from SF tbs List */
617       for(j=0;j<datReq->nmbOfTbs;j++)
618       {
619          if (!(tbIndex & (j+1)))
620          {
621             j++;
622          } 
623          rgDHMRlsHqProcTB(rgCb[inst].cell, hqProc, (uint8_t)(j+1));
624       }
625       return RFAILED;
626    }
627
628    for(i=0;i<datReq->nmbOfTbs;i++)
629    {
630       /* tbIndex 01 corresponds to presence of 1st TB
631        * 10 corresponds 2nd TB
632        * 11 corresponds two TBs of UE */
633       if (!(tbIndex & (i+1)))
634       {
635          continue;
636       }
637       if (hqProc->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk.node == NULLP)
638       {
639          /* release corresponding TBs from SF tbs List */
640          for(j=0;j<datReq->nmbOfTbs;j++)
641          {
642             if (!(tbIndex & (j+1)))
643             {
644                j++;
645             }
646             rgDHMRlsHqProcTB(rgCb[inst].cell, hqProc, (uint8_t)(j+1));
647             DU_LOG("\nINFO  -->  MAC : rgDHMHndlDedDatReq:: hqP %p \n", (Void *)hqProc);
648          }
649          return RFAILED;
650
651       }
652 #ifndef L2_OPTMZ
653       RG_FREE_MSG(hqProc->tbInfo[i].tb);
654       /* L2 optimization for mUe/Tti: Pre-allocated mBuf pointers(macHdr, 
655        * macCes and MacPad) of harq TB need to be reset to db_base
656        */
657 #else
658       tb = &hqProc->tbInfo[i].tb;
659       if (tb->tbPres == TRUE)
660       {
661          RG_FREE_TB(tb);
662       }
663 #endif
664       bldPdu.datReq    =  datReq;
665       bldPdu.reqType   =  EVTRGUDDATREQ;
666       bldPdu.schdTbSz  =  hqProc->tbInfo[i].tbSz;
667       bldPdu.tbIndex   =  i+1;
668       bldPdu.ta        =  hqProc->tbInfo[i].schdTa;
669 #ifdef LTE_ADV
670       bldPdu.sCellActCe= hqProc->tbInfo[i].sCellActCe;
671 #endif
672       bldPdu.contResId =  NULLP;
673 #ifdef LTE_L2_MEAS
674       /* Store tbId from RLC in DDatRequest */
675       hqProc->tbId[i] = datReq->datReqTb[i].tbId;
676
677
678       hqProc->status[i] =  FALSE;
679 #endif 
680       if(rgMUXBldPdu(inst,&bldPdu, &(hqProc->tbInfo[i].tb), err) != ROK)
681       {
682          DU_LOG("\nERROR  -->  MAC : MUXing failed for:  MacInst %d", inst);
683          DU_LOG("\nERROR  -->  MAC : MUXing failed for:  time: %d/%d\
684                procId %d ueId %d", hqProc->tbInfo[i].timingInfo.sfn,
685                hqProc->tbInfo[i].timingInfo.slot, hqProc->procId, 
686                hqProc->tbInfo[i].pdcch.rnti);
687
688          /* release corresponding TBs from SF tbs List */
689          for(j=0;j<datReq->nmbOfTbs;j++)
690          {
691             if (!(tbIndex & (j+1)))
692             {
693                j++;
694             }
695             rgDHMRlsHqProcTB(rgCb[inst].cell, hqProc, (uint8_t)(j+1));
696          }
697          return RFAILED;
698       }
699       /*
700          SFndLenMsg(hqProc->tbInfo[i].tb, &len);
701        */
702    }
703    return ROK;
704 }  /* rgDHMHndlDedDatReq */
705
706 /**
707  * @brief Function to handle RGU datReq received from ROM
708  *
709  * @details
710  *
711  *     Function : rgDHMHndlCmnDatReq
712  *     
713  *     This function shall act on the datReq received on RGU. It shall 
714  *     store the data IDs for all the logical channels and get the MAC 
715  *     PDU built.
716  *     
717  *           
718  *  @param[in]  Inst        inst
719  *  @param[in]  RgDlHqProcCb   *hqProc 
720  *  @param[in]  RgRguCmnDatReq *datReq
721  *  @param[out] RgErrInfo      *err
722  *  @return     S16
723  *      -# ROK 
724  *      -# RFAILED 
725  **/
726    S16 rgDHMHndlCmnDatReq
727 (
728  Inst           inst,
729  RgDlHqProcCb   *hqProc,
730  RgRguCmnDatReq *datReq,
731  RgErrInfo      *err
732  )
733 {
734    RgUstaDgn      dgn;
735    RgBldPduInfo   bldPdu;
736
737 #ifndef L2_OPTMZ
738    if (hqProc->tbInfo[0].tb != NULLP)
739 #else
740       /* If numLch is non zero means HQ Proc is busy*/
741       if (hqProc->tbInfo[0].tb.tbPres)
742 #endif
743       {
744          /* datReq discarded. Generate an alarm */
745          rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_HARQ); 
746          rgLMMStaInd(inst,LCM_CATEGORY_PROTOCOL, LCM_EVENT_UI_INV_EVT,
747                LRG_CAUSE_HQ_PROC_BUSY, &dgn);
748          return RFAILED;
749       }
750
751    bldPdu.datReq    =  datReq;
752    bldPdu.reqType   =  EVTRGUCDATREQ;
753    bldPdu.schdTbSz  =  hqProc->tbInfo[0].tbSz;
754    bldPdu.ta        =  hqProc->tbInfo[0].schdTa;
755 #ifdef LTE_ADV
756    bldPdu.sCellActCe= hqProc->tbInfo[0].sCellActCe;
757 #endif
758
759    bldPdu.contResId  =  hqProc->tbInfo[0].contResId;
760
761    if(rgMUXBldPdu(inst,&bldPdu, &(hqProc->tbInfo[0].tb), err) != ROK)
762    {
763       DU_LOG("\nERROR  -->  MAC : MUXing failed for:  MacInst %d", inst); 
764       DU_LOG("\nERROR  -->  MAC : MUXing failed for: time: %d/%d\
765             procId %d ueId %d", hqProc->tbInfo[0].timingInfo.sfn,
766             hqProc->tbInfo[0].timingInfo.slot, hqProc->procId, 
767             hqProc->tbInfo[0].pdcch.rnti);
768
769       RG_FREE_MSG(datReq->pdu);
770       return RFAILED;
771    }
772
773    return ROK;
774 }  /* rgDHMHndlCmnDatReq */
775
776 /**
777  * @brief Function to get consolidate grants and send consolidated grant to RLC
778  *
779  * @details
780  *
781  *     Function : rgDHMSndConsolidatedStaInd
782  *     
783  *     This function shall be invoked by Scheduler to trigger DHM to send a
784  *     consolidated status indication of all UE scheduled in a TTI as well as
785  *     send consolidated CStaInd for MSG4 and for all common channels(PCCH,
786  *     if RGR_SI_SCH is not defined then it includes BCH and BCCH also)
787  *     
788  *           
789  *  @param[in]  RgCellCb       *cell
790  *  @param[in]  RgInfUeInfo   *ueInfo,
791  *  @param[in]  CmLteTimingInfo timingInfo,
792  *  @param[out] RgErrInfo      err
793  *  @param[in]  RguCStaIndInfo   *cStaInd
794  *  @return     S16
795  *      -# ROK 
796  *      -# RFAILED 
797  **/
798 RgUeCb  *gUe =NULLP;
799    S16 rgDHMSndConsolidatedStaInd
800 (
801  RgCellCb        *cell,
802  RgInfUeInfo     *ueInfo,
803  CmLteTimingInfo timingInfo,
804  RgErrInfo       *err
805  )
806 {
807    SuId            rguDlSpId;/*need to use spID instead of suID*/
808    uint8_t         idx;
809    uint8_t         ueIdx;
810    uint8_t         lcIdx;
811    uint8_t         tbIndex=0,idx1;
812    RgDlSf          *dlSf = &cell->subFrms[(timingInfo.slot % RG_NUM_SUB_FRAMES)];
813    Inst            inst = cell->macInst - RG_INST_START;
814    //   Bool            isDStaReqrd = FALSE;
815    RgRguDedStaInd  *dStaInd[rgCb[inst].numRguSaps] ;
816    RgUpSapCb      *rguDlSap[rgCb[inst].numRguSaps];
817
818    int lchBufSize =0;
819    RgUeCb         *ue;
820    RgDlHqProcCb   *hqP;
821    RgInfUeAlloc   *allocInfo;
822    uint8_t        activeSapCnt = 0;
823    uint8_t        staIndCnt    = 0;
824 #ifdef LTE_ADV
825    Bool           hqPAdded     = FALSE;
826 #endif
827 #ifdef L2_OPTMZ
828    RgTfuDatReqTbInfo     *tb;   /* TB to be sent to CL/PHY*/
829 #endif
830
831    memset (dStaInd, 0, (sizeof(RgRguDedStaInd *) * rgCb[inst].numRguSaps));
832    memset (rguDlSap, 0, (sizeof(RgUpSapCb  *) * rgCb[inst].numRguSaps));
833
834    /* Send StaInd for the scheduled UEs */
835    for(ueIdx = 0; ueIdx < ueInfo->numUes; ueIdx++)
836    {
837 #ifdef LTE_ADV
838       hqPAdded = FALSE;
839 #endif
840       if((ue=rgDBMGetUeCb (cell, ueInfo->allocInfo[ueIdx].rnti)) == NULLP)
841       {
842          /* Check in RachLst */
843          if((ue=rgDBMGetUeCbFromRachLst (cell, 
844                      ueInfo->allocInfo[ueIdx].rnti)) == NULLP)
845          {
846             DU_LOG("\nERROR  -->  MAC : CRNTI:%d No ueCb found", 
847                   ueInfo->allocInfo[ueIdx].rnti);
848             /*Fix: If one UE is not present dont return, look for the next.*/
849             continue;
850          }
851       }
852
853
854       rgDHMGetHqProcFrmId(ue,ueInfo->allocInfo[ueIdx].hqProcId,&hqP);
855       allocInfo = &ueInfo->allocInfo[ueIdx];
856       gUe = ue;
857
858       /* Fix : syed Avoid sending data for a RETX
859        * if initial TX data processing was unsuccessful */
860       if((allocInfo->tbInfo[0].isReTx == TRUE) &&
861             (hqP->tbInfo[0].tbSz == 0)) 
862       {
863          DU_LOG("\nERROR  -->  MAC : CRNTI:%d RETX hqP(%d) tb(0) for a failed New Tx", 
864                allocInfo->rnti, hqP->procId);        
865          continue;
866       }
867       if((allocInfo->tbInfo[1].isReTx == TRUE) &&
868             (hqP->tbInfo[1].tbSz == 0)) 
869       {
870          DU_LOG("\nERROR  -->  MAC : CRNTI:%d RETX hqP(%d) tb(1) for a failed New Tx", 
871                allocInfo->rnti, hqP->procId);        
872          continue;
873       }
874
875       if(ue->rguDlSap != NULLP)
876       {
877          rguDlSpId = ue->rguDlSap->sapCfg.spId;
878       }else
879       {/* UeCb is from rachList */
880          rguDlSpId = cell->rguDlSap->sapCfg.spId;
881       }
882
883
884       for(idx=allocInfo->tbStrtIdx;((idx-allocInfo->tbStrtIdx) <\
885                allocInfo->nmbOfTBs); idx++)
886       {
887          RguCStaIndInfo  *cStaInd;
888 #ifdef TFU_UPGRADE
889          /* LTE_ADV_FLAG_REMOVED_START */
890          hqP->tbInfo[idx].isEnbSFR = allocInfo->isEnbSFR;
891          /* update pA value */
892          hqP->tbInfo[idx].pa = allocInfo->pa;
893          /* LTE_ADV_FLAG_REMOVED_END */
894 #endif
895
896          hqP->numOfTBs =  allocInfo->nmbOfTBs;
897          hqP->tbInfo[idx].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk.node = (PTR)hqP;
898          hqP->tbInfo[idx].sfLnkInfo[dlSf->schdTime.slot % 2].sf = dlSf;
899          cmLListAdd2Tail(&dlSf->tbs,&(hqP->tbInfo[idx].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk));
900          /* Changes as part of performance testing*/
901          /*   hqP->numOfTBs++;*/
902          hqP->tbInfo[idx].doa = allocInfo->doa;
903          hqP->tbInfo[idx].txMode = allocInfo->txMode;
904          hqP->tbInfo[idx].puschRptUsd = allocInfo->puschRptUsd;
905          hqP->tbInfo[idx].puschPmiInfo = allocInfo->puschPmiInfo;
906 #ifdef LTEMAC_SPS
907          hqP->tbInfo[idx].pdcch.rnti = allocInfo->pdcchRnti;
908 #else
909          hqP->tbInfo[idx].pdcch.rnti = allocInfo->rnti;
910 #endif
911          if(allocInfo->tbInfo[idx].isReTx == TRUE)
912          {
913             hqP->tbInfo[idx].pdcch.dci = allocInfo->dciInfo;
914             continue;
915          }
916
917          hqP->tbInfo[idx].timingInfo = timingInfo;
918          hqP->tbInfo[idx].pdcch.dci = allocInfo->dciInfo;
919 #ifndef L2_OPTMZ
920          RG_FREE_MSG(hqP->tbInfo[idx].tb);
921 #else
922          /* L2 optimization for mUe/Tti: Pre-allocated mBuf pointers(macHdr, 
923           * macCes and MacPad) of harq TB need to be reset to db_base
924           */
925          tb = &(hqP->tbInfo[idx].tb);
926          if (tb->tbPres == TRUE)
927          {
928             RG_FREE_TB(tb);
929          }
930 #endif
931          hqP->tbInfo[idx].tbSz = allocInfo->tbInfo[idx].schdTbSz; 
932
933          hqP->tbInfo[idx].schdTa.pres = allocInfo->tbInfo[idx].ta.pres;
934          hqP->tbInfo[idx].schdTa.val  = allocInfo->tbInfo[idx].ta.val;
935
936 #ifdef LTE_ADV
937          hqP->tbInfo[idx].sCellActCe.pres = allocInfo->tbInfo[idx].sCellActCe.pres;
938          hqP->tbInfo[idx].sCellActCe.val  = allocInfo->tbInfo[idx].sCellActCe.val;
939 #endif
940
941 #ifdef LTE_ADV 
942          if(( hqPAdded == TRUE) || (ROK == rgLaaPushHqPToScellLst(allocInfo,cell,timingInfo)))
943          {
944             hqPAdded = TRUE;
945             continue;
946          }
947 #endif
948          if (allocInfo->tbInfo[idx].schdDat[0].lcId == RG_CCCH_LCID)        
949          {
950 #ifndef L2_OPTMZ
951             RG_FREE_MSG(hqP->tbInfo[idx].tb);
952 #else
953             /* L2 optimization for mUe/Tti: Pre-allocated mBuf pointers(macHdr, 
954              * macCes and MacPad) of harq TB need to be reset to db_base
955              */
956             tb = &(hqP->tbInfo[idx].tb);
957
958             if (tb->tbPres == TRUE)
959             {
960                RG_FREE_TB(tb);
961             }
962 #endif
963             hqP->tbInfo[0].contResCe  = allocInfo->tbInfo[0].contResCe;
964             if(allocInfo->tbInfo[0].contResCe)
965             {
966                hqP->tbInfo[0].contResId = &ue->contResId;
967             }
968
969
970             if(allocInfo->tbInfo[idx].numSchLch == 0)
971             {
972                DU_LOG("\nDEBUG  -->  MAC : UEID:%d MSG4 with only contResId hqP(%d)",
973                      allocInfo->rnti,
974                      hqP->procId);
975                hqP->tbInfo[idx].numSchLch = 0;
976                continue;
977             }
978
979             /* Increamenting the tbIndex instead of
980                assigning it to constant */
981             tbIndex++;
982
983
984             hqP->tbInfo[idx].numSchLch = 1;
985             hqP->tbInfo[idx].schdData[0].lcId = 
986                allocInfo->tbInfo[idx].schdDat[0].lcId;
987             hqP->tbInfo[idx].schdData[0].schdSz = 
988                allocInfo->tbInfo[idx].schdDat[0].numBytes;
989
990             // if(cStaInd == NULLP)
991             {
992                if ((rgAllocShrablSBuf(inst,(Data**)&cStaInd, sizeof(RguCStaIndInfo))) != ROK)
993                {
994                   err->errType  = RGERR_DHM_SND_STA_IND;
995                   err->errCause = RG_DHM_MEM_ALLOC_FAIL;
996                   return RFAILED; 
997                }
998             }
999
1000             idx1 = (hqP->procId << 2) | tbIndex;
1001
1002             cStaInd->cellId    = cell->cellId;
1003             cStaInd->rnti      = allocInfo->rnti;
1004             cStaInd->lcId      = cell->dlCcchId;
1005             cStaInd->transId   = (timingInfo.sfn << 16) | 
1006                (timingInfo.slot << 8) | idx1;
1007             /* ADD Changes for Downlink UE Timing Optimization */
1008 #ifdef LTEMAC_DLUE_TMGOPTMZ
1009             dlSf->remDatReqCnt++;
1010 #endif
1011             DU_LOG("\nDEUBG  -->  MAC : RNTI:%d UE:MSG4 grant for CCCH hqP(%d) LCID:%d",
1012                   allocInfo->rnti, 
1013                   hqP->procId,
1014                   cStaInd->lcId);       
1015             /* Fix : syed Avoid return param for interface prim and
1016              * proceed for other UEs. For the failed UE, MAC shall
1017              * do padding. */
1018             rgUIMSndCmnStaInd(cell->macInst,cell->rguDlSap,cStaInd);
1019             break;
1020          }
1021          else
1022          {
1023             tbIndex+=idx+1;
1024 #ifndef L2_OPTMZ
1025             RG_FREE_MSG(hqP->tbInfo[idx].tb);
1026 #else
1027             /* L2 optimization for mUe/Tti: Pre-allocated mBuf pointers(macHdr, 
1028              * macCes and MacPad) of harq TB need to be reset to db_base
1029              */
1030             tb = &(hqP->tbInfo[idx].tb);
1031             if (tb->tbPres == TRUE)
1032             {  
1033                RG_FREE_TB(tb);
1034             }
1035 #endif
1036
1037             if((NULLP == dStaInd[rguDlSpId]) && (allocInfo->tbInfo[idx].numSchLch))
1038             {
1039                if ((rgAllocShrablSBuf (inst,(Data**)&dStaInd[rguDlSpId], sizeof(RguDStaIndInfo))) != ROK)
1040                {
1041                   err->errType  = RGERR_DHM_SND_STA_IND;
1042                   err->errCause = RG_DHM_MEM_ALLOC_FAIL;
1043                   /* Need to return as memory allocation will fail for other UEs also*/
1044                   return RFAILED;
1045                }
1046                dStaInd[rguDlSpId]->nmbOfUeGrantPerTti = 0;
1047                rguDlSap[rguDlSpId] = ue->rguDlSap;
1048                activeSapCnt++;
1049             }
1050
1051             for (lcIdx = 0; 
1052                   lcIdx < allocInfo->tbInfo[idx].numSchLch; lcIdx++)
1053             {
1054                hqP->tbInfo[idx].schdData[lcIdx].lcId = 
1055                   allocInfo->tbInfo[idx].schdDat[lcIdx].lcId;
1056                if (hqP->tbInfo[idx].schdData[lcIdx].lcId == 0)
1057                {
1058                   DU_LOG("\nERROR  -->  MAC : CCCH grant in DStaInd for LCID:%d CRNTI:%d",
1059                         hqP->tbInfo[idx].schdData[lcIdx].lcId,allocInfo->rnti);
1060                }
1061                hqP->tbInfo[idx].schdData[lcIdx].schdSz = 
1062                   allocInfo->tbInfo[idx].schdDat[lcIdx].numBytes;
1063                if(dStaInd[rguDlSpId])
1064                {
1065                   dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].staIndTb[idx].\
1066                      lchStaInd[lcIdx].lcId = allocInfo->tbInfo[idx].\
1067                      schdDat[lcIdx].lcId;
1068                   dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].staIndTb[idx].\
1069                      lchStaInd[lcIdx].totBufSize = allocInfo->tbInfo[idx].\
1070                      schdDat[lcIdx].numBytes;
1071                }
1072
1073                lchBufSize+=allocInfo->tbInfo[idx].schdDat[lcIdx].numBytes;
1074             }
1075             hqP->tbInfo[idx].numSchLch = 
1076                allocInfo->tbInfo[idx].numSchLch;
1077             if(dStaInd[rguDlSpId])
1078             {
1079                dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].staIndTb[idx].nmbLch =
1080                   allocInfo->tbInfo[idx].numSchLch;
1081 #ifdef LTE_L2_MEAS
1082                dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].staIndTb[idx].tbId =
1083                   hqP->tbId[idx]; 
1084 #endif
1085             }
1086             lchBufSize=0;
1087          }
1088       }
1089       //if((dStaInd) && (tbIndex) && (isDStaReqrd == TRUE))
1090       if((dStaInd[rguDlSpId]) && (tbIndex))
1091       {
1092          idx1 = (hqP->procId << 2) | tbIndex;
1093          /* Create RguDStaInd struct and send to UIM */
1094          dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].rnti    = allocInfo->rnti;
1095          /*
1096             dStaInd->transId = (hqP->timingInfo.sfn << 16) | 
1097             (hqP->timingInfo.slot << 8) | hqP->procId;
1098           */
1099          dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].transId = (timingInfo.sfn << 16) | 
1100             (timingInfo.slot << 8) | idx1;
1101          dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].nmbOfTbs = hqP->numOfTBs;
1102 #ifdef LTE_ADV
1103          dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].fillCtrlPdu = allocInfo->fillCtrlPdu;
1104 #endif        
1105          /*increment num of UE as staInd is prepared for it */
1106          dStaInd[rguDlSpId]->nmbOfUeGrantPerTti++;
1107          /* ADD Changes for Downlink UE Timing Optimization */
1108 #ifdef LTEMAC_DLUE_TMGOPTMZ
1109          dlSf->remDatReqCnt++;
1110 #endif
1111       }
1112       //isDStaReqrd = FALSE;
1113       tbIndex = 0;
1114    }
1115
1116    for(idx = 0; idx < rgCb[inst].numRguSaps ; idx++)
1117    {
1118       if(dStaInd[idx] != NULLP)
1119       {
1120          dStaInd[idx]->cellId  = cell->cellId;
1121          /* Fix : syed Avoid return param for interface prim and
1122           * proceed for other UEs. For the failed UE, MAC shall
1123           * do padding. */
1124          rgUIMSndDedStaInd(inst,rguDlSap[idx],dStaInd[idx]);
1125
1126          staIndCnt++;
1127          if(staIndCnt == activeSapCnt)
1128             break;/* all valid staind are considered */
1129       }
1130
1131    }
1132    return ROK;
1133 }  /* rgDHMSndConsolidatedStaInd */
1134
1135
1136 /**
1137  * @brief Function to handle building the TFU Data Request
1138  *
1139  * @details
1140  *
1141  *     Function : rgDHMBldTfuDatReq
1142  *     
1143  *     This function builds the TFU Data Request with the details 
1144  *     present in HARQ Process.
1145  *           
1146  *  @param[in]  RgDlHqProcCb     *hqP 
1147  *  @param[out] TfuDatReqPduInfo  *datReq 
1148  *  @return     Void
1149  *              None 
1150  **/
1151 //uint8_t crashFlag = 0;
1152    static Void rgDHMBldTfuDatReq
1153 (
1154  RgCellCb           *cellCb,
1155  RgDlSf             *dlSf,
1156  RgDlHqProcCb       *hqP,
1157  RgTfuDatReqPduInfo *datReq
1158  )
1159 {
1160
1161 #ifndef L2_OPTMZ
1162 #if !(!(defined TENB_ACC) && !(defined LTE_PAL_ENB))
1163    Inst inst;
1164 #elif defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD)
1165    Inst inst;
1166 #endif
1167 #endif
1168
1169    uint8_t i;
1170
1171 #ifdef L2_OPTMZ
1172    uint32_t lchIdx, pduIdx;
1173 #endif
1174
1175    datReq->nmbOfTBs = 0;
1176 #ifndef L2_OPTMZ
1177 #if !(!(defined TENB_ACC) && !(defined LTE_PAL_ENB))
1178    inst = cellCb->macInst - RG_INST_START;
1179 #elif defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD)
1180    inst = cellCb->macInst - RG_INST_START;
1181 #endif
1182 #endif
1183    /*MS_WORKAROUND  for ccpu00123904*/
1184    datReq->isTApres = FALSE;
1185 #ifdef TFU_ALLOC_EVENT_NO_INIT
1186 #ifndef L2_OPTMZ   
1187    datReq->mBuf[0] = 0;
1188    datReq->mBuf[1] = 0;
1189 #endif    
1190 #endif
1191
1192    for(i=0;i<RG_MAX_TB_PER_UE;i++)
1193    {
1194 #ifndef L2_OPTMZ
1195       if ((hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf == dlSf) &&
1196             (hqP->tbInfo[i].tb != NULLP))
1197 #else
1198          if ((hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf == dlSf) &&
1199                RgUtlIsTbMuxed(&(hqP->tbInfo[i].tb)))
1200 #endif
1201          {
1202
1203             datReq->rnti           =  hqP->tbInfo[i].pdcch.rnti;
1204             datReq->dciInfo        =  hqP->tbInfo[i].pdcch.dci;
1205             datReq->doa            =  hqP->tbInfo[i].doa;
1206             datReq->transMode      =  hqP->tbInfo[i].txMode;
1207             datReq->puschRptUsd    =  hqP->tbInfo[i].puschRptUsd;
1208             datReq->puschPmiInfo   =  hqP->tbInfo[i].puschPmiInfo;
1209             /*MS_WORKAROUND  for ccpu00123904*/
1210             if (hqP->tbInfo[i].schdTa.pres)
1211             {
1212                datReq->isTApres       =  TRUE; 
1213             }
1214 #ifdef   TFU_UPGRADE
1215             /* update pA value */
1216             datReq->pa             =  hqP->tbInfo[i].pa;
1217 #endif
1218             /* LTE_ADV_FLAG_REMOVED_START */
1219             datReq->isEnbSFR       =  hqP->tbInfo[i].isEnbSFR;
1220             /* LTE_ADV_FLAG_REMOVED_END */
1221 #ifndef L2_OPTMZ
1222 #if (!(defined TENB_ACC) && !(defined LTE_PAL_ENB))  /* ABHI */ /* This is only temp fix. It needs to be removed
1223                                                                    after rebasing to MAC CCB */
1224 #ifdef BRDCM
1225             datReq->mBuf[i] = hqP->tbInfo[i].tb;
1226 #else
1227             /* Intel Tdd- Commenting out the Optimization for direct Access of 
1228              * mBuf Index */
1229             /*Proper clean-up needed as this needs long stability tests
1230              * in all SoCs*/
1231 #if defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD)
1232             SIncMsgRef(hqP->tbInfo[i].tb, RG_GET_MEM_REGION(rgCb[inst]),
1233                   RG_GET_MEM_POOL(rgCb[inst]), &datReq->mBuf[i]); 
1234 #else
1235             datReq->mBuf[i] = hqP->tbInfo[i].tb;
1236 #endif
1237 #endif/*BRDCM*/
1238 #else
1239             SIncMsgRef(hqP->tbInfo[i].tb, RG_GET_MEM_REGION(rgCb[inst]),
1240                   RG_GET_MEM_POOL(rgCb[inst]), &datReq->mBuf[i]);
1241 #endif
1242             {
1243                MsgLen   dbgBufLen;
1244                if(SFndLenMsg(datReq->mBuf[i], &dbgBufLen))
1245                {
1246                   if(dbgBufLen == 0)
1247                   {              
1248                      DU_LOG("\nERROR  -->  MAC : RNTI:%d SFN:%d slot:%d tbIdx:%d Sdu Length 0 ",
1249                            datReq->rnti,
1250                            hqP->tbInfo[i].timingInfo.sfn,
1251                            hqP->tbInfo[i].timingInfo.slot,i);
1252                      DU_LOG("\nERROR  -->  MAC : taPres [%d] numOfTbs [%d] format[%d]",
1253                            datReq->isTApres, 
1254                            hqP->numOfTBs, 
1255                            datReq->dciInfo.format);  
1256                   }              
1257                }  
1258             }
1259 #else
1260             /* L2 optimization for mUe/Tti: Removing SIncMsgRef to avoid additional
1261              * mBuf allocation. MAC header, MAC Ces, MAC PDU per LCH per TB Per UE
1262              * and MAC padding Mbufs are being sent to CL. Populating these Ptrs
1263              * From TB Info to TfuDatReq
1264              */
1265             datReq->tbInfo[i].tbPres =  TRUE;
1266             datReq->tbInfo[i].tbSize =  hqP->tbInfo[i].tbSz;
1267             datReq->tbInfo[i].macHdr =  hqP->tbInfo[i].tb.macHdr;
1268             datReq->tbInfo[i].macCes =  hqP->tbInfo[i].tb.macCes;
1269             datReq->tbInfo[i].numLch =  hqP->tbInfo[i].tb.numLch;
1270             for(lchIdx = 0; lchIdx < hqP->tbInfo[i].tb.numLch; lchIdx++)
1271             {
1272                datReq->tbInfo[i].lchInfo[lchIdx].numPdu = hqP->tbInfo[i].tb.\
1273                                                           lchInfo[lchIdx].numPdu;
1274                for(pduIdx = 0; pduIdx < hqP->tbInfo[i].tb.lchInfo[lchIdx].numPdu;\
1275                      pduIdx++)
1276                {
1277                   datReq->tbInfo[i].lchInfo[lchIdx].mBuf[pduIdx] =
1278                      hqP->tbInfo[i].tb.lchInfo[lchIdx].mBuf[pduIdx];
1279                }
1280             }
1281             // datReq->tbInfo[i].macPad  =  hqP->tbInfo[i].tb.macPad;
1282             datReq->tbInfo[i].padSize =  hqP->tbInfo[i].tb.padSize;
1283             // prc_trace_format_string(0x40,3,"TfuDatReq:RNTI=%d TbIdx=%d TbSize=%d PdSz=(%d) macHdraddr: (%p) macCEAddr: (%p) noLch=(%d)",datReq->rnti, i,
1284             //     hqP->tbInfo[i].tbSz, datReq->tbInfo[i].padSize, datReq->tbInfo[i].macHdr, datReq->tbInfo[i].macCes, datReq->tbInfo[i].numLch);
1285
1286 #endif
1287             datReq->nmbOfTBs++;
1288          }
1289    }
1290    return;
1291 }  /* rgDHMBldTfuDatReq */
1292
1293
1294 #ifdef L2_OPTMZ
1295 /**
1296  * @brief This function releases a HARQ process
1297  *
1298  * @details
1299  *
1300  *     Function: rgDHMFreeHqProcTB
1301  *     Purpose:  This function returns a HARQ process to HARQ Entity 
1302  *               in the DL direction.
1303  *     
1304  *               1. Add the HARQ process to the free queue.
1305  *     Invoked by: scheduler and HARQ processing
1306  *     
1307  *  @param[in]  RgDlHqProc    *hqP
1308  *  @return  Void      
1309  *
1310  **/
1311 S16 rgDHMFreeHqProcTB(RgDlHqProcCb *hqP, uint8_t tbIndex)
1312 {
1313    RgTfuDatReqTbInfo     *tb;   /* TB to be sent to CL/PHY*/
1314    uint8_t               idx;
1315
1316    if((tbIndex > RG_MAX_TB_PER_UE) ||
1317          (tbIndex == 0))
1318    {
1319       return RFAILED;
1320    }
1321
1322    tb = &(hqP->tbInfo[tbIndex-1].tb);
1323    RG_FREE_MSG(tb->macHdr);
1324    RG_FREE_MSG(tb->macCes);
1325
1326    for(idx = 0; idx < 2; idx++)
1327    {
1328       if (hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk.node != NULLP)
1329       {
1330          cmLListDelFrm(&hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sf->tbs,
1331                &(hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk));
1332          hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk.node  = (PTR)NULLP;
1333          DU_LOG("\nINFO  -->  MAC : rgDHMFreeHqProcTB:: hqP %p \n", (Void *)hqP);
1334       }
1335       hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sf = NULLP;
1336    }
1337    return ROK;
1338 }
1339 #endif
1340
1341
1342
1343 /**
1344  * @brief Handler for freeing up the harq related information from ueCb
1345  *
1346  * @details
1347  *
1348  *     Function : rgDHMFreeUe
1349  *     
1350  *     This function shall free up the HARQ specific information from ueCb.
1351  *           
1352  *  @param[in]  Inst        inst
1353  *  @param[in]  RgDlHqEnt     *hqE 
1354  *
1355  *  @return     None.
1356  *
1357  **/
1358 Void rgDHMFreeUe(Inst  inst, RgDlHqEnt *hqE)
1359 {
1360    uint8_t             i;
1361
1362    if(hqE->procs)
1363    {
1364       /* Free all the memory associated with HARQ */
1365       for (i=0; i < hqE->numHqProcs; i++)
1366       {
1367 #ifndef L2_OPTMZ
1368          rgDHMRlsHqProcTB(rgCb[inst].cell, hqE->procs[i], 1);
1369          rgDHMRlsHqProcTB(rgCb[inst].cell, hqE->procs[i], 2);
1370 #else
1371          rgDHMFreeHqProcTB(hqE->procs[i], 1);
1372          rgDHMFreeHqProcTB(hqE->procs[i], 2);
1373 #endif
1374
1375          rgFreeSBuf(inst,(Data **)&(hqE->procs[i]), sizeof(RgDlHqProcCb));
1376 #ifdef LTE_ADV
1377          rgDHMFreeSavedHqP(inst,hqE,i);
1378 #endif
1379       }
1380
1381       /*ccpu00117052 - MOD - Passing double pointer for proper NULLP
1382         assignment */
1383    }
1384
1385    return;
1386
1387 }  /* rgDHMFreeUe */
1388 /**
1389  * @brief Function for handling RaResp request received from scheduler to MAC
1390  *
1391  * @details
1392  *
1393  *     Function : RgSchMacRstHqEntReq
1394  *     
1395  *     This function shall be invoked whenever a sec cell of an ue
1396  *     is deactivated. MAC needs to reset the harqentity associated 
1397  *     with the deactivated scell of the ue
1398  *     
1399  *           
1400  *  @param[in] Pst             *pst
1401  *  @param[in] RgInfResetHqEnt *hqEntInfo
1402  *  @return  S16
1403  *      -# ROK 
1404  **/
1405 S16 RgSchMacRstHqEntReq(Pst* pst, RgInfResetHqEnt* hqEntInfo)
1406 {
1407    Inst      inst;
1408    RgCellCb  *cell;
1409    RgUeCb    *ue;
1410
1411    inst = pst->dstInst - RG_INST_START;
1412
1413    if (((cell = rgCb[inst].cell) == NULLP) ||
1414          (rgCb[inst].cell->cellId != hqEntInfo->cellId))
1415    {
1416       DU_LOG("\nERROR  -->  MAC : For user [%d]Cell does not exist %d\n",
1417             hqEntInfo->crnti,hqEntInfo->cellId);
1418       return RFAILED;
1419    }
1420
1421    if ((ue = rgDBMGetUeCb(cell, hqEntInfo->crnti)) == NULLP)
1422    {
1423       DU_LOG("\nERROR  -->  MAC : [%d]UE does not exist for this hqEntInfo\n",
1424             hqEntInfo->crnti);
1425       return RFAILED;
1426    }
1427
1428    rgDHMUeReset(cell, &ue->dl.hqEnt);
1429
1430    return ROK;
1431 }
1432 uint32_t gSaveVal;
1433 \f
1434 /**
1435  * @brief Function for handling RaResp request received from scheduler to MAC
1436  *
1437  * @details
1438  *
1439  *     Function : RgSchMacRlsHqReq
1440  *     
1441  *     This function shall be invoked whenever scheduler is done with the
1442  *     allocations of random access responses for a slot.
1443  *     This shall invoke RAM to create ueCbs for all the rapIds allocated and 
1444  *     shall invoke MUX to create RAR PDUs for raRntis allocated.
1445  *     
1446  *           
1447  *  @param[in] CmLteCellId         cellId,
1448  *  @param[in] CmLteTimingInfo     timingInfo,
1449  *  @param[in] RaRespInfo          *rarInfo
1450  *  @return  S16
1451  *      -# ROK 
1452  **/
1453 S16 RgSchMacRlsHqReq(Pst *pst, RgInfRlsHqInfo *rlshqUeInfo)
1454 {
1455    Inst           inst;
1456    RgCellCb       *cell = NULLP;
1457    RgUeCb         *ue;
1458    RgDlHqProcCb   *hqP;
1459    uint8_t        idx1,idx2;
1460 #ifdef LTE_L2_MEAS
1461    uint8_t           tbId;
1462    RguHarqStatusInd  hqStaInd;
1463    Bool              isValidTbId = FALSE;
1464 #endif
1465    uint32_t        startTime=0;
1466
1467    RG_IS_INST_VALID(pst->dstInst);
1468    inst = pst->dstInst - RG_INST_START;
1469    cell  = rgCb[inst].cell;
1470    /*starting Task*/
1471    SStartTask(&startTime, PID_MAC_AM_HARQ_RLS);
1472
1473    if(NULLP == rlshqUeInfo)
1474    {
1475       return RFAILED;
1476    }
1477
1478    if((cell  == NULLP)
1479          ||( cell->cellId != rlshqUeInfo->cellId))
1480    {
1481
1482       DU_LOG("\nERROR  -->  MAC : No cellCb found with cellId");
1483       return RFAILED;
1484    }
1485
1486    if(NULLP == rlshqUeInfo->ueHqInfo)
1487    {
1488       return RFAILED;
1489    }
1490
1491    for(idx1 = 0; idx1 < rlshqUeInfo->numUes; idx1++)
1492    {
1493       if((ue=rgDBMGetUeCb (cell, rlshqUeInfo->ueHqInfo[idx1].rnti)) == NULLP)
1494       {
1495          /* Check in RachLst */
1496          if((ue=rgDBMGetUeCbFromRachLst (cell, 
1497                      rlshqUeInfo->ueHqInfo[idx1].rnti)) == NULLP)
1498          {
1499             DU_LOG("\nERROR  -->  MAC : CRNTI:%d No ueCb found",
1500                   rlshqUeInfo->ueHqInfo[idx1].rnti);
1501             continue;
1502          }
1503       }
1504 #ifdef LTE_ADV
1505 #ifdef LAA_DBG
1506       if ((rlshqUeInfo->ueHqInfo[idx1].rlsOperationType && !gSaveVal) || (rlshqUeInfo->ueHqInfo[idx1].hqProcId > 8))
1507       {
1508          int *p = NULL;
1509          DU_LOG("\nINFO  -->  MAC :  SPURIOUS CALLL !!!! procId %d \n", rlshqUeInfo->ueHqInfo[idx1].hqProcId);
1510
1511
1512          DU_LOG("\nINFO  -->  MAC : RgSchMacRlsHqReq cell %d : numUes %d idx %d rnti %d hqProc %d numTbsi\
1513                %d tbid[0] %d tbid[1] %d rlsopr %d \n",
1514                cell->cellId,
1515                rlshqUeInfo->numUes,
1516                idx1,
1517                rlshqUeInfo->ueHqInfo[idx1].rnti,
1518                rlshqUeInfo->ueHqInfo[idx1].hqProcId,
1519                rlshqUeInfo->ueHqInfo[idx1].numOfTBs,
1520                rlshqUeInfo->ueHqInfo[idx1].tbId[0],
1521                rlshqUeInfo->ueHqInfo[idx1].tbId[1],
1522                rlshqUeInfo->ueHqInfo[idx1].rlsOperationType);
1523
1524          *p = 10; 
1525       }
1526 #endif
1527       gSaveVal = 0;
1528
1529
1530       RgSchMacHndlRelReq(cell, ue, &rlshqUeInfo->ueHqInfo[idx1]);
1531
1532       if (RGINF_RLS_HQ_DEL_TB == rlshqUeInfo->ueHqInfo[idx1].rlsOperationType)
1533       {
1534          /* If REQ is to DEL the saved TBs no need to free the HqP as it's already
1535             freed up earlier */
1536          continue;
1537       }
1538 #endif /* LTE_ADV */
1539       rgDHMGetHqProcFrmId(ue,rlshqUeInfo->ueHqInfo[idx1].hqProcId,&hqP);
1540       if(rlshqUeInfo->ueHqInfo[idx1].status[0] != TRUE)
1541       {
1542          rgCb[inst].genSts.numHarqFail++;
1543       }
1544
1545 #ifdef LTE_L2_MEAS
1546       hqStaInd.cellId = cell->cellId;
1547       hqStaInd.ueId = rlshqUeInfo->ueHqInfo[idx1].rnti;
1548       hqStaInd.numTbs = rlshqUeInfo->ueHqInfo[idx1].numOfTBs;
1549 #endif
1550
1551       for(idx2=0; idx2 < rlshqUeInfo->ueHqInfo[idx1].numOfTBs; idx2++)
1552       {
1553 #ifdef LTE_L2_MEAS
1554          /* Fill the hq sta Ind stucture. Need to send the Status Ind for only
1555             those TBID's reported by Scheduler*/
1556          tbId = rlshqUeInfo->ueHqInfo[idx1].tbId[idx2];
1557          if (hqP->tbId[tbId-1] != RGU_INVALID_TBID)
1558          {
1559             /* Fill the correct Sn Map corresponding to the TBID */
1560             hqStaInd.tbId[idx2] = hqP->tbId[tbId-1];
1561             hqStaInd.status[idx2] = rlshqUeInfo->ueHqInfo[idx1].status[idx2];
1562             isValidTbId = TRUE;
1563          }
1564 #endif
1565          if(rgDHMRlsHqProcTB(cell, hqP, 
1566                   rlshqUeInfo->ueHqInfo[idx1].tbId[idx2]) != ROK)
1567          {
1568             DU_LOG("\nERROR  -->  MAC : CRNTI:%d Failure in releasing hq TB",
1569                   rlshqUeInfo->ueHqInfo[idx1].rnti);
1570             continue;
1571          }
1572       }
1573
1574 #ifdef LTE_L2_MEAS
1575
1576       if (isValidTbId)
1577       {
1578          if(ue->rguDlSap)
1579          {
1580             RgUiRguHqStaInd(&(ue->rguDlSap->sapCfg.sapPst),
1581                   ue->rguDlSap->sapCfg.suId,
1582                   &hqStaInd);
1583          }
1584          else
1585          {/* Ue is from rach list*/
1586             RgUiRguHqStaInd(&(cell->rguDlSap->sapCfg.sapPst),
1587                   cell->rguDlSap->sapCfg.suId,
1588                   &hqStaInd);
1589          }
1590       }
1591 #endif
1592    } /* end of ues loop */
1593
1594    /*starting Task*/
1595    SStopTask(startTime,PID_MAC_AM_HARQ_RLS);
1596
1597    return ROK;
1598 } /* end of RgSchMacRlsHqReq */
1599
1600
1601 /**********************************************************************
1602
1603   End of file
1604  **********************************************************************/