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