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 //EXTERN S16 ssGetDBufOfSize(Region region,Size size,Buffer **dBuf);
72 //void prc_trace_format_string(UINT32 group_mask, UINT16 level, const char *format, ...);
78 EXTERN S16 SIncMsgRef(Buffer *srcBuf,Region dstRegion, Pool dstPool,Buffer **dstBuf);
80 PRIVATE Void rgDHMBldTfuDatReq ARGS((RgCellCb *cellCb, RgDlSf *dlSf, RgDlHqProcCb *hqP,
81 RgTfuDatReqPduInfo *datReq));
84 PUBLIC S16 rgDHMFreeHqProcTB
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
115 PUBLIC S16 rgDHMHqEntInit
122 PUBLIC S16 rgDHMHqEntInit(inst,hqE, maxHqProcs)
130 Buffer *hdrDBuf = NULLP;
131 Buffer *ceDBuf = NULLP;
136 hqE->numHqProcs = maxHqProcs;
137 /* for each harq process */
138 for (idx1 = 0; idx1 < hqE->numHqProcs; idx1++)
140 if (rgAllocSBuf(inst,(Data **)&(hqE->procs[idx1]),sizeof(RgDlHqProcCb)) != ROK)
144 rgFreeSBuf(inst,(Data **)&(hqE->procs[idx1]), sizeof(RgDlHqProcCb));
146 RLOG0(L_ERROR, "Memory Alloc Failure for RgDlHqProcCb");
150 hqE->procs[idx1]->procId = idx1;
151 for(idx2 = 0; idx2 < RG_MAX_TB_PER_UE; idx2++)
154 hqE->procs[idx1]->tbInfo[idx2].tb = NULLP;
157 /* L2 optimization for mUe/Tti: Allocating buffers for macHdr, macCes
158 * and macPadding. These buffers shall not be released by MAC/CL.
159 * However, Only rPtr and wPtr will be reset while release of hq proc
161 tmpMBuf = hqE->procs[idx1]->tbInfo[idx2].tb.macHdr;
162 rgGetMsg(inst, &tmpMBuf);
163 RG_ADD_DBuf(hdrDBuf, RG_MAC_HDR_SIZE, tmpMBuf);
164 hqE->procs[idx1]->tbInfo[idx2].tb.macHdr = tmpMBuf;
165 macHeader[idx2] = MacPtrAddress;
167 tmpMBuf = hqE->procs[idx1]->tbInfo[idx2].tb.macCes;
168 rgGetMsg(inst, &tmpMBuf);
169 RG_ADD_DBuf(ceDBuf, RG_MAC_CE_SIZE, tmpMBuf);
170 hqE->procs[idx1]->tbInfo[idx2].tb.macCes = tmpMBuf;
172 hqE->procs[idx1]->tbInfo[idx2].tb.padSize = 0;
175 hqE->procs[idx1]->tbId[idx2] = RGU_INVALID_TBID;
179 cmLListInit(&hqE->savedProcLst[idx1]);
184 } /* rgDHMHqEntInit */
187 * @brief This function releases a HARQ process
191 * Function: rgDHMUeReset
192 * Purpose: This function resets TB in each HarqProc.
194 * Invoked by: CFG UE Reset
196 * @param[in] RgDlHqProc *hqP
201 PUBLIC Void rgDHMUeReset
207 PUBLIC Void rgDHMUeReset(cell, hqE)
218 /* Free all the TB memory associated with HARQ */
219 for (i=0; i < hqE->numHqProcs; i++)
221 rgDHMRlsHqProcTB(cell, hqE->procs[i], 1);
222 rgDHMRlsHqProcTB(cell, hqE->procs[i], 2);
225 rgDHMFreeSavedHqP((cell->macInst - RG_INST_START), hqE, i);
233 * @brief This function defers shared memory buffer
234 * freeing out of the critical RT path.
238 * Function: rgDHMHdlBufFree
239 * Purpose: To defer shared memory freeing post
240 * critical path. Defer as many if defer queue
241 * is full then release instantly.
243 * Invoked by: HARQ TB Release.
249 PUBLIC Void rgDHMHdlBufFree
255 PUBLIC Void rgDHMHdlBufFree(Inst inst, Buffer **mBuf)
259 RgCb *rgCbP = &rgCb[inst];
260 TRC2(rgDHMHdlBufFree)
262 if (rgCbP->bufCnt < RG_MAX_DFRD_FREE_BUFS)
266 rgCbP->bufToFree[rgCbP->bufCnt] = *mBuf;
278 * @brief This function is called to release the
279 * shared memory of the HARQ TBs outside
280 * the critical RT path.
284 * Function: rgDHMFreeTbBufs
285 * Purpose: This function is called to release the
286 * shared memory of the HARQ TBs outside
287 * the critical RT path.
289 * 1. Job of releasing TBs is shared across TTIs
290 * Invoked by: MAC every TTI
296 PUBLIC Void rgDHMFreeTbBufs
301 PUBLIC Void rgDHMFreeTbBufs(inst)
305 RgCb *rgCbP = &rgCb[inst];
306 U8 start = rgCbP->bufCnt;
309 TRC2(rgDHMFreeTbBufs)
311 if (rgCbP->bufCnt < RG_MAX_FREE_BUFS_PERTTI)
317 end = rgCbP->bufCnt - RG_MAX_FREE_BUFS_PERTTI;
322 SPutMsg(rgCbP->bufToFree[start]);
326 } /* rgDHMFreeTbBufs */
329 PUBLIC Void rgDHMFreeAllTbBufs
334 PUBLIC Void rgDHMFreeAllTbBufs(inst)
338 RgCb *rgCbP = &rgCb[inst];
339 U8 start = rgCbP->bufCnt;
342 TRC2(rgDHMFreeAllTbBufs)
347 SPutMsg(rgCbP->bufToFree[start]);
351 } /* rgDHMFreeTbBufs */
355 * @brief This function releases a HARQ process
359 * Function: rgDHMRlsHqProcTB
360 * Purpose: This function returns a HARQ process to HARQ Entity
361 * in the DL direction.
363 * 1. Add the HARQ process to the free queue.
364 * Invoked by: scheduler and HARQ processing
366 * @param[in] RgDlHqProc *hqP
371 PUBLIC S16 rgDHMRlsHqProcTB
378 PUBLIC S16 rgDHMRlsHqProcTB(cell, hqP, tbIndex)
386 RgTfuDatReqTbInfo *tb; /* TB to be sent to CL/PHY*/
387 // U32 lchIdx, pduIdx;
390 TRC2(rgDHMRlsHqProcTB)
392 if((tbIndex > RG_MAX_TB_PER_UE) ||
398 hqP->tbInfo[tbIndex-1].numSchLch = 0;
400 if (hqP->tbInfo[tbIndex-1].tb)
402 rgDHMHdlBufFree(cell->macInst - RG_INST_START, &hqP->tbInfo[tbIndex-1].tb);
405 /* L2 Optimization for mUe/Tti: macHdr, macCes and macPad mBuf pointers
406 * shall not be released. However, Inorder to release harq info/TB info,
407 * just Resetting rPtr and wPtr of these mbufs to db_base
409 tb = &(hqP->tbInfo[tbIndex-1].tb);
410 if (tb->tbPres == TRUE)
415 hqP->tbInfo[tbIndex-1].schdTa.pres = FALSE;
417 hqP->tbInfo[tbIndex -1].sCellActCe.pres = FALSE;
420 /* Decrementing might lead to roundoff error in case of say UE reset
421 * where all the HqProcs irrespective whether in use are called for rls.
422 * Hence to avoid the same shift operator is being used. */
423 hqP->numOfTBs = hqP->numOfTBs >> 1;
424 for(idx = 0; idx < 2; idx++)
426 if (hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk.node != NULLP)
428 cmLListDelFrm(&hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sf->tbs,
429 &(hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk));
430 hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk.node = (PTR)NULLP;
431 printf("\nrgDHMRlsHqProcTB:: hqP %p \n", (Void *)hqP);
433 hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sf = NULLP;
435 /* Fix : syed It is better to reset these feilds
436 * corruption avoidance */
437 hqP->tbInfo[tbIndex-1].tbSz = 0;
438 hqP->tbInfo[tbIndex-1].contResCe = NOTPRSNT;
439 hqP->tbInfo[tbIndex-1].contResId = NULLP;
442 } /* rgDHMRlsHqProc */
445 * @brief This function gets HARQ process with the given Id
449 * Function: rgDHMGetHqProcFrmId
450 * Purpose: This function returns the HARQ process with the given ID.
453 * @param[in] RgUeCb *ue
455 * @param[in] RgDlHqProc **hqP
457 * -# ROK if successful
458 * -# RFAILED otherwise
462 PUBLIC S16 rgDHMGetHqProcFrmId
469 PUBLIC S16 rgDHMGetHqProcFrmId(ue, idx, hqP)
475 TRC2(rgDHMGetHqProcFrmId)
477 /* Pick the proc based on the index provided */
478 *hqP = (ue->dl.hqEnt.procs[idx]);
481 } /* rgDHMGetHqProcFrmId */
483 /*PRIVATE U32 dataAvl; */
485 * @brief Handler for sending data to PHY
489 * Function : rgDHMSndDatReq
491 * This function shall send the MAC PDU built for the UE to TOM
492 * when invoked as part of TTI processing and keep track of the number of
493 * transmissions for this TB.
496 * @param[in] RgCellCb *cell
497 * @param[in] RgDlHqProcCb *hqE
498 * @param[out] RgErrInfo *err
504 PUBLIC S16 rgDHMSndDatReq
508 RgTfuDatReqInfo *datInfo,
513 PUBLIC S16 rgDHMSndDatReq(cellCb, dlSf, datInfo, hqP, err)
516 RgTfuDatReqInfo *datInfo;
522 Inst inst = cellCb->macInst - RG_INST_START;
523 RgTfuDatReqPduInfo *datReq;
525 /*Added this variable to figure out that whether this UE data
526 has to be inclueded in the TFU Data request.*/
532 for(i=0;i< RG_MAX_TB_PER_UE;i++)
534 /* printf("\nDHMSndDatReq1: Rnti %d dlSfSchdTime(sfn sf) : (%d %d)\n"
535 "macCell(sfn sf): (%d %d) tbTimingInfo(sfn sf): (%d %d)\n"
536 "dlSf %p dlSf->tbs.count %d hqp %p tb %p\n",
537 hqP->tbInfo[i].pdcch.rnti,
538 dlSf->schdTime.sfn, dlSf->schdTime.slot,
539 cellCb->crntTime.sfn, cellCb->crntTime.slot,
540 hqP->tbInfo[i].timingInfo.sfn,
541 hqP->tbInfo[i].timingInfo.slot,
542 (Void *)dlSf, dlSf->tbs.count,
544 (Void *)hqP->tbInfo[i].tb);*/
545 /* Mukesh :: in case of rpepetiton this is not rerd*/
546 if (hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf == dlSf)
548 /* Check if data from RLC had been received and got muxed. */
550 if (hqP->tbInfo[i].tb == NULLP)
552 if (!(hqP->tbInfo[i].tb.tbPres))
556 if (hqP->tbInfo[i].schdTa.pres == TRUE ||
557 hqP->tbInfo[i].contResCe == PRSNT_NODEF)
559 if ((hqP->tbInfo[i].schdTa.pres == TRUE) ||
560 (hqP->tbInfo[i].contResCe == PRSNT_NODEF) ||
561 (hqP->tbInfo[i].sCellActCe.pres == TRUE))
564 /* Data not received but ta needs to be sent. */
565 /* MUX TA and send it */
566 bldPdu.datReq = NULLP;
567 bldPdu.reqType = EVENT_SLOT_IND_TO_MAC;
568 bldPdu.schdTbSz = hqP->tbInfo[i].tbSz;
569 bldPdu.ta = hqP->tbInfo[i].schdTa;
571 bldPdu.sCellActCe= hqP->tbInfo[i].sCellActCe;
573 /* changes for CR timer implementation*/
574 bldPdu.contResId = hqP->tbInfo[i].contResId;
575 if (ROK != rgMUXBldPdu(inst,&bldPdu, &(hqP->tbInfo[i].tb), err))
577 RLOG1(L_ERROR, "MUXing failed for: MacInst %d", inst);
578 RLOG4(L_ERROR, "MUXing failed for: time: %d/%d\
579 procId %d ueId %d", hqP->tbInfo[i].timingInfo.sfn,
580 hqP->tbInfo[i].timingInfo.slot, hqP->procId,
581 hqP->tbInfo[i].pdcch.rnti);
588 #ifdef LTEMAC_RGU_PAD
589 /* Data not received from RLC. Padding at MAC */
590 bldPdu.datReq = NULLP;
591 bldPdu.reqType = EVENT_SLOT_IND_TO_MAC;
592 bldPdu.schdTbSz = hqP->tbInfo[i].tbSz;
593 bldPdu.ta = hqP->tbInfo[i].schdTa;
595 bldPdu.sCellActCe= hqP->tbInfo[i].sCellActCe;
598 bldPdu.contResId = NULLP;
600 if (ROK != rgMUXBldPdu(inst,&bldPdu, &(hqP->tbInfo[i].tb), err))
602 RLOG1(L_ERROR, "MUXing failed for: MacInst %d", inst);
603 RLOG4(L_ERROR, "MUXing failed for: time: %d/%d\
604 procId %d ueId %d", hqP->tbInfo[i].timingInfo.sfn,
605 hqP->tbInfo[i].timingInfo.slot, hqP->procId,
606 hqP->tbInfo[i].pdcch.rnti);
611 /*Padding is not done so data for this UE will not be
626 /*If Data/Padding is not available for UE, then we can not include
627 any Data for this UE in TFU Data Request.*/
630 /*Free up the HARQ process for this allocation.*/
631 /* Release First TB, as this would be anyway there*/
632 rgDHMRlsHqProcTB(cellCb, hqP, 1);
633 if(2 == hqP->numOfTBs)
635 rgDHMRlsHqProcTB(cellCb, hqP, 2);
641 if (rgGetEventMem(inst,(Ptr *)&datReq, sizeof(TfuDatReqPduInfo),
642 &(datInfo->memCp)) != ROK)
646 /* Fill the TFU Dat Req with information from Harq Proc */
648 rgDHMBldTfuDatReq(cellCb, dlSf, hqP, datReq);
650 /* MS_WORKAROUND for ccpu00122894 */
651 for(i=0;i< RG_MAX_TB_PER_UE;i++)
653 if (hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf == dlSf)
655 cmLListDelFrm(&dlSf->tbs, &(hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk));
656 hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk.node = NULLP;
659 hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf = NULLP;
662 cmLListAdd2Tail(&datInfo->pdus, &(datReq->lnk));
663 datReq->lnk.node = (PTR)datReq;
666 } /* rgDHMSndDatReq */
669 * @brief Function to handle RGU datReq received from ROM
673 * Function : rgDHMHndlDedDatReq
675 * This function shall act on the datReq received on RGU. It shall
676 * store the data IDs for all the logical channels and get the MAC
680 * @param[in] Inst inst
681 * @param[in] RgDlHqProcCb *hqProc
682 * @param[in] RgRguDedDatReq *datReq
683 * @param[out] RgErrInfo *err
689 PUBLIC S16 rgDHMHndlDedDatReq
692 RgDlHqProcCb *hqProc,
693 RgRguDDatReqPerUe *datReq,
698 PUBLIC S16 rgDHMHndlDedDatReq(inst,hqProc, datReq, dlSf, err)
700 RgDlHqProcCb *hqProc;
701 RgRguDDatReqPerUe *datReq;
712 RgTfuDatReqTbInfo *tb;
715 TRC2(rgDHMHndlDedDatReq);
717 tbIndex = (U8)(datReq->transId & 0x03);
718 /* Accept all the data requests even if delayed in case nothing
719 * has been sent earlier on the harq proc.
721 if((datReq->nmbOfTbs > RG_MAX_TB_PER_UE) ||
724 /* release corresponding TBs from SF tbs List */
725 for(j=0;j<datReq->nmbOfTbs;j++)
727 if (!(tbIndex & (j+1)))
731 rgDHMRlsHqProcTB(rgCb[inst].cell, hqProc, (U8)(j+1));
736 for(i=0;i<datReq->nmbOfTbs;i++)
738 /* tbIndex 01 corresponds to presence of 1st TB
739 * 10 corresponds 2nd TB
740 * 11 corresponds two TBs of UE */
741 if (!(tbIndex & (i+1)))
745 if (hqProc->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk.node == NULLP)
747 /* release corresponding TBs from SF tbs List */
748 for(j=0;j<datReq->nmbOfTbs;j++)
750 if (!(tbIndex & (j+1)))
754 rgDHMRlsHqProcTB(rgCb[inst].cell, hqProc, (U8)(j+1));
755 printf("\nrgDHMHndlDedDatReq:: hqP %p \n", (Void *)hqProc);
761 RG_FREE_MSG(hqProc->tbInfo[i].tb);
762 /* L2 optimization for mUe/Tti: Pre-allocated mBuf pointers(macHdr,
763 * macCes and MacPad) of harq TB need to be reset to db_base
766 tb = &hqProc->tbInfo[i].tb;
767 if (tb->tbPres == TRUE)
772 bldPdu.datReq = datReq;
773 bldPdu.reqType = EVTRGUDDATREQ;
774 bldPdu.schdTbSz = hqProc->tbInfo[i].tbSz;
775 bldPdu.tbIndex = i+1;
776 bldPdu.ta = hqProc->tbInfo[i].schdTa;
778 bldPdu.sCellActCe= hqProc->tbInfo[i].sCellActCe;
780 bldPdu.contResId = NULLP;
782 /* Store tbId from RLC in DDatRequest */
783 hqProc->tbId[i] = datReq->datReqTb[i].tbId;
786 hqProc->status[i] = FALSE;
788 if(rgMUXBldPdu(inst,&bldPdu, &(hqProc->tbInfo[i].tb), err) != ROK)
790 RLOG1(L_ERROR, "MUXing failed for: MacInst %d", inst);
791 RLOG4(L_ERROR, "MUXing failed for: time: %d/%d\
792 procId %d ueId %d", hqProc->tbInfo[i].timingInfo.sfn,
793 hqProc->tbInfo[i].timingInfo.slot, hqProc->procId,
794 hqProc->tbInfo[i].pdcch.rnti);
796 /* release corresponding TBs from SF tbs List */
797 for(j=0;j<datReq->nmbOfTbs;j++)
799 if (!(tbIndex & (j+1)))
803 rgDHMRlsHqProcTB(rgCb[inst].cell, hqProc, (U8)(j+1));
808 SFndLenMsg(hqProc->tbInfo[i].tb, &len);
812 } /* rgDHMHndlDedDatReq */
815 * @brief Function to handle RGU datReq received from ROM
819 * Function : rgDHMHndlCmnDatReq
821 * This function shall act on the datReq received on RGU. It shall
822 * store the data IDs for all the logical channels and get the MAC
826 * @param[in] Inst inst
827 * @param[in] RgDlHqProcCb *hqProc
828 * @param[in] RgRguCmnDatReq *datReq
829 * @param[out] RgErrInfo *err
835 PUBLIC S16 rgDHMHndlCmnDatReq
838 RgDlHqProcCb *hqProc,
839 RgRguCmnDatReq *datReq,
843 PUBLIC S16 rgDHMHndlCmnDatReq(inst,hqProc, datReq, err)
845 RgDlHqProcCb *hqProc;
846 RgRguCmnDatReq *datReq;
853 TRC2(rgDHMHndlCmnDatReq)
856 if (hqProc->tbInfo[0].tb != NULLP)
858 /* If numLch is non zero means HQ Proc is busy*/
859 if (hqProc->tbInfo[0].tb.tbPres)
862 /* datReq discarded. Generate an alarm */
863 rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_HARQ);
864 rgLMMStaInd(inst,LCM_CATEGORY_PROTOCOL, LCM_EVENT_UI_INV_EVT,
865 LRG_CAUSE_HQ_PROC_BUSY, &dgn);
869 bldPdu.datReq = datReq;
870 bldPdu.reqType = EVTRGUCDATREQ;
871 bldPdu.schdTbSz = hqProc->tbInfo[0].tbSz;
872 bldPdu.ta = hqProc->tbInfo[0].schdTa;
874 bldPdu.sCellActCe= hqProc->tbInfo[0].sCellActCe;
877 bldPdu.contResId = hqProc->tbInfo[0].contResId;
879 if(rgMUXBldPdu(inst,&bldPdu, &(hqProc->tbInfo[0].tb), err) != ROK)
881 RLOG1(L_ERROR, "MUXing failed for: MacInst %d", inst);
882 RLOG4(L_ERROR, "MUXing failed for: time: %d/%d\
883 procId %d ueId %d", hqProc->tbInfo[0].timingInfo.sfn,
884 hqProc->tbInfo[0].timingInfo.slot, hqProc->procId,
885 hqProc->tbInfo[0].pdcch.rnti);
887 RG_FREE_MSG(datReq->pdu);
892 } /* rgDHMHndlCmnDatReq */
895 * @brief Function to get consolidate grants and send consolidated grant to RLC
899 * Function : rgDHMSndConsolidatedStaInd
901 * This function shall be invoked by Scheduler to trigger DHM to send a
902 * consolidated status indication of all UE scheduled in a TTI as well as
903 * send consolidated CStaInd for MSG4 and for all common channels(PCCH,
904 * if RGR_SI_SCH is not defined then it includes BCH and BCCH also)
907 * @param[in] RgCellCb *cell
908 * @param[in] RgInfUeInfo *ueInfo,
909 * @param[in] CmLteTimingInfo timingInfo,
910 * @param[out] RgErrInfo err
911 * @param[in] RguCStaIndInfo *cStaInd
918 PUBLIC S16 rgDHMSndConsolidatedStaInd
922 CmLteTimingInfo timingInfo,
926 PUBLIC S16 rgDHMSndConsolidatedStaInd(cell, ueInfo, timingInfo, err)
929 CmLteTimingInfo timingInfo;
933 SuId rguDlSpId;/*need to use spID instead of suID*/
938 RgDlSf *dlSf = &cell->subFrms[(timingInfo.slot % RG_NUM_SUB_FRAMES)];
939 Inst inst = cell->macInst - RG_INST_START;
940 // Bool isDStaReqrd = FALSE;
941 RgRguDedStaInd *dStaInd[rgCb[inst].numRguSaps] ;
942 RgUpSapCb *rguDlSap[rgCb[inst].numRguSaps];
947 RgInfUeAlloc *allocInfo;
951 Bool hqPAdded = FALSE;
954 RgTfuDatReqTbInfo *tb; /* TB to be sent to CL/PHY*/
957 TRC2(rgDHMSndConsolidatedStaInd)
958 cmMemset ((U8 *)dStaInd, 0, (sizeof(RgRguDedStaInd *) * rgCb[inst].numRguSaps));
959 cmMemset ((U8 *)rguDlSap, 0, (sizeof(RgUpSapCb *) * rgCb[inst].numRguSaps));
961 /* Send StaInd for the scheduled UEs */
962 for(ueIdx = 0; ueIdx < ueInfo->numUes; ueIdx++)
967 if((ue=rgDBMGetUeCb (cell, ueInfo->allocInfo[ueIdx].rnti)) == NULLP)
969 /* Check in RachLst */
970 if((ue=rgDBMGetUeCbFromRachLst (cell,
971 ueInfo->allocInfo[ueIdx].rnti)) == NULLP)
973 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"CRNTI:%d No ueCb found",
974 ueInfo->allocInfo[ueIdx].rnti);
975 /*Fix: If one UE is not present dont return, look for the next.*/
981 rgDHMGetHqProcFrmId(ue,ueInfo->allocInfo[ueIdx].hqProcId,&hqP);
982 allocInfo = &ueInfo->allocInfo[ueIdx];
985 /* Fix : syed Avoid sending data for a RETX
986 * if initial TX data processing was unsuccessful */
987 if((allocInfo->tbInfo[0].isReTx == TRUE) &&
988 (hqP->tbInfo[0].tbSz == 0))
990 RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
991 "CRNTI:%d RETX hqP(%d) tb(0) for a failed New Tx",
992 allocInfo->rnti, hqP->procId);
995 if((allocInfo->tbInfo[1].isReTx == TRUE) &&
996 (hqP->tbInfo[1].tbSz == 0))
998 RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
999 "CRNTI:%d RETX hqP(%d) tb(1) for a failed New Tx",
1000 allocInfo->rnti, hqP->procId);
1004 if(ue->rguDlSap != NULLP)
1006 rguDlSpId = ue->rguDlSap->sapCfg.spId;
1008 {/* UeCb is from rachList */
1009 rguDlSpId = cell->rguDlSap->sapCfg.spId;
1013 for(idx=allocInfo->tbStrtIdx;((idx-allocInfo->tbStrtIdx) <\
1014 allocInfo->nmbOfTBs); idx++)
1016 RguCStaIndInfo *cStaInd;
1018 /* LTE_ADV_FLAG_REMOVED_START */
1019 hqP->tbInfo[idx].isEnbSFR = allocInfo->isEnbSFR;
1020 /* update pA value */
1021 hqP->tbInfo[idx].pa = allocInfo->pa;
1022 /* LTE_ADV_FLAG_REMOVED_END */
1025 hqP->numOfTBs = allocInfo->nmbOfTBs;
1026 hqP->tbInfo[idx].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk.node = (PTR)hqP;
1027 hqP->tbInfo[idx].sfLnkInfo[dlSf->schdTime.slot % 2].sf = dlSf;
1028 cmLListAdd2Tail(&dlSf->tbs,&(hqP->tbInfo[idx].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk));
1029 /* Changes as part of performance testing*/
1030 /* hqP->numOfTBs++;*/
1031 hqP->tbInfo[idx].doa = allocInfo->doa;
1032 hqP->tbInfo[idx].txMode = allocInfo->txMode;
1033 hqP->tbInfo[idx].puschRptUsd = allocInfo->puschRptUsd;
1034 hqP->tbInfo[idx].puschPmiInfo = allocInfo->puschPmiInfo;
1036 hqP->tbInfo[idx].pdcch.rnti = allocInfo->pdcchRnti;
1038 hqP->tbInfo[idx].pdcch.rnti = allocInfo->rnti;
1040 if(allocInfo->tbInfo[idx].isReTx == TRUE)
1042 hqP->tbInfo[idx].pdcch.dci = allocInfo->dciInfo;
1046 hqP->tbInfo[idx].timingInfo = timingInfo;
1047 hqP->tbInfo[idx].pdcch.dci = allocInfo->dciInfo;
1049 RG_FREE_MSG(hqP->tbInfo[idx].tb);
1051 /* L2 optimization for mUe/Tti: Pre-allocated mBuf pointers(macHdr,
1052 * macCes and MacPad) of harq TB need to be reset to db_base
1054 tb = &(hqP->tbInfo[idx].tb);
1055 if (tb->tbPres == TRUE)
1060 hqP->tbInfo[idx].tbSz = allocInfo->tbInfo[idx].schdTbSz;
1062 hqP->tbInfo[idx].schdTa.pres = allocInfo->tbInfo[idx].ta.pres;
1063 hqP->tbInfo[idx].schdTa.val = allocInfo->tbInfo[idx].ta.val;
1066 hqP->tbInfo[idx].sCellActCe.pres = allocInfo->tbInfo[idx].sCellActCe.pres;
1067 hqP->tbInfo[idx].sCellActCe.val = allocInfo->tbInfo[idx].sCellActCe.val;
1071 if(( hqPAdded == TRUE) || (ROK == rgLaaPushHqPToScellLst(allocInfo,cell,timingInfo)))
1077 if (allocInfo->tbInfo[idx].schdDat[0].lcId == RG_CCCH_LCID)
1080 RG_FREE_MSG(hqP->tbInfo[idx].tb);
1082 /* L2 optimization for mUe/Tti: Pre-allocated mBuf pointers(macHdr,
1083 * macCes and MacPad) of harq TB need to be reset to db_base
1085 tb = &(hqP->tbInfo[idx].tb);
1087 if (tb->tbPres == TRUE)
1092 hqP->tbInfo[0].contResCe = allocInfo->tbInfo[0].contResCe;
1093 if(allocInfo->tbInfo[0].contResCe)
1095 hqP->tbInfo[0].contResId = &ue->contResId;
1099 if(allocInfo->tbInfo[idx].numSchLch == 0)
1101 RLOG_ARG2(L_DEBUG,DBG_CELLID,cell->cellId,
1102 "UEID:%d MSG4 with only contResId hqP(%d)",
1105 hqP->tbInfo[idx].numSchLch = 0;
1109 /* Increamenting the tbIndex instead of
1110 assigning it to constant */
1114 hqP->tbInfo[idx].numSchLch = 1;
1115 hqP->tbInfo[idx].schdData[0].lcId =
1116 allocInfo->tbInfo[idx].schdDat[0].lcId;
1117 hqP->tbInfo[idx].schdData[0].schdSz =
1118 allocInfo->tbInfo[idx].schdDat[0].numBytes;
1120 // if(cStaInd == NULLP)
1122 if ((rgAllocShrablSBuf(inst,(Data**)&cStaInd, sizeof(RguCStaIndInfo))) != ROK)
1124 err->errType = RGERR_DHM_SND_STA_IND;
1125 err->errCause = RG_DHM_MEM_ALLOC_FAIL;
1130 idx1 = (hqP->procId << 2) | tbIndex;
1132 cStaInd->cellId = cell->cellId;
1133 cStaInd->rnti = allocInfo->rnti;
1134 cStaInd->lcId = cell->dlCcchId;
1135 cStaInd->transId = (timingInfo.sfn << 16) |
1136 (timingInfo.slot << 8) | idx1;
1137 /* ADD Changes for Downlink UE Timing Optimization */
1138 #ifdef LTEMAC_DLUE_TMGOPTMZ
1139 dlSf->remDatReqCnt++;
1141 RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,
1142 "RNTI:%d UE:MSG4 grant for CCCH hqP(%d) LCID:%d",
1146 /* Fix : syed Avoid return param for interface prim and
1147 * proceed for other UEs. For the failed UE, MAC shall
1149 rgUIMSndCmnStaInd(cell->macInst,cell->rguDlSap,cStaInd);
1156 RG_FREE_MSG(hqP->tbInfo[idx].tb);
1158 /* L2 optimization for mUe/Tti: Pre-allocated mBuf pointers(macHdr,
1159 * macCes and MacPad) of harq TB need to be reset to db_base
1161 tb = &(hqP->tbInfo[idx].tb);
1162 if (tb->tbPres == TRUE)
1168 if((NULLP == dStaInd[rguDlSpId]) && (allocInfo->tbInfo[idx].numSchLch))
1170 if ((rgAllocShrablSBuf (inst,(Data**)&dStaInd[rguDlSpId], sizeof(RguDStaIndInfo))) != ROK)
1172 err->errType = RGERR_DHM_SND_STA_IND;
1173 err->errCause = RG_DHM_MEM_ALLOC_FAIL;
1174 /* Need to return as memory allocation will fail for other UEs also*/
1177 dStaInd[rguDlSpId]->nmbOfUeGrantPerTti = 0;
1178 rguDlSap[rguDlSpId] = ue->rguDlSap;
1183 lcIdx < allocInfo->tbInfo[idx].numSchLch; lcIdx++)
1185 hqP->tbInfo[idx].schdData[lcIdx].lcId =
1186 allocInfo->tbInfo[idx].schdDat[lcIdx].lcId;
1187 if (hqP->tbInfo[idx].schdData[lcIdx].lcId == 0)
1189 RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
1190 "CCCH grant in DStaInd for LCID:%d CRNTI:%d",
1191 hqP->tbInfo[idx].schdData[lcIdx].lcId,allocInfo->rnti);
1193 hqP->tbInfo[idx].schdData[lcIdx].schdSz =
1194 allocInfo->tbInfo[idx].schdDat[lcIdx].numBytes;
1195 if(dStaInd[rguDlSpId])
1197 dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].staIndTb[idx].\
1198 lchStaInd[lcIdx].lcId = allocInfo->tbInfo[idx].\
1199 schdDat[lcIdx].lcId;
1200 dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].staIndTb[idx].\
1201 lchStaInd[lcIdx].totBufSize = allocInfo->tbInfo[idx].\
1202 schdDat[lcIdx].numBytes;
1205 lchBufSize+=allocInfo->tbInfo[idx].schdDat[lcIdx].numBytes;
1207 hqP->tbInfo[idx].numSchLch =
1208 allocInfo->tbInfo[idx].numSchLch;
1209 if(dStaInd[rguDlSpId])
1211 dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].staIndTb[idx].nmbLch =
1212 allocInfo->tbInfo[idx].numSchLch;
1214 dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].staIndTb[idx].tbId =
1221 //if((dStaInd) && (tbIndex) && (isDStaReqrd == TRUE))
1222 if((dStaInd[rguDlSpId]) && (tbIndex))
1224 idx1 = (hqP->procId << 2) | tbIndex;
1225 /* Create RguDStaInd struct and send to UIM */
1226 dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].rnti = allocInfo->rnti;
1228 dStaInd->transId = (hqP->timingInfo.sfn << 16) |
1229 (hqP->timingInfo.slot << 8) | hqP->procId;
1231 dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].transId = (timingInfo.sfn << 16) |
1232 (timingInfo.slot << 8) | idx1;
1233 dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].nmbOfTbs = hqP->numOfTBs;
1235 dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].fillCtrlPdu = allocInfo->fillCtrlPdu;
1237 /*increment num of UE as staInd is prepared for it */
1238 dStaInd[rguDlSpId]->nmbOfUeGrantPerTti++;
1239 /* ADD Changes for Downlink UE Timing Optimization */
1240 #ifdef LTEMAC_DLUE_TMGOPTMZ
1241 dlSf->remDatReqCnt++;
1244 //isDStaReqrd = FALSE;
1248 for(idx = 0; idx < rgCb[inst].numRguSaps ; idx++)
1250 if(dStaInd[idx] != NULLP)
1252 dStaInd[idx]->cellId = cell->cellId;
1253 /* Fix : syed Avoid return param for interface prim and
1254 * proceed for other UEs. For the failed UE, MAC shall
1256 rgUIMSndDedStaInd(inst,rguDlSap[idx],dStaInd[idx]);
1259 if(staIndCnt == activeSapCnt)
1260 break;/* all valid staind are considered */
1265 } /* rgDHMSndConsolidatedStaInd */
1269 * @brief Function to handle building the TFU Data Request
1273 * Function : rgDHMBldTfuDatReq
1275 * This function builds the TFU Data Request with the details
1276 * present in HARQ Process.
1278 * @param[in] RgDlHqProcCb *hqP
1279 * @param[out] TfuDatReqPduInfo *datReq
1285 PRIVATE Void rgDHMBldTfuDatReq
1290 RgTfuDatReqPduInfo *datReq
1293 PRIVATE Void rgDHMBldTfuDatReq(cellCb, dlSf, hqP, datReq)
1297 RgTfuDatReqPduInfo *datReq;
1302 #if !(!(defined TENB_ACC) && !(defined LTE_PAL_ENB))
1304 #elif defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD)
1314 TRC2(rgDHMBldTfuDatReq)
1316 datReq->nmbOfTBs = 0;
1318 #if !(!(defined TENB_ACC) && !(defined LTE_PAL_ENB))
1319 inst = cellCb->macInst - RG_INST_START;
1320 #elif defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD)
1321 inst = cellCb->macInst - RG_INST_START;
1324 /*MS_WORKAROUND for ccpu00123904*/
1325 datReq->isTApres = FALSE;
1326 #ifdef TFU_ALLOC_EVENT_NO_INIT
1328 datReq->mBuf[0] = 0;
1329 datReq->mBuf[1] = 0;
1333 for(i=0;i<RG_MAX_TB_PER_UE;i++)
1336 if ((hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf == dlSf) &&
1337 (hqP->tbInfo[i].tb != NULLP))
1339 if ((hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf == dlSf) &&
1340 RgUtlIsTbMuxed(&(hqP->tbInfo[i].tb)))
1344 datReq->rnti = hqP->tbInfo[i].pdcch.rnti;
1345 datReq->dciInfo = hqP->tbInfo[i].pdcch.dci;
1346 datReq->doa = hqP->tbInfo[i].doa;
1347 datReq->transMode = hqP->tbInfo[i].txMode;
1348 datReq->puschRptUsd = hqP->tbInfo[i].puschRptUsd;
1349 datReq->puschPmiInfo = hqP->tbInfo[i].puschPmiInfo;
1350 /*MS_WORKAROUND for ccpu00123904*/
1351 if (hqP->tbInfo[i].schdTa.pres)
1353 datReq->isTApres = TRUE;
1356 /* update pA value */
1357 datReq->pa = hqP->tbInfo[i].pa;
1359 /* LTE_ADV_FLAG_REMOVED_START */
1360 datReq->isEnbSFR = hqP->tbInfo[i].isEnbSFR;
1361 /* LTE_ADV_FLAG_REMOVED_END */
1363 #if (!(defined TENB_ACC) && !(defined LTE_PAL_ENB)) /* ABHI */ /* This is only temp fix. It needs to be removed
1364 after rebasing to MAC CCB */
1366 datReq->mBuf[i] = hqP->tbInfo[i].tb;
1368 /* Intel Tdd- Commenting out the Optimization for direct Access of
1370 /*Proper clean-up needed as this needs long stability tests
1372 #if defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD)
1373 SIncMsgRef(hqP->tbInfo[i].tb, RG_GET_MEM_REGION(rgCb[inst]),
1374 RG_GET_MEM_POOL(rgCb[inst]), &datReq->mBuf[i]);
1376 datReq->mBuf[i] = hqP->tbInfo[i].tb;
1380 SIncMsgRef(hqP->tbInfo[i].tb, RG_GET_MEM_REGION(rgCb[inst]),
1381 RG_GET_MEM_POOL(rgCb[inst]), &datReq->mBuf[i]);
1385 if(SFndLenMsg(datReq->mBuf[i], &dbgBufLen))
1389 RLOG_ARG4(L_ERROR,DBG_CELLID,cellCb->cellId,
1390 "RNTI:%d SFN:%d slot:%d tbIdx:%d Sdu Length 0 ",
1392 hqP->tbInfo[i].timingInfo.sfn,
1393 hqP->tbInfo[i].timingInfo.slot,i);
1394 RLOG_ARG3(L_ERROR,DBG_CELLID,cellCb->cellId,
1395 "taPres [%d] numOfTbs [%d] format[%d]",
1398 datReq->dciInfo.format);
1403 /* L2 optimization for mUe/Tti: Removing SIncMsgRef to avoid additional
1404 * mBuf allocation. MAC header, MAC Ces, MAC PDU per LCH per TB Per UE
1405 * and MAC padding Mbufs are being sent to CL. Populating these Ptrs
1406 * From TB Info to TfuDatReq
1408 datReq->tbInfo[i].tbPres = TRUE;
1409 datReq->tbInfo[i].tbSize = hqP->tbInfo[i].tbSz;
1410 datReq->tbInfo[i].macHdr = hqP->tbInfo[i].tb.macHdr;
1411 datReq->tbInfo[i].macCes = hqP->tbInfo[i].tb.macCes;
1412 datReq->tbInfo[i].numLch = hqP->tbInfo[i].tb.numLch;
1413 for(lchIdx = 0; lchIdx < hqP->tbInfo[i].tb.numLch; lchIdx++)
1415 datReq->tbInfo[i].lchInfo[lchIdx].numPdu = hqP->tbInfo[i].tb.\
1416 lchInfo[lchIdx].numPdu;
1417 for(pduIdx = 0; pduIdx < hqP->tbInfo[i].tb.lchInfo[lchIdx].numPdu;\
1420 datReq->tbInfo[i].lchInfo[lchIdx].mBuf[pduIdx] =
1421 hqP->tbInfo[i].tb.lchInfo[lchIdx].mBuf[pduIdx];
1424 // datReq->tbInfo[i].macPad = hqP->tbInfo[i].tb.macPad;
1425 datReq->tbInfo[i].padSize = hqP->tbInfo[i].tb.padSize;
1426 // prc_trace_format_string(0x40,3,"TfuDatReq:RNTI=%d TbIdx=%d TbSize=%d PdSz=(%d) macHdraddr: (%p) macCEAddr: (%p) noLch=(%d)",datReq->rnti, i,
1427 // hqP->tbInfo[i].tbSz, datReq->tbInfo[i].padSize, datReq->tbInfo[i].macHdr, datReq->tbInfo[i].macCes, datReq->tbInfo[i].numLch);
1434 } /* rgDHMBldTfuDatReq */
1439 * @brief This function releases a HARQ process
1443 * Function: rgDHMFreeHqProcTB
1444 * Purpose: This function returns a HARQ process to HARQ Entity
1445 * in the DL direction.
1447 * 1. Add the HARQ process to the free queue.
1448 * Invoked by: scheduler and HARQ processing
1450 * @param[in] RgDlHqProc *hqP
1455 PUBLIC S16 rgDHMFreeHqProcTB
1461 PUBLIC S16 rgDHMFreeHqProcTB(hqP, tbIndex)
1466 RgTfuDatReqTbInfo *tb; /* TB to be sent to CL/PHY*/
1469 TRC2(rgDHMFreeHqProcTB)
1471 if((tbIndex > RG_MAX_TB_PER_UE) ||
1477 tb = &(hqP->tbInfo[tbIndex-1].tb);
1478 RG_FREE_MSG(tb->macHdr);
1479 RG_FREE_MSG(tb->macCes);
1481 for(idx = 0; idx < 2; idx++)
1483 if (hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk.node != NULLP)
1485 cmLListDelFrm(&hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sf->tbs,
1486 &(hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk));
1487 hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk.node = (PTR)NULLP;
1488 printf("\nrgDHMFreeHqProcTB:: hqP %p \n", (Void *)hqP);
1490 hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sf = NULLP;
1499 * @brief Handler for freeing up the harq related information from ueCb
1503 * Function : rgDHMFreeUe
1505 * This function shall free up the HARQ specific information from ueCb.
1507 * @param[in] Inst inst
1508 * @param[in] RgDlHqEnt *hqE
1514 PUBLIC Void rgDHMFreeUe
1520 PUBLIC Void rgDHMFreeUe(inst,hqE)
1530 /* Free all the memory associated with HARQ */
1531 for (i=0; i < hqE->numHqProcs; i++)
1534 rgDHMRlsHqProcTB(rgCb[inst].cell, hqE->procs[i], 1);
1535 rgDHMRlsHqProcTB(rgCb[inst].cell, hqE->procs[i], 2);
1537 rgDHMFreeHqProcTB(hqE->procs[i], 1);
1538 rgDHMFreeHqProcTB(hqE->procs[i], 2);
1541 rgFreeSBuf(inst,(Data **)&(hqE->procs[i]), sizeof(RgDlHqProcCb));
1543 rgDHMFreeSavedHqP(inst,hqE,i);
1547 /*ccpu00117052 - MOD - Passing double pointer for proper NULLP
1555 * @brief Function for handling RaResp request received from scheduler to MAC
1559 * Function : RgSchMacRstHqEntReq
1561 * This function shall be invoked whenever a sec cell of an ue
1562 * is deactivated. MAC needs to reset the harqentity associated
1563 * with the deactivated scell of the ue
1566 * @param[in] Pst *pst
1567 * @param[in] RgInfResetHqEnt *hqEntInfo
1572 PUBLIC S16 RgSchMacRstHqEntReq
1575 RgInfResetHqEnt* hqEntInfo
1578 PUBLIC S16 RgSchMacRstHqEntReq(pst, hqEntInfo)
1580 RgInfResetHqEnt* hqEntInfo;
1587 inst = pst->dstInst - RG_INST_START;
1589 if (((cell = rgCb[inst].cell) == NULLP) ||
1590 (rgCb[inst].cell->cellId != hqEntInfo->cellId))
1592 RGDBGERRNEW(inst,(rgPBuf(inst), "For user [%d]Cell does not exist %d\n",
1593 hqEntInfo->crnti,hqEntInfo->cellId));
1597 if ((ue = rgDBMGetUeCb(cell, hqEntInfo->crnti)) == NULLP)
1599 RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]UE does not exist for this hqEntInfo\n",
1604 rgDHMUeReset(cell, &ue->dl.hqEnt);
1611 * @brief Function for handling RaResp request received from scheduler to MAC
1615 * Function : RgSchMacRlsHqReq
1617 * This function shall be invoked whenever scheduler is done with the
1618 * allocations of random access responses for a slot.
1619 * This shall invoke RAM to create ueCbs for all the rapIds allocated and
1620 * shall invoke MUX to create RAR PDUs for raRntis allocated.
1623 * @param[in] CmLteCellId cellId,
1624 * @param[in] CmLteTimingInfo timingInfo,
1625 * @param[in] RaRespInfo *rarInfo
1630 PUBLIC S16 RgSchMacRlsHqReq
1633 RgInfRlsHqInfo *rlshqUeInfo
1636 PUBLIC S16 RgSchMacRlsHqReq(pst, rlshqUeInfo)
1638 RgInfRlsHqInfo *rlshqUeInfo;
1642 RgCellCb *cell = NULLP;
1648 RguHarqStatusInd hqStaInd;
1649 Bool isValidTbId = FALSE;
1653 TRC2(RgSchMacRlsHqReq)
1655 RG_IS_INST_VALID(pst->dstInst);
1656 inst = pst->dstInst - RG_INST_START;
1657 cell = rgCb[inst].cell;
1659 SStartTask(&startTime, PID_MAC_AM_HARQ_RLS);
1661 if(NULLP == rlshqUeInfo)
1667 ||( cell->cellId != rlshqUeInfo->cellId))
1670 RLOG_ARG0(L_ERROR,DBG_CELLID,rlshqUeInfo->cellId,
1671 "No cellCb found with cellId");
1675 if(NULLP == rlshqUeInfo->ueHqInfo)
1680 for(idx1 = 0; idx1 < rlshqUeInfo->numUes; idx1++)
1682 if((ue=rgDBMGetUeCb (cell, rlshqUeInfo->ueHqInfo[idx1].rnti)) == NULLP)
1684 /* Check in RachLst */
1685 if((ue=rgDBMGetUeCbFromRachLst (cell,
1686 rlshqUeInfo->ueHqInfo[idx1].rnti)) == NULLP)
1688 RLOG_ARG1(L_ERROR,DBG_CELLID,rlshqUeInfo->cellId, "CRNTI:%d No ueCb found",
1689 rlshqUeInfo->ueHqInfo[idx1].rnti);
1695 if ((rlshqUeInfo->ueHqInfo[idx1].rlsOperationType && !gSaveVal) || (rlshqUeInfo->ueHqInfo[idx1].hqProcId > 8))
1698 RLOG_ARG1(L_INFO," SPURIOUS CALLL !!!! procId %d \n", rlshqUeInfo->ueHqInfo[idx1].hqProcId);
1701 printf ("RgSchMacRlsHqReq cell %d : numUes %d idx %d rnti %d hqProc %d numTbs %d tbid[0] %d tbid[1] %d rlsopr %d \n",
1703 rlshqUeInfo->numUes,
1705 rlshqUeInfo->ueHqInfo[idx1].rnti,
1706 rlshqUeInfo->ueHqInfo[idx1].hqProcId,
1707 rlshqUeInfo->ueHqInfo[idx1].numOfTBs,
1708 rlshqUeInfo->ueHqInfo[idx1].tbId[0],
1709 rlshqUeInfo->ueHqInfo[idx1].tbId[1],
1710 rlshqUeInfo->ueHqInfo[idx1].rlsOperationType);
1718 RgSchMacHndlRelReq(cell, ue, &rlshqUeInfo->ueHqInfo[idx1]);
1720 if (RGINF_RLS_HQ_DEL_TB == rlshqUeInfo->ueHqInfo[idx1].rlsOperationType)
1722 /* If REQ is to DEL the saved TBs no need to free the HqP as it's already
1726 #endif /* LTE_ADV */
1727 rgDHMGetHqProcFrmId(ue,rlshqUeInfo->ueHqInfo[idx1].hqProcId,&hqP);
1728 if(rlshqUeInfo->ueHqInfo[idx1].status[0] != TRUE)
1730 rgCb[inst].genSts.numHarqFail++;
1734 hqStaInd.cellId = cell->cellId;
1735 hqStaInd.ueId = rlshqUeInfo->ueHqInfo[idx1].rnti;
1736 hqStaInd.numTbs = rlshqUeInfo->ueHqInfo[idx1].numOfTBs;
1739 for(idx2=0; idx2 < rlshqUeInfo->ueHqInfo[idx1].numOfTBs; idx2++)
1742 /* Fill the hq sta Ind stucture. Need to send the Status Ind for only
1743 those TBID's reported by Scheduler*/
1744 tbId = rlshqUeInfo->ueHqInfo[idx1].tbId[idx2];
1745 if (hqP->tbId[tbId-1] != RGU_INVALID_TBID)
1747 /* Fill the correct Sn Map corresponding to the TBID */
1748 hqStaInd.tbId[idx2] = hqP->tbId[tbId-1];
1749 hqStaInd.status[idx2] = rlshqUeInfo->ueHqInfo[idx1].status[idx2];
1753 if(rgDHMRlsHqProcTB(cell, hqP,
1754 rlshqUeInfo->ueHqInfo[idx1].tbId[idx2]) != ROK)
1756 RLOG_ARG1(L_ERROR,DBG_CELLID,rlshqUeInfo->cellId,
1757 "CRNTI:%d Failure in releasing hq TB",
1758 rlshqUeInfo->ueHqInfo[idx1].rnti);
1769 RgUiRguHqStaInd(&(ue->rguDlSap->sapCfg.sapPst),
1770 ue->rguDlSap->sapCfg.suId,
1774 {/* Ue is from rach list*/
1775 RgUiRguHqStaInd(&(cell->rguDlSap->sapCfg.sapPst),
1776 cell->rguDlSap->sapCfg.suId,
1781 } /* end of ues loop */
1784 SStopTask(startTime,PID_MAC_AM_HARQ_RLS);
1787 } /* end of RgSchMacRlsHqReq */
1790 /**********************************************************************
1793 **********************************************************************/