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