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