[Epic-ID: ODUHIGH-406][Task-ID: ODUHIGH-447] PCCH Scheduling at SCH
[o-du/l2.git] / src / 5gnrmac / mac_slot_ind.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 "rlc_mac_inf.h"
26 #include "mac.h"
27 #include "mac_upr_inf_api.h"
28 #include "lwr_mac.h"
29 #include "lwr_mac_fsm.h"
30 #include "mac_utils.h"
31
32 /* function pointers for packing slot ind from mac to sch */
33 MacSchSlotIndFunc macSchSlotIndOpts[] =
34 {
35    packMacSchSlotInd,
36    MacSchSlotInd,
37    packMacSchSlotInd
38 };
39
40 /**
41  * @brief process DL allocation from scheduler
42  *
43  * @details
44  *
45  *     Function : MacProcDlAlloc 
46  *      
47  *      This function copied dl sch info in the mac slot info
48  *           
49  *  @param[in]  Pst            *pst
50  *  @param[in]  DL allocation from scheduler
51  *  @return
52  *      -# ROK 
53  *      -# RFAILED 
54  **/
55 uint8_t MacProcDlAlloc(Pst *pst, DlSchedInfo *dlSchedInfo)
56 {
57    uint8_t   schInfoIdx = 0;
58    uint8_t   ueId = 0, ueIdx = 0;
59    uint16_t  cellIdx = 0;
60    MacDlSlot *currDlSlot = NULLP;
61
62 #ifdef CALL_FLOW_DEBUG_LOG
63    DU_LOG("\nCall Flow: ENTSCH -> ENTMAC : EVENT_DL_SCH_INFO\n");
64 #endif
65    if(dlSchedInfo != NULLP)
66    {
67       GET_CELL_IDX(dlSchedInfo->cellId, cellIdx);
68       if(dlSchedInfo->isBroadcastPres)
69       {
70          currDlSlot = &macCb.macCell[cellIdx]->\
71                       dlSlot[dlSchedInfo->schSlotValue.broadcastTime.slot];
72          currDlSlot->dlInfo.isBroadcastPres = true;
73          memcpy(&currDlSlot->dlInfo.brdcstAlloc, &dlSchedInfo->brdcstAlloc, sizeof(DlBrdcstAlloc));
74          currDlSlot->dlInfo.brdcstAlloc.sib1Alloc.sib1PdcchCfg.dci.pdschCfg = \
75                                             &currDlSlot->dlInfo.brdcstAlloc.sib1Alloc.sib1PdschCfg;
76       }
77
78       for(ueIdx=0; ueIdx<MAX_NUM_UE; ueIdx++)
79       {
80          if(dlSchedInfo->rarAlloc[ueIdx] != NULLP)
81          {
82             currDlSlot = &macCb.macCell[cellIdx]->dlSlot[dlSchedInfo->schSlotValue.rarTime.slot];
83             currDlSlot->dlInfo.rarAlloc[ueIdx] = dlSchedInfo->rarAlloc[ueIdx];
84
85             /* MUXing of RAR */
86             fillRarPdu(&currDlSlot->dlInfo.rarAlloc[ueIdx]->rarInfo);
87          }
88
89          if(dlSchedInfo->dlMsgAlloc[ueIdx] != NULLP)
90          {
91             currDlSlot = &macCb.macCell[cellIdx]->\
92                          dlSlot[dlSchedInfo->schSlotValue.dlMsgTime.slot];
93             currDlSlot->dlInfo.dlMsgAlloc[ueIdx] = dlSchedInfo->dlMsgAlloc[ueIdx]; /* copy msg4 alloc pointer in MAC slot info */
94             currDlSlot->dlInfo.cellId = dlSchedInfo->cellId;
95
96             /* Check if the downlink pdu is msg4 */
97             for(schInfoIdx=0; schInfoIdx < dlSchedInfo->dlMsgAlloc[ueIdx]->numSchedInfo; schInfoIdx++)
98             {
99                if(dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgInfo.isMsg4Pdu)
100                {
101                   GET_UE_ID(dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgInfo.crnti, ueId);
102                   ueIdx = ueId -1;
103                   macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TbSize = \
104                      dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgPdschCfg.codeword[0].tbSize;
105                }
106                else
107                {
108                   memcpy(&currDlSlot->dlInfo.schSlotValue, &dlSchedInfo->schSlotValue, sizeof(SchSlotValue));
109                   /* Send LC schedule result to RLC */
110                   if((dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].pduPres == PDSCH_PDU) ||
111                         (dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].pduPres == BOTH))
112                      sendSchedRptToRlc(currDlSlot->dlInfo, dlSchedInfo->schSlotValue.dlMsgTime, ueIdx, schInfoIdx);
113                }
114             }
115          }
116       }
117
118       if(dlSchedInfo->ulGrant != NULLP)
119       {
120          currDlSlot = &macCb.macCell[cellIdx]->\
121                       dlSlot[dlSchedInfo->schSlotValue.ulDciTime.slot];
122          currDlSlot->dlInfo.ulGrant = dlSchedInfo->ulGrant;
123       }
124    }
125    return ROK;
126 }
127
128 /**
129  * @brief process DL Paging allocation from scheduler
130  *
131  * @details
132  *
133  *     Function : MacProcDlPageAlloc 
134  *      
135  *      This function copied dl Pag info in the mac slot info
136  *           
137  *  @param[in]  Pst            *pst
138  *  @param[in]  DL Paging allocation from scheduler
139  *  @return
140  *      -# ROK 
141  *      -# RFAILED 
142  **/
143 uint8_t MacProcDlPageAlloc(Pst *pst, DlPageAlloc *dlPageAlloc)
144 {
145    uint16_t  cellIdx = 0;
146    MacDlSlot *currDlSlot = NULLP;
147
148 #ifdef CALL_FLOW_DEBUG_LOG
149    DU_LOG("\nCall Flow: ENTSCH -> ENTMAC : EVENT_DL_PAGING_ALLOC\n");
150 #endif
151    if(dlPageAlloc != NULLP)
152    {
153       GET_CELL_IDX(dlPageAlloc->cellId, cellIdx);
154
155       currDlSlot = &macCb.macCell[cellIdx]->dlSlot[dlPageAlloc->dlPageTime.slot];
156       MAC_ALLOC(currDlSlot->pageAllocInfo, sizeof(DlPageAlloc));
157       if(currDlSlot->pageAllocInfo == NULLP)
158       {
159          DU_LOG("\nERROR  --> MAC : MacProcDlPageAlloc : Memory Allocation is failed!");
160          return RFAILED;
161       }
162       memcpy(currDlSlot->pageAllocInfo, dlPageAlloc, sizeof(DlPageAlloc));
163       currDlSlot->pageAllocInfo->pagePdcchCfg.dci.pdschCfg = \
164                                                              &currDlSlot->pageAllocInfo->pagePdschCfg;
165    }
166    else
167    {
168       DU_LOG("\nERROR  --> MAC : DL Paging Allocation is failed!");
169       return RFAILED;
170    }
171    return ROK;
172 }
173
174 /**
175  * @brief Forming and filling the MUX Pdu
176  * @details
177  *
178  *     Function : fillMsg4Pdu
179  * 
180  *      Forming and filling of Msg4Pdu
181  *           
182  *  @param[in]  DlMsgAlloc  *msg4Alloc
183  *  @return  void
184  **/
185 void fillMsg4Pdu(uint16_t cellId, DlMsgSchInfo *msg4SchInfo)
186 {
187    uint8_t   ueId = 0, ueIdx = 0;
188    uint16_t  cellIdx;
189    uint16_t  msg4TxPduLen;
190    MacDlData msg4DlData;
191    MacCeInfo  macCeData;
192
193    GET_CELL_IDX(cellId, cellIdx);
194
195    memset(&msg4DlData, 0, sizeof(MacDlData));
196    memset(&macCeData, 0, sizeof(MacCeInfo));
197
198    GET_UE_ID(msg4SchInfo->dlMsgInfo.crnti, ueId);
199    ueIdx = ueId -1;
200
201    if(macCb.macCell[cellIdx] == NULLP)
202    {
203       DU_LOG("\nERROR -->  MAC: Cell Id[%d] not found", cellId);
204       return;
205    }
206
207    if(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4Pdu != NULLP)
208    {
209       MAC_ALLOC(msg4DlData.pduInfo[msg4DlData.numPdu].dlPdu, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen);
210       if(msg4DlData.pduInfo[msg4DlData.numPdu].dlPdu != NULLP)
211       {
212          msg4TxPduLen = macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TbSize - TX_PAYLOAD_HDR_LEN;
213
214          fillMsg4DlData(&msg4DlData, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen, \
215             macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4Pdu);
216          fillMacCe(&macCeData, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg3Pdu);
217          /* Forming Mux Pdu */
218          macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu = NULLP;
219          MAC_ALLOC(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu, msg4TxPduLen);
220          if(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu != NULLP)
221          {
222             memset(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu, 0, msg4TxPduLen);
223             macMuxPdu(&msg4DlData, &macCeData, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu, msg4TxPduLen);
224          }
225          else
226          {
227             DU_LOG("\nERROR  -->  MAC: Failed allocating memory for msg4TxPdu");
228          }
229          /* Free memory allocated */
230          MAC_FREE(msg4DlData.pduInfo[msg4DlData.numPdu-1].dlPdu, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen);
231          msg4DlData.numPdu--;
232       }
233    }
234
235    /* storing msg4 Pdu in macDlSlot */
236    if(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu)
237    {
238       msg4SchInfo->dlMsgInfo.dlMsgPduLen = msg4TxPduLen;
239       MAC_ALLOC(msg4SchInfo->dlMsgInfo.dlMsgPdu, msg4SchInfo->dlMsgInfo.dlMsgPduLen);
240       if(msg4SchInfo->dlMsgInfo.dlMsgPdu != NULLP)
241       {
242          memcpy(msg4SchInfo->dlMsgInfo.dlMsgPdu, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu, \
243                msg4SchInfo->dlMsgInfo.dlMsgPduLen);
244       }
245    }
246    else
247    {
248       DU_LOG("\nERROR  -->  MAC: Failed at fillMsg4Pdu()");
249    }
250 }
251
252 /**
253  * @brief Builds and Send the Muxed Pdu to Lower MAC
254  *
255  * @details
256  *
257  *     Function : buildAndSendMuxPdu
258  * 
259  *      Build and Sends the Muxed Pdu to Lower MAC.
260  *           
261  *  @param[in]  SlotTimingInfo    *slotInd
262  *  @return  void
263  **/
264
265 void buildAndSendMuxPdu(SlotTimingInfo currTimingInfo)
266 {
267    uint8_t   ueIdx;
268    uint8_t   schInfoIdx;
269    uint16_t  cellIdx;
270    MacDlSlot *currDlSlot = NULLP;
271    SlotTimingInfo muxTimingInfo;
272    memset(&muxTimingInfo, 0, sizeof(SlotTimingInfo));
273
274    GET_CELL_IDX(currTimingInfo.cellId, cellIdx);
275
276    ADD_DELTA_TO_TIME(currTimingInfo, muxTimingInfo, PHY_DELTA_DL);
277    currDlSlot = &macCb.macCell[cellIdx]->dlSlot[muxTimingInfo.slot];
278
279    for(ueIdx=0; ueIdx<MAX_NUM_UE; ueIdx++)
280    {
281       if(currDlSlot->dlInfo.dlMsgAlloc[ueIdx])
282       {
283          for(schInfoIdx=0; schInfoIdx<currDlSlot->dlInfo.dlMsgAlloc[ueIdx]->numSchedInfo; schInfoIdx++)
284          {
285             if((currDlSlot->dlInfo.dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].dlMsgInfo.isMsg4Pdu) &&
286                   ((currDlSlot->dlInfo.dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].pduPres == PDSCH_PDU) ||
287                    (currDlSlot->dlInfo.dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx].pduPres == BOTH)))
288             {
289                fillMsg4Pdu(currTimingInfo.cellId, &currDlSlot->dlInfo.dlMsgAlloc[ueIdx]->dlMsgSchedInfo[schInfoIdx]);
290             }
291          }
292       }
293    }
294 }
295
296 /**
297  * @brief Transmission time interval indication from PHY.
298  *
299  * @details
300  *
301  *     Function : sendSlotIndMacToSch
302  * 
303  *      This API is invoked by MAC to send slot ind to scheduler.
304  *           
305  *  @param[in]  SlotTimingInfo    *slotInd
306  *  @return  
307  *      -# ROK 
308  *      -# RFAILED 
309  **/
310 int sendSlotIndMacToSch(SlotTimingInfo *slotInd)
311 {
312    /* fill Pst structure to send to lwr_mac to MAC */
313    Pst pst;
314
315    FILL_PST_MAC_TO_SCH(pst, EVENT_SLOT_IND_TO_SCH);
316    return(*macSchSlotIndOpts[pst.selector])(&pst,slotInd);
317 }
318
319 /*******************************************************************
320  *
321  * @brief Send cell up indication to DU APP
322  *
323  * @details
324  *
325  *    Function : sendCellUpIndMacToDuApp
326  *
327  *    Functionality:
328  *       Send cell up indication to DU APP
329  *
330  * @params[in] Cell Up indication info 
331  * @return ROK     - success
332  *         RFAILED - failure
333  *
334  * ****************************************************************/
335 int sendCellUpIndMacToDuApp(uint16_t cellId)
336 {
337    Pst pst;
338    uint16_t ret;
339    OduCellId *oduCellId;
340
341    /*  Allocate sharable memory */
342    MAC_ALLOC_SHRABL_BUF(oduCellId, sizeof(OduCellId));
343    if(!oduCellId)
344    {
345       DU_LOG("\nERROR  -->  MAC : Memory allocation failed for cell up indication");
346       return RFAILED;
347    }
348    oduCellId->cellId = cellId;
349
350    /* Fill Pst */
351    FILL_PST_MAC_TO_DUAPP(pst, EVENT_MAC_CELL_UP_IND);
352
353    ret = MacDuAppCellUpInd(&pst, oduCellId);
354    if(ret != ROK)
355    {
356       DU_LOG("\nERROR  -->  MAC: Failed to send cell up indication to DU APP");
357       MAC_FREE_SHRABL_BUF(MAC_MEM_REGION, MAC_POOL, oduCellId, sizeof(OduCellId));
358    }
359
360    return ret;
361 } /* sendCellUpIndMacToDuApp */
362
363 /*******************************************************************
364  *
365  * @brief Send slot indication to DU APP
366  *
367  * @details
368  *
369  *    Function : sendSlotIndToDuApp
370  *
371  *    Functionality:
372  *       Send cell up indication to DU APP
373  *
374  * @params[in] Cell Up indication info 
375  * @return ROK     - success
376  *         RFAILED - failure
377  *
378  * ****************************************************************/
379 uint8_t sendSlotIndToDuApp(SlotTimingInfo *slotInd)
380 {
381    Pst pst;
382    uint16_t ret;
383    SlotTimingInfo *slotIndInfo;
384
385    /*  Allocate sharable memory */
386    MAC_ALLOC_SHRABL_BUF(slotIndInfo, sizeof(SlotTimingInfo));
387    if(!slotIndInfo)
388    {
389       DU_LOG("\nERROR  -->  MAC : Memory allocation failed for slot indication");
390       return RFAILED;
391    }
392    memcpy(slotIndInfo, slotInd,sizeof(SlotTimingInfo));
393
394    /* Fill Pst */
395    FILL_PST_MAC_TO_DUAPP(pst, EVENT_MAC_SLOT_IND);
396
397    ret = MacDuAppSlotInd(&pst, slotIndInfo);
398    if(ret != ROK)
399    {
400       DU_LOG("\nERROR  -->  MAC: Failed to send slot up indication to DU APP");
401       MAC_FREE_SHRABL_BUF(MAC_MEM_REGION, MAC_POOL, slotIndInfo, sizeof(SlotTimingInfo));
402    }
403
404    return ret;
405 }
406 /*******************************************************************
407  *
408  * @brief Process slot indication at MAC
409  *
410  * @details
411  *
412  *    Function : macProcSlotInd
413  *
414  *    Functionality: Process slot indication at MAC
415  *
416  * @params[in] Slot indication info
417  * @return ROK     - success
418  *         RFAILED - failure
419  *
420  * ****************************************************************/
421 uint8_t macProcSlotInd(SlotTimingInfo slotInd)
422 {
423    uint16_t  cellIdx = 0;
424
425    GET_CELL_IDX(slotInd.cellId, cellIdx);
426    
427    if(macCb.macCell[cellIdx] == NULLP)
428    {
429       DU_LOG("ERROR  --> MAC : macProcSlotInd(): CellId[%d] does not exist. Error occurred at SFN [%d] Slot [%d]",\
430       slotInd.cellId, slotInd.sfn, slotInd.slot);
431       return RFAILED;
432    }
433    /* Store current time info */
434    macCb.macCell[cellIdx]->currTime.cellId = slotInd.cellId;
435    macCb.macCell[cellIdx]->currTime.slot = slotInd.slot;
436    macCb.macCell[cellIdx]->currTime.sfn = slotInd.sfn;
437
438    /* Mux Pdu for Msg4 */
439    buildAndSendMuxPdu(slotInd);
440
441    /* Trigger for DL TTI REQ */
442    fillDlTtiReq(slotInd);
443
444    return ROK;
445 }  /* macProcSlotInd */
446
447 /**
448  * @brief Transmission time interval indication from PHY.
449  *
450  * @details
451  *
452  *     Function : fapiMacSlotInd 
453  *      
454  *      This API is invoked by PHY to indicate TTI indication to MAC for a cell.
455  *           
456  *  @param[in]  Pst            *pst
457  *  @param[in]  SuId           suId 
458  *  @param[in]  SlotTimingInfo    *slotInd
459  *  @return  
460  *      -# ROK 
461  *      -# RFAILED 
462  **/
463 uint8_t fapiMacSlotInd(Pst *pst, SlotTimingInfo *slotInd)
464 {
465    uint8_t               ret = ROK;
466    uint16_t              cellIdx;
467    volatile uint32_t     startTime=0;
468
469 #ifdef ODU_SLOT_IND_DEBUG_LOG
470    DU_LOG("\nDEBUG  -->  MAC : Slot Indication received. [%d : %d]", slotInd->sfn, slotInd->slot);
471 #endif
472    /*starting Task*/
473    ODU_START_TASK(&startTime, PID_MAC_TTI_IND);
474    gSlotCount++;
475
476    if(gSlotCount == 1)
477    {
478            GET_CELL_IDX(slotInd->cellId, cellIdx);
479            macCb.macCell[cellIdx]->state = CELL_STATE_UP;
480    }
481
482 /* When testing L2 with Intel-L1, any changes specific to 
483  * timer mode testing must be guarded under INTEL_TIMER_MODE*/
484 #ifndef INTEL_TIMER_MODE
485    /* send slot indication to scheduler */
486    ret = sendSlotIndMacToSch(slotInd);
487    if(ret != ROK)
488    {
489       DU_LOG("\nERROR  -->  MAC : Sending of slot ind msg from MAC to SCH failed");
490       MAC_FREE_SHRABL_BUF(pst->region, pst->pool, slotInd, sizeof(SlotTimingInfo));
491       return ret;
492    }
493
494    ret = macProcSlotInd(*slotInd);
495    if(ret != ROK)
496    {
497       DU_LOG("\nERROR  -->  MAC : macProcSlotInd failed");
498       MAC_FREE_SHRABL_BUF(pst->region, pst->pool, slotInd, sizeof(SlotTimingInfo));
499       return ret;
500    }
501 #endif
502
503    /*First Slot Ind is for CellUp. Any other Slot, will be notified to DUAPP as
504     * SLOT_IND*/
505    if(gSlotCount == 1)   
506    {
507       /* send cell up indication to du app */
508       ret = sendCellUpIndMacToDuApp(slotInd->cellId);
509
510    }
511    else
512    {
513       /* send slot indication to du app */
514       ret = sendSlotIndToDuApp(slotInd);
515    }
516    
517    if(ret != ROK)
518    {
519       DU_LOG("\nERROR  -->  MAC :Sending of slot ind msg from MAC to DU APP failed");
520       MAC_FREE_SHRABL_BUF(pst->region, pst->pool, slotInd, sizeof(SlotTimingInfo));
521       return ret;
522    }
523
524    /*stoping Task*/
525    ODU_STOP_TASK(startTime, PID_MAC_TTI_IND);
526    MAC_FREE_SHRABL_BUF(pst->region, pst->pool, slotInd, sizeof(SlotTimingInfo));
527
528 #ifdef INTEL_WLS_MEM
529    lwrMacCb.phySlotIndCntr++;
530    if(lwrMacCb.phySlotIndCntr > WLS_MEM_FREE_PRD)
531    {
532       lwrMacCb.phySlotIndCntr = 1;
533    }
534    freeWlsBlockList(lwrMacCb.phySlotIndCntr - 1);
535 #endif
536
537    return ret;
538 }  /* fapiMacSlotInd */
539
540 /**********************************************************************
541   End of file
542  **********************************************************************/
543