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