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 **********************************************************************/
31 /** @file sch_common.c
32 @brief This module performs common scheduling
34 #include "common_def.h"
41 #include "du_app_mac_inf.h"
42 #include "mac_sch_interface.h"
44 #include "sch_utils.h"
46 SchCb schCb[SCH_MAX_INST];
47 uint16_t prachCfgIdxTable[MAX_PRACH_CONFIG_IDX][8];
48 uint16_t numRbForPrachTable[MAX_RACH_NUM_RB_IDX][5];
49 uint8_t pucchResourceSet[MAX_PUCCH_RES_SET_IDX][4];
50 uint8_t puschDeltaTable[MAX_MU_PUSCH];
52 SchMacUlSchInfoFunc schMacUlSchInfoOpts[] =
60 * @brief common resource allocation for SSB
64 * Function : schBroadcastSsbAlloc
66 * This function handles common scheduling for SSB
68 * @param[in] SchCellCb *cell, cell cb
69 * @param[in] DlBrdcstAlloc *dlBrdcstAlloc, DL brdcst allocation
72 uint8_t schBroadcastSsbAlloc(SchCellCb *cell, SlotTimingInfo slotTime, DlBrdcstAlloc *dlBrdcstAlloc)
75 uint8_t ssbStartSymb, idx;
77 SchDlSlotInfo *schDlSlotInfo;
80 schDlSlotInfo = cell->schDlSlotInfo[slotTime.slot];
81 ssbStartPrb = cell->cellCfg.ssbSchCfg.ssbOffsetPointA; //+Kssb
82 ssbStartSymb = cell->ssbStartSymbArr[dlBrdcstAlloc->ssbIdxSupported-1]; /*since we are
83 supporting only 1 ssb beam */
85 /* Assign interface structure */
86 for(idx=0; idx<dlBrdcstAlloc->ssbIdxSupported; idx++)
89 ssbInfo.fdAlloc.startPrb = ssbStartPrb;
90 ssbInfo.fdAlloc.numPrb = SCH_SSB_NUM_PRB;
91 ssbInfo.tdAlloc.startSymb = ssbStartSymb;
92 ssbInfo.tdAlloc.numSymb = SCH_SSB_NUM_SYMB;
93 dlBrdcstAlloc->ssbInfo[idx] = ssbInfo;
94 schDlSlotInfo->ssbInfo[idx] = ssbInfo;
97 if((allocatePrbDl(cell, slotTime, ssbStartSymb, SCH_SSB_NUM_SYMB, &ssbInfo.fdAlloc.startPrb, ssbInfo.fdAlloc.numPrb)) != ROK)
99 DU_LOG("\nERROR --> SCH: PRB allocation failed for SSB in SFN:SLOT [%d : %d]", slotTime.sfn, slotTime.slot);
104 schDlSlotInfo->ssbPres = true;
105 schDlSlotInfo->ssbIdxSupported = dlBrdcstAlloc->ssbIdxSupported;
110 * @brief common resource allocation for SIB1
114 * Function : schBroadcastSib1Alloc
116 * This function handles common scheduling for SIB1
118 * @param[in] SchCellCb *cell, cell cb
119 * @param[in] DlBrdcstAlloc *dlBrdcstAlloc, DL brdcst allocation
122 uint8_t schBroadcastSib1Alloc(SchCellCb *cell, SlotTimingInfo slotTime, DlBrdcstAlloc *dlBrdcstAlloc)
124 FreqDomainAlloc freqAlloc = cell->cellCfg.sib1SchCfg.sib1PdschCfg.pdschFreqAlloc.freqAlloc;
125 TimeDomainAlloc timeAlloc = cell->cellCfg.sib1SchCfg.sib1PdschCfg.pdschTimeAlloc.timeAlloc;
126 SchDlSlotInfo *schDlSlotInfo = cell->schDlSlotInfo[slotTime.slot];
128 if((allocatePrbDl(cell, slotTime, timeAlloc.startSymb, timeAlloc.numSymb, &freqAlloc.startPrb, freqAlloc.numPrb)) != ROK)
130 DU_LOG("\nERROR --> SCH: PRB allocation failed for SIB1 in SFN:Slot [%d : %d]", slotTime.sfn, slotTime.slot);
134 memcpy(&dlBrdcstAlloc->sib1Alloc.bwp, &cell->cellCfg.sib1SchCfg.bwp, sizeof(BwpCfg));
135 memcpy(&dlBrdcstAlloc->sib1Alloc.sib1PdcchCfg, &cell->cellCfg.sib1SchCfg.sib1PdcchCfg, sizeof(PdcchCfg));
136 memcpy(&dlBrdcstAlloc->sib1Alloc.sib1PdschCfg, &cell->cellCfg.sib1SchCfg.sib1PdschCfg, sizeof(PdschCfg));
137 dlBrdcstAlloc->sib1Alloc.sib1PdcchCfg.dci.pdschCfg = &dlBrdcstAlloc->sib1Alloc.sib1PdschCfg;
138 schDlSlotInfo->sib1Pres = true;
142 /*******************************************************************
144 * @brief Handles sending UL scheduler info to MAC
148 * Function : sendUlSchInfoToMac
151 * Sends UL Sch info to MAC from SCH
154 * @return ROK - success
157 * ****************************************************************/
158 int sendUlSchInfoToMac(UlSchedInfo *ulSchedInfo, Inst inst)
162 memset(&pst, 0, sizeof(Pst));
163 FILL_PST_SCH_TO_MAC(pst, inst);
164 pst.event = EVENT_UL_SCH_INFO;
166 return(*schMacUlSchInfoOpts[pst.selector])(&pst, ulSchedInfo);
169 * @brief resource allocation for PRACH
173 * Function : schPrachResAlloc
175 * This function handles PRACH allocation
177 * @param[in] SchCellCb *cell, cell cb
178 * @param[in] UlSchedInfo *ulSchedInfo, UL scheduling info
181 void schPrachResAlloc(SchCellCb *cell, UlSchedInfo *ulSchedInfo, SlotTimingInfo prachOccasionTimingInfo)
184 uint8_t numPrachRb = 0;
186 uint8_t freqStart = 0;
187 uint8_t prachCfgIdx = 0;
188 uint8_t prachFormat = 0;
191 uint16_t prachSubframe = 0;
192 uint8_t prachStartSymbol = 0;
193 uint8_t prachOcas = 0;
194 uint8_t dataType = 0;
196 uint8_t subFrame = 0;
197 SchUlSlotInfo *schUlSlotInfo = NULLP;
199 puschScs = cell->cellCfg.schInitialUlBwp.bwp.scs;
200 schUlSlotInfo = cell->schUlSlotInfo[prachOccasionTimingInfo.slot];
201 prachCfgIdx = cell->cellCfg.schRachCfg.prachCfgIdx;
203 /* derive the prachCfgIdx table paramters */
204 x = prachCfgIdxTable[prachCfgIdx][1];
205 y = prachCfgIdxTable[prachCfgIdx][2];
206 prachSubframe = prachCfgIdxTable[prachCfgIdx][3];
208 if((prachOccasionTimingInfo.sfn%x) == y)
211 subFrame = prachOccasionTimingInfo.slot/2;
213 subFrame = prachOccasionTimingInfo.slot;
215 /* check for subFrame number */
216 if ((1 << subFrame) & prachSubframe)
218 /* prach ocassion present in this subframe */
220 if(UL_SLOT != schGetSlotSymbFrmt(prachOccasionTimingInfo.slot%cell->numSlotsInPeriodicity,\
221 cell->slotFrmtBitMap))
223 DU_LOG("\nERROR --> SCH : PrachCfgIdx %d doesn't support UL slot", prachCfgIdx);
228 prachFormat = prachCfgIdxTable[prachCfgIdx][0];
229 prachStartSymbol = prachCfgIdxTable[prachCfgIdx][4];
230 prachOcas = prachCfgIdxTable[prachCfgIdx][6];
232 /* freq domain resource determination for RACH*/
233 freqStart = cell->cellCfg.schRachCfg.msg1FreqStart;
234 /* numRa determined as 𝑛 belonging {0,1,.., M − 1},
235 * where M is given by msg1Fdm */
236 numRa = (cell->cellCfg.schRachCfg.msg1Fdm - 1);
237 for(idx=0; idx<MAX_RACH_NUM_RB_IDX; idx++)
239 if(numRbForPrachTable[idx][0] == cell->cellCfg.schRachCfg.rootSeqLen)
241 if(numRbForPrachTable[idx][1] == cell->cellCfg.schRachCfg.prachSubcSpacing)
243 if(numRbForPrachTable[idx][2] == puschScs)
250 numPrachRb = numRbForPrachTable[idx][3];
251 dataType |= SCH_DATATYPE_PRACH;
252 /* Considering first slot in the frame for PRACH */
254 //schUlSlotInfo->assignedPrb[idx] = freqStart+numPrachRb;
256 ulSchedInfo->dataType = dataType;
258 ulSchedInfo->prachSchInfo.numPrachOcas = prachOcas;
259 ulSchedInfo->prachSchInfo.prachFormat = prachFormat;
260 ulSchedInfo->prachSchInfo.numRa = numRa;
261 ulSchedInfo->prachSchInfo.prachStartSymb = prachStartSymbol;
262 DU_LOG("\nINFO --> SCH : RACH occassion set for slot %d", prachOccasionTimingInfo.slot);
269 * @brief Function to fill Pucch Format 0
273 * Function : fillPucchFormat0
275 * Function to fill Pucch format 0
277 * @param[in] SchPucchInfo pointer, SchPucchResrcInfo pointer
281 void fillPucchFormat0(SchPucchInfo *ulSchedPucch, SchPucchResrcInfo *resrcInfo)
283 if(resrcInfo->SchPucchFormat.format0)
285 ulSchedPucch->fdAlloc.numPrb = PUCCH_NUM_PRB_FORMAT_0_1_4;
286 ulSchedPucch->pucchFormat = PUCCH_FORMAT_0;
287 ulSchedPucch->initialCyclicShift = resrcInfo->SchPucchFormat.format0->initialCyclicShift;
288 ulSchedPucch->tdAlloc.numSymb = resrcInfo->SchPucchFormat.format0->numSymbols;
289 ulSchedPucch->tdAlloc.startSymb = resrcInfo->SchPucchFormat.format0->startSymbolIdx;
294 * @brief Function to fill Pucch Format 1
298 * Function : fillPucchFormat1
300 * Function to fill Pucch format 1
302 * @param[in] SchPucchInfo pointer, SchPucchResrcInfo pointer
306 void fillPucchFormat1(SchPucchInfo *ulSchedPucch, SchPucchResrcInfo *resrcInfo)
308 if(resrcInfo->SchPucchFormat.format1)
310 ulSchedPucch->fdAlloc.numPrb = PUCCH_NUM_PRB_FORMAT_0_1_4;
311 ulSchedPucch->pucchFormat = PUCCH_FORMAT_1;
312 ulSchedPucch->initialCyclicShift = resrcInfo->SchPucchFormat.format1->initialCyclicShift;
313 ulSchedPucch->tdAlloc.numSymb = resrcInfo->SchPucchFormat.format1->numSymbols;
314 ulSchedPucch->tdAlloc.startSymb = resrcInfo->SchPucchFormat.format1->startSymbolIdx;
315 ulSchedPucch->timeDomOCC = resrcInfo->SchPucchFormat.format1->timeDomOCC;
320 * @brief Function to fill Pucch format for UL Sched Info
324 * Function : fillUlSchedPucchFormat
326 * Function to fill Pucch format for UL Sched Info
328 * @param[in] pucchFormat , SchPucchInfo pointer,
329 * @param[in] SchPucchFormatCfg pointer, SchPucchResrcInfo pointer
333 uint8_t fillUlSchedPucchFormat(uint8_t pucchFormat, SchPucchInfo *ulSchedPucch,\
334 SchPucchResrcInfo *resrcInfo, SchPucchFormatCfg *formatCfg)
343 fillPucchFormat0(ulSchedPucch, resrcInfo);
350 fillPucchFormat1(ulSchedPucch, resrcInfo);
354 memcpy(&ulSchedPucch->cmnFormatCfg, formatCfg, sizeof(SchPucchFormatCfg));
357 }/* To Add support for more Pucch Format */
360 DU_LOG("\nERROR --> SCH : Invalid PUCCH format[%d] in fillUlSchedPucchFormatCfg()", pucchFormat);
368 * @brief Function to fill Pucch Dedicated Cfg for UL Sched Info
372 * Function : fillUlSchedPucchDedicatedCfg
374 * Function to fill Pucch Dedicated Cfg for UL Sched Info
376 * @param[in] pucchFormat to be filled
377 * @param[in] SchPucchFormatCfg pointer, SchPucchCfg pointer
381 uint8_t fillUlSchedPucchDedicatedCfg(uint16_t numSlots, SchPucchCfg *pucchDedCfg,\
382 SlotTimingInfo *slotInfo, SchPucchInfo *ulSchedPucch)
384 uint8_t ret, resrcSetIdx, resrcIdx, schedReqIdx, srPeriodicity = 0;
385 uint16_t srOffset = 0;
388 if(pucchDedCfg->resrcSet && pucchDedCfg->resrc)
390 //Assuming one entry in the list
391 for(resrcSetIdx = 0; resrcSetIdx < pucchDedCfg->resrcSet->resrcSetToAddModListCount; resrcSetIdx++)
393 for(resrcIdx = 0; resrcIdx < pucchDedCfg->resrc->resrcToAddModListCount; resrcIdx++)
395 if(pucchDedCfg->resrcSet->resrcSetToAddModList[resrcSetIdx].resrcList[resrcSetIdx] ==\
396 pucchDedCfg->resrc->resrcToAddModList[resrcIdx].resrcId)
398 ulSchedPucch->intraFreqHop = pucchDedCfg->resrc->resrcToAddModList[resrcIdx].intraFreqHop;
399 ulSchedPucch->secondPrbHop = pucchDedCfg->resrc->resrcToAddModList[resrcIdx].secondPrbHop;
400 ulSchedPucch->fdAlloc.startPrb = pucchDedCfg->resrc->resrcToAddModList[resrcIdx].startPrb;
401 ulSchedPucch->pucchFormat = pucchDedCfg->resrc->resrcToAddModList[resrcIdx].pucchFormat;
402 ret = fillUlSchedPucchFormat(ulSchedPucch->pucchFormat, ulSchedPucch,\
403 &pucchDedCfg->resrc->resrcToAddModList[resrcIdx], NULLP);
410 if(pucchDedCfg->format1)
412 memset(&ulSchedPucch->cmnFormatCfg, 0, sizeof(SchPucchFormatCfg));
413 ret = fillUlSchedPucchFormat(ulSchedPucch->pucchFormat, ulSchedPucch, NULLP, pucchDedCfg->format1);
418 /* setting SR and UCI flag */
419 if(pucchDedCfg->schedReq)
421 for(schedReqIdx = 0; schedReqIdx < pucchDedCfg->schedReq->schedAddModListCount; schedReqIdx++)
423 srPeriodicity = pucchDedCfg->schedReq->schedAddModList[schedReqIdx].periodicity;
424 srOffset = pucchDedCfg->schedReq->schedAddModList[schedReqIdx].offset;
427 if(((numSlots * slotInfo->sfn + slotInfo->slot - srOffset) % srPeriodicity) == 0)
429 ulSchedPucch->srFlag = true;
430 ulSchedPucch->uciFlag = true;
437 * @brief Function to fill Pucch Resource Info
441 * Function : fillPucchResourceInfo
443 * Function to fill Pucch Resource Info
445 * @param[in] SchPucchInfo *schPucchInfo, Inst inst
446 * @return ROK/RFAILED
449 uint16_t fillPucchResourceInfo(SchPucchInfo *schPucchInfo, Inst inst)
451 uint8_t ret = ROK, ueIdx = 0, pucchIdx = 0;
452 SchCellCb *cell = schCb[inst].cells[inst];
453 SchPucchCfgCmn *pucchCfg = NULLP;
454 SchBwpParams *ulBwp = NULLP;
456 GET_UE_IDX(schPucchInfo->rnti, ueIdx);
457 if(cell->ueCb[ueIdx].ueCfg.spCellCfg.servCellCfg.initUlBwp.pucchCfgPres)
459 /* fill pucch dedicated cfg */
460 ret = fillUlSchedPucchDedicatedCfg(cell->numSlots,\
461 &cell->ueCb[ueIdx].ueCfg.spCellCfg.servCellCfg.initUlBwp.pucchCfg, &cell->slotInfo, schPucchInfo);
464 memset(schPucchInfo, 0, sizeof(SchPucchInfo));
465 DU_LOG("\nERROR --> SCH : Filling PUCCH dedicated cfg failed at fillPucchResourceInfo()");
471 /* fill pucch common cfg */
472 /* derive pucchResourceSet from schCellCfg */
473 pucchCfg = &cell->cellCfg.schInitialUlBwp.pucchCommon;
474 pucchIdx = pucchCfg->pucchResourceCommon;
475 ulBwp = &cell->cellCfg.schInitialUlBwp.bwp;
476 schPucchInfo->fdAlloc.startPrb = ulBwp->freqAlloc.startPrb + pucchResourceSet[pucchIdx][3];
477 schPucchInfo->fdAlloc.numPrb = PUCCH_NUM_PRB_FORMAT_0_1_4;
478 schPucchInfo->tdAlloc.startSymb = pucchResourceSet[pucchIdx][1];
479 schPucchInfo->tdAlloc.numSymb = pucchResourceSet[pucchIdx][2];
480 schPucchInfo->pucchFormat = pucchResourceSet[pucchIdx][0];
482 /* set SR and UCI flag to false */
483 schPucchInfo->srFlag = true;
484 schPucchInfo->uciFlag = true;
486 /* set HARQ flag to true */
487 schPucchInfo->harqFlag = true;
488 schPucchInfo->numHarqBits = 1; /* 1 bit for HARQ */
494 * @brief resource allocation for UL
498 * Function : schUlResAlloc
500 * This function handles UL Resource allocation
502 * @param[in] SchCellCb *cell, cellCb
505 uint8_t schUlResAlloc(SchCellCb *cell, Inst schInst)
508 UlSchedInfo ulSchedInfo;
509 SchUlSlotInfo *schUlSlotInfo = NULLP;
510 SlotTimingInfo ulTimingInfo;
511 memset(&ulSchedInfo, 0, sizeof(UlSchedInfo));
514 ADD_DELTA_TO_TIME(cell->slotInfo,ulTimingInfo,PHY_DELTA_UL+SCHED_DELTA);
516 ulSchedInfo.cellId = cell->cellId;
517 ulSchedInfo.slotIndInfo.cellId = ulSchedInfo.cellId;
518 ulSchedInfo.slotIndInfo.sfn = ulTimingInfo.sfn;
519 ulSchedInfo.slotIndInfo.slot = ulTimingInfo.slot;
521 /* Schedule resources for PRACH */
522 if(cell->firstSib1Transmitted)
523 schPrachResAlloc(cell, &ulSchedInfo, ulTimingInfo);
525 schUlSlotInfo = cell->schUlSlotInfo[ulTimingInfo.slot];
526 if(schUlSlotInfo->schPuschInfo)
528 ulSchedInfo.crnti = schUlSlotInfo->schPuschInfo->crnti;
529 ulSchedInfo.dataType |= SCH_DATATYPE_PUSCH;
530 memcpy(&ulSchedInfo.schPuschInfo, schUlSlotInfo->schPuschInfo,
531 sizeof(SchPuschInfo));
532 SCH_FREE(schUlSlotInfo->schPuschInfo, sizeof(SchPuschInfo));
533 schUlSlotInfo->schPuschInfo = NULL;
536 if(schUlSlotInfo->pucchPres)
538 ulSchedInfo.dataType |= SCH_DATATYPE_UCI;
539 fillPucchResourceInfo(&schUlSlotInfo->schPucchInfo, schInst);
540 memcpy(&ulSchedInfo.schPucchInfo, &schUlSlotInfo->schPucchInfo,
541 sizeof(SchPucchInfo));
542 memset(&schUlSlotInfo->schPucchInfo, 0, sizeof(SchPucchInfo));
546 ret = sendUlSchInfoToMac(&ulSchedInfo, schInst);
549 DU_LOG("\nERROR --> SCH : Sending UL Sch info from SCH to MAC failed");
552 schInitUlSlot(schUlSlotInfo);
556 /*******************************************************************
558 * @brief Fills pdcch and pdsch info for msg4
562 * Function : schDlRsrcAllocMsg4
565 * Fills pdcch and pdsch info for msg4
568 * @return ROK - success
571 * ****************************************************************/
572 uint8_t schDlRsrcAllocMsg4(SchCellCb *cell, SlotTimingInfo slotTime, DlMsgAlloc *msg4Alloc)
574 uint8_t coreset0Idx = 0;
576 uint8_t firstSymbol = 0;
577 uint8_t numSymbols = 0;
579 uint8_t offsetPointA;
580 uint8_t FreqDomainResource[6] = {0};
582 uint8_t mcs = 4; /* MCS fixed to 4 */
583 SchBwpDlCfg *initialBwp;
585 PdcchCfg *pdcch = &msg4Alloc->dlMsgPdcchCfg;
586 PdschCfg *pdsch = &msg4Alloc->dlMsgPdschCfg;
587 BwpCfg *bwp = &msg4Alloc->bwp;
589 initialBwp = &cell->cellCfg.schInitialDlBwp;
590 offsetPointA = cell->cellCfg.ssbSchCfg.ssbOffsetPointA;
591 coreset0Idx = initialBwp->pdcchCommon.commonSearchSpace.coresetId;
593 /* derive the sib1 coreset0 params from table 13-1 spec 38.213 */
594 numRbs = coresetIdxTable[coreset0Idx][1];
595 numSymbols = coresetIdxTable[coreset0Idx][2];
596 offset = coresetIdxTable[coreset0Idx][3];
598 /* calculate time domain parameters */
599 uint16_t mask = 0x2000;
600 for(firstSymbol=0; firstSymbol<14;firstSymbol++)
602 if(initialBwp->pdcchCommon.commonSearchSpace.monitoringSymbol & mask)
608 /* calculate the PRBs */
609 freqDomRscAllocType0(((offsetPointA-offset)/6), (numRbs/6), FreqDomainResource);
612 bwp->freqAlloc.numPrb = initialBwp->bwp.freqAlloc.numPrb;
613 bwp->freqAlloc.startPrb = initialBwp->bwp.freqAlloc.startPrb;
614 bwp->subcarrierSpacing = initialBwp->bwp.scs;
615 bwp->cyclicPrefix = initialBwp->bwp.cyclicPrefix;
617 /* fill the PDCCH PDU */
618 pdcch->coresetCfg.startSymbolIndex = firstSymbol;
619 pdcch->coresetCfg.durationSymbols = numSymbols;
620 memcpy(pdcch->coresetCfg.freqDomainResource,FreqDomainResource,6);
621 pdcch->coresetCfg.cceRegMappingType = 1; /* coreset0 is always interleaved */
622 pdcch->coresetCfg.regBundleSize = 6; /* spec-38.211 sec 7.3.2.2 */
623 pdcch->coresetCfg.interleaverSize = 2; /* spec-38.211 sec 7.3.2.2 */
624 pdcch->coresetCfg.coreSetType = 0;
625 pdcch->coresetCfg.coreSetSize = numRbs;
626 pdcch->coresetCfg.shiftIndex = cell->cellCfg.phyCellId;
627 pdcch->coresetCfg.precoderGranularity = 0; /* sameAsRegBundle */
629 pdcch->dci.rnti = cell->schDlSlotInfo[slotTime.slot]->dlMsgInfo->crnti;
630 pdcch->dci.scramblingId = cell->cellCfg.phyCellId;
631 pdcch->dci.scramblingRnti = 0;
632 pdcch->dci.cceIndex = 4; /* considering SIB1 is sent at cce 0-1-2-3 */
633 pdcch->dci.aggregLevel = 4;
634 pdcch->dci.beamPdcchInfo.numPrgs = 1;
635 pdcch->dci.beamPdcchInfo.prgSize = 1;
636 pdcch->dci.beamPdcchInfo.digBfInterfaces = 0;
637 pdcch->dci.beamPdcchInfo.prg[0].pmIdx = 0;
638 pdcch->dci.beamPdcchInfo.prg[0].beamIdx[0] = 0;
639 pdcch->dci.txPdcchPower.powerValue = 0;
640 pdcch->dci.txPdcchPower.powerControlOffsetSS = 0;
642 /* fill the PDSCH PDU */
644 pdsch->pduBitmap = 0; /* PTRS and CBG params are excluded */
645 pdsch->rnti = cell->schDlSlotInfo[slotTime.slot]->dlMsgInfo->crnti;
647 pdsch->numCodewords = 1;
648 for(cwCount = 0; cwCount < pdsch->numCodewords; cwCount++)
650 pdsch->codeword[cwCount].targetCodeRate = 308;
651 pdsch->codeword[cwCount].qamModOrder = 2;
652 pdsch->codeword[cwCount].mcsIndex = mcs; /* mcs configured to 4 */
653 pdsch->codeword[cwCount].mcsTable = 0; /* notqam256 */
654 pdsch->codeword[cwCount].rvIndex = 0;
655 tbSize = schCalcTbSize(msg4Alloc->dlMsgInfo.dlMsgPduLen + TX_PAYLOAD_HDR_LEN); /* MSG4 size + FAPI header size*/
656 pdsch->codeword[cwCount].tbSize = tbSize;
658 pdsch->dataScramblingId = cell->cellCfg.phyCellId;
659 pdsch->numLayers = 1;
660 pdsch->transmissionScheme = 0;
662 pdsch->dmrs.dlDmrsSymbPos = 4; /* Bitmap value 00000000000100 i.e. using 3rd symbol for PDSCH DMRS */
663 pdsch->dmrs.dmrsConfigType = 0; /* type-1 */
664 pdsch->dmrs.dlDmrsScramblingId = cell->cellCfg.phyCellId;
665 pdsch->dmrs.scid = 0;
666 pdsch->dmrs.numDmrsCdmGrpsNoData = 1;
667 pdsch->dmrs.dmrsPorts = 0;
668 pdsch->dmrs.mappingType = DMRS_MAP_TYPE_A; /* Setting to Type-A */
669 pdsch->dmrs.nrOfDmrsSymbols = NUM_DMRS_SYMBOLS;
670 pdsch->dmrs.dmrsAddPos = DMRS_ADDITIONAL_POS;
672 pdsch->pdschTimeAlloc.timeAlloc.startSymb = 3; /* spec-38.214, Table 5.1.2.1-1 */
673 pdsch->pdschTimeAlloc.timeAlloc.numSymb = NUM_PDSCH_SYMBOL;
675 pdsch->pdschFreqAlloc.resourceAllocType = 1; /* RAT type-1 RIV format */
676 pdsch->pdschFreqAlloc.freqAlloc.startPrb = MAX_NUM_RB;
677 pdsch->pdschFreqAlloc.freqAlloc.numPrb = schCalcNumPrb(tbSize, mcs, NUM_PDSCH_SYMBOL);
678 pdsch->pdschFreqAlloc.vrbPrbMapping = 0; /* non-interleaved */
680 /* Allocate the number of PRBs required for RAR PDSCH */
681 if((allocatePrbDl(cell, slotTime, pdsch->pdschTimeAlloc.timeAlloc.startSymb, pdsch->pdschTimeAlloc.timeAlloc.numSymb,\
682 &pdsch->pdschFreqAlloc.freqAlloc.startPrb, pdsch->pdschFreqAlloc.freqAlloc.numPrb)) != ROK)
684 DU_LOG("\nERROR --> SCH : Resource allocation failed for MSG4");
688 pdsch->beamPdschInfo.numPrgs = 1;
689 pdsch->beamPdschInfo.prgSize = 1;
690 pdsch->beamPdschInfo.digBfInterfaces = 0;
691 pdsch->beamPdschInfo.prg[0].pmIdx = 0;
692 pdsch->beamPdschInfo.prg[0].beamIdx[0] = 0;
693 pdsch->txPdschPower.powerControlOffset = 0;
694 pdsch->txPdschPower.powerControlOffsetSS = 0;
696 pdcch->dci.pdschCfg = pdsch;
701 uint16_t schAllocPucchResource(SchCellCb *cell, uint16_t crnti, uint16_t slot)
703 uint8_t k1 = SCH_DEFAULT_K1, ueIdx = 0, dlToUlAckIdx;
704 uint16_t pucchSlot = 0;
705 SchUlSlotInfo *schUlSlotInfo = NULLP;
706 SchPucchCfg *schPucchCfg = NULLP;
708 GET_UE_IDX(crnti, ueIdx);
709 if(cell->ueCb[ueIdx].ueCfg.spCellCfg.servCellCfg.initUlBwp.pucchCfgPres)
711 schPucchCfg = &(cell->ueCb[ueIdx].ueCfg.spCellCfg.servCellCfg.initUlBwp.pucchCfg);
712 if(schPucchCfg->dlDataToUlAck)
714 for(dlToUlAckIdx = 0; dlToUlAckIdx < schPucchCfg->dlDataToUlAck->dlDataToUlAckListCount; dlToUlAckIdx++)
716 //For now considering only the first value in the list
717 k1 = schPucchCfg->dlDataToUlAck->dlDataToUlAckList[dlToUlAckIdx];
723 pucchSlot = (slot + k1) % cell->numSlots;
724 schUlSlotInfo = cell->schUlSlotInfo[pucchSlot];
725 memset(&schUlSlotInfo->schPucchInfo, 0, sizeof(SchPucchInfo));
727 schUlSlotInfo->pucchPres = true;
728 schUlSlotInfo->schPucchInfo.rnti = crnti;
733 /*******************************************************************
735 * @brief Fills pdcch and pdsch info for dedicated DL msg
739 * Function : schDlRsrcAllocDlMsg
742 * Fills pdcch and pdsch info for dl msg
745 * @return ROK - success
748 * ****************************************************************/
749 uint8_t schDlRsrcAllocDlMsg(SchCellCb *cell, SlotTimingInfo slotTime, uint16_t crnti,
750 uint32_t *accumalatedSize, DlMsgAlloc *dlMsgAlloc)
754 PdcchCfg *pdcch = NULLP;
755 PdschCfg *pdsch = NULLP;
758 SchControlRsrcSet coreset1;
759 SchPdschConfig pdschCfg;
761 pdcch = &dlMsgAlloc->dlMsgPdcchCfg;
762 pdsch = &dlMsgAlloc->dlMsgPdschCfg;
763 bwp = &dlMsgAlloc->bwp;
765 GET_UE_IDX(crnti, ueIdx);
766 ueCb = cell->ueCb[ueIdx-1];
767 coreset1 = ueCb.ueCfg.spCellCfg.servCellCfg.initDlBwp.pdcchCfg.cRSetToAddModList[0];
768 pdschCfg = ueCb.ueCfg.spCellCfg.servCellCfg.initDlBwp.pdschCfg;
771 bwp->freqAlloc.numPrb = MAX_NUM_RB;
772 bwp->freqAlloc.startPrb = 0;
773 bwp->subcarrierSpacing = cell->cellCfg.sib1SchCfg.bwp.subcarrierSpacing;
774 bwp->cyclicPrefix = cell->cellCfg.sib1SchCfg.bwp.cyclicPrefix;
776 /* fill the PDCCH PDU */
777 //Considering coreset1 also starts from same symbol as coreset0
778 pdcch->coresetCfg.startSymbolIndex = coresetIdxTable[0][3];
779 pdcch->coresetCfg.durationSymbols = coreset1.duration;
780 memcpy(pdcch->coresetCfg.freqDomainResource, coreset1.freqDomainRsrc, FREQ_DOM_RSRC_SIZE);
781 pdcch->coresetCfg.cceRegMappingType = coreset1.cceRegMappingType; /* non-interleaved */
782 pdcch->coresetCfg.regBundleSize = 6; /* must be 6 for non-interleaved */
783 pdcch->coresetCfg.interleaverSize = 0; /* NA for non-interleaved */
784 pdcch->coresetCfg.coreSetType = 1; /* non PBCH coreset */
785 //Considering number of RBs in coreset1 is same as coreset0
786 pdcch->coresetCfg.coreSetSize = coresetIdxTable[0][1];
787 pdcch->coresetCfg.shiftIndex = cell->cellCfg.phyCellId;
788 pdcch->coresetCfg.precoderGranularity = coreset1.precoderGranularity;
790 pdcch->dci.rnti = ueCb.crnti;
791 pdcch->dci.scramblingId = cell->cellCfg.phyCellId;
792 pdcch->dci.scramblingRnti = 0;
793 pdcch->dci.cceIndex = 0; /* 0-3 for UL and 4-7 for DL */
794 pdcch->dci.aggregLevel = 4;
795 pdcch->dci.beamPdcchInfo.numPrgs = 1;
796 pdcch->dci.beamPdcchInfo.prgSize = 1;
797 pdcch->dci.beamPdcchInfo.digBfInterfaces = 0;
798 pdcch->dci.beamPdcchInfo.prg[0].pmIdx = 0;
799 pdcch->dci.beamPdcchInfo.prg[0].beamIdx[0] = 0;
800 pdcch->dci.txPdcchPower.powerValue = 0;
801 pdcch->dci.txPdcchPower.powerControlOffsetSS = 0;
803 /* fill the PDSCH PDU */
805 pdsch->pduBitmap = 0; /* PTRS and CBG params are excluded */
806 pdsch->rnti = ueCb.crnti;
808 pdsch->numCodewords = 1;
809 for(cwCount = 0; cwCount < pdsch->numCodewords; cwCount++)
811 pdsch->codeword[cwCount].targetCodeRate = 308;
812 pdsch->codeword[cwCount].qamModOrder = ueCb.ueCfg.dlModInfo.modOrder;
813 pdsch->codeword[cwCount].mcsIndex = ueCb.ueCfg.dlModInfo.mcsIndex;
814 pdsch->codeword[cwCount].mcsTable = ueCb.ueCfg.dlModInfo.mcsTable;
815 pdsch->codeword[cwCount].rvIndex = 0;
816 tbSize = schCalcTbSize(*accumalatedSize + TX_PAYLOAD_HDR_LEN);
817 if(tbSize < *accumalatedSize)
818 *accumalatedSize = tbSize - TX_PAYLOAD_HDR_LEN;
819 pdsch->codeword[cwCount].tbSize = tbSize;
821 pdsch->dataScramblingId = cell->cellCfg.phyCellId;
822 pdsch->numLayers = 1;
823 pdsch->transmissionScheme = 0;
825 pdsch->dmrs.dlDmrsSymbPos = 4; /* Bitmap value 00000000000100 i.e. using 3rd symbol for PDSCH DMRS */
826 pdsch->dmrs.dmrsConfigType = 0; /* type-1 */
827 pdsch->dmrs.dlDmrsScramblingId = cell->cellCfg.phyCellId;
828 pdsch->dmrs.scid = 0;
829 pdsch->dmrs.numDmrsCdmGrpsNoData = 1;
830 pdsch->dmrs.dmrsPorts = 0;
831 pdsch->dmrs.mappingType = DMRS_MAP_TYPE_A; /* Setting to Type-A */
832 pdsch->dmrs.nrOfDmrsSymbols = NUM_DMRS_SYMBOLS;
833 pdsch->dmrs.dmrsAddPos = pdschCfg.dmrsDlCfgForPdschMapTypeA.addPos;
835 pdsch->pdschTimeAlloc.timeAlloc.startSymb = pdschCfg.timeDomRsrcAllociList[0].startSymbol;
836 pdsch->pdschTimeAlloc.timeAlloc.numSymb = pdschCfg.timeDomRsrcAllociList[0].symbolLength;
838 pdsch->pdschFreqAlloc.vrbPrbMapping = 0; /* non-interleaved */
839 pdsch->pdschFreqAlloc.resourceAllocType = 1; /* RAT type-1 RIV format */
840 pdsch->pdschFreqAlloc.freqAlloc.startPrb = MAX_NUM_RB;
841 pdsch->pdschFreqAlloc.freqAlloc.numPrb = schCalcNumPrb(tbSize, ueCb.ueCfg.dlModInfo.mcsIndex, \
842 pdschCfg.timeDomRsrcAllociList[0].symbolLength);
844 /* Allocate the number of PRBs required for DL PDSCH */
845 if((allocatePrbDl(cell, slotTime, pdsch->pdschTimeAlloc.timeAlloc.startSymb, pdsch->pdschTimeAlloc.timeAlloc.numSymb,\
846 &pdsch->pdschFreqAlloc.freqAlloc.startPrb, pdsch->pdschFreqAlloc.freqAlloc.numPrb)) != ROK)
848 DU_LOG("\nERROR --> SCH : allocatePrbDl() failed for DL MSG");
852 pdsch->beamPdschInfo.numPrgs = 1;
853 pdsch->beamPdschInfo.prgSize = 1;
854 pdsch->beamPdschInfo.digBfInterfaces = 0;
855 pdsch->beamPdschInfo.prg[0].pmIdx = 0;
856 pdsch->beamPdschInfo.prg[0].beamIdx[0] = 0;
857 pdsch->txPdschPower.powerControlOffset = 0;
858 pdsch->txPdschPower.powerControlOffsetSS = 0;
860 pdcch->dci.pdschCfg = pdsch;
864 /*******************************************************************
866 * @brief Fills k0 and k1 information table for FDD
870 * Function : BuildK0K1TableForFdd
873 * Fills k0 and k1 information table for FDD
875 * @params[in] SchCellCb *cell,SchK0K1TimingInfoTbl *k0K1InfoTbl,bool
876 * pdschCfgCmnPres,uint8_t numTimeDomAlloc, SchPdschCfgCmnTimeDomRsrcAlloc
877 * cmnTimeDomRsrcAllocList[], SchPdschTimeDomRsrcAlloc
878 * dedTimeDomRsrcAllocList[], uint8_t ulAckListCount, uint8_t *UlAckTbl
879 * @return ROK - success
882 * ****************************************************************/
883 void BuildK0K1TableForFdd(SchCellCb *cell, SchK0K1TimingInfoTbl *k0K1InfoTbl, bool pdschCfgCmnPres,SchPdschCfgCmn pdschCmnCfg,\
884 SchPdschConfig pdschDedCfg, uint8_t ulAckListCount, uint8_t *UlAckTbl)
887 uint8_t k1TmpVal =0, cfgIdx=0;
888 uint8_t slotIdx=0, k0Index=0, k1Index=0, numK0=0, numK1=0, numTimeDomAlloc=0;
890 /* TODO Commented these below lines for resolving warnings. Presently these variable are not
891 * required but this will require for harq processing */
892 // uint8_t k0TmpVal = 0;
893 // SchPdschCfgCmnTimeDomRsrcAlloc cmnTimeDomRsrcAllocList[MAX_NUM_DL_ALLOC];
894 // SchPdschTimeDomRsrcAlloc dedTimeDomRsrcAllocList[MAX_NUM_DL_ALLOC];
896 /* Initialization the structure and storing the total slot values. */
897 memset(k0K1InfoTbl, 0, sizeof(SchK0K1TimingInfoTbl));
898 k0K1InfoTbl->tblSize = cell->numSlots;
900 /* Storing time domain resource allocation list based on common or dedicated configuration. */
901 if(pdschCfgCmnPres == true)
903 numTimeDomAlloc = pdschCmnCfg.numTimeDomAlloc;
904 for(cfgIdx = 0; cfgIdx<numTimeDomAlloc; cfgIdx++)
906 /*TODO uncomment this line during harq processing */
907 //cmnTimeDomRsrcAllocList[cfgIdx] = pdschCmnCfg.timeDomRsrcAllocList[cfgIdx];
912 numTimeDomAlloc = pdschDedCfg.numTimeDomRsrcAlloc;
913 for(cfgIdx = 0; cfgIdx<numTimeDomAlloc; cfgIdx++)
915 /*TODO uncomment this line during harq processing */
916 //dedTimeDomRsrcAllocList[cfgIdx] = pdschDedCfg.timeDomRsrcAllociList[cfgIdx];
920 /* Checking all the slots for K0 and K1 values. */
921 for(slotIdx = 0; slotIdx < cell->numSlots; slotIdx++)
924 /* Storing the values of k0 based on time domain resource
925 * allocation list. If the value is unavailable then fill default values,
926 * As per 38.331 PDSCH-TimeDomainResourceAllocation field descriptions. */
927 for(k0Index = 0; ((k0Index < numTimeDomAlloc) && (k0Index < MAX_NUM_K0_IDX)); k0Index++)
929 /* TODO These if 0 we will remove during harq processing */
931 if(pdschCfgCmnPres == true)
933 k0TmpVal = cmnTimeDomRsrcAllocList[k0Index].k0;
937 if(dedTimeDomRsrcAllocList[k0Index].k0 != NULLP)
939 k0TmpVal = *(dedTimeDomRsrcAllocList[k0Index].k0);
943 k0TmpVal = DEFAULT_K0_VALUE;
947 /* Checking all the Ul Alloc values. If value is less than MIN_NUM_K1_IDX
948 * then skip else continue storing the values. */
950 for(k1Index = 0; k1Index < ulAckListCount; k1Index++)
952 k1TmpVal = UlAckTbl[k1Index];
953 if(k1TmpVal <= MIN_NUM_K1_IDX)
958 k0K1InfoTbl->k0k1TimingInfo[slotIdx].k0Indexes[numK0].k1TimingInfo.k1Indexes[numK1++] = k1Index;
959 /* TODO Store K1 index where harq feedback will be received in harq table. */
963 k0K1InfoTbl->k0k1TimingInfo[slotIdx].k0Indexes[numK0].k1TimingInfo.numK1 = numK1;
964 k0K1InfoTbl->k0k1TimingInfo[slotIdx].k0Indexes[numK0].k0Index = k0Index;
970 k0K1InfoTbl->k0k1TimingInfo[slotIdx].numK0 = numK0;
975 /*******************************************************************
977 * @brief Fills k0 and k1 information table
981 * Function : BuildK0K1Table
984 * Fills K0 and k1 information table
986 * @params[in] SchCellCb *cell,SchK0K1TimingInfoTbl *k0K1InfoTbl,bool
987 * pdschCfgCmnPres,uint8_t numTimeDomAlloc, SchPdschCfgCmnTimeDomRsrcAlloc
988 * cmnTimeDomRsrcAllocList[], SchPdschTimeDomRsrcAlloc
989 * dedTimeDomRsrcAllocList[], uint8_t ulAckListCount, uint8_t *UlAckTbl
990 * @return ROK - success
993 * ****************************************************************/
994 void BuildK0K1Table(SchCellCb *cell, SchK0K1TimingInfoTbl *k0K1InfoTbl, bool pdschCfgCmnPres, SchPdschCfgCmn pdschCmnCfg,\
995 SchPdschConfig pdschDedCfg, uint8_t ulAckListCount, uint8_t *UlAckTbl)
1000 bool ulSlotPresent = false;
1001 uint8_t k0TmpVal = 0, k1TmpVal =0, tmpSlot=0, startSymbol=0, endSymbol=0, checkSymbol=0;
1002 uint8_t slotIdx=0, k0Index=0, k1Index=0, numK0=0, numK1=0, cfgIdx=0, numTimeDomAlloc =0, totalCfgSlot =0;
1003 SchPdschCfgCmnTimeDomRsrcAlloc cmnTimeDomRsrcAllocList[MAX_NUM_DL_ALLOC];
1004 SchPdschTimeDomRsrcAlloc dedTimeDomRsrcAllocList[MAX_NUM_DL_ALLOC];
1007 if(cell->cellCfg.dupMode == DUPLEX_MODE_FDD)
1009 BuildK0K1TableForFdd(cell, k0K1InfoTbl, pdschCfgCmnPres, pdschCmnCfg, pdschDedCfg, ulAckListCount, UlAckTbl);
1015 /* Initialization the K0K1 structure, total num of slot and calculating the slot pattern length. */
1016 memset(k0K1InfoTbl, 0, sizeof(SchK0K1TimingInfoTbl));
1017 k0K1InfoTbl->tblSize = cell->numSlots;
1018 totalCfgSlot = calculateSlotPatternLength(cell->cellCfg.ssbSchCfg.scsCommon, cell->cellCfg.tddCfg.tddPeriod);
1020 /* Storing time domain resource allocation list based on common or
1021 * dedicated configuration availability. */
1022 if(pdschCfgCmnPres == true)
1024 numTimeDomAlloc = pdschCmnCfg.numTimeDomAlloc;
1025 for(cfgIdx = 0; cfgIdx<numTimeDomAlloc; cfgIdx++)
1027 cmnTimeDomRsrcAllocList[cfgIdx] = pdschCmnCfg.timeDomRsrcAllocList[cfgIdx];
1032 numTimeDomAlloc = pdschDedCfg.numTimeDomRsrcAlloc;
1033 for(cfgIdx = 0; cfgIdx<numTimeDomAlloc; cfgIdx++)
1035 dedTimeDomRsrcAllocList[cfgIdx] = pdschDedCfg.timeDomRsrcAllociList[cfgIdx];
1039 /* Checking all possible indexes for K0 and K1 values. */
1040 for(slotIdx = 0; slotIdx < cell->numSlots; slotIdx++)
1042 /* If current slot is UL or FLEXI then Skip because PDCCH is sent only in DL slots. */
1043 slotCfg = schGetSlotSymbFrmt(slotIdx%totalCfgSlot, cell->slotFrmtBitMap);
1044 if(slotCfg == UL_SLOT || slotCfg == FLEXI_SLOT)
1049 /* Storing K0 , start symbol and length symbol for further processing.
1050 * If K0 value is not available then we can fill the default values
1051 * given in spec 38.331. */
1053 for(k0Index = 0; ((k0Index < numTimeDomAlloc) && (k0Index < MAX_NUM_K0_IDX)); k0Index++)
1055 if(pdschCfgCmnPres == true)
1057 k0TmpVal = cmnTimeDomRsrcAllocList[k0Index].k0;
1058 startSymbol = cmnTimeDomRsrcAllocList[k0Index].startSymbol;
1059 endSymbol = startSymbol + cmnTimeDomRsrcAllocList[k0Index].lengthSymbol;
1063 if(dedTimeDomRsrcAllocList[k0Index].k0 != NULLP)
1065 k0TmpVal = *(dedTimeDomRsrcAllocList[k0Index].k0);
1069 k0TmpVal = DEFAULT_K0_VALUE;
1071 startSymbol = dedTimeDomRsrcAllocList[k0Index].startSymbol;
1072 endSymbol = startSymbol + dedTimeDomRsrcAllocList[k0Index].symbolLength;
1075 /* If current slot + k0 is UL then skip the slot
1076 * else if it is DL slot then continue the next steps
1077 * else if it is a FLEXI slot then check symbols of slot, It should not
1078 * contain any UL slot. */
1079 tmpSlot = (slotIdx+k0TmpVal) % totalCfgSlot;
1080 slotCfg = schGetSlotSymbFrmt(tmpSlot, cell->slotFrmtBitMap);
1081 if(slotCfg == UL_SLOT)
1085 if(slotCfg == FLEXI_SLOT)
1087 for(checkSymbol = startSymbol; checkSymbol<endSymbol; checkSymbol ++)
1089 slotCfg = cell->cellCfg.tddCfg.slotCfg[tmpSlot][checkSymbol];
1090 if(slotCfg == UL_SLOT)
1097 /* If current slot + k0 + k1 is a DL slot then skip the slot
1098 * else if it is UL slot then store the information
1099 * else if it is FLEXI slot then check the symbols, it must have
1100 * at least one UL symbol. */
1102 for(k1Index = 0; k1Index < ulAckListCount; k1Index++)
1104 k1TmpVal = UlAckTbl[k1Index];
1105 if(k1TmpVal > MIN_NUM_K1_IDX)
1107 tmpSlot = (slotIdx+k0TmpVal+k1TmpVal) % totalCfgSlot;
1108 slotCfg = schGetSlotSymbFrmt(tmpSlot, cell->slotFrmtBitMap);
1109 if(slotCfg == DL_SLOT)
1113 if(slotCfg == FLEXI_SLOT)
1115 for(checkSymbol = 0; checkSymbol<SCH_SYMBOL_PER_SLOT;checkSymbol++)
1117 if(cell->cellCfg.tddCfg.slotCfg[tmpSlot][checkSymbol] == UL_SLOT)
1119 ulSlotPresent = true;
1124 if(ulSlotPresent == true || slotCfg == UL_SLOT)
1126 k0K1InfoTbl->k0k1TimingInfo[slotIdx].k0Indexes[numK0].k1TimingInfo.k1Indexes[numK1++] = k1Index;
1127 /* TODO Store K1 index where harq feedback will be received
1133 /* Store all the values if all condition satisfies. */
1136 k0K1InfoTbl->k0k1TimingInfo[slotIdx].k0Indexes[numK0].k1TimingInfo.numK1 = numK1;
1137 k0K1InfoTbl->k0k1TimingInfo[slotIdx].k0Indexes[numK0].k0Index = k0Index;
1143 k0K1InfoTbl->k0k1TimingInfo[slotIdx].numK0 = numK0;
1150 /*******************************************************************
1152 * @brief Fills K2 information table for FDD
1156 * Function : BuildK2InfoTableForFdd
1159 * Fills K2 information table for FDD
1161 * @params[in] SchCellCb *cell,SchPuschTimeDomRsrcAlloc timeDomRsrcAllocList[],
1162 * uint16_t puschSymTblSize,SchK2TimingInfoTbl *k2InfoTbl
1163 * @return ROK - success
1166 * ****************************************************************/
1167 void BuildK2InfoTableForFdd(SchCellCb *cell, SchPuschTimeDomRsrcAlloc timeDomRsrcAllocList[], uint16_t puschSymTblSize,\
1168 SchK2TimingInfoTbl *msg3K2InfoTbl, SchK2TimingInfoTbl *k2InfoTbl)
1170 uint16_t slotIdx=0, k2Index=0, k2TmpIdx=0, msg3K2TmpIdx=0;
1172 /* Initialization the structure and storing the total slot values. */
1173 memset(k2InfoTbl, 0, sizeof(SchK2TimingInfoTbl));
1174 k2InfoTbl->tblSize = cell->numSlots;
1176 msg3K2InfoTbl->tblSize = cell->numSlots;
1178 /* Checking all possible indexes for K2. */
1179 for(slotIdx = 0; slotIdx < cell->numSlots; slotIdx++)
1181 /* Storing K2 values. */
1182 for(k2Index = 0; ((k2Index < puschSymTblSize) && (k2Index < MAX_NUM_K2_IDX)); k2Index++)
1184 k2TmpIdx= k2InfoTbl->k2TimingInfo[slotIdx].numK2;
1185 k2InfoTbl->k2TimingInfo[slotIdx].k2Indexes[k2TmpIdx] = k2Index;
1186 k2InfoTbl->k2TimingInfo[slotIdx].numK2++;
1188 /* Updating K2 values for MSG3 */
1191 msg3K2TmpIdx = msg3K2InfoTbl->k2TimingInfo[slotIdx].numK2;
1192 msg3K2InfoTbl->k2TimingInfo[slotIdx].k2Indexes[msg3K2TmpIdx] = k2Index;
1193 msg3K2InfoTbl->k2TimingInfo[slotIdx].numK2++;
1199 /*******************************************************************
1201 * @brief Fills K2 information table
1205 * Function : BuildK2InfoTable
1208 * Fills K2 information table
1210 * @params[in] SchCellCb *cell,SchPuschTimeDomRsrcAlloc timeDomRsrcAllocList[],
1211 * uint16_t puschSymTblSize, SchK2TimingInfoTbl *k2InfoTbl
1212 * @return ROK - success
1215 * ****************************************************************/
1216 void BuildK2InfoTable(SchCellCb *cell, SchPuschTimeDomRsrcAlloc timeDomRsrcAllocList[], uint16_t puschSymTblSize,\
1217 SchK2TimingInfoTbl *msg3K2InfoTbl, SchK2TimingInfoTbl *k2InfoTbl)
1221 bool dlSymbolPresent = false;
1222 uint8_t slotIdx=0, k2Index=0, k2Val=0, k2TmpVal=0, msg3K2TmpVal=0, msg3Delta=0, numK2 =0, currentSymbol =0;
1223 uint8_t startSymbol =0, endSymbol =0, checkSymbol=0, totalCfgSlot=0, slotCfg=0;
1224 SlotConfig currentSlot;
1227 if(cell->cellCfg.dupMode == DUPLEX_MODE_FDD)
1229 BuildK2InfoTableForFdd(cell, timeDomRsrcAllocList, puschSymTblSize, msg3K2InfoTbl, k2InfoTbl);
1235 /* Initialization the structure and storing the total slot values. */
1236 memset(k2InfoTbl, 0, sizeof(SchK2TimingInfoTbl));
1237 k2InfoTbl->tblSize = cell->numSlots;
1239 msg3K2InfoTbl->tblSize = cell->numSlots;
1240 totalCfgSlot = calculateSlotPatternLength(cell->cellCfg.ssbSchCfg.scsCommon, cell->cellCfg.tddCfg.tddPeriod);
1242 /* Checking all possible indexes for K2. */
1243 for(slotIdx = 0; slotIdx < cell->numSlots; slotIdx++)
1245 currentSlot = schGetSlotSymbFrmt(slotIdx % totalCfgSlot, cell->slotFrmtBitMap);
1247 /* If current slot is UL then skip because PDCCH is sent only in DL slots */
1248 if(currentSlot != UL_SLOT)
1250 for(k2Index = 0; ((k2Index < puschSymTblSize) && (k2Index < MAX_NUM_K2_IDX)); k2Index++)
1252 /* Storing k2, startSymbol, endSymbol information for further processing.
1253 * If k2 is absent then fill the default values given in spec 38.331
1254 * PUSCH-TimeDomainResourceAllocationList field descriptions */
1255 k2Val = timeDomRsrcAllocList[k2Index].k2;
1258 switch(cell->cellCfg.ssbSchCfg.scsCommon)
1261 k2Val = DEFAULT_K2_VALUE_FOR_SCS15;
1264 k2Val = DEFAULT_K2_VALUE_FOR_SCS30;
1267 k2Val = DEFAULT_K2_VALUE_FOR_SCS60;
1270 k2Val = DEFAULT_K2_VALUE_FOR_SCS120;
1275 /* Current slot + k2 should be either UL or FLEXI slot.
1276 * If slot is FLEXI then check all the symbols of that slot,
1277 * it should not contain any DL or FLEXI slot */
1278 k2TmpVal = (slotIdx + k2Val) % totalCfgSlot;
1279 slotCfg = schGetSlotSymbFrmt(k2TmpVal, cell->slotFrmtBitMap);
1280 if(slotCfg != DL_SLOT)
1282 if(slotCfg == FLEXI_SLOT)
1284 startSymbol = timeDomRsrcAllocList[k2Index].startSymbol;
1285 endSymbol = startSymbol+ timeDomRsrcAllocList[k2Index].symbolLength;
1286 dlSymbolPresent = false;
1287 for(checkSymbol= startSymbol; checkSymbol<endSymbol; checkSymbol++)
1289 currentSymbol = cell->cellCfg.tddCfg.slotCfg[k2TmpVal][checkSymbol];
1290 if(currentSymbol == DL_SLOT || currentSymbol == FLEXI_SLOT)
1292 dlSymbolPresent = true;
1297 /* Store all the values if all condition satisfies. */
1298 if(dlSymbolPresent != true || slotCfg == UL_SLOT)
1300 numK2 = k2InfoTbl->k2TimingInfo[slotIdx].numK2;
1301 k2InfoTbl->k2TimingInfo[slotIdx].k2Indexes[numK2] = k2Index;
1302 k2InfoTbl->k2TimingInfo[slotIdx].numK2++;
1308 msg3Delta = puschDeltaTable[cell->cellCfg.numerology];
1310 /* Check for K2 for MSG3 */
1311 /* Current slot + k2 should be either UL or FLEXI slot.
1312 * If slot is FLEXI then check all the symbols of that slot,
1313 * it should not contain any DL or FLEXI slot */
1314 msg3K2TmpVal = (slotIdx + k2Val + msg3Delta) % totalCfgSlot;
1315 slotCfg = schGetSlotSymbFrmt(msg3K2TmpVal, cell->slotFrmtBitMap);
1316 if(slotCfg != DL_SLOT)
1318 if(slotCfg == FLEXI_SLOT)
1320 startSymbol = timeDomRsrcAllocList[k2Index].startSymbol;
1321 endSymbol = startSymbol+ timeDomRsrcAllocList[k2Index].symbolLength;
1322 dlSymbolPresent = false;
1323 for(checkSymbol= startSymbol; checkSymbol<endSymbol; checkSymbol++)
1325 currentSymbol = cell->cellCfg.tddCfg.slotCfg[msg3K2TmpVal][checkSymbol];
1326 if(currentSymbol == DL_SLOT || currentSymbol == FLEXI_SLOT)
1328 dlSymbolPresent = true;
1333 /* Store all the values if all condition satisfies. */
1334 if(dlSymbolPresent != true || slotCfg == UL_SLOT)
1336 numK2 = msg3K2InfoTbl->k2TimingInfo[slotIdx].numK2;
1337 msg3K2InfoTbl->k2TimingInfo[slotIdx].k2Indexes[numK2] = k2Index;
1338 msg3K2InfoTbl->k2TimingInfo[slotIdx].numK2++;
1349 /**********************************************************************
1351 **********************************************************************/