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