Merge "O-DU High Architecture updated"
[o-du/l2.git] / src / 5gnrmac / lwr_mac_phy.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
19 /* This file contains APIs to send/receive messages from PHY */
20
21 #include "common_def.h"
22 #include "lrg.h"
23 #include "lrg.x"
24 #include "du_app_mac_inf.h"
25 #include "mac_sch_interface.h"
26 #include "lwr_mac_upr_inf.h"
27 #include "mac.h"
28 #include "lwr_mac_phy.h"
29 #include "lwr_mac_fsm.h"
30 #include "mac_utils.h"
31 #include "lwr_mac_utils.h"
32 #include "lwr_mac.h"
33 #ifdef INTEL_FAPI
34 #include "fapi.h"
35 #include "fapi_vendor_extension.h"
36 #endif
37 #ifdef INTEL_WLS_MEM
38 #include "wls_lib.h"
39 #endif
40
41 uint8_t rgClHndlCfgReq ARGS((void *msg));
42 void l1ProcessFapiRequest ARGS((uint8_t msgType, uint32_t msgLen, void *msg));
43
44 #ifdef INTEL_WLS_MEM
45
46 /*******************************************************************
47  *
48  * @brief Sends request to start wls receiver thread
49  *
50  * @details
51  *
52  *    Function : LwrMacStartWlsRcvr
53  *
54  *    Functionality:
55  *      Sends request to start wls receiver thread
56  *
57  * @params[in] 
58  * @return void
59  *
60  * ****************************************************************/
61 void LwrMacStartWlsRcvr()
62 {
63    Pst pst;
64    Buffer *mBuf;
65
66    DU_LOG("\nLWR MAC: Requesting to start WLS receiver thread");
67
68    /* Filling post */
69    memset(&pst, 0, sizeof(Pst));
70    FILL_PST_LWR_MAC_TO_LWR_MAC(pst, EVT_START_WLS_RCVR);
71
72    if (ODU_GET_MSG_BUF(pst.region, pst.pool, &mBuf) != ROK)
73    {
74       DU_LOG("\nLWR MAC : Memory allocation failed for LwrMacStartWlsRcvr");
75       return;
76    }
77
78    ODU_POST_TASK(&pst, mBuf);
79 }
80
81 /*******************************************************************
82  *
83  * @brief Enqueues memory blocks for use by L1
84  *
85  * @details
86  *
87  *    Function : LwrMacEnqueueWlsBlock
88  *
89  *    Functionality:
90  *      Enqueues memory blocks for use by L1
91  *
92  * @params[in] 
93  * @return void
94  *
95  * ****************************************************************/
96 void LwrMacEnqueueWlsBlock()
97 {
98    void *memPtr;
99    void *wlsHdlr = NULLP;
100
101    WLS_MEM_ALLOC(memPtr, LWR_MAC_WLS_BUF_SIZE);
102
103    if(memPtr) 
104    {
105       mtGetWlsHdl(&wlsHdlr);
106       /* allocate blocks for UL transmittion */
107       while(WLS_EnqueueBlock(wlsHdlr, WLS_VA2PA(wlsHdlr, memPtr)))
108       {
109          WLS_MEM_ALLOC(memPtr, LWR_MAC_WLS_BUF_SIZE);
110          if(!memPtr)
111             break;
112       }
113
114       // free not enqueued block
115       if(memPtr)
116       {
117          WLS_MEM_FREE(memPtr, LWR_MAC_WLS_BUF_SIZE);
118       }
119    }
120 }/* LwrMacEnqueueWlsBlock */
121
122 /*******************************************************************
123  *
124  * @brief Add memory block (to be freed later) to list
125  *
126  * @details
127  *
128  *    Function : addWlsBlockToFree 
129  *
130  *    Functionality:
131  *       Add memory block (to be freed later) to list
132  *
133  * @params[in] 
134  * @return ROK     - success
135  *         RFAILED - failure
136  *
137  * ****************************************************************/
138 void addWlsBlockToFree(void *msg, uint32_t msgLen, uint8_t idx)
139 {
140    CmLList         *node;
141    WlsBlockToFree  *block;
142    MAC_ALLOC(block, sizeof(WlsBlockToFree));
143    if(block)
144    {
145       MAC_ALLOC(node, sizeof(CmLList));
146       if(node)
147       {
148          block->ptr = msg;
149          block->size = msgLen;
150
151          node->node = (PTR)block;
152          cmLListAdd2Tail(&wlsBlockToFreeList[idx], node);
153       }
154    }
155 }/* addWlsBlockToFree */
156
157
158 /*******************************************************************
159  *
160  * @brief Free DL Memory blocks stored in list
161  *
162  * @details
163  *
164  *    Function : freeWlsBlockList
165  *
166  *    Functionality: Free DL Memory blocks stored in list
167  *
168  * @params[in] Array index to be freed
169  * @return ROK     - success
170  *         RFAILED - failure
171  *
172  * ****************************************************************/
173 void freeWlsBlockList(uint8_t idx)
174 {
175    CmLList         *node;
176    WlsBlockToFree  *block;
177    if(wlsBlockToFreeList[idx].count)
178    {
179       CM_LLIST_FIRST_NODE(&wlsBlockToFreeList[idx], node);
180       while(node)
181       {
182          block = (WlsBlockToFree *)node->node;
183          cmLListDelFrm(&wlsBlockToFreeList[idx], node);
184          WLS_MEM_FREE(block->ptr, block->size);
185          MAC_FREE(block, sizeof(WlsBlockToFree));
186          MAC_FREE(node, sizeof(CmLList));
187          node = NULL;
188          CM_LLIST_FIRST_NODE(&wlsBlockToFreeList[idx], node);
189       }
190    }
191 }
192
193 /*******************************************************************
194  *
195  * @brief Receives msg from L1 
196  *
197  * @details
198  *
199  *    Function :LwrMacRecvPhyMsg 
200  *
201  *    Functionality:
202  *      Receives L1 Msg and enqueues memort for UL msg
203  *
204  * @params[in] 
205  * @return 
206  * ****************************************************************/
207 void LwrMacRecvPhyMsg()
208 {
209 #ifdef INTEL_FAPI
210    uint32_t numMsgToGet;   /* Number of Memory blocks to get */
211    void     *wlsHdlr;       /* WLS handler */
212    uint64_t l1Msg;         /* Message received */
213    void     *l1MsgPtr;
214    uint32_t msgSize;
215    uint16_t msgType;
216    uint16_t flag = 0;
217    p_fapi_api_queue_elem_t currElem  = NULLP;
218    struct timeval time;
219
220    mtGetWlsHdl(&wlsHdlr);
221    if(WLS_Ready(wlsHdlr) == 0) 
222    {
223       while(true)
224       {
225          numMsgToGet = WLS_Wait(wlsHdlr);
226          if(numMsgToGet == 0)
227          {
228             continue;
229          }
230
231          printf("\nLWR_MAC: numMsgToGet %d", numMsgToGet);
232          while(numMsgToGet--)
233          {
234             currElem = NULLP;
235             l1Msg = (uint64_t)NULLP;
236             l1MsgPtr = NULLP;
237             l1Msg = WLS_Get(wlsHdlr, &msgSize, &msgType, &flag);
238             if(l1Msg)
239             {
240                l1MsgPtr = WLS_PA2VA(wlsHdlr, l1Msg); 
241                currElem = (p_fapi_api_queue_elem_t) l1MsgPtr;
242                if(currElem->msg_type != FAPI_VENDOR_MSG_HEADER_IND)
243                {
244                   procPhyMessages(currElem->msg_type, 0, (void *)(currElem + 1));
245                }
246                WLS_MEM_FREE(currElem, LWR_MAC_WLS_BUF_SIZE);
247             }
248          }
249          LwrMacEnqueueWlsBlock();
250       }
251    }
252 #endif
253 } /* LwrMacRecvPhyMsg */
254
255 #endif /* INTEL_WLS_MEM */
256
257 /*******************************************************************
258  *
259  * @brief Send FAPI messages to Intel PHY/Phy stub
260  *
261  * @details
262  *
263  *    Function : LwrMacSendToL1
264  *
265  *    Functionality: Send FAPI messages to Intel PHY/Phy stub
266  *
267  * @params[in] Message pointer
268  * @return ROK     - success
269  *         RFAILED - failure
270  *
271  * ****************************************************************/
272 uint8_t LwrMacSendToL1(void *msg)
273 {
274    uint8_t ret = ROK;
275 #ifdef INTEL_FAPI
276    uint16_t msgLen;
277    p_fapi_api_queue_elem_t currMsg = NULLP;
278
279 #ifdef INTEL_WLS_MEM
280    void * wlsHdlr = NULLP;
281
282    mtGetWlsHdl(&wlsHdlr);
283    if(msg)
284    {
285       currMsg = (p_fapi_api_queue_elem_t)msg;
286       msgLen = currMsg->msg_len + sizeof(fapi_api_queue_elem_t);
287       addWlsBlockToFree(currMsg, msgLen, (slotIndIdx-1));
288       if(currMsg->p_next == NULLP)
289       {
290          DU_LOG("\nThere cannot be only one block to send");
291          return RFAILED;
292       }
293
294       /* Sending first block */
295       ret = WLS_Put(wlsHdlr, WLS_VA2PA(wlsHdlr, currMsg), msgLen, currMsg->msg_type, WLS_SG_FIRST);
296       if(ret != 0)
297       {
298          DU_LOG("\nFailure in sending message to PHY");
299          return RFAILED;
300       }
301       currMsg = currMsg->p_next;
302
303       while(currMsg)
304       {
305          /* Sending the next msg */
306          msgLen = currMsg->msg_len + sizeof(fapi_api_queue_elem_t);
307          addWlsBlockToFree(currMsg, msgLen, (slotIndIdx-1));
308          if(currMsg->p_next != NULLP)
309          {
310             ret = WLS_Put(wlsHdlr, WLS_VA2PA(wlsHdlr, currMsg), msgLen, currMsg->msg_type, WLS_SG_NEXT);
311             if(ret != 0)
312             {
313                DU_LOG("\nFailure in sending message to PHY");
314                return RFAILED;
315             }
316             currMsg = currMsg->p_next;
317          }
318          else
319          {
320             /* Sending last msg */
321             ret = WLS_Put(wlsHdlr, WLS_VA2PA(wlsHdlr, currMsg), msgLen, currMsg->msg_type, WLS_SG_LAST);
322             if(ret != 0)
323             {
324                DU_LOG("\nFailure in sending message to PHY");
325                return RFAILED;
326             }
327             currMsg = NULLP;
328          }
329       }
330    }
331 #else
332    p_fapi_api_queue_elem_t nextMsg = NULLP;
333
334    /* FAPI header and vendor specific msgs are freed here. Only 
335     * the main FAPI messages are sent to phy stub */
336    currMsg = (p_fapi_api_queue_elem_t)msg;
337    while(currMsg)
338    {
339       nextMsg = currMsg->p_next;
340       msgLen = currMsg->msg_len + sizeof(fapi_api_queue_elem_t);
341       if((currMsg->msg_type != FAPI_VENDOR_MSG_HEADER_IND) && \
342             (currMsg->msg_type != FAPI_VENDOR_MESSAGE))
343       {
344          l1ProcessFapiRequest(currMsg->msg_type, msgLen, currMsg);
345       }
346       else
347       {
348          LWR_MAC_FREE(currMsg, msgLen);   
349       }
350       currMsg = nextMsg;
351    }
352 #endif
353 #endif
354    return ret;
355 }
356
357 /**********************************************************************
358   End of file
359  **********************************************************************/