Fixes for SSB transmission in Radio mode integration [Issue-ID: ODUHIGH-267]
[o-du/l2.git] / src / 5gnrsch / sch.c
index c4cc663..881f93a 100644 (file)
@@ -123,7 +123,7 @@ uint8_t SchInstCfg(RgCfg *cfg, Inst  dInst)
    uint16_t ret = LCM_REASON_NOT_APPL;
    Inst     inst = (dInst - SCH_INST_START);
 
-   printf("\nEntered SchInstCfg()");
+   DU_LOG("\nDEBUG  -->  SCH : Entered SchInstCfg()");
    /* Check if Instance Configuration is done already */
    if (schCb[inst].schInit.cfgDone == TRUE)
    {
@@ -149,26 +149,26 @@ uint8_t SchInstCfg(RgCfg *cfg, Inst  dInst)
    schCb[inst].genCfg.isSCellActDeactAlgoEnable =  cfg->s.schInstCfg.genCfg.isSCellActDeactAlgoEnable;
 #endif
    schCb[inst].genCfg.startCellId    = cfg->s.schInstCfg.genCfg.startCellId;
-#if 0
+
    /* Initialzie the timer queue */   
-   memset(&schCb[inst].tmrTq, 0, sizeof(CmTqType)*RGSCH_TQ_SIZE);
+   memset(&schCb[inst].tmrTq, 0, sizeof(CmTqType) * SCH_TQ_SIZE);
    /* Initialize the timer control point */
    memset(&schCb[inst].tmrTqCp, 0, sizeof(CmTqCp));
    schCb[inst].tmrTqCp.tmrLen = RGSCH_TQ_SIZE;
 
    /* SS_MT_TMR needs to be enabled as schActvTmr needs instance information */
-   /* Timer Registration request to SSI */
+   /* Timer Registration request to system services */
    if (ODU_REG_TMR_MT(schCb[inst].schInit.ent, dInst,
            (int)schCb[inst].genCfg.tmrRes, schActvTmr) != ROK)
    {
-      RLOG_ARG0(L_ERROR,DBG_INSTID,inst, "SchInstCfg(): Failed to "
+      DU_LOG("\nERROR  -->  SCH : SchInstCfg(): Failed to "
            "register timer.");
       return (LCM_REASON_MEM_NOAVAIL);
    }   
-#endif               
+              
    /* Set Config done in TskInit */
    schCb[inst].schInit.cfgDone = TRUE;
-   printf("\nScheduler gen config done");
+   DU_LOG("\nINFO  -->  SCH : Scheduler gen config done");
 
    return ret;
 }
@@ -205,7 +205,7 @@ uint8_t SchProcGenCfgReq(Pst *pst, RgMngmt *cfg)
            "pst->dstInst=%d SCH_INST_START=%d", pst->dstInst,SCH_INST_START); 
       return ROK;
    }
-   printf("\nSCH : Received scheduler gen config");
+   DU_LOG("\nINFO -->  SCH : Received scheduler gen config");
    /* Fill the post structure for sending the confirmation */
    memset(&cfmPst, 0 , sizeof(Pst));
    SchFillCfmPst(pst, &cfmPst, cfg);
@@ -327,9 +327,256 @@ uint8_t MacSchCrcInd(Pst *pst, CrcIndInfo *crcInd)
    return ROK;
 }
 
