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