1 /******************************************************************************
3 * Copyright (c) 2019 Intel.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 *******************************************************************************/
20 * @brief This file is test FAPI wls lib main process
22 * @ingroup group_testfapiwls
23 * @author Intel Corporation
33 #include <rte_cfgfile.h>
34 #include <rte_string_fns.h>
35 #include <rte_common.h>
36 #include <rte_string_fns.h>
37 #include <rte_lcore.h>
38 #include <rte_debug.h>
39 #include <rte_launch.h>
45 #define NR5G_FAPI2PHY_WLS_INST 0
46 #define NR5G_FAPI2MAC_WLS_INST 1
49 #define WLS_TEST_DEV_NAME "wls"
50 #define WLS_TEST_MSG_ID 1
51 #define WLS_TEST_MSG_SIZE 100
52 #define ALLOC_TRACK_SIZE 16384
53 #define MIN_UL_BUF_LOCATIONS 50
54 #define MIN_DL_BUF_LOCATIONS 50
55 #define MAX_UL_BUF_LOCATIONS 50
56 #define MAX_DL_BUF_LOCATIONS 50
57 #define NUM_WLS_INSTANCES 2
58 #define WLS_HUGE_DEF_PAGE_SIZEA 0x40000000LL
59 #define MSG_MAXSIZE1 (16*16384)
60 #define NUM_TEST_MSGS 16
65 typedef void* WLS_HANDLE;
66 typedef struct wls_fapi_mem_array
73 } WLS_FAPI_MEM_STRUCT, *PWLS_FAPI_MEM_STRUCT;
75 // WLS context structure
76 typedef struct _nr5g_fapi_wls_context {
77 void *shmem; // shared memory region.
78 uint64_t shmem_size; // shared memory region size.
79 WLS_FAPI_MEM_STRUCT sWlsStruct;
80 WLS_HANDLE h_wls[NUM_WLS_INSTANCES]; // WLS context handle
82 uint32_t nTotalMemorySize;
83 uint32_t nTotalBlocks;
84 uint32_t nAllocBlocks;
85 uint32_t nTotalAllocCnt;
86 uint32_t nTotalFreeCnt;
87 uint32_t nTotalUlBufAllocCnt;
88 uint32_t nTotalUlBufFreeCnt;
89 uint32_t nTotalDlBufAllocCnt;
90 uint32_t nTotalDlBufFreeCnt;
91 uint32_t nPartitionMemSize;
92 void *pPartitionMemBase;
93 volatile pthread_mutex_t lock;
94 volatile pthread_mutex_t lock_alloc;
95 } nr5g_fapi_wls_context_t, *p_nr5g_fapi_wls_context_t;
97 nr5g_fapi_wls_context_t g_wls_ctx;
98 typedef void* WLS_HANDLE;
99 static uint8_t alloc_track[ALLOC_TRACK_SIZE];
101 uint32_t g_shmem_size=0;
102 uint32_t g_nTotalAllocCnt=0;
103 uint32_t g_nAllocBlocks=0;
104 uint32_t gwls_fapi_ready=0;
105 WLS_FAPI_MEM_STRUCT g_MemArray;
106 nr5g_fapi_wls_context_t g_wls_ctx;
107 uint32_t g_nTotalDlBufAllocCnt=0;
108 uint32_t g_nTotalUlBufAllocCnt=0;
110 wls_us_ctx_t gphy_wls;
111 wls_us_ctx_t gfapi_wls;
113 WLS_HANDLE g_phy_wls = &gphy_wls;
114 WLS_HANDLE g_fapi_wls = &gfapi_wls;
116 uint8_t fapi_dpdk_init(void);
117 uint8_t fapi_wls_init(const char *dev_name);
118 uint64_t fapi_mac_recv();
119 uint8_t fapi_phy_send();
120 uint64_t fapi_phy_recv();
121 uint8_t fapi_mac_send();
122 uint8_t fapi2Phy_wls_init(p_nr5g_fapi_wls_context_t pwls);
123 uint8_t wls_fapi_create_partition(p_nr5g_fapi_wls_context_t pWls);
124 uint32_t wls_fapi_alloc_mem_array(PWLS_FAPI_MEM_STRUCT pMemArray, void **ppBlock);
125 uint32_t wls_fapi_create_mem_array(PWLS_FAPI_MEM_STRUCT pMemArray, void *pMemArrayMemory, uint32_t totalSize, uint32_t nBlockSize);
127 uint64_t nr5g_fapi_wls_va_to_pa(WLS_HANDLE h_wls, void *ptr)
129 return ((uint64_t)WLS_VA2PA(h_wls, ptr));
132 inline p_nr5g_fapi_wls_context_t nr5g_fapi_wls_context()
137 static inline WLS_HANDLE nr5g_fapi_fapi2mac_wls_instance()
139 p_nr5g_fapi_wls_context_t p_wls_ctx = nr5g_fapi_wls_context();
141 return p_wls_ctx->h_wls[NR5G_FAPI2MAC_WLS_INST];
144 static inline WLS_HANDLE nr5g_fapi_fapi2phy_wls_instance()
146 p_nr5g_fapi_wls_context_t p_wls_ctx = nr5g_fapi_wls_context();
147 return p_wls_ctx->h_wls[NR5G_FAPI2PHY_WLS_INST];
149 void *wls_fapi_alloc_buffer(uint32_t size, uint32_t loc)
152 p_nr5g_fapi_wls_context_t pWls = nr5g_fapi_wls_context();
153 PWLS_FAPI_MEM_STRUCT pMemArray = &pWls->sWlsStruct;
155 pthread_mutex_lock((pthread_mutex_t *)&pWls->lock_alloc);
157 if (wls_fapi_alloc_mem_array(&pWls->sWlsStruct, &pBlock) != SUCCESS)
159 printf("wls_fapi_alloc_buffer alloc error size[%d] loc[%d]\n", size, loc);
165 pWls->nAllocBlocks++;
168 //printf("----------------wls_fapi_alloc_buffer: size[%d] loc[%d] buf[%p] nAllocBlocks[%d]\n", size, loc, pBlock, pWls->nAllocBlocks);
170 //printf("[%p]\n", pBlock);
172 pWls->nTotalAllocCnt++;
173 if (loc < MAX_DL_BUF_LOCATIONS)
174 pWls->nTotalDlBufAllocCnt++;
175 else if (loc < MAX_UL_BUF_LOCATIONS)
176 pWls->nTotalUlBufAllocCnt++;
178 pthread_mutex_unlock((pthread_mutex_t *)&pWls->lock_alloc);
182 uint32_t wls_fapi_create_mem_array(PWLS_FAPI_MEM_STRUCT pMemArray, void *pMemArrayMemory, uint32_t totalSize, uint32_t nBlockSize)
185 int numBlocks = totalSize / nBlockSize;
189 printf("wls_fapi_create_mem_array: pMemArray[%p] pMemArrayMemory[%p] totalSize[%d] nBlockSize[%d] numBlocks[%d]\n",
190 pMemArray, pMemArrayMemory, totalSize, nBlockSize, numBlocks);
192 // Can't be less than pointer size
193 if (nBlockSize < sizeof(void *))
198 // Can't be less than one block
199 if (totalSize < sizeof(void *))
204 pMemArray->ppFreeBlock = (void **)pMemArrayMemory;
205 pMemArray->pStorage = pMemArrayMemory;
206 pMemArray->pEndOfStorage = ((unsigned long*)pMemArrayMemory) + numBlocks * nBlockSize / sizeof(unsigned long);
207 pMemArray->nBlockSize = nBlockSize;
208 pMemArray->nBlockCount = numBlocks;
210 // Initialize single-linked list of free blocks;
211 ptr = (void **)pMemArrayMemory;
212 for (i = 0; i < pMemArray->nBlockCount; i++)
214 #ifdef MEMORY_CORRUPTION_DETECT
215 // Fill with some pattern
216 uint8_t *p = (uint8_t *)ptr;
219 p += (nBlockSize - 16);
220 for (j = 0; j < 16; j++)
222 p[j] = MEMORY_CORRUPTION_DETECT_FLAG;
226 if (i == pMemArray->nBlockCount - 1)
228 *ptr = NULL; // End of list
232 // Points to the next block
233 *ptr = (void **)(((uint8_t*)ptr) + nBlockSize);
234 ptr += nBlockSize / sizeof(unsigned long);
238 memset(alloc_track, 0, sizeof(uint8_t) * ALLOC_TRACK_SIZE);
243 uint32_t wls_fapi_alloc_mem_array(PWLS_FAPI_MEM_STRUCT pMemArray, void **ppBlock)
247 if (pMemArray->ppFreeBlock == NULL)
249 printf("wls_fapi_alloc_mem_array pMemArray->ppFreeBlock = NULL\n");
253 // FIXME: Remove after debugging
254 if (((void *) pMemArray->ppFreeBlock < pMemArray->pStorage) ||
255 ((void *) pMemArray->ppFreeBlock >= pMemArray->pEndOfStorage))
257 printf("wls_fapi_alloc_mem_array ERROR: Corrupted MemArray;Arr=%p,Stor=%p,Free=%p\n",
258 pMemArray, pMemArray->pStorage, pMemArray->ppFreeBlock);
262 pMemArray->ppFreeBlock = (void **)((unsigned long)pMemArray->ppFreeBlock & 0xFFFFFFFFFFFFFFF0);
263 *pMemArray->ppFreeBlock = (void **)((unsigned long)*pMemArray->ppFreeBlock & 0xFFFFFFFFFFFFFFF0);
265 if ((*pMemArray->ppFreeBlock != NULL) &&
266 (((*pMemArray->ppFreeBlock) < pMemArray->pStorage) ||
267 ((*pMemArray->ppFreeBlock) >= pMemArray->pEndOfStorage)))
269 fprintf(stderr, "ERROR: Corrupted MemArray;Arr=%p,Stor=%p,Free=%p,Curr=%p\n",
270 pMemArray, pMemArray->pStorage, pMemArray->ppFreeBlock,
271 *pMemArray->ppFreeBlock);
275 *ppBlock = (void *) pMemArray->ppFreeBlock;
276 pMemArray->ppFreeBlock = (void **) (*pMemArray->ppFreeBlock);
278 idx = (((uint64_t)*ppBlock - (uint64_t)pMemArray->pStorage)) / pMemArray->nBlockSize;
279 if (alloc_track[idx])
281 printf("wls_fapi_alloc_mem_array Double alloc Arr=%p,Stor=%p,Free=%p,Curr=%p\n",
282 pMemArray, pMemArray->pStorage, pMemArray->ppFreeBlock,
283 *pMemArray->ppFreeBlock);
287 #ifdef MEMORY_CORRUPTION_DETECT
288 uint32_t nBlockSize = pMemArray->nBlockSize, i;
289 uint8_t *p = (uint8_t *)*ppBlock;
291 p += (nBlockSize - 16);
292 for (i = 0; i < 16; i++)
294 p[i] = MEMORY_CORRUPTION_DETECT_FLAG;
297 alloc_track[idx] = 1;
300 //printf("Block allocd [%p,%p]\n", pMemArray, *ppBlock);
307 uint8_t wls_fapi_create_partition(p_nr5g_fapi_wls_context_t pWls)
309 static long hugePageSize = WLS_HUGE_DEF_PAGE_SIZEA;
310 void *pPartitionMemBase;
311 uint32_t nPartitionMemSize;
312 uint32_t nTotalBlocks;
314 pWls->pPartitionMemBase = pWls->pWlsMemBase + hugePageSize;
315 pWls->nPartitionMemSize = (pWls->nTotalMemorySize - hugePageSize);
317 pWls->nTotalBlocks = pWls->nPartitionMemSize / MSG_MAXSIZE1;
319 return wls_fapi_create_mem_array(&pWls->sWlsStruct, pWls->pPartitionMemBase, pWls->nPartitionMemSize, MSG_MAXSIZE1);
322 uint8_t nr5g_fapi2Phy_wls_init(p_nr5g_fapi_wls_context_t pWls)
325 uint8_t retval = SUCCESS;
328 WLS_HANDLE h_wls = pWls->h_wls[NR5G_FAPI2PHY_WLS_INST];
329 pthread_mutex_init((pthread_mutex_t *)&pWls->lock, NULL);
330 pthread_mutex_init((pthread_mutex_t *)&pWls->lock_alloc, NULL);
332 pWls->nTotalAllocCnt = 0;
333 pWls->nTotalFreeCnt = 0;
334 pWls->nTotalUlBufAllocCnt = 0;
335 pWls->nTotalUlBufFreeCnt = 0;
336 pWls->nTotalDlBufAllocCnt = 0;
337 pWls->nTotalDlBufFreeCnt = 0;
338 // Need to add wls_fapi_create_partition
339 retval = wls_fapi_create_partition(pWls);
340 if (retval == SUCCESS)
343 nBlocks = WLS_EnqueueBlock(h_wls, nr5g_fapi_wls_va_to_pa( h_wls, wls_fapi_alloc_buffer(0, MIN_UL_BUF_LOCATIONS+2)));
344 printf("WLS_EnqueueBlock [%d]\n", nBlocks);
345 // Allocate Blocks for UL Transmission
346 while(WLS_EnqueueBlock(h_wls, nr5g_fapi_wls_va_to_pa(h_wls,wls_fapi_alloc_buffer(0, MIN_UL_BUF_LOCATIONS+3))))
350 printf ("fapi2Phy UL Buffer Allocation completed\n");
354 printf ("can't create WLS FAPI2PHY partition \n");
360 uint8_t nr5g_fapi_fapi2mac_wls_ready()
363 ret = WLS_Ready1(nr5g_fapi_fapi2mac_wls_instance());
368 inline uint8_t nr5g_fapi_fapi2phy_wls_ready()
371 //NR5G_FAPI_LOG(TRACE_LOG, ("Waiting for L1 to respond in WLS Ready"));
372 ret = WLS_Ready(nr5g_fapi_fapi2phy_wls_instance());
380 uint8_t retval= FAILURE;
381 p_nr5g_fapi_wls_context_t pwls;
384 ret = fapi_dpdk_init();
387 printf("\n[FAPI] DPDK Init - Failed\n");
390 printf("\n[FAPI] DPDK Init - Done\n");
393 ret = fapi_wls_init(WLS_TEST_DEV_NAME);
396 printf("\n[FAPI] WLS Init - Failed\n");
399 // Need to check for L1 and L2 started before attempting partition creation
400 // First let's wait for the L1 and L2 to be present
403 retval = nr5g_fapi_fapi2phy_wls_ready();
405 // Now the L2 is up so let's make sure that the L1 was started first
409 retval = nr5g_fapi_fapi2mac_wls_ready();
411 // Now that the L2 is up and has completed the Common Memory initialization the FT needs to initialize the FAPI2PHY buffers
412 pwls = nr5g_fapi_wls_context();
414 ret = nr5g_fapi2Phy_wls_init(pwls);
417 printf("\n[FAPI] 2Phy WLS Init - Failed\n");
421 printf("\n[FAPI] WLS Init - Done\n");
423 // Receive from MAC WLS
424 p_msg = fapi_mac_recv();
427 printf("\n[FAPI] Receive from MAC - Failed\n");
430 printf("\n[FAPI] Receive from MAC - Done\n");
433 ret = fapi_phy_send();
436 printf("\n[FAPI] Send to PHY - Failed\n");
439 printf("\n[FAPI] Send to PHY - Done\n");
441 // Receive from PHY WLS
442 p_msg = fapi_phy_recv();
445 printf("\n[FAPI] Receive from PHY - Failed\n");
448 printf("\n[FAPI] Receive from PHY - Done\n");
451 ret = fapi_mac_send();
454 printf("\n[FAPI] Send to MAC - Failed\n");
457 printf("\n[FAPI] Send to MAC - Done\n");
460 printf("\n[FAPI] Exiting...\n");
465 uint8_t fapi_dpdk_init(void)
470 char *argv[] = {"fapi_app", "--proc-type=secondary",
471 "--file-prefix", "wls", whitelist};
473 int argc = RTE_DIM(argv);
475 /* initialize EAL first */
476 sprintf(whitelist, "-a%s", "0000:00:06.0");
477 printf("[FAPI] Calling rte_eal_init: ");
479 for (i = 0; i < RTE_DIM(argv); i++)
481 printf("%s ", argv[i]);
485 if (rte_eal_init(argc, argv) < 0)
486 rte_panic("Cannot init EAL\n");
491 uint8_t fapi_wls_init(const char *dev_name)
493 uint64_t nWlsMacMemorySize;
494 uint64_t nWlsPhyMemorySize;
496 static const struct rte_memzone *mng_memzone;
497 p_nr5g_fapi_wls_context_t p_wls_ctx = nr5g_fapi_wls_context();
498 wls_drv_ctx_t *pDrv_ctx;
500 p_wls_ctx->h_wls[NR5G_FAPI2MAC_WLS_INST] =
501 WLS_Open_Dual(dev_name, WLS_SLAVE_CLIENT, &nWlsMacMemorySize, &nWlsPhyMemorySize, &p_wls_ctx->h_wls[NR5G_FAPI2PHY_WLS_INST]);
502 if((NULL == p_wls_ctx->h_wls[NR5G_FAPI2PHY_WLS_INST]) &&
503 (NULL == p_wls_ctx->h_wls[NR5G_FAPI2MAC_WLS_INST]))
507 g_shmem_size = nWlsMacMemorySize + nWlsPhyMemorySize;
508 p_wls_ctx->shmem_size = g_shmem_size;
509 // Issue WLS_Alloc() for FAPI2MAC
510 p_wls_ctx->shmem = WLS_Alloc(
511 p_wls_ctx->h_wls[NR5G_FAPI2MAC_WLS_INST],
512 p_wls_ctx->shmem_size);
514 if (NULL == p_wls_ctx->shmem)
516 printf("Unable to alloc WLS Memory for FAPI2MAC\n");
519 p_wls_ctx->shmem = WLS_Alloc(
520 p_wls_ctx->h_wls[NR5G_FAPI2PHY_WLS_INST],
521 p_wls_ctx->shmem_size);
522 p_wls_ctx->pWlsMemBase = p_wls_ctx->shmem;
523 p_wls_ctx->nTotalMemorySize = p_wls_ctx->shmem_size;
524 if (NULL == p_wls_ctx->shmem)
526 printf("Unable to alloc WLS Memory for FAPI2PHY\n");
534 uint64_t fapi_mac_recv()
536 uint8_t num_blks = 0;
543 WLS_HANDLE wls= nr5g_fapi_fapi2mac_wls_instance();
545 for (i=0; i < NUM_TEST_MSGS; i++)
547 num_blks = WLS_Wait1(wls);
551 p_msg = WLS_Get1(wls, &msg_size, &msg_id, &flags);
555 printf("\n[FAPI] FAPI2MAC WLS wait returned 0 blocks\n");
559 printf("\n[FAPI] Receive from MAC Msg %d-\n", i);
565 uint8_t fapi_phy_send()
567 uint64_t pa_block = 0;
568 uint8_t ret = FAILURE;
570 WLS_HANDLE wls = nr5g_fapi_fapi2mac_wls_instance();
571 WLS_HANDLE wlsp = nr5g_fapi_fapi2phy_wls_instance();
573 for (i=0; i < NUM_TEST_MSGS; i++)
575 pa_block = (uint64_t) WLS_DequeueBlock((void*) wls);
578 printf("\n[FAPI] FAPI2MAC WLS Dequeue block error %d\n",i);
582 ret = WLS_Put(wlsp, pa_block, WLS_TEST_MSG_SIZE, WLS_TEST_MSG_ID, (i== (NUM_TEST_MSGS-1))? WLS_TF_FIN:0);
585 printf("\n[FAPI] Send to PHY %d- Failed\n",i);
590 printf("\n[FAPI] Send to PHY %d done \n",i);
596 uint64_t fapi_phy_recv()
598 uint8_t num_blks = 0;
604 WLS_HANDLE wls = nr5g_fapi_fapi2phy_wls_instance();
608 num_blks = WLS_Wait(wls);
609 printf("WLS_Wait returns %d\n",num_blks);
613 p_msg = WLS_Get(wls, &msg_size, &msg_id, &flags);
614 printf("\n[FAPI] FAPI2PHY Received Block %d \n", i);
616 if (flags & WLS_TF_FIN)
623 printf("\n[FAPI] FAPI2MAC WLS wait returned 0 blocks\n");
629 uint8_t fapi_mac_send()
631 uint64_t pa_block = 0;
632 uint8_t ret = FAILURE;
634 WLS_HANDLE wls = nr5g_fapi_fapi2mac_wls_instance();
635 WLS_HANDLE wlsp = nr5g_fapi_fapi2phy_wls_instance();
637 for (i=0; i < NUM_TEST_MSGS; i++)
639 pa_block = (uint64_t) WLS_DequeueBlock((void*) wlsp);
642 printf("\n[FAPI] FAPI2MAC WLS Dequeue block %d error\n",i);
646 ret = WLS_Put1(wls, pa_block, WLS_TEST_MSG_SIZE, WLS_TEST_MSG_ID, (i== (NUM_TEST_MSGS-1))? WLS_TF_FIN:0);
647 printf("\n[FAPI] FAPI2MAC WLS Put1 block %d\n",i);