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 "envopt.h" /* environment options */
40 #include "envdep.h" /* environment dependent */
41 #include "envind.h" /* environment independent */
42 #include "gen.h" /* general layer */
43 #include "ssi.h" /* system service interface */
47 #include "cm5.h" /* common timers */
48 #include "cm_hash.h" /* common hash list */
49 #include "cm_mblk.h" /* common memory link list library */
50 #include "cm_llist.h" /* common linked list library */
51 #include "cm_err.h" /* common error */
52 #include "cm_lte.h" /* common LTE */
57 #include "rg_sch_inf.h"
62 /* header/extern include files (.x) */
63 #include "gen.x" /* general layer */
64 #include "ssi.x" /* system service interface */
68 #include "cm5.x" /* common timers */
69 #include "cm_lib.x" /* common library */
70 #include "cm_hash.x" /* common hash list */
71 #include "cm_llist.x" /* common linked list library */
72 #include "cm_mblk.x" /* memory management */
73 #include "cm_tkns.x" /* common tokens */
74 #include "cm_lte.x" /* common LTE */
79 #include "rg_sch_inf.x"
80 #include "rg_prg.x" /* PRG interface typedefs */
81 #include "du_app_mac_inf.h"
88 #include "ss_msg.x" /* MAC includes */
90 //EXTERN S16 ssGetDBufOfSize(Region region,Size size,Buffer **dBuf);
91 //void prc_trace_format_string(UINT32 group_mask, UINT16 level, const char *format, ...);
97 EXTERN S16 SIncMsgRef(Buffer *srcBuf,Region dstRegion, Pool dstPool,Buffer **dstBuf);
99 PRIVATE Void rgDHMBldTfuDatReq ARGS((RgCellCb *cellCb, RgDlSf *dlSf, RgDlHqProcCb *hqP,
100 RgTfuDatReqPduInfo *datReq));
103 PUBLIC S16 rgDHMFreeHqProcTB
111 /* forward references */
114 * @brief This function initializes the DL HARQ Entity of UE
118 * Function: rgDHMHqEntInit
119 * Purpose: This function initializes the DL HARQ entity of
120 * UE control block. This is performed at the time
121 * of creating UE control block.
123 * Invoked by: configuration module
125 * @param[in] Inst inst
126 * @param[in] RgCellCb* cell
127 * @param[in] RgUeCb* ue
134 PUBLIC S16 rgDHMHqEntInit
141 PUBLIC S16 rgDHMHqEntInit(inst,hqE, maxHqProcs)
149 Buffer *hdrDBuf = NULLP;
150 Buffer *ceDBuf = NULLP;
155 hqE->numHqProcs = maxHqProcs;
156 /* for each harq process */
157 for (idx1 = 0; idx1 < hqE->numHqProcs; idx1++)
159 if (rgAllocSBuf(inst,(Data **)&(hqE->procs[idx1]),sizeof(RgDlHqProcCb)) != ROK)
163 rgFreeSBuf(inst,(Data **)&(hqE->procs[idx1]), sizeof(RgDlHqProcCb));
165 RLOG0(L_ERROR, "Memory Alloc Failure for RgDlHqProcCb");
169 hqE->procs[idx1]->procId = idx1;
170 for(idx2 = 0; idx2 < RG_MAX_TB_PER_UE; idx2++)
173 hqE->procs[idx1]->tbInfo[idx2].tb = NULLP;
176 /* L2 optimization for mUe/Tti: Allocating buffers for macHdr, macCes
177 * and macPadding. These buffers shall not be released by MAC/CL.
178 * However, Only rPtr and wPtr will be reset while release of hq proc
180 tmpMBuf = hqE->procs[idx1]->tbInfo[idx2].tb.macHdr;
181 rgGetMsg(inst, &tmpMBuf);
182 RG_ADD_DBuf(hdrDBuf, RG_MAC_HDR_SIZE, tmpMBuf);
183 hqE->procs[idx1]->tbInfo[idx2].tb.macHdr = tmpMBuf;
184 macHeader[idx2] = MacPtrAddress;
186 tmpMBuf = hqE->procs[idx1]->tbInfo[idx2].tb.macCes;
187 rgGetMsg(inst, &tmpMBuf);
188 RG_ADD_DBuf(ceDBuf, RG_MAC_CE_SIZE, tmpMBuf);
189 hqE->procs[idx1]->tbInfo[idx2].tb.macCes = tmpMBuf;
191 hqE->procs[idx1]->tbInfo[idx2].tb.padSize = 0;
194 hqE->procs[idx1]->tbId[idx2] = RGU_INVALID_TBID;
198 cmLListInit(&hqE->savedProcLst[idx1]);
203 } /* rgDHMHqEntInit */
206 * @brief This function releases a HARQ process
210 * Function: rgDHMUeReset
211 * Purpose: This function resets TB in each HarqProc.
213 * Invoked by: CFG UE Reset
215 * @param[in] RgDlHqProc *hqP
220 PUBLIC Void rgDHMUeReset
226 PUBLIC Void rgDHMUeReset(cell, hqE)
237 /* Free all the TB memory associated with HARQ */
238 for (i=0; i < hqE->numHqProcs; i++)
240 rgDHMRlsHqProcTB(cell, hqE->procs[i], 1);
241 rgDHMRlsHqProcTB(cell, hqE->procs[i], 2);
244 rgDHMFreeSavedHqP((cell->macInst - RG_INST_START), hqE, i);
252 * @brief This function defers shared memory buffer
253 * freeing out of the critical RT path.
257 * Function: rgDHMHdlBufFree
258 * Purpose: To defer shared memory freeing post
259 * critical path. Defer as many if defer queue
260 * is full then release instantly.
262 * Invoked by: HARQ TB Release.
268 PUBLIC Void rgDHMHdlBufFree
274 PUBLIC Void rgDHMHdlBufFree(Inst inst, Buffer **mBuf)
278 RgCb *rgCbP = &rgCb[inst];
279 TRC2(rgDHMHdlBufFree)
281 if (rgCbP->bufCnt < RG_MAX_DFRD_FREE_BUFS)
285 rgCbP->bufToFree[rgCbP->bufCnt] = *mBuf;
297 * @brief This function is called to release the
298 * shared memory of the HARQ TBs outside
299 * the critical RT path.
303 * Function: rgDHMFreeTbBufs
304 * Purpose: This function is called to release the
305 * shared memory of the HARQ TBs outside
306 * the critical RT path.
308 * 1. Job of releasing TBs is shared across TTIs
309 * Invoked by: MAC every TTI
315 PUBLIC Void rgDHMFreeTbBufs
320 PUBLIC Void rgDHMFreeTbBufs(inst)
324 RgCb *rgCbP = &rgCb[inst];
325 U8 start = rgCbP->bufCnt;
328 TRC2(rgDHMFreeTbBufs)
330 if (rgCbP->bufCnt < RG_MAX_FREE_BUFS_PERTTI)
336 end = rgCbP->bufCnt - RG_MAX_FREE_BUFS_PERTTI;
341 SPutMsg(rgCbP->bufToFree[start]);
345 } /* rgDHMFreeTbBufs */
348 PUBLIC Void rgDHMFreeAllTbBufs
353 PUBLIC Void rgDHMFreeAllTbBufs(inst)
357 RgCb *rgCbP = &rgCb[inst];
358 U8 start = rgCbP->bufCnt;
361 TRC2(rgDHMFreeAllTbBufs)
366 SPutMsg(rgCbP->bufToFree[start]);
370 } /* rgDHMFreeTbBufs */
374 * @brief This function releases a HARQ process
378 * Function: rgDHMRlsHqProcTB
379 * Purpose: This function returns a HARQ process to HARQ Entity
380 * in the DL direction.
382 * 1. Add the HARQ process to the free queue.
383 * Invoked by: scheduler and HARQ processing
385 * @param[in] RgDlHqProc *hqP
390 PUBLIC S16 rgDHMRlsHqProcTB
397 PUBLIC S16 rgDHMRlsHqProcTB(cell, hqP, tbIndex)
405 RgTfuDatReqTbInfo *tb; /* TB to be sent to CL/PHY*/
406 // U32 lchIdx, pduIdx;
409 TRC2(rgDHMRlsHqProcTB)
411 if((tbIndex > RG_MAX_TB_PER_UE) ||
417 hqP->tbInfo[tbIndex-1].numSchLch = 0;
419 if (hqP->tbInfo[tbIndex-1].tb)
421 rgDHMHdlBufFree(cell->macInst - RG_INST_START, &hqP->tbInfo[tbIndex-1].tb);
424 /* L2 Optimization for mUe/Tti: macHdr, macCes and macPad mBuf pointers
425 * shall not be released. However, Inorder to release harq info/TB info,
426 * just Resetting rPtr and wPtr of these mbufs to db_base
428 tb = &(hqP->tbInfo[tbIndex-1].tb);
429 if (tb->tbPres == TRUE)
434 hqP->tbInfo[tbIndex-1].schdTa.pres = FALSE;
436 hqP->tbInfo[tbIndex -1].sCellActCe.pres = FALSE;
439 /* Decrementing might lead to roundoff error in case of say UE reset
440 * where all the HqProcs irrespective whether in use are called for rls.
441 * Hence to avoid the same shift operator is being used. */
442 hqP->numOfTBs = hqP->numOfTBs >> 1;
443 for(idx = 0; idx < 2; idx++)
445 if (hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk.node != NULLP)
447 cmLListDelFrm(&hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sf->tbs,
448 &(hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk));
449 hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk.node = (PTR)NULLP;
450 printf("\nrgDHMRlsHqProcTB:: hqP %p \n", (Void *)hqP);
452 hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sf = NULLP;
454 /* Fix : syed It is better to reset these feilds
455 * corruption avoidance */
456 hqP->tbInfo[tbIndex-1].tbSz = 0;
457 hqP->tbInfo[tbIndex-1].contResCe = NOTPRSNT;
458 hqP->tbInfo[tbIndex-1].contResId = NULLP;
461 } /* rgDHMRlsHqProc */
464 * @brief This function gets HARQ process with the given Id
468 * Function: rgDHMGetHqProcFrmId
469 * Purpose: This function returns the HARQ process with the given ID.
472 * @param[in] RgUeCb *ue
474 * @param[in] RgDlHqProc **hqP
476 * -# ROK if successful
477 * -# RFAILED otherwise
481 PUBLIC S16 rgDHMGetHqProcFrmId
488 PUBLIC S16 rgDHMGetHqProcFrmId(ue, idx, hqP)
494 TRC2(rgDHMGetHqProcFrmId)
496 /* Pick the proc based on the index provided */
497 *hqP = (ue->dl.hqEnt.procs[idx]);
500 } /* rgDHMGetHqProcFrmId */
502 /*PRIVATE U32 dataAvl; */
504 * @brief Handler for sending data to PHY
508 * Function : rgDHMSndDatReq
510 * This function shall send the MAC PDU built for the UE to TOM
511 * when invoked as part of TTI processing and keep track of the number of
512 * transmissions for this TB.
515 * @param[in] RgCellCb *cell
516 * @param[in] RgDlHqProcCb *hqE
517 * @param[out] RgErrInfo *err
523 PUBLIC S16 rgDHMSndDatReq
527 RgTfuDatReqInfo *datInfo,
532 PUBLIC S16 rgDHMSndDatReq(cellCb, dlSf, datInfo, hqP, err)
535 RgTfuDatReqInfo *datInfo;
541 Inst inst = cellCb->macInst - RG_INST_START;
542 RgTfuDatReqPduInfo *datReq;
544 /*Added this variable to figure out that whether this UE data
545 has to be inclueded in the TFU Data request.*/
551 for(i=0;i< RG_MAX_TB_PER_UE;i++)
553 /* printf("\nDHMSndDatReq1: Rnti %d dlSfSchdTime(sfn sf) : (%d %d)\n"
554 "macCell(sfn sf): (%d %d) tbTimingInfo(sfn sf): (%d %d)\n"
555 "dlSf %p dlSf->tbs.count %d hqp %p tb %p\n",
556 hqP->tbInfo[i].pdcch.rnti,
557 dlSf->schdTime.sfn, dlSf->schdTime.slot,
558 cellCb->crntTime.sfn, cellCb->crntTime.slot,
559 hqP->tbInfo[i].timingInfo.sfn,
560 hqP->tbInfo[i].timingInfo.slot,
561 (Void *)dlSf, dlSf->tbs.count,
563 (Void *)hqP->tbInfo[i].tb);*/
564 /* Mukesh :: in case of rpepetiton this is not rerd*/
565 if (hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf == dlSf)
567 /* Check if data from RLC had been received and got muxed. */
569 if (hqP->tbInfo[i].tb == NULLP)
571 if (!(hqP->tbInfo[i].tb.tbPres))
575 if (hqP->tbInfo[i].schdTa.pres == TRUE ||
576 hqP->tbInfo[i].contResCe == PRSNT_NODEF)
578 if ((hqP->tbInfo[i].schdTa.pres == TRUE) ||
579 (hqP->tbInfo[i].contResCe == PRSNT_NODEF) ||
580 (hqP->tbInfo[i].sCellActCe.pres == TRUE))
583 /* Data not received but ta needs to be sent. */
584 /* MUX TA and send it */
585 bldPdu.datReq = NULLP;
586 bldPdu.reqType = EVENT_SLOT_IND_TO_MAC;
587 bldPdu.schdTbSz = hqP->tbInfo[i].tbSz;
588 bldPdu.ta = hqP->tbInfo[i].schdTa;
590 bldPdu.sCellActCe= hqP->tbInfo[i].sCellActCe;
592 /* changes for CR timer implementation*/
593 bldPdu.contResId = hqP->tbInfo[i].contResId;
594 if (ROK != rgMUXBldPdu(inst,&bldPdu, &(hqP->tbInfo[i].tb), err))
596 RLOG1(L_ERROR, "MUXing failed for: MacInst %d", inst);
597 RLOG4(L_ERROR, "MUXing failed for: time: %d/%d\
598 procId %d ueId %d", hqP->tbInfo[i].timingInfo.sfn,
599 hqP->tbInfo[i].timingInfo.slot, hqP->procId,
600 hqP->tbInfo[i].pdcch.rnti);
607 #ifdef LTEMAC_RGU_PAD
608 /* Data not received from RLC. Padding at MAC */
609 bldPdu.datReq = NULLP;
610 bldPdu.reqType = EVENT_SLOT_IND_TO_MAC;
611 bldPdu.schdTbSz = hqP->tbInfo[i].tbSz;
612 bldPdu.ta = hqP->tbInfo[i].schdTa;
614 bldPdu.sCellActCe= hqP->tbInfo[i].sCellActCe;
617 bldPdu.contResId = NULLP;
619 if (ROK != rgMUXBldPdu(inst,&bldPdu, &(hqP->tbInfo[i].tb), err))
621 RLOG1(L_ERROR, "MUXing failed for: MacInst %d", inst);
622 RLOG4(L_ERROR, "MUXing failed for: time: %d/%d\
623 procId %d ueId %d", hqP->tbInfo[i].timingInfo.sfn,
624 hqP->tbInfo[i].timingInfo.slot, hqP->procId,
625 hqP->tbInfo[i].pdcch.rnti);
630 /*Padding is not done so data for this UE will not be
645 /*If Data/Padding is not available for UE, then we can not include
646 any Data for this UE in TFU Data Request.*/
649 /*Free up the HARQ process for this allocation.*/
650 /* Release First TB, as this would be anyway there*/
651 rgDHMRlsHqProcTB(cellCb, hqP, 1);
652 if(2 == hqP->numOfTBs)
654 rgDHMRlsHqProcTB(cellCb, hqP, 2);
660 if (rgGetEventMem(inst,(Ptr *)&datReq, sizeof(TfuDatReqPduInfo),
661 &(datInfo->memCp)) != ROK)
665 /* Fill the TFU Dat Req with information from Harq Proc */
667 rgDHMBldTfuDatReq(cellCb, dlSf, hqP, datReq);
669 /* MS_WORKAROUND for ccpu00122894 */
670 for(i=0;i< RG_MAX_TB_PER_UE;i++)
672 if (hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf == dlSf)
674 cmLListDelFrm(&dlSf->tbs, &(hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk));
675 hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk.node = NULLP;
678 hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf = NULLP;
681 cmLListAdd2Tail(&datInfo->pdus, &(datReq->lnk));
682 datReq->lnk.node = (PTR)datReq;
685 } /* rgDHMSndDatReq */
688 * @brief Function to handle RGU datReq received from ROM
692 * Function : rgDHMHndlDedDatReq
694 * This function shall act on the datReq received on RGU. It shall
695 * store the data IDs for all the logical channels and get the MAC
699 * @param[in] Inst inst
700 * @param[in] RgDlHqProcCb *hqProc
701 * @param[in] RgRguDedDatReq *datReq
702 * @param[out] RgErrInfo *err
708 PUBLIC S16 rgDHMHndlDedDatReq
711 RgDlHqProcCb *hqProc,
712 RgRguDDatReqPerUe *datReq,
717 PUBLIC S16 rgDHMHndlDedDatReq(inst,hqProc, datReq, dlSf, err)
719 RgDlHqProcCb *hqProc;
720 RgRguDDatReqPerUe *datReq;
731 RgTfuDatReqTbInfo *tb;
734 TRC2(rgDHMHndlDedDatReq);
736 tbIndex = (U8)(datReq->transId & 0x03);
737 /* Accept all the data requests even if delayed in case nothing
738 * has been sent earlier on the harq proc.
740 if((datReq->nmbOfTbs > RG_MAX_TB_PER_UE) ||
743 /* release corresponding TBs from SF tbs List */
744 for(j=0;j<datReq->nmbOfTbs;j++)
746 if (!(tbIndex & (j+1)))
750 rgDHMRlsHqProcTB(rgCb[inst].cell, hqProc, (U8)(j+1));
755 for(i=0;i<datReq->nmbOfTbs;i++)
757 /* tbIndex 01 corresponds to presence of 1st TB
758 * 10 corresponds 2nd TB
759 * 11 corresponds two TBs of UE */
760 if (!(tbIndex & (i+1)))
764 if (hqProc->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk.node == NULLP)
766 /* release corresponding TBs from SF tbs List */
767 for(j=0;j<datReq->nmbOfTbs;j++)
769 if (!(tbIndex & (j+1)))
773 rgDHMRlsHqProcTB(rgCb[inst].cell, hqProc, (U8)(j+1));
774 printf("\nrgDHMHndlDedDatReq:: hqP %p \n", (Void *)hqProc);
780 RG_FREE_MSG(hqProc->tbInfo[i].tb);
781 /* L2 optimization for mUe/Tti: Pre-allocated mBuf pointers(macHdr,
782 * macCes and MacPad) of harq TB need to be reset to db_base
785 tb = &hqProc->tbInfo[i].tb;
786 if (tb->tbPres == TRUE)
791 bldPdu.datReq = datReq;
792 bldPdu.reqType = EVTRGUDDATREQ;
793 bldPdu.schdTbSz = hqProc->tbInfo[i].tbSz;
794 bldPdu.tbIndex = i+1;
795 bldPdu.ta = hqProc->tbInfo[i].schdTa;
797 bldPdu.sCellActCe= hqProc->tbInfo[i].sCellActCe;
799 bldPdu.contResId = NULLP;
801 /* Store tbId from RLC in DDatRequest */
802 hqProc->tbId[i] = datReq->datReqTb[i].tbId;
805 hqProc->status[i] = FALSE;
807 if(rgMUXBldPdu(inst,&bldPdu, &(hqProc->tbInfo[i].tb), err) != ROK)
809 RLOG1(L_ERROR, "MUXing failed for: MacInst %d", inst);
810 RLOG4(L_ERROR, "MUXing failed for: time: %d/%d\
811 procId %d ueId %d", hqProc->tbInfo[i].timingInfo.sfn,
812 hqProc->tbInfo[i].timingInfo.slot, hqProc->procId,
813 hqProc->tbInfo[i].pdcch.rnti);
815 /* release corresponding TBs from SF tbs List */
816 for(j=0;j<datReq->nmbOfTbs;j++)
818 if (!(tbIndex & (j+1)))
822 rgDHMRlsHqProcTB(rgCb[inst].cell, hqProc, (U8)(j+1));
827 SFndLenMsg(hqProc->tbInfo[i].tb, &len);
831 } /* rgDHMHndlDedDatReq */
834 * @brief Function to handle RGU datReq received from ROM
838 * Function : rgDHMHndlCmnDatReq
840 * This function shall act on the datReq received on RGU. It shall
841 * store the data IDs for all the logical channels and get the MAC
845 * @param[in] Inst inst
846 * @param[in] RgDlHqProcCb *hqProc
847 * @param[in] RgRguCmnDatReq *datReq
848 * @param[out] RgErrInfo *err
854 PUBLIC S16 rgDHMHndlCmnDatReq
857 RgDlHqProcCb *hqProc,
858 RgRguCmnDatReq *datReq,
862 PUBLIC S16 rgDHMHndlCmnDatReq(inst,hqProc, datReq, err)
864 RgDlHqProcCb *hqProc;
865 RgRguCmnDatReq *datReq;
872 TRC2(rgDHMHndlCmnDatReq)
875 if (hqProc->tbInfo[0].tb != NULLP)
877 /* If numLch is non zero means HQ Proc is busy*/
878 if (hqProc->tbInfo[0].tb.tbPres)
881 /* datReq discarded. Generate an alarm */
882 rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_HARQ);
883 rgLMMStaInd(inst,LCM_CATEGORY_PROTOCOL, LCM_EVENT_UI_INV_EVT,
884 LRG_CAUSE_HQ_PROC_BUSY, &dgn);
888 bldPdu.datReq = datReq;
889 bldPdu.reqType = EVTRGUCDATREQ;
890 bldPdu.schdTbSz = hqProc->tbInfo[0].tbSz;
891 bldPdu.ta = hqProc->tbInfo[0].schdTa;
893 bldPdu.sCellActCe= hqProc->tbInfo[0].sCellActCe;
896 bldPdu.contResId = hqProc->tbInfo[0].contResId;
898 if(rgMUXBldPdu(inst,&bldPdu, &(hqProc->tbInfo[0].tb), err) != ROK)
900 RLOG1(L_ERROR, "MUXing failed for: MacInst %d", inst);
901 RLOG4(L_ERROR, "MUXing failed for: time: %d/%d\
902 procId %d ueId %d", hqProc->tbInfo[0].timingInfo.sfn,
903 hqProc->tbInfo[0].timingInfo.slot, hqProc->procId,
904 hqProc->tbInfo[0].pdcch.rnti);
906 RG_FREE_MSG(datReq->pdu);
911 } /* rgDHMHndlCmnDatReq */
914 * @brief Function to get consolidate grants and send consolidated grant to RLC
918 * Function : rgDHMSndConsolidatedStaInd
920 * This function shall be invoked by Scheduler to trigger DHM to send a
921 * consolidated status indication of all UE scheduled in a TTI as well as
922 * send consolidated CStaInd for MSG4 and for all common channels(PCCH,
923 * if RGR_SI_SCH is not defined then it includes BCH and BCCH also)
926 * @param[in] RgCellCb *cell
927 * @param[in] RgInfUeInfo *ueInfo,
928 * @param[in] CmLteTimingInfo timingInfo,
929 * @param[out] RgErrInfo err
930 * @param[in] RguCStaIndInfo *cStaInd
937 PUBLIC S16 rgDHMSndConsolidatedStaInd
941 CmLteTimingInfo timingInfo,
945 PUBLIC S16 rgDHMSndConsolidatedStaInd(cell, ueInfo, timingInfo, err)
948 CmLteTimingInfo timingInfo;
952 SuId rguDlSpId;/*need to use spID instead of suID*/
957 RgDlSf *dlSf = &cell->subFrms[(timingInfo.slot % RG_NUM_SUB_FRAMES)];
958 Inst inst = cell->macInst - RG_INST_START;
959 // Bool isDStaReqrd = FALSE;
960 RgRguDedStaInd *dStaInd[rgCb[inst].numRguSaps] ;
961 RgUpSapCb *rguDlSap[rgCb[inst].numRguSaps];
966 RgInfUeAlloc *allocInfo;
970 Bool hqPAdded = FALSE;
973 RgTfuDatReqTbInfo *tb; /* TB to be sent to CL/PHY*/
976 TRC2(rgDHMSndConsolidatedStaInd)
977 cmMemset ((U8 *)dStaInd, 0, (sizeof(RgRguDedStaInd *) * rgCb[inst].numRguSaps));
978 cmMemset ((U8 *)rguDlSap, 0, (sizeof(RgUpSapCb *) * rgCb[inst].numRguSaps));
980 /* Send StaInd for the scheduled UEs */
981 for(ueIdx = 0; ueIdx < ueInfo->numUes; ueIdx++)
986 if((ue=rgDBMGetUeCb (cell, ueInfo->allocInfo[ueIdx].rnti)) == NULLP)
988 /* Check in RachLst */
989 if((ue=rgDBMGetUeCbFromRachLst (cell,
990 ueInfo->allocInfo[ueIdx].rnti)) == NULLP)
992 RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"CRNTI:%d No ueCb found",
993 ueInfo->allocInfo[ueIdx].rnti);
994 /*Fix: If one UE is not present dont return, look for the next.*/
1000 rgDHMGetHqProcFrmId(ue,ueInfo->allocInfo[ueIdx].hqProcId,&hqP);
1001 allocInfo = &ueInfo->allocInfo[ueIdx];
1004 /* Fix : syed Avoid sending data for a RETX
1005 * if initial TX data processing was unsuccessful */
1006 if((allocInfo->tbInfo[0].isReTx == TRUE) &&
1007 (hqP->tbInfo[0].tbSz == 0))
1009 RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
1010 "CRNTI:%d RETX hqP(%d) tb(0) for a failed New Tx",
1011 allocInfo->rnti, hqP->procId);
1014 if((allocInfo->tbInfo[1].isReTx == TRUE) &&
1015 (hqP->tbInfo[1].tbSz == 0))
1017 RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
1018 "CRNTI:%d RETX hqP(%d) tb(1) for a failed New Tx",
1019 allocInfo->rnti, hqP->procId);
1023 if(ue->rguDlSap != NULLP)
1025 rguDlSpId = ue->rguDlSap->sapCfg.spId;
1027 {/* UeCb is from rachList */
1028 rguDlSpId = cell->rguDlSap->sapCfg.spId;
1032 for(idx=allocInfo->tbStrtIdx;((idx-allocInfo->tbStrtIdx) <\
1033 allocInfo->nmbOfTBs); idx++)
1035 RguCStaIndInfo *cStaInd;
1037 /* LTE_ADV_FLAG_REMOVED_START */
1038 hqP->tbInfo[idx].isEnbSFR = allocInfo->isEnbSFR;
1039 /* update pA value */
1040 hqP->tbInfo[idx].pa = allocInfo->pa;
1041 /* LTE_ADV_FLAG_REMOVED_END */
1044 hqP->numOfTBs = allocInfo->nmbOfTBs;
1045 hqP->tbInfo[idx].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk.node = (PTR)hqP;
1046 hqP->tbInfo[idx].sfLnkInfo[dlSf->schdTime.slot % 2].sf = dlSf;
1047 cmLListAdd2Tail(&dlSf->tbs,&(hqP->tbInfo[idx].sfLnkInfo[dlSf->schdTime.slot % 2].sfLnk));
1048 /* Changes as part of performance testing*/
1049 /* hqP->numOfTBs++;*/
1050 hqP->tbInfo[idx].doa = allocInfo->doa;
1051 hqP->tbInfo[idx].txMode = allocInfo->txMode;
1052 hqP->tbInfo[idx].puschRptUsd = allocInfo->puschRptUsd;
1053 hqP->tbInfo[idx].puschPmiInfo = allocInfo->puschPmiInfo;
1055 hqP->tbInfo[idx].pdcch.rnti = allocInfo->pdcchRnti;
1057 hqP->tbInfo[idx].pdcch.rnti = allocInfo->rnti;
1059 if(allocInfo->tbInfo[idx].isReTx == TRUE)
1061 hqP->tbInfo[idx].pdcch.dci = allocInfo->dciInfo;
1065 hqP->tbInfo[idx].timingInfo = timingInfo;
1066 hqP->tbInfo[idx].pdcch.dci = allocInfo->dciInfo;
1068 RG_FREE_MSG(hqP->tbInfo[idx].tb);
1070 /* L2 optimization for mUe/Tti: Pre-allocated mBuf pointers(macHdr,
1071 * macCes and MacPad) of harq TB need to be reset to db_base
1073 tb = &(hqP->tbInfo[idx].tb);
1074 if (tb->tbPres == TRUE)
1079 hqP->tbInfo[idx].tbSz = allocInfo->tbInfo[idx].schdTbSz;
1081 hqP->tbInfo[idx].schdTa.pres = allocInfo->tbInfo[idx].ta.pres;
1082 hqP->tbInfo[idx].schdTa.val = allocInfo->tbInfo[idx].ta.val;
1085 hqP->tbInfo[idx].sCellActCe.pres = allocInfo->tbInfo[idx].sCellActCe.pres;
1086 hqP->tbInfo[idx].sCellActCe.val = allocInfo->tbInfo[idx].sCellActCe.val;
1090 if(( hqPAdded == TRUE) || (ROK == rgLaaPushHqPToScellLst(allocInfo,cell,timingInfo)))
1096 if (allocInfo->tbInfo[idx].schdDat[0].lcId == RG_CCCH_LCID)
1099 RG_FREE_MSG(hqP->tbInfo[idx].tb);
1101 /* L2 optimization for mUe/Tti: Pre-allocated mBuf pointers(macHdr,
1102 * macCes and MacPad) of harq TB need to be reset to db_base
1104 tb = &(hqP->tbInfo[idx].tb);
1106 if (tb->tbPres == TRUE)
1111 hqP->tbInfo[0].contResCe = allocInfo->tbInfo[0].contResCe;
1112 if(allocInfo->tbInfo[0].contResCe)
1114 hqP->tbInfo[0].contResId = &ue->contResId;
1118 if(allocInfo->tbInfo[idx].numSchLch == 0)
1120 RLOG_ARG2(L_DEBUG,DBG_CELLID,cell->cellId,
1121 "UEID:%d MSG4 with only contResId hqP(%d)",
1124 hqP->tbInfo[idx].numSchLch = 0;
1128 /* Increamenting the tbIndex instead of
1129 assigning it to constant */
1133 hqP->tbInfo[idx].numSchLch = 1;
1134 hqP->tbInfo[idx].schdData[0].lcId =
1135 allocInfo->tbInfo[idx].schdDat[0].lcId;
1136 hqP->tbInfo[idx].schdData[0].schdSz =
1137 allocInfo->tbInfo[idx].schdDat[0].numBytes;
1139 // if(cStaInd == NULLP)
1141 if ((rgAllocShrablSBuf(inst,(Data**)&cStaInd, sizeof(RguCStaIndInfo))) != ROK)
1143 err->errType = RGERR_DHM_SND_STA_IND;
1144 err->errCause = RG_DHM_MEM_ALLOC_FAIL;
1149 idx1 = (hqP->procId << 2) | tbIndex;
1151 cStaInd->cellId = cell->cellId;
1152 cStaInd->rnti = allocInfo->rnti;
1153 cStaInd->lcId = cell->dlCcchId;
1154 cStaInd->transId = (timingInfo.sfn << 16) |
1155 (timingInfo.slot << 8) | idx1;
1156 /* ADD Changes for Downlink UE Timing Optimization */
1157 #ifdef LTEMAC_DLUE_TMGOPTMZ
1158 dlSf->remDatReqCnt++;
1160 RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,
1161 "RNTI:%d UE:MSG4 grant for CCCH hqP(%d) LCID:%d",
1165 /* Fix : syed Avoid return param for interface prim and
1166 * proceed for other UEs. For the failed UE, MAC shall
1168 rgUIMSndCmnStaInd(cell->macInst,cell->rguDlSap,cStaInd);
1175 RG_FREE_MSG(hqP->tbInfo[idx].tb);
1177 /* L2 optimization for mUe/Tti: Pre-allocated mBuf pointers(macHdr,
1178 * macCes and MacPad) of harq TB need to be reset to db_base
1180 tb = &(hqP->tbInfo[idx].tb);
1181 if (tb->tbPres == TRUE)
1187 if((NULLP == dStaInd[rguDlSpId]) && (allocInfo->tbInfo[idx].numSchLch))
1189 if ((rgAllocShrablSBuf (inst,(Data**)&dStaInd[rguDlSpId], sizeof(RguDStaIndInfo))) != ROK)
1191 err->errType = RGERR_DHM_SND_STA_IND;
1192 err->errCause = RG_DHM_MEM_ALLOC_FAIL;
1193 /* Need to return as memory allocation will fail for other UEs also*/
1196 dStaInd[rguDlSpId]->nmbOfUeGrantPerTti = 0;
1197 rguDlSap[rguDlSpId] = ue->rguDlSap;
1202 lcIdx < allocInfo->tbInfo[idx].numSchLch; lcIdx++)
1204 hqP->tbInfo[idx].schdData[lcIdx].lcId =
1205 allocInfo->tbInfo[idx].schdDat[lcIdx].lcId;
1206 if (hqP->tbInfo[idx].schdData[lcIdx].lcId == 0)
1208 RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
1209 "CCCH grant in DStaInd for LCID:%d CRNTI:%d",
1210 hqP->tbInfo[idx].schdData[lcIdx].lcId,allocInfo->rnti);
1212 hqP->tbInfo[idx].schdData[lcIdx].schdSz =
1213 allocInfo->tbInfo[idx].schdDat[lcIdx].numBytes;
1214 if(dStaInd[rguDlSpId])
1216 dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].staIndTb[idx].\
1217 lchStaInd[lcIdx].lcId = allocInfo->tbInfo[idx].\
1218 schdDat[lcIdx].lcId;
1219 dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].staIndTb[idx].\
1220 lchStaInd[lcIdx].totBufSize = allocInfo->tbInfo[idx].\
1221 schdDat[lcIdx].numBytes;
1224 lchBufSize+=allocInfo->tbInfo[idx].schdDat[lcIdx].numBytes;
1226 hqP->tbInfo[idx].numSchLch =
1227 allocInfo->tbInfo[idx].numSchLch;
1228 if(dStaInd[rguDlSpId])
1230 dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].staIndTb[idx].nmbLch =
1231 allocInfo->tbInfo[idx].numSchLch;
1233 dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].staIndTb[idx].tbId =
1240 //if((dStaInd) && (tbIndex) && (isDStaReqrd == TRUE))
1241 if((dStaInd[rguDlSpId]) && (tbIndex))
1243 idx1 = (hqP->procId << 2) | tbIndex;
1244 /* Create RguDStaInd struct and send to UIM */
1245 dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].rnti = allocInfo->rnti;
1247 dStaInd->transId = (hqP->timingInfo.sfn << 16) |
1248 (hqP->timingInfo.slot << 8) | hqP->procId;
1250 dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].transId = (timingInfo.sfn << 16) |
1251 (timingInfo.slot << 8) | idx1;
1252 dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].nmbOfTbs = hqP->numOfTBs;
1254 dStaInd[rguDlSpId]->staInd[dStaInd[rguDlSpId]->nmbOfUeGrantPerTti].fillCtrlPdu = allocInfo->fillCtrlPdu;
1256 /*increment num of UE as staInd is prepared for it */
1257 dStaInd[rguDlSpId]->nmbOfUeGrantPerTti++;
1258 /* ADD Changes for Downlink UE Timing Optimization */
1259 #ifdef LTEMAC_DLUE_TMGOPTMZ
1260 dlSf->remDatReqCnt++;
1263 //isDStaReqrd = FALSE;
1267 for(idx = 0; idx < rgCb[inst].numRguSaps ; idx++)
1269 if(dStaInd[idx] != NULLP)
1271 dStaInd[idx]->cellId = cell->cellId;
1272 /* Fix : syed Avoid return param for interface prim and
1273 * proceed for other UEs. For the failed UE, MAC shall
1275 rgUIMSndDedStaInd(inst,rguDlSap[idx],dStaInd[idx]);
1278 if(staIndCnt == activeSapCnt)
1279 break;/* all valid staind are considered */
1284 } /* rgDHMSndConsolidatedStaInd */
1288 * @brief Function to handle building the TFU Data Request
1292 * Function : rgDHMBldTfuDatReq
1294 * This function builds the TFU Data Request with the details
1295 * present in HARQ Process.
1297 * @param[in] RgDlHqProcCb *hqP
1298 * @param[out] TfuDatReqPduInfo *datReq
1304 PRIVATE Void rgDHMBldTfuDatReq
1309 RgTfuDatReqPduInfo *datReq
1312 PRIVATE Void rgDHMBldTfuDatReq(cellCb, dlSf, hqP, datReq)
1316 RgTfuDatReqPduInfo *datReq;
1321 #if !(!(defined TENB_ACC) && !(defined LTE_PAL_ENB))
1323 #elif defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD)
1333 TRC2(rgDHMBldTfuDatReq)
1335 datReq->nmbOfTBs = 0;
1337 #if !(!(defined TENB_ACC) && !(defined LTE_PAL_ENB))
1338 inst = cellCb->macInst - RG_INST_START;
1339 #elif defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD)
1340 inst = cellCb->macInst - RG_INST_START;
1343 /*MS_WORKAROUND for ccpu00123904*/
1344 datReq->isTApres = FALSE;
1345 #ifdef TFU_ALLOC_EVENT_NO_INIT
1347 datReq->mBuf[0] = 0;
1348 datReq->mBuf[1] = 0;
1352 for(i=0;i<RG_MAX_TB_PER_UE;i++)
1355 if ((hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf == dlSf) &&
1356 (hqP->tbInfo[i].tb != NULLP))
1358 if ((hqP->tbInfo[i].sfLnkInfo[dlSf->schdTime.slot % 2].sf == dlSf) &&
1359 RgUtlIsTbMuxed(&(hqP->tbInfo[i].tb)))
1363 datReq->rnti = hqP->tbInfo[i].pdcch.rnti;
1364 datReq->dciInfo = hqP->tbInfo[i].pdcch.dci;
1365 datReq->doa = hqP->tbInfo[i].doa;
1366 datReq->transMode = hqP->tbInfo[i].txMode;
1367 datReq->puschRptUsd = hqP->tbInfo[i].puschRptUsd;
1368 datReq->puschPmiInfo = hqP->tbInfo[i].puschPmiInfo;
1369 /*MS_WORKAROUND for ccpu00123904*/
1370 if (hqP->tbInfo[i].schdTa.pres)
1372 datReq->isTApres = TRUE;
1375 /* update pA value */
1376 datReq->pa = hqP->tbInfo[i].pa;
1378 /* LTE_ADV_FLAG_REMOVED_START */
1379 datReq->isEnbSFR = hqP->tbInfo[i].isEnbSFR;
1380 /* LTE_ADV_FLAG_REMOVED_END */
1382 #if (!(defined TENB_ACC) && !(defined LTE_PAL_ENB)) /* ABHI */ /* This is only temp fix. It needs to be removed
1383 after rebasing to MAC CCB */
1385 datReq->mBuf[i] = hqP->tbInfo[i].tb;
1387 /* Intel Tdd- Commenting out the Optimization for direct Access of
1389 /*Proper clean-up needed as this needs long stability tests
1391 #if defined(TENB_T2K3K_SPECIFIC_CHANGES) && defined(LTE_TDD)
1392 SIncMsgRef(hqP->tbInfo[i].tb, RG_GET_MEM_REGION(rgCb[inst]),
1393 RG_GET_MEM_POOL(rgCb[inst]), &datReq->mBuf[i]);
1395 datReq->mBuf[i] = hqP->tbInfo[i].tb;
1399 SIncMsgRef(hqP->tbInfo[i].tb, RG_GET_MEM_REGION(rgCb[inst]),
1400 RG_GET_MEM_POOL(rgCb[inst]), &datReq->mBuf[i]);
1404 if(SFndLenMsg(datReq->mBuf[i], &dbgBufLen))
1408 RLOG_ARG4(L_ERROR,DBG_CELLID,cellCb->cellId,
1409 "RNTI:%d SFN:%d slot:%d tbIdx:%d Sdu Length 0 ",
1411 hqP->tbInfo[i].timingInfo.sfn,
1412 hqP->tbInfo[i].timingInfo.slot,i);
1413 RLOG_ARG3(L_ERROR,DBG_CELLID,cellCb->cellId,
1414 "taPres [%d] numOfTbs [%d] format[%d]",
1417 datReq->dciInfo.format);
1422 /* L2 optimization for mUe/Tti: Removing SIncMsgRef to avoid additional
1423 * mBuf allocation. MAC header, MAC Ces, MAC PDU per LCH per TB Per UE
1424 * and MAC padding Mbufs are being sent to CL. Populating these Ptrs
1425 * From TB Info to TfuDatReq
1427 datReq->tbInfo[i].tbPres = TRUE;
1428 datReq->tbInfo[i].tbSize = hqP->tbInfo[i].tbSz;
1429 datReq->tbInfo[i].macHdr = hqP->tbInfo[i].tb.macHdr;
1430 datReq->tbInfo[i].macCes = hqP->tbInfo[i].tb.macCes;
1431 datReq->tbInfo[i].numLch = hqP->tbInfo[i].tb.numLch;
1432 for(lchIdx = 0; lchIdx < hqP->tbInfo[i].tb.numLch; lchIdx++)
1434 datReq->tbInfo[i].lchInfo[lchIdx].numPdu = hqP->tbInfo[i].tb.\
1435 lchInfo[lchIdx].numPdu;
1436 for(pduIdx = 0; pduIdx < hqP->tbInfo[i].tb.lchInfo[lchIdx].numPdu;\
1439 datReq->tbInfo[i].lchInfo[lchIdx].mBuf[pduIdx] =
1440 hqP->tbInfo[i].tb.lchInfo[lchIdx].mBuf[pduIdx];
1443 // datReq->tbInfo[i].macPad = hqP->tbInfo[i].tb.macPad;
1444 datReq->tbInfo[i].padSize = hqP->tbInfo[i].tb.padSize;
1445 // prc_trace_format_string(0x40,3,"TfuDatReq:RNTI=%d TbIdx=%d TbSize=%d PdSz=(%d) macHdraddr: (%p) macCEAddr: (%p) noLch=(%d)",datReq->rnti, i,
1446 // hqP->tbInfo[i].tbSz, datReq->tbInfo[i].padSize, datReq->tbInfo[i].macHdr, datReq->tbInfo[i].macCes, datReq->tbInfo[i].numLch);
1453 } /* rgDHMBldTfuDatReq */
1458 * @brief This function releases a HARQ process
1462 * Function: rgDHMFreeHqProcTB
1463 * Purpose: This function returns a HARQ process to HARQ Entity
1464 * in the DL direction.
1466 * 1. Add the HARQ process to the free queue.
1467 * Invoked by: scheduler and HARQ processing
1469 * @param[in] RgDlHqProc *hqP
1474 PUBLIC S16 rgDHMFreeHqProcTB
1480 PUBLIC S16 rgDHMFreeHqProcTB(hqP, tbIndex)
1485 RgTfuDatReqTbInfo *tb; /* TB to be sent to CL/PHY*/
1488 TRC2(rgDHMFreeHqProcTB)
1490 if((tbIndex > RG_MAX_TB_PER_UE) ||
1496 tb = &(hqP->tbInfo[tbIndex-1].tb);
1497 RG_FREE_MSG(tb->macHdr);
1498 RG_FREE_MSG(tb->macCes);
1500 for(idx = 0; idx < 2; idx++)
1502 if (hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk.node != NULLP)
1504 cmLListDelFrm(&hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sf->tbs,
1505 &(hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk));
1506 hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sfLnk.node = (PTR)NULLP;
1507 printf("\nrgDHMFreeHqProcTB:: hqP %p \n", (Void *)hqP);
1509 hqP->tbInfo[tbIndex-1].sfLnkInfo[idx].sf = NULLP;
1518 * @brief Handler for freeing up the harq related information from ueCb
1522 * Function : rgDHMFreeUe
1524 * This function shall free up the HARQ specific information from ueCb.
1526 * @param[in] Inst inst
1527 * @param[in] RgDlHqEnt *hqE
1533 PUBLIC Void rgDHMFreeUe
1539 PUBLIC Void rgDHMFreeUe(inst,hqE)
1549 /* Free all the memory associated with HARQ */
1550 for (i=0; i < hqE->numHqProcs; i++)
1553 rgDHMRlsHqProcTB(rgCb[inst].cell, hqE->procs[i], 1);
1554 rgDHMRlsHqProcTB(rgCb[inst].cell, hqE->procs[i], 2);
1556 rgDHMFreeHqProcTB(hqE->procs[i], 1);
1557 rgDHMFreeHqProcTB(hqE->procs[i], 2);
1560 rgFreeSBuf(inst,(Data **)&(hqE->procs[i]), sizeof(RgDlHqProcCb));
1562 rgDHMFreeSavedHqP(inst,hqE,i);
1566 /*ccpu00117052 - MOD - Passing double pointer for proper NULLP
1574 * @brief Function for handling RaResp request received from scheduler to MAC
1578 * Function : RgSchMacRstHqEntReq
1580 * This function shall be invoked whenever a sec cell of an ue
1581 * is deactivated. MAC needs to reset the harqentity associated
1582 * with the deactivated scell of the ue
1585 * @param[in] Pst *pst
1586 * @param[in] RgInfResetHqEnt *hqEntInfo
1591 PUBLIC S16 RgSchMacRstHqEntReq
1594 RgInfResetHqEnt* hqEntInfo
1597 PUBLIC S16 RgSchMacRstHqEntReq(pst, hqEntInfo)
1599 RgInfResetHqEnt* hqEntInfo;
1606 inst = pst->dstInst - RG_INST_START;
1608 if (((cell = rgCb[inst].cell) == NULLP) ||
1609 (rgCb[inst].cell->cellId != hqEntInfo->cellId))
1611 RGDBGERRNEW(inst,(rgPBuf(inst), "For user [%d]Cell does not exist %d\n",
1612 hqEntInfo->crnti,hqEntInfo->cellId));
1616 if ((ue = rgDBMGetUeCb(cell, hqEntInfo->crnti)) == NULLP)
1618 RGDBGERRNEW(inst,(rgPBuf(inst), "[%d]UE does not exist for this hqEntInfo\n",
1623 rgDHMUeReset(cell, &ue->dl.hqEnt);
1630 * @brief Function for handling RaResp request received from scheduler to MAC
1634 * Function : RgSchMacRlsHqReq
1636 * This function shall be invoked whenever scheduler is done with the
1637 * allocations of random access responses for a slot.
1638 * This shall invoke RAM to create ueCbs for all the rapIds allocated and
1639 * shall invoke MUX to create RAR PDUs for raRntis allocated.
1642 * @param[in] CmLteCellId cellId,
1643 * @param[in] CmLteTimingInfo timingInfo,
1644 * @param[in] RaRespInfo *rarInfo
1649 PUBLIC S16 RgSchMacRlsHqReq
1652 RgInfRlsHqInfo *rlshqUeInfo
1655 PUBLIC S16 RgSchMacRlsHqReq(pst, rlshqUeInfo)
1657 RgInfRlsHqInfo *rlshqUeInfo;
1661 RgCellCb *cell = NULLP;
1667 RguHarqStatusInd hqStaInd;
1668 Bool isValidTbId = FALSE;
1672 TRC2(RgSchMacRlsHqReq)
1674 RG_IS_INST_VALID(pst->dstInst);
1675 inst = pst->dstInst - RG_INST_START;
1676 cell = rgCb[inst].cell;
1678 SStartTask(&startTime, PID_MAC_AM_HARQ_RLS);
1680 if(NULLP == rlshqUeInfo)
1686 ||( cell->cellId != rlshqUeInfo->cellId))
1689 RLOG_ARG0(L_ERROR,DBG_CELLID,rlshqUeInfo->cellId,
1690 "No cellCb found with cellId");
1694 if(NULLP == rlshqUeInfo->ueHqInfo)
1699 for(idx1 = 0; idx1 < rlshqUeInfo->numUes; idx1++)
1701 if((ue=rgDBMGetUeCb (cell, rlshqUeInfo->ueHqInfo[idx1].rnti)) == NULLP)
1703 /* Check in RachLst */
1704 if((ue=rgDBMGetUeCbFromRachLst (cell,
1705 rlshqUeInfo->ueHqInfo[idx1].rnti)) == NULLP)
1707 RLOG_ARG1(L_ERROR,DBG_CELLID,rlshqUeInfo->cellId, "CRNTI:%d No ueCb found",
1708 rlshqUeInfo->ueHqInfo[idx1].rnti);
1714 if ((rlshqUeInfo->ueHqInfo[idx1].rlsOperationType && !gSaveVal) || (rlshqUeInfo->ueHqInfo[idx1].hqProcId > 8))
1717 RLOG_ARG1(L_INFO," SPURIOUS CALLL !!!! procId %d \n", rlshqUeInfo->ueHqInfo[idx1].hqProcId);
1720 printf ("RgSchMacRlsHqReq cell %d : numUes %d idx %d rnti %d hqProc %d numTbs %d tbid[0] %d tbid[1] %d rlsopr %d \n",
1722 rlshqUeInfo->numUes,
1724 rlshqUeInfo->ueHqInfo[idx1].rnti,
1725 rlshqUeInfo->ueHqInfo[idx1].hqProcId,
1726 rlshqUeInfo->ueHqInfo[idx1].numOfTBs,
1727 rlshqUeInfo->ueHqInfo[idx1].tbId[0],
1728 rlshqUeInfo->ueHqInfo[idx1].tbId[1],
1729 rlshqUeInfo->ueHqInfo[idx1].rlsOperationType);
1737 RgSchMacHndlRelReq(cell, ue, &rlshqUeInfo->ueHqInfo[idx1]);
1739 if (RGINF_RLS_HQ_DEL_TB == rlshqUeInfo->ueHqInfo[idx1].rlsOperationType)
1741 /* If REQ is to DEL the saved TBs no need to free the HqP as it's already
1745 #endif /* LTE_ADV */
1746 rgDHMGetHqProcFrmId(ue,rlshqUeInfo->ueHqInfo[idx1].hqProcId,&hqP);
1747 if(rlshqUeInfo->ueHqInfo[idx1].status[0] != TRUE)
1749 rgCb[inst].genSts.numHarqFail++;
1753 hqStaInd.cellId = cell->cellId;
1754 hqStaInd.ueId = rlshqUeInfo->ueHqInfo[idx1].rnti;
1755 hqStaInd.numTbs = rlshqUeInfo->ueHqInfo[idx1].numOfTBs;
1758 for(idx2=0; idx2 < rlshqUeInfo->ueHqInfo[idx1].numOfTBs; idx2++)
1761 /* Fill the hq sta Ind stucture. Need to send the Status Ind for only
1762 those TBID's reported by Scheduler*/
1763 tbId = rlshqUeInfo->ueHqInfo[idx1].tbId[idx2];
1764 if (hqP->tbId[tbId-1] != RGU_INVALID_TBID)
1766 /* Fill the correct Sn Map corresponding to the TBID */
1767 hqStaInd.tbId[idx2] = hqP->tbId[tbId-1];
1768 hqStaInd.status[idx2] = rlshqUeInfo->ueHqInfo[idx1].status[idx2];
1772 if(rgDHMRlsHqProcTB(cell, hqP,
1773 rlshqUeInfo->ueHqInfo[idx1].tbId[idx2]) != ROK)
1775 RLOG_ARG1(L_ERROR,DBG_CELLID,rlshqUeInfo->cellId,
1776 "CRNTI:%d Failure in releasing hq TB",
1777 rlshqUeInfo->ueHqInfo[idx1].rnti);
1788 RgUiRguHqStaInd(&(ue->rguDlSap->sapCfg.sapPst),
1789 ue->rguDlSap->sapCfg.suId,
1793 {/* Ue is from rach list*/
1794 RgUiRguHqStaInd(&(cell->rguDlSap->sapCfg.sapPst),
1795 cell->rguDlSap->sapCfg.suId,
1800 } /* end of ues loop */
1803 SStopTask(startTime,PID_MAC_AM_HARQ_RLS);
1806 } /* end of RgSchMacRlsHqReq */
1809 /**********************************************************************
1812 **********************************************************************/