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