+#ifdef NR_TDD
+/**
+ *@brief Returns TDD periodicity in micro seconds
+ *
+ * @details
+ * 
+ * Function : schGetPeriodicityInMsec 
+ * 
+ * This API retunrs TDD periodicity in micro seconds
+ * 
+ * @param[in] DlUlTxPeriodicity 
+ * @return  periodicityInMsec
+ * **/
+
+uint16_t schGetPeriodicityInMsec(DlUlTxPeriodicity tddPeriod)
+{
+   uint16_t  periodicityInMsec = 0;
+   switch(tddPeriod)
+   {
+      case TX_PRDCTY_MS_0P5:
+      {
+         periodicityInMsec = 500;
+         break;
+      }
+      case TX_PRDCTY_MS_0P625:
+      {
+         periodicityInMsec = 625;
+         break;
+      }
+      case TX_PRDCTY_MS_1:
+      {
+         periodicityInMsec = 1000;
+         break;
+      }
+      case TX_PRDCTY_MS_1P25:
+      {
+         periodicityInMsec = 1250;
+         break;
+      }
+      case TX_PRDCTY_MS_2:
+      {
+         periodicityInMsec = 2000;
+         break;
+      }
+      case TX_PRDCTY_MS_2P5:
+      {
+         periodicityInMsec = 2500;
+         break;
+      }
+      case TX_PRDCTY_MS_5:
+      {
+         periodicityInMsec = 5000;
+         break;
+      }
+      case TX_PRDCTY_MS_10:
+      {
+         periodicityInMsec = 10000;
+         break;
+      }
+      default:
+      {
+        DU_LOG("\nERROR  -->  SCH : Invalid DlUlTxPeriodicity:%d", tddPeriod);
+      }
+   }
+
+   return periodicityInMsec;
+}
+
+
+/**
+ * @brief init TDD slot config 
+ *
+ * @details
+ *
+ *     Function : schInitTddSlotCfg 
+ *      
+ *      This API is invoked after receiving schCellCfg
+ *           
+ *  @param[in]  schCellCb *cell
+ *  @param[in]  SchCellCfg *schCellCfg
+ *  @return  void
+ **/
+void schInitTddSlotCfg(SchCellCb *cell, SchCellCfg *schCellCfg)
+{
+   uint16_t periodicityInMicroSec = 0;
+   uint32_t slotBitPos, symbBitPos, bitMask;
+   int8_t slotIdx, symbIdx;
+
+   periodicityInMicroSec = schGetPeriodicityInMsec(schCellCfg->tddCfg.tddPeriod);
+   cell->numSlotsInPeriodicity = (periodicityInMicroSec * pow(2, schCellCfg->numerology))/1000;
+cell->slotFrmtBitMap = 0;
+   cell->symbFrmtBitMap = 0;
+   slotBitPos = (cell->numSlotsInPeriodicity*2)-1; /* considering 2 bits to represent a slot */
+   symbBitPos = (MAX_SYMB_PER_SLOT*2)-1; /* considering 2 bits to represent a symbol */
+   for(slotIdx = cell->numSlotsInPeriodicity-1; slotIdx >= 0; slotIdx--)
+   {
+      symbIdx = 0;
+      /* If the first and last symbol are the same, the entire slot is the same type */
+      if((schCellCfg->tddCfg.slotCfg[slotIdx][symbIdx] == schCellCfg->tddCfg.slotCfg[slotIdx][MAX_SYMB_PER_SLOT-1]) &&
+              schCellCfg->tddCfg.slotCfg[slotIdx][symbIdx] != FLEXI_SLOT)
+      {
+         switch(schCellCfg->tddCfg.slotCfg[slotIdx][symbIdx])
+         {
+            case DL_SLOT:
+            {
+               /*BitMap to be set to 00 */
+               bitMask = 1<<slotBitPos;
+               cell->slotFrmtBitMap = (cell->slotFrmtBitMap & ~(bitMask)) | ((0<<slotBitPos) & bitMask);
+               slotBitPos--;
+               bitMask = 1<<slotBitPos;
+               cell->slotFrmtBitMap = (cell->slotFrmtBitMap & ~(bitMask)) | ((0<<slotBitPos) & bitMask);
+               slotBitPos--;
+               break;
+            }
+            case UL_SLOT:
+            {
+               /*BitMap to be set to 01 */
+               bitMask = 1<<slotBitPos;
+               cell->slotFrmtBitMap = (cell->slotFrmtBitMap & ~(bitMask)) | ((0<<slotBitPos) & bitMask);
+               slotBitPos--;
+               bitMask = 1<<slotBitPos;
+               cell->slotFrmtBitMap = (cell->slotFrmtBitMap & ~(bitMask)) | ((1<<slotBitPos) & bitMask);
+               slotBitPos--;
+               break;
+            }
+            default:
+               DU_LOG("\nERROR  -->  SCH : Invalid slot Config in schInitTddSlotCfg");
+           }
+         continue;
+      }
+      /* slot config is flexible. First set slotBitMap to 10 */
+      bitMask = 1<<slotBitPos;
+      cell->slotFrmtBitMap = (cell->slotFrmtBitMap & ~(bitMask)) | ((1<<slotBitPos) & bitMask);
+      slotBitPos--;
+      bitMask = 1<<slotBitPos;
+      cell->slotFrmtBitMap = (cell->slotFrmtBitMap & ~(bitMask)) | ((0<<slotBitPos) & bitMask);
+      slotBitPos--;
+      /* Now set symbol bitmap */ 
+      for(symbIdx = MAX_SYMB_PER_SLOT-1; symbIdx >= 0; symbIdx--)
+      {
+         switch(schCellCfg->tddCfg.slotCfg[slotIdx][symbIdx])
+         {
+            case DL_SLOT:
+            {
+               /*symbol BitMap to be set to 00 */
+               bitMask = 1<<symbBitPos;
+               cell->symbFrmtBitMap = (cell->symbFrmtBitMap & ~(bitMask)) | ((0<<symbBitPos) & bitMask);
+               symbBitPos--;
+               bitMask = 1<<symbBitPos;
+               cell->symbFrmtBitMap = (cell->symbFrmtBitMap & ~(bitMask)) | ((0<<symbBitPos) & bitMask);
+               symbBitPos--;
+               break;
+            }
+            case UL_SLOT:
+            {
+               /*symbol BitMap to be set to 01 */
+               bitMask = 1<<symbBitPos;
+               cell->symbFrmtBitMap = (cell->symbFrmtBitMap & ~(bitMask)) | ((0<<symbBitPos) & bitMask);
+               symbBitPos--;
+               bitMask = 1<<symbBitPos;
+               cell->symbFrmtBitMap = (cell->symbFrmtBitMap & ~(bitMask)) | ((1<<symbBitPos) & bitMask);
+               symbBitPos--;
+               break;
+            }
+            case FLEXI_SLOT:
+            {
+               /*symbol BitMap to be set to 10 */
+               bitMask = 1<<symbBitPos;
+               cell->symbFrmtBitMap = (cell->symbFrmtBitMap & ~(bitMask)) | ((1<<symbBitPos) & bitMask);
+               symbBitPos--;
+               bitMask = 1<<symbBitPos;
+               cell->symbFrmtBitMap = (cell->symbFrmtBitMap & ~(bitMask)) | ((0<<symbBitPos) & bitMask);
+               symbBitPos--;
+               break;
+            }
+            default:
+              DU_LOG("\nERROR  -->  SCH : Invalid slot Config in schInitTddSlotCfg");
+         }
+      }
+   }
+
+}
+#endif
+
+/**
+ * @brief Fill SSB start symbol
+ *
+ * @details
+ *
+ *     Function : fillSsbStartSymb 
+ *      
+ *      This API stores SSB start index per beam
+ *           
+ *  @param[in]  SchCellCb     *cellCb
+ *  @return  int
+ *      -# ROK 
+ *      -# RFAILED 
+ **/
+void fillSsbStartSymb(SchCellCb *cellCb)
+{
+   uint8_t cnt, scs, symbIdx, ssbStartSymbArr[SCH_MAX_SSB_BEAM];
+
+   scs = cellCb->cellCfg.ssbSchCfg.scsCommon;
+
+   memset(ssbStartSymbArr, 0, sizeof(SCH_MAX_SSB_BEAM));
+   symbIdx = 0;
+   /* Determine value of "n" based on Section 4.1 of 3GPP TS 38.213 */
+   switch(scs)
+   {
+      case SCS_15KHZ:
+        {
+            if(cellCb->cellCfg.dlFreq <= 300000)
+              cnt = 2;/* n = 0, 1 */
+            else
+               cnt = 4; /* n = 0, 1, 2, 3 */
+           for(uint8_t idx=0; idx<cnt; idx++)
+           {
+              /* start symbol determined using {2, 8} + 14n */
+              ssbStartSymbArr[symbIdx++] = 2 + SCH_SYMBOL_PER_SLOT*idx;
+              ssbStartSymbArr[symbIdx++] = 8 + SCH_SYMBOL_PER_SLOT*idx;
+           }
+        }
+        break;
+      case SCS_30KHZ:
+        {
+            if(cellCb->cellCfg.dlFreq <= 300000)
+              cnt = 1;/* n = 0 */
+            else
+               cnt = 2; /* n = 0, 1 */
+           for(uint8_t idx=0; idx<cnt; idx++)
+           {
+              /* start symbol determined using {4, 8, 16, 20} + 28n */
+              ssbStartSymbArr[symbIdx++] = 4 + SCH_SYMBOL_PER_SLOT*idx;
+              ssbStartSymbArr[symbIdx++] = 8 + SCH_SYMBOL_PER_SLOT*idx;
+              ssbStartSymbArr[symbIdx++] = 16 + SCH_SYMBOL_PER_SLOT*idx;
+              ssbStartSymbArr[symbIdx++] = 20 + SCH_SYMBOL_PER_SLOT*idx;
+            }
+        }
+        break;
+      default:
+        DU_LOG("\nERROR  -->  SCH : SCS %d is currently not supported", scs);
+   }
+   memset(cellCb->ssbStartSymbArr, 0, sizeof(SCH_MAX_SSB_BEAM));
+   memcpy(cellCb->ssbStartSymbArr, ssbStartSymbArr, SCH_MAX_SSB_BEAM);
+
+}
+
 
 /**
- * @brief inti cellCb based on cellCfg
+ * @brief init cellCb based on cellCfg
  *
  * @details
  *
@@ -345,7 +592,7 @@ uint8_t MacSchCrcInd(Pst *pst, CrcIndInfo *crcInd)
  **/
 uint8_t schInitCellCb(Inst inst, SchCellCfg *schCellCfg)
 {
-   SchCellCb *cell;
+   SchCellCb *cell= NULLP;
    SCH_ALLOC(cell, sizeof(SchCellCb));
    if(!cell)
    {
@@ -385,6 +632,9 @@ uint8_t schInitCellCb(Inst inst, SchCellCfg *schCellCfg)
       default:
         DU_LOG("\nERROR  -->  SCH : Numerology %d not supported", schCellCfg->numerology);
    }
+#ifdef NR_TDD
+   schInitTddSlotCfg(cell, schCellCfg);   
+#endif
 
    SCH_ALLOC(cell->schDlSlotInfo, cell->numSlots * sizeof(SchDlSlotInfo*));
    if(!cell->schDlSlotInfo)
@@ -428,6 +678,9 @@ uint8_t schInitCellCb(Inst inst, SchCellCfg *schCellCfg)
       cell->schUlSlotInfo[idx] = schUlSlotInfo;
 
    }
