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