Update to odulow per maintenance bronze
[o-du/phy.git] / wls_lib / wls_lib_dpdk.c
1 /******************************************************************************
2 *
3 *   Copyright (c) 2019 Intel.
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 #include <stdio.h>
20 #include <unistd.h>
21 #include <sys/mman.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25 #include <stdint.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <pthread.h>
30
31 #include <sys/ipc.h>
32 #include <sys/shm.h>
33
34 #include <rte_eal.h>
35 #include <rte_errno.h>
36 #include <rte_lcore.h>
37 #include <rte_memory.h>
38 #include <rte_memzone.h>
39 #include <rte_branch_prediction.h>
40
41 #include "ttypes.h"
42 #include "wls_lib.h"
43 #include "wls.h"
44 #include "syslib.h"
45
46 #define WLS_MAP_SHM 1
47
48 #define WLS_PHY_SHM_FILE_NAME "hp_"
49
50 #define HUGE_PAGE_FILE_NAME "/mnt/huge/page"
51
52 #define DIV_ROUND_OFFSET(X,Y) ( X/Y + ((X%Y)?1:0) )
53
54 #define WLS_LIB_USER_SPACE_CTX_SIZE DMA_MAP_MAX_BLOCK_SIZE
55
56 #define PLIB_ERR(x, args...)   printf("wls_lib: "x, ## args);
57 #define PLIB_INFO(x, args...)  printf("wls_lib: "x, ## args);
58
59 #ifdef _DEBUG_
60 #define PLIB_DEBUG(x, args...)  printf("wls_lib debug: "x, ## args);
61 #else
62 #define PLIB_DEBUG(x, args...)  do { } while(0)
63 #endif
64
65 extern int gethugepagesizes(long pagesizes[], int n_elem);
66
67
68 static uint32_t get_hugepagesz_flag(uint64_t hugepage_sz)
69 {
70     unsigned size_flag = 0;
71
72     switch (hugepage_sz) {
73         case RTE_PGSIZE_256K:
74             size_flag = RTE_MEMZONE_256KB;
75             break;
76         case RTE_PGSIZE_2M:
77             size_flag = RTE_MEMZONE_2MB;
78             break;
79         case RTE_PGSIZE_16M:
80             size_flag = RTE_MEMZONE_16MB;
81             break;
82         case RTE_PGSIZE_256M:
83             size_flag = RTE_MEMZONE_256MB;
84             break;
85         case RTE_PGSIZE_512M:
86             size_flag = RTE_MEMZONE_512MB;
87             break;
88         case RTE_PGSIZE_1G:
89             size_flag = RTE_MEMZONE_1GB;
90             break;
91         case RTE_PGSIZE_4G:
92             size_flag = RTE_MEMZONE_4GB;
93             break;
94         case RTE_PGSIZE_16G:
95             size_flag = RTE_MEMZONE_16GB;
96             break;
97         default:
98             PLIB_INFO("Unknown hugepage size %lu\n", hugepage_sz);
99             break;
100     }
101     return size_flag;
102 }
103
104 static pthread_mutex_t wls_put_lock;
105 static pthread_mutex_t wls_get_lock;
106 static pthread_mutex_t wls_put_lock1;
107 static pthread_mutex_t wls_get_lock1;
108
109 static wls_us_ctx_t* wls_us_ctx = NULL;
110 static wls_us_ctx_t* wls_us_ctx1 = NULL;
111 static const struct rte_memzone *hp_memzone = NULL;
112 static long hugePageSize = WLS_HUGE_DEF_PAGE_SIZE;
113 static uint64_t gWlsMemorySize = 0;
114
115 static inline int wls_check_ctx(void *h)
116 {
117     if (h != wls_us_ctx) {
118         PLIB_ERR("Incorrect user space context\n");
119         return -1;
120     }
121     return 0;
122 }
123
124 static inline int wls_check_ctx1(void *h)
125 {
126     if (h != wls_us_ctx1) {
127         PLIB_ERR("Incorrect user space context1\n");
128         return -1;
129     }
130     return 0;
131 }
132
133 static int wls_VirtToIova(const void* virtAddr, uint64_t* iovaAddr)
134 {
135     *iovaAddr = rte_mem_virt2iova(virtAddr);
136     if (*iovaAddr==RTE_BAD_IOVA)
137         return -1;
138     return 0;
139 }
140
141 static void wls_mutex_destroy(pthread_mutex_t* pMutex)
142 {
143     pthread_mutex_destroy(pMutex);
144 }
145
146 static void wls_mutex_init(pthread_mutex_t* pMutex)
147 {
148     pthread_mutexattr_t prior;
149     pthread_mutexattr_init(&prior);
150     pthread_mutexattr_setprotocol(&prior, PTHREAD_PRIO_INHERIT);
151     pthread_mutex_init(pMutex, &prior);
152     pthread_mutexattr_destroy(&prior);
153 }
154
155 static void wls_mutex_lock(pthread_mutex_t* pMutex)
156 {
157     pthread_mutex_lock(pMutex);
158 }
159
160 static void wls_mutex_unlock(pthread_mutex_t* pMutex)
161 {
162     pthread_mutex_unlock(pMutex);
163 }
164
165 static int wls_initialize(const char *ifacename, uint64_t nWlsMemorySize)
166 {
167     int ret;
168     pthread_mutexattr_t attr;
169
170     uint64_t nSize = nWlsMemorySize + sizeof(wls_drv_ctx_t);
171     uint8_t *pMemZone;
172     const struct rte_memzone *mng_ctx_memzone;
173     wls_drv_ctx_t *mng_ctx;
174
175     mng_ctx_memzone = rte_memzone_reserve_aligned(ifacename, nSize, rte_socket_id(), get_hugepagesz_flag(hugePageSize), hugePageSize);
176     if (mng_ctx_memzone == NULL) {
177         PLIB_ERR("Cannot reserve memory zone[%s]: %s\n", ifacename, rte_strerror(rte_errno));
178         return -1;
179     }
180
181     pMemZone = ((uint8_t *)mng_ctx_memzone->addr) + nWlsMemorySize;
182     memset(pMemZone, 0, sizeof(wls_drv_ctx_t));
183     mng_ctx = (wls_drv_ctx_t *)pMemZone;
184
185     pthread_mutexattr_init(&attr);
186     pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
187     if (ret = pthread_mutex_init(&mng_ctx->mng_mutex, &attr)) {
188         PLIB_ERR("Failed to initialize mng_mutex %d\n", ret);
189         pthread_mutexattr_destroy(&attr);
190         return ret;
191     }
192     pthread_mutexattr_destroy(&attr);
193     PLIB_DEBUG("Run wls_initialized\n");
194     return 0;
195 }
196
197 static wls_us_ctx_t* wls_create_us_ctx(wls_drv_ctx_t *pDrv_ctx)
198 {
199     int idx;
200
201     wls_mutex_lock(&pDrv_ctx->mng_mutex);
202
203     if (unlikely(pDrv_ctx->nWlsClients >= WLS_US_CLIENTS_MAX)) {
204         PLIB_ERR("Maximum number of clients reached");
205         wls_mutex_unlock(&pDrv_ctx->mng_mutex);
206         return NULL;
207     }
208
209     wls_us_ctx_t *pUsCtx = &pDrv_ctx->p_wls_us_ctx[pDrv_ctx->nWlsClients];
210     wls_us_priv_t *pUs_priv = &pUsCtx->wls_us_private;
211
212     PLIB_DEBUG("wls_create_us_ctx for %d client\n", pDrv_ctx->nWlsClients);
213     memset(pUsCtx, 0, sizeof (wls_us_ctx_t));
214
215     SFL_DefQueue(&pUsCtx->ul_free_block_pq, pUsCtx->ul_free_block_storage,
216         UL_FREE_BLOCK_QUEUE_SIZE * sizeof (void*));
217     WLS_MsgDefineQueue(&pUsCtx->get_queue, pUsCtx->get_storage, WLS_GET_QUEUE_N_ELEMENTS, 0);
218     WLS_MsgDefineQueue(&pUsCtx->put_queue, pUsCtx->put_storage, WLS_PUT_QUEUE_N_ELEMENTS, 0);
219
220     memset(pUs_priv, 0, sizeof (wls_us_priv_t));
221     if (sem_init(&pUs_priv->sema.sem, 1, 0)) {
222         PLIB_ERR("Failed to initialize semaphore %s\n", strerror(errno));
223         memset(pUsCtx, 0, sizeof (wls_us_ctx_t));
224         wls_mutex_unlock(&pDrv_ctx->mng_mutex);
225         return NULL;
226     }
227     rte_atomic16_init(&pUs_priv->sema.is_irq);
228
229     idx = pDrv_ctx->nWlsClients;
230     pDrv_ctx->p_wls_us_ctx[idx].dst_user_va = (uint64_t) & pDrv_ctx->p_wls_us_ctx[idx ^ 1];
231     PLIB_INFO("link: %d <-> %d\n", idx, idx ^ 1);
232
233     pUs_priv->pid = getpid();
234     pDrv_ctx->nWlsClients++;
235
236     wls_mutex_unlock(&pDrv_ctx->mng_mutex);
237     return pUsCtx;
238 }
239
240 static int wls_destroy_us_ctx(wls_us_ctx_t *pUsCtx, wls_drv_ctx_t *pDrv_ctx)
241 {
242     wls_us_priv_t* pUs_priv = NULL;
243
244     wls_mutex_lock(&pDrv_ctx->mng_mutex);
245     if (pDrv_ctx->p_wls_us_ctx[0].wls_us_private.pid
246         && pDrv_ctx->p_wls_us_ctx[1].wls_us_private.pid) {
247         PLIB_INFO("un-link: 0 <-> 1\n");
248         pDrv_ctx->p_wls_us_ctx[0].dst_user_va = 0ULL;
249         pDrv_ctx->p_wls_us_ctx[1].dst_user_va = 0ULL;
250     }
251
252
253     if (pUsCtx) {
254         pUs_priv = (wls_us_priv_t*) & pUsCtx->wls_us_private;
255         if (pUs_priv) {
256             sem_destroy(&pUs_priv->sema.sem);
257             memset(pUsCtx, 0, sizeof (wls_us_ctx_t));
258             pDrv_ctx->nWlsClients--;
259         }
260     }
261
262     wls_mutex_unlock(&pDrv_ctx->mng_mutex);
263     return 0;
264 }
265
266 static int wls_destroy_us_ctx1(wls_us_ctx_t *pUsCtx, wls_drv_ctx_t *pDrv_ctx)
267 {
268     wls_us_priv_t* pUs_priv = NULL;
269
270     wls_mutex_lock(&pDrv_ctx->mng_mutex);
271     if (pDrv_ctx->p_wls_us_ctx[2].wls_us_private.pid
272         && pDrv_ctx->p_wls_us_ctx[3].wls_us_private.pid) {
273         PLIB_INFO("un-link: 2 <-> 3\n");
274         pDrv_ctx->p_wls_us_ctx[2].dst_user_va = 0ULL;
275         pDrv_ctx->p_wls_us_ctx[3].dst_user_va = 0ULL;
276     }
277
278
279     if (pUsCtx) {
280         pUs_priv = (wls_us_priv_t*) & pUsCtx->wls_us_private;
281         if (pUs_priv) {
282             sem_destroy(&pUs_priv->sema.sem);
283             memset(pUsCtx, 0, sizeof (wls_us_ctx_t));
284             pDrv_ctx->nWlsClients--;
285         }
286     }
287
288     wls_mutex_unlock(&pDrv_ctx->mng_mutex);
289     return 0;
290 }
291
292 static int wls_wake_up_user_thread(char *buf, wls_sema_priv_t *semap)
293 {
294     if (unlikely(rte_atomic16_read(&semap->is_irq) >= FIFO_LEN))
295         return 0;
296
297     unsigned int put = semap->drv_block_put + 1;
298     if (put >= FIFO_LEN)
299         put = 0;
300     memcpy(&semap->drv_block[put], buf, sizeof (wls_wait_req_t));
301     semap->drv_block_put = put;
302     rte_atomic16_inc(&semap->is_irq);
303     PLIB_DEBUG("PUT: put=%d get=%d T=%lu is_irq=%d\n",
304             semap->drv_block_put, semap->drv_block_get,
305             semap->drv_block[put].start_time, rte_atomic16_read(&semap->is_irq));
306     sem_post(&semap->sem);
307     return 0;
308 }
309
310 static int wls_process_put(wls_us_ctx_t *src, wls_us_ctx_t *dst)
311 {
312     int ret = 0;
313     WLS_MSG_HANDLE hMsg;
314     int n = 0;
315
316     wls_us_priv_t* pDstPriv = NULL;
317     wls_wait_req_t drv_block;
318
319     if (NULL == src || NULL == dst) {
320         PLIB_DEBUG("Bad input addresses\n");
321         return -1;
322     }
323
324     n = WLS_GetNumItemsInTheQueue(&src->put_queue);
325
326     while (n--) {
327         if (WLS_MsgDequeue(&src->put_queue, &hMsg, NULL, (void*) src) == FALSE) {
328             PLIB_ERR("WLS_MsgDequeue src failed\n");
329             ret = -1;
330             break;
331         }
332         PLIB_DEBUG("WLS_Get %lx %d type %d\n", (U64) hMsg.pIaPaMsg, hMsg.MsgSize, hMsg.TypeID);
333         if (WLS_MsgEnqueue(&dst->get_queue, hMsg.pIaPaMsg, hMsg.MsgSize, hMsg.TypeID,
334                 hMsg.flags, NULL, (void*) dst) == FALSE) { // try to send
335             if (WLS_MsgEnqueue(&src->put_queue, hMsg.pIaPaMsg, hMsg.MsgSize, hMsg.TypeID,
336                     hMsg.flags, NULL, (void*) src) == FALSE) { // return back
337                 PLIB_ERR("wls_process_put: Cannot return block to back to queue \n");
338                 ret = -1;
339             }
340             break;
341         }
342     }
343
344     if (dst->wls_us_private.pid) {
345         pDstPriv = (wls_us_priv_t*) & dst->wls_us_private;
346
347         drv_block.start_time = wls_rdtsc();
348         pDstPriv->NeedToWakeUp = 1;
349         wls_wake_up_user_thread((char *) &drv_block, &pDstPriv->sema);
350     } else
351         ret = -1;
352
353     return ret;
354 }
355
356 static int wls_process_wakeup(void* h)
357 {
358     wls_us_ctx_t* pWls_us = (wls_us_ctx_t*) h;
359     int ret = 0;
360     wls_wait_req_t drv_block;
361     if (wls_check_ctx(h))
362         return -1;
363     if (!pWls_us->wls_us_private.pid) {
364         PLIB_ERR("wakeup failed");
365         return -1;
366     }
367     drv_block.start_time = wls_rdtsc();
368     wls_wake_up_user_thread((char *) &drv_block, &pWls_us->wls_us_private.sema);
369
370     return ret;
371 }
372
373 static int wls_process_wakeup1(void* h)
374 {
375     wls_us_ctx_t* pWls_us = (wls_us_ctx_t*) h;
376     int ret = 0;
377     wls_wait_req_t drv_block;
378     if (wls_check_ctx1(h))
379         return -1;
380     if (!pWls_us->wls_us_private.pid) {
381         PLIB_ERR("wakeup failed");
382         return -1;
383     }
384     drv_block.start_time = wls_rdtsc();
385     wls_wake_up_user_thread((char *) &drv_block, &pWls_us->wls_us_private.sema);
386
387     return ret;
388 }
389
390 static int wls_wait(wls_sema_priv_t *priv)
391 {
392     if (!rte_atomic16_read(&priv->is_irq)) {
393         if (sem_wait(&priv->sem) || !rte_atomic16_read(&priv->is_irq)) {
394             return -1;
395         }
396     }
397
398     rte_atomic16_dec(&priv->is_irq);
399
400     if (priv->drv_block_put != priv->drv_block_get) {
401         unsigned int get = priv->drv_block_get + 1;
402
403         if (get >= FIFO_LEN)
404             get = 0;
405
406         priv->drv_block_get = get;
407
408         PLIB_DEBUG("GET: put=%d get=%d T=%lu is_irq=%d\n",
409                 priv->drv_block_put, priv->drv_block_get,
410                 priv->drv_block[get].start_time, rte_atomic16_read(&priv->is_irq));
411     } else {
412         PLIB_DEBUG("[wrong computation of queueing\n");
413     }
414
415     return 0;
416 }
417
418 static int wls_process_wait(void* h)
419 {
420     wls_us_ctx_t* pUsCtx = (wls_us_ctx_t*) h;
421
422     if (wls_check_ctx(h))
423         return -1;
424
425     if (pUsCtx == NULL) {
426         PLIB_ERR("Wait failed on User context");
427         return -1;
428     }
429
430
431     if (!pUsCtx->wls_us_private.pid) {
432         PLIB_ERR("Wait failed");
433         return -1;
434     }
435     pUsCtx->wls_us_private.isWait = 1;
436     wls_wait(&pUsCtx->wls_us_private.sema);
437     pUsCtx->wls_us_private.isWait = 0;
438     return WLS_GetNumItemsInTheQueue(&pUsCtx->get_queue);
439 }
440
441 static int wls_process_wait1(void* h)
442 {
443     wls_us_ctx_t* pUsCtx = (wls_us_ctx_t*) h;
444
445     if (wls_check_ctx1(h))
446         return -1;
447
448     if (pUsCtx == NULL) {
449         PLIB_ERR("Wait failed on User context");
450         return -1;
451     }
452
453
454     if (!pUsCtx->wls_us_private.pid) {
455         PLIB_ERR("Wait failed");
456         return -1;
457     }
458     pUsCtx->wls_us_private.isWait = 1;
459     wls_wait(&pUsCtx->wls_us_private.sema);
460     pUsCtx->wls_us_private.isWait = 0;
461     return WLS_GetNumItemsInTheQueue(&pUsCtx->get_queue);
462 }
463
464
465 void* WLS_Open(const char *ifacename, unsigned int mode, unsigned long long nWlsMemorySize)
466 {
467     wls_us_ctx_t* pWls_us = NULL;
468     int i, len;
469     char temp[WLS_DEV_SHM_NAME_LEN] = {0};
470     uint8_t *pMemZone;
471
472     gethugepagesizes(&hugePageSize, 1);
473
474     if (wls_us_ctx)
475         return wls_us_ctx;
476
477     strncpy(temp, ifacename, WLS_DEV_SHM_NAME_LEN - 1);
478     PLIB_INFO("Open %s (DPDK memzone)\n", temp);
479
480     static const struct rte_memzone *mng_memzone;
481     mng_memzone = rte_memzone_lookup(temp);
482     if ((mng_memzone == NULL)&&(RTE_PROC_PRIMARY==rte_eal_process_type())) {
483         wls_initialize(temp, nWlsMemorySize);
484     }
485
486     mng_memzone = rte_memzone_lookup(temp);
487     if (mng_memzone == NULL) {
488         PLIB_ERR("Cannot initialize wls shared memory: %s\n", temp);
489         return NULL;
490     }
491
492     pMemZone = ((uint8_t *)mng_memzone->addr) + nWlsMemorySize;
493
494     PLIB_INFO("WLS_Open %p\n", pMemZone);
495     if ((pWls_us = wls_create_us_ctx((wls_drv_ctx_t *)pMemZone)) == NULL) {
496         PLIB_ERR("WLS_Open failed to create context\n");
497         return NULL;
498     }
499
500     PLIB_DEBUG("Local: pWls_us %p\n", pWls_us);
501
502     pWls_us->padding_wls_us_user_space_va = 0LL;
503     pWls_us->wls_us_user_space_va = pWls_us;
504     pWls_us->wls_us_ctx_size = sizeof (*pWls_us);
505     gWlsMemorySize = nWlsMemorySize;
506
507     wls_mutex_init(&wls_put_lock);
508     wls_mutex_init(&wls_get_lock);
509
510     pWls_us->mode = mode;
511     pWls_us->secmode = WLS_SEC_NA;
512     pWls_us->dualMode = WLS_SINGLE_MODE;
513     PLIB_INFO("Mode %d\n", pWls_us->mode);
514
515     PLIB_INFO("WLS shared management memzone: %s\n", temp);
516     strncpy(pWls_us->wls_dev_name, temp, WLS_DEV_SHM_NAME_LEN - 1);
517     wls_us_ctx = pWls_us;
518
519     return wls_us_ctx;
520 }
521
522 void* WLS_Open_Dual(const char *ifacename, unsigned int mode, unsigned long long nWlsMemorySize, void** handle1)
523 {
524     wls_us_ctx_t* pWls_us = NULL;
525     wls_us_ctx_t* pWls_us1 = NULL;
526     int i, len;
527     char temp[WLS_DEV_SHM_NAME_LEN] = {0};
528     uint8_t *pMemZone;
529
530     gethugepagesizes(&hugePageSize, 1);
531
532     if (wls_us_ctx)
533         return wls_us_ctx;
534
535     strncpy(temp, ifacename, WLS_DEV_SHM_NAME_LEN - 1);
536     PLIB_INFO("Open %s (DPDK memzone)\n", temp);
537
538     static const struct rte_memzone *mng_memzone;
539     mng_memzone = rte_memzone_lookup(temp);
540     if ((mng_memzone == NULL)&&(RTE_PROC_PRIMARY==rte_eal_process_type())) {
541         wls_initialize(temp, nWlsMemorySize);
542     }
543
544     mng_memzone = rte_memzone_lookup(temp);
545     if (mng_memzone == NULL) {
546         PLIB_ERR("Cannot initialize wls shared memory: %s\n", temp);
547         return NULL;
548     }
549
550     pMemZone = ((uint8_t *)mng_memzone->addr) + nWlsMemorySize;
551     PLIB_INFO("nWlsMemorySize is %llu\n", nWlsMemorySize);
552     PLIB_INFO("WLS_Open Dual 1 %p\n", pMemZone);
553      if ((pWls_us = wls_create_us_ctx((wls_drv_ctx_t *)pMemZone)) == NULL) {
554         PLIB_ERR("WLS_Open Dual 1 failed to create context\n");
555         return NULL;
556      }
557      else
558      {    
559         PLIB_DEBUG("Local: pWls_us %p\n", pWls_us);
560  
561         pWls_us->padding_wls_us_user_space_va = 0LL;
562         pWls_us->wls_us_user_space_va = pWls_us;
563         pWls_us->wls_us_ctx_size = sizeof (*pWls_us);
564         gWlsMemorySize = nWlsMemorySize;
565
566         wls_mutex_init(&wls_put_lock);
567         wls_mutex_init(&wls_get_lock);
568
569         pWls_us->mode = mode;
570         pWls_us->secmode = WLS_SEC_MASTER;
571         pWls_us->dualMode = WLS_DUAL_MODE;
572         PLIB_INFO("Mode %d SecMode %d \n", pWls_us->mode, pWls_us->secmode);
573
574         PLIB_INFO("WLS shared management memzone 1: %s\n", temp);
575         strncpy(pWls_us->wls_dev_name, temp, WLS_DEV_SHM_NAME_LEN - 1);
576         wls_us_ctx = pWls_us;
577             PLIB_INFO("pWLs_us is %p\n", wls_us_ctx);
578             *handle1 = pWls_us;  // Now the first context is for L1-FT_iapi
579      }
580      
581      // Create second context to support the second wls shared memory interface
582      if ((pWls_us1 = wls_create_us_ctx((wls_drv_ctx_t *)pMemZone)) == NULL) {
583         PLIB_ERR("WLS_Open Dual failed to create context 1\n");
584         return NULL;
585      }
586      else
587      {
588         PLIB_DEBUG("Local: pWls_us1 %p\n", pWls_us1);
589         pWls_us1->padding_wls_us_user_space_va = 0LL;
590         pWls_us1->wls_us_user_space_va = pWls_us1;
591         pWls_us1->wls_us_ctx_size = sizeof (*pWls_us1);
592         gWlsMemorySize = nWlsMemorySize;
593
594         wls_mutex_init(&wls_put_lock1);
595         wls_mutex_init(&wls_get_lock1);
596
597         pWls_us1->mode = mode;
598         pWls_us1->secmode = WLS_SEC_NA;
599         PLIB_INFO("Mode %d Secmode %d\n", pWls_us1->mode, pWls_us1->secmode);
600
601         PLIB_INFO("WLS shared management memzone 2: %s\n", temp);
602         strncpy(pWls_us1->wls_dev_name, temp, WLS_DEV_SHM_NAME_LEN - 1);
603         wls_us_ctx1 = pWls_us1; // Now the second context is for the L2-FT_fapi
604             PLIB_INFO("pWLs_us1 is %p\n", wls_us_ctx1);
605
606      }
607
608     return wls_us_ctx1; // returning second context preserves the L2 legacy code
609 }
610
611 int WLS_Ready(void* h)
612 {
613     wls_us_ctx_t *pWls_us = (wls_us_ctx_t*) h;
614     wls_us_ctx_t *pWls_usRem = (wls_us_ctx_t*) pWls_us->dst_user_va;
615
616     if (!wls_us_ctx) {
617         PLIB_ERR("Library was not opened\n");
618         return -1;
619     }
620
621     if (pWls_usRem->wls_us_private.pid) {
622         return 0;
623     }
624     return -1;
625 }
626
627 int WLS_Ready1(void* h)
628 {
629     wls_us_ctx_t *pWls_us = (wls_us_ctx_t*) h;
630     wls_us_ctx_t *pWls_usRem = (wls_us_ctx_t*) pWls_us->dst_user_va;
631
632     if (!wls_us_ctx1) {
633         PLIB_ERR("Library was not opened for Context 1\n");
634         return -1;
635     }
636
637     if (pWls_usRem->wls_us_private.pid) {
638         return 0;
639     }
640     return -1;
641 }
642
643 int WLS_Close(void* h)
644 {
645     wls_us_ctx_t* pWls_us = (wls_us_ctx_t*) h;
646     int ret = 0;
647     uint8_t *pMemZone;
648     wls_drv_ctx_t *pDrv_ctx;
649
650     if (!wls_us_ctx) {
651         PLIB_ERR("Library was not opened\n");
652         return -1;
653     }
654
655     if (wls_check_ctx(h))
656         return -1;
657
658     static const struct rte_memzone *mng_memzone;
659     mng_memzone = rte_memzone_lookup(pWls_us->wls_dev_name);
660     if (mng_memzone == NULL) {
661         PLIB_ERR("Cannot find mng memzone: %s %s\n",
662                     pWls_us->wls_dev_name, rte_strerror(rte_errno));
663         return -1;
664     }
665
666     pMemZone = ((uint8_t *)mng_memzone->addr) + gWlsMemorySize;
667     pDrv_ctx = (wls_drv_ctx_t *)pMemZone;
668
669     PLIB_INFO("WLS_Close\n");
670     if ((ret = wls_destroy_us_ctx(pWls_us, pDrv_ctx)) < 0) {
671         PLIB_ERR("Close failed [%d]\n", ret);
672         return ret;
673     }
674
675     wls_mutex_destroy(&wls_put_lock);
676     wls_mutex_destroy(&wls_get_lock);
677
678     wls_us_ctx = NULL;
679
680     if (0 == pDrv_ctx->nWlsClients) {
681         wls_mutex_destroy(&pDrv_ctx->mng_mutex);
682         rte_memzone_free(mng_memzone);
683     }
684     return 0;
685 }
686
687 int WLS_Close1(void* h)
688 {
689     wls_us_ctx_t* pWls_us = (wls_us_ctx_t*) h;
690     int ret = 0;
691     uint8_t *pMemZone;
692     wls_drv_ctx_t *pDrv_ctx;
693
694     if (!wls_us_ctx1) {
695         PLIB_ERR("Library was not opened\n");
696         return -1;
697     }
698
699     if (wls_check_ctx1(h))
700         return -1;
701
702     static const struct rte_memzone *mng_memzone;
703     mng_memzone = rte_memzone_lookup(pWls_us->wls_dev_name);
704     if (mng_memzone == NULL) {
705         PLIB_ERR("Cannot find mng memzone: %s %s\n",
706                     pWls_us->wls_dev_name, rte_strerror(rte_errno));
707         return -1;
708     }
709
710     pMemZone = ((uint8_t *)mng_memzone->addr) + gWlsMemorySize;
711     pDrv_ctx = (wls_drv_ctx_t *)pMemZone;
712
713     PLIB_INFO("WLS_Close1\n");
714     if ((ret = wls_destroy_us_ctx1(pWls_us, pDrv_ctx)) < 0) {
715         PLIB_ERR("Close failed [%d]\n", ret);
716         return ret;
717     }
718
719     wls_mutex_destroy(&wls_put_lock1);
720     wls_mutex_destroy(&wls_get_lock1);
721
722     wls_us_ctx1 = NULL;
723
724     if (0 == pDrv_ctx->nWlsClients) {
725         wls_mutex_destroy(&pDrv_ctx->mng_mutex);
726         rte_memzone_free(mng_memzone);
727     }
728     return 0;
729 }
730
731 void* WLS_Alloc(void* h, unsigned int size)
732 {
733     wls_us_ctx_t* pWls_us = (wls_us_ctx_t*) h;
734     static const struct rte_memzone *mng_memzone;
735     long nHugePage;
736     void *pvirtAddr = NULL;
737     int count;
738
739     if ((NULL != hp_memzone)&&(pWls_us->dualMode != WLS_DUAL_MODE)) {
740         PLIB_ERR("Memory zone already reserved\n");
741         return hp_memzone->addr;
742     }
743
744     hugepage_tabl_t* pHugePageTlb = &pWls_us->hugepageTbl[0];
745     hugepage_tabl_t* pHugePageTlb1 = &pWls_us->hugepageTbl[1];
746     hugepage_tabl_t* pHugePageTlb2 = &pWls_us->hugepageTbl[2];
747
748     PLIB_INFO("hugePageSize on the system is %ld\n", hugePageSize);
749
750     /* calculate total number of hugepages */
751     nHugePage = DIV_ROUND_OFFSET(size, hugePageSize);
752
753     if (nHugePage >= MAX_N_HUGE_PAGES) {
754         PLIB_INFO("not enough hugepages: need %ld  system has %d\n", nHugePage, MAX_N_HUGE_PAGES);
755         return NULL;
756     }
757
758     mng_memzone = rte_memzone_lookup(pWls_us->wls_dev_name);
759     if (mng_memzone == NULL) {
760         PLIB_ERR("Cannot initialize wls shared memory: %s\n", pWls_us->wls_dev_name);
761         return NULL;
762     }
763
764     hp_memzone = (struct rte_memzone *)mng_memzone;
765     pvirtAddr = (void *)hp_memzone->addr;
766
767     if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
768         memset(pvirtAddr, 0, sizeof (wls_drv_ctx_t));
769     }
770
771     for (count = 0; count < nHugePage; count++) {
772         /*Increment virtual address to next hugepage to create table*/
773         pHugePageTlb[count].pageVa = ((unsigned char*) pvirtAddr + \
774                                                 (count * hugePageSize));
775         /*Creating dummy page fault in process for each page
776                                                 inorder to get pagemap*/
777         *(unsigned char*) pHugePageTlb[count].pageVa = 1;
778
779         if (wls_VirtToIova((uint64_t*) pHugePageTlb[count].pageVa,
780                 &pHugePageTlb[count].pagePa) == -1) {
781             PLIB_ERR("Virtual to physical conversion failed\n");
782             return NULL;
783         }
784     }
785
786     PLIB_DEBUG("count is %d, pHugePageTlb->pageVa is %p  pHugePageTlb1->pageVa is %p  pHugePageTlb2->pageVa is %p\n",count, pHugePageTlb->pageVa, pHugePageTlb1->pageVa, pHugePageTlb2->pageVa);
787     PLIB_INFO("WLS_Alloc [%d] bytes\n", size);
788
789     pWls_us->HugePageSize = (uint32_t) hugePageSize;
790     pWls_us->alloc_buffer = pvirtAddr;
791     pWls_us->alloc_size = (uint32_t) (nHugePage * hugePageSize);
792
793     if ((pWls_us->mode == WLS_MASTER_CLIENT)||(pWls_us->secmode == WLS_SEC_MASTER)) {
794         wls_us_ctx_t *pWls_usRem = (wls_us_ctx_t*) pWls_us->dst_user_va;
795         PLIB_INFO("Connecting to remote peer ...\n");
796         while (pWls_usRem->wls_us_private.pid == 0) { // wait for slave
797         }
798
799         PLIB_INFO("Connected to remote peer\n");
800         pWls_us->dst_user_va = (uint64_t) pWls_usRem;
801     }
802     return pvirtAddr;
803 }
804
805 int WLS_Free(void* h, PVOID pMsg)
806 {
807     static const struct rte_memzone *mng_memzone;
808     wls_us_ctx_t* pWls_us = (wls_us_ctx_t*) h;
809     wls_drv_ctx_t *pDrv_ctx;
810
811     mng_memzone = rte_memzone_lookup(pWls_us->wls_dev_name);
812     if (mng_memzone == NULL) {
813         PLIB_ERR("Cannot find mng memzone: %s %s\n",
814                     pWls_us->wls_dev_name, rte_strerror(rte_errno));
815         return -1;
816     }
817     pDrv_ctx = mng_memzone->addr;
818
819     if (pMsg !=  pWls_us->alloc_buffer) {
820         PLIB_ERR("incorrect pMsg %p [expected %p]\n", pMsg, pWls_us->alloc_buffer);
821         return -1;
822     }
823
824     if ((pWls_us->mode == WLS_MASTER_CLIENT)||(pWls_us->mode == WLS_SEC_MASTER)) {
825         if (pWls_us->dst_user_va) {
826             pWls_us->dst_user_va = 0;
827         }
828     }
829
830     PLIB_DEBUG("WLS_Free %s\n", shm_name);
831     if ( (1 == pDrv_ctx->nWlsClients) && hp_memzone)
832         hp_memzone = NULL;
833     return 0;
834 }
835
836 int WLS_Put(void *h, unsigned long long pMsg, unsigned int MsgSize, unsigned short MsgTypeID, unsigned short Flags)
837 {
838     wls_us_ctx_t* pWls_us = (wls_us_ctx_t*) h;
839     int ret = 0;
840     unsigned short nFlags = Flags & (~WLS_TF_URLLC);
841
842     if (wls_check_ctx(h))
843         return -1;
844
845     if (!WLS_IS_ONE_HUGE_PAGE(pMsg, MsgSize, hugePageSize)) {
846         PLIB_ERR("WLS_Put input error: buffer is crossing 2MB page boundary %lx size %u\n",
847                 (U64) pMsg, MsgSize);
848     }
849
850     wls_mutex_lock(&wls_put_lock);
851
852     if ((WLS_FLAGS_MASK & nFlags)) { // multi block transaction
853         if (nFlags & WLS_TF_SYN) {
854             PLIB_DEBUG("WLS_SG_FIRST\n");
855             if (WLS_MsgEnqueue(&pWls_us->put_queue, pMsg, MsgSize, MsgTypeID,
856                     Flags, NULL, (void*) pWls_us)) {
857                 PLIB_DEBUG("WLS_Get %lx %d type %d\n", (U64) pMsg, MsgSize, MsgTypeID);
858             }
859         } else if ((nFlags & WLS_TF_SCATTER_GATHER)
860                     && !(nFlags & WLS_TF_SYN)
861                     && !(nFlags & WLS_TF_FIN)) {
862             PLIB_DEBUG("WLS_SG_NEXT\n");
863             if (WLS_MsgEnqueue(&pWls_us->put_queue, pMsg, MsgSize, MsgTypeID,
864                     Flags, NULL, (void*) pWls_us)) {
865                 PLIB_DEBUG("WLS_Put %lx %d type %d\n", (U64) pMsg, MsgSize, MsgTypeID);
866             }
867         } else if (nFlags & WLS_TF_FIN) {
868             if (WLS_MsgEnqueue(&pWls_us->put_queue, pMsg, MsgSize, MsgTypeID,
869                     Flags, NULL, (void*) pWls_us)) {
870                 PLIB_DEBUG("WLS_Put %lx %d type %d\n", (U64) pMsg, MsgSize, MsgTypeID);
871             }
872
873             PLIB_DEBUG("List: call wls_process_put\n");
874             if (pWls_us->dst_user_va) {
875                 if ((ret = wls_process_put(pWls_us, (wls_us_ctx_t*) pWls_us->dst_user_va)) < 0) {
876                     PLIB_ERR("Put failed [%d]\n", ret);
877                     wls_mutex_unlock(&wls_put_lock);
878                     return -1;
879                 }
880             }
881         } else
882             PLIB_ERR("unsupported flags %x\n", WLS_FLAGS_MASK & Flags);
883     } else { // one block transaction
884         if (WLS_MsgEnqueue(&pWls_us->put_queue, pMsg, MsgSize, MsgTypeID,
885                 Flags, NULL, (void*) pWls_us)) {
886             PLIB_DEBUG("WLS_Put %lx %d type %d\n", (U64) pMsg, MsgSize, MsgTypeID);
887         }
888
889         PLIB_DEBUG("One block: call wls_process_put\n");
890         if (likely(pWls_us->dst_user_va)) {
891             if ((ret = wls_process_put(pWls_us, (wls_us_ctx_t*) pWls_us->dst_user_va)) < 0) {
892                 PLIB_ERR("Put failed [%d]\n", ret);
893                 wls_mutex_unlock(&wls_put_lock);
894                 return -1;
895             }
896         } else {
897             PLIB_ERR("Destination address is empty\n");
898             wls_mutex_unlock(&wls_put_lock);
899             return -1;
900         }
901     }
902     wls_mutex_unlock(&wls_put_lock);
903
904     return 0;
905 }
906
907 int WLS_Put1(void *h, unsigned long long pMsg, unsigned int MsgSize, unsigned short MsgTypeID, unsigned short Flags)
908 {
909     wls_us_ctx_t* pWls_us = (wls_us_ctx_t*) h;
910     int ret = 0;
911     unsigned short nFlags = Flags & (~WLS_TF_URLLC);    
912
913     if (wls_check_ctx1(h))
914         return -1;
915
916     if (!WLS_IS_ONE_HUGE_PAGE(pMsg, MsgSize, hugePageSize)) {
917         PLIB_ERR("WLS_Put input error: buffer is crossing 2MB page boundary %lx size %u\n",
918                 (U64) pMsg, MsgSize);
919     }
920
921     wls_mutex_lock(&wls_put_lock1);
922
923     if ((WLS_FLAGS_MASK & nFlags)) { // multi block transaction
924         if (nFlags & WLS_TF_SYN) {
925             PLIB_DEBUG("WLS_SG_FIRST\n");
926             if (WLS_MsgEnqueue(&pWls_us->put_queue, pMsg, MsgSize, MsgTypeID,
927                     Flags, NULL, (void*) pWls_us)) {
928                 PLIB_DEBUG("WLS_Get %lx %d type %d\n", (U64) pMsg, MsgSize, MsgTypeID);
929             }
930         } else if ((nFlags & WLS_TF_SCATTER_GATHER)
931                     && !(nFlags & WLS_TF_SYN)
932                     && !(nFlags & WLS_TF_FIN)) {
933             PLIB_DEBUG("WLS_SG_NEXT\n");
934             if (WLS_MsgEnqueue(&pWls_us->put_queue, pMsg, MsgSize, MsgTypeID,
935                     Flags, NULL, (void*) pWls_us)) {
936                 PLIB_DEBUG("WLS_Put %lx %d type %d\n", (U64) pMsg, MsgSize, MsgTypeID);
937             }
938         } else if (nFlags & WLS_TF_FIN) {
939             if (WLS_MsgEnqueue(&pWls_us->put_queue, pMsg, MsgSize, MsgTypeID,
940                     Flags, NULL, (void*) pWls_us)) {
941                 PLIB_DEBUG("WLS_Put %lx %d type %d\n", (U64) pMsg, MsgSize, MsgTypeID);
942             }
943
944             PLIB_DEBUG("List: call wls_process_put\n");
945             if (pWls_us->dst_user_va) {
946                 if ((ret = wls_process_put(pWls_us, (wls_us_ctx_t*) pWls_us->dst_user_va)) < 0) {
947                     PLIB_ERR("Put failed [%d]\n", ret);
948                     wls_mutex_unlock(&wls_put_lock1);
949                     return -1;
950                 }
951             }
952         } else
953             PLIB_ERR("unsupported flags %x\n", WLS_FLAGS_MASK & Flags);
954     } else { // one block transaction
955         if (WLS_MsgEnqueue(&pWls_us->put_queue, pMsg, MsgSize, MsgTypeID,
956                 Flags, NULL, (void*) pWls_us)) {
957             PLIB_DEBUG("WLS_Put %lx %d type %d\n", (U64) pMsg, MsgSize, MsgTypeID);
958         }
959
960         PLIB_DEBUG("One block: call wls_process_put\n");
961         if (likely(pWls_us->dst_user_va)) {
962             if ((ret = wls_process_put(pWls_us, (wls_us_ctx_t*) pWls_us->dst_user_va)) < 0) {
963                 PLIB_ERR("Put failed [%d]\n", ret);
964                 wls_mutex_unlock(&wls_put_lock1);
965                 return -1;
966             }
967         } else {
968             PLIB_ERR("Destination address is empty\n");
969             wls_mutex_unlock(&wls_put_lock1);
970             return -1;
971         }
972     }
973     wls_mutex_unlock(&wls_put_lock1);
974
975     return 0;
976 }
977
978 int WLS_Check(void* h)
979 {
980     wls_us_ctx_t* pWls_us = (wls_us_ctx_t*) h;
981
982     if (wls_check_ctx(h))
983         return 0;
984
985     return WLS_GetNumItemsInTheQueue(&pWls_us->get_queue);
986 }
987
988 int WLS_Check1(void* h)
989 {
990     wls_us_ctx_t* pWls_us = (wls_us_ctx_t*) h;
991
992     if (wls_check_ctx1(h))
993         return 0;
994
995     return WLS_GetNumItemsInTheQueue(&pWls_us->get_queue);
996 }
997
998 unsigned long long WLS_Get(void* h, unsigned int *MsgSize, unsigned short *MsgTypeID, unsigned short *Flags)
999 {
1000     wls_us_ctx_t* pWls_us = (wls_us_ctx_t*) h;
1001     WLS_MSG_HANDLE hMsg;
1002     uint64_t pMsg = (uint64_t) NULL;
1003
1004     if (wls_check_ctx(h))
1005     {
1006         PLIB_ERR("WLS_Get fails wls_check_ctx\n");
1007         return 0;
1008     }
1009
1010     wls_mutex_lock(&wls_get_lock);
1011
1012     if (WLS_MsgDequeue(&pWls_us->get_queue, &hMsg, NULL, (void*) pWls_us)) {
1013         PLIB_DEBUG("WLS_Get %lx %d type %d\n", (U64) hMsg.pIaPaMsg, hMsg.MsgSize, hMsg.TypeID);
1014         pMsg = hMsg.pIaPaMsg;
1015         *MsgSize = hMsg.MsgSize;
1016         *MsgTypeID = hMsg.TypeID;
1017         *Flags = hMsg.flags;
1018     }
1019
1020     wls_mutex_unlock(&wls_get_lock);
1021
1022     return pMsg;
1023 }
1024
1025 unsigned long long WLS_Get1(void* h, unsigned int *MsgSize, unsigned short *MsgTypeID, unsigned short *Flags)
1026 {
1027     wls_us_ctx_t* pWls_us = (wls_us_ctx_t*) h;
1028     WLS_MSG_HANDLE hMsg;
1029     uint64_t pMsg = (uint64_t) NULL;
1030
1031     if (wls_check_ctx1(h))
1032         return 0;
1033
1034     wls_mutex_lock(&wls_get_lock1);
1035
1036     if (WLS_MsgDequeue(&pWls_us->get_queue, &hMsg, NULL, (void*) pWls_us)) {
1037         PLIB_DEBUG("WLS_Get %lx %d type %d\n", (U64) hMsg.pIaPaMsg, hMsg.MsgSize, hMsg.TypeID);
1038         pMsg = hMsg.pIaPaMsg;
1039         *MsgSize = hMsg.MsgSize;
1040         *MsgTypeID = hMsg.TypeID;
1041         *Flags = hMsg.flags;
1042     }
1043
1044     wls_mutex_unlock(&wls_get_lock1);
1045
1046     return pMsg;
1047 }
1048
1049 int WLS_WakeUp(void* h)
1050 {
1051     if (!wls_us_ctx) {
1052         PLIB_ERR("Library was not opened\n");
1053         return -1;
1054     }
1055     if (wls_check_ctx(h))
1056         return -1;
1057
1058     PLIB_DEBUG("WLS_WakeUp\n");
1059
1060     return wls_process_wakeup(h);
1061
1062
1063     return 0;
1064 }
1065
1066 int WLS_WakeUp1(void* h)
1067 {
1068     if (!wls_us_ctx1) {
1069         PLIB_ERR("Library was not opened\n");
1070         return -1;
1071     }
1072     if (wls_check_ctx1(h))
1073         return -1;
1074
1075     PLIB_DEBUG("WLS_WakeUp1\n");
1076
1077     return wls_process_wakeup1(h);
1078
1079
1080     return 0;
1081 }
1082
1083 int WLS_Wait(void* h)
1084 {
1085     wls_us_ctx_t* pWls_us = (wls_us_ctx_t*) h;
1086
1087     if (!wls_us_ctx || (wls_us_ctx != pWls_us)) {
1088         PLIB_ERR("Library was not opened\n");
1089         return -1;
1090     }
1091
1092     return wls_process_wait(h);
1093 }
1094
1095 int WLS_Wait1(void* h)
1096 {
1097     wls_us_ctx_t* pWls_us = (wls_us_ctx_t*) h;
1098
1099     if (!wls_us_ctx1 || (wls_us_ctx1 != pWls_us)) {
1100         PLIB_ERR("Library was not opened\n");
1101         return -1;
1102     }
1103
1104     return wls_process_wait1(h);
1105 }
1106
1107 unsigned long long WLS_WGet(void* h, unsigned int *MsgSize, unsigned short *MsgTypeID, unsigned short *Flags)
1108 {
1109     uint64_t pRxMsg = WLS_Get(h, MsgSize, MsgTypeID, Flags);
1110
1111     if (pRxMsg)
1112         return pRxMsg;
1113
1114     WLS_Wait(h);
1115     return WLS_Get(h, MsgSize, MsgTypeID, Flags);
1116 }
1117
1118 unsigned long long WLS_WGet1(void* h, unsigned int *MsgSize, unsigned short *MsgTypeID, unsigned short *Flags)
1119 {
1120     uint64_t pRxMsg = WLS_Get1(h, MsgSize, MsgTypeID, Flags);
1121
1122     if (pRxMsg)
1123         return pRxMsg;
1124
1125     WLS_Wait1(h);
1126     return WLS_Get1(h, MsgSize, MsgTypeID, Flags);
1127 }
1128
1129 unsigned long long WLS_VA2PA(void* h, PVOID pMsg)
1130 {
1131     uint64_t ret = 0;
1132     wls_us_ctx_t* pWls_us = (wls_us_ctx_t*) h;
1133
1134     unsigned long alloc_base;
1135     hugepage_tabl_t* pHugePageTlb;
1136     uint64_t hugePageBase;
1137     uint64_t hugePageOffet;
1138     unsigned int count = 0;
1139
1140     uint64_t HugePageMask = ((unsigned long) pWls_us->HugePageSize - 1);
1141     if (pWls_us->alloc_buffer == NULL) {
1142         PLIB_ERR("WLS_VA2PA: nothing was allocated [%ld]\n", ret);
1143         return (uint64_t) ret;
1144     }
1145
1146     alloc_base = (unsigned long) pWls_us->alloc_buffer;
1147
1148     pHugePageTlb = &pWls_us->hugepageTbl[0];
1149
1150     hugePageBase = (uint64_t) pMsg & ~HugePageMask;
1151     hugePageOffet = (uint64_t) pMsg & HugePageMask;
1152
1153     count = (hugePageBase - alloc_base) / pWls_us->HugePageSize;
1154     PLIB_DEBUG("WLS_VA2PA %lx base %llx off %llx  count %u\n", (unsigned long) pMsg,
1155             (uint64_t) hugePageBase, (uint64_t) hugePageOffet, count);
1156
1157     ret = pHugePageTlb[count].pagePa + hugePageOffet;
1158
1159     //printf("       WLS_VA2PA: %p -> %p   HugePageSize[%d] HugePageMask[%p] count[%d] pagePa[%p] hugePageBase[%p] alloc_buffer[%p] hugePageOffet[%lld]\n",
1160     //    pMsg, (void*)ret, pWls_us->HugePageSize, (void*)HugePageMask, count, (void*)pHugePageTlb[count].pagePa, (void*)hugePageBase, pWls_us->alloc_buffer, hugePageOffet);
1161
1162     return (uint64_t) ret;
1163 }
1164
1165 void* WLS_PA2VA(void* h, unsigned long long pMsg)
1166 {
1167     unsigned long ret = 0;
1168     wls_us_ctx_t* pWls_us = (wls_us_ctx_t*) h;
1169
1170     hugepage_tabl_t* pHugePageTlb;
1171     uint64_t hugePageBase;
1172     uint64_t hugePageOffet;
1173     unsigned int count;
1174     int i;
1175     uint64_t HugePageMask = ((uint64_t) pWls_us->HugePageSize - 1);
1176
1177     if (pWls_us->alloc_buffer == NULL) {
1178         PLIB_ERR("WLS_PA2VA: nothing was allocated [%ld]\n", ret);
1179         return (void*) ret;
1180     }
1181
1182     pHugePageTlb = &pWls_us->hugepageTbl[0];
1183
1184     hugePageBase = (uint64_t) pMsg & ~HugePageMask;
1185     hugePageOffet = (uint64_t) pMsg & HugePageMask;
1186
1187     count = pWls_us->alloc_size / pWls_us->HugePageSize;
1188
1189     PLIB_DEBUG("WLS_PA2VA %llx base %llx off %llx  count %d\n", (uint64_t) pMsg,
1190             (uint64_t) hugePageBase, (uint64_t) hugePageOffet, count);
1191
1192     for (i = 0; i < count; i++) {
1193         if (pHugePageTlb[i].pagePa == hugePageBase) {
1194             ret = (unsigned long) pHugePageTlb[i].pageVa;
1195             ret += hugePageOffet;
1196             return (void*) ret;
1197         }
1198     }
1199
1200     //printf("       WLS_VA2PA: %p -> %p   HugePageSize[%d] HugePageMask[%p] count[%d] pagePa[%p] hugePageBase[%p] alloc_buffer[%p] hugePageOffet[%lld]\n",
1201     //    (void*)pMsg, (void*)ret, pWls_us->HugePageSize, (void*)HugePageMask, count, (void*)pHugePageTlb[count].pagePa, (void*)hugePageBase, pWls_us->alloc_buffer, hugePageOffet);
1202
1203     return (void*) (ret);
1204 }
1205
1206 int WLS_EnqueueBlock(void* h, unsigned long long pMsg)
1207 {
1208     int ret = 0;
1209     wls_us_ctx_t* pWls_us = (wls_us_ctx_t*) h;
1210
1211     if (!wls_us_ctx) {
1212         PLIB_ERR("Library was not opened\n");
1213         return -1;
1214     }
1215
1216
1217     if (pMsg == 0) {
1218         PLIB_ERR("WLS_EnqueueBlock: Null\n");
1219         return -1;
1220     }
1221
1222     if (pWls_us->dst_user_va) {
1223         wls_us_ctx_t* pDstWls_us = (wls_us_ctx_t*) pWls_us->dst_user_va;
1224         ret = SFL_WlsEnqueue(&pDstWls_us->ul_free_block_pq, pMsg, NULL, pWls_us);
1225         if (ret == 1) {
1226             unsigned long* ptr = (unsigned long*) WLS_PA2VA(pWls_us, pMsg);
1227             if (ptr) {
1228                 *ptr = 0xFFFFFFFFFFFFFFFF;
1229             }
1230         }
1231     } else
1232         ret = -1;
1233
1234     PLIB_DEBUG("SFL_WlsEnqueue %d\n", ret);
1235     return ret;
1236 }
1237
1238 int WLS_EnqueueBlock1(void* h, unsigned long long pMsg)
1239 {
1240     int ret = 0;
1241     wls_us_ctx_t* pWls_us = (wls_us_ctx_t*) h;
1242
1243     if (!wls_us_ctx1) {
1244         PLIB_ERR("Library was not opened for a second context\n");
1245         return -1;
1246     }
1247
1248     if (pWls_us->mode == WLS_SLAVE_CLIENT) {
1249         PLIB_ERR("Slave doesn't support memory allocation\n");
1250         return -1;
1251     }
1252
1253     if (pMsg == 0) {
1254         PLIB_ERR("WLS_EnqueueBlock: Null\n");
1255         return -1;
1256     }
1257
1258     if (pWls_us->dst_user_va) {
1259         wls_us_ctx_t* pDstWls_us = (wls_us_ctx_t*) pWls_us->dst_user_va;
1260         ret = SFL_WlsEnqueue(&pDstWls_us->ul_free_block_pq, pMsg, NULL, pWls_us);
1261         if (ret == 1) {
1262             unsigned long* ptr = (unsigned long*) WLS_PA2VA(pWls_us, pMsg);
1263             if (ptr) {
1264                 *ptr = 0xFFFFFFFFFFFFFFFF;
1265             }
1266         }
1267     } else
1268         ret = -1;
1269
1270     PLIB_DEBUG("SFL_WlsEnqueue %d\n", ret);
1271     return ret;
1272 }
1273
1274
1275 unsigned long long WLS_DequeueBlock(void* h)
1276 {
1277     unsigned long long retval = 0;
1278     wls_us_ctx_t* pWls_us = (wls_us_ctx_t*) h;
1279
1280     if ((pWls_us->mode == WLS_SLAVE_CLIENT)&&(pWls_us->secmode==WLS_SEC_NA))
1281     {
1282         // local
1283         return SFL_WlsDequeue(&pWls_us->ul_free_block_pq, NULL, h);
1284     }    
1285     if (!pWls_us->dst_user_va)
1286     {
1287         return retval;
1288     }
1289         // remote
1290     wls_us_ctx_t* pDstWls_us = (wls_us_ctx_t*) pWls_us->dst_user_va;
1291     retval = SFL_WlsDequeue(&pDstWls_us->ul_free_block_pq, NULL, pDstWls_us);
1292     if (retval) {
1293         unsigned long* ptr = (unsigned long*) WLS_PA2VA(pWls_us, retval);
1294         if (ptr) {
1295             if (*ptr != 0xFFFFFFFFFFFFFFFF) {
1296                 PLIB_ERR("WLS_EnqueueBlock: incorrect content pa: 0x%016lx: 0x%016lx\n",
1297                          (unsigned long) retval, *ptr);
1298             }
1299         }
1300     }
1301
1302     return retval;
1303 }
1304
1305 int WLS_NumBlocks(void* h)
1306 {
1307     wls_us_ctx_t* pWls_us = (wls_us_ctx_t*) h;
1308     int n = 0;
1309
1310     if (pWls_us->mode == WLS_SLAVE_CLIENT) {
1311         // local
1312         n = SFL_GetNumItemsInTheQueue(&pWls_us->ul_free_block_pq);
1313     } else if (pWls_us->dst_user_va) {
1314         // remote
1315         wls_us_ctx_t* pDstWls_us = (wls_us_ctx_t*) pWls_us->dst_user_va;
1316         n = SFL_GetNumItemsInTheQueue(&pDstWls_us->ul_free_block_pq);
1317     }
1318
1319     return n;
1320 }