Multi-UE support upto MSG4 handling [Issue-ID: ODUHIGH-387]
[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   ueIdx;
58    uint16_t  cellIdx;
59    MacDlSlot *currDlSlot = NULLP;
60
61 #ifdef CALL_FLOW_DEBUG_LOG
62    DU_LOG("\nCall Flow: ENTSCH -> ENTMAC : EVENT_DL_SCH_INFO\n");
63 #endif
64    if(dlSchedInfo != NULLP)
65    {
66       GET_CELL_IDX(dlSchedInfo->cellId, cellIdx);
67       if(dlSchedInfo->isBroadcastPres)
68       {
69          currDlSlot = &macCb.macCell[cellIdx]->\
70                       dlSlot[dlSchedInfo->schSlotValue.broadcastTime.slot];
71          currDlSlot->dlInfo.isBroadcastPres = true;
72          memcpy(&currDlSlot->dlInfo.brdcstAlloc, &dlSchedInfo->brdcstAlloc, sizeof(DlBrdcstAlloc));
73          currDlSlot->dlInfo.brdcstAlloc.sib1Alloc.sib1PdcchCfg.dci.pdschCfg = \
74                                             &currDlSlot->dlInfo.brdcstAlloc.sib1Alloc.sib1PdschCfg;
75       }
76
77       for(ueIdx=0; ueIdx<MAX_NUM_UE; ueIdx++)
78       {
79          if(dlSchedInfo->rarAlloc[ueIdx] != NULLP)
80          {
81             currDlSlot = &macCb.macCell[cellIdx]->dlSlot[dlSchedInfo->schSlotValue.rarTime.slot];
82             currDlSlot->dlInfo.rarAlloc[ueIdx] = dlSchedInfo->rarAlloc[ueIdx];
83
84             /* MUXing of RAR */
85             fillRarPdu(&currDlSlot->dlInfo.rarAlloc[ueIdx]->rarInfo);
86          }
87
88          if(dlSchedInfo->dlMsgAlloc[ueIdx] != NULLP)
89          {
90             currDlSlot = &macCb.macCell[cellIdx]->\
91                          dlSlot[dlSchedInfo->schSlotValue.dlMsgTime.slot];
92             currDlSlot->dlInfo.dlMsgAlloc[ueIdx] = dlSchedInfo->dlMsgAlloc[ueIdx]; /* copy msg4 alloc pointer in MAC slot info */
93             currDlSlot->dlInfo.cellId = dlSchedInfo->cellId;
94
95             /* Check if the downlink pdu is msg4 */
96             if(dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgInfo.isMsg4Pdu)
97             {
98                GET_UE_IDX(dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgInfo.crnti, ueIdx);
99                ueIdx = ueIdx -1;
100                macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TbSize = \
101                   dlSchedInfo->dlMsgAlloc[ueIdx]->dlMsgPdschCfg.codeword[0].tbSize;
102             }
103             else
104             {
105                memcpy(&currDlSlot->dlInfo.schSlotValue, &dlSchedInfo->schSlotValue, sizeof(SchSlotValue));
106                /* Send LC schedule result to RLC */
107                sendSchedRptToRlc(currDlSlot->dlInfo, dlSchedInfo->schSlotValue.dlMsgTime);
108             }
109          }
110       }
111
112       if(dlSchedInfo->ulGrant != NULLP)
113       {
114          currDlSlot = &macCb.macCell[cellIdx]->\
115                       dlSlot[dlSchedInfo->schSlotValue.ulDciTime.slot];
116          currDlSlot->dlInfo.ulGrant = dlSchedInfo->ulGrant;
117       }
118    }
119    return ROK;
120 }
121
122 /**
123  * @brief Forming anf filling the MUX Pdu
124  * @details
125  *
126  *     Function : fillMsg4Pdu
127  * 
128  *      Forming and filling of Msg4Pdu
129  *           
130  *  @param[in]  DlMsgAlloc  *msg4Alloc
131  *  @return  void
132  **/
133 void fillMsg4Pdu(uint16_t cellId, DlMsgAlloc *msg4Alloc)
134 {
135    uint8_t   ueIdx;
136    uint16_t  cellIdx;
137    uint16_t  msg4TxPduLen;
138    MacDlData msg4DlData;
139    MacCeInfo  macCeData;
140
141    GET_CELL_IDX(cellId, cellIdx);
142
143    memset(&msg4DlData, 0, sizeof(MacDlData));
144    memset(&macCeData, 0, sizeof(MacCeInfo));
145
146    GET_UE_IDX(msg4Alloc->dlMsgInfo.crnti, ueIdx);
147    ueIdx = ueIdx -1;
148
149    if(macCb.macCell[cellIdx] == NULLP)
150    {
151       DU_LOG("\nERROR -->  MAC: Cell Id[%d] not found", cellId);
152       return;
153    }
154
155    if(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4Pdu != NULLP)
156    {
157       MAC_ALLOC(msg4DlData.pduInfo[msg4DlData.numPdu].dlPdu, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen);
158       if(msg4DlData.pduInfo[msg4DlData.numPdu].dlPdu != NULLP)
159       {
160          msg4TxPduLen = macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TbSize - TX_PAYLOAD_HDR_LEN;
161
162          fillMsg4DlData(&msg4DlData, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen, \
163             macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4Pdu);
164          fillMacCe(&macCeData, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg3Pdu);
165          /* Forming Mux Pdu */
166          macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu = NULLP;
167          MAC_ALLOC(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu, msg4TxPduLen);
168          if(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu != NULLP)
169          {
170             memset(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu, 0, msg4TxPduLen);
171             macMuxPdu(&msg4DlData, &macCeData, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu, msg4TxPduLen);
172          }
173          else
174          {
175             DU_LOG("\nERROR  -->  MAC: Failed allocating memory for msg4TxPdu");
176          }
177          /* Free memory allocated */
178          MAC_FREE(msg4DlData.pduInfo[msg4DlData.numPdu-1].dlPdu, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4PduLen);
179          msg4DlData.numPdu--;
180       }
181    }
182
183    /* storing msg4 Pdu in macDlSlot */
184    if(macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu)
185    {
186       msg4Alloc->dlMsgInfo.dlMsgPduLen = msg4TxPduLen;
187       MAC_ALLOC(msg4Alloc->dlMsgInfo.dlMsgPdu, msg4Alloc->dlMsgInfo.dlMsgPduLen);
188       if(msg4Alloc->dlMsgInfo.dlMsgPdu != NULLP)
189       {
190          memcpy(msg4Alloc->dlMsgInfo.dlMsgPdu, macCb.macCell[cellIdx]->macRaCb[ueIdx].msg4TxPdu, \
191                msg4Alloc->dlMsgInfo.dlMsgPduLen);
192       }
193    }
194    else
195    {
196       DU_LOG("\nERROR  -->  MAC: Failed at macMuxPdu()");
197    }
198 }
199
200 /**
201  * @brief Builds and Send the Muxed Pdu to Lower MAC
202  *
203  * @details
204  *
205  *     Function : buildAndSendMuxPdu
206  * 
207  *      Build and Sends the Muxed Pdu to Lower MAC.
208  *           
209  *  @param[in]  SlotTimingInfo    *slotInd
210  *  @return  void
211  **/
212
213 void buildAndSendMuxPdu(SlotTimingInfo currTimingInfo)
214 {
215    uint8_t   ueIdx;
216    uint16_t  cellIdx;
217    MacDlSlot *currDlSlot = NULLP;
218    SlotTimingInfo muxTimingInfo;
219    memset(&muxTimingInfo, 0, sizeof(SlotTimingInfo));
220
221    GET_CELL_IDX(currTimingInfo.cellId, cellIdx);
222
223    ADD_DELTA_TO_TIME(currTimingInfo, muxTimingInfo, PHY_DELTA_DL);
224    currDlSlot = &macCb.macCell[cellIdx]->dlSlot[muxTimingInfo.slot];
225
226    for(ueIdx=0; ueIdx<MAX_NUM_UE; ueIdx++)
227    {
228       if(currDlSlot->dlInfo.dlMsgAlloc[ueIdx])
229       {
230          if(currDlSlot->dlInfo.dlMsgAlloc[ueIdx]->dlMsgInfo.isMsg4Pdu)
231          {
232             fillMsg4Pdu(currTimingInfo.cellId, currDlSlot->dlInfo.dlMsgAlloc[ueIdx]);
233          }
234       }
235    }
236 }
237
238 /**
239  * @brief Transmission time interval indication from PHY.
240  *
241  * @details
242  *
243  *     Function : sendSlotIndMacToSch
244  * 
245  *      This API is invoked by MAC to send slot ind to scheduler.
246  *           
247  *  @param[in]  SlotTimingInfo    *slotInd
248  *  @return  
249  *      -# ROK 
250  *      -# RFAILED 
251  **/
252 int sendSlotIndMacToSch(SlotTimingInfo *slotInd)
253 {
254    /* fill Pst structure to send to lwr_mac to MAC */
255    Pst pst;
256
257    FILL_PST_MAC_TO_SCH(pst, EVENT_SLOT_IND_TO_SCH);
258    return(*macSchSlotIndOpts[pst.selector])(&pst,slotInd);
259 }
260
261 /*******************************************************************
262  *
263  * @brief Send cell up indication to DU APP
264  *
265  * @details
266  *
267  *    Function : sendCellUpIndMacToDuApp
268  *
269  *    Functionality:
270  *       Send cell up indication to DU APP
271  *
272  * @params[in] Cell Up indication info 
273  * @return ROK     - success
274  *         RFAILED - failure
275  *
276  * ****************************************************************/
277 int sendCellUpIndMacToDuApp(uint16_t cellId)
278 {
279    Pst pst;
280    uint16_t ret;
281    OduCellId *oduCellId;
282
283    /*  Allocate sharable memory */
284    MAC_ALLOC_SHRABL_BUF(oduCellId, sizeof(OduCellId));
285    if(!oduCellId)
286    {
287       DU_LOG("\nERROR  -->  MAC : Memory allocation failed for cell up indication");
288       return RFAILED;
289    }
290    oduCellId->cellId = cellId;
291
292    /* Fill Pst */
293    FILL_PST_MAC_TO_DUAPP(pst, EVENT_MAC_CELL_UP_IND);
294
295    ret = MacDuAppCellUpInd(&pst, oduCellId);
296    if(ret != ROK)
297    {
298       DU_LOG("\nERROR  -->  MAC: Failed to send cell up indication to DU APP");
299       MAC_FREE_SHRABL_BUF(MAC_MEM_REGION, MAC_POOL, oduCellId, sizeof(OduCellId));
300    }
301
302    return ret;
303 } /* sendCellUpIndMacToDuApp */
304
305 /*******************************************************************
306  *
307  * @brief Process slot indication at MAC
308  *
309  * @details
310  *
311  *    Function : macProcSlotInd
312  *
313  *    Functionality: Process slot indication at MAC
314  *
315  * @params[in] Slot indication info
316  * @return ROK     - success
317  *         RFAILED - failure
318  *
319  * ****************************************************************/
320 uint8_t macProcSlotInd(SlotTimingInfo slotInd)
321 {
322    uint16_t  cellIdx = 0;
323
324    GET_CELL_IDX(slotInd.cellId, cellIdx);
325    
326    if(macCb.macCell[cellIdx] == NULLP)
327    {
328       DU_LOG("ERROR  --> MAC : macProcSlotInd(): CellId[%d] does not exist. Error occurred at SFN [%d] Slot [%d]",\
329       slotInd.cellId, slotInd.sfn, slotInd.slot);
330       return RFAILED;
331    }
332    /* Store current time info */
333    macCb.macCell[cellIdx]->currTime.cellId = slotInd.cellId;
334    macCb.macCell[cellIdx]->currTime.slot = slotInd.slot;
335    macCb.macCell[cellIdx]->currTime.sfn = slotInd.sfn;
336
337    /* Mux Pdu for Msg4 */
338    buildAndSendMuxPdu(slotInd);
339
340    /* Trigger for DL TTI REQ */
341    fillDlTtiReq(slotInd);
342
343    return ROK;
344 }  /* macProcSlotInd */
345
346 /**
347  * @brief Transmission time interval indication from PHY.
348  *
349  * @details
350  *
351  *     Function : fapiMacSlotInd 
352  *      
353  *      This API is invoked by PHY to indicate TTI indication to MAC for a cell.
354  *           
355  *  @param[in]  Pst            *pst
356  *  @param[in]  SuId           suId 
357  *  @param[in]  SlotTimingInfo    *slotInd
358  *  @return  
359  *      -# ROK 
360  *      -# RFAILED 
361  **/
362 uint8_t fapiMacSlotInd(Pst *pst, SlotTimingInfo *slotInd)
363 {
364    uint8_t               ret = ROK;
365    uint16_t              cellIdx;
366    volatile uint32_t     startTime=0;
367
368 #ifdef ODU_SLOT_IND_DEBUG_LOG
369    DU_LOG("\nDEBUG  -->  MAC : Slot Indication received. [%d : %d]", slotInd->sfn, slotInd->slot);
370 #endif
371    /*starting Task*/
372    ODU_START_TASK(&startTime, PID_MAC_TTI_IND);
373    gSlotCount++;
374
375    if(gSlotCount == 1)
376    {
377            GET_CELL_IDX(slotInd->cellId, cellIdx);
378            macCb.macCell[cellIdx]->state = CELL_STATE_UP;
379    }
380
381 /* When testing L2 with Intel-L1, any changes specific to 
382  * timer mode testing must be guarded under INTEL_TIMER_MODE*/
383 #ifndef INTEL_TIMER_MODE
384    /* send slot indication to scheduler */
385    ret = sendSlotIndMacToSch(slotInd);
386    if(ret != ROK)
387    {
388       DU_LOG("\nERROR  -->  MAC : Sending of slot ind msg from MAC to SCH failed");
389       MAC_FREE_SHRABL_BUF(pst->region, pst->pool, slotInd, sizeof(SlotTimingInfo));
390       return ret;
391    }
392
393    ret = macProcSlotInd(*slotInd);
394    if(ret != ROK)
395    {
396       DU_LOG("\nERROR  -->  MAC : macProcSlotInd failed");
397       MAC_FREE_SHRABL_BUF(pst->region, pst->pool, slotInd, sizeof(SlotTimingInfo));
398       return ret;
399    }
400 #endif
401
402    /* send slot indication to du app */
403    if(gSlotCount == 1)   
404    {
405       ret = sendCellUpIndMacToDuApp(slotInd->cellId);
406       if(ret != ROK)
407       {
408          DU_LOG("\nERROR  -->  MAC :Sending of slot ind msg from MAC to DU APP failed");
409          MAC_FREE_SHRABL_BUF(pst->region, pst->pool, slotInd, sizeof(SlotTimingInfo));
410          return ret;
411       }
412    }
413
414    /*stoping Task*/
415    ODU_STOP_TASK(startTime, PID_MAC_TTI_IND);
416    MAC_FREE_SHRABL_BUF(pst->region, pst->pool, slotInd, sizeof(SlotTimingInfo));
417
418 #ifdef INTEL_WLS_MEM
419    lwrMacCb.phySlotIndCntr++;
420    if(lwrMacCb.phySlotIndCntr > WLS_MEM_FREE_PRD)
421    {
422       lwrMacCb.phySlotIndCntr = 1;
423    }
424    freeWlsBlockList(lwrMacCb.phySlotIndCntr - 1);
425 #endif
426
427    return ret;
428 }  /* fapiMacSlotInd */
429
430 /**********************************************************************
431   End of file
432  **********************************************************************/
433