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