1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
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 #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
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 *******************************************************************************/
19 /************************************************************************
25 Desc: C source code for Entry point fucntions
29 **********************************************************************/
32 @brief APIs related to Downlink HARQ.
35 static const char* RLOG_MODULE_NAME="MAC";
36 static int RLOG_FILE_ID=279;
37 static int RLOG_MODULE_ID=4096;
38 /* header include files -- defines (.h) */
39 #include "common_def.h"
47 #include "rg_sch_inf.h"
51 #include "du_app_mac_inf.h"
53 /* header/extern include files (.x) */
61 #include "rg_sch_inf.x"
62 #include "rg_prg.x" /* PRG interface typedefs */
69 #include "ss_msg.x" /* MAC includes */
71 // S16 ssGetDBufOfSize(Region region,Size size,Buffer **dBuf);
72 //void prc_trace_format_string(UINT32 group_mask, UINT16 level, const char *format, ...);
78 S16 SIncMsgRef(Buffer *srcBuf,Region dstRegion, Pool dstPool,Buffer **dstBuf);
80 static Void rgDHMBldTfuDatReq ARGS((RgCellCb *cellCb, RgDlSf *dlSf, RgDlHqProcCb *hqP,
81 RgTfuDatReqPduInfo *datReq));
92 /* forward references */
95 * @brief This function initializes the DL HARQ Entity of UE
99 * Function: rgDHMHqEntInit
100 * Purpose: This function initializes the DL HARQ entity of
101 * UE control block. This is performed at the time
102 * of creating UE control block.
104 * Invoked by: configuration module
106 * @param[in] Inst inst
107 * @param[in] RgCellCb* cell
108 * @param[in] RgUeCb* ue
114 S16 rgDHMHqEntInit(Inst inst, RgDlHqEnt *hqE, uint8_t maxHqProcs)
118 Buffer *hdrDBuf = NULLP;
119 Buffer *ceDBuf = NULLP;
122 hqE->numHqProcs = maxHqProcs;
123 /* for each harq process */
124 for (idx1 = 0; idx1 < hqE->numHqProcs; idx1++)
126 if (rgAllocSBuf(inst,(Data **)&(hqE->procs[idx1]),sizeof(RgDlHqProcCb)) != ROK)
130 rgFreeSBuf(inst,(Data **)&(hqE->procs[idx1]), sizeof(RgDlHqProcCb));
132 RLOG0(L_ERROR, "Memory Alloc Failure for RgDlHqProcCb");
136 hqE->procs[idx1]->procId = idx1;
137 for(idx2 = 0; idx2 < RG_MAX_TB_PER_UE; idx2++)
140 hqE->procs[idx1]->tbInfo[idx2].tb = NULLP;
143 /* L2 optimization for mUe/Tti: Allocating buffers for macHdr, macCes
144 * and macPadding. These buffers shall not be released by MAC/CL.
145 * However, Only rPtr and wPtr will be reset while release of hq proc
147 tmpMBuf = hqE->procs[idx1]->tbInfo[idx2].tb.macHdr;
148 rgGetMsg(inst, &tmpMBuf);
149 RG_ADD_DBuf(hdrDBuf, RG_MAC_HDR_SIZE, tmpMBuf);
150 hqE->procs[idx1]->tbInfo[idx2].tb.macHdr = tmpMBuf;
151 macHeader[idx2] = MacPtrAddress;
153 tmpMBuf = hqE->procs[idx1]->tbInfo[idx2].tb.macCes;
154 rgGetMsg(inst, &tmpMBuf);
155 RG_ADD_DBuf(ceDBuf, RG_MAC_CE_SIZE, tmpMBuf);
156 hqE->procs[idx1]->tbInfo[idx2].tb.macCes = tmpMBuf;
158 hqE->procs[idx1]->tbInfo[idx2].tb.padSize = 0;
161 hqE->procs[idx1]->tbId[idx2] = RGU_INVALID_TBID;
165 cmLListInit(&hqE->savedProcLst[idx1]);
170 } /* rgDHMHqEntInit */
173 * @brief This function releases a HARQ process
177 * Function: rgDHMUeReset
178 * Purpose: This function resets TB in each HarqProc.
180 * Invoked by: CFG UE Reset
182 * @param[in] RgDlHqProc *hqP
186 Void rgDHMUeReset(RgCellCb *cell, RgDlHqEnt *hqE)
192 /* Free all the TB memory associated with HARQ */
193 for (i=0; i < hqE->numHqProcs; i++)
195 rgDHMRlsHqProcTB(cell, hqE->procs[i], 1);
196 rgDHMRlsHqProcTB(cell, hqE->procs[i], 2);
199 rgDHMFreeSavedHqP((cell->macInst - RG_INST_START), hqE, i);
207 * @brief This function defers shared memory buffer
208 * freeing out of the critical RT path.
212 * Function: rgDHMHdlBufFree
213 * Purpose: To defer shared memory freeing post
214 * critical path. Defer as many if defer queue
215 * is full then release instantly.
217 * Invoked by: HARQ TB Release.
222 Void rgDHMHdlBufFree(Inst inst, Buffer **mBuf)
224 RgCb *rgCbP = &rgCb[inst];
226 if (rgCbP->bufCnt < RG_MAX_DFRD_FREE_BUFS)
230 rgCbP->bufToFree[rgCbP->bufCnt] = *mBuf;
242 * @brief This function is called to release the
243 * shared memory of the HARQ TBs outside
244 * the critical RT path.
248 * Function: rgDHMFreeTbBufs
249 * Purpose: This function is called to release the
250 * shared memory of the HARQ TBs outside
251 * the critical RT path.
253 * 1. Job of releasing TBs is shared across TTIs
254 * Invoked by: MAC every TTI
259 Void rgDHMFreeTbBufs(Inst inst)
261 RgCb *rgCbP = &rgCb[inst];
262 uint8_t start = rgCbP->bufCnt;
265 if (rgCbP->bufCnt < RG_MAX_FREE_BUFS_PERTTI)
271 end = rgCbP->bufCnt - RG_MAX_FREE_BUFS_PERTTI;
276 SPutMsg(rgCbP->bufToFree[start]);
280 } /* rgDHMFreeTbBufs */
282 Void rgDHMFreeAllTbBufs(Inst inst)
284 RgCb *rgCbP = &rgCb[inst];
285 uint8_t start = rgCbP->bufCnt;
291 SPutMsg(rgCbP->bufToFree[start]);
295 } /* rgDHMFreeTbBufs */
299 * @brief This function releases a HARQ process
303 * Function: rgDHMRlsHqProcTB
304 * Purpose: This function returns a HARQ process to HARQ Entity
305 * in the DL direction.
307 * 1. Add the HARQ process to the free queue.
308 * Invoked by: scheduler and HARQ processing
310 * @param[in] RgDlHqProc *hqP
314 S16 rgDHMRlsHqProcTB(RgCellCb *cell, RgDlHqProcCb *hqP, uint8_t tbIndex)
318 RgTfuDatReqTbInfo *tb; /* TB to be sent to CL/PHY*/
319 // uint32_t lchIdx, pduIdx;
322 if((tbIndex > RG_MAX_TB_PER_UE) ||
328 hqP->tbInfo[tbIndex-1].numSchLch = 0;
330 if (hqP->tbInfo[tbIndex-1].tb)
332 rgDHMHdlBufFree(cell->macInst - RG_INST_START, &hqP->tbInfo[tbIndex-1].tb);
335 /* L2 Optimization for mUe/Tti: macHdr, macCes and macPad mBuf pointers
336 * shall not be released. However, Inorder to release harq info/TB info,
337 * just Resetting rPtr and wPtr of these mbufs to db_base
339 tb = &(hqP->tbInfo[tbIndex-1].tb);
340 if (tb->tbPres == TRUE)
345 hqP->tbInfo[tbIndex-1].schdTa.pres = FALSE;
347 hqP->tbInfo[tbIndex -1].sCellActCe.pres = FALSE;
350 /* Decrementing might lead to roundoff error in case of say UE reset
351 * where all the HqProcs irrespective whether in use are called for rls.
352 * Hence to avoid the same shift operator is being used. */
353 hqP->numOfTBs = hqP->numOfTBs >> 1;
354 for(idx = 0; idx < 2; idx++)
356 if (hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk.node != NULLP)
358 cmLListDelFrm(&hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sf->tbs,
359 &(hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk));
360 hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk.node = (PTR)NULLP;
361 printf("\nrgDHMRlsHqProcTB:: hqP %p \n", (Void *)hqP);
363 hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sf = NULLP;
365 /* Fix : syed It is better to reset these feilds
366 * corruption avoidance */
367 hqP->tbInfo[tbIndex-1].tbSz = 0;
368 hqP->tbInfo[tbIndex-1].contResCe = NOTPRSNT;
369 hqP->tbInfo[tbIndex-1].contResId = NULLP;
372 } /* rgDHMRlsHqProc */
375 * @brief This function gets HARQ process with the given Id
379 * Function: rgDHMGetHqProcFrmId
380 * Purpose: This function returns the HARQ process with the given ID.
383 * @param[in] RgUeCb *ue
384 * @param[in] uint8_t idx
385 * @param[in] RgDlHqProc **hqP
387 * -# ROK if successful
388 * -# RFAILED otherwise
391 S16 rgDHMGetHqProcFrmId(RgUeCb *ue, uint8_t idx, RgDlHqProcCb **hqP)
393 /* Pick the proc based on the index provided */
394 *hqP = (ue->dl.hqEnt.procs[idx]);
397 } /* rgDHMGetHqProcFrmId */
399 /*static uint32_t dataAvl; */
401 * @brief Handler for sending data to PHY
405 * Function : rgDHMSndDatReq
407 * This function shall send the MAC PDU built for the UE to TOM
408 * when invoked as part of TTI processing and keep track of the number of
409 * transmissions for this TB.
412 * @param[in] RgCellCb *cell
413 * @param[in] RgDlHqProcCb *hqE
414 * @param[out] RgErrInfo *err
423 RgTfuDatReqInfo *datInfo,
429 Inst inst = cellCb->macInst - RG_INST_START;
430 RgTfuDatReqPduInfo *datReq;
432 /*Added this variable to figure out that whether this UE data
433 has to be inclueded in the TFU Data request.*/
437 for(i=0;i< RG_MAX_TB_PER_UE;i++)
439 /* printf("\nDHMSndDatReq1: Rnti %d dlSfSchdTime(sfn sf) : (%d %d)\n"
440 "macCell(sfn sf): (%d %d) tbTimingInfo(sfn sf): (%d %d)\n"
441 "dlSf %p dlSf->tbs.count %d hqp %p tb %p\n",
442 hqP->tbInfo[i].pdcch.rnti,
443 dlSf->schdTime.sfn, dlSf->schdTime.slot,
444 cellCb->crntTime.sfn, cellCb->crntTime.slot,
445 hqP->tbInfo[i].timingInfo.sfn,
446 hqP->tbInfo[i].timingInfo.slot,
447 (Void *)dlSf, dlSf->tbs.count,
449 (Void *)hqP->tbInfo[i].tb);*/
450 /* Mukesh :: in case of rpepetiton this is not rerd*/
451 if (hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf == dlSf)
453 /* Check if data from RLC had been received and got muxed. */
455 if (hqP->tbInfo[i].tb == NULLP)
457 if (!(hqP->tbInfo[i].tb.tbPres))
461 if (hqP->tbInfo[i].schdTa.pres == TRUE ||
462 hqP->tbInfo[i].contResCe == PRSNT_NODEF)
464 if ((hqP->tbInfo[i].schdTa.pres == TRUE) ||
465 (hqP->tbInfo[i].contResCe == PRSNT_NODEF) ||
466 (hqP->tbInfo[i].sCellActCe.pres == TRUE))
469 /* Data not received but ta needs to be sent. */
470 /* MUX TA and send it */
471 bldPdu.datReq = NULLP;
472 //bldPdu.reqType = EVENT_SLOT_IND_TO_MAC;
473 bldPdu.schdTbSz = hqP->tbInfo[i].tbSz;
474 bldPdu.ta = hqP->tbInfo[i].schdTa;
476 bldPdu.sCellActCe= hqP->tbInfo[i].sCellActCe;
478 /* changes for CR timer implementation*/
479 bldPdu.contResId = hqP->tbInfo[i].contResId;
480 if (ROK != rgMUXBldPdu(inst,&bldPdu, &(hqP->tbInfo[i].tb), err))
482 RLOG1(L_ERROR, "MUXing failed for: MacInst %d", inst);
483 RLOG4(L_ERROR, "MUXing failed for: time: %d/%d\
484 procId %d ueId %d", hqP->tbInfo[i].timingInfo.sfn,
485 hqP->tbInfo[i].timingInfo.slot, hqP->procId,
486 hqP->tbInfo[i].pdcch.rnti);
493 #ifdef LTEMAC_RGU_PAD
494 /* Data not received from RLC. Padding at MAC */
495 bldPdu.datReq = NULLP;
496 //bldPdu.reqType = EVENT_SLOT_IND_TO_MAC;
497 bldPdu.schdTbSz = hqP->tbInfo[i].tbSz;
498 bldPdu.ta = hqP->tbInfo[i].schdTa;
500 bldPdu.sCellActCe= hqP->tbInfo[i].sCellActCe;
503 bldPdu.contResId = NULLP;
505 if (ROK != rgMUXBldPdu(inst,&bldPdu, &(hqP->tbInfo[i].tb), err))
507 RLOG1(L_ERROR, "MUXing failed for: MacInst %d", inst);
508 RLOG4(L_ERROR, "MUXing failed for: time: %d/%d\
509 procId %d ueId %d", hqP->tbInfo[i].timingInfo.sfn,
510 hqP->tbInfo[i].timingInfo.slot, hqP->procId,
511 hqP->tbInfo[i].pdcch.rnti);
516 /*Padding is not done so data for this UE will not be
531 /*If Data/Padding is not available for UE, then we can not include
532 any Data for this UE in TFU Data Request.*/
535 /*Free up the HARQ process for this allocation.*/
536 /* Release First TB, as this would be anyway there*/
537 rgDHMRlsHqProcTB(cellCb, hqP, 1);
538 if(2 == hqP->numOfTBs)
540 rgDHMRlsHqProcTB(cellCb, hqP, 2);
546 if (rgGetEventMem(inst,(Ptr *)&datReq, sizeof(TfuDatReqPduInfo),
547 &(datInfo->memCp)) != ROK)
551 /* Fill the TFU Dat Req with information from Harq Proc */
553 rgDHMBldTfuDatReq(cellCb, dlSf, hqP, datReq);
555 /* MS_WORKAROUND for ccpu00122894 */
556 for(i=0;i< RG_MAX_TB_PER_UE;i++)
558 if (hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf == dlSf)
560 cmLListDelFrm(&dlSf->tbs, &(hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk));
561 hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk.node = NULLP;
564 hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf = NULLP;
567 cmLListAdd2Tail(&datInfo->pdus, &(datReq->lnk));
568 datReq->lnk.node = (PTR)datReq;
571 } /* rgDHMSndDatReq */
574 * @brief Function to handle RGU datReq received from ROM
578 * Function : rgDHMHndlDedDatReq
580 * This function shall act on the datReq received on RGU. It shall
581 * store the data IDs for all the logical channels and get the MAC
585 * @param[in] Inst inst
586 * @param[in] RgDlHqProcCb *hqProc
587 * @param[in] RgRguDedDatReq *datReq
588 * @param[out] RgErrInfo *err
593 S16 rgDHMHndlDedDatReq
596 RgDlHqProcCb *hqProc,
597 RgRguDDatReqPerUe *datReq,
608 RgTfuDatReqTbInfo *tb;
612 tbIndex = (uint8_t)(datReq->transId & 0x03);
613 /* Accept all the data requests even if delayed in case nothing
614 * has been sent earlier on the harq proc.
616 if((datReq->nmbOfTbs > RG_MAX_TB_PER_UE) ||
619 /* release corresponding TBs from SF tbs List */
620 for(j=0;j<datReq->nmbOfTbs;j++)
622 if (!(tbIndex & (j+1)))
626 rgDHMRlsHqProcTB(rgCb[inst].cell, hqProc, (uint8_t)(j+1));
631 for(i=0;i<datReq->nmbOfTbs;i++)
633 /* tbIndex 01 corresponds to presence of 1st TB
634 * 10 corresponds 2nd TB
635 * 11 corresponds two TBs of UE */
636 if (!(tbIndex & (i+1)))
640 if (hqProc->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk.node == NULLP)
642 /* release corresponding TBs from SF tbs List */
643 for(j=0;j<datReq->nmbOfTbs;j++)
645 if (!(tbIndex & (j+1)))
649 rgDHMRlsHqProcTB(rgCb[inst].cell, hqProc, (uint8_t)(j+1));
650 printf("\nrgDHMHndlDedDatReq:: hqP %p \n", (Void *)hqProc);
656 RG_FREE_MSG(hqProc->tbInfo[i].tb);
657 /* L2 optimization for mUe/Tti: Pre-allocated mBuf pointers(macHdr,
658 * macCes and MacPad) of harq TB need to be reset to db_base
661 tb = &hqProc->tbInfo[i].tb;
662 if (tb->tbPres == TRUE)
667 bldPdu.datReq = datReq;
668 bldPdu.reqType = EVTRGUDDATREQ;
669 bldPdu.schdTbSz = hqProc->tbInfo[i].tbSz;
670 bldPdu.tbIndex = i+1;
671 bldPdu.ta = hqProc->tbInfo[i].schdTa;
673 bldPdu.sCellActCe= hqProc->tbInfo[i].sCellActCe;
675 bldPdu.contResId = NULLP;
677 /* Store tbId from RLC in DDatRequest */
678 hqProc->tbId[i] = datReq->datReqTb[i].tbId;
681 hqProc->status[i] = FALSE;
683 if(rgMUXBldPdu(inst,&bldPdu, &(hqProc->tbInfo[i].tb), err) != ROK)
685 RLOG1(L_ERROR, "MUXing failed for: MacInst %d", inst);
686 RLOG4(L_ERROR, "MUXing failed for: time: %d/%d\
687 procId %d ueId %d", hqProc->tbInfo[i].timingInfo.sfn,
688 hqProc->tbInfo[i].timingInfo.slot, hqProc->procId,
689 hqProc->tbInfo[i].pdcch.rnti);
691 /* release corresponding TBs from SF tbs List */
692 for(j=0;j<datReq->nmbOfTbs;j++)
694 if (!(tbIndex & (j+1)))
698 rgDHMRlsHqProcTB(rgCb[inst].cell, hqProc, (uint8_t)(j+1));
703 SFndLenMsg(hqProc->tbInfo[i].tb, &len);
707 } /* rgDHMHndlDedDatReq */
710 * @brief Function to handle RGU datReq received from ROM
714 * Function : rgDHMHndlCmnDatReq
716 * This function shall act on the datReq received on RGU. It shall
717 * store the data IDs for all the logical channels and get the MAC
721 * @param[in] Inst inst
722 * @param[in] RgDlHqProcCb *hqProc
723 * @param[in] RgRguCmnDatReq *datReq
724 * @param[out] RgErrInfo *err
729 S16 rgDHMHndlCmnDatReq
732 RgDlHqProcCb *hqProc,
733 RgRguCmnDatReq *datReq,
741 if (hqProc->tbInfo[0].tb != NULLP)
743 /* If numLch is non zero means HQ Proc is busy*/
744 if (hqProc->tbInfo[0].tb.tbPres)
747 /* datReq discarded. Generate an alarm */
748 rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_HARQ);
749 rgLMMStaInd(inst,LCM_CATEGORY_PROTOCOL, LCM_EVENT_UI_INV_EVT,
750 LRG_CAUSE_HQ_PROC_BUSY, &dgn);
754 bldPdu.datReq = datReq;
755 bldPdu.reqType = EVTRGUCDATREQ;
756 bldPdu.schdTbSz = hqProc->tbInfo[0].tbSz;
757 bldPdu.ta = hqProc->tbInfo[0].schdTa;
759 bldPdu.sCellActCe= hqProc->tbInfo[0].sCellActCe;
762 bldPdu.contResId = hqProc->tbInfo[0].contResId;
764 if(rgMUXBldPdu(inst,&bldPdu, &(hqProc->tbInfo[0].tb), err) != ROK)
766 RLOG1(L_ERROR, "MUXing failed for: MacInst %d", inst);
767 RLOG4(L_ERROR, "MUXing failed for: time: %d/%d\
768 procId %d ueId %d", hqProc->tbInfo[0].timingInfo.sfn,
769 hqProc->tbInfo[0].timingInfo.slot, hqProc->procId,
770 hqProc->tbInfo[0].pdcch.rnti);
772 RG_FREE_MSG(datReq->pdu);
777 } /* rgDHMHndlCmnDatReq */
780 * @brief Function to get consolidate grants and send consolidated grant to RLC
784 * Function : rgDHMSndConsolidatedStaInd
786 * This function shall be invoked by Scheduler to trigger DHM to send a
787 * consolidated status indication of all UE scheduled in a TTI as well as
788 * send consolidated CStaInd for MSG4 and for all common channels(PCCH,
789 * if RGR_SI_SCH is not defined then it includes BCH and BCCH also)
792 * @param[in] RgCellCb *cell
793 * @param[in] RgInfUeInfo *ueInfo,
794 * @param[in] CmLteTimingInfo timingInfo,
795 * @param[out] RgErrInfo err
796 * @param[in] RguCStaIndInfo *cStaInd
802 S16 rgDHMSndConsolidatedStaInd
806 CmLteTimingInfo timingInfo,
810 SuId rguDlSpId;/*need to use spID instead of suID*/
814 uint8_t tbIndex=0,idx1;
815 RgDlSf *dlSf = &cell->subFrms[(timingInfo.slot % RG_NUM_SUB_FRAMES)];
816 Inst inst = cell->macInst - RG_INST_START;
817 // Bool isDStaReqrd = FALSE;
818 RgRguDedStaInd *dStaInd[rgCb[inst].numRguSaps] ;
819 RgUpSapCb *rguDlSap[rgCb[inst].numRguSaps];
824 RgInfUeAlloc *allocInfo;
825 uint8_t activeSapCnt = 0;
826 uint8_t staIndCnt = 0;
828 Bool hqPAdded = FALSE;
831 RgTfuDatReqTbInfo *tb; /* TB to be sent to CL/PHY*/
834 memset (dStaInd, 0, (sizeof(RgRguDedStaInd *) * rgCb[inst].numRguSaps));
835 memset (rguDlSap, 0, (sizeof(RgUpSapCb *) * rgCb[inst].numRguSaps));
837 /* Send StaInd for the scheduled UEs */
838 for(ueIdx = 0; ueIdx < ueInfo->numUes; ueIdx++)
843 if((ue=rgDBMGetUeCb (cell, ueInfo->allocInfo[ueIdx].rnti)) == NULLP)
845 /* Check in RachLst */
846 if((ue=rgDBMGetUeCbFromRachLst (cell,
847 ueInfo->allocInfo[ueIdx].rnti)) == NULLP)
849 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"CRNTI:%d No ueCb found",
850 ueInfo->allocInfo[ueIdx].rnti);
851 /*Fix: If one UE is not present dont return, look for the next.*/
857 rgDHMGetHqProcFrmId(ue,ueInfo->allocInfo[ueIdx].hqProcId,&hqP);
858 allocInfo = &ueInfo->allocInfo[ueIdx];
861 /* Fix : syed Avoid sending data for a RETX
862 * if initial TX data processing was unsuccessful */
863 if((allocInfo->tbInfo[0].isReTx == TRUE) &&
864 (hqP->tbInfo[0].tbSz == 0))
866 RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
867 "CRNTI:%d RETX hqP(%d) tb(0) for a failed New Tx",
868 allocInfo->rnti, hqP->procId);
871 if((allocInfo->tbInfo[1].isReTx == TRUE) &&
872 (hqP->tbInfo[1].tbSz == 0))
874 RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
875 "CRNTI:%d RETX hqP(%d) tb(1) for a failed New Tx",
876 allocInfo->rnti, hqP->procId);
880 if(ue->rguDlSap != NULLP)
882 rguDlSpId = ue->rguDlSap->sapCfg.spId;
884 {/* UeCb is from rachList */
885 rguDlSpId = cell->rguDlSap->sapCfg.spId;
889 for(idx=allocInfo->tbStrtIdx;((idx-allocInfo->tbStrtIdx) <\
890 allocInfo->nmbOfTBs); idx++)
892 RguCStaIndInfo *cStaInd;
894 /* LTE_ADV_FLAG_REMOVED_START */
895 hqP->tbInfo[idx].isEnbSFR = allocInfo->isEnbSFR;
896 /* update pA value */
897 hqP->tbInfo[idx].pa = allocInfo->pa;
898 /* LTE_ADV_FLAG_REMOVED_END */
901 hqP->numOfTBs = allocInfo->nmbOfTBs;
902 hqP->tbInfo[idx].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk.node = (PTR)hqP;
903 hqP->tbInfo[idx].sfLnkInfo[dlSf->schdTime.slot % 2].sf = dlSf;
904 cmLListAdd2Tail(&dlSf->tbs,&(hqP->tbInfo[idx].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk));
905 /* Changes as part of performance testing*/
906 /* hqP->numOfTBs++;*/
907 hqP->tbInfo[idx].doa = allocInfo->doa;
908 hqP->tbInfo[idx].txMode = allocInfo->txMode;
909 hqP->tbInfo[idx].puschRptUsd = allocInfo->puschRptUsd;
910 hqP->tbInfo[idx].puschPmiInfo = allocInfo->puschPmiInfo;
912 hqP->tbInfo[idx].pdcch.rnti = allocInfo->pdcchRnti;
914 hqP->tbInfo[idx].pdcch.rnti = allocInfo->rnti;
916 if(allocInfo->tbInfo[idx].isReTx == TRUE)
918 hqP->tbInfo[idx].pdcch.dci = allocInfo->dciInfo;
922 hqP->tbInfo[idx].timingInfo = timingInfo;
923 hqP->tbInfo[idx].pdcch.dci = allocInfo->dciInfo;
925 RG_FREE_MSG(hqP->tbInfo[idx].tb);
927 /* L2 optimization for mUe/Tti: Pre-allocated mBuf pointers(macHdr,
928 * macCes and MacPad) of harq TB need to be reset to db_base
930 tb = &(hqP->tbInfo[idx].tb);
931 if (tb->tbPres == TRUE)
936 hqP->tbInfo[idx].tbSz = allocInfo->tbInfo[idx].schdTbSz;
938 hqP->tbInfo[idx].schdTa.pres = allocInfo->tbInfo[idx].ta.pres;
939 hqP->tbInfo[idx].schdTa.val = allocInfo->tbInfo[idx].ta.val;
942 hqP->tbInfo[idx].sCellActCe.pres = allocInfo->tbInfo[idx].sCellActCe.pres;
943 hqP->tbInfo[idx].sCellActCe.val = allocInfo->tbInfo[idx].sCellActCe.val;
947 if(( hqPAdded == TRUE) || (ROK == rgLaaPushHqPToScellLst(allocInfo,cell,timingInfo)))
953 if (allocInfo->tbInfo[idx].schdDat[0].lcId == RG_CCCH_LCID)
956 RG_FREE_MSG(hqP->tbInfo[idx].tb);
958 /* L2 optimization for mUe/Tti: Pre-allocated mBuf pointers(macHdr,
959 * macCes and MacPad) of harq TB need to be reset to db_base
961 tb = &(hqP->tbInfo[idx].tb);
963 if (tb->tbPres == TRUE)
968 hqP->tbInfo[0].contResCe = allocInfo->tbInfo[0].contResCe;
969 if(allocInfo->tbInfo[0].contResCe)
971 hqP->tbInfo[0].contResId = &ue->contResId;
975 if(allocInfo->tbInfo[idx].numSchLch == 0)
977 RLOG_ARG2(L_DEBUG,DBG_CELLID,cell->cellId,
978 "UEID:%d MSG4 with only contResId hqP(%d)",
981 hqP->tbInfo[idx].numSchLch = 0;
985 /* Increamenting the tbIndex instead of
986 assigning it to constant */
990 hqP->tbInfo[idx].numSchLch = 1;
991 hqP->tbInfo[idx].schdData[0].lcId =
992 allocInfo->tbInfo[idx].schdDat[0].lcId;
993 hqP->tbInfo[idx].schdData[0].schdSz =
994 allocInfo->tbInfo[idx].schdDat[0].numBytes;
996 // if(cStaInd == NULLP)
998 if ((rgAllocShrablSBuf(inst,(Data**)&cStaInd, sizeof(RguCStaIndInfo))) != ROK)
1000 err->errType = RGERR_DHM_SND_STA_IND;
1001 err->errCause = RG_DHM_MEM_ALLOC_FAIL;
1006 idx1 = (hqP->procId << 2) | tbIndex;
1008 cStaInd->cellId = cell->cellId;
1009 cStaInd->rnti = allocInfo->rnti;
1010 cStaInd->lcId = cell->dlCcchId;
1011 cStaInd->transId = (timingInfo.sfn << 16) |
1012 (timingInfo.slot << 8) | idx1;
1013 /* ADD Changes for Downlink UE Timing Optimization */
1014 #ifdef LTEMAC_DLUE_TMGOPTMZ
1015 dlSf->remDatReqCnt++;
1017 RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,
1018 "RNTI:%d UE:MSG4 grant for CCCH hqP(%d) LCID:%d",
1022 /* Fix : syed Avoid return param for interface prim and
1023 * proceed for other UEs. For the failed UE, MAC shall
1025 rgUIMSndCmnStaInd(cell->macInst,cell->rguDlSap,cStaInd);
1032 RG_FREE_MSG(hqP->tbInfo[idx].tb);
1034 /* L2 optimization for mUe/Tti: Pre-allocated mBuf pointers(macHdr,
1035 * macCes and MacPad) of harq TB need to be reset to db_base
1037 tb = &(hqP->tbInfo[idx].tb);
1038 if (tb->tbPres == TRUE)
1044 if((NULLP == dStaInd[rguDlSpId]) && (allocInfo->tbInfo[idx].numSchLch))
1046 if ((rgAllocShrablSBuf (inst,(Data**)&dStaInd[rguDlSpId], sizeof(RguDStaIndInfo))) != ROK)
1048 err->errType = RGERR_DHM_SND_STA_IND;
1049 err->errCause = RG_DHM_MEM_ALLOC_FAIL;
1050 /* Need to return as memory allocation will fail for other UEs also*/
1053 dStaInd[rguDlSpId]->nmbOfUeGrantPerTti = 0;
1054 rguDlSap[rguDlSpId] = ue->rguDlSap;
1059 lcIdx < allocInfo->tbInfo[idx].numSchLch; lcIdx++)
1061 hqP->tbInfo[idx].schdData[lcIdx].lcId =
1062 allocInfo->tbInfo[idx].schdDat[lcIdx].lcId;
1063 if (hqP->tbInfo[idx].schdData[lcIdx].lcId == 0)
1065 RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
1066 "CCCH grant in DStaInd for LCID:%d CRNTI:%d",
1067 hqP->tbInfo[idx].schdData[lcIdx].lcId,allocInfo->rnti);
1069 hqP->tbInfo[idx].schdData[lcIdx].schdSz =
1070 allocInfo->tbInfo[idx].schdDat[lcIdx].numBytes;
1071 if(dStaInd[rguDlSpId])
1073 dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].staIndTb[idx].\
1074 lchStaInd[lcIdx].lcId = allocInfo->tbInfo[idx].\
1075 schdDat[lcIdx].lcId;
1076 dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].staIndTb[idx].\
1077 lchStaInd[lcIdx].totBufSize = allocInfo->tbInfo[idx].\
1078 schdDat[lcIdx].numBytes;
1081 lchBufSize+=allocInfo->tbInfo[idx].schdDat[lcIdx].numBytes;
1083 hqP->tbInfo[idx].numSchLch =
1084 allocInfo->tbInfo[idx].numSchLch;
1085 if(dStaInd[rguDlSpId])
1087 dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].staIndTb[idx].nmbLch =
1088 allocInfo->tbInfo[idx].numSchLch;
1090 dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].staIndTb[idx].tbId =
1097 //if((dStaInd) && (tbIndex) && (isDStaReqrd == TRUE))
1098 if((dStaInd[rguDlSpId]) && (tbIndex))
1100 idx1 = (hqP->procId << 2) | tbIndex;
1101 /* Create RguDStaInd struct and send to UIM */
1102 dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].rnti = allocInfo->rnti;
1104 dStaInd->transId = (hqP->timingInfo.sfn << 16) |
1105 (hqP->timingInfo.slot << 8) | hqP->procId;
1107 dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].transId = (timingInfo.sfn << 16) |
1108 (timingInfo.slot << 8) | idx1;
1109 dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].nmbOfTbs = hqP->numOfTBs;
1111 dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].fillCtrlPdu = allocInfo->fillCtrlPdu;
1113 /*increment num of UE as staInd is prepared for it */
1114 dStaInd[rguDlSpId]->nmbOfUeGrantPerTti++;
1115 /* ADD Changes for Downlink UE Timing Optimization */
1116 #ifdef LTEMAC_DLUE_TMGOPTMZ
1117 dlSf->remDatReqCnt++;
1120 //isDStaReqrd = FALSE;
1124 for(idx = 0; idx < rgCb[inst].numRguSaps ; idx++)
1126 if(dStaInd[idx] != NULLP)
1128 dStaInd[idx]->cellId = cell->cellId;
1129 /* Fix : syed Avoid return param for interface prim and
1130 * proceed for other UEs. For the failed UE, MAC shall
1132 rgUIMSndDedStaInd(inst,rguDlSap[idx],dStaInd[idx]);
1135 if(staIndCnt == activeSapCnt)
1136 break;/* all valid staind are considered */
1141 } /* rgDHMSndConsolidatedStaInd */
1145 * @brief Function to handle building the TFU Data Request
1149 * Function : rgDHMBldTfuDatReq
1151 * This function builds the TFU Data Request with the details
1152 * present in HARQ Process.
1154 * @param[in] RgDlHqProcCb *hqP
1155 * @param[out] TfuDatReqPduInfo *datReq
1159 //uint8_t crashFlag = 0;
1160 static Void rgDHMBldTfuDatReq
1165 RgTfuDatReqPduInfo *datReq
1170 #if !(!(defined TENB_ACC) && !(defined LTE_PAL_ENB))
1172 #elif defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD)
1180 uint32_t lchIdx, pduIdx;
1183 datReq->nmbOfTBs = 0;
1185 #if !(!(defined TENB_ACC) && !(defined LTE_PAL_ENB))
1186 inst = cellCb->macInst - RG_INST_START;
1187 #elif defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD)
1188 inst = cellCb->macInst - RG_INST_START;
1191 /*MS_WORKAROUND for ccpu00123904*/
1192 datReq->isTApres = FALSE;
1193 #ifdef TFU_ALLOC_EVENT_NO_INIT
1195 datReq->mBuf[0] = 0;
1196 datReq->mBuf[1] = 0;
1200 for(i=0;i<RG_MAX_TB_PER_UE;i++)
1203 if ((hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf == dlSf) &&
1204 (hqP->tbInfo[i].tb != NULLP))
1206 if ((hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf == dlSf) &&
1207 RgUtlIsTbMuxed(&(hqP->tbInfo[i].tb)))
1211 datReq->rnti = hqP->tbInfo[i].pdcch.rnti;
1212 datReq->dciInfo = hqP->tbInfo[i].pdcch.dci;
1213 datReq->doa = hqP->tbInfo[i].doa;
1214 datReq->transMode = hqP->tbInfo[i].txMode;
1215 datReq->puschRptUsd = hqP->tbInfo[i].puschRptUsd;
1216 datReq->puschPmiInfo = hqP->tbInfo[i].puschPmiInfo;
1217 /*MS_WORKAROUND for ccpu00123904*/
1218 if (hqP->tbInfo[i].schdTa.pres)
1220 datReq->isTApres = TRUE;
1223 /* update pA value */
1224 datReq->pa = hqP->tbInfo[i].pa;
1226 /* LTE_ADV_FLAG_REMOVED_START */
1227 datReq->isEnbSFR = hqP->tbInfo[i].isEnbSFR;
1228 /* LTE_ADV_FLAG_REMOVED_END */
1230 #if (!(defined TENB_ACC) && !(defined LTE_PAL_ENB)) /* ABHI */ /* This is only temp fix. It needs to be removed
1231 after rebasing to MAC CCB */
1233 datReq->mBuf[i] = hqP->tbInfo[i].tb;
1235 /* Intel Tdd- Commenting out the Optimization for direct Access of
1237 /*Proper clean-up needed as this needs long stability tests
1239 #if defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD)
1240 SIncMsgRef(hqP->tbInfo[i].tb, RG_GET_MEM_REGION(rgCb[inst]),
1241 RG_GET_MEM_POOL(rgCb[inst]), &datReq->mBuf[i]);
1243 datReq->mBuf[i] = hqP->tbInfo[i].tb;
1247 SIncMsgRef(hqP->tbInfo[i].tb, RG_GET_MEM_REGION(rgCb[inst]),
1248 RG_GET_MEM_POOL(rgCb[inst]), &datReq->mBuf[i]);
1252 if(SFndLenMsg(datReq->mBuf[i], &dbgBufLen))
1256 RLOG_ARG4(L_ERROR,DBG_CELLID,cellCb->cellId,
1257 "RNTI:%d SFN:%d slot:%d tbIdx:%d Sdu Length 0 ",
1259 hqP->tbInfo[i].timingInfo.sfn,
1260 hqP->tbInfo[i].timingInfo.slot,i);
1261 RLOG_ARG3(L_ERROR,DBG_CELLID,cellCb->cellId,
1262 "taPres [%d] numOfTbs [%d] format[%d]",
1265 datReq->dciInfo.format);
1270 /* L2 optimization for mUe/Tti: Removing SIncMsgRef to avoid additional
1271 * mBuf allocation. MAC header, MAC Ces, MAC PDU per LCH per TB Per UE
1272 * and MAC padding Mbufs are being sent to CL. Populating these Ptrs
1273 * From TB Info to TfuDatReq
1275 datReq->tbInfo[i].tbPres = TRUE;
1276 datReq->tbInfo[i].tbSize = hqP->tbInfo[i].tbSz;
1277 datReq->tbInfo[i].macHdr = hqP->tbInfo[i].tb.macHdr;
1278 datReq->tbInfo[i].macCes = hqP->tbInfo[i].tb.macCes;
1279 datReq->tbInfo[i].numLch = hqP->tbInfo[i].tb.numLch;
1280 for(lchIdx = 0; lchIdx < hqP->tbInfo[i].tb.numLch; lchIdx++)
1282 datReq->tbInfo[i].lchInfo[lchIdx].numPdu = hqP->tbInfo[i].tb.\
1283 lchInfo[lchIdx].numPdu;
1284 for(pduIdx = 0; pduIdx < hqP->tbInfo[i].tb.lchInfo[lchIdx].numPdu;\
1287 datReq->tbInfo[i].lchInfo[lchIdx].mBuf[pduIdx] =
1288 hqP->tbInfo[i].tb.lchInfo[lchIdx].mBuf[pduIdx];
1291 // datReq->tbInfo[i].macPad = hqP->tbInfo[i].tb.macPad;
1292 datReq->tbInfo[i].padSize = hqP->tbInfo[i].tb.padSize;
1293 // prc_trace_format_string(0x40,3,"TfuDatReq:RNTI=%d TbIdx=%d TbSize=%d PdSz=(%d) macHdraddr: (%p) macCEAddr: (%p) noLch=(%d)",datReq->rnti, i,
1294 // hqP->tbInfo[i].tbSz, datReq->tbInfo[i].padSize, datReq->tbInfo[i].macHdr, datReq->tbInfo[i].macCes, datReq->tbInfo[i].numLch);
1301 } /* rgDHMBldTfuDatReq */
1306 * @brief This function releases a HARQ process
1310 * Function: rgDHMFreeHqProcTB
1311 * Purpose: This function returns a HARQ process to HARQ Entity
1312 * in the DL direction.
1314 * 1. Add the HARQ process to the free queue.
1315 * Invoked by: scheduler and HARQ processing
1317 * @param[in] RgDlHqProc *hqP
1321 S16 rgDHMFreeHqProcTB(RgDlHqProcCb *hqP, uint8_t tbIndex)
1323 RgTfuDatReqTbInfo *tb; /* TB to be sent to CL/PHY*/
1326 if((tbIndex > RG_MAX_TB_PER_UE) ||
1332 tb = &(hqP->tbInfo[tbIndex-1].tb);
1333 RG_FREE_MSG(tb->macHdr);
1334 RG_FREE_MSG(tb->macCes);
1336 for(idx = 0; idx < 2; idx++)
1338 if (hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk.node != NULLP)
1340 cmLListDelFrm(&hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sf->tbs,
1341 &(hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk));
1342 hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk.node = (PTR)NULLP;
1343 printf("\nrgDHMFreeHqProcTB:: hqP %p \n", (Void *)hqP);
1345 hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sf = NULLP;
1354 * @brief Handler for freeing up the harq related information from ueCb
1358 * Function : rgDHMFreeUe
1360 * This function shall free up the HARQ specific information from ueCb.
1362 * @param[in] Inst inst
1363 * @param[in] RgDlHqEnt *hqE
1368 Void rgDHMFreeUe(Inst inst, RgDlHqEnt *hqE)
1374 /* Free all the memory associated with HARQ */
1375 for (i=0; i < hqE->numHqProcs; i++)
1378 rgDHMRlsHqProcTB(rgCb[inst].cell, hqE->procs[i], 1);
1379 rgDHMRlsHqProcTB(rgCb[inst].cell, hqE->procs[i], 2);
1381 rgDHMFreeHqProcTB(hqE->procs[i], 1);
1382 rgDHMFreeHqProcTB(hqE->procs[i], 2);
1385 rgFreeSBuf(inst,(Data **)&(hqE->procs[i]), sizeof(RgDlHqProcCb));
1387 rgDHMFreeSavedHqP(inst,hqE,i);
1391 /*ccpu00117052 - MOD - Passing double pointer for proper NULLP
1399 * @brief Function for handling RaResp request received from scheduler to MAC
1403 * Function : RgSchMacRstHqEntReq
1405 * This function shall be invoked whenever a sec cell of an ue
1406 * is deactivated. MAC needs to reset the harqentity associated
1407 * with the deactivated scell of the ue
1410 * @param[in] Pst *pst
1411 * @param[in] RgInfResetHqEnt *hqEntInfo
1415 S16 RgSchMacRstHqEntReq(Pst* pst, RgInfResetHqEnt* hqEntInfo)
1421 inst = pst->dstInst - RG_INST_START;
1423 if (((cell = rgCb[inst].cell) == NULLP) ||
1424 (rgCb[inst].cell->cellId != hqEntInfo->cellId))
1426 RGDBGERRNEW(inst,(rgPBuf(inst), "For user [%d]Cell does not exist %d\n",
1427 hqEntInfo->crnti,hqEntInfo->cellId));
1431 if ((ue = rgDBMGetUeCb(cell, hqEntInfo->crnti)) == NULLP)
1433 RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]UE does not exist for this hqEntInfo\n",
1438 rgDHMUeReset(cell, &ue->dl.hqEnt);
1445 * @brief Function for handling RaResp request received from scheduler to MAC
1449 * Function : RgSchMacRlsHqReq
1451 * This function shall be invoked whenever scheduler is done with the
1452 * allocations of random access responses for a slot.
1453 * This shall invoke RAM to create ueCbs for all the rapIds allocated and
1454 * shall invoke MUX to create RAR PDUs for raRntis allocated.
1457 * @param[in] CmLteCellId cellId,
1458 * @param[in] CmLteTimingInfo timingInfo,
1459 * @param[in] RaRespInfo *rarInfo
1463 S16 RgSchMacRlsHqReq(Pst *pst, RgInfRlsHqInfo *rlshqUeInfo)
1466 RgCellCb *cell = NULLP;
1472 RguHarqStatusInd hqStaInd;
1473 Bool isValidTbId = FALSE;
1475 uint32_t startTime=0;
1477 RG_IS_INST_VALID(pst->dstInst);
1478 inst = pst->dstInst - RG_INST_START;
1479 cell = rgCb[inst].cell;
1481 SStartTask(&startTime, PID_MAC_AM_HARQ_RLS);
1483 if(NULLP == rlshqUeInfo)
1489 ||( cell->cellId != rlshqUeInfo->cellId))
1492 RLOG_ARG0(L_ERROR,DBG_CELLID,rlshqUeInfo->cellId,
1493 "No cellCb found with cellId");
1497 if(NULLP == rlshqUeInfo->ueHqInfo)
1502 for(idx1 = 0; idx1 < rlshqUeInfo->numUes; idx1++)
1504 if((ue=rgDBMGetUeCb (cell, rlshqUeInfo->ueHqInfo[idx1].rnti)) == NULLP)
1506 /* Check in RachLst */
1507 if((ue=rgDBMGetUeCbFromRachLst (cell,
1508 rlshqUeInfo->ueHqInfo[idx1].rnti)) == NULLP)
1510 RLOG_ARG1(L_ERROR,DBG_CELLID,rlshqUeInfo->cellId, "CRNTI:%d No ueCb found",
1511 rlshqUeInfo->ueHqInfo[idx1].rnti);
1517 if ((rlshqUeInfo->ueHqInfo[idx1].rlsOperationType && !gSaveVal) || (rlshqUeInfo->ueHqInfo[idx1].hqProcId > 8))
1520 RLOG_ARG1(L_INFO," SPURIOUS CALLL !!!! procId %d \n", rlshqUeInfo->ueHqInfo[idx1].hqProcId);
1523 printf ("RgSchMacRlsHqReq cell %d : numUes %d idx %d rnti %d hqProc %d numTbs %d tbid[0] %d tbid[1] %d rlsopr %d \n",
1525 rlshqUeInfo->numUes,
1527 rlshqUeInfo->ueHqInfo[idx1].rnti,
1528 rlshqUeInfo->ueHqInfo[idx1].hqProcId,
1529 rlshqUeInfo->ueHqInfo[idx1].numOfTBs,
1530 rlshqUeInfo->ueHqInfo[idx1].tbId[0],
1531 rlshqUeInfo->ueHqInfo[idx1].tbId[1],
1532 rlshqUeInfo->ueHqInfo[idx1].rlsOperationType);
1540 RgSchMacHndlRelReq(cell, ue, &rlshqUeInfo->ueHqInfo[idx1]);
1542 if (RGINF_RLS_HQ_DEL_TB == rlshqUeInfo->ueHqInfo[idx1].rlsOperationType)
1544 /* If REQ is to DEL the saved TBs no need to free the HqP as it's already
1548 #endif /* LTE_ADV */
1549 rgDHMGetHqProcFrmId(ue,rlshqUeInfo->ueHqInfo[idx1].hqProcId,&hqP);
1550 if(rlshqUeInfo->ueHqInfo[idx1].status[0] != TRUE)
1552 rgCb[inst].genSts.numHarqFail++;
1556 hqStaInd.cellId = cell->cellId;
1557 hqStaInd.ueId = rlshqUeInfo->ueHqInfo[idx1].rnti;
1558 hqStaInd.numTbs = rlshqUeInfo->ueHqInfo[idx1].numOfTBs;
1561 for(idx2=0; idx2 < rlshqUeInfo->ueHqInfo[idx1].numOfTBs; idx2++)
1564 /* Fill the hq sta Ind stucture. Need to send the Status Ind for only
1565 those TBID's reported by Scheduler*/
1566 tbId = rlshqUeInfo->ueHqInfo[idx1].tbId[idx2];
1567 if (hqP->tbId[tbId-1] != RGU_INVALID_TBID)
1569 /* Fill the correct Sn Map corresponding to the TBID */
1570 hqStaInd.tbId[idx2] = hqP->tbId[tbId-1];
1571 hqStaInd.status[idx2] = rlshqUeInfo->ueHqInfo[idx1].status[idx2];
1575 if(rgDHMRlsHqProcTB(cell, hqP,
1576 rlshqUeInfo->ueHqInfo[idx1].tbId[idx2]) != ROK)
1578 RLOG_ARG1(L_ERROR,DBG_CELLID,rlshqUeInfo->cellId,
1579 "CRNTI:%d Failure in releasing hq TB",
1580 rlshqUeInfo->ueHqInfo[idx1].rnti);
1591 RgUiRguHqStaInd(&(ue->rguDlSap->sapCfg.sapPst),
1592 ue->rguDlSap->sapCfg.suId,
1596 {/* Ue is from rach list*/
1597 RgUiRguHqStaInd(&(cell->rguDlSap->sapCfg.sapPst),
1598 cell->rguDlSap->sapCfg.suId,
1603 } /* end of ues loop */
1606 SStopTask(startTime,PID_MAC_AM_HARQ_RLS);
1609 } /* end of RgSchMacRlsHqReq */
1612 /**********************************************************************
1615 **********************************************************************/