Moving all common header file into common_def.h file
[o-du/l2.git] / src / 5gnrsch / rg_sch_uhm.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_sch_uhm.c
28   
29 **********************************************************************/
30
31 /** @file rg_sch_uhm.c
32 @brief This module handles uplink harq related functionality in MAC.
33 */
34
35 /* header include files -- defines (.h) */
36 #include "common_def.h"
37 #include "rg_env.h"        /* MAC Environment Defines */
38 #include "tfu.h"           /* TFU Interface defines */
39 #include "rgr.h"           /* RGR Interface defines */
40 #include "lrg.h"           /* LRG Interface defines */
41
42 #include "rg_sch.h"            /* Scheduler defines */
43 #include "rg_sch_inf.h"            /* Scheduler defines */
44 #include "rg_sch_err.h"        /* MAC error defines */
45
46 /* header/extern include files (.x) */
47
48 #include "tfu.x"           /* TFU Interface defines */
49 #include "rgr.x"           /* RGR Interface includes */
50 #include "lrg.x"           /* LRG Interface includes */
51 #include "rgm.x"
52 #include "rg_sch_inf.x"            /* Scheduler defines */
53 #include "rg_sch.x"            /* Scheduler includes */
54 #include "rg_sch_cmn.h"
55 #include "rg_sch_cmn.x"
56
57 /* local defines */
58
59 /* local typedefs */
60  
61 /* local externs */
62  
63 /* forward references */
64
65 #ifdef EMTC_ENABLE
66    U32 gUlRetxPassCntr = 0;
67    /*EXTERN U32 gUlRetxFailCntr;
68    EXTERN U32 gUlCrcPassCounter;
69    EXTERN U32 gUlCrcFailCounter;*/
70 #endif
71 PUBLIC U8 rgRvIdxTable[] = {0, 3, 1, 2}; /* This gives rvIdx for a given rv */
72 PUBLIC U8 rgRvTable[] = {0, 2, 3 ,1};    /* This gives rv for a given rvIdx */
73
74 #ifdef EMTC_ENABLE
75 PUBLIC Void rgSCHCmnEmtcHdlHarqProcFail
76 (
77 RgSchCellCb       *cell,
78 RgSchUeCb         *ue,
79 RgSchUlHqProcCb   *hqProc,
80 CmLteTimingInfo   frm
81 );
82 PUBLIC Void rgSCHEmtcInitUlUeHqEnt
83 (
84 RgSchCellCb      *cell,
85 RgrUeCfg         *ueCfg,
86 RgSchUeCb        *ueCb
87 );
88
89 #endif
90
91 /**
92  * @brief Handler for HARQ processing on recieving Data indication from PHY.
93  *
94  * @details
95  *
96  *     Function: rgSCHUhmProcDatInd
97  *     
98  *     Invoked by: rgSCHTomTfuDatInd of  TOM
99  *
100  *     Processing Steps:
101  *      - Set rcvdCrcInd variable to TRUE
102  *           
103  *  @param[in] *cell
104  *  @param[in] *ue
105  *  @param[in] frm
106  *  @return  Void
107  **/
108 #ifndef MAC_SCH_STATS
109 #ifdef ANSI
110 PUBLIC Void rgSCHUhmProcDatInd
111 (
112 RgSchCellCb          *cell,
113 RgSchUeCb            *ue,
114 CmLteTimingInfo      frm
115 )
116 #else
117 PUBLIC Void rgSCHUhmProcDatInd(cell, ue, frm)
118 RgSchCellCb          *cell;
119 RgSchUeCb            *ue;
120 CmLteTimingInfo      frm;
121 #endif
122 #else  /* MAC_SCH_STATS */
123 #ifdef ANSI
124 PUBLIC Void rgSCHUhmProcDatInd
125 (
126 RgSchCellCb          *cell,
127 RgSchUeCb            *ue,
128 CmLteTimingInfo      frm,
129 U8                   cqi
130 )
131 #else
132 PUBLIC Void rgSCHUhmProcDatInd(cell, ue, frm, cqi)
133 RgSchCellCb          *cell;
134 RgSchUeCb            *ue;
135 CmLteTimingInfo      frm;
136 U8                   cqi;
137 #endif
138 #endif /* MAC_SCH_STATS */
139 {
140    RgSchUlHqProcCb   *hqProc;
141 #ifdef UL_LA
142    RgSchCmnUlUe   *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
143    S32            iTbs;
144    U8             maxiTbs = rgSchCmnUlCqiToTbsTbl[cell->isCpUlExtend]
145                                                  [ueUl->maxUlCqi];
146 #endif
147
148    TRC2(rgSCHUhmProcDatInd);
149
150    rgSCHUtlUlHqProcForUe(cell, frm, ue, &hqProc);
151    if (hqProc == NULLP)
152    {
153       printf("UE[%d] failed to find UL HqProc for [%d:%d]\n",
154                       ue->ueId, frm.sfn, frm.slot);
155       RETVOID;
156    }
157    hqProc->rcvdCrcInd = TRUE;
158
159 #ifdef UL_LA
160    {
161       ueUl->ulLaCb.deltaiTbs += UL_LA_STEPUP;
162       iTbs = (ueUl->ulLaCb.cqiBasediTbs + ueUl->ulLaCb.deltaiTbs)/100;
163
164       if (iTbs > maxiTbs)
165       {
166          ueUl->ulLaCb.deltaiTbs = (maxiTbs * 100) - ueUl->ulLaCb.cqiBasediTbs;
167       }
168
169    }
170 #endif
171 #ifdef MAC_SCH_STATS
172    /** Stats update over here 
173     */
174    {
175       hqFailStats.ulCqiStat[cqi - 1].numOfAcks++;
176    }
177 #endif
178
179 #ifdef TENB_STATS
180    /* UL stats are filled in primary index as of now */
181    cell->tenbStats->sch.ulAckNack[rgRvTable[hqProc->rvIdx]]++;
182    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].ulAckNackCnt++;
183    if(hqProc->alloc)
184    {
185       ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].ulTpt += (hqProc->alloc->grnt.datSz << 3);
186       cell->tenbStats->sch.ulTtlTpt +=(hqProc->alloc->grnt.datSz << 3);//pverma
187    }
188 #endif
189    
190    RETVOID;
191 }  /* rgSCHUhmProcDatInd */
192
193 /**
194  * @brief Handler for HARQ processing on recieving Data indication from PHY.
195  *
196  * @details
197  *
198  *     Function: rgSCHUhmProcMsg3DatInd
199  *     
200  *     Invoked by: rgSCHTomTfuDatInd of  TOM
201  *
202  *     Processing Steps:
203  *      - Set rcvdCrcInd variable to TRUE  
204  *           
205  *  @param[in,out] *hqProc
206  *  @return  Void
207  **/
208 #ifdef ANSI
209 PUBLIC Void rgSCHUhmProcMsg3DatInd
210 (
211 RgSchUlHqProcCb *hqProc
212 )
213 #else
214 PUBLIC Void rgSCHUhmProcMsg3DatInd(hqProc)
215 RgSchUlHqProcCb *hqProc;
216 #endif
217 {
218    TRC2(rgSCHUhmProcMsg3DatInd);
219    hqProc->rcvdCrcInd = TRUE;
220    hqProc->remTx = 0;        /*Reseting the value of rem Tx*/
221    printf("\nrgSCHUhmProcMsg3DatInd,id:%u\n",hqProc->procId);
222    RETVOID;
223 }  /* rgSCHUhmProcMsg3DatInd */
224
225 /**
226  * @brief Handler for HARQ processing on recieving Data indication from PHY.
227  *
228  * @details
229  *
230  *     Function: rgSCHUhmProcMsg3Failure
231  *     
232  *     Invoked by: rgSCHTomTfuDatInd of  TOM
233  *
234  *     Processing Steps:
235  *      - Set rcvdCrcInd variable to TRUE  
236  *           
237  *  @param[in,out] *hqProc
238  *  @return  Void
239  **/
240 #ifdef ANSI
241 PUBLIC Void rgSCHUhmProcMsg3Failure
242 (
243 RgSchUlHqProcCb *hqProc
244 )
245 #else
246 PUBLIC Void rgSCHUhmProcMsg3Failure(hqProc)
247 RgSchUlHqProcCb *hqProc;
248 #endif
249 {
250    TRC2(rgSCHUhmProcMsg3Failure);
251 #ifdef EMTC_ENABLE
252    RG_SCH_EMTC_IS_CRCIND_RCVD_CHK_RACB(hqProc);
253 #endif  
254    if(hqProc->rcvdCrcInd != TRUE) 
255    {
256       hqProc->rcvdCrcInd = FALSE;
257    }
258
259    RETVOID;
260 }  /* rgSCHUhmProcMsg3Failure */
261
262 /**
263  * @brief Handler for HARQ processing on recieving Decode failure from PHY.
264  *
265  * @details
266  *
267  *     Function: rgSCHUhmProcHqFailure
268  *     
269  *     Invoked by: rgSCHTomTfuDecFailInd of TOM
270  *
271  *     Processing Steps: 
272  *      - Update NACK information in harq info.
273  *      - Update RV index of received RV from PHY in harq info.
274  *      - Set PhichInfo in DlSf
275  *           
276  *  @param[in] *cell
277  *  @param[in] *ue
278  *  @param[in] frm
279  *  @param[in] rv
280  *  @return  Void
281  **/
282 #ifndef MAC_SCH_STATS
283 #ifdef ANSI
284 PUBLIC Void rgSCHUhmProcHqFailure
285 (
286 RgSchCellCb          *cell,
287 RgSchUeCb            *ue,
288 CmLteTimingInfo      frm,
289 TknU8                rv
290 )
291 #else
292 PUBLIC Void rgSCHUhmProcHqFailure(cell, ue, frm, rv)
293 RgSchCellCb          *cell;
294 RgSchUeCb            *ue;
295 CmLteTimingInfo      frm;
296 TknU8                rv;
297 #endif
298 #else /* MAC_SCH_STATS */
299 #ifdef ANSI
300 PUBLIC Void rgSCHUhmProcHqFailure
301 (
302 RgSchCellCb          *cell,
303 RgSchUeCb            *ue,
304 CmLteTimingInfo      frm,
305 TknU8                rv,
306 U8                   cqi
307 )
308 #else
309 PUBLIC Void rgSCHUhmProcHqFailure(cell, ue, frm, rv, cqi)
310 RgSchCellCb          *cell;
311 RgSchUeCb            *ue;
312 CmLteTimingInfo      frm;
313 TknU8                rv;
314 U8                   cqi;
315 #endif
316 #endif /* MAC_SCH_STATS */
317 {
318    RgSchUlHqProcCb   *hqProc;
319 #ifdef UL_LA
320    RgSchCmnUlUe   *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
321    S32               iTbs;
322 #endif
323    TRC2(rgSCHUhmProcHqFailure);
324
325    rgSCHUtlUlHqProcForUe(cell, frm, ue, &hqProc);
326    if (hqProc == NULLP)
327    {
328       printf("UE[%d] failed to find UL HqProc for [%d:%d]\n",
329                       ue->ueId, frm.sfn, frm.slot);
330       RETVOID;
331    }
332 #ifdef UL_LA
333    {
334       ueUl->ulLaCb.deltaiTbs -= UL_LA_STEPDOWN;
335       iTbs = (ueUl->ulLaCb.cqiBasediTbs + ueUl->ulLaCb.deltaiTbs)/100;
336
337       if (iTbs < 0)
338       {
339          ueUl->ulLaCb.deltaiTbs = -(ueUl->ulLaCb.cqiBasediTbs);
340       }
341
342    } 
343 #endif
344 #ifdef MAC_SCH_STATS
345    /** Stats update over here */
346    {
347       static U32 retxCnt = 0;
348       ++retxCnt;
349       hqFailStats.ulCqiStat[cqi - 1].numOfNacks++;
350    }
351 #endif /* MAC_SCH_STATS */
352    if(hqProc->rcvdCrcInd != TRUE) 
353    {
354       hqProc->rcvdCrcInd = FALSE;
355    }
356 #ifdef TENB_STATS
357    /* UL stats are filled in primary index as of now */
358    cell->tenbStats->sch.ulAckNack[rgRvTable[hqProc->rvIdx]]++;
359    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].ulAckNackCnt++;
360    cell->tenbStats->sch.ulNack[rgRvTable[hqProc->rvIdx]]++;
361    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].ulNackCnt++;
362 #endif
363    hqProc->rvIdxPhy.pres = rv.pres;
364    if(rv.pres)
365    {
366       hqProc->rvIdxPhy.val = rgRvIdxTable[rv.val];
367    }
368    RETVOID;
369 } /* rgSCHUhmProcHqFailure */
370
371 /**
372  * @brief Handler for identifying the HARQ process cb associated with the
373  * index.
374  *
375  * @details
376  *
377  *     Function: rgSCHUhmGetUlHqProc
378  *     
379  *     Processing Steps: 
380  *      - Return pointer to uplink harq process corresponding to the timing
381  *        information passed.
382  *           
383  *  @param[in]  *ue
384  *  @param[in]  idx
385  *  @return  RgSchUlHqProcCb*
386  *      -# Pointer to harq process corresponding to index
387  *      -# NULL
388  **/
389 #ifdef ANSI
390 PUBLIC RgSchUlHqProcCb* rgSCHUhmGetUlHqProc
391 (
392 RgSchCellCb      *cell,
393 RgSchUeCb        *ue, 
394 U8               idx
395 )
396 #else
397 PUBLIC RgSchUlHqProcCb* rgSCHUhmGetUlHqProc(cell, ue, idx)
398 RgSchCellCb      *cell;
399 RgSchUeCb        *ue; 
400 U8               idx;
401 #endif
402 {
403    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
404    TRC2(rgSCHUhmGetUlHqProc);
405
406 #if (ERRCLASS & ERRCLS_DEBUG)
407    if(idx >= ueUl->hqEnt.numHqPrcs)
408    {
409       RETVALUE(NULLP);
410    }
411 #endif
412    RETVALUE(&(ueUl->hqEnt.hqProcCb[idx]));
413 }  /* rgSCHUhmGetUlHqProc */
414
415 /**
416  * @brief Handler for HARQ processing on recieving new trasmission indication 
417  * from USM.
418  *
419  * @details
420  *
421  *     Function: rgSCHUhmNewTx
422  *     
423  *     Invoked by: USM
424  *
425  *     Processing Steps: 
426  *      - Update harq info with values indicating new HARQ transmission.
427  *           
428  *  @param[in,out]  *hqProc
429  *  @param[in]      *alloc
430  *  @return  Void
431  **/
432 #ifdef ANSI
433 PUBLIC Void rgSCHUhmNewTx
434 (
435 RgSchUlHqProcCb *hqProc,
436 U8              maxHqRetx,
437 RgSchUlAlloc    *alloc
438 )
439 #else
440 PUBLIC Void rgSCHUhmNewTx(hqProc, maxHqRetx, alloc)
441 RgSchUlHqProcCb *hqProc;
442 U8              maxHqRetx;
443 RgSchUlAlloc    *alloc;
444 #endif
445 {
446    TRC2(rgSCHUhmNewTx);
447
448    hqProc->ndi ^= 1;
449    hqProc->alloc = alloc;
450    hqProc->remTx = maxHqRetx;
451    hqProc->rcvdCrcInd = FALSE;
452    hqProc->rvIdx = 0;
453    hqProc->rvIdxPhy.pres = FALSE;
454 #ifdef LTE_L2_MEAS
455    if (hqProc->alloc->ue)
456    {
457       ((RgUeUlHqCb*)hqProc->hqEnt)->numBusyHqProcs++;
458    }
459 #endif
460    RETVOID;
461 }  /* rgSCHUhmNewTx */
462
463 /**
464  * @brief Free an uplink HARQ process.
465  *
466  * @details
467  *
468  *     Function: rgSCHUhmFreeProc
469  *     
470  *     Invoked by: USM
471  *
472  *     Processing Steps: 
473  *      - Set alloc pointer to NULLP
474  *           
475  *  @param[in]  RgSchUlHqProcCb   *hqProc
476  *  @param[in]  RgSchCellCb      *cell
477  *  @return  Void
478  **/
479 #ifdef ANSI
480 PUBLIC Void rgSCHUhmFreeProc
481 (
482 RgSchUlHqProcCb *hqProc,
483 RgSchCellCb      *cell
484 )
485 #else
486 PUBLIC Void rgSCHUhmFreeProc(hqProc, cell)
487 RgSchUlHqProcCb *hqProc;
488 RgSchCellCb      *cell;
489 #endif
490 {
491 #ifdef LTE_L2_MEAS
492    RgSchUeCb         *ueCb;
493    U8 qci = 1;
494 #endif
495    TRC2(rgSCHUhmFreeProc);
496
497 #ifdef LTE_L2_MEAS
498    if (hqProc->alloc && hqProc->alloc->ue)
499    {
500       ueCb = hqProc->alloc->ue;
501       if (ueCb && cell)
502       {
503          U32 nonLcg0ReportedBs = ((RgSchCmnLcg *)(ueCb->ul.lcgArr[1].sch))->reportedBs + \
504                                ((RgSchCmnLcg *)(ueCb->ul.lcgArr[2].sch))->reportedBs + \
505                                ((RgSchCmnLcg *)(ueCb->ul.lcgArr[3].sch))->reportedBs;
506          ((RgUeUlHqCb*)hqProc->hqEnt)->numBusyHqProcs--;
507          if (! ((RgUeUlHqCb*)hqProc->hqEnt)->numBusyHqProcs && !(nonLcg0ReportedBs))
508          {
509             while (ueCb->ulActiveLCs)
510             {
511                if (ueCb->ulActiveLCs & 0x1)
512                {
513                   cell->qciArray[qci].ulUeCount--;
514                }
515                qci++;
516                ueCb->ulActiveLCs >>= 1;
517             }
518          }
519       }
520    }
521 #endif
522
523
524  if(hqProc && (RgUeUlHqCb*)hqProc->hqEnt)
525  {
526
527 #ifdef UL_ADPT_DBG 
528     printf("\n\n########HARQ FREED HARQPROC ID (%d )after rgSCHUhmFreeProc inuse %ld free %ld \n",hqProc->alloc->grnt.hqProcId, (CmLListCp *)(&((RgUeUlHqCb*)hqProc->hqEnt)->inUse)->count,(CmLListCp *) (&((RgUeUlHqCb*)hqProc->hqEnt)->free)->count);
529 #endif
530    hqProc->alloc = NULLP;
531    hqProc->ulSfIdx = RGSCH_INVALID_INFO;
532    /*ccpu00116293 - Correcting relation between UL slot and DL slot based on RG_UL_DELTA*/
533    hqProc->isRetx  = FALSE;
534    hqProc->remTx = 0; /*Reseting the remTx value to 0*/
535 #ifdef EMTC_ENABLE
536    RG_SCH_EMTC_SET_ISDTX_TO_FALSE(hqProc);
537 #endif
538    cmLListDelFrm(&((RgUeUlHqCb*)hqProc->hqEnt)->inUse,&hqProc->lnk);
539    cmLListAdd2Tail(&((RgUeUlHqCb*)hqProc->hqEnt)->free, &hqProc->lnk);
540
541    /*
542    printf("after rgSCHUhmFreeProc inuse %ld free %ld \n", 
543         (CmLListCp *)(&((RgUeUlHqCb*)hqProc->hqEnt)->inUse)->count,
544          (CmLListCp *) (&((RgUeUlHqCb*)hqProc->hqEnt)->free)->count);
545    */
546  }
547  else
548  {
549      printf("\nhqEnt is NULL\n");
550  }
551    RETVOID;
552 }  /* rgSCHUhmFreeProc */
553
554 /**
555  * @brief Handler for HARQ processing on recieving re-trasmission 
556  * indication from USM.
557  *
558  * @details
559  *
560  *     Function: rgSCHUhmRetx
561  *     
562  *     Invoked by: USM
563  *
564  *     Processing Steps: 
565  *      - Update harq info with values corresponding to
566  *        re-transmission. 
567  *           
568  *  @param[in,out]  *hqProc
569  *  @return  Void
570  **/
571 #ifdef ANSI
572 PUBLIC Void rgSCHUhmRetx
573 (
574 RgSchUlHqProcCb *hqProc,
575 RgSchUlAlloc    *alloc
576 )
577 #else
578 PUBLIC Void rgSCHUhmRetx(hqProc, alloc) 
579 RgSchUlHqProcCb *hqProc;
580 RgSchUlAlloc    *alloc;
581 #endif
582 {
583    TRC2(rgSCHUhmRetx);
584
585    hqProc->alloc = alloc;
586    --hqProc->remTx;
587    hqProc->rvIdx = (hqProc->rvIdx + 1) % 4;
588    hqProc->rvIdxPhy.pres = FALSE;
589    RETVOID;
590 }  /* rgSCHUhmRetx */
591
592
593 /**
594  * @brief Handler for initializing the HARQ entity.
595  *
596  * @details
597  *
598  *     Function: rgSCHUhmRgrUeCfg
599  *     
600  *     Invoked by: RGR
601  *
602  *     Processing Steps: 
603  *      -  Initialize maxHqRetx
604  *           
605  *  @param[in]      *cellCb
606  *  @param[in,out]  *ueCb
607  *  @param[in]      *ueCfg
608  *  @param[out]     *err
609  *  @return  Void
610  **/
611 #ifdef ANSI
612 PUBLIC Void rgSCHUhmRgrUeCfg
613 (
614 RgSchCellCb       *cellCb,
615 RgSchUeCb         *ueCb,
616 RgrUeCfg          *ueCfg
617 )
618 #else
619 PUBLIC Void rgSCHUhmRgrUeCfg(cellCb, ueCb, ueCfg) 
620 RgSchCellCb       *cellCb;
621 RgSchUeCb         *ueCb;
622 RgrUeCfg          *ueCfg;
623 #endif
624 {
625    U8 i;
626    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ueCb, cellCb);
627    
628    TRC2(rgSCHUhmRgrUeCfg);
629
630    ueUl->hqEnt.maxHqRetx = ((ueCfg->ueUlHqCfg.maxUlHqTx) - 1);
631 #ifdef TFU_UPGRADE
632    /* Storing the delta HARQ offset for HARQ + PUSCH */
633    ueCb->ul.betaHqOffst = ueCfg->puschDedCfg.bACKIdx;
634 #endif
635    cmLListInit(&ueUl->hqEnt.free);
636    cmLListInit(&ueUl->hqEnt.inUse);
637    for(i=0; i < ueUl->hqEnt.numHqPrcs; i++)
638    {
639       ueUl->hqEnt.hqProcCb[i].hqEnt = (void*)(&ueUl->hqEnt);
640       ueUl->hqEnt.hqProcCb[i].procId = i;
641       ueUl->hqEnt.hqProcCb[i].remTx = 0;
642       ueUl->hqEnt.hqProcCb[i].ulSfIdx = RGSCH_INVALID_INFO;
643       ueUl->hqEnt.hqProcCb[i].alloc = NULLP;
644 #ifdef LTEMAC_SPS
645       /* ccpu00139513- Initializing SPS flags*/
646       ueUl->hqEnt.hqProcCb[i].isSpsActvnHqP = FALSE;
647       ueUl->hqEnt.hqProcCb[i].isSpsOccnHqP = FALSE;
648 #endif
649       cmLListAdd2Tail(&ueUl->hqEnt.free, &ueUl->hqEnt.hqProcCb[i].lnk);
650       ueUl->hqEnt.hqProcCb[i].lnk.node = (PTR)&ueUl->hqEnt.hqProcCb[i];
651    }
652
653 #ifdef EMTC_ENABLE
654    rgSCHEmtcInitUlUeHqEnt(cellCb, ueCfg, ueCb);
655 #endif
656    RETVOID;
657 }  /* rgSCHUhmRgrUeCfg */
658
659 /**
660  * @brief Handler for re-initializing the HARQ entity.
661  *
662  * @details
663  *
664  *     Function: rgSCHUhmRgrUeRecfg
665  *     
666  *     Invoked by: RGR
667  *
668  *     Processing Steps: 
669  *      -  Re-initialize maxHqRetx
670  *           
671  *  @param[in]      *cellCb
672  *  @param[in,out]  *ueCb
673  *  @param[in]      *ueCfg
674  *  @param[out]     *err
675  *  @return  Void
676  **/
677 #ifdef ANSI
678 PUBLIC Void rgSCHUhmRgrUeRecfg
679 (
680 RgSchCellCb       *cellCb,
681 RgSchUeCb         *ueCb,
682 RgrUeRecfg        *ueRecfg
683 )
684 #else
685 PUBLIC Void rgSCHUhmRgrUeRecfg(cellCb, ueCb, ueRecfg) 
686 RgSchCellCb       *cellCb;
687 RgSchUeCb         *ueCb;
688 RgrUeRecfg        *ueRecfg;
689 #endif
690 {
691    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ueCb, cellCb);
692    TRC2(rgSCHUhmRgrUeRecfg);
693
694    /* [ccpu00123958]-ADD- Check for HARQ Reconfig from the bit mask  */
695    if(RGR_UE_ULHARQ_RECFG & ueRecfg->ueRecfgTypes)
696    {
697       ueUl->hqEnt.maxHqRetx = (ueRecfg->ueUlHqRecfg.maxUlHqTx - 1); 
698    }
699
700    RETVOID;
701 }  /* rgSCHUhmRgrUeRecfg */
702
703 /**
704  * @brief Handler for de-initializing the HARQ entity.
705  *
706  * @details
707  *
708  *     Function: rgSCHUhmFreeUe
709  *     
710  *     Invoked by: RGR
711  *
712  *     Processing Steps: 
713  *      - 
714  *           
715  *  @param[in,out]  *ueCb
716  *  @return  Void
717  **/
718 #ifdef ANSI
719 PUBLIC Void rgSCHUhmFreeUe
720 (
721 RgSchCellCb       *cellCb,
722 RgUeUlHqCb        *hqEnt
723 )
724 #else
725 PUBLIC Void rgSCHUhmFreeUe(cellCb, hqEnt) 
726 RgSchCellCb       *cellCb;
727 RgUeUlHqCb       *hqEnt;
728 #endif
729 {
730    TRC2(rgSCHUhmFreeUe);
731 #ifdef LTE_TDD
732    /* ccpu00117052 - MOD - Passing double pointer
733    for proper NULLP assignment*/
734    rgSCHUtlFreeSBuf(cellCb->instIdx, 
735                   (Data **)(&(hqEnt->hqProcCb)),
736                   hqEnt->numHqPrcs * sizeof(RgSchUlHqProcCb));
737 #endif
738
739    RETVOID;
740 }  /* rgSCHUhmFreeUe */
741
742
743 /**
744 * @brief Handler for appending the PHICH information in to the dlSf.
745 *
746 * @details
747 *
748 *     Function: rgSCHUhmAppendPhich
749 *     
750 *     Invoked by: TOM
751 *
752 *     Processing Steps:
753 *      - Set PhichInfo in DlSf for each Hq
754 *
755 *  @param[in] *RgSchCellCb
756 *  @param[in] CmLteTimingInfo
757 *  @param[in] idx
758 *  @return  Void
759 */
760 #ifdef ANSI
761 PUBLIC S16 rgSCHUhmAppendPhich
762 (
763 RgSchCellCb            *cellCb,
764 CmLteTimingInfo        frm,
765 U8                     idx
766 )
767 #else
768 PUBLIC S16 rgSCHUhmAppendPhich (cellCb, frm, idx)
769 RgSchCellCb            *cellCb;
770 CmLteTimingInfo        frm;
771 U8                     idx;
772 #endif
773 {
774    U8              nDmrs;
775    U8              rbStart;
776 #ifdef LTE_TDD
777    U8              iPhich;
778 #endif
779    RgSchUlAlloc    *ulAlloc;
780 #ifdef LTEMAC_HDFDD
781    Bool            allwNack = TRUE;
782 #endif /* LTEMAC_HDFDD */
783    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cellCb);
784
785    TRC2(rgSCHUhmAppendPhich)
786
787 #ifdef RG_5GTF
788    RETVALUE(ROK);
789 #endif
790    if(cellUl->hqFdbkIdx[idx] != RGSCH_INVALID_INFO)
791    {
792       ulAlloc = rgSCHUtlFirstHqFdbkAlloc (cellCb, idx);
793       while (ulAlloc)
794       {
795          /*ccpu00106104 MOD added check for ACKNACK rep*/
796          /*added check for acknack so that adaptive retx considers ue 
797            inactivity due to ack nack repetition*/
798          if((ulAlloc->ue != NULLP) && ((TRUE != ulAlloc->forMsg3) &&
799                   ((ulAlloc->ue->measGapCb.isMeasuring == TRUE) ||
800                    (ulAlloc->ue->ackNakRepCb.isAckNakRep == TRUE))))
801          {
802             /* Mark the UE for retransmission */
803             /* If UE is measuring then we should not be sending PHICH unless msg3 */
804             /*UE assumes ack, if nack then do adaptive re-transmission*/
805             /*ulAlloc->hqProc->rcvdCrcInd = FALSE;--*/
806             ulAlloc = rgSCHUtlNextHqFdbkAlloc (cellCb, ulAlloc, idx);
807             continue;
808          }
809 #ifdef LTE_TDD
810          if (rgSCHUtlGetPhichInfo (ulAlloc->hqProc, &rbStart, &nDmrs, &iPhich) != ROK)
811 #else
812             if (rgSCHUtlGetPhichInfo (ulAlloc->hqProc, &rbStart, &nDmrs) != ROK)
813 #endif
814             {
815                RETVALUE (RFAILED);
816             }
817          if(nDmrs != RGSCH_INVALID_NDMRS)
818          {
819             if(cellCb->dynCfiCb.switchOvrInProgress)
820             {
821                ulAlloc->hqProc->rcvdCrcInd = TRUE;
822             }    
823
824             if(ulAlloc->hqProc->rcvdCrcInd) 
825             {
826 #ifdef LTE_TDD
827                rgSCHUtlAddPhich (cellCb, frm, TRUE, nDmrs, rbStart, iPhich);
828 #else
829                rgSCHUtlAddPhich (cellCb, frm, TRUE, nDmrs, rbStart, ulAlloc->forMsg3);
830 #endif
831             }
832             /* Sending NACK in PHICH for failed UL TX */
833             else
834             {
835 #ifdef LTE_TDD
836                rgSCHUtlAddPhich (cellCb, frm, FALSE, nDmrs, rbStart, iPhich);
837 #else
838 #ifdef LTEMAC_HDFDD
839                if (ulAlloc->ue != NULLP && ulAlloc->ue->hdFddEnbld)
840                {
841                   rgSCHCmnHdFddChkNackAllow( cellCb, ulAlloc->ue, frm, &allwNack);
842                   /* Present implementaion of non-HDFDD does not send phich req
843                      incase of NACK. So commented this part to maintain same right
844                      now.*/
845
846                   if (allwNack)
847                   {
848                      rgSCHUtlAddPhich (cellCb, frm, FALSE, nDmrs, rbStart, ulAlloc->forMsg3);
849                   }
850                   else
851                   {
852                      rgSCHUtlAddPhich (cellCb, frm, TRUE, nDmrs, rbStart, ulAlloc->forMsg3);
853                   }
854                }
855                else
856                {
857                   rgSCHUtlAddPhich (cellCb, frm, FALSE, nDmrs, rbStart, ulAlloc->forMsg3);
858                }
859 #else
860                rgSCHUtlAddPhich (cellCb, frm, FALSE, nDmrs, rbStart, ulAlloc->forMsg3);
861 #endif/* LTEMAC_HDFDD */
862 #endif
863             }
864          }
865          ulAlloc = rgSCHUtlNextHqFdbkAlloc (cellCb, ulAlloc, idx);
866       }
867    }
868    RETVALUE(ROK);
869 } /* rgSCHUhmAppendPhich */
870
871 /**
872  * @brief This function initializes the DL HARQ Entity of UE.
873  *
874  * @details
875  *
876  *     Function: rgSCHUhmHqEntInit
877  *     Purpose:  This function initializes the UL HARQ Processes of 
878  *               UE control block. This is performed at the time
879  *               of creating UE control block.
880  *     
881  *     Invoked by: configuration module
882  *     
883  *  @param[in]  RgSchUeCb*    ueCb
884  *  @return  S16
885  *           -# ROK
886  *           -# RFAILED
887  *
888  **/
889 #ifdef ANSI
890 PUBLIC S16 rgSCHUhmHqEntInit
891 (
892 RgSchCellCb       *cellCb,
893 RgSchUeCb           *ueCb
894 )
895 #else
896 PUBLIC S16 rgSCHUhmHqEntInit(cellCb, ueCb)
897 RgSchCellCb       *cellCb;
898 RgSchUeCb           *ueCb;
899 #endif
900 {
901    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ueCb, cellCb);
902 #ifdef LTE_TDD   
903    Inst              inst = ueCb->cell->instIdx;
904 #endif
905    TRC2(rgSCHUhmHqEntInit)
906
907 #ifndef LTE_TDD
908    /* Init the HARQ processes */
909    ueUl->hqEnt.numHqPrcs = RGSCH_NUM_UL_HQ_PROC;
910 #else
911    /* Init the HARQ processes */
912    ueUl->hqEnt.numHqPrcs = 
913                         rgSchTddUlNumHarqProcTbl[ueCb->cell->ulDlCfgIdx];
914    if (rgSCHUtlAllocSBuf(inst, (Data **)&ueUl->hqEnt.hqProcCb, 
915                            ueUl->hqEnt.numHqPrcs * \
916                            sizeof(RgSchUlHqProcCb)) != ROK)
917    {
918       RETVALUE(RFAILED);
919    }
920 #endif
921
922    RETVALUE(ROK);
923 } /* rgSCHUhmHqEntInit */
924
925 #ifdef RG_5GTF
926 /**
927  * @brief This function gets an available HARQ process.
928  *
929  * @details
930  *
931  *     Function: rgSCHUhmGetAvlHqProc
932  *     Purpose:  This function returns an available HARQ process in 
933  *               the UL direction. All HARQ processes are maintained
934  *               in queues of free and inuse.
935  *
936  *               1. Check if the free queue is empty. If yes, return
937  *                  RFAILED
938  *               2. If not empty, update the proc variable with the
939  *                  first process in the queue. Return ROK.
940  *     
941  *     Invoked by: scheduler
942  *     
943  *  @param[in]  RgSchUeCb           *ue
944  *  @param[in]  CmLteTimingInfo  timingInfo
945  *  @param[out] RgSchDlHqProc       **hqP
946  *  @return  S16       
947  *         -#ROK     if successful
948  *         -#RFAILED otherwise
949  *
950  **/
951 #ifdef ANSI
952 PUBLIC S16 rgSCHUhmGetAvlHqProc
953 (
954 RgSchCellCb           *cell,
955 RgSchUeCb               *ue,
956 RgSchUlHqProcCb         **hqP
957 )
958 #else
959 PUBLIC S16 rgSCHUhmGetAvlHqProc (cell, ue, hqP)
960 RgSchCellCb           *cell;
961 RgSchUeCb             *ue;
962 RgSchUlHqProcCb       **hqP;
963 #endif
964 {
965    RgSchCmnUlCell    *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
966    RgSchCmnUlUe      *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
967    RgSchUlHqProcCb   *tmpHqProc;
968    CmLList           *tmp;
969    RgUeUlHqCb        *hqE;
970
971    TRC2(rgSCHUhmGetAvlHqProc);
972
973    hqE = &ueUl->hqEnt;
974  
975    CM_LLIST_FIRST_NODE(&(hqE->free), tmp);
976
977    if (NULLP == tmp)
978    {
979       //RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId,
980        //                "rgSCHUhmGetAvlHqProc free %ld inUse %ld ue %d"
981         //                                   , hqE->free.count, hqE->inUse.count, ue->ueId);
982       //printf("5GTF_ERROR rgSCHUhmGetAvlHqProc cellId %d  %ld inUse %ld ue %d"
983                               //, cell->cellId, hqE->free.count, hqE->inUse.count, ue->ueId);
984       /* No Harq Process available in the free queue. */
985       RETVALUE(RFAILED);
986    }
987
988    tmpHqProc = (RgSchUlHqProcCb *)(tmp->node);
989
990    /* Remove the element from the free Queue */
991    cmLListDelFrm(&hqE->free, tmp);
992
993    /* Add the element into the inUse Queue as well */
994    cmLListAdd2Tail(&hqE->inUse, &tmpHqProc->lnk);
995
996 #ifdef UL_ADPT_DBG 
997          printf("rgSCHUhmGetAvlHqProc cellId %d  free %ld inUse %ld ue %d time (%d %d)\n",cell->cellId, hqE->free.count, hqE->inUse.count, ue->ueId,cellUl->schdTime.sfn,cellUl->schdTime.slot);
998 #endif         
999    tmpHqProc->schdTime = cellUl->schdTime;
1000
1001    *hqP = tmpHqProc;
1002    
1003    RETVALUE(ROK);
1004 } /* rgSCHUhmGetAvlHqProc */
1005
1006 /**
1007  * @brief Handler for identifying the HARQ process cb associated with the
1008  * TX Time.
1009  *
1010  * @details
1011  *
1012  *     Function: rgSCHUhmGetUlProcByTime 
1013  *     
1014  *     Processing Steps: 
1015  *      - Return pointer to uplink harq process corresponding to the timing
1016  *        information passed.
1017  *           
1018  *  @param[in]  *ue
1019  *  @param[in]  idx
1020  *  @return  RgSchUlHqProcCb*
1021  *      -# Pointer to harq process corresponding to index
1022  *      -# NULL
1023  **/
1024 #ifdef ANSI
1025 PUBLIC RgSchUlHqProcCb* rgSCHUhmGetUlProcByTime 
1026 (
1027 RgSchCellCb      *cell,
1028 RgSchUeCb        *ue, 
1029 CmLteTimingInfo  frm
1030 )
1031 #else
1032 PUBLIC RgSchUlHqProcCb* rgSCHUhmGetUlProcByTime(cell, ue, frm)
1033 RgSchCellCb      *cell;
1034 RgSchUeCb        *ue; 
1035 CmLteTimingInfo  frm;
1036 #endif
1037 {
1038    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
1039    CmLListCp    *lst = &ueUl->hqEnt.inUse;
1040    CmLList      *lnk = lst->first;
1041    RgSchUlHqProcCb   *proc;
1042
1043    TRC2(rgSCHUhmGetUlProcByTime);
1044
1045    while (lnk)
1046    {
1047       proc = (RgSchUlHqProcCb *)(lnk->node);
1048       lnk = lnk->next;
1049       //   printf("compare rgSCHUhmGetUlProcByTime time (%d %d) CRC time (%d %d) proc->procId %d \n",proc->schdTime.sfn,proc->schdTime.slot,frm.sfn,frm.slot ,proc->procId);
1050       if (RGSCH_TIMEINFO_SAME(proc->schdTime, frm))
1051       {
1052         // printf("Harq timing Matched rgSCHUhmGetUlProcByTime time (%d %d) proc->procId %d \n",proc->schdTime.sfn,proc->schdTime.slot, proc->procId);
1053          RETVALUE(proc);
1054       }
1055    }
1056
1057    RETVALUE(NULLP);
1058 }  /* rgSCHUhmGetUlProcByTime */
1059 #endif
1060
1061
1062 /**********************************************************************
1063  
1064          End of file
1065 **********************************************************************/