Building mib PDU and SSB changes at scheduler
[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 "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.slot);
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.slot);
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 LTE_L2_MEAS
513    RgSchUeCb         *ueCb;
514    U8 qci = 1;
515 #endif
516    TRC2(rgSCHUhmFreeProc);
517
518 #ifdef LTE_L2_MEAS
519    if (hqProc->alloc && hqProc->alloc->ue)
520    {
521       ueCb = hqProc->alloc->ue;
522       if (ueCb && cell)
523       {
524          U32 nonLcg0ReportedBs = ((RgSchCmnLcg *)(ueCb->ul.lcgArr[1].sch))->reportedBs + \
525                                ((RgSchCmnLcg *)(ueCb->ul.lcgArr[2].sch))->reportedBs + \
526                                ((RgSchCmnLcg *)(ueCb->ul.lcgArr[3].sch))->reportedBs;
527          ((RgUeUlHqCb*)hqProc->hqEnt)->numBusyHqProcs--;
528          if (! ((RgUeUlHqCb*)hqProc->hqEnt)->numBusyHqProcs && !(nonLcg0ReportedBs))
529          {
530             while (ueCb->ulActiveLCs)
531             {
532                if (ueCb->ulActiveLCs & 0x1)
533                {
534                   cell->qciArray[qci].ulUeCount--;
535                }
536                qci++;
537                ueCb->ulActiveLCs >>= 1;
538             }
539          }
540       }
541    }
542 #endif
543
544
545  if(hqProc && (RgUeUlHqCb*)hqProc->hqEnt)
546  {
547
548 #ifdef UL_ADPT_DBG 
549     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);
550 #endif
551    hqProc->alloc = NULLP;
552    hqProc->ulSfIdx = RGSCH_INVALID_INFO;
553    /*ccpu00116293 - Correcting relation between UL slot and DL slot based on RG_UL_DELTA*/
554    hqProc->isRetx  = FALSE;
555    hqProc->remTx = 0; /*Reseting the remTx value to 0*/
556 #ifdef EMTC_ENABLE
557    RG_SCH_EMTC_SET_ISDTX_TO_FALSE(hqProc);
558 #endif
559    cmLListDelFrm(&((RgUeUlHqCb*)hqProc->hqEnt)->inUse,&hqProc->lnk);
560    cmLListAdd2Tail(&((RgUeUlHqCb*)hqProc->hqEnt)->free, &hqProc->lnk);
561
562    /*
563    printf("after rgSCHUhmFreeProc inuse %ld free %ld \n", 
564         (CmLListCp *)(&((RgUeUlHqCb*)hqProc->hqEnt)->inUse)->count,
565          (CmLListCp *) (&((RgUeUlHqCb*)hqProc->hqEnt)->free)->count);
566    */
567  }
568  else
569  {
570      printf("\nhqEnt is NULL\n");
571  }
572    RETVOID;
573 }  /* rgSCHUhmFreeProc */
574
575 /**
576  * @brief Handler for HARQ processing on recieving re-trasmission 
577  * indication from USM.
578  *
579  * @details
580  *
581  *     Function: rgSCHUhmRetx
582  *     
583  *     Invoked by: USM
584  *
585  *     Processing Steps: 
586  *      - Update harq info with values corresponding to
587  *        re-transmission. 
588  *           
589  *  @param[in,out]  *hqProc
590  *  @return  Void
591  **/
592 #ifdef ANSI
593 PUBLIC Void rgSCHUhmRetx
594 (
595 RgSchUlHqProcCb *hqProc,
596 RgSchUlAlloc    *alloc
597 )
598 #else
599 PUBLIC Void rgSCHUhmRetx(hqProc, alloc) 
600 RgSchUlHqProcCb *hqProc;
601 RgSchUlAlloc    *alloc;
602 #endif
603 {
604    TRC2(rgSCHUhmRetx);
605
606    hqProc->alloc = alloc;
607    --hqProc->remTx;
608    hqProc->rvIdx = (hqProc->rvIdx + 1) % 4;
609    hqProc->rvIdxPhy.pres = FALSE;
610    RETVOID;
611 }  /* rgSCHUhmRetx */
612
613
614 /**
615  * @brief Handler for initializing the HARQ entity.
616  *
617  * @details
618  *
619  *     Function: rgSCHUhmRgrUeCfg
620  *     
621  *     Invoked by: RGR
622  *
623  *     Processing Steps: 
624  *      -  Initialize maxHqRetx
625  *           
626  *  @param[in]      *cellCb
627  *  @param[in,out]  *ueCb
628  *  @param[in]      *ueCfg
629  *  @param[out]     *err
630  *  @return  Void
631  **/
632 #ifdef ANSI
633 PUBLIC Void rgSCHUhmRgrUeCfg
634 (
635 RgSchCellCb       *cellCb,
636 RgSchUeCb         *ueCb,
637 RgrUeCfg          *ueCfg
638 )
639 #else
640 PUBLIC Void rgSCHUhmRgrUeCfg(cellCb, ueCb, ueCfg) 
641 RgSchCellCb       *cellCb;
642 RgSchUeCb         *ueCb;
643 RgrUeCfg          *ueCfg;
644 #endif
645 {
646    U8 i;
647    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ueCb, cellCb);
648    
649    TRC2(rgSCHUhmRgrUeCfg);
650
651    ueUl->hqEnt.maxHqRetx = ((ueCfg->ueUlHqCfg.maxUlHqTx) - 1);
652 #ifdef TFU_UPGRADE
653    /* Storing the delta HARQ offset for HARQ + PUSCH */
654    ueCb->ul.betaHqOffst = ueCfg->puschDedCfg.bACKIdx;
655 #endif
656    cmLListInit(&ueUl->hqEnt.free);
657    cmLListInit(&ueUl->hqEnt.inUse);
658    for(i=0; i < ueUl->hqEnt.numHqPrcs; i++)
659    {
660       ueUl->hqEnt.hqProcCb[i].hqEnt = (void*)(&ueUl->hqEnt);
661       ueUl->hqEnt.hqProcCb[i].procId = i;
662       ueUl->hqEnt.hqProcCb[i].remTx = 0;
663       ueUl->hqEnt.hqProcCb[i].ulSfIdx = RGSCH_INVALID_INFO;
664       ueUl->hqEnt.hqProcCb[i].alloc = NULLP;
665 #ifdef LTEMAC_SPS
666       /* ccpu00139513- Initializing SPS flags*/
667       ueUl->hqEnt.hqProcCb[i].isSpsActvnHqP = FALSE;
668       ueUl->hqEnt.hqProcCb[i].isSpsOccnHqP = FALSE;
669 #endif
670       cmLListAdd2Tail(&ueUl->hqEnt.free, &ueUl->hqEnt.hqProcCb[i].lnk);
671       ueUl->hqEnt.hqProcCb[i].lnk.node = (PTR)&ueUl->hqEnt.hqProcCb[i];
672    }
673
674 #ifdef EMTC_ENABLE
675    rgSCHEmtcInitUlUeHqEnt(cellCb, ueCfg, ueCb);
676 #endif
677    RETVOID;
678 }  /* rgSCHUhmRgrUeCfg */
679
680 /**
681  * @brief Handler for re-initializing the HARQ entity.
682  *
683  * @details
684  *
685  *     Function: rgSCHUhmRgrUeRecfg
686  *     
687  *     Invoked by: RGR
688  *
689  *     Processing Steps: 
690  *      -  Re-initialize maxHqRetx
691  *           
692  *  @param[in]      *cellCb
693  *  @param[in,out]  *ueCb
694  *  @param[in]      *ueCfg
695  *  @param[out]     *err
696  *  @return  Void
697  **/
698 #ifdef ANSI
699 PUBLIC Void rgSCHUhmRgrUeRecfg
700 (
701 RgSchCellCb       *cellCb,
702 RgSchUeCb         *ueCb,
703 RgrUeRecfg        *ueRecfg
704 )
705 #else
706 PUBLIC Void rgSCHUhmRgrUeRecfg(cellCb, ueCb, ueRecfg) 
707 RgSchCellCb       *cellCb;
708 RgSchUeCb         *ueCb;
709 RgrUeRecfg        *ueRecfg;
710 #endif
711 {
712    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ueCb, cellCb);
713    TRC2(rgSCHUhmRgrUeRecfg);
714
715    /* [ccpu00123958]-ADD- Check for HARQ Reconfig from the bit mask  */
716    if(RGR_UE_ULHARQ_RECFG & ueRecfg->ueRecfgTypes)
717    {
718       ueUl->hqEnt.maxHqRetx = (ueRecfg->ueUlHqRecfg.maxUlHqTx - 1); 
719    }
720
721    RETVOID;
722 }  /* rgSCHUhmRgrUeRecfg */
723
724 /**
725  * @brief Handler for de-initializing the HARQ entity.
726  *
727  * @details
728  *
729  *     Function: rgSCHUhmFreeUe
730  *     
731  *     Invoked by: RGR
732  *
733  *     Processing Steps: 
734  *      - 
735  *           
736  *  @param[in,out]  *ueCb
737  *  @return  Void
738  **/
739 #ifdef ANSI
740 PUBLIC Void rgSCHUhmFreeUe
741 (
742 RgSchCellCb       *cellCb,
743 RgUeUlHqCb        *hqEnt
744 )
745 #else
746 PUBLIC Void rgSCHUhmFreeUe(cellCb, hqEnt) 
747 RgSchCellCb       *cellCb;
748 RgUeUlHqCb       *hqEnt;
749 #endif
750 {
751    TRC2(rgSCHUhmFreeUe);
752 #ifdef LTE_TDD
753    /* ccpu00117052 - MOD - Passing double pointer
754    for proper NULLP assignment*/
755    rgSCHUtlFreeSBuf(cellCb->instIdx, 
756                   (Data **)(&(hqEnt->hqProcCb)),
757                   hqEnt->numHqPrcs * sizeof(RgSchUlHqProcCb));
758 #endif
759
760    RETVOID;
761 }  /* rgSCHUhmFreeUe */
762
763
764 /**
765 * @brief Handler for appending the PHICH information in to the dlSf.
766 *
767 * @details
768 *
769 *     Function: rgSCHUhmAppendPhich
770 *     
771 *     Invoked by: TOM
772 *
773 *     Processing Steps:
774 *      - Set PhichInfo in DlSf for each Hq
775 *
776 *  @param[in] *RgSchCellCb
777 *  @param[in] CmLteTimingInfo
778 *  @param[in] idx
779 *  @return  Void
780 */
781 #ifdef ANSI
782 PUBLIC S16 rgSCHUhmAppendPhich
783 (
784 RgSchCellCb            *cellCb,
785 CmLteTimingInfo        frm,
786 U8                     idx
787 )
788 #else
789 PUBLIC S16 rgSCHUhmAppendPhich (cellCb, frm, idx)
790 RgSchCellCb            *cellCb;
791 CmLteTimingInfo        frm;
792 U8                     idx;
793 #endif
794 {
795    U8              nDmrs;
796    U8              rbStart;
797 #ifdef LTE_TDD
798    U8              iPhich;
799 #endif
800    RgSchUlAlloc    *ulAlloc;
801 #ifdef LTEMAC_HDFDD
802    Bool            allwNack = TRUE;
803 #endif /* LTEMAC_HDFDD */
804    RgSchCmnUlCell  *cellUl = RG_SCH_CMN_GET_UL_CELL(cellCb);
805
806    TRC2(rgSCHUhmAppendPhich)
807
808 #ifdef RG_5GTF
809    RETVALUE(ROK);
810 #endif
811    if(cellUl->hqFdbkIdx[idx] != RGSCH_INVALID_INFO)
812    {
813       ulAlloc = rgSCHUtlFirstHqFdbkAlloc (cellCb, idx);
814       while (ulAlloc)
815       {
816          /*ccpu00106104 MOD added check for ACKNACK rep*/
817          /*added check for acknack so that adaptive retx considers ue 
818            inactivity due to ack nack repetition*/
819          if((ulAlloc->ue != NULLP) && ((TRUE != ulAlloc->forMsg3) &&
820                   ((ulAlloc->ue->measGapCb.isMeasuring == TRUE) ||
821                    (ulAlloc->ue->ackNakRepCb.isAckNakRep == TRUE))))
822          {
823             /* Mark the UE for retransmission */
824             /* If UE is measuring then we should not be sending PHICH unless msg3 */
825             /*UE assumes ack, if nack then do adaptive re-transmission*/
826             /*ulAlloc->hqProc->rcvdCrcInd = FALSE;--*/
827             ulAlloc = rgSCHUtlNextHqFdbkAlloc (cellCb, ulAlloc, idx);
828             continue;
829          }
830 #ifdef LTE_TDD
831          if (rgSCHUtlGetPhichInfo (ulAlloc->hqProc, &rbStart, &nDmrs, &iPhich) != ROK)
832 #else
833             if (rgSCHUtlGetPhichInfo (ulAlloc->hqProc, &rbStart, &nDmrs) != ROK)
834 #endif
835             {
836                RETVALUE (RFAILED);
837             }
838          if(nDmrs != RGSCH_INVALID_NDMRS)
839          {
840             if(cellCb->dynCfiCb.switchOvrInProgress)
841             {
842                ulAlloc->hqProc->rcvdCrcInd = TRUE;
843             }    
844
845             if(ulAlloc->hqProc->rcvdCrcInd) 
846             {
847 #ifdef LTE_TDD
848                rgSCHUtlAddPhich (cellCb, frm, TRUE, nDmrs, rbStart, iPhich);
849 #else
850                rgSCHUtlAddPhich (cellCb, frm, TRUE, nDmrs, rbStart, ulAlloc->forMsg3);
851 #endif
852             }
853             /* Sending NACK in PHICH for failed UL TX */
854             else
855             {
856 #ifdef LTE_TDD
857                rgSCHUtlAddPhich (cellCb, frm, FALSE, nDmrs, rbStart, iPhich);
858 #else
859 #ifdef LTEMAC_HDFDD
860                if (ulAlloc->ue != NULLP && ulAlloc->ue->hdFddEnbld)
861                {
862                   rgSCHCmnHdFddChkNackAllow( cellCb, ulAlloc->ue, frm, &allwNack);
863                   /* Present implementaion of non-HDFDD does not send phich req
864                      incase of NACK. So commented this part to maintain same right
865                      now.*/
866
867                   if (allwNack)
868                   {
869                      rgSCHUtlAddPhich (cellCb, frm, FALSE, nDmrs, rbStart, ulAlloc->forMsg3);
870                   }
871                   else
872                   {
873                      rgSCHUtlAddPhich (cellCb, frm, TRUE, nDmrs, rbStart, ulAlloc->forMsg3);
874                   }
875                }
876                else
877                {
878                   rgSCHUtlAddPhich (cellCb, frm, FALSE, nDmrs, rbStart, ulAlloc->forMsg3);
879                }
880 #else
881                rgSCHUtlAddPhich (cellCb, frm, FALSE, nDmrs, rbStart, ulAlloc->forMsg3);
882 #endif/* LTEMAC_HDFDD */
883 #endif
884             }
885          }
886          ulAlloc = rgSCHUtlNextHqFdbkAlloc (cellCb, ulAlloc, idx);
887       }
888    }
889    RETVALUE(ROK);
890 } /* rgSCHUhmAppendPhich */
891
892 /**
893  * @brief This function initializes the DL HARQ Entity of UE.
894  *
895  * @details
896  *
897  *     Function: rgSCHUhmHqEntInit
898  *     Purpose:  This function initializes the UL HARQ Processes of 
899  *               UE control block. This is performed at the time
900  *               of creating UE control block.
901  *     
902  *     Invoked by: configuration module
903  *     
904  *  @param[in]  RgSchUeCb*    ueCb
905  *  @return  S16
906  *           -# ROK
907  *           -# RFAILED
908  *
909  **/
910 #ifdef ANSI
911 PUBLIC S16 rgSCHUhmHqEntInit
912 (
913 RgSchCellCb       *cellCb,
914 RgSchUeCb           *ueCb
915 )
916 #else
917 PUBLIC S16 rgSCHUhmHqEntInit(cellCb, ueCb)
918 RgSchCellCb       *cellCb;
919 RgSchUeCb           *ueCb;
920 #endif
921 {
922    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ueCb, cellCb);
923 #ifdef LTE_TDD   
924    Inst              inst = ueCb->cell->instIdx;
925 #endif
926    TRC2(rgSCHUhmHqEntInit)
927
928 #ifndef LTE_TDD
929    /* Init the HARQ processes */
930    ueUl->hqEnt.numHqPrcs = RGSCH_NUM_UL_HQ_PROC;
931 #else
932    /* Init the HARQ processes */
933    ueUl->hqEnt.numHqPrcs = 
934                         rgSchTddUlNumHarqProcTbl[ueCb->cell->ulDlCfgIdx];
935    if (rgSCHUtlAllocSBuf(inst, (Data **)&ueUl->hqEnt.hqProcCb, 
936                            ueUl->hqEnt.numHqPrcs * \
937                            sizeof(RgSchUlHqProcCb)) != ROK)
938    {
939       RETVALUE(RFAILED);
940    }
941 #endif
942
943    RETVALUE(ROK);
944 } /* rgSCHUhmHqEntInit */
945
946 #ifdef RG_5GTF
947 /**
948  * @brief This function gets an available HARQ process.
949  *
950  * @details
951  *
952  *     Function: rgSCHUhmGetAvlHqProc
953  *     Purpose:  This function returns an available HARQ process in 
954  *               the UL direction. All HARQ processes are maintained
955  *               in queues of free and inuse.
956  *
957  *               1. Check if the free queue is empty. If yes, return
958  *                  RFAILED
959  *               2. If not empty, update the proc variable with the
960  *                  first process in the queue. Return ROK.
961  *     
962  *     Invoked by: scheduler
963  *     
964  *  @param[in]  RgSchUeCb           *ue
965  *  @param[in]  CmLteTimingInfo  timingInfo
966  *  @param[out] RgSchDlHqProc       **hqP
967  *  @return  S16       
968  *         -#ROK     if successful
969  *         -#RFAILED otherwise
970  *
971  **/
972 #ifdef ANSI
973 PUBLIC S16 rgSCHUhmGetAvlHqProc
974 (
975 RgSchCellCb           *cell,
976 RgSchUeCb               *ue,
977 RgSchUlHqProcCb         **hqP
978 )
979 #else
980 PUBLIC S16 rgSCHUhmGetAvlHqProc (cell, ue, hqP)
981 RgSchCellCb           *cell;
982 RgSchUeCb             *ue;
983 RgSchUlHqProcCb       **hqP;
984 #endif
985 {
986    RgSchCmnUlCell    *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
987    RgSchCmnUlUe      *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
988    RgSchUlHqProcCb   *tmpHqProc;
989    CmLList           *tmp;
990    RgUeUlHqCb        *hqE;
991
992    TRC2(rgSCHUhmGetAvlHqProc);
993
994    hqE = &ueUl->hqEnt;
995  
996    CM_LLIST_FIRST_NODE(&(hqE->free), tmp);
997
998    if (NULLP == tmp)
999    {
1000       //RLOG_ARG3(L_ERROR,DBG_CELLID,cell->cellId,
1001        //                "rgSCHUhmGetAvlHqProc free %ld inUse %ld ue %d"
1002         //                                   , hqE->free.count, hqE->inUse.count, ue->ueId);
1003       //printf("5GTF_ERROR rgSCHUhmGetAvlHqProc cellId %d  %ld inUse %ld ue %d"
1004                               //, cell->cellId, hqE->free.count, hqE->inUse.count, ue->ueId);
1005       /* No Harq Process available in the free queue. */
1006       RETVALUE(RFAILED);
1007    }
1008
1009    tmpHqProc = (RgSchUlHqProcCb *)(tmp->node);
1010
1011    /* Remove the element from the free Queue */
1012    cmLListDelFrm(&hqE->free, tmp);
1013
1014    /* Add the element into the inUse Queue as well */
1015    cmLListAdd2Tail(&hqE->inUse, &tmpHqProc->lnk);
1016
1017 #ifdef UL_ADPT_DBG 
1018          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);
1019 #endif         
1020    tmpHqProc->schdTime = cellUl->schdTime;
1021
1022    *hqP = tmpHqProc;
1023    
1024    RETVALUE(ROK);
1025 } /* rgSCHUhmGetAvlHqProc */
1026
1027 /**
1028  * @brief Handler for identifying the HARQ process cb associated with the
1029  * TX Time.
1030  *
1031  * @details
1032  *
1033  *     Function: rgSCHUhmGetUlProcByTime 
1034  *     
1035  *     Processing Steps: 
1036  *      - Return pointer to uplink harq process corresponding to the timing
1037  *        information passed.
1038  *           
1039  *  @param[in]  *ue
1040  *  @param[in]  idx
1041  *  @return  RgSchUlHqProcCb*
1042  *      -# Pointer to harq process corresponding to index
1043  *      -# NULL
1044  **/
1045 #ifdef ANSI
1046 PUBLIC RgSchUlHqProcCb* rgSCHUhmGetUlProcByTime 
1047 (
1048 RgSchCellCb      *cell,
1049 RgSchUeCb        *ue, 
1050 CmLteTimingInfo  frm
1051 )
1052 #else
1053 PUBLIC RgSchUlHqProcCb* rgSCHUhmGetUlProcByTime(cell, ue, frm)
1054 RgSchCellCb      *cell;
1055 RgSchUeCb        *ue; 
1056 CmLteTimingInfo  frm;
1057 #endif
1058 {
1059    RgSchCmnUlUe *ueUl = RG_SCH_CMN_GET_UL_UE(ue, cell);
1060    CmLListCp    *lst = &ueUl->hqEnt.inUse;
1061    CmLList      *lnk = lst->first;
1062    RgSchUlHqProcCb   *proc;
1063
1064    TRC2(rgSCHUhmGetUlProcByTime);
1065
1066    while (lnk)
1067    {
1068       proc = (RgSchUlHqProcCb *)(lnk->node);
1069       lnk = lnk->next;
1070       //   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);
1071       if (RGSCH_TIMEINFO_SAME(proc->schdTime, frm))
1072       {
1073         // printf("Harq timing Matched rgSCHUhmGetUlProcByTime time (%d %d) proc->procId %d \n",proc->schdTime.sfn,proc->schdTime.slot, proc->procId);
1074          RETVALUE(proc);
1075       }
1076    }
1077
1078    RETVALUE(NULLP);
1079 }  /* rgSCHUhmGetUlProcByTime */
1080 #endif
1081
1082
1083 /**********************************************************************
1084  
1085          End of file
1086 **********************************************************************/