[Task-ID: ODUHIGH-455] Changes to support new L1 20.11
[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_fsm.h"
29 #include "lwr_mac_phy.h"
30 #include "mac_utils.h"
31 #include "lwr_mac_utils.h"
32 #include "lwr_mac.h"
33 #ifdef INTEL_FAPI
34 #include "nr5g_fapi_internal.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("\nINFO  -->  LWR 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("\nERROR  -->  LWR 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 = NULLP;
141    WlsBlockToFree  *block = NULLP;
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
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          while(numMsgToGet--)
231          {
232             currElem = NULLP;
233             l1Msg = (uint64_t)NULLP;
234             l1MsgPtr = NULLP;
235             l1Msg = WLS_Get(wlsHdlr, &msgSize, &msgType, &flag);
236             if(l1Msg)
237             {
238                l1MsgPtr = WLS_PA2VA(wlsHdlr, l1Msg); 
239                currElem = (p_fapi_api_queue_elem_t) l1MsgPtr;
240                if(currElem->msg_type != FAPI_VENDOR_MSG_HEADER_IND)
241                {
242                   procPhyMessages(currElem->msg_type, 0, (void *)(currElem + 1));
243                }
244                WLS_MEM_FREE(currElem, LWR_MAC_WLS_BUF_SIZE);
245             }
246          }
247          LwrMacEnqueueWlsBlock();
248       }
249    }
250 #endif
251 } /* LwrMacRecvPhyMsg */
252
253 #endif /* INTEL_WLS_MEM */
254
255 /*******************************************************************
256  *
257  * @brief Send FAPI messages to Intel PHY/Phy stub
258  *
259  * @details
260  *
261  *    Function : LwrMacSendToL1
262  *
263  *    Functionality: Send FAPI messages to Intel PHY/Phy stub
264  *
265  * @params[in] Message pointer
266  * @return ROK     - success
267  *         RFAILED - failure
268  *
269  * ****************************************************************/
270 uint8_t LwrMacSendToL1(void *msg)
271 {
272    uint8_t ret = ROK;
273 #ifdef INTEL_FAPI
274    uint16_t msgLen =0;
275    p_fapi_api_queue_elem_t currMsg = NULLP;
276
277 #ifdef CALL_FLOW_DEBUG_LOG   
278    char message[100];
279
280    currMsg = (p_fapi_api_queue_elem_t)msg;
281    while(currMsg)
282    {
283       switch(currMsg->msg_type)
284       {
285          case FAPI_PARAM_REQUEST:
286             strcpy(message, "FAPI_PARAM_REQUEST");
287             break;
288          case FAPI_CONFIG_REQUEST:
289             strcpy(message, "FAPI_CONFIG_REQUEST");
290             break;
291          case FAPI_START_REQUEST:
292             strcpy(message, "FAPI_START_REQUEST");
293             break;
294          case FAPI_DL_TTI_REQUEST:
295             strcpy(message, "FAPI_DL_TTI_REQUEST");
296             break;
297          case FAPI_TX_DATA_REQUEST:
298             strcpy(message, "FAPI_TX_DATA_REQUEST");
299             break;
300          case FAPI_UL_TTI_REQUEST:
301             strcpy(message, "FAPI_UL_TTI_REQUEST");
302             break;
303          case FAPI_STOP_REQUEST:
304             strcpy(message, "FAPI_STOP_REQUEST");
305             break;
306          case FAPI_UL_DCI_REQUEST:
307             strcpy(message, "FAPI_UL_DCI_REQUEST");
308             break;
309          default:
310             strcpy(message, "INVALID_MSG");
311             break;
312       }
313       DU_LOG("\nCall Flow: ENTLWRMAC -> PHY : %s\n",message);
314       currMsg = currMsg->p_next;
315    }
316 #endif
317
318
319 #ifdef INTEL_WLS_MEM
320    void * wlsHdlr = NULLP;
321
322    mtGetWlsHdl(&wlsHdlr);
323    if(msg)
324    {
325       currMsg = (p_fapi_api_queue_elem_t)msg;
326       msgLen = currMsg->msg_len + sizeof(fapi_api_queue_elem_t);
327       addWlsBlockToFree(currMsg, msgLen, (lwrMacCb.phySlotIndCntr-1));
328       if(currMsg->p_next == NULLP)
329       {
330          DU_LOG("\nERROR  -->  LWR MAC : There cannot be only one block to send");
331          return RFAILED;
332       }
333
334       /* Sending first block */
335       ret = WLS_Put(wlsHdlr, WLS_VA2PA(wlsHdlr, currMsg), msgLen, currMsg->msg_type, WLS_SG_FIRST);
336       if(ret != 0)
337       {
338          DU_LOG("\nERROR  -->  LWR MAC : Failure in sending message to PHY");
339          return RFAILED;
340       }
341       currMsg = currMsg->p_next;
342
343       while(currMsg)
344       {
345          /* Sending the next msg */
346          msgLen = currMsg->msg_len + sizeof(fapi_api_queue_elem_t);
347          addWlsBlockToFree(currMsg, msgLen, (lwrMacCb.phySlotIndCntr-1));
348          if(currMsg->p_next != NULLP)
349          {
350             ret = WLS_Put(wlsHdlr, WLS_VA2PA(wlsHdlr, currMsg), msgLen, currMsg->msg_type, WLS_SG_NEXT);
351             if(ret != 0)
352             {
353                DU_LOG("\nERROR  -->  LWR MAC : Failure in sending message to PHY");
354                return RFAILED;
355             }
356             currMsg = currMsg->p_next;
357          }
358          else
359          {
360             /* Sending last msg */
361             ret = WLS_Put(wlsHdlr, WLS_VA2PA(wlsHdlr, currMsg), msgLen, currMsg->msg_type, WLS_SG_LAST);
362             if(ret != 0)
363             {
364                DU_LOG("\nERROR  -->  LWR MAC : Failure in sending message to PHY");
365                return RFAILED;
366             }
367             currMsg = NULLP;
368          }
369       }
370    }
371 #else
372    p_fapi_api_queue_elem_t nextMsg = NULLP;
373
374    /* FAPI header and vendor specific msgs are freed here. Only 
375     * the main FAPI messages are sent to phy stub */
376    currMsg = (p_fapi_api_queue_elem_t)msg;
377    while(currMsg)
378    {
379       nextMsg = currMsg->p_next;
380       msgLen = currMsg->msg_len + sizeof(fapi_api_queue_elem_t);
381       if((currMsg->msg_type != FAPI_VENDOR_MSG_HEADER_IND) && \
382             (currMsg->msg_type != FAPI_VENDOR_MESSAGE))
383       {
384          l1ProcessFapiRequest(currMsg->msg_type, msgLen, currMsg);
385       }
386       else
387       {
388          LWR_MAC_FREE(currMsg, msgLen);   
389       }
390       currMsg = nextMsg;
391    }
392 #endif
393 #endif
394    return ret;
395 }
396
397 /**********************************************************************
398   End of file
399  **********************************************************************/