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