Front Haul Interface Library first seed code contribution
[o-du/phy.git] / fhi_lib / app / lls-cu / sample-lls-cu.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 #define _GNU_SOURCE
20 #include <unistd.h>
21 #include <sys/syscall.h>
22 #include <sched.h>
23 #include <assert.h>
24 #include <err.h>
25 #include <libgen.h>
26 #include <sys/time.h>
27 #include <time.h>
28 #include <unistd.h>
29 #include <stdio.h>
30 #include <pthread.h>
31
32 #include "common.h"
33 #include "config.h"
34
35 #ifndef MLOG_ENABLED
36 #include "../../lib/src/mlog_lnx_xRAN.h"
37 #else
38 #include "mlog_lnx.h"
39 #endif
40
41
42 #include "xran_fh_lls_cu.h"
43 //#include "xran_pkt.h"
44 //#include "xran_up_api.h"
45 #include "xran_cp_api.h"
46 #include "xran_sync_api.h"
47 #include "xran_mlog_task_id.h"
48
49 #define SW_FPGA_TOTAL_BUFFER_LEN 4*1024*1024*1024
50 #define SW_FPGA_SEGMENT_BUFFER_LEN 1*1024*1024*1024
51 #define SW_FPGA_FH_TOTAL_BUFFER_LEN 1*1024*1024*1024
52 #define FPGA_TO_SW_PRACH_RX_BUFFER_LEN   (8192)
53
54 #define NSEC_PER_SEC 1000000000
55
56 #define MAX_PKT_BURST (448+4) // 4x14x8
57 #define N_MAX_BUFFER_SEGMENT MAX_PKT_BURST
58
59 #define MAIN_PRIORITY 98
60 #define NUM_OF_SUBFRAME_PER_FRAME (10)
61
62 enum app_state state;
63
64 uint64_t  tick_per_usec;
65 static volatile uint64_t timer_last_irq_tick = 0;
66 static uint64_t tsc_resolution_hz = 0;
67
68 RuntimeConfig startupConfiguration = {0};
69
70 //FH FPGA buffer
71 uint32_t    nFpgaToSW_FTH_RxBufferLen;
72 uint32_t    nFpgaToSW_PRACH_RxBufferLen;
73 uint32_t    nSW_ToFpga_FTH_TxBufferLen;
74
75 static XRANFHINIT xranInit;
76 void * xranHandle = NULL;
77
78 XRANFHCONFIG  xranConf;
79 PXRANFHCONFIG pXranConf = NULL;
80
81 typedef struct
82 {
83     uint32_t phaseFlag   :1;
84     uint32_t NRARFCN     :22;
85     uint32_t SULFreShift :1;
86     uint32_t SULFlag     :1;
87     uint32_t rsv         :7;
88 }FPGAPhaseCompCfg;
89
90 typedef struct XranLibConfig
91 {
92     uint32_t nDriverCoreId;
93     uint32_t nTimingAdvance;
94     uint32_t nFhConfig;
95     uint32_t nFhBufIntFlag;
96     uint32_t nSectorNum;
97     uint32_t nNrOfSlotInSf;
98     uint32_t nNrofSfInFrame;
99     void *   pFthInstanceHandles;
100 }XranLibConfigStruct;
101 typedef enum {
102     XRANFTHTX_OUT = 0,
103     XRANFTHRX_IN,
104     XRANFTHRACH_IN,
105     MAX_SW_XRAN_INTERFACE_NUM
106 }SWXRANInterfaceTypeEnum;
107
108 /*
109  * manage one cell's all Ethernet frames for one DL or UL LTE subframe
110  */
111 typedef struct {
112     /* -1-this subframe is not used in current frame format
113          0-this subframe can be transmitted, i.e., data is ready
114           1-this subframe is waiting transmission, i.e., data is not ready
115          10 - DL transmission missing deadline. When FE needs this subframe data but bValid is still 1,
116         set bValid to 10.
117     */
118     int32_t bValid ; // when UL rx, it is subframe index.
119     int32_t nSegToBeGen;
120     int32_t nSegGenerated; // how many date segment are generated by DL LTE processing or received from FE
121                        // -1 means that DL packet to be transmitted is not ready in BS
122     int32_t nSegTransferred; // number of data segments has been transmitted or received
123     struct rte_mbuf *pData[N_MAX_BUFFER_SEGMENT]; // point to DPDK allocated memory pool
124     XRANBufferListStruct sBufferList;
125 } BbuIoBufCtrlStruct;
126
127 typedef struct  {
128     uint64_t nCoreMask;
129     int16_t cpuSocketId;
130     uint8_t nDriverCoreId;
131     uint8_t nFHCoreId;
132
133     struct rte_mempool *bbuio_buf_pool;
134
135     /* io struct */
136     BbuIoBufCtrlStruct sFrontHaulTxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
137     BbuIoBufCtrlStruct sFrontHaulRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
138     BbuIoBufCtrlStruct sFHPrachRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
139
140     /* buffers lists */
141     XRANFlatBufferStruct sFrontHaulTxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
142     XRANFlatBufferStruct sFrontHaulRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
143     XRANFlatBufferStruct sFHPrachRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
144
145     void*    nInstanceHandle[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR]; // instance per sector
146     uint32_t nBufPoolIndex[XRAN_MAX_SECTOR_NR][MAX_SW_XRAN_INTERFACE_NUM];   // every api owns unique buffer pool
147     uint16_t nInstanceNum;
148
149     /*subframe type for this TTI:
150         0: DL control + DL data
151         1: DL control + DL data + UL control
152         2: DL control + UL data
153         3: DL control + UL data + UL control
154     */
155     uint8_t nSubframeType;
156
157     uint64_t nTscTiming[XRAN_N_FE_BUF_LEN]; // records the TSC when a timing packet is received.
158 } BbuXranIoIfStruct;
159
160 static BbuXranIoIfStruct    gsXranIoIf;
161 static XranLibConfigStruct *gpXranLibConfig = NULL;
162
163 #define CPU_HZ tick_per_usec //us
164
165 /* Application User space functions */
166 void xran_fh_rx_callback(void *pCallbackTag, int32_t status);
167 void xran_fh_rx_prach_callback(void *pCallbackTag, int32_t status);
168
169 static BbuXranIoIfStruct *xran_get_ctx(void)
170 {
171     return &gsXranIoIf;
172 }
173
174 static void print_menu()
175 {
176     puts("+---------------------------------------+");
177     puts("| Press 1 to start 5G NR XRAN traffic   |");
178     puts("| Press 2 reserved for future use       |");
179     puts("| Press 3 to quit                       |");
180     puts("+---------------------------------------+");
181 }
182
183 void xran_fh_rx_callback(void *pCallbackTag, XranStatusInt32 status)
184 {
185     uint64_t t1 = MLogTick();
186     uint32_t mlogVar[10];
187     uint32_t mlogVarCnt = 0;
188
189     mlogVar[mlogVarCnt++] = 0xCCCCCCCC;
190     mlogVar[mlogVarCnt++] = status >> 16; /* tti */
191     mlogVar[mlogVarCnt++] = status & 0xFF; /* sym */
192     MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
193     rte_pause();
194
195     MLogTask(PID_GNB_SYM_CB, t1, MLogTick());
196     return;
197 }
198
199 void xran_fh_rx_prach_callback(void *pCallbackTag, XranStatusInt32 status)
200 {
201     uint64_t t1 = MLogTick();
202     rte_pause();
203     MLogTask(PID_GNB_PRACH_CB, t1, MLogTick());
204 }
205
206 //-------------------------------------------------------------------------------------------
207 /** @ingroup group_nbiot_source_auxlib_timer
208  *
209  *  @param   void
210  *
211  *  @return  Ticks
212  *
213  *  @description
214  *  This function reads the rtdsc clock and returns the current value in there.
215  *
216 **/
217 //-------------------------------------------------------------------------------------------
218 unsigned long timer_get_ticks(void)
219 {
220     unsigned long ret;
221     union
222     {
223         unsigned long tsc_64;
224         struct
225         {
226             uint32_t lo_32;
227             uint32_t hi_32;
228         };
229     } tsc;
230
231     __asm volatile("rdtsc" :
232              "=a" (tsc.lo_32),
233              "=d" (tsc.hi_32));
234
235      ret = ((unsigned long)tsc.tsc_64);
236      return ret;
237 }
238
239 //-------------------------------------------------------------------------------------------
240 /** @ingroup group_lte_source_auxlib_timer
241  *
242  *  @param   void
243  *
244  *  @return  0 if SUCCESS
245  *
246  *  @description
247  *  This function gets the clock speed of the core and figures out number of ticks per usec.
248  *  It is used by l1app and testmac applications to initialize the mlog utility
249  *
250 **/
251 //-------------------------------------------------------------------------------------------
252 int timer_set_tsc_freq_from_clock(void)
253 {
254 #define NS_PER_SEC 1E9
255     struct timespec sleeptime = {.tv_nsec = 5E8 }; /* 1/2 second */
256     struct timespec t_start, t_end;
257     uint64_t tsc_resolution_hz = 0;
258
259     if (clock_gettime(CLOCK_MONOTONIC_RAW, &t_start) == 0)
260     {
261         unsigned long ns, end, start = timer_get_ticks();
262         nanosleep(&sleeptime,NULL);
263         clock_gettime(CLOCK_MONOTONIC_RAW, &t_end);
264         end = timer_get_ticks();
265         ns = ((t_end.tv_sec - t_start.tv_sec) * NS_PER_SEC);
266         ns += (t_end.tv_nsec - t_start.tv_nsec);
267
268         double secs = (double)ns/NS_PER_SEC;
269         tsc_resolution_hz = (unsigned long)((end - start)/secs);
270
271         tick_per_usec = (tsc_resolution_hz / 1000000);
272         printf("System clock (rdtsc) resolution %lu [Hz]\n", tsc_resolution_hz);
273         printf("Ticks per us %lu\n", tick_per_usec);
274         return 0;
275     }
276
277     return -1;
278 }
279
280 int physide_dl_tti_call_back(void * param)
281 {
282     uint64_t t1 = MLogTick();
283     rte_pause();
284     MLogTask(PID_GNB_PROC_TIMING, t1, MLogTick());
285     return 0;
286 }
287
288 int physide_ul_half_slot_call_back(void * param)
289 {
290     uint64_t t1 = MLogTick();
291     rte_pause();
292     MLogTask(PID_GNB_PROC_TIMING, t1, MLogTick());
293     return 0;
294 }
295
296 int physide_ul_full_slot_call_back(void * param)
297 {
298     uint64_t t1 = MLogTick();
299     rte_pause();
300     MLogTask(PID_GNB_PROC_TIMING, t1, MLogTick());
301     return 0;
302 }
303
304 int32_t init_xran(void)
305 {
306     BbuXranIoIfStruct *psBbuIo = xran_get_ctx();
307     XranStatusInt32 status;
308     int32_t nSectorIndex[XRAN_MAX_SECTOR_NR];
309     int32_t nSectorNum;
310     int32_t i, j, k, z;
311
312     void *ptr;
313     uint32_t *u32dptr;
314     uint16_t *u16dptr;
315     uint8_t  *u8dptr;
316
317     SWXRANInterfaceTypeEnum eInterfaceType;
318
319     XranLibConfigStruct  *ptrLibConfig;
320
321     XRANBufferListStruct *pFthTxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
322     XRANBufferListStruct *pFthRxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
323     XRANBufferListStruct *pFthRxRachBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
324
325     FPGAPhaseCompCfg *pPhaseCompDl = NULL;
326     FPGAPhaseCompCfg *pPhaseCompUl = NULL;
327     uint32_t nPhaseCompDl,nPhaseCompUl;
328
329
330 #if 0
331     printf("init_xran: nFpgaProbe[%d] nSecNum[%d] nUENum[%d] nTimeAdvance[%d] nEthPorts[%d] nPhaseCompFlag[%d]\n",
332         psFPGAInitPara->nFpgaProbe, psFPGAInitPara->nSecNum, psFPGAInitPara->nUENum, psFPGAInitPara->nTimeAdvance, psFPGAInitPara->nEthPorts, psFPGAInitPara->nPhaseCompFlag);
333     for (i = 0; i < nSectorNum; i ++)
334     {
335         printf("           [%d]: nDlArfcn[%d] nUlArfcn[%d]\n", i, psFPGAInitPara->nDlArfcn[i], psFPGAInitPara->nUlArfcn[i]);
336     }
337 #endif
338     for (nSectorNum = 0; nSectorNum < XRAN_MAX_SECTOR_NR; nSectorNum++)
339     {
340         nSectorIndex[nSectorNum] = nSectorNum;
341     }
342
343     nSectorNum = numCCPorts;
344     printf ("XRAN front haul xran_mm_init \n");
345     status = xran_mm_init (xranHandle, (uint64_t) SW_FPGA_FH_TOTAL_BUFFER_LEN, SW_FPGA_SEGMENT_BUFFER_LEN);
346     if (status != XRAN_STATUS_SUCCESS)
347     {
348         printf ("Failed at XRAN front haul xran_mm_init \n");
349         exit(-1);
350     }
351
352     psBbuIo->nInstanceNum = numCCPorts;
353
354     for (k = 0; k < XRAN_PORTS_NUM; k++) {
355         status = xran_sector_get_instances (xranHandle, psBbuIo->nInstanceNum,psBbuIo->nInstanceHandle[k]);
356         if (status != XRAN_STATUS_SUCCESS)
357         {
358             printf ("get sector instance failed %d for XRAN nInstanceNum %d\n",k, psBbuIo->nInstanceNum);
359             exit(-1);
360         }
361     }
362
363     printf("Sucess xran_mm_init \n");
364     gpXranLibConfig = (XranLibConfigStruct*)malloc(sizeof(XranLibConfigStruct));
365     ptrLibConfig = gpXranLibConfig;
366     if (ptrLibConfig)
367     {
368         #if 0
369         ptrLibConfig->nDriverCoreId =  psBbuIo->nDriverCoreId;
370         ptrLibConfig->pFecInstanceHandles = &(psBbuIo->nInstanceHandle[FPGA_FEC][0]);
371         ptrLibConfig->pFthInstanceHandles = &(psBbuIo->nInstanceHandle[FPGA_FRONTHAUL][0]);
372         ptrLibConfig->nTimingAdvance = psFPGAInitPara->nTimeAdvance;
373         ptrLibConfig->nFhConfig = psFPGAInitPara->nEthPorts;
374         ptrLibConfig->nFhBufIntFlag = 0; //need init fronthaul buffer, then set to 1.
375         ptrLibConfig->nNrofSfInFrame = NUM_OF_SUBFRAME_PER_FRAME;
376         ptrLibConfig->nNrOfSlotInSf = pConfigParams->nNumOfSlotPerSubframe;
377         if (pConfigParams->nNumerology < 3)
378         {
379             ptrLibConfig->nSectorNum = psFPGAInitPara->nSecNum;
380         }
381         #endif
382     }
383     else
384     {
385         printf ("could not allocate ptrLibConfig in init_xran\n");
386         exit(-1);
387     }
388
389     printf("nSectorNum %d\n", nSectorNum);
390
391     /* Init Memory */
392     for(i = 0; i<nSectorNum; i++)
393     {
394         eInterfaceType = XRANFTHTX_OUT;
395         status = xran_bm_init(xranHandle, &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],
396             XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, nSW_ToFpga_FTH_TxBufferLen);
397         if(XRAN_STATUS_SUCCESS != status)
398         {
399             printf("Failed at  xran_bm_init , status %d\n", status);
400             iAssert(status == XRAN_STATUS_SUCCESS);
401         }
402         for(j = 0; j < XRAN_N_FE_BUF_LEN; j++)
403         {
404             for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
405                 psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].bValid = 0;
406                 psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
407                 psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
408                 psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
409                 psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
410                 psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFrontHaulTxBuffers[j][i][z][0];
411
412                 for(k = 0; k < XRAN_NUM_OF_SYMBOL_PER_SLOT; k++)
413                 {
414                     psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = nSW_ToFpga_FTH_TxBufferLen; // 14 symbols 3200bytes/symbol
415                     psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
416                     psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
417                     status = xran_bm_allocate_buffer(xranHandle,psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr);
418                     if(XRAN_STATUS_SUCCESS != status)
419                     {
420                         printf("Failed at  xran_bm_allocate_buffer , status %d\n",status);
421                         iAssert(status == XRAN_STATUS_SUCCESS);
422                     }
423                     psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
424
425                     if(ptr){
426                         u32dptr = (uint32_t*)(ptr);
427                         uint8_t *ptr_temp = (uint8_t *)ptr;
428                         memset(u32dptr, 0xCC, nSW_ToFpga_FTH_TxBufferLen);
429                         ptr_temp[0] = j; // TTI
430                         ptr_temp[1] = i; // Sec
431                         ptr_temp[2] = z; // Ant
432                         ptr_temp[3] = k; // sym
433                     }
434                 }
435             }
436         }
437     }
438
439     for(i = 0; i<nSectorNum; i++)
440     {
441         eInterfaceType = XRANFTHRX_IN;
442         status = xran_bm_init(xranHandle, &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType], XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, nSW_ToFpga_FTH_TxBufferLen);
443         if(XRAN_STATUS_SUCCESS != status)
444         {
445             printf("Failed at xran_bm_init, status %d\n", status);
446             iAssert(status == XRAN_STATUS_SUCCESS);
447         }
448
449         for(j = 0;j < XRAN_N_FE_BUF_LEN; j++)
450         {
451             for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
452                 psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].bValid = 0;
453                 psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
454                 psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
455                 psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
456                 psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
457                 psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFrontHaulRxBuffers[j][i][z][0];
458                 for(k = 0; k< XRAN_NUM_OF_SYMBOL_PER_SLOT; k++)
459                 {
460                     psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = nFpgaToSW_FTH_RxBufferLen; // 1 symbols 3200bytes
461                     psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
462                     psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
463                     status = xran_bm_allocate_buffer(xranHandle,psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr);
464                     if(XRAN_STATUS_SUCCESS != status)
465                     {
466                         printf("Failed at  cpa_bb_bm_allocate_buffer , status %d\n",status);
467                         iAssert(status == XRAN_STATUS_SUCCESS);
468                     }
469                     psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
470                     if(ptr){
471                         u32dptr = (uint32_t*)(ptr);
472                         uint8_t *ptr_temp = (uint8_t *)ptr;
473                         memset(u32dptr, 0xCC, nFpgaToSW_FTH_RxBufferLen);
474                         ptr_temp[0] = j; // TTI
475                         ptr_temp[1] = i; // Sec
476                         ptr_temp[2] = z; // Ant
477                         ptr_temp[3] = k; // sym
478                     }
479                 }
480             }
481         }
482     }
483
484     // add prach rx buffer
485     for(i = 0; i<nSectorNum; i++)
486     {
487         eInterfaceType = XRANFTHRACH_IN;
488         status =xran_bm_init(xranHandle,&psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, FPGA_TO_SW_PRACH_RX_BUFFER_LEN);
489         if(XRAN_STATUS_SUCCESS != status)
490         {
491             printf("Failed at xran_bm_init, status %d\n", status);
492             iAssert(status == XRAN_STATUS_SUCCESS);
493         }
494         for(j = 0;j < XRAN_N_FE_BUF_LEN; j++)
495         {
496             for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
497                 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].bValid = 0;
498                 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
499                 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
500                 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
501                 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_MAX_ANTENNA_NR; // ant number.
502                 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFHPrachRxBuffers[j][i][z][0];
503                 //for(k = 0; k< XRAN_NUM_OF_SYMBOL_PER_SLOT; k++)
504                 k = 0; // one PRACH buffer per antenna per slot
505                 {
506                     psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = FPGA_TO_SW_PRACH_RX_BUFFER_LEN;
507                     psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
508                     psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
509                     status = xran_bm_allocate_buffer(xranHandle,psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr);
510                     if(XRAN_STATUS_SUCCESS != status)
511                     {
512                         printf("Failed at  xran_bm_allocate_buffer, status %d\n",status);
513                         iAssert(status == XRAN_STATUS_SUCCESS);
514                     }
515                     psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
516                     if(ptr){
517                         u32dptr = (uint32_t*)(ptr);
518                         memset(u32dptr, 0xCC, FPGA_TO_SW_PRACH_RX_BUFFER_LEN);
519                     }
520                 }
521             }
522         }
523     }
524
525     for(i=0; i<nSectorNum; i++)
526     {
527         for(j=0; j<XRAN_N_FE_BUF_LEN; j++)
528         {
529             for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
530                 pFthTxBuffer[i][z][j]     = &(psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList);
531                 pFthRxBuffer[i][z][j]     = &(psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList);
532                 pFthRxRachBuffer[i][z][j] = &(psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList);
533             }
534         }
535     }
536
537     if(NULL != psBbuIo->nInstanceHandle[0])
538     {
539         for (i = 0; i<nSectorNum; i++)
540         {
541             xran_5g_fronthault_config (psBbuIo->nInstanceHandle[0][i],
542                 pFthTxBuffer[i],
543                 pFthRxBuffer[i],
544                 xran_fh_rx_callback,  &pFthRxBuffer[i][0]);
545         }
546
547         // add prach callback here
548         for (i = 0; i<nSectorNum; i++)
549         {
550             xran_5g_prach_req(psBbuIo->nInstanceHandle[0][i], pFthRxRachBuffer[i],
551                 xran_fh_rx_prach_callback,&pFthRxRachBuffer[i][0]);
552         }
553         ptrLibConfig->nFhBufIntFlag = 1;
554     }
555
556     /*config phase compensation*/
557     /* TODO: add phase compensation handling */
558     for(i=0; i<nSectorNum; i++)
559     {
560         pPhaseCompDl = (FPGAPhaseCompCfg *)(&nPhaseCompDl);
561         pPhaseCompDl->NRARFCN = 0;//psFPGAInitPara->nDlArfcn[i];
562         pPhaseCompDl->phaseFlag = 0;//psFPGAInitPara->nPhaseCompFlag;
563         pPhaseCompDl->SULFlag = 0;
564         pPhaseCompDl->SULFreShift = 0;
565         pPhaseCompDl->rsv = 0;
566
567         pPhaseCompUl = (FPGAPhaseCompCfg *)(&nPhaseCompUl);
568         pPhaseCompUl->NRARFCN =  0;//psFPGAInitPara->nUlArfcn[i];
569         pPhaseCompUl->phaseFlag = 0;// psFPGAInitPara->nPhaseCompFlag;
570         pPhaseCompUl->SULFlag = 0;
571         pPhaseCompUl->SULFreShift = 0;
572         pPhaseCompUl->rsv = 0;
573
574         xran_5g_pre_compenstor_cfg(psBbuIo->nInstanceHandle[0][i],nPhaseCompDl,nPhaseCompUl,i);
575
576         printf("@@@ NB cell %d DL NR-ARFCN  %d,DL phase comp flag %d UL NR-ARFCN  %d,UL phase comp flag %d \n",
577             i,pPhaseCompDl->NRARFCN,pPhaseCompDl->phaseFlag,
578             pPhaseCompUl->NRARFCN,pPhaseCompUl->phaseFlag);
579     }
580     return status;
581 }
582
583 int init_xran_iq_content(void)
584 {
585     BbuXranIoIfStruct *psBbuIo = xran_get_ctx();
586     XranStatusInt32 status;
587     int32_t nSectorIndex[XRAN_MAX_SECTOR_NR];
588     int32_t nSectorNum;
589     int32_t cc_id, ant_id, sym_id, tti;
590     int32_t flowId;
591
592     uint8_t    frame_id    = 0;
593     uint8_t    subframe_id = 0;
594     uint8_t    slot_id     = 0;
595     uint8_t    sym         = 0;
596
597     void *ptr;
598     uint32_t *u32dptr;
599     uint16_t *u16dptr;
600     uint8_t  *u8dptr;
601
602     char        *pos = NULL;
603
604     for (nSectorNum = 0; nSectorNum < XRAN_MAX_SECTOR_NR; nSectorNum++)
605     {
606         nSectorIndex[nSectorNum] = nSectorNum;
607     }
608     nSectorNum = numCCPorts;
609     printf ("init_xran_iq_content\n");
610
611     /* Init Memory */
612     for(cc_id = 0; cc_id <nSectorNum; cc_id++)
613     {
614         for(tti  = 0; tti  < XRAN_N_FE_BUF_LEN; tti ++) {
615             for(ant_id = 0; ant_id < XRAN_MAX_ANTENNA_NR; ant_id++){
616                 for(sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) {
617                     flowId = nSectorNum * ant_id + cc_id;
618
619                     if(p_tx_play_buffer[flowId]){
620                         /* (0-79 slots) 10ms of IQs */
621                         pos =  ((char*)p_tx_play_buffer[flowId]) + tx_play_buffer_position[flowId];
622
623                         ptr = psBbuIo->sFrontHaulTxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
624
625                         if(ptr){
626                             u32dptr = (uint32_t*)(ptr);
627                             rte_memcpy(u32dptr, pos, PDSCH_PAYLOAD_SIZE);
628 #ifdef DEBUG_XRAN_BUFFERS
629                             uint8_t *ptr_temp = (uint8_t *)ptr;
630                                 ptr_temp[0] = tti; // TTI
631                                 ptr_temp[1] = cc_id; // Sec
632                                 ptr_temp[2] = ant_id; // Ant
633                                 ptr_temp[3] = sym_id; // sym
634 #endif
635                         }else
636                             printf("ptr ==NULL\n");
637
638                         tx_play_buffer_position[flowId] += PDSCH_PAYLOAD_SIZE;
639
640                         if(tx_play_buffer_position[flowId] >= tx_play_buffer_size[flowId])
641                             tx_play_buffer_position[flowId] = 0;
642                     } else {
643                         //printf("flowId %d\n", flowId);
644                     }
645                 }
646             }
647         }
648
649     }
650
651     return 0;
652 }
653
654 void stop_xran(void)
655 {
656     XranStatusInt32 status = 0;
657     SWXRANInterfaceTypeEnum eInterfaceType;
658
659     free(gpXranLibConfig);
660     gpXranLibConfig = NULL;
661
662     status += xran_mm_destroy(xranHandle)*2;
663
664     if(XRAN_STATUS_SUCCESS != status)
665     {
666         printf("Failed at  xran_mm_destroy, status %d\n",status);
667         iAssert(status == XRAN_STATUS_SUCCESS);
668     }
669 }
670
671 int32_t get_xran_sfidx(uint8_t nNrOfSlotInSf)
672 {
673     int32_t nSfIdx = -1;
674     uint32_t nFrameIdx;
675     uint32_t nSubframeIdx;
676     uint32_t nSlotIdx;
677     uint64_t nSecond;
678
679     uint32_t nXranTime  = xran_get_slot_idx(&nFrameIdx, &nSubframeIdx, &nSlotIdx, &nSecond);
680     nSfIdx = nFrameIdx*NUM_OF_SUBFRAME_PER_FRAME*nNrOfSlotInSf
681         + nSubframeIdx*nNrOfSlotInSf
682         + nSlotIdx;
683 #if 0
684     printf("\nxranTime is %d, return is %d, radio frame is %d, subframe is %d slot is %d tsc is %llu us",
685         nXranTime,
686         nSfIdx,
687         nFrameIdx,
688         nSubframeIdx,
689         nSlotIdx,
690         __rdtsc()/CPU_HZ);
691 #endif
692
693     return nSfIdx;
694 }
695
696 int get_xran_iq_content(void)
697 {
698     BbuXranIoIfStruct *psBbuIo = xran_get_ctx();
699     XranStatusInt32 status;
700     int32_t nSectorIndex[XRAN_MAX_SECTOR_NR];
701     int32_t nSectorNum;
702     int32_t cc_id, ant_id, sym_id, tti;
703     int32_t flowId;
704
705     uint8_t    frame_id    = 0;
706     uint8_t    subframe_id = 0;
707     uint8_t    slot_id     = 0;
708     uint8_t    sym         = 0;
709
710     void *ptr;
711     uint32_t *u32dptr;
712     uint16_t *u16dptr;
713     uint8_t  *u8dptr;
714
715     char        *pos = NULL;
716
717     for (nSectorNum = 0; nSectorNum < XRAN_MAX_SECTOR_NR; nSectorNum++)
718     {
719         nSectorIndex[nSectorNum] = nSectorNum;
720     }
721     nSectorNum = numCCPorts;
722     printf ("get_xran_iq_content\n");
723
724     /* Init Memory */
725     for(cc_id = 0; cc_id <nSectorNum; cc_id++)
726     {
727         for(tti  = 0; tti  < XRAN_N_FE_BUF_LEN; tti++) {
728             for(ant_id = 0; ant_id < XRAN_MAX_ANTENNA_NR; ant_id++){
729                 for(sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) {
730                     flowId = nSectorNum * ant_id + cc_id;
731                     if(p_rx_log_buffer[flowId]){
732                         /* (0-79 slots) 10ms of IQs */
733                         pos =  ((char*)p_rx_log_buffer[flowId]) + rx_log_buffer_position[flowId];
734                         ptr = psBbuIo->sFrontHaulRxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
735                         if(ptr){
736                             u32dptr = (uint32_t*)(ptr);
737                             rte_memcpy(pos, u32dptr, PDSCH_PAYLOAD_SIZE);
738 #ifdef DEBUG_XRAN_BUFFERS
739                             if (pos[0] != tti||
740                                 pos[1] != cc_id  ||
741                                 pos[2] != ant_id ||
742                                 pos[3] != sym_id){
743                                     printf("[flowId %d] %d %d %d %d\n", flowId, pos[0], pos[1], pos[2], pos[3]);
744                             }
745 #endif
746                         }else
747                             printf("ptr ==NULL\n");
748
749                         rx_log_buffer_position[flowId] += PDSCH_PAYLOAD_SIZE;
750
751                         if(rx_log_buffer_position[flowId] >= rx_log_buffer_size[flowId])
752                             rx_log_buffer_position[flowId] = 0;
753                     } else {
754                         //printf("flowId %d\n", flowId);
755                     }
756                 }
757             }
758         }
759     }
760
761     return 0;
762 }
763
764 int main(int argc, char *argv[])
765 {
766     int i;
767     int j;
768     int  lcore_id = 0;
769     char filename[64];
770
771     if (argc == 3)
772         errx(2, "Need two argument - the PCI address of the network port");
773
774     if (xran_is_synchronized() != 0)
775         printf("Machine is not synchronized using PTP!\n");
776     else
777         printf("Machine is synchronized using PTP!\n");
778
779     memset(&startupConfiguration, 0, sizeof(RuntimeConfig));
780
781     if (parseConfigFile(argv[1], &startupConfiguration) != 0) {
782         printf("Configuration file error.\n");
783         return 0;
784     }
785
786     if(startupConfiguration.ant_file[0] == NULL){
787         printf("it looks like test vector for antennas were not provided\n");
788         exit(-1);
789     }
790
791     numCCPorts = startupConfiguration.numCC;
792     num_eAxc   = startupConfiguration.numAxc;
793
794     printf("numCCPorts %d num_eAxc%d\n", numCCPorts, num_eAxc);
795
796     /* Numerology 3 */
797     nFpgaToSW_FTH_RxBufferLen    = 3328; //3200 * 14;
798     nFpgaToSW_PRACH_RxBufferLen  = 8192;
799     nSW_ToFpga_FTH_TxBufferLen   = 3328; //3200; * 14;
800
801     memset(&xranInit, 0, sizeof(XRANFHINIT));
802
803     if(startupConfiguration.appMode == APP_LLS_CU) {
804         printf("set lls-CU\n");
805         xranInit.io_cfg.id = 0;//ID_LLS_CU;
806         xranInit.io_cfg.core          = 4+1;
807         xranInit.io_cfg.system_core   = 0;
808         xranInit.io_cfg.pkt_proc_core = 4+2;
809         xranInit.io_cfg.pkt_aux_core  = 0; /* do not start*/
810         xranInit.io_cfg.timing_core   = 4+3;
811     } else {
812         printf("set RU\n");
813         xranInit.io_cfg.id = 1; /* ID_LLS_CU;*/
814         xranInit.io_cfg.core          = 1;
815         xranInit.io_cfg.system_core   = 0;
816         xranInit.io_cfg.pkt_proc_core = 2;
817         xranInit.io_cfg.pkt_aux_core  = 0; /* do not start */
818         xranInit.io_cfg.timing_core   = 3;
819     }
820
821     xranInit.llscuId        = 0;    // for ecpriRtcid/ecpriPcid
822     xranInit.nSec           = 1;    // shall be one
823
824     xranInit.eAxCId_conf.mask_cuPortId      = 0xf000;
825     xranInit.eAxCId_conf.mask_bandSectorId  = 0x0f00;
826     xranInit.eAxCId_conf.mask_ccId          = 0x00f0;
827     xranInit.eAxCId_conf.mask_ruPortId      = 0x000f;
828     xranInit.eAxCId_conf.bit_cuPortId       = 12;
829     xranInit.eAxCId_conf.bit_bandSectorId   = 8;
830     xranInit.eAxCId_conf.bit_ccId           = 4;
831     xranInit.eAxCId_conf.bit_ruPortId       = 0;
832
833     xranInit.io_cfg.dpdk_dev[XRAN_UP_VF]      = argv[2];
834     xranInit.io_cfg.dpdk_dev[XRAN_CP_VF]      = argv[3];
835     xranInit.p_lls_cu_addr = (int8_t*)&startupConfiguration.lls_cu_addr;
836     xranInit.p_ru_addr     = (int8_t*)&startupConfiguration.ru_addr;
837     xranInit.ttiPeriod     = startupConfiguration.ttiPeriod;
838
839     xranInit.Tadv_cp_dl     = startupConfiguration.Tadv_cp_dl;
840     xranInit.T2a_min_cp_dl  = startupConfiguration.T2a_min_cp_dl;
841     xranInit.T2a_max_cp_dl  = startupConfiguration.T2a_max_cp_dl;
842     xranInit.T2a_min_cp_ul  = startupConfiguration.T2a_min_cp_ul;
843     xranInit.T2a_max_cp_ul  = startupConfiguration.T2a_max_cp_ul;
844     xranInit.T2a_min_up     = startupConfiguration.T2a_min_up;
845     xranInit.T2a_max_up     = startupConfiguration.T2a_max_up;
846     xranInit.Ta3_min        = startupConfiguration.Ta3_min;
847     xranInit.Ta3_max        = startupConfiguration.Ta3_max;
848     xranInit.T1a_min_cp_dl  = startupConfiguration.T1a_min_cp_dl;
849     xranInit.T1a_max_cp_dl  = startupConfiguration.T1a_max_cp_dl;
850     xranInit.T1a_min_cp_ul  = startupConfiguration.T1a_min_cp_ul;
851     xranInit.T1a_max_cp_ul  = startupConfiguration.T1a_max_cp_ul;
852     xranInit.T1a_min_up     = startupConfiguration.T1a_min_up;
853     xranInit.T1a_max_up     = startupConfiguration.T1a_max_up;
854     xranInit.Ta4_min        = startupConfiguration.Ta4_min;
855     xranInit.Ta4_max        = startupConfiguration.Ta4_max;
856
857     xranInit.enableCP = startupConfiguration.enableCP;
858     xranInit.debugStop = startupConfiguration.debugStop;
859
860     xranInit.cp_vlan_tag = startupConfiguration.cp_vlan_tag;
861     xranInit.up_vlan_tag = startupConfiguration.up_vlan_tag;
862
863
864     for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
865
866         p_tx_play_buffer[i]    = (int16_t*)malloc(IQ_PLAYBACK_BUFFER_BYTES);
867         tx_play_buffer_size[i] = (int32_t)IQ_PLAYBACK_BUFFER_BYTES;
868
869         if (p_tx_play_buffer[i] == NULL)
870             exit(-1);
871
872         tx_play_buffer_size[i] = sys_load_file_to_buff(startupConfiguration.ant_file[i],
873                             "DL IFFT IN IQ Samples in binary format",
874                             (uint8_t*) p_tx_play_buffer[i],
875                             tx_play_buffer_size[i],
876                             1);
877         tx_play_buffer_position[i] = 0;
878     }
879
880     /* log of ul */
881     for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
882
883         p_rx_log_buffer[i]    = (int16_t*)malloc(IQ_PLAYBACK_BUFFER_BYTES);
884         rx_log_buffer_size[i] = (int32_t)IQ_PLAYBACK_BUFFER_BYTES;
885
886         if (p_rx_log_buffer[i] == NULL)
887             exit(-1);
888
889         rx_log_buffer_position[i] = 0;
890
891         memset(p_rx_log_buffer[i], 0, rx_log_buffer_size[i]);
892     }
893
894     /* log of Prach */
895     for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
896
897         p_prach_log_buffer[i]    = (int16_t*)malloc(PRACH_PLAYBACK_BUFFER_BYTES);
898         prach_log_buffer_size[i] = (int32_t)PRACH_PLAYBACK_BUFFER_BYTES;
899
900         if (p_prach_log_buffer[i] == NULL)
901             exit(-1);
902
903         memset(p_prach_log_buffer[i], 0, prach_log_buffer_size[i]);
904         prach_log_buffer_position[i] = 0;
905     }
906
907     for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
908
909         sprintf(filename, "%s-play_ant%d.txt",((startupConfiguration.appMode == APP_LLS_CU) ? "lls-cu" : "ru"),  i);
910         sys_save_buf_to_file_txt(filename,
911                             "DL IFFT IN IQ Samples in human readable format",
912                             (uint8_t*) p_tx_play_buffer[i],
913                             tx_play_buffer_size[i],
914                             1);
915
916         sprintf(filename, "%s-play_ant%d.bin",((startupConfiguration.appMode == APP_LLS_CU) ? "lls-cu" : "ru"), i);
917         sys_save_buf_to_file(filename,
918                             "DL IFFT IN IQ Samples in binary format",
919                             (uint8_t*) p_tx_play_buffer[i],
920                             tx_play_buffer_size[i]/sizeof(short),
921                             sizeof(short));
922     }
923     if (startupConfiguration.iqswap == 1){
924         for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
925             printf("TX: Swap I and Q to match RU format: [%d]\n",i);
926             {
927                 /* swap I and Q */
928                 int32_t j;
929                 signed short *ptr = (signed short *)  p_tx_play_buffer[i];
930                 signed short temp;
931
932                 for (j = 0; j < (int32_t)(tx_play_buffer_size[i]/sizeof(short)) ; j = j + 2){
933                    temp    = ptr[j];
934                    ptr[j]  = ptr[j + 1];
935                    ptr[j + 1] = temp;
936                 }
937             }
938         }
939     }
940
941 #if 0
942     for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
943
944         sprintf(filename, "swap_IQ_play_ant%d.txt", i);
945         sys_save_buf_to_file_txt(filename,
946                             "DL IFFT IN IQ Samples in human readable format",
947                             (uint8_t*) p_tx_play_buffer[i],
948                             tx_play_buffer_size[i],
949                             1);
950     }
951 #endif
952     if (startupConfiguration.nebyteorderswap == 1){
953         for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
954             printf("TX: Convert S16 I and S16 Q to network byte order for XRAN Ant: [%d]\n",i);
955             for (j = 0; j < tx_play_buffer_size[i]/sizeof(short); j++){
956                 p_tx_play_buffer[i][j]  = rte_cpu_to_be_16(p_tx_play_buffer[i][j]);
957             }
958         }
959     }
960
961 #if 0
962     for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
963
964         sprintf(filename, "swap_be_play_ant%d.txt", i);
965         sys_save_buf_to_file_txt(filename,
966                             "DL IFFT IN IQ Samples in human readable format",
967                             (uint8_t*) p_tx_play_buffer[i],
968                             tx_play_buffer_size[i],
969                             1);
970     }
971 #endif
972
973     timer_set_tsc_freq_from_clock();
974     xran_init(argc, argv, &xranInit, argv[0], &xranHandle);
975     if(xranHandle == NULL)
976         exit(1);
977
978     memset(&xranConf, 0, sizeof(XRANFHCONFIG));
979     pXranConf = &xranConf;
980
981     for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
982         pXranConf->playback_conf.TxPlayBufAddr[i] = (unsigned long)p_tx_play_buffer[i];
983         pXranConf->playback_conf.TxPlayBufSize    = tx_play_buffer_size[i];
984     }
985
986     pXranConf->sector_id                        = 0;
987     pXranConf->nCC                              = numCCPorts;
988     pXranConf->neAxc                            = num_eAxc;
989
990     pXranConf->frame_conf.nFrameDuplexType      = 1;    // TDD
991     pXranConf->frame_conf.nNumerology           = startupConfiguration.mu_number;    // 120KHz; same as XRAN_SCS_120KHz?
992 //  pXranConf->frame_conf.nTddPeriod            = ;
993
994     pXranConf->prach_conf.nPrachSubcSpacing     = XRAN_SCS_120KHZ;
995     pXranConf->prach_conf.nPrachFreqStart       = 0;
996     pXranConf->prach_conf.nPrachFilterIdx       = XRAN_FILTERINDEX_PRACH_ABC;
997     pXranConf->prach_conf.nPrachConfIdx         = 81;
998     pXranConf->prach_conf.nPrachFreqOffset      = -792;
999
1000     pXranConf->ru_conf.iqWidth                  = 16;
1001     pXranConf->ru_conf.compMeth                 = XRAN_COMPMETHOD_NONE;
1002     pXranConf->ru_conf.fftSize                  = XRAN_FFTSIZE_2048;
1003
1004
1005     if(init_xran() != 0)
1006         exit(-1);
1007
1008     xran_reg_physide_cb(xranHandle, physide_dl_tti_call_back, NULL, 10, XRAN_CB_TTI);
1009     xran_reg_physide_cb(xranHandle, physide_ul_half_slot_call_back, NULL, 10, XRAN_CB_HALF_SLOT_RX);
1010     xran_reg_physide_cb(xranHandle, physide_ul_full_slot_call_back, NULL, 10, XRAN_CB_FULL_SLOT_RX);
1011
1012     init_xran_iq_content();
1013
1014     xran_open(xranHandle, pXranConf);
1015
1016     sprintf(filename, "mlog-%s", startupConfiguration.appMode == 0 ? "lls-cu" : "ru");
1017
1018     MLogOpen(0, 32, 0, 0xFFFFFFFF, filename);
1019     puts("----------------------------------------");
1020     printf("MLog Info: virt=0x%016lx size=%d\n", MLogGetFileLocation(), MLogGetFileSize());
1021     puts("----------------------------------------");
1022
1023     state = APP_RUNNING;
1024     sleep(6);
1025     for (;;) {
1026         print_menu();
1027         char input[10];
1028         int sel_opt;
1029 //#ifdef Nightly_build
1030 //        sel_opt = 3;
1031 //        sleep(10);
1032 //#else
1033         if (NULL == fgets(input, 10, stdin)) {
1034             state = APP_STOPPED;
1035             break;
1036         }
1037         sel_opt = atoi(input);
1038 //#endif
1039         switch (sel_opt) {
1040             case 1:
1041                 xran_start(xranHandle);
1042                 printf("Start XRAN traffic\n");
1043                 break;
1044             case 2:
1045                 break;
1046             case 3:
1047                 xran_stop(xranHandle);
1048                 printf("Stop XRAN traffic\n");
1049                 state = APP_STOPPED;
1050                 break;
1051             case 4:
1052 //                send_cpmsg_dlul(XRAN_DIR_DL, flowId,
1053 //                                    frame_id, subframe_id, slot_id,
1054 //                                    0, XRAN_SYMBOLPERSLOT_MAX, NUM_OF_PRB_IN_FULL_BAND,
1055 //                                    beam_id, cc_id, ant_id,
1056 //                                    cp_seq_id_num[XRAN_DIR_DL][ant_id]++);
1057                 break;
1058             default:
1059                 puts("Wrong option passed!");
1060                 break;
1061         }
1062
1063         if (APP_STOPPED == state)
1064             break;
1065     }
1066
1067     get_xran_iq_content();
1068
1069     puts("Closing l1 app... Ending all threads...");
1070     xran_close(xranHandle);
1071     MLogPrint(NULL);
1072
1073     stop_xran();
1074     puts("Dump IQs...");
1075
1076     if (startupConfiguration.iqswap == 1){
1077         for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1078             printf("RX: Swap I and Q to match CPU format: [%d]\n",i);
1079             {
1080                 /* swap I and Q */
1081                 int32_t j;
1082                 signed short *ptr = (signed short *)  p_rx_log_buffer[i];
1083                 signed short temp;
1084
1085                 for (j = 0; j < (int32_t)(rx_log_buffer_size[i]/sizeof(short)) ; j = j + 2){
1086                    temp    = ptr[j];
1087                    ptr[j]  = ptr[j + 1];
1088                    ptr[j + 1] = temp;
1089                 }
1090             }
1091         }
1092     }
1093
1094     if (startupConfiguration.nebyteorderswap == 1){
1095         for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1096             printf("RX: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [%d]\n",i);
1097             for (j = 0; j < rx_log_buffer_size[i]/sizeof(short); j++){
1098                 p_rx_log_buffer[i][j]  = rte_be_to_cpu_16(p_rx_log_buffer[i][j]);
1099             }
1100         }
1101     }
1102
1103     for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1104
1105         sprintf(filename, "%s-rx_log_ant%d.txt",((startupConfiguration.appMode == APP_LLS_CU) ? "lls-cu" : "ru"),  i);
1106         sys_save_buf_to_file_txt(filename,
1107                             "UL FFT OUT IQ Samples in human readable format",
1108                             (uint8_t*) p_rx_log_buffer[i],
1109                             rx_log_buffer_size[i],
1110                             1);
1111
1112         sprintf(filename, "%s-rx_log_ant%d.bin",((startupConfiguration.appMode == APP_LLS_CU) ? "lls-cu" : "ru"), i);
1113         sys_save_buf_to_file(filename,
1114                             "UL FFT OUT IQ Samples in binary format",
1115                             (uint8_t*) p_rx_log_buffer[i],
1116                             rx_log_buffer_size[i]/sizeof(short),
1117                             sizeof(short));
1118     }
1119
1120     if (startupConfiguration.iqswap == 1){
1121         for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1122             printf("PRACH: Swap I and Q to match CPU format: [%d]\n",i);
1123             {
1124                 /* swap I and Q */
1125                 int32_t j;
1126                 signed short *ptr = (signed short *)  p_prach_log_buffer[i];
1127                 signed short temp;
1128
1129                 for (j = 0; j < (int32_t)(prach_log_buffer_size[i]/sizeof(short)) ; j = j + 2){
1130                    temp    = ptr[j];
1131                    ptr[j]  = ptr[j + 1];
1132                    ptr[j + 1] = temp;
1133                 }
1134             }
1135         }
1136     }
1137
1138     if (startupConfiguration.nebyteorderswap == 1){
1139         for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1140             printf("PRACH: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [%d]\n",i);
1141             for (j = 0; j < prach_log_buffer_size[i]/sizeof(short); j++){
1142                 p_prach_log_buffer[i][j]  = rte_be_to_cpu_16(p_prach_log_buffer[i][j]);
1143             }
1144         }
1145     }
1146
1147     for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1148
1149         sprintf(filename, "%s-prach_log_ant%d.txt",((startupConfiguration.appMode == APP_LLS_CU) ? "lls-cu" : "ru"),  i);
1150         sys_save_buf_to_file_txt(filename,
1151                             "PRACH FFT OUT IQ Samples in human readable format",
1152                             (uint8_t*) p_prach_log_buffer[i],
1153                             prach_log_buffer_size[i],
1154                             1);
1155
1156         sprintf(filename, "%s-prach_log_ant%d.bin",((startupConfiguration.appMode == APP_LLS_CU) ? "lls-cu" : "ru"), i);
1157         sys_save_buf_to_file(filename,
1158                             "PRACH FFT OUT IQ Samples in binary format",
1159                             (uint8_t*) p_prach_log_buffer[i],
1160                             prach_log_buffer_size[i]/sizeof(short),
1161                             sizeof(short));
1162     }
1163
1164     return 0;
1165 }