010063100fd63b351d3a728cd12a4e3000942384
[o-du/l2.git] / src / 5gnrmac / mac_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 /* header include files (.h) */
19 #include "common_def.h"
20 #include "lrg.h"
21 #include "lrg.x"
22 #include "du_app_mac_inf.h"
23 #include "mac_sch_interface.h"
24 #include "lwr_mac_upr_inf.h"
25 #include "mac.h"
26 #include "mac_utils.h"
27
28 /* Function pointer for sending rach ind from MAC to SCH */
29 MacSchRachIndFunc macSchRachIndOpts[]=
30 {
31    packMacSchRachInd,   /* packing for loosely coupled */
32    MacSchRachInd,       /* packing for tightly coupled */ 
33    packMacSchRachInd    /* packing for light weight loosely coupled */
34 };
35
36 /* Function pointer for sending RACH resource request from MAC to SCH */
37 MacSchRachRsrcReqFunc macSchRachRsrcReqOpts[] = 
38 {
39    packMacSchRachRsrcReq,   /* packing for loosely coupled */
40    MacSchRachRsrcReq,       /* packing for tightly coupled */
41    packMacSchRachRsrcReq    /* packing for light weight loosely coupled */
42 };
43
44 /* Function pointer for sending RACH resource response from MAC to DU APP */
45 MacDuRachRsrcRspFunc macDuRachRsrcRspOpts[] =
46 {
47    packDuMacRachRsrcRsp,   /* packing for loosely coupled */
48    DuProcMacRachRsrcRsp,   /* packing for tightly coupled */
49    packDuMacRachRsrcRsp    /* packing for light weight loosly coupled */
50 };
51
52 /* Function pointer for sending RACH resource release from MAC to SCH */
53 MacSchRachRsrcRelFunc macSchRachRsrcRelOpts[] =
54 {
55    packMacSchRachRsrcRel,   /* packing for loosely coupled */
56    MacSchRachRsrcRel,       /* packing for tightly coupled */
57    packMacSchRachRsrcRel    /* packing for light weight loosely coupled */
58 };
59
60 /*******************************************************************
61  *
62  * @brief Sends RACH indication to SCH
63  *
64  * @details
65  *
66  *    Function : sendRachIndMacToSch
67  *
68  *    Functionality:
69  *     Sends RACH indication to SCH
70  *
71  * @params[in] RACH indication info
72  * @return ROK     - success
73  *         RFAILED - failure
74  *
75  * ****************************************************************/
76 uint8_t sendRachIndMacToSch(RachIndInfo *rachInd)
77 {
78    Pst pst;
79
80    FILL_PST_MAC_TO_SCH(pst, EVENT_RACH_IND_TO_SCH);
81    return(*macSchRachIndOpts[pst.selector])(&pst, rachInd); 
82 }
83
84 /*******************************************************************
85  *
86  * @brief Adds an entry in list of RA Cb and fills RACH ind info
87  *
88  * @details
89  *
90  *    Function : createMacRaCb
91  *
92  *    Functionality:
93  *     Adds an entry in list of RA Cb and fills RACH ind info
94  *
95  * @params[in] Pointer to cellCB,
96  *             Pointer to RACH Indication information
97  * @return ROK - SUCCESS
98  *         RFAILED - FAILURE
99  *
100  * ****************************************************************/
101 uint8_t createMacRaCb(MacCellCb *cellCb, RachIndInfo *rachIndInfo)
102 {
103    int8_t ueIdx = -1;
104    uint8_t  ssbIdx = 0;
105    uint16_t crnti = 0;
106    MacUeCb  *ueCb = NULLP;
107
108    /* Search if a UE CB is already present to which the incoming preamble index was dedicated */
109    for(ueIdx = 0; ueIdx < MAX_NUM_UE; ueIdx++) 
110    {
111       /* Check if ueCb has a crnti alloted to it. If not, it means this ueIdx
112        * has no UE context stored in it, hence searching for preamble index in
113        * this ueCb is not required */
114       if(cellCb->ueCb[ueIdx].crnti)
115       {
116          for(ssbIdx = 0; ssbIdx < cellCb->ueCb[ueIdx].cfraResource.numSsb; ssbIdx++)
117          {
118             if(cellCb->ueCb[ueIdx].cfraResource.ssbResource[ssbIdx].raPreambleIdx == rachIndInfo->preambleIdx)
119             {
120                ueCb = &cellCb->ueCb[ueIdx];
121                break;
122             }
123          }
124          if(ueCb)
125             break;
126       }
127    }
128
129    if(ueCb)
130    {
131       /* If UE context is already present as in case of handover, fetch CRNTI from
132        * UE CB allocated during UE context creation */
133       crnti = ueCb->crnti;
134    }
135    else
136    {
137       /* If UE context not present, assign CRNTI to this UE */
138       ueIdx = getFreeBitFromUeBitMap(rachIndInfo->cellId);
139       if(ueIdx == -1)
140       {
141          DU_LOG("\nERROR  -->  MAC : Failed to find free UE Idx in UE bit map of cell Id [%d]", rachIndInfo->cellId);
142          return RFAILED;
143       }
144
145       /* Calculate CRNTI from UE Index */
146       GET_CRNTI(crnti, ueIdx+1);
147
148       /* Store in raCb */
149       cellCb->macRaCb[ueIdx].cellId = rachIndInfo->cellId;
150       cellCb->macRaCb[ueIdx].crnti  = crnti;
151    }
152
153    /* Store in Rach Indication message to be sent to SCH */
154    rachIndInfo->crnti  = crnti;
155    return ROK;
156 }
157
158 /*******************************************************************
159  *
160  * @brief Processes RACH indication from PHY
161  *
162  * @details
163  *
164  *    Function : fapiMacRachInd
165  *
166  *    Functionality:
167  *      Processes RACH indication from PHY
168  *
169  * @params[in] Post structure
170  *             Rach indication message
171  * @return ROK     - success
172  *         RFAILED - failure
173  *
174  * ****************************************************************/ 
175 uint8_t fapiMacRachInd(Pst *pst, RachInd *rachInd)
176 {
177    uint8_t      ret = ROK;
178    uint8_t      pduIdx = 0;
179    uint8_t      preambleIdx = 0;
180    uint16_t     cellIdx = 0;  
181    RachIndInfo  *rachIndInfo = NULLP;
182    MacCellCb    *cellCb = NULLP;
183
184    DU_LOG("\nINFO  -->  MAC : Received RACH indication");
185    /* Considering one pdu and one preamble */
186    pduIdx = 0;
187    preambleIdx = 0;
188
189    /* Validate cell Id */
190    GET_CELL_IDX(rachInd->cellId, cellIdx);
191    if(macCb.macCell[cellIdx] && (macCb.macCell[cellIdx]->cellId == rachInd->cellId))
192          cellCb = macCb.macCell[cellIdx];
193
194    if(!cellCb)
195    {
196       DU_LOG("\nERROR  --> MAC : Invalid Cell ID [%d] received in RACH Indication", rachInd->cellId);
197       return RFAILED;
198    }
199
200    MAC_ALLOC(rachIndInfo, sizeof(RachIndInfo));
201    if(!rachIndInfo)
202    {
203       DU_LOG("\nERROR  --> MAC : Memory allocation failure in fapiMacRachInd");
204       MAC_FREE_SHRABL_BUF(pst->region, pst->pool, rachInd, sizeof(RachInd));
205       return RFAILED;
206    }
207
208    rachIndInfo->cellId = rachInd->cellId;
209    rachIndInfo->timingInfo.sfn = rachInd->timingInfo.sfn;
210    rachIndInfo->timingInfo.slot = rachInd->timingInfo.slot;
211    rachIndInfo->slotIdx = rachInd->rachPdu[pduIdx].slotIdx;
212    rachIndInfo->symbolIdx = rachInd->rachPdu[pduIdx].symbolIdx;
213    rachIndInfo->freqIdx = rachInd->rachPdu[pduIdx].freqIdx;
214    rachIndInfo->preambleIdx = rachInd->rachPdu[pduIdx].preamInfo[preambleIdx].preamIdx;
215    rachIndInfo->timingAdv = rachInd->rachPdu[pduIdx].preamInfo[preambleIdx].timingAdv;
216
217    /* Store the value in macRaCb */
218    if((ret = createMacRaCb(cellCb, rachIndInfo)) == ROK)
219    {
220       /* Send RACH Indication to SCH */
221       ret = sendRachIndMacToSch(rachIndInfo);
222    }
223
224    /* Free sharable buffer used to send RACH Indication from lower MAC to MAC */
225    MAC_FREE_SHRABL_BUF(pst->region, pst->pool, rachInd, sizeof(RachInd));
226
227    return ret;
228 }
229
230 /*******************************************************************
231  *
232  * @brief Processes RACH Resource request from DU APP
233  *
234  * @details
235  *
236  *    Function : MacProcRachRsrcReq
237  *
238  *    Functionality: Processes RACH resource request from DU APP.
239  *      Fills and sends RACH resource request towards SCH.
240  *
241  * @params[in] Post structure
242  *             RACH resource request
243  * @return ROK     - success
244  *         RFAILED - failure
245  *
246  * ****************************************************************/
247 uint8_t MacProcRachRsrcReq(Pst *pst, MacRachRsrcReq *rachRsrcReq)
248 {
249    uint8_t   ret = RFAILED;
250    uint16_t  cellIdx = 0;
251    Pst       schPst;
252    MacCellCb *cellCb = NULLP;
253    MacUeCb   *ueCb = NULLP;
254    SchRachRsrcReq *schRachRsrcReq = NULLP;
255
256    DU_LOG("\nINFO  -->  MAC : Recieved RACH Resource Request for Cell ID [%d] UE ID [%d]",\
257          rachRsrcReq->cellId, rachRsrcReq->ueId);
258
259    /* Fetch Cell Cb */
260    GET_CELL_IDX(rachRsrcReq->cellId, cellIdx);
261    if(macCb.macCell[cellIdx] && (macCb.macCell[cellIdx]->cellId == rachRsrcReq->cellId))
262    {
263       cellCb = macCb.macCell[cellIdx];
264
265       /* Fetch UE Cb */
266       if(cellCb->ueCb[rachRsrcReq->ueId-1].ueId == rachRsrcReq->ueId)
267       {
268          ueCb = &cellCb->ueCb[rachRsrcReq->ueId-1];
269          /* Allocate memory to RACH resource request to be sent to SCH */
270          MAC_ALLOC(schRachRsrcReq, sizeof(SchRachRsrcReq));
271          if(schRachRsrcReq)
272          {
273             /* Fill SCH RACH resource request from information received from DU APP to MAC */
274             schRachRsrcReq->cellId = rachRsrcReq->cellId;
275             schRachRsrcReq->crnti = ueCb->crnti;
276             schRachRsrcReq->numSsb = rachRsrcReq->numSsb;
277             memcpy(schRachRsrcReq->ssbIdx, rachRsrcReq->ssbIdx, sizeof(schRachRsrcReq->ssbIdx));
278
279             /* Send RACH resource request from MAC to SCH */
280             FILL_PST_MAC_TO_SCH(schPst, EVENT_RACH_RESOURCE_REQUEST_TO_SCH);
281             ret = (*macSchRachRsrcReqOpts[schPst.selector])(&schPst, schRachRsrcReq);
282          }
283          else
284             DU_LOG("\nERROR  -->  MAC : Memory allocation failed for RACH resource request to SCH");
285       }
286       else
287          DU_LOG("\nERROR  -->  MAC : UE ID [%d] not found", rachRsrcReq->ueId);
288    }
289    else
290       DU_LOG("\nERROR  -->  MAC : Cell ID [%d] not found", rachRsrcReq->cellId);
291
292    /* Free sharable buffer used to send RACH reource request from DU APP to MAC */
293    MAC_FREE_SHRABL_BUF(pst->region, pst->pool, rachRsrcReq, sizeof(MacRachRsrcReq));
294    return ret;
295 }
296
297 /*******************************************************************
298  *
299  * @brief Processes RACH Resource response from SCH
300  *
301  * @details
302  *
303  *    Function : MacProcSchRachRsrcRsp
304  *
305  *    Functionality: Processes RACH resource response from SCH
306  *      Fills and sends RACH resource response towards DU APP
307  *
308  * @params[in] Post structure
309  *             RACH resource response
310  * @return ROK     - success
311  *         RFAILED - failure
312  *
313  * ****************************************************************/
314 uint8_t MacProcSchRachRsrcRsp(Pst *pst, SchRachRsrcRsp *schRachRsrcRsp)
315 {
316    uint16_t cellIdx = 0;
317    Pst rspPst;
318    MacRachRsrcRsp *rachRsrcRsp = NULLP;
319    MacCellCb *cellCb = NULLP;
320    MacUeCb   *ueCb = NULLP;
321
322    DU_LOG("\nINFO  -->  MAC : Received RACH resource response from SCH : Cell ID [%d] CRNTI [%d]", \
323          schRachRsrcRsp->cellId, schRachRsrcRsp->crnti);
324
325    /* Fill RACH resource response to send to DU APP */
326    MAC_ALLOC_SHRABL_BUF(rachRsrcRsp, sizeof(MacRachRsrcRsp));
327    if(!rachRsrcRsp)
328    {
329       DU_LOG("\nERROR  -->  MAC : Memory allocation failed for RACH resource response");
330       MAC_FREE(schRachRsrcRsp, sizeof(SchRachRsrcRsp));
331       return RFAILED;
332    }
333    rachRsrcRsp->cellId = schRachRsrcRsp->cellId;
334    GET_UE_ID(schRachRsrcRsp->crnti, rachRsrcRsp->ueId);
335    rachRsrcRsp->result = MAC_DU_APP_RSP_OK;
336
337    /* Fill Pst structure to send RACH resource response from MAC to DU APP */
338    FILL_PST_MAC_TO_DUAPP(rspPst, EVENT_MAC_RACH_RESOURCE_RSP);
339
340    /* If negative response is received from SCH, send it further to DU APP */ 
341    if(schRachRsrcRsp->result == RSP_NOK)
342    {
343       DU_LOG("\nINFO  -->  MAC : RACH Resource response from SCH : Result [FAILURE]");
344       rachRsrcRsp->result = MAC_DU_APP_RSP_NOK;
345    }
346    else
347    {
348       DU_LOG("\nINFO  -->  MAC : RACH Resource response from SCH : Result [SUCCESS]");
349       
350       /* Fetch Cell Cb */
351       GET_CELL_IDX(schRachRsrcRsp->cellId, cellIdx);
352       if(macCb.macCell[cellIdx] && (macCb.macCell[cellIdx]->cellId == schRachRsrcRsp->cellId))
353       {   
354          cellCb = macCb.macCell[cellIdx];
355
356          /* Fetch UE Cb */
357          if(cellCb->ueCb[rachRsrcRsp->ueId-1].crnti == schRachRsrcRsp->crnti)
358             ueCb = &cellCb->ueCb[rachRsrcRsp->ueId-1];
359          else
360          {
361             DU_LOG("\nERROR  -->  MAC : CRNTI [%d] not found", schRachRsrcRsp->crnti);
362             rachRsrcRsp->result = MAC_DU_APP_RSP_NOK;
363          }   
364       }   
365       else
366       {   
367          DU_LOG("\nERROR  -->  MAC : Cell ID [%d] not found", schRachRsrcRsp->cellId);
368          rachRsrcRsp->result = MAC_DU_APP_RSP_NOK;
369       }   
370    }
371
372    /* Fill SSB RACH resource info if SCH has sent a positive response and 
373     * processing of SCH RACH resource response at MAC has been successful so far */
374    if(rachRsrcRsp->result == MAC_DU_APP_RSP_OK)
375    {
376       rachRsrcRsp->newCrnti = ueCb->crnti; 
377       rachRsrcRsp->cfraResource.numSsb = schRachRsrcRsp->cfraResource.numSsb;
378       memcpy(rachRsrcRsp->cfraResource.ssbResource, schRachRsrcRsp->cfraResource.ssbResource, \
379          rachRsrcRsp->cfraResource.numSsb * sizeof(MacCfraSsbResource));
380
381       /* Copy resources to UE CB in MAC */
382       memcpy(&ueCb->cfraResource, &rachRsrcRsp->cfraResource, sizeof(MacCfraResource));
383    }
384
385    /* Free SCH RACH resource response */
386    MAC_FREE(schRachRsrcRsp, sizeof(SchRachRsrcRsp));
387
388    /* Send RACH resource response to DU APP */
389    FILL_PST_MAC_TO_DUAPP(rspPst, EVENT_MAC_RACH_RESOURCE_RSP);
390    return (*macDuRachRsrcRspOpts[rspPst.selector])(&rspPst, rachRsrcRsp);
391 }
392
393
394 /*******************************************************************
395  *
396  * @brief Processes RACH Resource release from DU APP
397  *
398  * @details
399  *
400  *    Function : MacProcRachRsrcRel
401  *
402  *    Functionality: Processes RACH resource release from DU APP.
403  *      Fills and sends RACH resource release towards SCH.
404  *
405  * @params[in] Post structure
406  *             RACH resource release
407  * @return ROK     - success
408  *         RFAILED - failure
409  *
410  * ****************************************************************/
411 uint8_t MacProcRachRsrcRel(Pst *pst, MacRachRsrcRel *rachRsrcRel)
412 {
413    uint8_t   ret = RFAILED;
414    uint16_t  cellIdx = 0;
415    Pst       schPst;
416    MacCellCb *cellCb = NULLP;
417    MacUeCb   *ueCb = NULLP;
418    SchRachRsrcRel *schRachRsrcRel = NULLP;
419
420    DU_LOG("\nINFO  -->  MAC : Recieved RACH Resource Release for Cell ID [%d] UE ID [%d]",\
421          rachRsrcRel->cellId, rachRsrcRel->ueId);
422
423    /* Fetch Cell Cb */
424    GET_CELL_IDX(rachRsrcRel->cellId, cellIdx);
425    if(macCb.macCell[cellIdx] && (macCb.macCell[cellIdx]->cellId == rachRsrcRel->cellId))
426    {
427       cellCb = macCb.macCell[cellIdx];
428
429       /* Fetch UE Cb */
430       if(cellCb->ueCb[rachRsrcRel->ueId-1].ueId == rachRsrcRel->ueId)
431       {
432          ueCb = &cellCb->ueCb[rachRsrcRel->ueId-1];
433          /* Allocate memory to RACH resource release to be sent to SCH */
434          MAC_ALLOC(schRachRsrcRel, sizeof(SchRachRsrcRel));
435          if(schRachRsrcRel)
436          {
437             /* Fill SCH RACH resource release from information received from DU APP to MAC */
438             memset(schRachRsrcRel, 0, sizeof(SchRachRsrcRel));
439             schRachRsrcRel->cellId = rachRsrcRel->cellId;
440             schRachRsrcRel->crnti = ueCb->crnti;
441             memcpy(&schRachRsrcRel->cfraResource, &ueCb->cfraResource, sizeof(schRachRsrcRel->cfraResource));
442             
443             /* Release RACH resources at MAC */
444             memset(&ueCb->cfraResource, 0, sizeof(MacCfraResource));
445
446             /* Send RACH resource release from MAC to SCH */
447             FILL_PST_MAC_TO_SCH(schPst, EVENT_RACH_RESOURCE_RELEASE_TO_SCH);
448             ret = (*macSchRachRsrcRelOpts[schPst.selector])(&schPst, schRachRsrcRel);
449          }
450          else
451             DU_LOG("\nERROR  -->  MAC : Memory allocation failed for RACH resource release to SCH");
452       }
453       else
454          DU_LOG("\nERROR  -->  MAC : UE ID [%d] not found", rachRsrcRel->ueId);
455    }
456    else
457       DU_LOG("\nERROR  -->  MAC : Cell ID [%d] not found", rachRsrcRel->cellId);
458
459    /* Free sharable buffer used to send RACH reource release from DU APP to MAC */
460    MAC_FREE_SHRABL_BUF(pst->region, pst->pool, rachRsrcRel, sizeof(MacRachRsrcRel));
461    return ret;
462 }
463
464 /* spec-38.211 Table 6.3.3.1-7 */
465 uint8_t UnrestrictedSetNcsTable[MAX_ZERO_CORR_CFG_IDX] = 
466 {0, 2, 4, 6, 8, 10, 12, 13, 15, 17, 19, 23, 27, 34, 46, 69};
467
468 /*******************************************************************
469  *
470  * @brief Processes UL scheduling info from SCH
471  *
472  * @details
473  *
474  *    Function : MacProcUlSchInfo
475  *
476  *    Functionality: Processes UL scheduling info from SCH
477  *
478  * @params[in] Post structure
479  *             UL scheduling info
480  * @return ROK     - success
481  *         RFAILED - failure
482  *
483  * ****************************************************************/
484 uint8_t MacProcUlSchInfo(Pst *pst, UlSchedInfo *ulSchedInfo)
485 {
486    uint16_t  cellIdx;
487
488 #ifdef CALL_FLOW_DEBUG_LOG
489    DU_LOG("\nCall Flow: ENTSCH -> ENTMAC : EVENT_UL_SCH_INFO\n");
490 #endif
491
492    GET_CELL_IDX(ulSchedInfo->cellId, cellIdx);
493    if(ulSchedInfo != NULLP)
494    {
495       MacUlSlot *currUlSlot = 
496          &macCb.macCell[cellIdx]->ulSlot[ulSchedInfo->slotIndInfo.slot % MAX_SLOTS];
497       memcpy(&currUlSlot->ulInfo, ulSchedInfo, sizeof(UlSchedInfo)); 
498    }
499    return ROK;
500 }
501
502 /**********************************************************************
503   End of file
504  **********************************************************************/
505