[Epic-ID: ODUHIGH-464][Task-ID: ODUHIGH-483] Memeory related fix in FDD and TDD mode
[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    uint32_t gUlRetxPassCntr = 0;
67    /*uint32_t gUlRetxFailCntr;
68    uint32_t gUlCrcPassCounter;
69    uint32_t gUlCrcFailCounter;*/
70 #endif
71 uint8_t rgRvIdxTable[] = {0, 3, 1, 2}; /* This gives rvIdx for a given rv */
72 uint8_t rgRvTable[] = {0, 2, 3 ,1};    /* This gives rv for a given rvIdx */
73
74 #ifdef EMTC_ENABLE
75 Void rgSCHCmnEmtcHdlHarqProcFail
76 (
77 RgSchCellCb       *cell,
78 RgSchUeCb         *ue,
79 RgSchUlHqProcCb   *hqProc,
80 CmLteTimingInfo   frm
81 );
82 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 Void rgSCHUhmProcDatInd(RgSchCellCb *cell,RgSchUeCb *ue,CmLteTimingInfo frm)
110 #else  /* MAC_SCH_STATS */
111 Void rgSCHUhmProcDatInd(RgSchCellCb *cell,RgSchUeCb  *ue,CmLteTimingInfo frm,uint8_t  cqi)
112 #endif /* MAC_SCH_STATS */
113 {
114    RgSchUlHqProcCb   *hqProc;
115 #ifdef UL_LA
116    RgSchCmnUlUe   *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
117    S32            iTbs;
118    uint8_t        maxiTbs = rgSchCmnUlCqiToTbsTbl[cell->isCpUlExtend]
119                                                  [ueUl->maxUlCqi];
120 #endif
121
122    rgSCHUtlUlHqProcForUe(cell, frm, ue, &hqProc);
123    if (hqProc == NULLP)
124    {
125       DU_LOG("\nERROR  -->  SCH : UE[%d] failed to find UL HqProc for [%d:%d]\n",
126                       ue->ueId, frm.sfn, frm.slot);
127       return;
128    }
129    hqProc->rcvdCrcInd = TRUE;
130
131 #ifdef UL_LA
132    {
133       ueUl->ulLaCb.deltaiTbs += UL_LA_STEPUP;
134       iTbs = (ueUl->ulLaCb.cqiBasediTbs + ueUl->ulLaCb.deltaiTbs)/100;
135
136       if (iTbs > maxiTbs)
137       {
138          ueUl->ulLaCb.deltaiTbs = (maxiTbs * 100) - ueUl->ulLaCb.cqiBasediTbs;
139       }
140
141    }
142 #endif
143 #ifdef MAC_SCH_STATS
144    /** Stats update over here 
145     */
146    {
147       hqFailStats.ulCqiStat[cqi - 1].numOfAcks++;
148    }
149 #endif
150
151 #ifdef TENB_STATS
152    /* UL stats are filled in primary index as of now */
153    cell->tenbStats->sch.ulAckNack[rgRvTable[hqProc->rvIdx]]++;
154    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].ulAckNackCnt++;
155    if(hqProc->alloc)
156    {
157       ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].ulTpt += (hqProc->alloc->grnt.datSz << 3);
158       cell->tenbStats->sch.ulTtlTpt +=(hqProc->alloc->grnt.datSz << 3);//pverma
159    }
160 #endif
161    
162    return;
163 }  /* rgSCHUhmProcDatInd */
164
165 /**
166  * @brief Handler for HARQ processing on recieving Data indication from PHY.
167  *
168  * @details
169  *
170  *     Function: rgSCHUhmProcMsg3DatInd
171  *     
172  *     Invoked by: rgSCHTomTfuDatInd of  TOM
173  *
174  *     Processing Steps:
175  *      - Set rcvdCrcInd variable to TRUE  
176  *           
177  *  @param[in,out] *hqProc
178  *  @return  Void
179  **/
180 Void rgSCHUhmProcMsg3DatInd(RgSchUlHqProcCb *hqProc)
181 {
182    hqProc->rcvdCrcInd = TRUE;
183    hqProc->remTx = 0;        /*Reseting the value of rem Tx*/
184    DU_LOG("\nINFO  -->  SCH : rgSCHUhmProcMsg3DatInd,id:%u\n",hqProc->procId);
185    return;
186 }  /* rgSCHUhmProcMsg3DatInd */
187
188 /**
189  * @brief Handler for HARQ processing on recieving Data indication from PHY.
190  *
191  * @details
192  *
193  *     Function: rgSCHUhmProcMsg3Failure
194  *     
195  *     Invoked by: rgSCHTomTfuDatInd of  TOM
196  *
197  *     Processing Steps:
198  *      - Set rcvdCrcInd variable to TRUE  
199  *           
200  *  @param[in,out] *hqProc
201  *  @return  Void
202  **/
203 Void rgSCHUhmProcMsg3Failure(RgSchUlHqProcCb *hqProc)
204 {
205 #ifdef EMTC_ENABLE
206    RG_SCH_EMTC_IS_CRCIND_RCVD_CHK_RACB(hqProc);
207 #endif  
208    if(hqProc->rcvdCrcInd != TRUE) 
209    {
210       hqProc->rcvdCrcInd = FALSE;
211    }
212
213    return;
214 }  /* rgSCHUhmProcMsg3Failure */
215
216 /**
217  * @brief Handler for HARQ processing on recieving Decode failure from PHY.
218  *
219  * @details
220  *
221  *     Function: rgSCHUhmProcHqFailure
222  *     
223  *     Invoked by: rgSCHTomTfuDecFailInd of TOM
224  *
225  *     Processing Steps: 
226  *      - Update NACK information in harq info.
227  *      - Update RV index of received RV from PHY in harq info.
228  *      - Set PhichInfo in DlSf
229  *           
230  *  @param[in] *cell
231  *  @param[in] *ue
232  *  @param[in] frm
233  *  @param[in] rv
234  *  @return  Void
235  **/
236 #ifndef MAC_SCH_STATS
237 Void rgSCHUhmProcHqFailure(RgSchCellCb *cell,RgSchUeCb *ue,CmLteTimingInfo  frm,TknUInt8  rv)
238 #else /* MAC_SCH_STATS */
239 Void rgSCHUhmProcHqFailure(RgSchCellCb  *cell,RgSchUeCb  *ue,CmLteTimingInfo  frm,TknUInt8  rv,uint8_t cqi)
240 #endif /* MAC_SCH_STATS */
241 {
242    RgSchUlHqProcCb   *hqProc;
243 #ifdef UL_LA
244    RgSchCmnUlUe   *ueUl = RG_SCH_CMN_GET_UL_UE(ue,cell);
245    S32               iTbs;
246 #endif
247
248    rgSCHUtlUlHqProcForUe(cell, frm, ue, &hqProc);
249    if (hqProc == NULLP)
250    {
251       DU_LOG("\nERROR  -->  SCH : UE[%d] failed to find UL HqProc for [%d:%d]\n",
252                       ue->ueId, frm.sfn, frm.slot);
253       return;
254    }
255 #ifdef UL_LA
256    {
257       ueUl->ulLaCb.deltaiTbs -= UL_LA_STEPDOWN;
258       iTbs = (ueUl->ulLaCb.cqiBasediTbs + ueUl->ulLaCb.deltaiTbs)/100;
259
260       if (iTbs < 0)
261       {
262          ueUl->ulLaCb.deltaiTbs = -(ueUl->ulLaCb.cqiBasediTbs);
263       }
264
265    } 
266 #endif
267 #ifdef MAC_SCH_STATS
268    /** Stats update over here */
269    {
270       static uint32_t retxCnt = 0;
271       ++retxCnt;
272       hqFailStats.ulCqiStat[cqi - 1].numOfNacks++;
273    }
274 #endif /* MAC_SCH_STATS */
275    if(hqProc->rcvdCrcInd != TRUE) 
276    {
277       hqProc->rcvdCrcInd = FALSE;
278    }
279 #ifdef TENB_STATS
280    /* UL stats are filled in primary index as of now */
281    cell->tenbStats->sch.ulAckNack[rgRvTable[hqProc->rvIdx]]++;
282    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].ulAckNackCnt++;
283    cell->tenbStats->sch.ulNack[rgRvTable[hqProc->rvIdx]]++;
284    ue->tenbStats->stats.nonPersistent.sch[RG_SCH_CELLINDEX(cell)].ulNackCnt++;
285 #endif
286    hqProc->rvIdxPhy.pres = rv.pres;
287    if(rv.pres)
288    {
289       hqProc->rvIdxPhy.val = rgRvIdxTable[rv.val];
290    }
291    return;
292 } /* rgSCHUhmProcHqFailure */
293
294 /**
295  * @brief Handler for identifying the HARQ process cb associated with the
296  * index.
297  *
298  * @details
299  *
300  *     Function: rgSCHUhmGetUlHqProc
301  *     
302  *     Processing Steps: 
303  *      - Return pointer to uplink harq process corresponding to the timing
304  *        information passed.
305  *           
306  *  @param[in]  *ue
307  *  @param[in]  idx
308  *  @return  RgSchUlHqProcCb*
309  *      -# Pointer to harq process corresponding to index
310  *      -# NULL
311  **/
312 RgSchUlHqProcCb* rgSCHUhmGetUlHqProc(RgSchCellCb *cell,RgSchUeCb  *ue, uint8_t idx)
313 {
314    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
315
316 #if (ERRCLASS & ERRCLS_DEBUG)
317    if(idx >= ueUl->hqEnt.numHqPrcs)
318    {
319       return (NULLP);
320    }
321 #endif
322    return (&(ueUl->hqEnt.hqProcCb[idx]));
323 }  /* rgSCHUhmGetUlHqProc */
324
325 /**
326  * @brief Handler for HARQ processing on recieving new trasmission indication 
327  * from USM.
328  *
329  * @details
330  *
331  *     Function: rgSCHUhmNewTx
332  *     
333  *     Invoked by: USM
334  *
335  *     Processing Steps: 
336  *      - Update harq info with values indicating new HARQ transmission.
337  *           
338  *  @param[in,out]  *hqProc
339  *  @param[in]      *alloc
340  *  @return  Void
341  **/
342 Void rgSCHUhmNewTx(RgSchUlHqProcCb *hqProc,uint8_t maxHqRetx,RgSchUlAlloc *alloc)
343 {
344
345    hqProc->ndi ^= 1;
346    hqProc->alloc = alloc;
347    hqProc->remTx = maxHqRetx;
348    hqProc->rcvdCrcInd = FALSE;
349    hqProc->rvIdx = 0;
350    hqProc->rvIdxPhy.pres = FALSE;
351 #ifdef LTE_L2_MEAS
352    if (hqProc->alloc->ue)
353    {
354       ((RgUeUlHqCb*)hqProc->hqEnt)->numBusyHqProcs++;
355    }
356 #endif
357    return;
358 }  /* rgSCHUhmNewTx */
359
360 /**
361  * @brief Free an uplink HARQ process.
362  *
363  * @details
364  *
365  *     Function: rgSCHUhmFreeProc
366  *     
367  *     Invoked by: USM
368  *
369  *     Processing Steps: 
370  *      - Set alloc pointer to NULLP
371  *           
372  *  @param[in]  RgSchUlHqProcCb   *hqProc
373  *  @param[in]  RgSchCellCb      *cell
374  *  @return  Void
375  **/
376 Void rgSCHUhmFreeProc(RgSchUlHqProcCb *hqProc,RgSchCellCb *cell)
377 {
378 #ifdef LTE_L2_MEAS
379    RgSchUeCb         *ueCb;
380    uint8_t qci = 1;
381 #endif
382
383 #ifdef LTE_L2_MEAS
384    if (hqProc->alloc && hqProc->alloc->ue)
385    {
386       ueCb = hqProc->alloc->ue;
387       if (ueCb && cell)
388       {
389          uint32_t nonLcg0ReportedBs = ((RgSchCmnLcg *)(ueCb->ul.lcgArr[1].sch))->reportedBs + \
390                                ((RgSchCmnLcg *)(ueCb->ul.lcgArr[2].sch))->reportedBs + \
391                                ((RgSchCmnLcg *)(ueCb->ul.lcgArr[3].sch))->reportedBs;
392          ((RgUeUlHqCb*)hqProc->hqEnt)->numBusyHqProcs--;
393          if (! ((RgUeUlHqCb*)hqProc->hqEnt)->numBusyHqProcs && !(nonLcg0ReportedBs))
394          {
395             while (ueCb->ulActiveLCs)
396             {
397                if (ueCb->ulActiveLCs & 0x1)
398                {
399                   cell->qciArray[qci].ulUeCount--;
400                }
401                qci++;
402                ueCb->ulActiveLCs >>= 1;
403             }
404          }
405       }
406    }
407 #endif
408
409
410  if(hqProc && (RgUeUlHqCb*)hqProc->hqEnt)
411  {
412
413 #ifdef UL_ADPT_DBG 
414     DU_LOG("\nDEBUG  -->  SCH : ########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);
415 #endif
416    hqProc->alloc = NULLP;
417    hqProc->ulSfIdx = RGSCH_INVALID_INFO;
418    /*ccpu00116293 - Correcting relation between UL slot and DL slot based on RG_UL_DELTA*/
419    hqProc->isRetx  = FALSE;
420    hqProc->remTx = 0; /*Reseting the remTx value to 0*/
421 #ifdef EMTC_ENABLE
422    RG_SCH_EMTC_SET_ISDTX_TO_FALSE(hqProc);
423 #endif
424    cmLListDelFrm(&((RgUeUlHqCb*)hqProc->hqEnt)->inUse,&hqProc->lnk);
425    cmLListAdd2Tail(&((RgUeUlHqCb*)hqProc->hqEnt)->free, &hqProc->lnk);
426
427    /*
428    DU_LOG("\nINFO  -->  SCH : after rgSCHUhmFreeProc inuse %ld free %ld \n", 
429         (CmLListCp *)(&((RgUeUlHqCb*)hqProc->hqEnt)->inUse)->count,
430          (CmLListCp *) (&((RgUeUlHqCb*)hqProc->hqEnt)->free)->count);
431    */
432  }
433  else
434  {
435      DU_LOG("\nERROR  -->  SCH : hqEnt is NULL\n");
436  }
437    return;
438 }  /* rgSCHUhmFreeProc */
439
440 /**
441  * @brief Handler for HARQ processing on recieving re-trasmission 
442  * indication from USM.
443  *
444  * @details
445  *
446  *     Function: rgSCHUhmRetx
447  *     
448  *     Invoked by: USM
449  *
450  *     Processing Steps: 
451  *      - Update harq info with values corresponding to
452  *        re-transmission. 
453  *           
454  *  @param[in,out]  *hqProc
455  *  @return  Void
456  **/
457 Void rgSCHUhmRetx(RgSchUlHqProcCb *hqProc,RgSchUlAlloc    *alloc)
458 {
459
460    hqProc->alloc = alloc;
461    --hqProc->remTx;
462    hqProc->rvIdx = (hqProc->rvIdx + 1) % 4;
463    hqProc->rvIdxPhy.pres = FALSE;
464    return;
465 }  /* rgSCHUhmRetx */
466
467
468 /**
469  * @brief Handler for initializing the HARQ entity.
470  *
471  * @details
472  *
473  *     Function: rgSCHUhmRgrUeCfg
474  *     
475  *     Invoked by: RGR
476  *
477  *     Processing Steps: 
478  *      -  Initialize maxHqRetx
479  *           
480  *  @param[in]      *cellCb
481  *  @param[in,out]  *ueCb
482  *  @param[in]      *ueCfg
483  *  @param[out]     *err
484  *  @return  Void
485  **/
486 Void rgSCHUhmRgrUeCfg(RgSchCellCb *cellCb,RgSchUeCb *ueCb,RgrUeCfg *ueCfg)
487 {
488    uint8_t i;
489    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ueCb, cellCb);
490    
491    ueUl->hqEnt.maxHqRetx = ((ueCfg->ueUlHqCfg.maxUlHqTx) - 1);
492 #ifdef TFU_UPGRADE
493    /* Storing the delta HARQ offset for HARQ + PUSCH */
494    ueCb->ul.betaHqOffst = ueCfg->puschDedCfg.bACKIdx;
495 #endif
496    cmLListInit(&ueUl->hqEnt.free);
497    cmLListInit(&ueUl->hqEnt.inUse);
498    for(i=0; i < ueUl->hqEnt.numHqPrcs; i++)
499    {
500       ueUl->hqEnt.hqProcCb[i].hqEnt = (void*)(&ueUl->hqEnt);
501       ueUl->hqEnt.hqProcCb[i].procId = i;
502       ueUl->hqEnt.hqProcCb[i].remTx = 0;
503       ueUl->hqEnt.hqProcCb[i].ulSfIdx = RGSCH_INVALID_INFO;
504       ueUl->hqEnt.hqProcCb[i].alloc = NULLP;
505 #ifdef LTEMAC_SPS
506       /* ccpu00139513- Initializing SPS flags*/
507       ueUl->hqEnt.hqProcCb[i].isSpsActvnHqP = FALSE;
508       ueUl->hqEnt.hqProcCb[i].isSpsOccnHqP = FALSE;
509 #endif
510       cmLListAdd2Tail(&ueUl->hqEnt.free, &ueUl->hqEnt.hqProcCb[i].lnk);
511       ueUl->hqEnt.hqProcCb[i].lnk.node = (PTR)&ueUl->hqEnt.hqProcCb[i];
512    }
513
514 #ifdef EMTC_ENABLE
515    rgSCHEmtcInitUlUeHqEnt(cellCb, ueCfg, ueCb);
516 #endif
517    return;
518 }  /* rgSCHUhmRgrUeCfg */
519
520 /**
521  * @brief Handler for re-initializing the HARQ entity.
522  *
523  * @details
524  *
525  *     Function: rgSCHUhmRgrUeRecfg
526  *     
527  *     Invoked by: RGR
528  *
529  *     Processing Steps: 
530  *      -  Re-initialize maxHqRetx
531  *           
532  *  @param[in]      *cellCb
533  *  @param[in,out]  *ueCb
534  *  @param[in]      *ueCfg
535  *  @param[out]     *err
536  *  @return  Void
537  **/
538 Void rgSCHUhmRgrUeRecfg(RgSchCellCb *cellCb,RgSchUeCb *ueCb,RgrUeRecfg  *ueRecfg)
539 {
540    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ueCb, cellCb);
541
542    /* [ccpu00123958]-ADD- Check for HARQ Reconfig from the bit mask  */
543    if(RGR_UE_ULHARQ_RECFG & ueRecfg->ueRecfgTypes)
544    {
545       ueUl->hqEnt.maxHqRetx = (ueRecfg->ueUlHqRecfg.maxUlHqTx - 1); 
546    }
547
548    return;
549 }  /* rgSCHUhmRgrUeRecfg */
550
551 /**
552  * @brief Handler for de-initializing the HARQ entity.
553  *
554  * @details
555  *
556  *     Function: rgSCHUhmFreeUe
557  *     
558  *     Invoked by: RGR
559  *
560  *     Processing Steps: 
561  *      - 
562  *           
563  *  @param[in,out]  *ueCb
564  *  @return  Void
565  **/
566 Void rgSCHUhmFreeUe(RgSchCellCb *cellCb,RgUeUlHqCb *hqEnt)
567 {
568 #ifdef LTE_TDD
569    /* ccpu00117052 - MOD - Passing double pointer
570    for proper NULLP assignment*/
571    rgSCHUtlFreeSBuf(cellCb->instIdx, 
572                   (Data **)(&(hqEnt->hqProcCb)),
573                   hqEnt->numHqPrcs * sizeof(RgSchUlHqProcCb));
574 #endif
575
576    return;
577 }  /* rgSCHUhmFreeUe */
578
579
580 /**
581 * @brief Handler for appending the PHICH information in to the dlSf.
582 *
583 * @details
584 *
585 *     Function: rgSCHUhmAppendPhich
586 *     
587 *     Invoked by: TOM
588 *
589 *     Processing Steps:
590 *      - Set PhichInfo in DlSf for each Hq
591 *
592 *  @param[in] *RgSchCellCb
593 *  @param[in] CmLteTimingInfo
594 *  @param[in] idx
595 *  @return  Void
596 */
597 S16 rgSCHUhmAppendPhich(RgSchCellCb *cellCb,CmLteTimingInfo frm,uint8_t idx)
598 {
599    uint8_t         nDmrs;
600    uint8_t         rbStart;
601 #ifdef LTE_TDD
602    uint8_t         iPhich;
603 #endif
604    RgSchUlAlloc    *ulAlloc;
605 #ifdef LTEMAC_HDFDD
606    Bool            allwNack = TRUE;
607 #endif /* LTEMAC_HDFDD */
608    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cellCb);
609
610 #ifdef RG_5GTF
611    return ROK;
612 #endif
613    if(cellUl->hqFdbkIdx[idx] != RGSCH_INVALID_INFO)
614    {
615       ulAlloc = rgSCHUtlFirstHqFdbkAlloc (cellCb, idx);
616       while (ulAlloc)
617       {
618          /*ccpu00106104 MOD added check for ACKNACK rep*/
619          /*added check for acknack so that adaptive retx considers ue 
620            inactivity due to ack nack repetition*/
621          if((ulAlloc->ue != NULLP) && ((TRUE != ulAlloc->forMsg3) &&
622                   ((ulAlloc->ue->measGapCb.isMeasuring == TRUE) ||
623                    (ulAlloc->ue->ackNakRepCb.isAckNakRep == TRUE))))
624          {
625             /* Mark the UE for retransmission */
626             /* If UE is measuring then we should not be sending PHICH unless msg3 */
627             /*UE assumes ack, if nack then do adaptive re-transmission*/
628             /*ulAlloc->hqProc->rcvdCrcInd = FALSE;--*/
629             ulAlloc = rgSCHUtlNextHqFdbkAlloc (cellCb, ulAlloc, idx);
630             continue;
631          }
632 #ifdef LTE_TDD
633          if (rgSCHUtlGetPhichInfo (ulAlloc->hqProc, &rbStart, &nDmrs, &iPhich) != ROK)
634 #else
635             if (rgSCHUtlGetPhichInfo (ulAlloc->hqProc, &rbStart, &nDmrs) != ROK)
636 #endif
637             {
638                return  (RFAILED);
639             }
640          if(nDmrs != RGSCH_INVALID_NDMRS)
641          {
642             if(cellCb->dynCfiCb.switchOvrInProgress)
643             {
644                ulAlloc->hqProc->rcvdCrcInd = TRUE;
645             }    
646
647             if(ulAlloc->hqProc->rcvdCrcInd) 
648             {
649 #ifdef LTE_TDD
650                rgSCHUtlAddPhich (cellCb, frm, TRUE, nDmrs, rbStart, iPhich);
651 #else
652                rgSCHUtlAddPhich (cellCb, frm, TRUE, nDmrs, rbStart, ulAlloc->forMsg3);
653 #endif
654             }
655             /* Sending NACK in PHICH for failed UL TX */
656             else
657             {
658 #ifdef LTE_TDD
659                rgSCHUtlAddPhich (cellCb, frm, FALSE, nDmrs, rbStart, iPhich);
660 #else
661 #ifdef LTEMAC_HDFDD
662                if (ulAlloc->ue != NULLP && ulAlloc->ue->hdFddEnbld)
663                {
664                   rgSCHCmnHdFddChkNackAllow( cellCb, ulAlloc->ue, frm, &allwNack);
665                   /* Present implementaion of non-HDFDD does not send phich req
666                      incase of NACK. So commented this part to maintain same right
667                      now.*/
668
669                   if (allwNack)
670                   {
671                      rgSCHUtlAddPhich (cellCb, frm, FALSE, nDmrs, rbStart, ulAlloc->forMsg3);
672                   }
673                   else
674                   {
675                      rgSCHUtlAddPhich (cellCb, frm, TRUE, nDmrs, rbStart, ulAlloc->forMsg3);
676                   }
677                }
678                else
679                {
680                   rgSCHUtlAddPhich (cellCb, frm, FALSE, nDmrs, rbStart, ulAlloc->forMsg3);
681                }
682 #else
683                rgSCHUtlAddPhich (cellCb, frm, FALSE, nDmrs, rbStart, ulAlloc->forMsg3);
684 #endif/* LTEMAC_HDFDD */
685 #endif
686             }
687          }
688          ulAlloc = rgSCHUtlNextHqFdbkAlloc (cellCb, ulAlloc, idx);
689       }
690    }
691    return ROK;
692 } /* rgSCHUhmAppendPhich */
693
694 /**
695  * @brief This function initializes the DL HARQ Entity of UE.
696  *
697  * @details
698  *
699  *     Function: rgSCHUhmHqEntInit
700  *     Purpose:  This function initializes the UL HARQ Processes of 
701  *               UE control block. This is performed at the time
702  *               of creating UE control block.
703  *     
704  *     Invoked by: configuration module
705  *     
706  *  @param[in]  RgSchUeCb*    ueCb
707  *  @return  S16
708  *           -# ROK
709  *           -# RFAILED
710  *
711  **/
712 S16 rgSCHUhmHqEntInit(RgSchCellCb *cellCb,RgSchUeCb *ueCb)
713 {
714    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ueCb, cellCb);
715 #ifdef LTE_TDD   
716    Inst              inst = ueCb->cell->instIdx;
717 #endif
718
719 #ifndef LTE_TDD
720    /* Init the HARQ processes */
721    ueUl->hqEnt.numHqPrcs = RGSCH_NUM_UL_HQ_PROC;
722 #else
723    /* Init the HARQ processes */
724    ueUl->hqEnt.numHqPrcs = 
725                         rgSchTddUlNumHarqProcTbl[ueCb->cell->ulDlCfgIdx];
726    if (rgSCHUtlAllocSBuf(inst, (Data **)&ueUl->hqEnt.hqProcCb, 
727                            ueUl->hqEnt.numHqPrcs * \
728                            sizeof(RgSchUlHqProcCb)) != ROK)
729    {
730       return RFAILED;
731    }
732 #endif
733
734    return ROK;
735 } /* rgSCHUhmHqEntInit */
736
737 #ifdef RG_5GTF
738 /**
739  * @brief This function gets an available HARQ process.
740  *
741  * @details
742  *
743  *     Function: rgSCHUhmGetAvlHqProc
744  *     Purpose:  This function returns an available HARQ process in 
745  *               the UL direction. All HARQ processes are maintained
746  *               in queues of free and inuse.
747  *
748  *               1. Check if the free queue is empty. If yes, return
749  *                  RFAILED
750  *               2. If not empty, update the proc variable with the
751  *                  first process in the queue. Return ROK.
752  *     
753  *     Invoked by: scheduler
754  *     
755  *  @param[in]  RgSchUeCb           *ue
756  *  @param[in]  CmLteTimingInfo  timingInfo
757  *  @param[out] RgSchDlHqProc       **hqP
758  *  @return  S16       
759  *         -#ROK     if successful
760  *         -#RFAILED otherwise
761  *
762  **/
763 S16 rgSCHUhmGetAvlHqProc(RgSchCellCb *cell,RgSchUeCb  *ue,RgSchUlHqProcCb  **hqP)
764 {
765    RgSchCmnUlCell    *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
766    RgSchCmnUlUe      *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
767    RgSchUlHqProcCb   *tmpHqProc;
768    CmLList           *tmp;
769    RgUeUlHqCb        *hqE;
770
771    hqE = &ueUl->hqEnt;
772  
773    CM_LLIST_FIRST_NODE(&(hqE->free), tmp);
774
775    if (NULLP == tmp)
776    {
777        //DU_LOG("rgSCHUhmGetAvlHqProc free %ld inUse %ld ue %d"
778         //                                   , hqE->free.count, hqE->inUse.count, ue->ueId);
779       //DU_LOG("5GTF_ERROR rgSCHUhmGetAvlHqProc cellId %d  %ld inUse %ld ue %d"
780                               //, cell->cellId, hqE->free.count, hqE->inUse.count, ue->ueId);
781       /* No Harq Process available in the free queue. */
782       return RFAILED;
783    }
784
785    tmpHqProc = (RgSchUlHqProcCb *)(tmp->node);
786
787    /* Remove the element from the free Queue */
788    cmLListDelFrm(&hqE->free, tmp);
789
790    /* Add the element into the inUse Queue as well */
791    cmLListAdd2Tail(&hqE->inUse, &tmpHqProc->lnk);
792
793 #ifdef UL_ADPT_DBG 
794          DU_LOG("\nDEBUG  -->  SCH : 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);
795 #endif         
796    tmpHqProc->schdTime = cellUl->schdTime;
797
798    *hqP = tmpHqProc;
799    
800    return ROK;
801 } /* rgSCHUhmGetAvlHqProc */
802
803 /**
804  * @brief Handler for identifying the HARQ process cb associated with the
805  * TX Time.
806  *
807  * @details
808  *
809  *     Function: rgSCHUhmGetUlProcByTime 
810  *     
811  *     Processing Steps: 
812  *      - Return pointer to uplink harq process corresponding to the timing
813  *        information passed.
814  *           
815  *  @param[in]  *ue
816  *  @param[in]  idx
817  *  @return  RgSchUlHqProcCb*
818  *      -# Pointer to harq process corresponding to index
819  *      -# NULL
820  **/
821 RgSchUlHqProcCb* rgSCHUhmGetUlProcByTime(RgSchCellCb *cell,RgSchUeCb *ue, CmLteTimingInfo  frm)
822 {
823    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
824    CmLListCp    *lst = &ueUl->hqEnt.inUse;
825    CmLList      *lnk = lst->first;
826    RgSchUlHqProcCb   *proc;
827
828    while (lnk)
829    {
830       proc = (RgSchUlHqProcCb *)(lnk->node);
831       lnk = lnk->next;
832       //   DU_LOG("\nINFO  -->  SCH : compare rgSCHUhmGetUlProcByTime time (%d %d) CRC time (%d %d) proc->procId %d
833       //   \n",\proc->schdTime.sfn,proc->schdTime.slot,frm.sfn,frm.slot ,proc->procId);
834       if (RGSCH_TIMEINFO_SAME(proc->schdTime, frm))
835       {
836         // DU_LOG("\nINFO  -->  SCH : Harq timing Matched rgSCHUhmGetUlProcByTime time (%d %d) proc->procId %d \n",\
837         proc->schdTime.sfn,proc->schdTime.slot, proc->procId);
838          return (proc);
839       }
840    }
841
842    return (NULLP);
843 }  /* rgSCHUhmGetUlProcByTime */
844 #endif
845
846
847 /**********************************************************************
848  
849          End of file
850 **********************************************************************/