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 typedef struct schCellCb SchCellCb;
34 typedef struct schUeCb SchUeCb;
35 void schDlHqEntReset(SchCellCb *cellCb, SchUeCb *ueCb, SchDlHqEnt *hqE);
36 void schDlHqAddToFreeList(SchDlHqProcCb *hqP);
39 * @brief DL Harq entity intialization
43 * Function : schDlHqEntInit
45 * This function intialize DL Harq entity
47 * @param[in] SchCellCb *cellCb, cell cb pointer
48 * @param[in] SchUeCb *ueCb, ue cb pointer
52 void schDlHqEntInit(SchCellCb *cellCb, SchUeCb *ueCb)
54 ueCb->dlHqEnt.numHqPrcs = SCH_MAX_NUM_DL_HQ_PROC;
55 ueCb->dlHqEnt.maxHqTx = cellCb->schHqCfg.maxDlDataHqTx;
56 ueCb->dlHqEnt.cell = cellCb;
57 ueCb->dlHqEnt.ue =ueCb;
58 schDlHqEntReset(cellCb, ueCb, &ueCb->dlHqEnt);
61 * @brief DL Harq entity Reset
65 * Function : schDlHqEntReset
67 * This function Reset DL Harq entity
69 * @param[in] SchCellCb *cellCb, cell cb pointer
70 * @param[in] SchUeCb *ueCb, ue cb pointer
71 * @param[in] SchDlHqEnt *hqE, Dl Harq entity pointer
75 void schDlHqEntReset(SchCellCb *cellCb, SchUeCb *ueCb, SchDlHqEnt *hqE)
78 SchDlHqProcCb *hqP = NULL;
79 cmLListInit(&hqE->free);
80 cmLListInit(&hqE->inUse);
82 for(count=0; count < hqE->numHqPrcs; count++)
84 hqP = &(hqE->procs[count]);
87 hqP->maxHqTxPerHqP = hqE->maxHqTx;
88 hqP->dlHqEntLnk.node = (PTR)hqP;
89 hqP->dlHqProcLink.node = (PTR)hqP;
90 hqP->ulSlotLnk.node = (PTR)hqP;
91 cellCb->api->SchInitDlHqProcCb(hqP);
92 schDlHqAddToFreeList(hqP);
96 * @brief Add hq process to free list of DL Harq entity
100 * Function : schDlHqAddToFreeList
102 * This function adds hq process to free list of DL Harq entity
104 * @param[in] SchDlHqProcCb *hqP, DL harq process pointer
108 void schDlHqAddToFreeList(SchDlHqProcCb *hqP)
110 cmLListAdd2Tail(&(hqP->hqEnt->free), &hqP->dlHqEntLnk);
113 * @brief Delete hq process from free list of DL Harq entity
117 * Function : schDlHqDeleteFromFreeList
119 * This function deletes hq process to free list of DL Harq entity
121 * @param[in] SchDlHqProcCb *hqP, DL harq process pointer
125 void schDlHqDeleteFromFreeList(SchDlHqProcCb *hqP)
127 cmLListDelFrm(&(hqP->hqEnt->free), &hqP->dlHqEntLnk);
130 * @brief Add hq process to in use list of DL Harq entity
134 * Function : schDlHqAddToInUseList
136 * This function adds hq process to in use list of DL Harq entity
138 * @param[in] SchDlHqProcCb *hqP, DL harq process pointer
142 void schDlHqAddToInUseList(SchDlHqProcCb *hqP)
144 cmLListAdd2Tail(&(hqP->hqEnt->inUse), &hqP->dlHqEntLnk);
147 * @brief Delete hq process from in use list of DL Harq entity
151 * Function : schDlHqDeleteFromInUseList
153 * This function deletes hq process to in use list of DL Harq entity
155 * @param[in] SchDlHqProcCb *hqP, DL harq process pointer
159 void schDlHqDeleteFromInUseList(SchDlHqProcCb *hqP)
161 cmLListDelFrm(&(hqP->hqEnt->inUse), &hqP->dlHqEntLnk);
164 * @brief Get available Harq process from Harq entity
168 * Function : schDlGetAvlHqProcess
170 * This function fetches hq process from free list and puts in in use list
172 * @param[in] SchCellCb *cellCb, cell cb pointer
173 * @param[in] SchUeCb *ueCb, ue cb pointer
174 * @param[in] SchDlHqProcCb **hqP, Address of DL harq process pointer
179 uint8_t schDlGetAvlHqProcess(SchCellCb *cellCb, SchUeCb *ueCb, SchDlHqProcCb **hqP)
182 if (ueCb->dlHqEnt.free.count == 0)
186 tmp = (SchDlHqProcCb*)(cmLListFirst(&(ueCb->dlHqEnt.free))->node);
191 schDlHqDeleteFromFreeList(tmp);
192 schDlHqAddToInUseList(tmp);
194 (*hqP)->maxHqTxPerHqP = ueCb->dlHqEnt.maxHqTx;
198 * @brief Release Harq process from the DL Harq entity
202 * Function : schDlReleaseHqProcess
204 * This function releases Harq process from DL Harq entity
206 * @param[in] SchDlHqProcCb *hqP, DL harq process pointer
210 void schDlReleaseHqProcess(SchDlHqProcCb *hqP)
212 SchCellCb *cellCb = NULLP;
215 cellCb = hqP->hqEnt->cell;
216 cellCb->api->SchFreeDlHqProcCb(hqP);
217 schDlHqDeleteFromInUseList(hqP);
218 schDlHqAddToFreeList(hqP);
222 /*******************************************************************
224 * @brief Handles sending DL HARQ process release to MAC
228 * Function : sendDlHarqProcReleaseToMac
231 * Sends DL DL HARQ process release to MAC from SCH
234 * @return ROK - success
237 * ****************************************************************/
238 uint8_t sendDlHarqProcReleaseToMac(SchDlHqProcCb *hqP, Inst inst)
241 SchRlsHqInfo *rlsHqInfo;
242 memset(&pst, 0, sizeof(Pst));
243 FILL_PST_SCH_TO_MAC(pst, inst);
244 pst.event = EVENT_DL_REL_HQ_PROC;
246 SCH_ALLOC(rlsHqInfo, sizeof(SchRlsHqInfo));
247 rlsHqInfo->cellId = hqP->hqEnt->cell->cellId;
248 rlsHqInfo->numUes = 1;
250 SCH_ALLOC(rlsHqInfo->ueHqInfo, sizeof(SchUeHqInfo)*rlsHqInfo->numUes);
251 rlsHqInfo->ueHqInfo[0].crnti = hqP->hqEnt->ue->crnti;
252 rlsHqInfo->ueHqInfo[0].hqProcId = hqP->procId;
254 return(MacMessageRouter(&pst, (void *)rlsHqInfo));
257 * @brief Release Harq process TB from the DL Harq process
261 * Function : schDlReleaseHqPTb
263 * This function releases Harq process TB from DL Harq proces
265 * @param[in] SchDlHqProcCb *hqP, DL harq process pointer
266 * @param[in] uint8_t tbIdx, TB index
267 * @param[in] bool togNdi, indication to toggle NDI bit
271 void schDlReleaseHqPTb(SchDlHqProcCb *hqP, uint8_t tbIdx, bool togNdi)
275 hqP->tbInfo[tbIdx].ndi ^= 1;
279 hqP->tbInfo[tbIdx].isAckNackDtx = HQ_ACK;
280 hqP->tbInfo[tbIdx].isEnabled = FALSE;
281 hqP->tbInfo[tbIdx].state = HQ_TB_ACKED;
282 hqP->tbInfo[tbIdx].txCntr = 0;
283 if (HQ_TB_ACKED == hqP->tbInfo[tbIdx^1].state)
285 schDlReleaseHqProcess(hqP);
286 sendDlHarqProcReleaseToMac(hqP, hqP->hqEnt->cell->instIdx);
291 * @brief Handles failure of HARQ process TB
295 * Function : schDlHqTbFail
297 * This function handles failure of HARQ process TB
299 * @param[in] SchDlHqProcCb *hqP, DL harq process pointer
300 * @param[in] uint8_t tbIdx, TB index
301 * @param[in] bool isMaxRetx, indicates max retransmission
305 void schDlHqTbFail(SchDlHqProcCb *hqP, uint8_t tbIdx, bool isMaxRetx)
309 schDlReleaseHqPTb(hqP, tbIdx, TRUE);
313 hqP->tbInfo[tbIdx].state = HQ_TB_NACKED;
314 if (HQ_TB_WAITING == hqP->tbInfo[tbIdx^1].state)
316 hqP->hqEnt->cell->api->SchAddToDlHqRetxList(hqP);
321 * @brief Handles Harq feedback for MSG4
325 * Function : schMsg4FeedbackUpdate
327 * This function handles Harq feedback for MSG4
329 * @param[in] SchDlHqProcCb *hqP, DL harq process pointer
330 * @param[in] uint8_t fdbk, Received feedback
334 void schMsg4FeedbackUpdate(SchDlHqProcCb *hqP, uint8_t fdbk)
336 hqP->tbInfo[0].isAckNackDtx = fdbk;
337 hqP->tbInfo[1].isAckNackDtx = HQ_TB_ACKED;
338 if (HQ_TB_ACKED == hqP->tbInfo[0].isAckNackDtx)
340 schDlReleaseHqPTb(hqP, 0, TRUE);
341 schDlReleaseHqPTb(hqP, 1, TRUE);
342 schMsg4Complete(hqP->hqEnt->ue);
346 if( hqP->tbInfo[0].txCntr >= hqP->hqEnt->cell->schHqCfg.maxMsg4HqTx)
348 schDlReleaseHqProcess(hqP);
349 hqP->hqEnt->ue->msg4HqProc = NULLP;
350 hqP->hqEnt->ue->retxMsg4HqProc = NULLP;
351 /* Delete UE and RA context */
353 hqP->hqEnt->cell->api->SchAddUeToSchedule(hqP->hqEnt->cell,hqP->hqEnt->ue->ueId);
354 hqP->hqEnt->ue->retxMsg4HqProc = hqP;
359 * @brief Handles Harq feedback for DL Data
363 * Function : schDlHqFeedbackUpdate
365 * This function handles Harq feedback for DL data
367 * @param[in] SchDlHqProcCb *hqP, DL harq process pointer
368 * @param[in] uint8_t fdbk1, Received feedback for TB -0
369 * @param[in] uint8_t fdbk2, Received feedback for TB -1
373 void schDlHqFeedbackUpdate(SchDlHqProcCb *hqP, uint8_t fdbk1, uint8_t fdbk2)
376 for (tbIdx = 0; tbIdx <2; tbIdx++)
378 if (HQ_TB_WAITING == hqP->tbInfo[tbIdx].state)
380 hqP->tbInfo[tbIdx].isAckNackDtx = (0 == tbIdx)?fdbk1:fdbk2;
382 if (TRUE == hqP->tbInfo[tbIdx].isEnabled)
384 if (HQ_TB_ACKED == hqP->tbInfo[tbIdx].isAckNackDtx)
386 schDlReleaseHqPTb(hqP, tbIdx, TRUE);
390 if(hqP->tbInfo[tbIdx].txCntr >= hqP->maxHqTxPerHqP)
392 schDlHqTbFail(hqP, tbIdx, TRUE);
396 schDlHqTbFail(hqP, tbIdx, FALSE);
404 * @brief Deletes HARQ Entity
408 * Function : schDlHqEntDelete
410 * This function deletes HARQ entity and its member paremeters
412 * @param[in] Pointer to UE
416 void schDlHqEntDelete(SchUeCb *ueCb)
421 cmLListDeleteLList(&ueCb->dlHqEnt.free);
422 cmLListDeleteLList(&ueCb->dlHqEnt.inUse);
423 for(count=0; count < ueCb->dlHqEnt.numHqPrcs; count++)
425 hqP = &(ueCb->dlHqEnt.procs[count]);
426 ueCb->cellCb->api->SchDeleteDlHqProcCb(hqP);
428 memset(&ueCb->dlHqEnt, 0, sizeof(SchDlHqEnt));
431 /**********************************************************************
433 **********************************************************************/