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