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