+ if((slotTime.sfn % SCH_SIB1_TRANS == 0) && (slotTime.slot ==0))
+ {
+ return NEW_TRANSMISSION;
+ }
+ else if(cell->firstSib1Transmitted)
+ {
+ if((slotTime.sfn % (SIB1_REPETITION_PERIOD/10) == 0) &&
+ (slotTime.slot == 0))
+ {
+ return REPEATITION;
+ }
+ }
+ /* not SIB1 occassion */
+ return NO_TRANSMISSION;
+}
+
+/*******************************************************************
+ *
+ * @brief find correct combination of k0-k1 value
+ *
+ * @details
+ *
+ * Function : findValidK0K1Value
+ *
+ * Functionality:
+ * find correct combination of k0-k1 value
+ *
+ * @params[in] SchCellCb *cell, SlotTimingInfo currTime
+ * @params[in] uint8_t ueId, bool dedMsg
+ * @params[in] uint8_t *pdschStartSymbol, uint8_t *pdschSymblLen
+ * @params[in] SlotTimingInfo *pdcchTime, SlotTimingInfo *pdschTime
+ * @params[in] SlotTimingInfo *pucchTime, bool isRetx, SchDlHqProcCb *hqP
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ *******************************************************************/
+bool findValidK0K1Value(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId, bool dedMsg,
+ uint8_t *pdschStartSymbol, uint8_t *pdschSymblLen, SlotTimingInfo *pdcchTime,
+ SlotTimingInfo *pdschTime, SlotTimingInfo *pucchTime, bool isRetx, SchDlHqProcCb *hqP)
+{
+ uint8_t numK0 = 0, k0TblIdx = 0, k0Val = 0, k0Index =0 ;
+ uint8_t k1TblIdx = 0, k1Index = 0, k1Val = 0, numK1 = 0;
+ SchUeCb *ueCb = NULLP;
+ SchK0K1TimingInfoTbl *k0K1InfoTbl;
+
+ ADD_DELTA_TO_TIME(currTime, (*pdcchTime), PHY_DELTA_DL + SCHED_DELTA, cell->numSlots);
+#ifdef NR_TDD
+ if(schGetSlotSymbFrmt(pdcchTime->slot, cell->slotFrmtBitMap) != DL_SLOT)
+ {
+ /* If it is not a DL slot, cannot schedule PDCCH. Return from here. */
+ return false;
+ }
+#endif
+
+ if(cell->schDlSlotInfo[pdcchTime->slot]->pdcchUe != 0)
+ {
+ return false;
+ }
+
+ if(dedMsg == true)
+ {
+ ueCb = &cell->ueCb[ueId-1];
+ k0K1InfoTbl = &ueCb->k0K1InfoTbl;
+ }
+ else
+ {
+ k0K1InfoTbl = &cell->k0K1InfoTbl;
+ }
+
+ numK0 = k0K1InfoTbl->k0k1TimingInfo[pdcchTime->slot].numK0;
+ for(k0TblIdx = 0; k0TblIdx < numK0; k0TblIdx++)
+ {
+ k0Index = k0K1InfoTbl->k0k1TimingInfo[pdcchTime->slot].k0Indexes[k0TblIdx].k0Index;
+ if(dedMsg != true)
+ {
+ k0Val = cell->cellCfg.dlCfgCommon.schInitialDlBwp.pdschCommon.timeDomRsrcAllocList[k0Index].k0;
+ *pdschStartSymbol = cell->cellCfg.dlCfgCommon.schInitialDlBwp.pdschCommon.timeDomRsrcAllocList[k0Index].startSymbol;
+ *pdschSymblLen = cell->cellCfg.dlCfgCommon.schInitialDlBwp.pdschCommon.timeDomRsrcAllocList[k0Index].lengthSymbol;
+ }
+ else
+ {
+ if(ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[k0Index].k0 != NULLP)
+ {
+ k0Val = *(ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[k0Index].k0);
+ *pdschStartSymbol = ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[k0Index].startSymbol;
+ *pdschSymblLen = ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[k0Index].symbolLength;
+ }
+ }
+
+ ADD_DELTA_TO_TIME((*pdcchTime), (*pdschTime), k0Val, cell->numSlots);
+#ifdef NR_TDD
+ if(schGetSlotSymbFrmt(pdschTime->slot, cell->slotFrmtBitMap) != DL_SLOT)
+ {
+ continue;
+ }
+#endif
+ if(cell->schDlSlotInfo[pdschTime->slot]->pdschUe != 0)
+ {
+ continue;
+ }
+
+ numK1 = k0K1InfoTbl->k0k1TimingInfo[pdcchTime->slot].k0Indexes[k0TblIdx].k1TimingInfo.numK1;
+ for(k1TblIdx = 0; k1TblIdx < numK1; k1TblIdx++)
+ {
+ k1Index = k0K1InfoTbl->k0k1TimingInfo[pdcchTime->slot].k0Indexes[k0TblIdx].k1TimingInfo.k1Indexes[k1TblIdx];
+ if(dedMsg != true)
+ {
+ k1Val = defaultUlAckTbl[k1Index];
+ }
+ else
+ {
+ if(ueCb->ueCfg.spCellCfg.servCellRecfg.initUlBwp.pucchCfg.dlDataToUlAck)
+ {
+ k1Val = ueCb->ueCfg.spCellCfg.servCellRecfg.initUlBwp.pucchCfg.dlDataToUlAck->dlDataToUlAckList[k1Index];
+ }
+ }
+ ADD_DELTA_TO_TIME((*pdschTime),(*pucchTime), k1Val, cell->numSlots);
+#ifdef NR_TDD
+ if(schGetSlotSymbFrmt(pucchTime->slot, cell->slotFrmtBitMap) == DL_SLOT)
+ {
+ continue;
+ }
+#endif
+ if(cell->schUlSlotInfo[pucchTime->slot]->pucchUe != 0)
+ {
+ continue;
+ }
+ if(hqP)
+ {
+ ADD_DELTA_TO_TIME((*pucchTime), hqP->pucchTime, 0, cell->numSlots);
+ }
+ pdcchTime->cellId = cell->cellId;
+ pdschTime->cellId = cell->cellId;
+
+ return true;
+ }
+ }
+ /*
+ * Number of symbols in case of retransmisson should be same as it was in
+ * original transmisson. Symbol availablity checks need to be added.
+ */
+ return false;
+}
+
+/*******************************************************************
+*
+* @brief Process DL Resource allocation for Page
+*
+* @details
+*
+* Function : schProcDlPageAlloc
+*
+* Functionality: Process DL Resource allocation for Page
+*
+* @params[in] SchCellCb *cell, SlotTimingInfo currTime, Inst schInst
+*
+* @return pointer to return Value(ROK, RFAILED)
+*
+* ****************************************************************/
+uint8_t schProcDlPageAlloc(SchCellCb *cell, SlotTimingInfo currTime, Inst schInst)
+{
+ DlPageAlloc dlPageAlloc;
+ CmLList *pageInfoNode = NULLP;
+ SchPageInfo *pageInfo = NULLP;
+ SlotTimingInfo pdschTime;
+ uint32_t tbSize = 0;
+ uint16_t startPrb = 0, maxFreePRB = 0, nPRB = 0;
+ uint8_t ret = RFAILED;
+
+ pageInfoNode = schPageInfoSearchFromPageList(currTime, &(cell->pageCb.pageIndInfoRecord[currTime.sfn]));
+
+ if(pageInfoNode == NULLP)
+ {
+ return ROK;
+ }
+ pageInfo = (SchPageInfo *)pageInfoNode->node;
+
+ while(true)
+ {
+ dlPageAlloc.cellId = currTime.cellId;
+
+ ADD_DELTA_TO_TIME(currTime, dlPageAlloc.dlPageTime, PHY_DELTA_DL + SCHED_DELTA, cell->numSlots);
+ dlPageAlloc.shortMsgInd = FALSE;
+ pdschTime = dlPageAlloc.dlPageTime;
+
+ /*Calculate Best FREE BLOCK with MAX PRB count*/
+ maxFreePRB = searchLargestFreeBlock(cell, pdschTime, &startPrb, DIR_DL);
+
+ if(maxFreePRB != 0)
+ {
+ tbSize = calculateEstimateTBSize(pageInfo->msgLen, pageInfo->mcs, NUM_PDSCH_SYMBOL, maxFreePRB, &nPRB);
+ }
+ else
+ {
+ DU_LOG("\nERROR --> SCH: Unable to get any free block for Paging at SFN:%d, SLOT:%d",\
+ pdschTime.sfn, pdschTime.slot);
+ break;
+ }
+ /*Fill PDCCH: PDCCH Cfg is same as SIB1 as Paging will be a broadcast message*/
+ memcpy(dlPageAlloc.pageDlDci.freqDomainResource, cell->sib1SchCfg.sib1PdcchCfg.coresetCfg.freqDomainResource, 6 * sizeof(uint8_t));
+ dlPageAlloc.pageDlDci.durationSymbols = cell->sib1SchCfg.sib1PdcchCfg.coresetCfg.durationSymbols;
+ dlPageAlloc.pageDlDci.cceRegMappingType = INTERLEAVED_CCE_REG_MAPPING;
+ dlPageAlloc.pageDlDci.cceReg.interleaved.regBundleSize = cell->sib1SchCfg.sib1PdcchCfg.coresetCfg.regBundleSize;
+ dlPageAlloc.pageDlDci.cceReg.interleaved.interleaverSize = cell->sib1SchCfg.sib1PdcchCfg.coresetCfg.interleaverSize;
+ dlPageAlloc.pageDlDci.cceReg.interleaved.shiftIndex = cell->sib1SchCfg.sib1PdcchCfg.coresetCfg.shiftIndex;
+ dlPageAlloc.pageDlDci.ssStartSymbolIndex = cell->sib1SchCfg.sib1PdcchCfg.coresetCfg.startSymbolIndex;
+ dlPageAlloc.pageDlDci.cceIndex = cell->sib1SchCfg.sib1PdcchCfg.dci.cceIndex;
+ dlPageAlloc.pageDlDci.aggregLevel = cell->sib1SchCfg.sib1PdcchCfg.dci.aggregLevel;
+ dlPageAlloc.pageDlDci.precoderGranularity = cell->sib1SchCfg.sib1PdcchCfg.coresetCfg.precoderGranularity;
+ dlPageAlloc.pageDlDci.coreSetSize = cell->sib1SchCfg.sib1PdcchCfg.coresetCfg.coreSetSize;
+ /*Fill BWP*/
+ memcpy(&dlPageAlloc.bwp, &cell->sib1SchCfg.bwp, sizeof(BwpCfg));
+
+ /*Fill PDSCH*/
+ if(schFillPagePdschCfg(cell, &dlPageAlloc.pageDlSch, pdschTime, tbSize, pageInfo->mcs, startPrb) != ROK)
+ {
+ DU_LOG("\nERROR --> SCH: Issue in PDSCH Allocation for Paging at SFN:%d, SLOT:%d",\
+ pdschTime.sfn, pdschTime.slot);
+ break;
+ }
+
+ /*Fill Page PDU information*/
+ dlPageAlloc.pageDlSch.dlPagePduLen = pageInfo->msgLen;
+
+ SCH_ALLOC(dlPageAlloc.pageDlSch.dlPagePdu, sizeof(dlPageAlloc.pageDlSch.dlPagePduLen));
+
+ if(dlPageAlloc.pageDlSch.dlPagePdu == NULLP)
+ {
+ DU_LOG("\nERROR --> SCH: Memory Allocation Failed during Page Resource allocation");
+ break;
+ }
+ memcpy(dlPageAlloc.pageDlSch.dlPagePdu, pageInfo->pagePdu, dlPageAlloc.pageDlSch.dlPagePduLen);
+
+ /* Send msg to MAC */
+ if(sendDlPageAllocToMac(&dlPageAlloc, schInst) != ROK)
+ {
+ DU_LOG("\nERROR --> SCH : Sending DL Paging allocation from SCH to MAC failed");
+ SCH_FREE(dlPageAlloc.pageDlSch.dlPagePdu, sizeof(dlPageAlloc.pageDlSch.dlPagePduLen));
+ break;
+ }
+ ret = ROK;
+ break;
+ }
+
+ /*Remove the Page Node*/
+ SCH_FREE(pageInfo->pagePdu, pageInfo->msgLen);
+ schDeleteFromPageInfoList(&(cell->pageCb.pageIndInfoRecord[currTime.sfn]), pageInfoNode);
+
+ return(ret);
+
+}
+
+/*******************************************************************
+ *
+ * @brief Handles slot indication at SCH
+ *
+ * @details
+ *
+ * Function : SchProcSlotInd
+ *
+ * Functionality:
+ * Handles TTI indication received from PHY
+ *
+ * @params[in]
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t SchProcSlotInd(Pst *pst, SlotTimingInfo *slotInd)
+{
+ uint8_t ueIdx, ret = ROK;
+ uint16_t slot;
+ DlSchedInfo dlSchedInfo;
+ DlBrdcstAlloc *dlBrdcstAlloc = NULLP;
+ SchCellCb *cell = NULLP;
+ Inst schInst = pst->dstInst-SCH_INST_START;
+ CmLList *node = NULLP;
+ TotalPrbUsage *dlTotalPrbUsage = NULLP;
+
+ cell = schCb[schInst].cells[schInst];
+ if(cell == NULLP)
+ {
+ DU_LOG("\nERROR --> SCH : Cell Does not exist");
+ return RFAILED;
+ }
+ memset(&dlSchedInfo, 0, sizeof(DlSchedInfo));
+ schCalcSlotValues(*slotInd, &dlSchedInfo.schSlotValue, cell->numSlots);
+ dlBrdcstAlloc = &dlSchedInfo.brdcstAlloc;
+ dlBrdcstAlloc->ssbTransmissionMode = NO_TRANSMISSION;
+ dlBrdcstAlloc->sib1TransmissionMode = NO_TRANSMISSION;
+
+ memcpy(&cell->slotInfo, slotInd, sizeof(SlotTimingInfo));
+ dlBrdcstAlloc->ssbIdxSupported = SSB_IDX_SUPPORTED;
+
+ dlSchedInfo.cellId = cell->cellId;
+ slot = dlSchedInfo.schSlotValue.broadcastTime.slot;
+
+#ifdef NR_DRX
+ schHandleStartDrxTimer(cell);
+#endif
+
+ /* Check for SSB occassion */
+ dlBrdcstAlloc->ssbTransmissionMode = schCheckSsbOcc(cell, dlSchedInfo.schSlotValue.broadcastTime);
+ if(dlBrdcstAlloc->ssbTransmissionMode)
+ {
+ if(schBroadcastSsbAlloc(cell, dlSchedInfo.schSlotValue.broadcastTime, dlBrdcstAlloc) != ROK)
+ {
+ DU_LOG("\nERROR --> SCH : schBroadcastSsbAlloc failed");
+ dlBrdcstAlloc->ssbTransmissionMode = NO_TRANSMISSION;
+ }
+ else
+ {
+ dlSchedInfo.isBroadcastPres = true;
+ if((dlBrdcstAlloc->ssbTransmissionMode == NEW_TRANSMISSION) && (!cell->firstSsbTransmitted))
+ cell->firstSsbTransmitted = true;
+ }
+ }
+
+ /* Check for SIB1 occassion */
+ dlBrdcstAlloc->sib1TransmissionMode = schCheckSib1Occ(cell, dlSchedInfo.schSlotValue.broadcastTime);
+ if(dlBrdcstAlloc->sib1TransmissionMode)
+ {
+ if(schBroadcastSib1Alloc(cell, dlSchedInfo.schSlotValue.broadcastTime, dlBrdcstAlloc) != ROK)
+ {
+ DU_LOG("\nERROR --> SCH : schBroadcastSib1Alloc failed");
+ dlBrdcstAlloc->sib1TransmissionMode = NO_TRANSMISSION;
+ }
+ else
+ {
+ dlSchedInfo.isBroadcastPres = true;
+ if((dlBrdcstAlloc->sib1TransmissionMode == NEW_TRANSMISSION) && (!cell->firstSib1Transmitted))
+ cell->firstSib1Transmitted = true;
+ }
+ }
+
+ /*Process Paging Msg*/
+ schProcDlPageAlloc(cell, *slotInd, schInst);
+
+ cell->api->SchScheduleSlot(cell, slotInd, schInst);
+
+ /* Check if any PDU is scheduled at this slot for any UE */
+ for(ueIdx=0; ueIdx<MAX_NUM_UE; ueIdx++)
+ {
+ /* If RAR PDCCH/PDSCH is scheduled for a UE at this slot, fill RAR specific interface
+ * structure to send to MAC */
+ if(cell->schDlSlotInfo[dlSchedInfo.schSlotValue.rarTime.slot]->rarAlloc[ueIdx] != NULLP)
+ {
+ slot = dlSchedInfo.schSlotValue.rarTime.slot;
+ dlSchedInfo.rarAlloc[ueIdx] = cell->schDlSlotInfo[slot]->rarAlloc[ueIdx];
+ cell->schDlSlotInfo[slot]->rarAlloc[ueIdx] = NULLP;
+ }
+
+ /* If DL-Msg PDCCH/PDSCH is scheduled for a UE at this slot, fill
+ * specific interface structure to send to MAC */
+ if(cell->schDlSlotInfo[dlSchedInfo.schSlotValue.dlMsgTime.slot]->dlMsgAlloc[ueIdx] != NULLP)
+ {
+ slot = dlSchedInfo.schSlotValue.dlMsgTime.slot;
+ dlSchedInfo.dlMsgAlloc[ueIdx] = cell->schDlSlotInfo[slot]->dlMsgAlloc[ueIdx];
+ cell->schDlSlotInfo[slot]->dlMsgAlloc[ueIdx] = NULLP;
+ }
+ }
+
+ if(cell->schDlSlotInfo[dlSchedInfo.schSlotValue.ulDciTime.slot]->ulGrant != NULLP)
+ {
+ slot = dlSchedInfo.schSlotValue.ulDciTime.slot;
+ dlSchedInfo.ulGrant = cell->schDlSlotInfo[slot]->ulGrant;
+ cell->schDlSlotInfo[slot]->ulGrant = NULLP;
+ }
+
+ /* Send msg to MAC */
+ ret = sendDlAllocToMac(&dlSchedInfo, schInst);