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