+   cell->firstSsbTransmitted = false;
+   cell->firstSib1Transmitted = false;
+   fillSsbStartSymb(cell);
    schCb[inst].cells[inst] = cell;
 
    DU_LOG("\nINFO  -->  SCH : Cell init completed for cellId:%d", cell->cellId);
@@ -578,7 +831,7 @@ void fillSchSib1Cfg(uint8_t bandwidth, uint8_t numSlots, SchSib1Cfg *sib1SchCfg,
    pdsch->dmrs.dmrsAddPos                    = DMRS_ADDITIONAL_POS;
 
    pdsch->pdschFreqAlloc.resourceAllocType   = 1; /* RAT type-1 RIV format */
-   pdsch->pdschFreqAlloc.freqAlloc.startPrb  = offset + SCH_SSB_NUM_PRB; /* the RB numbering starts from coreset0,
+   pdsch->pdschFreqAlloc.freqAlloc.startPrb  = offsetPointA + SCH_SSB_NUM_PRB + 1; /* the RB numbering starts from coreset0,
                                                                            and PDSCH is always above SSB */
    pdsch->pdschFreqAlloc.freqAlloc.numPrb    = schCalcNumPrb(tbSize,sib1SchCfg->sib1Mcs,numPdschSymbols);
    pdsch->pdschFreqAlloc.vrbPrbMapping       = 0; /* non-interleaved */
@@ -595,51 +848,6 @@ void fillSchSib1Cfg(uint8_t bandwidth, uint8_t numSlots, SchSib1Cfg *sib1SchCfg,
 
 }
 
-/**
- * @brief Fill SSB start symbol
- *
- * @details
- *
- *     Function : fillSsbStartSymb 
- *      
- *      This API stores SSB start index per beam
- *           
- *  @param[in]  SchCellCb     *cellCb
- *  @return  int
- *      -# ROK 
- *      -# RFAILED 
- **/
-void fillSsbStartSymb(SchCellCb *cellCb)
-{
-   uint8_t cnt, scs;
-
-   scs = cellCb->cellCfg.ssbSchCfg.scsCommon;
-   uint8_t ssbStartSymbArr[SCH_MAX_SSB_BEAM];
-
-   memset(ssbStartSymbArr, 0, sizeof(SCH_MAX_SSB_BEAM));
-   /* Determine value of "n" based on Section 4.1 of 3GPP TS 38.213 */
-   switch(scs)
-   {
-      case SCH_SCS_15KHZ:
-        {
-           uint8_t symbIdx=0;
-           cnt = 2;/* n = 0, 1 for SCS = 15KHz */
-           for(uint8_t idx=0; idx<cnt; idx++)
-           {
-              /* start symbol determined using {2, 8} + 14n */
-              ssbStartSymbArr[symbIdx++]       = 2 + SCH_SYMBOL_PER_SLOT*idx;
-              ssbStartSymbArr[symbIdx++]       = 8 + SCH_SYMBOL_PER_SLOT*idx;
-           }
-        }
-        break;
-      default:
-        DU_LOG("\nERROR  -->  SCH : SCS %d is currently not supported", scs);
-   }
-   memset(cellCb->ssbStartSymbArr, 0, sizeof(SCH_MAX_SSB_BEAM));
-   memcpy(cellCb->ssbStartSymbArr, ssbStartSymbArr, SCH_MAX_SSB_BEAM);
-
-}
-
 /**
  * @brief cell config from MAC to SCH.
  *
@@ -736,7 +944,7 @@ uint8_t MacSchDlRlcBoInfo(Pst *pst, DlRlcBoInfo *dlBoInfo)
       return RFAILED;
    }
 
-   slot = (cell->slotInfo.slot + SCHED_DELTA + PHY_DELTA + BO_DELTA) % cell->numSlots;
+   slot = (cell->slotInfo.slot + SCHED_DELTA + PHY_DELTA_DL + BO_DELTA) % cell->numSlots;
    schDlSlotInfo = cell->schDlSlotInfo[slot];
 
    SCH_ALLOC(schDlSlotInfo->dlMsgInfo, sizeof(DlMsgInfo));