Addressing flow wise comments
[o-du/l2.git] / src / 5gnrsch / sch_rach.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
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                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
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 *******************************************************************************/
18
19 /************************************************************************
20  
21      Name:     sch_rach.c
22   
23      Type:     C source file
24   
25      Desc:     C source code for rach handling functions
26   
27      File:     sch_rach.c
28   
29 **********************************************************************/
30
31 /** @file sch_rach.c
32 @brief This file implements the rach handling.
33 */
34
35 #include "stdbool.h"
36 #include "envopt.h"        /* environment options */
37 #include "envdep.h"        /* environment dependent */
38 #include "envind.h"        /* environment independent */
39 #include "gen.h"           /* general layer */
40 #include "ssi.h"           /* system service interface */
41 #include "cm_tkns.h"       /* Common Token Defines */
42 #include "cm_llist.h"      /* Common Link List Defines */
43 #include "cm_hash.h"       /* Common Hash List Defines */
44 #include "cm_mblk.h"       /* common memory link list library */
45 #include "cm_lte.h"        /* Common LTE Defines */
46 #include "tfu.h"
47 #include "lrg.h"
48
49 #include "gen.x"           /* general layer typedefs */
50 #include "ssi.x"           /* system services typedefs */
51 #include "cm5.x"           /* system services */
52 #include "cm_tkns.x"       /* Common Token Definitions */
53 #include "cm_llist.x"      /* Common Link List Definitions */
54 #include "cm_lib.x"        /* Common Library Definitions */
55 #include "cm_hash.x"       /* Common Hash List Definitions */
56 #include "cm_mblk.x"       /* common memory link list library */
57 #include "cm_lte.x"        /* Common LTE Defines */
58 #include "tfu.x"
59 #include "lrg.x"
60 #include "du_log.h"
61 #include "du_app_mac_inf.h"
62 #include "mac_sch_interface.h"
63 #include "sch.h"
64 #include "sch_utils.h"
65 #include "common_def.h"
66
67 extern SchCb schCb[SCH_MAX_INST];
68 extern uint8_t puschDeltaTable[MAX_MU_PUSCH];
69
70 /**
71  * @brief calculate ra-rnti function. 
72  *
73  * @details
74  *
75  *     Function : calculateRaRnti
76  *     
77  *     This function calculates ra-rnti
78  *     
79  *  @param[in]  symbol index
80  *  @param[in]  slot index
81  *  @param[in]  frequency index
82  *  @return  ra-rnti
83  **/
84 uint16_t calculateRaRnti(uint8_t symbolIdx, uint8_t slotIdx, uint8_t freqIdx)
85 {
86    uint16_t raRnti = 0;
87         uint8_t ulCarrierIdx = 0; /* configured to 0 */
88    raRnti = (1+symbolIdx+(14*slotIdx)+(14*80*freqIdx)+(14*80*8*ulCarrierIdx));
89         return raRnti;
90 }
91
92 /**
93  * @brief create raCb function. 
94  *
95  * @details
96  *
97  *     Function : createSchRaCb
98  *     
99  *     This function create raCb
100  *     
101  *  @param[in]  tcrnti
102  *  @param[in]  shed instance
103  *  @return  void
104  **/
105 void createSchRaCb(uint16_t tcrnti, Inst schInst)
106 {
107         schCb[schInst].cells[schInst]->raCb[0].tcrnti = tcrnti;
108 }
109
110 /**
111  * @brief resource allocation for msg3 PUSCH
112  *
113  * @details
114  *
115  *     Function : schAllocMsg3Pusch 
116  *     
117  *     This function handles msg3 PUSCH allocation
118  *     
119  *  @param[in]  Inst schInst, SCH instance
120  *  @param[in]  slot, current slot
121  *  @param[out]  msg3StartRb
122  *  @param[out]  msg3NumRb
123  *  @return  void
124  **/
125 uint8_t schAllocMsg3Pusch(Inst schInst, uint16_t slot, uint16_t *msg3StartRb,
126 uint8_t *msg3NumRb)
127 {
128         SchCellCb      *cell         = NULLP;
129         SchUlSlotInfo  *schUlSlotInfo    = NULLP;
130         uint8_t    puschMu       = 0;
131         uint8_t    msg3SlotAlloc = 0;
132         uint8_t    delta         = 0;
133         uint8_t    k2            = 0; 
134         uint8_t    startSymb     = 0;
135         uint8_t    symbLen       = 0; 
136         uint8_t    startRb       = 0;
137         uint8_t    numRb         = 0;
138         uint8_t    idx           = 0;
139
140
141    cell = schCb[schInst].cells[schInst];
142 //      puschMu = cell->cellCfg.puschMu;
143         delta = puschDeltaTable[puschMu];
144         k2 = cell->cellCfg.schInitialUlBwp.puschCommon.k2;
145         startSymb = cell->cellCfg.schInitialUlBwp.puschCommon.startSymbol;
146         symbLen = cell->cellCfg.schInitialUlBwp.puschCommon.lengthSymbol;
147
148         /* Slot allocation for msg3 based on 38.214 section 6.1.2.1 */
149         msg3SlotAlloc = slot + k2 + delta;
150         msg3SlotAlloc = msg3SlotAlloc % SCH_NUM_SLOTS; 
151
152         startRb = PUSCH_START_RB;
153
154         /* formula used for calculation of rbSize, 38.214 section 6.1.4.2 
155          * Ninfo = S.Nre.R.Qm.v
156          * Nre'  = Nsc.NsymPdsch-NdmrsSymb-Noh
157          * Nre   = min(156,Nre').nPrb */
158         numRb = 1; /* based on above calculation */
159
160         /* allocating 1 extra RB for now */
161         numRb++;
162
163         for(idx=startSymb; idx<symbLen; idx++)
164         {
165                 cell->schUlSlotInfo[msg3SlotAlloc]->assignedPrb[idx] = startRb + numRb;
166         }
167         schUlSlotInfo = cell->schUlSlotInfo[msg3SlotAlloc];
168
169    SCH_ALLOC(schUlSlotInfo->schPuschInfo, sizeof(SchPuschInfo));
170         if(!schUlSlotInfo->schPuschInfo)
171         {
172       DU_LOG("SCH: Memory allocation failed in schAllocMsg3Pusch");
173                 return RFAILED;
174         }
175         schUlSlotInfo->schPuschInfo->harqProcId        = SCH_HARQ_PROC_ID;
176         schUlSlotInfo->schPuschInfo->resAllocType      = SCH_ALLOC_TYPE_1;
177         schUlSlotInfo->schPuschInfo->fdAlloc.startPrb  = startRb;
178         schUlSlotInfo->schPuschInfo->fdAlloc.numPrb    = numRb;
179         schUlSlotInfo->schPuschInfo->tdAlloc.startSymb = startSymb;
180         schUlSlotInfo->schPuschInfo->tdAlloc.numSymb   = symbLen;
181         schUlSlotInfo->schPuschInfo->tbInfo.mcs      = 4;
182         schUlSlotInfo->schPuschInfo->tbInfo.ndi        = 1; /* new transmission */
183         schUlSlotInfo->schPuschInfo->tbInfo.rv          = 0;
184         schUlSlotInfo->schPuschInfo->tbInfo.tbSize     = 24; /*Considering 2 PRBs */
185
186         *msg3StartRb = startRb;
187         *msg3NumRb   = numRb;
188
189         return ROK;
190 }
191
192
193
194 /**
195  * @brief process rach indication function. 
196  *
197  * @details
198  *
199  *     Function : schProcessRachInd
200  *     
201  *     This function process rach indication
202  *     
203  *  @param[in]  rachInd parameters
204  *  @param[in]  shed instance
205  *  @return  ROK
206  **/
207 uint8_t schProcessRachInd(RachIndInfo *rachInd, Inst schInst)
208 {
209    SchCellCb *cell = schCb[schInst].cells[schInst];
210         RarInfo *rarInfo = NULLP;
211         uint16_t raRnti = 0;
212         uint16_t rarSlot = 0;
213         uint16_t msg3StartRb;
214         uint8_t  msg3NumRb;
215    uint8_t  ret = ROK;
216
217    /* RAR will sent with a delay of RAR_DELAY */
218    rarSlot = (rachInd->timingInfo.slot+RAR_DELAY+PHY_DELTA)%SCH_NUM_SLOTS;
219
220    SchDlSlotInfo *schDlSlotInfo = cell->schDlSlotInfo[rarSlot]; /* RAR will sent in the next slot */
221
222    /* Allocate the rarInfo, this pointer will be checked at schProcessSlotInd function */
223         SCH_ALLOC(rarInfo, sizeof(RarInfo));
224         if(rarInfo == NULLP)
225         {
226       DU_LOG("\nMAC: Memory Allocation failed for rarInfo");
227       return RFAILED;
228         }
229
230         schDlSlotInfo->rarInfo = rarInfo;
231    
232    /* calculate the ra-rnti value */
233         raRnti = calculateRaRnti(rachInd->symbolIdx,rachInd->slotIdx,rachInd->freqIdx);
234    
235         /* create raCb at SCH */
236         createSchRaCb(rachInd->crnti,schInst);
237
238         /* allocate resources for msg3 */
239         ret = schAllocMsg3Pusch(schInst, rarSlot, &msg3StartRb, &msg3NumRb);
240         if(ret == ROK)
241         {
242                 /* fill RAR info */
243                 rarInfo->raRnti                 = raRnti;
244                 rarInfo->tcrnti                 = rachInd->crnti;
245                 rarInfo->RAPID                  = rachInd->preambleIdx;
246                 rarInfo->ta                     = rachInd->timingAdv;
247                 rarInfo->msg3FreqAlloc.startPrb = msg3StartRb;
248                 rarInfo->msg3FreqAlloc.numPrb   = msg3NumRb;
249         }
250    return ret;
251 }
252
253 /**
254  * @brief fill RAR info function. 
255  *
256  * @details
257  *
258  *     Function : calculateRaRnti
259  *     
260  *     This function fills pdcch and pdsch info for RAR
261  *     
262  *  @param[in]  rar Allocation info
263  *  @param[in]  ra-rnti
264  *  @param[in]  PCI
265  *  @param[in]  offset to pointA to determine freq alloc
266  *  @return  ROK
267  **/
268 uint8_t schFillRar(RarAlloc *rarAlloc, uint16_t raRnti, uint16_t pci, uint8_t offsetPointA)
269 {
270    Inst inst = 0;
271    uint8_t coreset0Idx = 0;
272    uint8_t numRbs = 0;
273         uint8_t firstSymbol = 0;
274    uint8_t numSymbols = 0;
275    uint8_t offset = 0;
276    uint8_t FreqDomainResource[6] = {0};
277    uint16_t tbSize = 0;
278         uint8_t numPdschSymbols = 12; /* considering pdsch region from 2 to 13 */
279    uint8_t mcs = 4;  /* MCS fixed to 4 */
280
281    SchBwpDlCfg *initialBwp = &schCb[inst].cells[inst]->cellCfg.schInitialDlBwp;
282
283         PdcchCfg *pdcch = &rarAlloc->rarPdcchCfg;
284         PdschCfg *pdsch = &rarAlloc->rarPdschCfg;
285    BwpCfg *bwp = &rarAlloc->bwp;
286
287    coreset0Idx     = initialBwp->pdcchCommon.commonSearchSpace.coresetId;
288
289    /* derive the sib1 coreset0 params from table 13-1 spec 38.213 */
290    numRbs        = coresetIdxTable[coreset0Idx][1];
291    numSymbols    = coresetIdxTable[coreset0Idx][2];
292    offset        = coresetIdxTable[coreset0Idx][3];
293
294    /* calculate time domain parameters */
295         // note: since slot value is made sl1, RAR can be sent at all slots
296         uint16_t mask = 0x2000;
297         for(firstSymbol=0; firstSymbol<14;firstSymbol++)
298         {
299            if(initialBwp->pdcchCommon.commonSearchSpace.monitoringSymbol & mask)
300                    break;
301                 else
302                    mask = mask>>1;
303    }
304
305    /* calculate the PRBs */
306    schAllocFreqDomRscType0(((offsetPointA-offset)/6), (numRbs/6), FreqDomainResource);
307
308    /* fill BWP */
309    bwp->freqAlloc.numPrb   = initialBwp->bwp.freqAlloc.numPrb;
310    bwp->freqAlloc.startPrb = initialBwp->bwp.freqAlloc.startPrb;
311    bwp->subcarrierSpacing  = initialBwp->bwp.scs;
312    bwp->cyclicPrefix       = initialBwp->bwp.cyclicPrefix;
313
314    /* fill the PDCCH PDU */
315    pdcch->coreset0Cfg.startSymbolIndex = firstSymbol;
316    pdcch->coreset0Cfg.durationSymbols = numSymbols;
317    memcpy(pdcch->coreset0Cfg.freqDomainResource,FreqDomainResource,6);
318    pdcch->coreset0Cfg.cceRegMappingType = 1; /* coreset0 is always interleaved */
319    pdcch->coreset0Cfg.regBundleSize = 6;    /* spec-38.211 sec 7.3.2.2 */
320    pdcch->coreset0Cfg.interleaverSize = 2;  /* spec-38.211 sec 7.3.2.2 */
321    pdcch->coreset0Cfg.coreSetType = 0;
322    pdcch->coreset0Cfg.shiftIndex = pci;
323    pdcch->coreset0Cfg.precoderGranularity = 0; /* sameAsRegBundle */
324    pdcch->numDlDci = 1;
325    pdcch->dci.rnti = raRnti; /* RA-RNTI */
326    pdcch->dci.scramblingId = pci;
327    pdcch->dci.scramblingRnti = 0;
328    pdcch->dci.cceIndex = 4; /* considering SIB1 is sent at cce 0-1-2-3 */
329    pdcch->dci.aggregLevel = 4;
330    pdcch->dci.beamPdcchInfo.numPrgs = 1;
331    pdcch->dci.beamPdcchInfo.prgSize = 1;
332    pdcch->dci.beamPdcchInfo.digBfInterfaces = 0;
333    pdcch->dci.beamPdcchInfo.prg[0].pmIdx = 0;
334    pdcch->dci.beamPdcchInfo.prg[0].beamIdx[0] = 0;
335    pdcch->dci.txPdcchPower.powerValue = 0;
336    pdcch->dci.txPdcchPower.powerControlOffsetSS = 0;
337         pdcch->dci.pdschCfg = pdsch;
338
339    /* fill the PDSCH PDU */
340         uint8_t cwCount = 0;
341    pdsch->pduBitmap = 0; /* PTRS and CBG params are excluded */
342    pdsch->rnti = raRnti; /* RA-RNTI */
343    pdsch->pduIndex = 0;
344    pdsch->numCodewords = 1;
345         for(cwCount = 0; cwCount < pdsch->numCodewords; cwCount++)
346         {
347       pdsch->codeword[cwCount].targetCodeRate = 308;
348       pdsch->codeword[cwCount].qamModOrder = 2;
349       pdsch->codeword[cwCount].mcsIndex = mcs; /* mcs configured to 4 */
350       pdsch->codeword[cwCount].mcsTable = 0;   /* notqam256 */
351       pdsch->codeword[cwCount].rvIndex = 0;
352                 tbSize = schCalcTbSize(10); /* 8 bytes RAR and 2 bytes padding */
353       pdsch->codeword[cwCount].tbSize = tbSize;
354    }
355    pdsch->dataScramblingId = pci;
356    pdsch->numLayers = 1;
357    pdsch->transmissionScheme = 0;
358    pdsch->refPoint = 0;
359    pdsch->dmrs.dlDmrsSymbPos = 2;
360    pdsch->dmrs.dmrsConfigType = 0; /* type-1 */
361    pdsch->dmrs.dlDmrsScramblingId = pci;
362    pdsch->dmrs.scid = 0;
363    pdsch->dmrs.numDmrsCdmGrpsNoData = 1;
364    pdsch->dmrs.dmrsPorts = 0;
365    pdsch->pdschFreqAlloc.resourceAllocType = 1; /* RAT type-1 RIV format */
366    pdsch->pdschFreqAlloc.freqAlloc.startPrb = offset + SCH_SSB_NUM_PRB; /* the RB numbering starts from coreset0, and PDSCH is always above SSB */ 
367    pdsch->pdschFreqAlloc.freqAlloc.numPrb = schCalcNumPrb(tbSize,mcs,numPdschSymbols);
368    pdsch->pdschFreqAlloc.vrbPrbMapping = 0; /* non-interleaved */
369    pdsch->pdschTimeAlloc.timeAlloc.startSymb = initialBwp->pdschCommon.startSymbol;
370    pdsch->pdschTimeAlloc.timeAlloc.numSymb = initialBwp->pdschCommon.lengthSymbol;
371    pdsch->beamPdschInfo.numPrgs = 1;
372    pdsch->beamPdschInfo.prgSize = 1;
373    pdsch->beamPdschInfo.digBfInterfaces = 0;
374    pdsch->beamPdschInfo.prg[0].pmIdx = 0;
375    pdsch->beamPdschInfo.prg[0].beamIdx[0] = 0;
376    pdsch->txPdschPower.powerControlOffset = 0;
377    pdsch->txPdschPower.powerControlOffsetSS = 0;
378         
379         return ROK;
380 }
381
382 /**********************************************************************
383          End of file
384 **********************************************************************/