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