X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2F5gnrsch%2Fsch_common.c;h=89f1969b3fdb2ba68e6ed4045abdde3748be243f;hb=eae02ffcdfa215eb3ad990e2b0718d7a62eaa84a;hp=448434cad5e9838c6779572e12dfa2ff6f9d5d8b;hpb=3c9a60ea3d2abf5e22f741f268bdfc37a09743ef;p=o-du%2Fl2.git diff --git a/src/5gnrsch/sch_common.c b/src/5gnrsch/sch_common.c index 448434cad..89f1969b3 100644 --- a/src/5gnrsch/sch_common.c +++ b/src/5gnrsch/sch_common.c @@ -47,6 +47,7 @@ SchCb schCb[SCH_MAX_INST]; uint16_t prachCfgIdxTable[MAX_PRACH_CONFIG_IDX][8]; uint16_t numRbForPrachTable[MAX_RACH_NUM_RB_IDX][5]; uint8_t pucchResourceSet[MAX_PUCCH_RES_SET_IDX][4]; +uint8_t puschDeltaTable[MAX_MU_PUSCH]; SchMacUlSchInfoFunc schMacUlSchInfoOpts[] = { @@ -166,7 +167,7 @@ int sendUlSchInfoToMac(UlSchedInfo *ulSchedInfo, Inst inst) * @param[in] UlSchedInfo *ulSchedInfo, UL scheduling info * @return void **/ -void schPrachResAlloc(SchCellCb *cell, UlSchedInfo *ulSchedInfo, SlotIndInfo prachOccasionTimingInfo) +void schPrachResAlloc(SchCellCb *cell, UlSchedInfo *ulSchedInfo, SlotTimingInfo prachOccasionTimingInfo) { uint8_t puschScs; uint8_t numPrachRb = 0; @@ -367,7 +368,7 @@ uint8_t fillUlSchedPucchFormat(uint8_t pucchFormat, SchPucchInfo *ulSchedPucch,\ **/ uint8_t fillUlSchedPucchDedicatedCfg(uint16_t numSlots, SchPucchCfg *pucchDedCfg,\ - SlotIndInfo *slotInfo, SchPucchInfo *ulSchedPucch) + SlotTimingInfo *slotInfo, SchPucchInfo *ulSchedPucch) { uint8_t ret, resrcSetIdx, resrcIdx, schedReqIdx, srPeriodicity = 0; uint16_t srOffset = 0; @@ -495,7 +496,7 @@ uint8_t schUlResAlloc(SchCellCb *cell, Inst schInst) int ret = ROK; UlSchedInfo ulSchedInfo; SchUlSlotInfo *schUlSlotInfo = NULLP; - SlotIndInfo ulTimingInfo; + SlotTimingInfo ulTimingInfo; memset(&ulSchedInfo, 0, sizeof(UlSchedInfo)); /* add PHY delta */ @@ -841,6 +842,491 @@ uint8_t schDlRsrcAllocDlMsg(DlMsgAlloc *dlMsgAlloc, SchCellCb *cell, uint16_t cr return ROK; } +/******************************************************************* + * + * @brief Fills k0 and k1 information table for FDD + * + * @details + * + * Function : BuildK0K1TableForFdd + * + * Functionality: + * Fills k0 and k1 information table for FDD + * + * @params[in] SchCellCb *cell,SchK0K1TimingInfoTbl *k0K1InfoTbl,bool + * pdschCfgCmnPres,uint8_t numTimeDomAlloc, SchPdschCfgCmnTimeDomRsrcAlloc + * cmnTimeDomRsrcAllocList[], SchPdschTimeDomRsrcAlloc + * dedTimeDomRsrcAllocList[], uint8_t ulAckListCount, uint8_t *UlAckTbl + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +void BuildK0K1TableForFdd(SchCellCb *cell, SchK0K1TimingInfoTbl *k0K1InfoTbl, bool pdschCfgCmnPres,SchPdschCfgCmn pdschCmnCfg,\ +SchPdschConfig pdschDedCfg, uint8_t ulAckListCount, uint8_t *UlAckTbl) +{ + + uint8_t k1TmpVal =0, cfgIdx=0; + uint8_t slotIdx=0, k0Index=0, k1Index=0, numK0=0, numK1=0, numTimeDomAlloc=0; + + /* TODO Commented these below lines for resolving warnings. Presently these variable are not + * required but this will require for harq processing */ + // uint8_t k0TmpVal = 0; + // SchPdschCfgCmnTimeDomRsrcAlloc cmnTimeDomRsrcAllocList[MAX_NUM_DL_ALLOC]; + // SchPdschTimeDomRsrcAlloc dedTimeDomRsrcAllocList[MAX_NUM_DL_ALLOC]; + + /* Initialization the structure and storing the total slot values. */ + memset(k0K1InfoTbl, 0, sizeof(SchK0K1TimingInfoTbl)); + k0K1InfoTbl->tblSize = cell->numSlots; + + /* Storing time domain resource allocation list based on common or dedicated configuration. */ + if(pdschCfgCmnPres == true) + { + numTimeDomAlloc = pdschCmnCfg.numTimeDomAlloc; + for(cfgIdx = 0; cfgIdxnumSlots; slotIdx++) + { + numK0 = 0; + /* Storing the values of k0 based on time domain resource + * allocation list. If the value is unavailable then fill default values, + * As per 38.331 PDSCH-TimeDomainResourceAllocation field descriptions. */ + for(k0Index = 0; ((k0Index < numTimeDomAlloc) && (k0Index < MAX_NUM_K0_IDX)); k0Index++) + { + /* TODO These if 0 we will remove during harq processing */ +#if 0 + if(pdschCfgCmnPres == true) + { + k0TmpVal = cmnTimeDomRsrcAllocList[k0Index].k0; + } + else + { + if(dedTimeDomRsrcAllocList[k0Index].k0 != NULLP) + { + k0TmpVal = *(dedTimeDomRsrcAllocList[k0Index].k0); + } + else + { + k0TmpVal = DEFAULT_K0_VALUE; + } + } +#endif + /* Checking all the Ul Alloc values. If value is less than MIN_NUM_K1_IDX + * then skip else continue storing the values. */ + numK1 = 0; + for(k1Index = 0; k1Index < ulAckListCount; k1Index++) + { + k1TmpVal = UlAckTbl[k1Index]; + if(k1TmpVal <= MIN_NUM_K1_IDX) + { + continue; + } + + k0K1InfoTbl->k0k1TimingInfo[slotIdx].k0Indexes[numK0].k1TimingInfo.k1Indexes[numK1++] = k1Index; + /* TODO Store K1 index where harq feedback will be received in harq table. */ + } + if(numK1) + { + k0K1InfoTbl->k0k1TimingInfo[slotIdx].k0Indexes[numK0].k1TimingInfo.numK1 = numK1; + k0K1InfoTbl->k0k1TimingInfo[slotIdx].k0Indexes[numK0].k0Index = k0Index; + numK0++; + } + } + if(numK0) + { + k0K1InfoTbl->k0k1TimingInfo[slotIdx].numK0 = numK0; + } + } +} + +/******************************************************************* + * + * @brief Fills k0 and k1 information table + * + * @details + * + * Function : BuildK0K1Table + * + * Functionality: + * Fills K0 and k1 information table + * + * @params[in] SchCellCb *cell,SchK0K1TimingInfoTbl *k0K1InfoTbl,bool + * pdschCfgCmnPres,uint8_t numTimeDomAlloc, SchPdschCfgCmnTimeDomRsrcAlloc + * cmnTimeDomRsrcAllocList[], SchPdschTimeDomRsrcAlloc + * dedTimeDomRsrcAllocList[], uint8_t ulAckListCount, uint8_t *UlAckTbl + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +void BuildK0K1Table(SchCellCb *cell, SchK0K1TimingInfoTbl *k0K1InfoTbl, bool pdschCfgCmnPres, SchPdschCfgCmn pdschCmnCfg,\ +SchPdschConfig pdschDedCfg, uint8_t ulAckListCount, uint8_t *UlAckTbl) +{ + +#ifdef NR_TDD + SlotConfig slotCfg; + bool ulSlotPresent = false; + uint8_t k0TmpVal = 0, k1TmpVal =0, tmpSlot=0, startSymbol=0, endSymbol=0, checkSymbol=0; + uint8_t slotIdx=0, k0Index=0, k1Index=0, numK0=0, numK1=0, cfgIdx=0, numTimeDomAlloc =0, totalCfgSlot =0; + SchPdschCfgCmnTimeDomRsrcAlloc cmnTimeDomRsrcAllocList[MAX_NUM_DL_ALLOC]; + SchPdschTimeDomRsrcAlloc dedTimeDomRsrcAllocList[MAX_NUM_DL_ALLOC]; +#endif + + if(cell->cellCfg.dupMode == DUPLEX_MODE_FDD) + { + BuildK0K1TableForFdd(cell, k0K1InfoTbl, pdschCfgCmnPres, pdschCmnCfg, pdschDedCfg, ulAckListCount, UlAckTbl); + } + else + { +#ifdef NR_TDD + + /* Initialization the K0K1 structure, total num of slot and calculating the slot pattern length. */ + memset(k0K1InfoTbl, 0, sizeof(SchK0K1TimingInfoTbl)); + k0K1InfoTbl->tblSize = cell->numSlots; + totalCfgSlot = calculateSlotPatternLength(cell->cellCfg.ssbSchCfg.scsCommon, cell->cellCfg.tddCfg.tddPeriod); + + /* Storing time domain resource allocation list based on common or + * dedicated configuration availability. */ + if(pdschCfgCmnPres == true) + { + numTimeDomAlloc = pdschCmnCfg.numTimeDomAlloc; + for(cfgIdx = 0; cfgIdxnumSlots; slotIdx++) + { + /* If current slot is UL or FLEXI then Skip because PDCCH is sent only in DL slots. */ + slotCfg = schGetSlotSymbFrmt(slotIdx%totalCfgSlot, cell->slotFrmtBitMap); + if(slotCfg == UL_SLOT || slotCfg == FLEXI_SLOT) + { + continue; + } + + /* Storing K0 , start symbol and length symbol for further processing. + * If K0 value is not available then we can fill the default values + * given in spec 38.331. */ + numK0 = 0; + for(k0Index = 0; ((k0Index < numTimeDomAlloc) && (k0Index < MAX_NUM_K0_IDX)); k0Index++) + { + if(pdschCfgCmnPres == true) + { + k0TmpVal = cmnTimeDomRsrcAllocList[k0Index].k0; + startSymbol = cmnTimeDomRsrcAllocList[k0Index].startSymbol; + endSymbol = startSymbol + cmnTimeDomRsrcAllocList[k0Index].lengthSymbol; + } + else + { + if(dedTimeDomRsrcAllocList[k0Index].k0 != NULLP) + { + k0TmpVal = *(dedTimeDomRsrcAllocList[k0Index].k0); + } + else + { + k0TmpVal = DEFAULT_K0_VALUE; + } + startSymbol = dedTimeDomRsrcAllocList[k0Index].startSymbol; + endSymbol = startSymbol + dedTimeDomRsrcAllocList[k0Index].symbolLength; + } + + /* If current slot + k0 is UL then skip the slot + * else if it is DL slot then continue the next steps + * else if it is a FLEXI slot then check symbols of slot, It should not + * contain any UL slot. */ + tmpSlot = (slotIdx+k0TmpVal) % totalCfgSlot; + slotCfg = schGetSlotSymbFrmt(tmpSlot, cell->slotFrmtBitMap); + if(slotCfg == UL_SLOT) + { + continue; + } + if(slotCfg == FLEXI_SLOT) + { + for(checkSymbol = startSymbol; checkSymbolcellCfg.tddCfg.slotCfg[tmpSlot][checkSymbol]; + if(slotCfg == UL_SLOT) + { + continue; + } + } + } + + /* If current slot + k0 + k1 is a DL slot then skip the slot + * else if it is UL slot then store the information + * else if it is FLEXI slot then check the symbols, it must have + * at least one UL symbol. */ + numK1 = 0; + for(k1Index = 0; k1Index < ulAckListCount; k1Index++) + { + k1TmpVal = UlAckTbl[k1Index]; + if(k1TmpVal > MIN_NUM_K1_IDX) + { + tmpSlot = (slotIdx+k0TmpVal+k1TmpVal) % totalCfgSlot; + slotCfg = schGetSlotSymbFrmt(tmpSlot, cell->slotFrmtBitMap); + if(slotCfg == DL_SLOT) + { + continue; + } + if(slotCfg == FLEXI_SLOT) + { + for(checkSymbol = 0; checkSymbolcellCfg.tddCfg.slotCfg[tmpSlot][checkSymbol] == UL_SLOT) + { + ulSlotPresent = true; + break; + } + } + } + if(ulSlotPresent == true || slotCfg == UL_SLOT) + { + k0K1InfoTbl->k0k1TimingInfo[slotIdx].k0Indexes[numK0].k1TimingInfo.k1Indexes[numK1++] = k1Index; + /* TODO Store K1 index where harq feedback will be received + * in harq table. */ + } + } + } + + /* Store all the values if all condition satisfies. */ + if(numK1) + { + k0K1InfoTbl->k0k1TimingInfo[slotIdx].k0Indexes[numK0].k1TimingInfo.numK1 = numK1; + k0K1InfoTbl->k0k1TimingInfo[slotIdx].k0Indexes[numK0].k0Index = k0Index; + numK0++; + } + } + if(numK0) + { + k0K1InfoTbl->k0k1TimingInfo[slotIdx].numK0 = numK0; + } + } +#endif + } +} + +/******************************************************************* +* +* @brief Fills K2 information table for FDD +* +* @details +* +* Function : BuildK2InfoTableForFdd +* +* Functionality: +* Fills K2 information table for FDD +* +* @params[in] SchCellCb *cell,SchPuschTimeDomRsrcAlloc timeDomRsrcAllocList[], +* uint16_t puschSymTblSize,SchK2TimingInfoTbl *k2InfoTbl +* @return ROK - success +* RFAILED - failure +* +* ****************************************************************/ +void BuildK2InfoTableForFdd(SchCellCb *cell, SchPuschTimeDomRsrcAlloc timeDomRsrcAllocList[], uint16_t puschSymTblSize,\ +SchK2TimingInfoTbl *msg3K2InfoTbl, SchK2TimingInfoTbl *k2InfoTbl) +{ + uint16_t slotIdx=0, k2Index=0, k2TmpIdx=0, msg3K2TmpIdx=0; + + /* Initialization the structure and storing the total slot values. */ + memset(k2InfoTbl, 0, sizeof(SchK2TimingInfoTbl)); + k2InfoTbl->tblSize = cell->numSlots; + if(msg3K2InfoTbl) + msg3K2InfoTbl->tblSize = cell->numSlots; + + /* Checking all possible indexes for K2. */ + for(slotIdx = 0; slotIdx < cell->numSlots; slotIdx++) + { + /* Storing K2 values. */ + for(k2Index = 0; ((k2Index < puschSymTblSize) && (k2Index < MAX_NUM_K2_IDX)); k2Index++) + { + k2TmpIdx= k2InfoTbl->k2TimingInfo[slotIdx].numK2; + k2InfoTbl->k2TimingInfo[slotIdx].k2Indexes[k2TmpIdx] = k2Index; + k2InfoTbl->k2TimingInfo[slotIdx].numK2++; + + /* Updating K2 values for MSG3 */ + if(msg3K2InfoTbl) + { + msg3K2TmpIdx = msg3K2InfoTbl->k2TimingInfo[slotIdx].numK2; + msg3K2InfoTbl->k2TimingInfo[slotIdx].k2Indexes[msg3K2TmpIdx] = k2Index; + msg3K2InfoTbl->k2TimingInfo[slotIdx].numK2++; + } + } + } +} + +/******************************************************************* + * + * @brief Fills K2 information table + * + * @details + * + * Function : BuildK2InfoTable + * + * Functionality: + * Fills K2 information table + * + * @params[in] SchCellCb *cell,SchPuschTimeDomRsrcAlloc timeDomRsrcAllocList[], + * uint16_t puschSymTblSize, SchK2TimingInfoTbl *k2InfoTbl + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +void BuildK2InfoTable(SchCellCb *cell, SchPuschTimeDomRsrcAlloc timeDomRsrcAllocList[], uint16_t puschSymTblSize,\ +SchK2TimingInfoTbl *msg3K2InfoTbl, SchK2TimingInfoTbl *k2InfoTbl) +{ + +#ifdef NR_TDD + bool dlSymbolPresent = false; + uint8_t slotIdx=0, k2Index=0, k2Val=0, k2TmpVal=0, msg3K2TmpVal=0, msg3Delta=0, numK2 =0, currentSymbol =0; + uint8_t startSymbol =0, endSymbol =0, checkSymbol=0, totalCfgSlot=0, slotCfg=0; + SlotConfig currentSlot; +#endif + + if(cell->cellCfg.dupMode == DUPLEX_MODE_FDD) + { + BuildK2InfoTableForFdd(cell, timeDomRsrcAllocList, puschSymTblSize, msg3K2InfoTbl, k2InfoTbl); + } + else + { +#ifdef NR_TDD + + /* Initialization the structure and storing the total slot values. */ + memset(k2InfoTbl, 0, sizeof(SchK2TimingInfoTbl)); + k2InfoTbl->tblSize = cell->numSlots; + if(msg3K2InfoTbl) + msg3K2InfoTbl->tblSize = cell->numSlots; + totalCfgSlot = calculateSlotPatternLength(cell->cellCfg.ssbSchCfg.scsCommon, cell->cellCfg.tddCfg.tddPeriod); + + /* Checking all possible indexes for K2. */ + for(slotIdx = 0; slotIdx < cell->numSlots; slotIdx++) + { + currentSlot = schGetSlotSymbFrmt(slotIdx % totalCfgSlot, cell->slotFrmtBitMap); + + /* If current slot is UL then skip because PDCCH is sent only in DL slots */ + if(currentSlot != UL_SLOT) + { + for(k2Index = 0; ((k2Index < puschSymTblSize) && (k2Index < MAX_NUM_K2_IDX)); k2Index++) + { + /* Storing k2, startSymbol, endSymbol information for further processing. + * If k2 is absent then fill the default values given in spec 38.331 + * PUSCH-TimeDomainResourceAllocationList field descriptions */ + k2Val = timeDomRsrcAllocList[k2Index].k2; + if(!k2Val) + { + switch(cell->cellCfg.ssbSchCfg.scsCommon) + { + case SCS_15KHZ: + k2Val = DEFAULT_K2_VALUE_FOR_SCS15; + break; + case SCS_30KHZ: + k2Val = DEFAULT_K2_VALUE_FOR_SCS30; + break; + case SCS_60KHZ: + k2Val = DEFAULT_K2_VALUE_FOR_SCS60; + break; + case SCS_120KHZ: + k2Val = DEFAULT_K2_VALUE_FOR_SCS120; + break; + } + } + + /* Current slot + k2 should be either UL or FLEXI slot. + * If slot is FLEXI then check all the symbols of that slot, + * it should not contain any DL or FLEXI slot */ + k2TmpVal = (slotIdx + k2Val) % totalCfgSlot; + slotCfg = schGetSlotSymbFrmt(k2TmpVal, cell->slotFrmtBitMap); + if(slotCfg != DL_SLOT) + { + if(slotCfg == FLEXI_SLOT) + { + startSymbol = timeDomRsrcAllocList[k2Index].startSymbol; + endSymbol = startSymbol+ timeDomRsrcAllocList[k2Index].symbolLength; + dlSymbolPresent = false; + for(checkSymbol= startSymbol; checkSymbolcellCfg.tddCfg.slotCfg[k2TmpVal][checkSymbol]; + if(currentSymbol == DL_SLOT || currentSymbol == FLEXI_SLOT) + { + dlSymbolPresent = true; + break; + } + } + } + /* Store all the values if all condition satisfies. */ + if(dlSymbolPresent != true || slotCfg == UL_SLOT) + { + numK2 = k2InfoTbl->k2TimingInfo[slotIdx].numK2; + k2InfoTbl->k2TimingInfo[slotIdx].k2Indexes[numK2] = k2Index; + k2InfoTbl->k2TimingInfo[slotIdx].numK2++; + } + } + + if(msg3K2InfoTbl) + { + msg3Delta = puschDeltaTable[cell->cellCfg.numerology]; + + /* Check for K2 for MSG3 */ + /* Current slot + k2 should be either UL or FLEXI slot. + * If slot is FLEXI then check all the symbols of that slot, + * it should not contain any DL or FLEXI slot */ + msg3K2TmpVal = (slotIdx + k2Val + msg3Delta) % totalCfgSlot; + slotCfg = schGetSlotSymbFrmt(msg3K2TmpVal, cell->slotFrmtBitMap); + if(slotCfg != DL_SLOT) + { + if(slotCfg == FLEXI_SLOT) + { + startSymbol = timeDomRsrcAllocList[k2Index].startSymbol; + endSymbol = startSymbol+ timeDomRsrcAllocList[k2Index].symbolLength; + dlSymbolPresent = false; + for(checkSymbol= startSymbol; checkSymbolcellCfg.tddCfg.slotCfg[msg3K2TmpVal][checkSymbol]; + if(currentSymbol == DL_SLOT || currentSymbol == FLEXI_SLOT) + { + dlSymbolPresent = true; + break; + } + } + } + /* Store all the values if all condition satisfies. */ + if(dlSymbolPresent != true || slotCfg == UL_SLOT) + { + numK2 = msg3K2InfoTbl->k2TimingInfo[slotIdx].numK2; + msg3K2InfoTbl->k2TimingInfo[slotIdx].k2Indexes[numK2] = k2Index; + msg3K2InfoTbl->k2TimingInfo[slotIdx].numK2++; + } + } + } + } + } + } +#endif + } +} + /********************************************************************** End of file **********************************************************************/