J-Release Documentation
[o-du/l2.git] / src / 5gnrsch / sch_utils.c
index 34aa846..3e8b23a 100644 (file)
@@ -746,24 +746,25 @@ uint16_t mcsTable[32][3] = {
       {  31,   6,     0}};  /* mcs index 31 */
 
 /* PUCCH resource sets before dedicated PUCCH resource configuration */
-/* Table 9.2.1-1 spec 38.213      */ 
-uint8_t pucchResourceSet[MAX_PUCCH_RES_SET_IDX][4] = {
-{ 0,  12,  2,  0 }, /* index  0 */
-{ 0,  12,  2,  0 }, /* index  1 */
-{ 0,  12,  2,  3 }, /* index  2 */
-{ 1,  10,  4,  0 }, /* index  3 */
-{ 1,  10,  4,  0 }, /* index  4 */
-{ 1,  10,  4,  2 }, /* index  5 */
-{ 1,  10,  4,  4 }, /* index  6 */
-{ 1,   4, 10,  0 }, /* index  7 */
-{ 1,   4, 10,  0 }, /* index  8 */
-{ 1,   4, 10,  2 }, /* index  9 */
-{ 1,   4, 10,  4 }, /* index 10 */
-{ 1,   0, 14,  0 }, /* index 11 */
-{ 1,   0, 14,  0 }, /* index 12 */
-{ 1,   0, 14,  2 }, /* index 13 */
-{ 1,   0, 14,  4 }, /* index 14 */
-{ 1,   0, 14,  0 }, /* index 15 */
+/* Table 9.2.1-1 spec 38.213      */
+/*{PUCCH_Format, 1stSym, NumSym, PRBOffset, Num_CyclicShift}*/
+uint8_t pucchResourceSet[MAX_PUCCH_RES_SET_IDX][5] = {
+{ 0,  12,  2,  0,  2 }, /* index  0 */
+{ 0,  12,  2,  0,  3 }, /* index  1 */
+{ 0,  12,  2,  3,  3 }, /* index  2 */
+{ 1,  10,  4,  0,  2 }, /* index  3 */
+{ 1,  10,  4,  0,  4 }, /* index  4 */
+{ 1,  10,  4,  2,  4 }, /* index  5 */
+{ 1,  10,  4,  4,  4 }, /* index  6 */
+{ 1,   4, 10,  0,  2 }, /* index  7 */
+{ 1,   4, 10,  0,  4 }, /* index  8 */
+{ 1,   4, 10,  2,  4 }, /* index  9 */
+{ 1,   4, 10,  4,  4 }, /* index 10 */
+{ 1,   0, 14,  0,  2 }, /* index 11 */
+{ 1,   0, 14,  0,  4 }, /* index 12 */
+{ 1,   0, 14,  2,  4 }, /* index 13 */
+{ 1,   0, 14,  4,  4 }, /* index 14 */
+{ 1,   0, 14,  (MAX_NUM_RB/4),  4 }, /* index 15 */
 };
 
 /*CQI Table From Spec 38.214 Table 5.2.2.1-2
@@ -771,7 +772,7 @@ uint8_t pucchResourceSet[MAX_PUCCH_RES_SET_IDX][4] = {
  * Modulation Scheme is numbered based on bit rate as follows
  * QPSK = 2, 16QAM = 4, 64QAM = 6
  * */
-unsigned long cqiTable1[MAX_NUM_CQI_IDX][3] = {
+float cqiTable1[MAX_NUM_CQI_IDX][3] = {
 { 0, 0, 0},        /*index 0*/
 { 2, 78, 0.1523},  /*index 1*/
 { 2, 120, 0.2344}, /*index 2*/
@@ -1198,6 +1199,7 @@ SchUeCb* schGetUeCb(SchCellCb *cellCb, uint16_t crnti)
  **/
 void schInitUlSlot(SchUlSlotInfo *schUlSlotInfo)
 {
+   uint8_t ueIdx = 0;
    CmLList *node = NULLP, *next = NULLP;
    FreePrbBlock *freeBlock;
 
@@ -1226,9 +1228,11 @@ void schInitUlSlot(SchUlSlotInfo *schUlSlotInfo)
       freeBlock->endPrb = MAX_NUM_RB-1;
       addNodeToLList(&schUlSlotInfo->prbAlloc.freePrbBlockList, freeBlock, NULL);
    }
-
-   schUlSlotInfo->puschCurrentPrb = PUSCH_START_RB;
-   schUlSlotInfo->schPuschInfo = NULLP;
+   for(ueIdx = 0; ueIdx < MAX_NUM_UE; ueIdx++)
+   {
+      schUlSlotInfo->schPuschInfo[ueIdx] = NULLP;
+   }
 }
 
 /**
@@ -1857,6 +1861,60 @@ uint8_t findSsStartSymbol(uint8_t *mSymbolsWithinSlot)
    return(MAX_SYMB_PER_SLOT);
 }
 
+/*
+ *  @brief: Function will extract the StartPrb as per the given RBGIndex 
+ *
+ *  Function: extractStartPrbForRBG
+ *
+ *  This function will extract the StartPrb of a rbgIndex. This RbgIndex doesnt
+ *  have direct mapping with index in FreqDomRsrc instead it is mapping with
+ *  those rbg which is set(i.e. available for PDCCH)
+ *
+ *  @param[in]  uint8_t freqDomainRsrc[6] (As per Spec 38.331, ControlResourceSet.frequencyDomainResources)
+ *                 freqDomainRsrc[0] =RBG0 to RBG7
+ *                 freqDomainRsrc[1] =RBG8 to RBG15
+ *                 ...
+ *                 freqDomainRsrc[5] =RBG40 to RBG47
+ *                 (Every RBG has 6 PRBs)
+ *
+ *              uint8_t rbgIndex
+ *
+ *
+ *         [return]: startPrb of that rbgIndex
+ * */
+uint16_t extractStartPrbForRBG(uint8_t *freqDomainRsrc, uint8_t rbgIndex)
+{
+   uint8_t freqIdx = 0, idx = 0;
+   uint8_t count = 0, bitPos = 0;
+   uint8_t totalPrbPerFreqIdx = NUM_PRBS_PER_RBG * 8; /*8 = no. of Bits in uint8_t*/
+   uint16_t startPrb = MAX_NUM_RB;
+
+   for(freqIdx = 0; freqIdx < FREQ_DOM_RSRC_SIZE; freqIdx++)
+   {
+      if(freqDomainRsrc[freqIdx] & 0xFF)
+      {
+         /*Tracking from the 7th Bit because in FreqDomRsrc , lowestPRB is
+          * stored in MSB and so on*/
+         idx = 128;
+         bitPos = 0;
+         while(idx)
+         {
+           if(freqDomainRsrc[freqIdx] & idx)
+           {
+               if(count == rbgIndex)
+               {
+                  startPrb = (totalPrbPerFreqIdx * freqIdx) + (bitPos * NUM_PRBS_PER_RBG);
+                  return startPrb;
+               }
+               count++;
+           }
+           bitPos++;
+           idx = idx >> 1;
+         }
+      }
+   }
+   return startPrb;
+}
 /**
  * @brief Function to count number of RBG from Coreset's FreqDomainResource 
  *
@@ -1879,7 +1937,7 @@ uint8_t findSsStartSymbol(uint8_t *mSymbolsWithinSlot)
 **/
 uint8_t countRBGFrmCoresetFreqRsrc(uint8_t *freqDomainRsrc)
 {
-   uint8_t freqIdx = 0, idx = 1;
+   uint8_t freqIdx = 0, idx = 0;
    uint8_t count = 0;
 
    for(freqIdx = 0; freqIdx < FREQ_DOM_RSRC_SIZE; freqIdx++)
@@ -1887,7 +1945,6 @@ uint8_t countRBGFrmCoresetFreqRsrc(uint8_t *freqDomainRsrc)
       if(freqDomainRsrc[freqIdx] & 0xFF)
       {
          idx = 1;
-         count = 0;
          while(idx)
          {
            if(freqDomainRsrc[freqIdx] & idx)
@@ -1985,7 +2042,7 @@ void fillCqiAggLvlMapping(SchPdcchInfo *pdcchInfo)
       /*CQI table number 1 is used Spec 38.214 Table 5.2.2.1-2 by default.
        *TODO: cqi-table param in CSI-RepotConfig(3gpp 38.331) will report
        * which table to be used*/
-      pdcchBits = dciSize / cqiTable1[cqiIdx][2];
+      pdcchBits = ceil(dciSize / cqiTable1[cqiIdx][2]);
       for(aggLvlIdx = 0; (aggLvlIdx < MAX_NUM_AGG_LVL) && (pdcchBits != 0); aggLvlIdx++)
       {
          numOfBitsAvailForAggLevel = (totalRE_PerAggLevel[aggLvlIdx] * cqiTable1[cqiIdx][0]);
@@ -2005,6 +2062,234 @@ void fillCqiAggLvlMapping(SchPdcchInfo *pdcchInfo)
    }
 }
 
+/*
+ * @brief Function to calculate Value Y 
+ *
+ *   Function: schCalY
+ *
+ *   Calculates value of YpKp as per [10.1,TS38.213].
+ *   A0 is for first CS, A1 for second CS and A2 is for third CS
+ *
+ *   @params[in]: coresetId and Previous Y
+ * */
+uint32_t schCalY(uint8_t csId, uint32_t prevY)
+{
+   uint32_t A0 = 39827, A1 = 39829, A2 = 39839;
+   uint32_t D = 65537;
+
+   switch(csId % 3)
+   {
+      case 0:
+        {
+           return((A0 * prevY) % D);                 
+        } 
+      case 1:
+        {
+           return((A1 * prevY) % D);                 
+        } 
+      case 2:
+        {
+           return((A2 * prevY) % D);                 
+        }
+      default:
+        {
+           DU_LOG("\nERROR  --> SCH: Issue in calculating value of Y");
+           return(0);
+        }
+   }
+   return 0;
+}
+
+/*
+ * @brief Function to calculate the value Y used for CCE Index formula
+ *
+ *   Function: schUpdValY
+ *
+ *   As per Spec 38.213, Sec 10.1 Formula for CCE Index contains a coefficient
+ *   value called 'Y' and storing the same in the ueCb which will be later used
+ *   in pdcch allocation
+ *
+ * @params[in] : SchUeCb, PdcchInfo
+ *    [return] : uint8_t ROK, RFAILED : Memory allocation status
+ *
+ * */
+uint8_t schUpdValY(SchUeCb *ueCb, SchPdcchInfo *pdcchInfo)
+{
+   uint8_t slotIdx = 0;
+   if(pdcchInfo->y == NULLP)
+   {
+      SCH_ALLOC(pdcchInfo->y, (sizeof(uint32_t) *  ueCb->cellCb->numSlots));
+      if(pdcchInfo->y == NULLP)
+      {
+         DU_LOG("\nERROR  --> SCH: Memory Allocation of Y failed");
+         return RFAILED;
+      }
+   }
+
+   for(slotIdx= 0 ; slotIdx < ueCb->cellCb->numSlots; slotIdx++)
+   {
+      if(slotIdx == 0)
+      {
+         pdcchInfo->y[slotIdx] = schCalY(pdcchInfo->cRSetRef->cRSetId, ueCb->crnti);
+      }
+      else
+      {
+         pdcchInfo->y[slotIdx] = schCalY(pdcchInfo->cRSetRef->cRSetId, pdcchInfo->y[slotIdx - 1]);
+      }
+   }
+   return ROK;
+}
+
+/*
+ *  @brief : Function to convert SlotPeriodicity to Value
+ *
+ *  Function: schConvertSlotPeriodicityEnumToValue
+ *
+ *  @param[IN]: SchMSlotPeriodicity enum
+ *        [return]: slotOffsetVal
+ * */
+uint16_t schConvertSlotPeriodicityEnumToValue(SchMSlotPeriodicity slotPeriod)
+{
+   uint16_t slotPeriodVal = 0;
+
+   switch(slotPeriod)
+   {
+      case SLOT_PERIODICITY_SL_1:
+      {
+         slotPeriodVal = 1;
+         break;
+      }
+      case SLOT_PERIODICITY_SL_2:
+      {
+         slotPeriodVal = 2;
+         break;
+      }
+      case SLOT_PERIODICITY_SL_4:
+      {
+         slotPeriodVal = 4;
+         break;
+      }
+      case SLOT_PERIODICITY_SL_5:
+      {
+         slotPeriodVal = 5;
+         break;
+      }
+      case SLOT_PERIODICITY_SL_8:
+      {
+         slotPeriodVal = 8;
+         break;
+      }
+      case SLOT_PERIODICITY_SL_10:
+      {
+         slotPeriodVal = 10;
+         break;
+      }
+      case SLOT_PERIODICITY_SL_16:
+      {
+         slotPeriodVal = 16;
+         break;
+      }
+      case SLOT_PERIODICITY_SL_20:
+      {
+         slotPeriodVal = 20;
+         break;
+      }
+      case SLOT_PERIODICITY_SL_40:
+      {
+         slotPeriodVal = 40;
+         break;
+      }
+      case SLOT_PERIODICITY_SL_80:
+      {
+         slotPeriodVal = 80;
+         break;
+      }
+      case SLOT_PERIODICITY_SL_160:
+      {
+         slotPeriodVal = 160;
+         break;
+      }
+      case SLOT_PERIODICITY_SL_320:
+      {
+         slotPeriodVal = 320;
+         break;
+      }
+      case SLOT_PERIODICITY_SL_640:
+      {
+         slotPeriodVal = 640;
+         break;
+      }
+      case SLOT_PERIODICITY_SL_1280:
+      {
+         slotPeriodVal = 1280;
+         break;
+      }
+      case SLOT_PERIODICITY_SL_2560:
+      {
+         slotPeriodVal = 2560;
+         break;
+      }
+      default:
+      {
+         slotPeriodVal = 0;
+         break;
+      }
+   }
+   return slotPeriodVal;
+}
+
+/*
+ *  @brief: Function to extract the numCandidates from aggLevel.
+ *
+ *  Function: extractNumOfCandForAggLvl
+ *
+ *  @params[IN]: SearchSpace, aggLevel
+ *         [RETURN]: numCandidates.
+ * */
+uint8_t extractNumOfCandForAggLvl(SchSearchSpace *searchSpace, uint8_t aggLvl)
+{
+   uint8_t numCand = 0;
+
+   switch(aggLvl)
+   {
+      case 1:
+      {
+         numCand = searchSpace->numCandidatesAggLevel1;
+         break;
+      }
+      case 2:
+      {
+         numCand = searchSpace->numCandidatesAggLevel2;
+         break;
+      }
+      case 4:
+      {
+         numCand = searchSpace->numCandidatesAggLevel4;
+         break;
+      }
+      case 8:
+      {
+         numCand = searchSpace->numCandidatesAggLevel8;
+         break;
+      }
+      case 16:
+      {
+         numCand = searchSpace->numCandidatesAggLevel16;
+         break;
+      }
+      default:
+      {
+         numCand = 0;
+      }
+      /*AGGREGATION_LEVEL_N8 enum Value is 7 thus hardcoding the correct Value
+       * (8)*/
+      if(numCand == AGGREGATION_LEVEL_N8)
+      {
+         numCand = 8;
+      }
+   }
+   return numCand;
+}
 /**********************************************************************
          End of file
 **********************************************************************/