37cb68751f453e718558e7c3b7711c0990b93da4
[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    /* 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    /* TODO : check if this too needs to be sent in sequence with Dl and Ul TTI req.
319     * If so , move trigger for fillUlDciReq to lower mac */
320    /* Trigger for UL DCI REQ */
321    fillUlDciReq(slotInd);
322
323    return ROK;
324 }  /* macProcSlotInd */
325
326 /**
327  * @brief Transmission time interval indication from PHY.
328  *
329  * @details
330  *
331  *     Function : fapiMacSlotInd 
332  *      
333  *      This API is invoked by PHY to indicate TTI indication to MAC for a cell.
334  *           
335  *  @param[in]  Pst            *pst
336  *  @param[in]  SuId           suId 
337  *  @param[in]  SlotIndInfo    *slotInd
338  *  @return  
339  *      -# ROK 
340  *      -# RFAILED 
341  **/
342 uint8_t fapiMacSlotInd(Pst *pst, SlotIndInfo *slotInd)
343 {
344    uint8_t               ret = ROK;
345    volatile uint32_t     startTime=0;
346
347 #ifdef ODU_SLOT_IND_DEBUG_LOG
348    DU_LOG("\nDEBUG  -->  MAC : Slot Indication received. [%d : %d]", slotInd->sfn, slotInd->slot);
349 #endif
350    /*starting Task*/
351    ODU_START_TASK(&startTime, PID_MAC_TTI_IND);
352    gSlotCount++;
353
354 /* When testing L2 with Intel-L1, any changes specific to 
355  * timer mode testing must be guarded under INTEL_TIMER_MODE*/
356 #ifndef INTEL_TIMER_MODE
357    /* send slot indication to scheduler */
358    ret = sendSlotIndMacToSch(slotInd);
359    if(ret != ROK)
360    {
361       DU_LOG("\nERROR  -->  MAC : Sending of slot ind msg from MAC to SCH failed");
362       MAC_FREE_SHRABL_BUF(pst->region, pst->pool, slotInd, sizeof(SlotIndInfo));
363       return ret;
364    }
365
366    ret = macProcSlotInd(*slotInd);
367    if(ret != ROK)
368    {
369       DU_LOG("\nERROR  -->  MAC : macProcSlotInd failed");
370       MAC_FREE_SHRABL_BUF(pst->region, pst->pool, slotInd, sizeof(SlotIndInfo));
371       return ret;
372    }
373 #endif
374
375    /* send slot indication to du app */
376    if(gSlotCount == 1)   
377    {
378       ret = sendCellUpIndMacToDuApp(slotInd->cellId);
379       if(ret != ROK)
380       {
381          DU_LOG("\nERROR  -->  MAC :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
387    /*stoping Task*/
388    ODU_STOP_TASK(startTime, PID_MAC_TTI_IND);
389    MAC_FREE_SHRABL_BUF(pst->region, pst->pool, slotInd, sizeof(SlotIndInfo));
390
391 #ifdef INTEL_WLS_MEM
392    lwrMacCb.phySlotIndCntr++;
393    if(lwrMacCb.phySlotIndCntr > WLS_MEM_FREE_PRD)
394    {
395       lwrMacCb.phySlotIndCntr = 1;
396    }
397    freeWlsBlockList(lwrMacCb.phySlotIndCntr - 1);
398 #endif
399
400    return ret;
401 }  /* fapiMacSlotInd */
402
403 /**********************************************************************
404   End of file
405  **********************************************************************/
406