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 *******************************************************************************/
18 #include "common_def.h"
24 #include "du_app_mac_inf.h"
25 #include "mac_sch_interface.h"
27 #include "sch_utils.h"
33 SchMacDlReleaseHarqFunc schMacDlReleaseHarqOpts[] =
35 packSchMacDlReleaseHarq,
36 MacSchReleaseDlHarqProc,
37 packSchMacDlReleaseHarq
40 typedef struct schCellCb SchCellCb;
41 typedef struct schUeCb SchUeCb;
42 void schDlHqEntReset(SchCellCb *cellCb, SchUeCb *ueCb, SchDlHqEnt *hqE);
43 void schDlHqAddToFreeList(SchDlHqProcCb *hqP);
46 * @brief DL Harq entity intialization
50 * Function : schDlHqEntInit
52 * This function intialize DL Harq entity
54 * @param[in] SchCellCb *cellCb, cell cb pointer
55 * @param[in] SchUeCb *ueCb, ue cb pointer
59 void schDlHqEntInit(SchCellCb *cellCb, SchUeCb *ueCb)
61 ueCb->dlHqEnt.numHqPrcs = SCH_MAX_NUM_DL_HQ_PROC;
62 ueCb->dlHqEnt.maxHqTx = cellCb->cellCfg.schHqCfg.maxDlDataHqTx;
63 ueCb->dlHqEnt.cell = cellCb;
64 ueCb->dlHqEnt.ue =ueCb;
65 schDlHqEntReset(cellCb, ueCb, &ueCb->dlHqEnt);
68 * @brief DL Harq entity Reset
72 * Function : schDlHqEntReset
74 * This function Reset DL Harq entity
76 * @param[in] SchCellCb *cellCb, cell cb pointer
77 * @param[in] SchUeCb *ueCb, ue cb pointer
78 * @param[in] SchDlHqEnt *hqE, Dl Harq entity pointer
82 void schDlHqEntReset(SchCellCb *cellCb, SchUeCb *ueCb, SchDlHqEnt *hqE)
85 SchDlHqProcCb *hqP = NULL;
86 cmLListInit(&hqE->free);
87 cmLListInit(&hqE->inUse);
89 for(count=0; count < hqE->numHqPrcs; count++)
91 hqP = &(hqE->procs[count]);
94 hqP->maxHqTxPerHqP = hqE->maxHqTx;
95 hqP->dlHqEntLnk.node = (PTR)hqP;
96 hqP->dlHqProcLink.node = (PTR)hqP;
97 hqP->ulSlotLnk.node = (PTR)hqP;
98 schDlHqAddToFreeList(hqP);
102 * @brief Add hq process to free list of DL Harq entity
106 * Function : schDlHqAddToFreeList
108 * This function adds hq process to free list of DL Harq entity
110 * @param[in] SchDlHqProcCb *hqP, DL harq process pointer
114 void schDlHqAddToFreeList(SchDlHqProcCb *hqP)
116 cmLListAdd2Tail(&(hqP->hqEnt->free), &hqP->dlHqEntLnk);
119 * @brief Delete hq process from free list of DL Harq entity
123 * Function : schDlHqDeleteFromFreeList
125 * This function deletes hq process to free list of DL Harq entity
127 * @param[in] SchDlHqProcCb *hqP, DL harq process pointer
131 void schDlHqDeleteFromFreeList(SchDlHqProcCb *hqP)
133 cmLListDelFrm(&(hqP->hqEnt->free), &hqP->dlHqEntLnk);
136 * @brief Add hq process to in use list of DL Harq entity
140 * Function : schDlHqAddToInUseList
142 * This function adds hq process to in use list of DL Harq entity
144 * @param[in] SchDlHqProcCb *hqP, DL harq process pointer
148 void schDlHqAddToInUseList(SchDlHqProcCb *hqP)
150 cmLListAdd2Tail(&(hqP->hqEnt->inUse), &hqP->dlHqEntLnk);
153 * @brief Delete hq process from in use list of DL Harq entity
157 * Function : schDlHqDeleteFromInUseList
159 * This function deletes hq process to in use list of DL Harq entity
161 * @param[in] SchDlHqProcCb *hqP, DL harq process pointer
165 void schDlHqDeleteFromInUseList(SchDlHqProcCb *hqP)
167 cmLListDelFrm(&(hqP->hqEnt->inUse), &hqP->dlHqEntLnk);
170 * @brief Get available Harq process from Harq entity
174 * Function : schDlGetAvlHqProcess
176 * This function fetches hq process from free list and puts in in use list
178 * @param[in] SchCellCb *cellCb, cell cb pointer
179 * @param[in] SchUeCb *ueCb, ue cb pointer
180 * @param[in] SchDlHqProcCb **hqP, Address of DL harq process pointer
185 uint8_t schDlGetAvlHqProcess(SchCellCb *cellCb, SchUeCb *ueCb, SchDlHqProcCb **hqP)
188 if (ueCb->dlHqEnt.free.count == 0)
192 tmp = (SchDlHqProcCb*)(cmLListFirst(&(ueCb->dlHqEnt.free))->node);
197 schDlHqDeleteFromFreeList(tmp);
198 schDlHqAddToInUseList(tmp);
200 (*hqP)->maxHqTxPerHqP = ueCb->dlHqEnt.maxHqTx;
204 * @brief Release Harq process from the DL Harq entity
208 * Function : schDlReleaseHqProcess
210 * This function releases Harq process from DL Harq entity
212 * @param[in] SchDlHqProcCb *hqP, DL harq process pointer
216 void schDlReleaseHqProcess(SchDlHqProcCb *hqP)
220 cmLListDeleteLList(&hqP->dlLcPrbEst.dedLcList);
221 cmLListDeleteLList(&hqP->dlLcPrbEst.defLcList);
222 schDlHqDeleteFromInUseList(hqP);
223 schDlHqAddToFreeList(hqP);
227 /*******************************************************************
229 * @brief Handles sending DL HARQ process release to MAC
233 * Function : sendDlHarqProcReleaseToMac
236 * Sends DL DL HARQ process release to MAC from SCH
239 * @return ROK - success
242 * ****************************************************************/
243 uint8_t sendDlHarqProcReleaseToMac(SchDlHqProcCb *hqP, Inst inst)
246 SchRlsHqInfo *rlsHqInfo;
247 memset(&pst, 0, sizeof(Pst));
248 FILL_PST_SCH_TO_MAC(pst, inst);
249 pst.event = EVENT_DL_REL_HQ_PROC;
251 SCH_ALLOC(rlsHqInfo, sizeof(SchRlsHqInfo));
252 rlsHqInfo->cellId = hqP->hqEnt->cell->cellId;
253 rlsHqInfo->numUes = 1;
255 SCH_ALLOC(rlsHqInfo->ueHqInfo, sizeof(SchUeHqInfo)*rlsHqInfo->numUes);
256 rlsHqInfo->ueHqInfo[0].crnti = hqP->hqEnt->ue->crnti;
257 rlsHqInfo->ueHqInfo[0].hqProcId = hqP->procId;
259 return(*schMacDlReleaseHarqOpts[pst.selector])(&pst, rlsHqInfo);
262 * @brief Release Harq process TB from the DL Harq process
266 * Function : schDlReleaseHqPTb
268 * This function releases Harq process TB from DL Harq proces
270 * @param[in] SchDlHqProcCb *hqP, DL harq process pointer
271 * @param[in] uint8_t tbIdx, TB index
272 * @param[in] bool togNdi, indication to toggle NDI bit
276 void schDlReleaseHqPTb(SchDlHqProcCb *hqP, uint8_t tbIdx, bool togNdi)
280 hqP->tbInfo[tbIdx].ndi ^= 1;
284 hqP->tbInfo[tbIdx].isAckNackDtx = HQ_ACK;
285 hqP->tbInfo[tbIdx].isEnabled = FALSE;
286 hqP->tbInfo[tbIdx].state = HQ_TB_ACKED;
287 hqP->tbInfo[tbIdx].txCntr = 0;
288 if (HQ_TB_ACKED == hqP->tbInfo[tbIdx^1].state)
290 schDlReleaseHqProcess(hqP);
291 sendDlHarqProcReleaseToMac(hqP, hqP->hqEnt->cell->instIdx);
296 * @brief Handles failure of HARQ process TB
300 * Function : schDlHqTbFail
302 * This function handles failure of HARQ process TB
304 * @param[in] SchDlHqProcCb *hqP, DL harq process pointer
305 * @param[in] uint8_t tbIdx, TB index
306 * @param[in] bool isMaxRetx, indicates max retransmission
310 void schDlHqTbFail(SchDlHqProcCb *hqP, uint8_t tbIdx, bool isMaxRetx)
314 schDlReleaseHqPTb(hqP, tbIdx, TRUE);
318 hqP->tbInfo[tbIdx].state = HQ_TB_NACKED;
319 if (HQ_TB_WAITING == hqP->tbInfo[tbIdx^1].state)
321 cmLListAdd2Tail( &(hqP->hqEnt->ue->dlRetxHqList), &hqP->dlHqProcLink);
326 * @brief Handles Harq feedback for MSG4
330 * Function : schMsg4FeedbackUpdate
332 * This function handles Harq feedback for MSG4
334 * @param[in] SchDlHqProcCb *hqP, DL harq process pointer
335 * @param[in] uint8_t fdbk, Received feedback
339 void schMsg4FeedbackUpdate(SchDlHqProcCb *hqP, uint8_t fdbk)
341 hqP->tbInfo[0].isAckNackDtx = fdbk;
342 hqP->tbInfo[1].isAckNackDtx = HQ_TB_ACKED;
343 if (HQ_TB_ACKED == hqP->tbInfo[0].isAckNackDtx)
345 schDlReleaseHqPTb(hqP, 0, TRUE);
346 schDlReleaseHqPTb(hqP, 1, TRUE);
347 schMsg4Complete(hqP->hqEnt->ue);
351 if( hqP->tbInfo[0].txCntr >= hqP->hqEnt->cell->cellCfg.schHqCfg.maxMsg4HqTx)
353 schDlReleaseHqProcess(hqP);
354 hqP->hqEnt->ue->msg4Proc = NULLP;
355 hqP->hqEnt->ue->retxMsg4HqProc = NULLP;
356 /* Delete UE and RA context */
358 addUeToBeScheduled(hqP->hqEnt->cell,hqP->hqEnt->ue->ueId);
359 hqP->hqEnt->ue->retxMsg4HqProc = hqP;
363 * @brief Handles Harq feedback for DL Data
367 * Function : schDlHqFeedbackUpdate
369 * This function handles Harq feedback for DL data
371 * @param[in] SchDlHqProcCb *hqP, DL harq process pointer
372 * @param[in] uint8_t fdbk1, Received feedback for TB -0
373 * @param[in] uint8_t fdbk2, Received feedback for TB -1
377 void schDlHqFeedbackUpdate(SchDlHqProcCb *hqP, uint8_t fdbk1, uint8_t fdbk2)
380 for (tbIdx = 0; tbIdx <2; tbIdx++)
382 if (HQ_TB_WAITING == hqP->tbInfo[tbIdx].state)
384 hqP->tbInfo[tbIdx].isAckNackDtx = (0 == tbIdx)?fdbk1:fdbk2;
386 if (TRUE == hqP->tbInfo[tbIdx].isEnabled)
388 if (HQ_TB_ACKED == hqP->tbInfo[tbIdx].isAckNackDtx)
390 schDlReleaseHqPTb(hqP, tbIdx, TRUE);
394 if(hqP->tbInfo[tbIdx].txCntr >= hqP->maxHqTxPerHqP)
396 schDlHqTbFail(hqP, tbIdx, TRUE);
400 schDlHqTbFail(hqP, tbIdx, FALSE);
402 if(hqP->hqEnt->ue->ueDrxInfoPres == true)
404 schDrxStrtDlHqRttTmr(hqP);
409 addUeToBeScheduled(hqP->hqEnt->cell, hqP->hqEnt->ue->ueId);
416 /**********************************************************************
418 **********************************************************************/