1 /******************************************************************************
3 * Copyright (c) 2019 Intel.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 *******************************************************************************/
22 #include <sys/syscall.h>
39 #include "xran_mlog_lnx.h"
41 #include "xran_fh_o_du.h"
42 #include "xran_cp_api.h"
43 #include "xran_sync_api.h"
44 #include "xran_mlog_task_id.h"
46 #define MAX_BBU_POOL_CORE_MASK (4)
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)
54 #define NSEC_PER_SEC 1000000000
56 #define MAX_PKT_BURST (448+4) // 4x14x8
57 #define N_MAX_BUFFER_SEGMENT MAX_PKT_BURST
59 #define MAIN_PRIORITY 98
60 #define NUM_OF_SUBFRAME_PER_FRAME (10)
64 uint64_t tick_per_usec;
65 static volatile uint64_t timer_last_irq_tick = 0;
66 static uint64_t tsc_resolution_hz = 0;
68 RuntimeConfig startupConfiguration = {0};
71 uint32_t nFpgaToSW_FTH_RxBufferLen;
72 uint32_t nFpgaToSW_PRACH_RxBufferLen;
73 uint32_t nSW_ToFpga_FTH_TxBufferLen;
75 static struct xran_fh_init xranInit;
76 void * xranHandle = NULL;
78 struct xran_fh_config xranConf;
79 struct xran_fh_config *pXranConf = NULL;
83 uint32_t phaseFlag :1;
85 uint32_t SULFreShift :1;
90 typedef struct XranLibConfig
92 uint32_t nDriverCoreId;
93 uint32_t nTimingAdvance;
95 uint32_t nFhBufIntFlag;
97 uint32_t nNrOfSlotInSf;
98 uint32_t nNrofSfInFrame;
99 void * pFthInstanceHandles;
100 }XranLibConfigStruct;
103 XRANFTHTX_PRB_MAP_OUT,
105 XRANFTHRX_PRB_MAP_IN,
107 MAX_SW_XRAN_INTERFACE_NUM
108 }SWXRANInterfaceTypeEnum;
111 * manage one cell's all Ethernet frames for one DL or UL LTE subframe
114 /* -1-this subframe is not used in current frame format
115 0-this subframe can be transmitted, i.e., data is ready
116 1-this subframe is waiting transmission, i.e., data is not ready
117 10 - DL transmission missing deadline. When FE needs this subframe data but bValid is still 1,
120 int32_t bValid ; // when UL rx, it is subframe index.
122 int32_t nSegGenerated; // how many date segment are generated by DL LTE processing or received from FE
123 // -1 means that DL packet to be transmitted is not ready in BS
124 int32_t nSegTransferred; // number of data segments has been transmitted or received
125 struct rte_mbuf *pData[N_MAX_BUFFER_SEGMENT]; // point to DPDK allocated memory pool
126 struct xran_buffer_list sBufferList;
127 } BbuIoBufCtrlStruct;
132 uint8_t nDriverCoreId;
135 struct rte_mempool *bbuio_buf_pool;
138 BbuIoBufCtrlStruct sFrontHaulTxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
139 BbuIoBufCtrlStruct sFrontHaulTxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
140 BbuIoBufCtrlStruct sFrontHaulRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
141 BbuIoBufCtrlStruct sFrontHaulRxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
142 BbuIoBufCtrlStruct sFHPrachRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
145 struct xran_flat_buffer sFrontHaulTxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
146 struct xran_flat_buffer sFrontHaulTxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
147 struct xran_flat_buffer sFrontHaulRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
148 struct xran_flat_buffer sFrontHaulRxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
149 struct xran_flat_buffer sFHPrachRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
151 void* nInstanceHandle[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR]; // instance per sector
152 uint32_t nBufPoolIndex[XRAN_MAX_SECTOR_NR][MAX_SW_XRAN_INTERFACE_NUM]; // every api owns unique buffer pool
153 uint16_t nInstanceNum;
155 uint64_t nTscTiming[XRAN_N_FE_BUF_LEN]; // records the TSC when a timing packet is received.
158 static BbuXranIoIfStruct gsXranIoIf;
159 static XranLibConfigStruct *gpXranLibConfig = NULL;
161 extern long rx_counter;
162 extern long tx_counter;
164 #define CPU_HZ tick_per_usec //us
166 /* Application User space functions */
167 void xran_fh_rx_callback(void *pCallbackTag, int32_t status);
168 void xran_fh_rx_prach_callback(void *pCallbackTag, int32_t status);
170 static BbuXranIoIfStruct *xran_get_ctx(void)
175 static void print_menu()
177 puts("+---------------------------------------+");
178 puts("| Press 1 to start 5G NR XRAN traffic |");
179 puts("| Press 2 reserved for future use |");
180 puts("| Press 3 to quit |");
181 puts("+---------------------------------------+");
184 static int32_t get_xran_sfidx(uint8_t nNrOfSlotInSf)
188 uint32_t nSubframeIdx;
192 uint32_t nXranTime = xran_get_slot_idx(&nFrameIdx, &nSubframeIdx, &nSlotIdx, &nSecond);
193 nSfIdx = nFrameIdx*NUM_OF_SUBFRAME_PER_FRAME*nNrOfSlotInSf
194 + nSubframeIdx*nNrOfSlotInSf
197 printf("\nxranTime is %d, return is %d, radio frame is %d, subframe is %d slot is %d tsc is %llu us",
209 void xran_fh_rx_callback(void *pCallbackTag, xran_status_t status)
211 uint64_t t1 = MLogTick();
212 uint32_t mlogVar[10];
213 uint32_t mlogVarCnt = 0;
214 uint8_t Numerlogy = xranConf.frame_conf.nNumerology;
215 uint8_t nNrOfSlotInSf = 1<<Numerlogy;
216 int32_t sfIdx = get_xran_sfidx(nNrOfSlotInSf);
218 mlogVar[mlogVarCnt++] = 0xCCCCCCCC;
219 mlogVar[mlogVarCnt++] = status >> 16; /* tti */
220 mlogVar[mlogVarCnt++] = status & 0xFF; /* sym */
221 mlogVar[mlogVarCnt++] = (uint32_t)sfIdx;
222 MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
225 MLogTask(PID_GNB_SYM_CB, t1, MLogTick());
229 void xran_fh_rx_prach_callback(void *pCallbackTag, xran_status_t status)
231 uint64_t t1 = MLogTick();
232 uint32_t mlogVar[10];
233 uint32_t mlogVarCnt = 0;
235 mlogVar[mlogVarCnt++] = 0xDDDDDDDD;
236 mlogVar[mlogVarCnt++] = status >> 16; /* tti */
237 mlogVar[mlogVarCnt++] = status & 0xFF; /* sym */
238 MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
241 MLogTask(PID_GNB_PRACH_CB, t1, MLogTick());
244 //-------------------------------------------------------------------------------------------
245 /** @ingroup group_nbiot_source_auxlib_timer
252 * This function reads the rtdsc clock and returns the current value in there.
255 //-------------------------------------------------------------------------------------------
256 unsigned long timer_get_ticks(void)
261 unsigned long tsc_64;
269 __asm volatile("rdtsc" :
273 ret = ((unsigned long)tsc.tsc_64);
277 //-------------------------------------------------------------------------------------------
278 /** @ingroup group_lte_source_auxlib_timer
282 * @return 0 if SUCCESS
285 * This function gets the clock speed of the core and figures out number of ticks per usec.
286 * It is used by l1app and testmac applications to initialize the mlog utility
289 //-------------------------------------------------------------------------------------------
290 int timer_set_tsc_freq_from_clock(void)
292 #define NS_PER_SEC 1E9
293 struct timespec sleeptime = {.tv_nsec = 5E8 }; /* 1/2 second */
294 struct timespec t_start, t_end;
295 uint64_t tsc_resolution_hz = 0;
297 if (clock_gettime(CLOCK_MONOTONIC_RAW, &t_start) == 0)
299 unsigned long ns, end, start = timer_get_ticks();
300 nanosleep(&sleeptime,NULL);
301 clock_gettime(CLOCK_MONOTONIC_RAW, &t_end);
302 end = timer_get_ticks();
303 ns = ((t_end.tv_sec - t_start.tv_sec) * NS_PER_SEC);
304 ns += (t_end.tv_nsec - t_start.tv_nsec);
306 double secs = (double)ns/NS_PER_SEC;
307 tsc_resolution_hz = (unsigned long)((end - start)/secs);
309 tick_per_usec = (tsc_resolution_hz / 1000000);
310 printf("System clock (rdtsc) resolution %lu [Hz]\n", tsc_resolution_hz);
311 printf("Ticks per us %lu\n", tick_per_usec);
318 int physide_dl_tti_call_back(void * param)
320 uint64_t t1 = MLogTick();
322 MLogTask(PID_GNB_PROC_TIMING, t1, MLogTick());
326 int physide_ul_half_slot_call_back(void * param)
328 uint64_t t1 = MLogTick();
330 MLogTask(PID_GNB_PROC_TIMING, t1, MLogTick());
334 int physide_ul_full_slot_call_back(void * param)
336 uint64_t t1 = MLogTick();
338 MLogTask(PID_GNB_PROC_TIMING, t1, MLogTick());
342 int32_t init_xran(void)
344 BbuXranIoIfStruct *psBbuIo = xran_get_ctx();
345 xran_status_t status;
346 int32_t nSectorIndex[XRAN_MAX_SECTOR_NR];
356 SWXRANInterfaceTypeEnum eInterfaceType;
358 XranLibConfigStruct *ptrLibConfig;
360 struct xran_buffer_list *pFthTxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
361 struct xran_buffer_list *pFthTxPrbMapBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
362 struct xran_buffer_list *pFthRxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
363 struct xran_buffer_list *pFthRxPrbMapBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
364 struct xran_buffer_list *pFthRxRachBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
366 for (nSectorNum = 0; nSectorNum < XRAN_MAX_SECTOR_NR; nSectorNum++)
368 nSectorIndex[nSectorNum] = nSectorNum;
371 nSectorNum = numCCPorts;
372 printf ("XRAN front haul xran_mm_init \n");
373 status = xran_mm_init (xranHandle, (uint64_t) SW_FPGA_FH_TOTAL_BUFFER_LEN, SW_FPGA_SEGMENT_BUFFER_LEN);
374 if (status != XRAN_STATUS_SUCCESS)
376 printf ("Failed at XRAN front haul xran_mm_init \n");
380 psBbuIo->nInstanceNum = numCCPorts;
382 for (k = 0; k < XRAN_PORTS_NUM; k++) {
383 status = xran_sector_get_instances (xranHandle, psBbuIo->nInstanceNum,&psBbuIo->nInstanceHandle[k][0]);
384 if (status != XRAN_STATUS_SUCCESS)
386 printf ("get sector instance failed %d for XRAN nInstanceNum %d\n",k, psBbuIo->nInstanceNum);
389 for (i = 0; i < psBbuIo->nInstanceNum; i++){
390 printf("%s [%d]: CC %d handle %p\n", __FUNCTION__, k, i, psBbuIo->nInstanceHandle[0][i]);
394 printf("Sucess xran_mm_init \n");
395 gpXranLibConfig = (XranLibConfigStruct*)malloc(sizeof(XranLibConfigStruct));
396 ptrLibConfig = gpXranLibConfig;
400 ptrLibConfig->nDriverCoreId = psBbuIo->nDriverCoreId;
401 ptrLibConfig->pFecInstanceHandles = &(psBbuIo->nInstanceHandle[FPGA_FEC][0]);
402 ptrLibConfig->pFthInstanceHandles = &(psBbuIo->nInstanceHandle[FPGA_FRONTHAUL][0]);
403 ptrLibConfig->nTimingAdvance = psFPGAInitPara->nTimeAdvance;
404 ptrLibConfig->nFhConfig = psFPGAInitPara->nEthPorts;
405 ptrLibConfig->nFhBufIntFlag = 0; //need init fronthaul buffer, then set to 1.
406 ptrLibConfig->nNrofSfInFrame = NUM_OF_SUBFRAME_PER_FRAME;
407 ptrLibConfig->nNrOfSlotInSf = pConfigParams->nNumOfSlotPerSubframe;
408 if (pConfigParams->nNumerology < 3)
410 ptrLibConfig->nSectorNum = psFPGAInitPara->nSecNum;
416 printf ("could not allocate ptrLibConfig in init_xran\n");
420 printf("nSectorNum %d\n", nSectorNum);
423 for(i = 0; i<nSectorNum; i++)
425 eInterfaceType = XRANFTHTX_OUT;
426 printf("nSectorIndex[%d] = %d\n",i, nSectorIndex[i]);
427 status = xran_bm_init(psBbuIo->nInstanceHandle[0][i], &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],
428 XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, nSW_ToFpga_FTH_TxBufferLen);
429 if(XRAN_STATUS_SUCCESS != status)
431 printf("Failed at xran_bm_init , status %d\n", status);
432 iAssert(status == XRAN_STATUS_SUCCESS);
434 for(j = 0; j < XRAN_N_FE_BUF_LEN; j++)
436 for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
437 psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].bValid = 0;
438 psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
439 psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
440 psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
441 psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
442 psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFrontHaulTxBuffers[j][i][z][0];
444 for(k = 0; k < XRAN_NUM_OF_SYMBOL_PER_SLOT; k++)
446 psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = nSW_ToFpga_FTH_TxBufferLen; // 14 symbols 3200bytes/symbol
447 psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
448 psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
449 status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i], psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
450 if(XRAN_STATUS_SUCCESS != status)
452 printf("Failed at xran_bm_allocate_buffer , status %d\n",status);
453 iAssert(status == XRAN_STATUS_SUCCESS);
455 psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
456 psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *)mb;
459 u32dptr = (uint32_t*)(ptr);
460 uint8_t *ptr_temp = (uint8_t *)ptr;
461 memset(u32dptr, 0xCC, nSW_ToFpga_FTH_TxBufferLen);
462 ptr_temp[0] = j; // TTI
463 ptr_temp[1] = i; // Sec
464 ptr_temp[2] = z; // Ant
465 ptr_temp[3] = k; // sym
472 eInterfaceType = XRANFTHTX_PRB_MAP_OUT;
473 printf("nSectorIndex[%d] = %d\n",i, nSectorIndex[i]);
474 status = xran_bm_init(psBbuIo->nInstanceHandle[0][i], &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],
475 XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, sizeof(struct xran_prb_map));
476 if(XRAN_STATUS_SUCCESS != status)
478 printf("Failed at xran_bm_init , status %d\n", status);
479 iAssert(status == XRAN_STATUS_SUCCESS);
481 for(j = 0; j < XRAN_N_FE_BUF_LEN; j++)
483 for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
484 psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0;
485 psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
486 psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
487 psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
488 psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
489 psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFrontHaulTxPrbMapBuffers[j][i][z];
492 psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nElementLenInBytes = sizeof(struct xran_prb_map);
493 psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nNumberOfElements = 1;
494 psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nOffsetInBytes = 0;
495 status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i], psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
496 if(XRAN_STATUS_SUCCESS != status)
498 printf("Failed at xran_bm_allocate_buffer , status %d\n",status);
499 iAssert(status == XRAN_STATUS_SUCCESS);
501 psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pData = (uint8_t *)ptr;
502 psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pCtrl = (void *)mb;
505 u32dptr = (uint32_t*)(ptr);
506 uint8_t *ptr_temp = (uint8_t *)ptr;
507 memset(u32dptr, 0xCC, sizeof(struct xran_prb_map));
508 ptr_temp[0] = j; // TTI
509 ptr_temp[1] = i; // Sec
510 ptr_temp[2] = z; // Ant
511 ptr_temp[3] = k; // sym
518 for(i = 0; i<nSectorNum; i++)
520 eInterfaceType = XRANFTHRX_IN;
521 status = xran_bm_init(psBbuIo->nInstanceHandle[0][i], &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType], XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, nSW_ToFpga_FTH_TxBufferLen);
522 if(XRAN_STATUS_SUCCESS != status)
524 printf("Failed at xran_bm_init, status %d\n", status);
525 iAssert(status == XRAN_STATUS_SUCCESS);
528 for(j = 0;j < XRAN_N_FE_BUF_LEN; j++)
530 for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
531 psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].bValid = 0;
532 psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
533 psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
534 psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
535 psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
536 psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFrontHaulRxBuffers[j][i][z][0];
537 for(k = 0; k< XRAN_NUM_OF_SYMBOL_PER_SLOT; k++)
539 psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = nFpgaToSW_FTH_RxBufferLen; // 1 symbols 3200bytes
540 psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
541 psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
542 status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i],psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
543 if(XRAN_STATUS_SUCCESS != status)
545 printf("Failed at xran_bm_allocate_buffer , status %d\n",status);
546 iAssert(status == XRAN_STATUS_SUCCESS);
548 psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
549 psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *) mb;
551 u32dptr = (uint32_t*)(ptr);
552 uint8_t *ptr_temp = (uint8_t *)ptr;
553 memset(u32dptr, 0xCC, nFpgaToSW_FTH_RxBufferLen);
554 ptr_temp[0] = j; // TTI
555 ptr_temp[1] = i; // Sec
556 ptr_temp[2] = z; // Ant
557 ptr_temp[3] = k; // sym
564 eInterfaceType = XRANFTHRX_PRB_MAP_IN;
565 status = xran_bm_init(psBbuIo->nInstanceHandle[0][i], &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],
566 XRAN_N_FE_BUF_LEN*XRAN_MAX_ANTENNA_NR*XRAN_NUM_OF_SYMBOL_PER_SLOT, sizeof(struct xran_prb_map));
567 if(XRAN_STATUS_SUCCESS != status)
569 printf("Failed at xran_bm_init, status %d\n", status);
570 iAssert(status == XRAN_STATUS_SUCCESS);
573 for(j = 0;j < XRAN_N_FE_BUF_LEN; j++)
575 for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
576 psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0;
577 psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
578 psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
579 psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
580 psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
581 psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFrontHaulRxPrbMapBuffers[j][i][z];
583 psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nElementLenInBytes = sizeof(struct xran_prb_map);
584 psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nNumberOfElements = 1;
585 psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nOffsetInBytes = 0;
586 status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i],psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
587 if(XRAN_STATUS_SUCCESS != status)
589 printf("Failed at xran_bm_allocate_buffer , status %d\n",status);
590 iAssert(status == XRAN_STATUS_SUCCESS);
592 psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pData = (uint8_t *)ptr;
593 psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pCtrl = (void *)mb;
595 u32dptr = (uint32_t*)(ptr);
596 uint8_t *ptr_temp = (uint8_t *)ptr;
597 memset(u32dptr, 0xCC, sizeof(struct xran_prb_map));
598 ptr_temp[0] = j; // TTI
599 ptr_temp[1] = i; // Sec
600 ptr_temp[2] = z; // Ant
601 ptr_temp[3] = k; // sym
608 // add prach rx buffer
609 for(i = 0; i<nSectorNum; i++)
611 eInterfaceType = XRANFTHRACH_IN;
612 status = xran_bm_init(psBbuIo->nInstanceHandle[0][i],&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);
613 if(XRAN_STATUS_SUCCESS != status)
615 printf("Failed at xran_bm_init, status %d\n", status);
616 iAssert(status == XRAN_STATUS_SUCCESS);
618 for(j = 0;j < XRAN_N_FE_BUF_LEN; j++)
620 for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
621 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].bValid = 0;
622 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
623 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
624 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
625 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_MAX_ANTENNA_NR; // ant number.
626 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFHPrachRxBuffers[j][i][z][0];
627 for(k = 0; k< XRAN_NUM_OF_SYMBOL_PER_SLOT; k++)
629 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = FPGA_TO_SW_PRACH_RX_BUFFER_LEN;
630 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
631 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
632 status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i],psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
633 if(XRAN_STATUS_SUCCESS != status)
635 printf("Failed at xran_bm_allocate_buffer, status %d\n",status);
636 iAssert(status == XRAN_STATUS_SUCCESS);
638 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
639 psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *)mb;
641 u32dptr = (uint32_t*)(ptr);
642 memset(u32dptr, 0xCC, FPGA_TO_SW_PRACH_RX_BUFFER_LEN);
649 for(i=0; i<nSectorNum; i++)
651 for(j=0; j<XRAN_N_FE_BUF_LEN; j++)
653 for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
654 pFthTxBuffer[i][z][j] = &(psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList);
655 pFthTxPrbMapBuffer[i][z][j] = &(psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList);
656 pFthRxBuffer[i][z][j] = &(psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList);
657 pFthRxPrbMapBuffer[i][z][j] = &(psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList);
658 pFthRxRachBuffer[i][z][j] = &(psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList);
663 if(NULL != psBbuIo->nInstanceHandle[0])
665 for (i = 0; i<nSectorNum; i++)
667 xran_5g_fronthault_config (psBbuIo->nInstanceHandle[0][i],
669 pFthTxPrbMapBuffer[i],
671 pFthRxPrbMapBuffer[i],
672 xran_fh_rx_callback, &pFthRxBuffer[i][0]);
675 // add prach callback here
676 for (i = 0; i<nSectorNum; i++)
678 xran_5g_prach_req(psBbuIo->nInstanceHandle[0][i], pFthRxRachBuffer[i],
679 xran_fh_rx_prach_callback,&pFthRxRachBuffer[i][0]);
681 ptrLibConfig->nFhBufIntFlag = 1;
687 int init_xran_iq_content(void)
689 BbuXranIoIfStruct *psBbuIo = xran_get_ctx();
690 xran_status_t status;
691 int32_t nSectorIndex[XRAN_MAX_SECTOR_NR];
693 int32_t cc_id, ant_id, sym_id, tti;
696 uint8_t frame_id = 0;
697 uint8_t subframe_id = 0;
707 struct xran_prb_map *pRbMap = NULL;
709 for (nSectorNum = 0; nSectorNum < XRAN_MAX_SECTOR_NR; nSectorNum++)
711 nSectorIndex[nSectorNum] = nSectorNum;
713 nSectorNum = numCCPorts;
714 printf ("init_xran_iq_content\n");
717 for(cc_id = 0; cc_id <nSectorNum; cc_id++)
719 for(tti = 0; tti < XRAN_N_FE_BUF_LEN; tti ++) {
720 for(ant_id = 0; ant_id < XRAN_MAX_ANTENNA_NR; ant_id++){
721 for(sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) {
723 flowId = XRAN_MAX_ANTENNA_NR*cc_id + ant_id;
725 if(p_tx_play_buffer[flowId]){
726 pos = ((char*)p_tx_play_buffer[flowId]) + tx_play_buffer_position[flowId];
727 ptr = psBbuIo->sFrontHaulTxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
730 u32dptr = (uint32_t*)(ptr);
731 rte_memcpy(u32dptr, pos, pXranConf->nDLRBs*N_SC_PER_PRB*4);
732 #ifdef DEBUG_XRAN_BUFFERS
733 uint8_t *ptr_temp = (uint8_t *)ptr;
734 ptr_temp[0] = tti; // TTI
735 ptr_temp[1] = cc_id; // Sec
736 ptr_temp[2] = ant_id; // Ant
737 ptr_temp[3] = sym_id; // sym
741 printf("ptr ==NULL\n");
745 pRbMap = (struct xran_prb_map *) psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers->pData;
747 pRbMap->dir = XRAN_DIR_DL;
748 pRbMap->xran_port = 0;
750 pRbMap->cc_id = cc_id;
751 pRbMap->ru_port_id = ant_id;
752 pRbMap->tti_id = tti;
753 pRbMap->start_sym_id = 0;
755 pRbMap->prbMap[0].nRBStart = 0;
756 pRbMap->prbMap[0].nRBSize = pXranConf->nDLRBs;
757 pRbMap->prbMap[0].nBeamIndex = 0;
758 pRbMap->prbMap[0].compMethod = XRAN_COMPMETHOD_NONE;
760 printf("DL pRbMap ==NULL\n");
765 pRbMap = (struct xran_prb_map *) psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers->pData;
767 pRbMap->dir = XRAN_DIR_UL;
768 pRbMap->xran_port = 0;
770 pRbMap->cc_id = cc_id;
771 pRbMap->ru_port_id = ant_id;
772 pRbMap->tti_id = tti;
773 pRbMap->start_sym_id = 0;
775 pRbMap->prbMap[0].nRBStart = 0;
776 pRbMap->prbMap[0].nRBSize = pXranConf->nULRBs;
777 pRbMap->prbMap[0].nBeamIndex = 0;
778 pRbMap->prbMap[0].compMethod = XRAN_COMPMETHOD_NONE;
780 printf("UL: pRbMap ==NULL\n");
784 tx_play_buffer_position[flowId] += pXranConf->nDLRBs*N_SC_PER_PRB*4;
786 if(tx_play_buffer_position[flowId] >= tx_play_buffer_size[flowId])
787 tx_play_buffer_position[flowId] = 0;
789 //printf("flowId %d\n", flowId);
794 /* prach TX for RU only */
795 if(startupConfiguration.appMode == APP_O_RU && startupConfiguration.enablePrach){
796 for(ant_id = 0; ant_id < XRAN_MAX_ANTENNA_NR; ant_id++){
797 for(sym_id = 0; sym_id < 1; sym_id++) {
798 flowId = XRAN_MAX_ANTENNA_NR*cc_id + ant_id;
800 if(p_tx_prach_play_buffer[flowId]){
801 /* (0-79 slots) 10ms of IQs */
802 pos = ((char*)p_tx_prach_play_buffer[flowId]);
804 ptr = psBbuIo->sFHPrachRxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
807 u32dptr = (uint32_t*)(ptr);
808 rte_memcpy(u32dptr, pos, PRACH_PLAYBACK_BUFFER_BYTES);
809 #ifdef DEBUG_XRAN_BUFFERS
810 uint8_t *ptr_temp = (uint8_t *)ptr;
811 ptr_temp[0] = tti; // TTI
812 ptr_temp[1] = cc_id; // Sec
813 ptr_temp[2] = ant_id; // Ant
814 ptr_temp[3] = sym_id; // sym
818 printf("ptr ==NULL\n");
821 //printf("flowId %d\n", flowId);
834 xran_status_t status = 0;
835 SWXRANInterfaceTypeEnum eInterfaceType;
837 free(gpXranLibConfig);
838 gpXranLibConfig = NULL;
840 status += xran_mm_destroy(xranHandle)*2;
842 if(XRAN_STATUS_SUCCESS != status)
844 printf("Failed at xran_mm_destroy, status %d\n",status);
845 iAssert(status == XRAN_STATUS_SUCCESS);
849 int get_xran_iq_content(void)
851 BbuXranIoIfStruct *psBbuIo = xran_get_ctx();
852 xran_status_t status;
853 int32_t nSectorIndex[XRAN_MAX_SECTOR_NR];
855 int32_t cc_id, ant_id, sym_id, tti;
858 uint8_t frame_id = 0;
859 uint8_t subframe_id = 0;
870 for (nSectorNum = 0; nSectorNum < XRAN_MAX_SECTOR_NR; nSectorNum++)
872 nSectorIndex[nSectorNum] = nSectorNum;
874 nSectorNum = numCCPorts;
875 printf ("get_xran_iq_content\n");
878 for(cc_id = 0; cc_id <nSectorNum; cc_id++)
880 for(tti = 0; tti < XRAN_N_FE_BUF_LEN; tti++) {
881 for(ant_id = 0; ant_id < XRAN_MAX_ANTENNA_NR; ant_id++){
882 for(sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) {
883 flowId = XRAN_MAX_ANTENNA_NR * cc_id + ant_id;
884 if(p_rx_log_buffer[flowId]){
885 /* (0-79 slots) 10ms of IQs */
886 pos = ((char*)p_rx_log_buffer[flowId]) + rx_log_buffer_position[flowId];
887 ptr = psBbuIo->sFrontHaulRxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
889 u32dptr = (uint32_t*)(ptr);
890 rte_memcpy(pos, u32dptr, pXranConf->nULRBs*N_SC_PER_PRB*4);
891 #ifdef DEBUG_XRAN_BUFFERS
896 printf("[flowId %d] %d %d %d %d\n", flowId, pos[0], pos[1], pos[2], pos[3]);
900 printf("ptr ==NULL\n");
902 rx_log_buffer_position[flowId] += pXranConf->nULRBs*N_SC_PER_PRB*4;
904 if(rx_log_buffer_position[flowId] >= rx_log_buffer_size[flowId])
905 rx_log_buffer_position[flowId] = 0;
907 //printf("flowId %d\n", flowId);
911 /* prach RX for O-DU only */
912 if(startupConfiguration.appMode == APP_O_DU){
913 flowId = XRAN_MAX_ANTENNA_NR * cc_id + ant_id;
916 if(p_prach_log_buffer[flowId]){
917 /* (0-79 slots) 10ms of IQs */
918 pos = ((char*)p_prach_log_buffer[flowId]) + prach_log_buffer_position[flowId];
919 ptr = psBbuIo->sFHPrachRxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
921 u32dptr = (uint32_t*)(ptr);
922 rte_memcpy(pos, u32dptr, PRACH_PLAYBACK_BUFFER_BYTES);
923 #ifdef DEBUG_XRAN_BUFFERS
928 printf("[flowId %d] %d %d %d %d\n", flowId, pos[0], pos[1], pos[2], pos[3]);
932 printf("ptr ==NULL\n");
934 prach_log_buffer_position[flowId] += PRACH_PLAYBACK_BUFFER_BYTES;
936 if(prach_log_buffer_position[flowId] >= prach_log_buffer_size[flowId])
937 prach_log_buffer_position[flowId] = 0;
939 //printf("flowId %d\n", flowId);
950 void version_print(void)
952 char sysversion[100];
953 char *compilation_date = __DATE__;
954 char *compilation_time = __TIME__;
959 snprintf(sysversion, 99, "Version: %s", VERSIONX);
960 nLen = strlen(sysversion);
963 printf("===========================================================================================================\n");
964 printf("SAMPLE-APP VERSION\n");
965 printf("===========================================================================================================\n");
967 printf("%s\n", sysversion);
968 printf("build-date: %s\n", compilation_date);
969 printf("build-time: %s\n", compilation_time);
972 int main(int argc, char *argv[])
978 uint32_t nCenterFreq;
980 struct stat st = {0};
981 uint32_t filenameLength = strlen(argv[1]);
982 char *pCheckName1 = NULL, *pCheckName2 = NULL;
983 enum xran_if_state xran_curr_if_state = XRAN_INIT;
986 errx(2, "Need two argument - the PCI address of the network port");
987 if (filenameLength >= 64)
989 printf("Config file name input is too long, exiting!\n");
996 len = strlen(argv[1]) + 1;
997 if (len > (sizeof(filename) - 10))
998 len = (sizeof(filename) - 10);
999 strncpy(filename, argv[1], (sizeof(filename) - 10));
1000 filename[len] = '\0';
1002 pCheckName1 = strstr(filename, "config_file_o_du.dat");
1003 pCheckName2 = strstr(filename, "config_file_o_ru.dat");
1004 if ((pCheckName1 == NULL) && (pCheckName2 == NULL))
1006 printf("config file name %s is not valid!\n", filename);
1010 if (xran_is_synchronized() != 0)
1011 printf("Machine is not synchronized using PTP!\n");
1013 printf("Machine is synchronized using PTP!\n");
1015 memset(&startupConfiguration, 0, sizeof(RuntimeConfig));
1017 if (parseConfigFile(filename, (RuntimeConfig*)&startupConfiguration) != 0) {
1018 printf("Configuration file error.\n");
1022 if(startupConfiguration.ant_file[0] == NULL){
1023 printf("it looks like test vector for antennas were not provided\n");
1026 if (startupConfiguration.numCC > XRAN_MAX_SECTOR_NR)
1028 printf("Number of cells %d exceeds max number supported %d!\n", startupConfiguration.numCC, XRAN_MAX_SECTOR_NR);
1029 startupConfiguration.numCC = XRAN_MAX_SECTOR_NR;
1032 numCCPorts = startupConfiguration.numCC;
1033 num_eAxc = startupConfiguration.numAxc;
1035 printf("numCCPorts %d num_eAxc%d\n", numCCPorts, num_eAxc);
1037 if (startupConfiguration.mu_number <= 1){
1038 nFpgaToSW_FTH_RxBufferLen = 13168; /* 273*12*4 + 64*/
1039 nFpgaToSW_PRACH_RxBufferLen = 8192;
1040 nSW_ToFpga_FTH_TxBufferLen = 13168; /* 273*12*4 + 64*/
1041 } else if (startupConfiguration.mu_number == 3){
1042 nFpgaToSW_FTH_RxBufferLen = 3328;
1043 nFpgaToSW_PRACH_RxBufferLen = 8192;
1044 nSW_ToFpga_FTH_TxBufferLen = 3328;
1046 printf("given numerology is not supported %d\n", startupConfiguration.mu_number);
1050 memset(&xranInit, 0, sizeof(struct xran_fh_init));
1052 if(startupConfiguration.appMode == APP_O_DU) {
1053 printf("set O-DU\n");
1054 xranInit.io_cfg.id = 0;//ID_LLS_CU;
1055 xranInit.io_cfg.core = 4+1;
1056 xranInit.io_cfg.system_core = 0;
1057 xranInit.io_cfg.pkt_proc_core = 4+2;
1058 xranInit.io_cfg.pkt_aux_core = 0; /* do not start*/
1059 xranInit.io_cfg.timing_core = 4+3;
1061 printf("set O-DU\n");
1062 xranInit.io_cfg.id = 1; /* ID_LLS_CU;*/
1063 xranInit.io_cfg.core = 1;
1064 xranInit.io_cfg.system_core = 0;
1065 xranInit.io_cfg.pkt_proc_core = 2;
1066 xranInit.io_cfg.pkt_aux_core = 0; /* do not start */
1067 xranInit.io_cfg.timing_core = 3;
1070 xranInit.io_cfg.bbdev_mode = XRAN_BBDEV_NOT_USED;
1072 xranInit.eAxCId_conf.mask_cuPortId = 0xf000;
1073 xranInit.eAxCId_conf.mask_bandSectorId = 0x0f00;
1074 xranInit.eAxCId_conf.mask_ccId = 0x00f0;
1075 xranInit.eAxCId_conf.mask_ruPortId = 0x000f;
1076 xranInit.eAxCId_conf.bit_cuPortId = 12;
1077 xranInit.eAxCId_conf.bit_bandSectorId = 8;
1078 xranInit.eAxCId_conf.bit_ccId = 4;
1079 xranInit.eAxCId_conf.bit_ruPortId = 0;
1081 xranInit.io_cfg.dpdk_dev[XRAN_UP_VF] = argv[2];
1082 xranInit.io_cfg.dpdk_dev[XRAN_CP_VF] = argv[3];
1083 xranInit.mtu = startupConfiguration.mtu;
1085 xranInit.p_o_du_addr = (int8_t*)&startupConfiguration.o_du_addr;
1086 xranInit.p_o_ru_addr = (int8_t*)&startupConfiguration.o_ru_addr;
1087 xranInit.filePrefix = "wls";
1088 xranInit.xranCat = XRAN_CATRGORY_A;
1090 xranInit.Tadv_cp_dl = startupConfiguration.Tadv_cp_dl;
1091 xranInit.T2a_min_cp_dl = startupConfiguration.T2a_min_cp_dl;
1092 xranInit.T2a_max_cp_dl = startupConfiguration.T2a_max_cp_dl;
1093 xranInit.T2a_min_cp_ul = startupConfiguration.T2a_min_cp_ul;
1094 xranInit.T2a_max_cp_ul = startupConfiguration.T2a_max_cp_ul;
1095 xranInit.T2a_min_up = startupConfiguration.T2a_min_up;
1096 xranInit.T2a_max_up = startupConfiguration.T2a_max_up;
1097 xranInit.Ta3_min = startupConfiguration.Ta3_min;
1098 xranInit.Ta3_max = startupConfiguration.Ta3_max;
1099 xranInit.T1a_min_cp_dl = startupConfiguration.T1a_min_cp_dl;
1100 xranInit.T1a_max_cp_dl = startupConfiguration.T1a_max_cp_dl;
1101 xranInit.T1a_min_cp_ul = startupConfiguration.T1a_min_cp_ul;
1102 xranInit.T1a_max_cp_ul = startupConfiguration.T1a_max_cp_ul;
1103 xranInit.T1a_min_up = startupConfiguration.T1a_min_up;
1104 xranInit.T1a_max_up = startupConfiguration.T1a_max_up;
1105 xranInit.Ta4_min = startupConfiguration.Ta4_min;
1106 xranInit.Ta4_max = startupConfiguration.Ta4_max;
1108 xranInit.enableCP = startupConfiguration.enableCP;
1109 xranInit.prachEnable = startupConfiguration.enablePrach;
1110 xranInit.debugStop = startupConfiguration.debugStop;
1111 xranInit.debugStopCount = startupConfiguration.debugStopCount;
1112 xranInit.DynamicSectionEna = startupConfiguration.DynamicSectionEna;
1113 xranInit.io_cfg.bbdev_mode = XRAN_BBDEV_NOT_USED; //startupConfiguration.bbdevMode;
1115 xranInit.cp_vlan_tag = startupConfiguration.cp_vlan_tag;
1116 xranInit.up_vlan_tag = startupConfiguration.up_vlan_tag;
1118 printf("IQ files size is %d slots\n", startupConfiguration.numSlots);
1120 iq_playback_buffer_size_dl = (startupConfiguration.numSlots * N_SYM_PER_SLOT * N_SC_PER_PRB *
1121 app_xran_get_num_rbs(startupConfiguration.mu_number, startupConfiguration.nDLBandwidth, startupConfiguration.nDLAbsFrePointA)
1124 iq_playback_buffer_size_ul = (startupConfiguration.numSlots * N_SYM_PER_SLOT * N_SC_PER_PRB *
1125 app_xran_get_num_rbs(startupConfiguration.mu_number, startupConfiguration.nULBandwidth, startupConfiguration.nULAbsFrePointA)
1128 for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1130 p_tx_play_buffer[i] = (int16_t*)malloc(iq_playback_buffer_size_dl);
1131 tx_play_buffer_size[i] = (int32_t)iq_playback_buffer_size_dl;
1133 if (p_tx_play_buffer[i] == NULL)
1136 tx_play_buffer_size[i] = sys_load_file_to_buff(startupConfiguration.ant_file[i],
1137 "DL IFFT IN IQ Samples in binary format",
1138 (uint8_t*) p_tx_play_buffer[i],
1139 tx_play_buffer_size[i],
1141 tx_play_buffer_position[i] = 0;
1144 if (startupConfiguration.appMode == APP_O_RU && startupConfiguration.enablePrach){
1145 for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1146 p_tx_prach_play_buffer[i] = (int16_t*)malloc(PRACH_PLAYBACK_BUFFER_BYTES);
1147 tx_prach_play_buffer_size[i] = (int32_t)PRACH_PLAYBACK_BUFFER_BYTES;
1149 if (p_tx_prach_play_buffer[i] == NULL)
1152 tx_prach_play_buffer_size[i] = sys_load_file_to_buff(startupConfiguration.prach_file[i],
1153 "PRACH IQ Samples in binary format",
1154 (uint8_t*) p_tx_prach_play_buffer[i],
1155 tx_prach_play_buffer_size[i],
1157 tx_prach_play_buffer_position[i] = 0;
1161 for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1163 p_rx_log_buffer[i] = (int16_t*)malloc(iq_playback_buffer_size_ul);
1164 rx_log_buffer_size[i] = (int32_t)iq_playback_buffer_size_ul;
1166 if (p_rx_log_buffer[i] == NULL)
1169 rx_log_buffer_position[i] = 0;
1171 memset(p_rx_log_buffer[i], 0, rx_log_buffer_size[i]);
1175 for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1177 p_prach_log_buffer[i] = (int16_t*)malloc(startupConfiguration.numSlots*PRACH_PLAYBACK_BUFFER_BYTES);
1178 prach_log_buffer_size[i] = (int32_t)startupConfiguration.numSlots*PRACH_PLAYBACK_BUFFER_BYTES;
1180 if (p_prach_log_buffer[i] == NULL)
1183 memset(p_prach_log_buffer[i], 0, prach_log_buffer_size[i]);
1184 prach_log_buffer_position[i] = 0;
1187 if (stat("./logs", &st) == -1) {
1188 mkdir("./logs", 0777);
1191 for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1193 sprintf(filename, "./logs/%s-play_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
1194 sys_save_buf_to_file_txt(filename,
1195 "DL IFFT IN IQ Samples in human readable format",
1196 (uint8_t*) p_tx_play_buffer[i],
1197 tx_play_buffer_size[i],
1200 sprintf(filename, "./logs/%s-play_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
1201 sys_save_buf_to_file(filename,
1202 "DL IFFT IN IQ Samples in binary format",
1203 (uint8_t*) p_tx_play_buffer[i],
1204 tx_play_buffer_size[i]/sizeof(short),
1207 if (startupConfiguration.appMode == APP_O_RU && startupConfiguration.enablePrach){
1208 sprintf(filename, "./logs/%s-play_prach_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
1209 sys_save_buf_to_file_txt(filename,
1210 "DL IFFT IN IQ Samples in human readable format",
1211 (uint8_t*) p_tx_prach_play_buffer[i],
1212 tx_prach_play_buffer_size[i],
1215 sprintf(filename, "./logs/%s-play_prach_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
1216 sys_save_buf_to_file(filename,
1217 "DL IFFT IN IQ Samples in binary format",
1218 (uint8_t*) p_tx_prach_play_buffer[i],
1219 tx_prach_play_buffer_size[i]/sizeof(short),
1223 if (startupConfiguration.iqswap == 1){
1224 for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1225 printf("TX: Swap I and Q to match RU format: [%d]\n",i);
1229 signed short *ptr = (signed short *) p_tx_play_buffer[i];
1232 for (j = 0; j < (int32_t)(tx_play_buffer_size[i]/sizeof(short)) ; j = j + 2){
1234 ptr[j] = ptr[j + 1];
1239 if (startupConfiguration.appMode == APP_O_RU){
1240 for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1241 printf("PRACH: Swap I and Q to match RU format: [%d]\n",i);
1245 signed short *ptr = (signed short *) p_tx_prach_play_buffer[i];
1248 for (j = 0; j < (int32_t)(tx_prach_play_buffer_size[i]/sizeof(short)) ; j = j + 2){
1250 ptr[j] = ptr[j + 1];
1260 for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1262 sprintf(filename, "./logs/swap_IQ_play_ant%d.txt", i);
1263 sys_save_buf_to_file_txt(filename,
1264 "DL IFFT IN IQ Samples in human readable format",
1265 (uint8_t*) p_tx_play_buffer[i],
1266 tx_play_buffer_size[i],
1270 if (startupConfiguration.nebyteorderswap == 1){
1271 for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1272 printf("TX: Convert S16 I and S16 Q to network byte order for XRAN Ant: [%d]\n",i);
1273 for (j = 0; j < tx_play_buffer_size[i]/sizeof(short); j++){
1274 p_tx_play_buffer[i][j] = rte_cpu_to_be_16(p_tx_play_buffer[i][j]);
1278 if (startupConfiguration.appMode == APP_O_RU){
1279 for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1280 printf("PRACH: Convert S16 I and S16 Q to network byte order for XRAN Ant: [%d]\n",i);
1281 for (j = 0; j < tx_prach_play_buffer_size[i]/sizeof(short); j++){
1282 p_tx_prach_play_buffer[i][j] = rte_cpu_to_be_16(p_tx_prach_play_buffer[i][j]);
1289 for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1291 sprintf(filename, "./logs/swap_be_play_ant%d.txt", i);
1292 sys_save_buf_to_file_txt(filename,
1293 "DL IFFT IN IQ Samples in human readable format",
1294 (uint8_t*) p_tx_play_buffer[i],
1295 tx_play_buffer_size[i],
1301 timer_set_tsc_freq_from_clock();
1302 xret = xran_init(argc, argv, &xranInit, argv[0], &xranHandle);
1303 if(xret != XRAN_STATUS_SUCCESS){
1304 printf("xran_init failed %d\n", xret);
1308 if(xranHandle == NULL)
1311 memset(&xranConf, 0, sizeof(struct xran_fh_config));
1312 pXranConf = &xranConf;
1314 pXranConf->sector_id = 0;
1315 pXranConf->nCC = numCCPorts;
1316 pXranConf->neAxc = num_eAxc;
1318 pXranConf->frame_conf.nFrameDuplexType = startupConfiguration.nFrameDuplexType;
1319 pXranConf->frame_conf.nNumerology = startupConfiguration.mu_number;
1320 pXranConf->frame_conf.nTddPeriod = startupConfiguration.nTddPeriod;
1322 for (i = 0; i < startupConfiguration.nTddPeriod; i++){
1323 pXranConf->frame_conf.sSlotConfig[i] = startupConfiguration.sSlotConfig[i];
1326 pXranConf->prach_conf.nPrachSubcSpacing = startupConfiguration.mu_number;
1327 pXranConf->prach_conf.nPrachFreqStart = 0;
1328 pXranConf->prach_conf.nPrachFilterIdx = XRAN_FILTERINDEX_PRACH_ABC;
1329 pXranConf->prach_conf.nPrachConfIdx = startupConfiguration.prachConfigIndex;
1330 pXranConf->prach_conf.nPrachFreqOffset = -792;
1332 pXranConf->ru_conf.iqWidth = 16;
1333 pXranConf->ru_conf.compMeth = XRAN_COMPMETHOD_NONE;
1334 pXranConf->ru_conf.fftSize = 0;
1335 while (startupConfiguration.nULFftSize >>= 1)
1336 ++pXranConf->ru_conf.fftSize;
1338 pXranConf->ru_conf.byteOrder = (startupConfiguration.nebyteorderswap == 1) ? XRAN_NE_BE_BYTE_ORDER : XRAN_CPU_LE_BYTE_ORDER ;
1339 pXranConf->ru_conf.iqOrder = (startupConfiguration.iqswap == 1) ? XRAN_Q_I_ORDER : XRAN_I_Q_ORDER;
1341 printf("FFT Order %d\n", pXranConf->ru_conf.fftSize);
1343 pXranConf->nDLRBs = app_xran_get_num_rbs(startupConfiguration.mu_number, startupConfiguration.nDLBandwidth, startupConfiguration.nDLAbsFrePointA);
1344 pXranConf->nULRBs = app_xran_get_num_rbs(startupConfiguration.mu_number, startupConfiguration.nULBandwidth, startupConfiguration.nULAbsFrePointA);
1346 nCenterFreq = startupConfiguration.nDLAbsFrePointA + (((pXranConf->nDLRBs * N_SC_PER_PRB) / 2) * app_xran_get_scs(startupConfiguration.mu_number));
1347 pXranConf->nDLCenterFreqARFCN = app_xran_cal_nrarfcn(nCenterFreq);
1348 printf("DL center freq %d DL NR-ARFCN %d\n", nCenterFreq, pXranConf->nDLCenterFreqARFCN);
1350 nCenterFreq = startupConfiguration.nULAbsFrePointA + (((pXranConf->nULRBs * N_SC_PER_PRB) / 2) * app_xran_get_scs(startupConfiguration.mu_number));
1351 pXranConf->nULCenterFreqARFCN = app_xran_cal_nrarfcn(nCenterFreq);
1352 printf("UL center freq %d UL NR-ARFCN %d\n", nCenterFreq, pXranConf->nULCenterFreqARFCN);
1354 pXranConf->bbdev_dec = NULL;
1355 pXranConf->bbdev_enc = NULL;
1357 if(init_xran() != 0)
1360 xran_reg_physide_cb(xranHandle, physide_dl_tti_call_back, NULL, 10, XRAN_CB_TTI);
1361 xran_reg_physide_cb(xranHandle, physide_ul_half_slot_call_back, NULL, 10, XRAN_CB_HALF_SLOT_RX);
1362 xran_reg_physide_cb(xranHandle, physide_ul_full_slot_call_back, NULL, 10, XRAN_CB_FULL_SLOT_RX);
1364 init_xran_iq_content();
1366 xret = xran_open(xranHandle, pXranConf);
1368 if(xret != XRAN_STATUS_SUCCESS){
1369 printf("xran_open failed %d\n", xret);
1373 sprintf(filename, "mlog-%s", startupConfiguration.appMode == 0 ? "o-du" : "o-ru");
1375 // MLogOpen(0, 32, 0, 0xFFFFFFFF, filename);
1377 MLogOpen(256, 3, 20000, 0xFFFFFFFF, filename);
1379 puts("----------------------------------------");
1380 printf("MLog Info: virt=0x%016lx size=%d\n", MLogGetFileLocation(), MLogGetFileSize());
1381 puts("----------------------------------------");
1384 uint64_t nActiveCoreMask[MAX_BBU_POOL_CORE_MASK] = {0};
1385 nActiveCoreMask[0] = 1 << xranInit.io_cfg.timing_core;
1386 uint32_t numCarriers = startupConfiguration.numCC;
1388 MLogAddTestCase(nActiveCoreMask, numCarriers);
1390 fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);
1392 state = APP_RUNNING;
1393 printf("Start XRAN traffic\n");
1394 xran_start(xranHandle);
1398 struct xran_common_counters x_counters;
1401 xran_curr_if_state = xran_get_if_state();
1402 if(xran_get_common_counters(xranHandle, &x_counters) == XRAN_STATUS_SUCCESS) {
1403 printf("rx %ld tx %ld [on_time %ld early %ld late %ld corrupt %ld pkt_dupl %ld Total %ld\n", rx_counter, tx_counter,
1404 x_counters.Rx_on_time,
1405 x_counters.Rx_early,
1407 x_counters.Rx_corrupt,
1408 x_counters.Rx_pkt_dupl,
1409 x_counters.Total_msgs_rcvd);
1411 printf("error xran_get_common_counters\n");
1414 if (xran_curr_if_state == XRAN_STOPPED){
1417 if (NULL == fgets(input, 10, stdin)) {
1421 const int sel_opt = atoi(input);
1424 xran_start(xranHandle);
1425 printf("Start XRAN traffic\n");
1430 xran_stop(xranHandle);
1431 printf("Stop XRAN traffic\n");
1432 state = APP_STOPPED;
1435 puts("Wrong option passed!");
1438 if (APP_STOPPED == state)
1442 get_xran_iq_content();
1444 puts("Closing l1 app... Ending all threads...");
1445 xran_close(xranHandle);
1449 puts("Dump IQs...");
1451 if (startupConfiguration.iqswap == 1){
1452 for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1453 printf("RX: Swap I and Q to match CPU format: [%d]\n",i);
1457 signed short *ptr = (signed short *) p_rx_log_buffer[i];
1460 for (j = 0; j < (int32_t)(rx_log_buffer_size[i]/sizeof(short)) ; j = j + 2){
1462 ptr[j] = ptr[j + 1];
1469 if (startupConfiguration.nebyteorderswap == 1){
1470 for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1471 printf("RX: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [%d]\n",i);
1472 for (j = 0; j < rx_log_buffer_size[i]/sizeof(short); j++){
1473 p_rx_log_buffer[i][j] = rte_be_to_cpu_16(p_rx_log_buffer[i][j]);
1478 for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1480 sprintf(filename, "./logs/%s-rx_log_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
1481 sys_save_buf_to_file_txt(filename,
1482 "UL FFT OUT IQ Samples in human readable format",
1483 (uint8_t*) p_rx_log_buffer[i],
1484 rx_log_buffer_size[i],
1487 sprintf(filename, "./logs/%s-rx_log_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
1488 sys_save_buf_to_file(filename,
1489 "UL FFT OUT IQ Samples in binary format",
1490 (uint8_t*) p_rx_log_buffer[i],
1491 rx_log_buffer_size[i]/sizeof(short),
1495 if (startupConfiguration.appMode == APP_O_DU && startupConfiguration.enablePrach){
1496 if (startupConfiguration.iqswap == 1){
1497 for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1498 printf("PRACH: Swap I and Q to match CPU format: [%d]\n",i);
1502 signed short *ptr = (signed short *) p_prach_log_buffer[i];
1505 for (j = 0; j < (int32_t)(prach_log_buffer_size[i]/sizeof(short)) ; j = j + 2){
1507 ptr[j] = ptr[j + 1];
1515 if (startupConfiguration.nebyteorderswap == 1){
1516 for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1517 printf("PRACH: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [%d]\n",i);
1518 for (j = 0; j < prach_log_buffer_size[i]/sizeof(short); j++){
1519 p_prach_log_buffer[i][j] = rte_be_to_cpu_16(p_prach_log_buffer[i][j]);
1525 for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
1527 sprintf(filename, "./logs/%s-prach_log_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
1528 sys_save_buf_to_file_txt(filename,
1529 "PRACH FFT OUT IQ Samples in human readable format",
1530 (uint8_t*) p_prach_log_buffer[i],
1531 prach_log_buffer_size[i],
1534 sprintf(filename, "./logs/%s-prach_log_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
1535 sys_save_buf_to_file(filename,
1536 "PRACH FFT OUT IQ Samples in binary format",
1537 (uint8_t*) p_prach_log_buffer[i],
1538 prach_log_buffer_size[i]/sizeof(short),