/****************************************************************************** * * Copyright (c) 2019 Intel. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *******************************************************************************/ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "common.h" #include "config.h" #include "xran_mlog_lnx.h" #include "xran_fh_o_du.h" #include "xran_compression.h" #include "xran_cp_api.h" #include "xran_sync_api.h" #include "xran_mlog_task_id.h" #define MAX_BBU_POOL_CORE_MASK (4) #define SW_FPGA_TOTAL_BUFFER_LEN 4*1024*1024*1024 #define SW_FPGA_SEGMENT_BUFFER_LEN 1*1024*1024*1024 #define SW_FPGA_FH_TOTAL_BUFFER_LEN 1*1024*1024*1024 #define FPGA_TO_SW_PRACH_RX_BUFFER_LEN (8192) #define NSEC_PER_SEC 1000000000 #define MAX_PKT_BURST (448+4) // 4x14x8 #define N_MAX_BUFFER_SEGMENT MAX_PKT_BURST #define MAIN_PRIORITY 98 #define NUM_OF_SUBFRAME_PER_FRAME (10) enum app_state state; uint64_t tick_per_usec; static volatile uint64_t timer_last_irq_tick = 0; static uint64_t tsc_resolution_hz = 0; RuntimeConfig startupConfiguration = {0}; /* buffers size */ uint32_t nFpgaToSW_FTH_RxBufferLen; uint32_t nFpgaToSW_PRACH_RxBufferLen; uint32_t nSW_ToFpga_FTH_TxBufferLen; static struct xran_fh_init xranInit; void * xranHandle = NULL; struct xran_fh_config xranConf; struct xran_fh_config *pXranConf = NULL; typedef struct { uint32_t phaseFlag :1; uint32_t NRARFCN :22; uint32_t SULFreShift :1; uint32_t SULFlag :1; uint32_t rsv :7; }FPGAPhaseCompCfg; typedef struct XranLibConfig { uint32_t nDriverCoreId; uint32_t nTimingAdvance; uint32_t nFhConfig; uint32_t nFhBufIntFlag; uint32_t nSectorNum; uint32_t nNrOfSlotInSf; uint32_t nNrofSfInFrame; void * pFthInstanceHandles; }XranLibConfigStruct; typedef enum { XRANFTHTX_OUT = 0, XRANFTHTX_PRB_MAP_OUT, XRANFTHTX_SEC_DESC_OUT, XRANFTHRX_IN, XRANFTHRX_PRB_MAP_IN, XRANFTHTX_SEC_DESC_IN, XRANFTHRACH_IN, XRANSRS_IN, MAX_SW_XRAN_INTERFACE_NUM }SWXRANInterfaceTypeEnum; /* * manage one cell's all Ethernet frames for one DL or UL LTE subframe */ typedef struct { /* -1-this subframe is not used in current frame format 0-this subframe can be transmitted, i.e., data is ready 1-this subframe is waiting transmission, i.e., data is not ready 10 - DL transmission missing deadline. When FE needs this subframe data but bValid is still 1, set bValid to 10. */ int32_t bValid ; // when UL rx, it is subframe index. int32_t nSegToBeGen; int32_t nSegGenerated; // how many date segment are generated by DL LTE processing or received from FE // -1 means that DL packet to be transmitted is not ready in BS int32_t nSegTransferred; // number of data segments has been transmitted or received struct rte_mbuf *pData[N_MAX_BUFFER_SEGMENT]; // point to DPDK allocated memory pool struct xran_buffer_list sBufferList; } BbuIoBufCtrlStruct; typedef struct { uint64_t nCoreMask; int16_t cpuSocketId; uint8_t nDriverCoreId; uint8_t nFHCoreId; struct rte_mempool *bbuio_buf_pool; /* io struct */ BbuIoBufCtrlStruct sFrontHaulTxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR]; BbuIoBufCtrlStruct sFrontHaulTxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR]; BbuIoBufCtrlStruct sFrontHaulRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR]; BbuIoBufCtrlStruct sFrontHaulRxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR]; BbuIoBufCtrlStruct sFHPrachRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR]; /* Cat B */ BbuIoBufCtrlStruct sFHSrsRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANT_ARRAY_ELM_NR]; /* buffers lists */ struct xran_flat_buffer sFrontHaulTxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT]; struct xran_flat_buffer sFrontHaulTxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR]; struct xran_flat_buffer sFrontHaulRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT]; struct xran_flat_buffer sFrontHaulRxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR]; struct xran_flat_buffer sFHPrachRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT]; /* Cat B SRS buffers */ struct xran_flat_buffer sFHSrsRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANT_ARRAY_ELM_NR][XRAN_MAX_NUM_OF_SRS_SYMBOL_PER_SLOT]; void* nInstanceHandle[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR]; // instance per sector uint32_t nBufPoolIndex[XRAN_MAX_SECTOR_NR][MAX_SW_XRAN_INTERFACE_NUM]; // every api owns unique buffer pool uint16_t nInstanceNum; uint64_t nTscTiming[XRAN_N_FE_BUF_LEN]; // records the TSC when a timing packet is received. } BbuXranIoIfStruct; static BbuXranIoIfStruct gsXranIoIf; static XranLibConfigStruct *gpXranLibConfig = NULL; extern long rx_counter; extern long tx_counter; extern long tx_bytes_counter; extern long rx_bytes_counter; extern long tx_bytes_per_sec; extern long rx_bytes_per_sec; long old_rx_counter = 0; long old_tx_counter = 0; #define CPU_HZ tick_per_usec //us /* Application User space functions */ void xran_fh_rx_callback(void *pCallbackTag, int32_t status); void xran_fh_rx_prach_callback(void *pCallbackTag, int32_t status); static BbuXranIoIfStruct *xran_get_ctx(void) { return &gsXranIoIf; } static void print_menu() { puts("+---------------------------------------+"); puts("| Press 1 to start 5G NR XRAN traffic |"); puts("| Press 2 reserved for future use |"); puts("| Press 3 to quit |"); puts("+---------------------------------------+"); } static int32_t get_xran_sfidx(uint8_t nNrOfSlotInSf) { int32_t nSfIdx = -1; uint32_t nFrameIdx; uint32_t nSubframeIdx; uint32_t nSlotIdx; uint64_t nSecond; uint32_t nXranTime = xran_get_slot_idx(&nFrameIdx, &nSubframeIdx, &nSlotIdx, &nSecond); nSfIdx = nFrameIdx*NUM_OF_SUBFRAME_PER_FRAME*nNrOfSlotInSf + nSubframeIdx*nNrOfSlotInSf + nSlotIdx; #if 0 printf("\nxranTime is %d, return is %d, radio frame is %d, subframe is %d slot is %d tsc is %llu us", nXranTime, nSfIdx, nFrameIdx, nSubframeIdx, nSlotIdx, __rdtsc()/CPU_HZ); #endif return nSfIdx; } void xran_fh_rx_callback(void *pCallbackTag, xran_status_t status) { uint64_t t1 = MLogTick(); uint32_t mlogVar[10]; uint32_t mlogVarCnt = 0; uint8_t Numerlogy = xranConf.frame_conf.nNumerology; uint8_t nNrOfSlotInSf = 1<> 16; /* tti */ mlogVar[mlogVarCnt++] = status & 0xFF; /* sym */ mlogVar[mlogVarCnt++] = (uint32_t)sfIdx; MLogAddVariables(mlogVarCnt, mlogVar, MLogTick()); rte_pause(); MLogTask(PID_GNB_SYM_CB, t1, MLogTick()); return; } void xran_fh_rx_prach_callback(void *pCallbackTag, xran_status_t status) { uint64_t t1 = MLogTick(); uint32_t mlogVar[10]; uint32_t mlogVarCnt = 0; mlogVar[mlogVarCnt++] = 0xDDDDDDDD; mlogVar[mlogVarCnt++] = status >> 16; /* tti */ mlogVar[mlogVarCnt++] = status & 0xFF; /* sym */ MLogAddVariables(mlogVarCnt, mlogVar, MLogTick()); rte_pause(); MLogTask(PID_GNB_PRACH_CB, t1, MLogTick()); } void xran_fh_rx_srs_callback(void *pCallbackTag, xran_status_t status) { uint64_t t1 = MLogTick(); uint32_t mlogVar[10]; uint32_t mlogVarCnt = 0; mlogVar[mlogVarCnt++] = 0xCCCCCCCC; mlogVar[mlogVarCnt++] = status >> 16; /* tti */ mlogVar[mlogVarCnt++] = status & 0xFF; /* sym */ MLogAddVariables(mlogVarCnt, mlogVar, MLogTick()); rte_pause(); MLogTask(PID_GNB_SRS_CB, t1, MLogTick()); } //------------------------------------------------------------------------------------------- /** @ingroup group_nbiot_source_auxlib_timer * * @param void * * @return Ticks * * @description * This function reads the rtdsc clock and returns the current value in there. * **/ //------------------------------------------------------------------------------------------- unsigned long timer_get_ticks(void) { unsigned long ret; union { unsigned long tsc_64; struct { uint32_t lo_32; uint32_t hi_32; }; } tsc; __asm volatile("rdtsc" : "=a" (tsc.lo_32), "=d" (tsc.hi_32)); ret = ((unsigned long)tsc.tsc_64); return ret; } //------------------------------------------------------------------------------------------- /** @ingroup group_lte_source_auxlib_timer * * @param void * * @return 0 if SUCCESS * * @description * This function gets the clock speed of the core and figures out number of ticks per usec. * It is used by l1app and testmac applications to initialize the mlog utility * **/ //------------------------------------------------------------------------------------------- int timer_set_tsc_freq_from_clock(void) { #define NS_PER_SEC 1E9 struct timespec sleeptime = {.tv_nsec = 5E8 }; /* 1/2 second */ struct timespec t_start, t_end; uint64_t tsc_resolution_hz = 0; if (clock_gettime(CLOCK_MONOTONIC_RAW, &t_start) == 0) { unsigned long ns, end, start = timer_get_ticks(); nanosleep(&sleeptime,NULL); clock_gettime(CLOCK_MONOTONIC_RAW, &t_end); end = timer_get_ticks(); ns = ((t_end.tv_sec - t_start.tv_sec) * NS_PER_SEC); ns += (t_end.tv_nsec - t_start.tv_nsec); double secs = (double)ns/NS_PER_SEC; tsc_resolution_hz = (unsigned long)((end - start)/secs); tick_per_usec = (tsc_resolution_hz / 1000000); printf("System clock (rdtsc) resolution %lu [Hz]\n", tsc_resolution_hz); printf("Ticks per us %lu\n", tick_per_usec); return 0; } return -1; } int physide_dl_tti_call_back(void * param) { uint64_t t1 = MLogTick(); rte_pause(); MLogTask(PID_GNB_PROC_TIMING, t1, MLogTick()); return 0; } int physide_ul_half_slot_call_back(void * param) { uint64_t t1 = MLogTick(); rte_pause(); MLogTask(PID_GNB_PROC_TIMING, t1, MLogTick()); return 0; } int physide_ul_full_slot_call_back(void * param) { uint64_t t1 = MLogTick(); rte_pause(); MLogTask(PID_GNB_PROC_TIMING, t1, MLogTick()); return 0; } int32_t init_xran(void) { BbuXranIoIfStruct *psBbuIo = xran_get_ctx(); xran_status_t status; int32_t nSectorIndex[XRAN_MAX_SECTOR_NR]; int32_t nSectorNum; int32_t i, j, k, z; void *ptr; void *mb; uint32_t *u32dptr; uint16_t *u16dptr; uint8_t *u8dptr; SWXRANInterfaceTypeEnum eInterfaceType; XranLibConfigStruct *ptrLibConfig; struct xran_buffer_list *pFthTxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN]; struct xran_buffer_list *pFthTxPrbMapBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN]; struct xran_buffer_list *pFthRxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN]; struct xran_buffer_list *pFthRxPrbMapBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN]; struct xran_buffer_list *pFthRxRachBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN]; struct xran_buffer_list *pFthRxSrsBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANT_ARRAY_ELM_NR][XRAN_N_FE_BUF_LEN]; for (nSectorNum = 0; nSectorNum < XRAN_MAX_SECTOR_NR; nSectorNum++) { nSectorIndex[nSectorNum] = nSectorNum; } nSectorNum = numCCPorts; printf ("XRAN front haul xran_mm_init \n"); status = xran_mm_init (xranHandle, (uint64_t) SW_FPGA_FH_TOTAL_BUFFER_LEN, SW_FPGA_SEGMENT_BUFFER_LEN); if (status != XRAN_STATUS_SUCCESS) { printf ("Failed at XRAN front haul xran_mm_init \n"); exit(-1); } psBbuIo->nInstanceNum = numCCPorts; for (k = 0; k < XRAN_PORTS_NUM; k++) { status = xran_sector_get_instances (xranHandle, psBbuIo->nInstanceNum,&psBbuIo->nInstanceHandle[k][0]); if (status != XRAN_STATUS_SUCCESS) { printf ("get sector instance failed %d for XRAN nInstanceNum %d\n",k, psBbuIo->nInstanceNum); exit(-1); } for (i = 0; i < psBbuIo->nInstanceNum; i++){ printf("%s [%d]: CC %d handle %p\n", __FUNCTION__, k, i, psBbuIo->nInstanceHandle[0][i]); } } printf("Sucess xran_mm_init \n"); gpXranLibConfig = (XranLibConfigStruct*)malloc(sizeof(XranLibConfigStruct)); ptrLibConfig = gpXranLibConfig; if (ptrLibConfig) { #if 0 ptrLibConfig->nDriverCoreId = psBbuIo->nDriverCoreId; ptrLibConfig->pFecInstanceHandles = &(psBbuIo->nInstanceHandle[FPGA_FEC][0]); ptrLibConfig->pFthInstanceHandles = &(psBbuIo->nInstanceHandle[FPGA_FRONTHAUL][0]); ptrLibConfig->nTimingAdvance = psFPGAInitPara->nTimeAdvance; ptrLibConfig->nFhConfig = psFPGAInitPara->nEthPorts; ptrLibConfig->nFhBufIntFlag = 0; //need init fronthaul buffer, then set to 1. ptrLibConfig->nNrofSfInFrame = NUM_OF_SUBFRAME_PER_FRAME; ptrLibConfig->nNrOfSlotInSf = pConfigParams->nNumOfSlotPerSubframe; if (pConfigParams->nNumerology < 3) { ptrLibConfig->nSectorNum = psFPGAInitPara->nSecNum; } #endif } else { printf ("could not allocate ptrLibConfig in init_xran\n"); exit(-1); } printf("nSectorNum %d\n", nSectorNum); /* Init Memory */ for(i = 0; inInstanceHandle[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); if(XRAN_STATUS_SUCCESS != status) { rte_panic("Failed at xran_bm_init , status %d\n", status); } for(j = 0; j < XRAN_N_FE_BUF_LEN; j++) { for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){ psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].bValid = 0; psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegGenerated = -1; psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1; psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegTransferred = 0; psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT; psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFrontHaulTxBuffers[j][i][z][0]; for(k = 0; k < XRAN_NUM_OF_SYMBOL_PER_SLOT; k++) { psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = nSW_ToFpga_FTH_TxBufferLen; // 14 symbols 3200bytes/symbol psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1; psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0; status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i], psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb); if(XRAN_STATUS_SUCCESS != status){ rte_panic("Failed at xran_bm_allocate_buffer , status %d\n",status); } psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr; psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *)mb; if(ptr){ u32dptr = (uint32_t*)(ptr); uint8_t *ptr_temp = (uint8_t *)ptr; memset(u32dptr, 0x0, nSW_ToFpga_FTH_TxBufferLen); // ptr_temp[0] = j; // TTI // ptr_temp[1] = i; // Sec // ptr_temp[2] = z; // Ant // ptr_temp[3] = k; // sym } } } } /* C-plane DL */ eInterfaceType = XRANFTHTX_SEC_DESC_OUT; 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*XRAN_MAX_SECTIONS_PER_SYM, sizeof(struct xran_section_desc)); if(XRAN_STATUS_SUCCESS != status) { rte_panic("Failed at xran_bm_init , status %d\n", status); } eInterfaceType = XRANFTHTX_PRB_MAP_OUT; 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, sizeof(struct xran_prb_map)); if(XRAN_STATUS_SUCCESS != status) { rte_panic("Failed at xran_bm_init , status %d\n", status); } for(j = 0; j < XRAN_N_FE_BUF_LEN; j++) { for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){ psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0; psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1; psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1; psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0; psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT; psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFrontHaulTxPrbMapBuffers[j][i][z]; { psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nElementLenInBytes = sizeof(struct xran_prb_map); psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nNumberOfElements = 1; psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nOffsetInBytes = 0; status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i], psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb); if(XRAN_STATUS_SUCCESS != status) { rte_panic("Failed at xran_bm_allocate_buffer , status %d\n",status); } psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pData = (uint8_t *)ptr; psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pCtrl = (void *)mb; if(ptr){ void *sd_ptr; void *sd_mb; int elm_id; struct xran_prb_map * p_rb_map = (struct xran_prb_map *)ptr; if (startupConfiguration.appMode == APP_O_DU) memcpy(ptr, &startupConfiguration.PrbMapDl, sizeof(struct xran_prb_map)); else memcpy(ptr, &startupConfiguration.PrbMapUl, sizeof(struct xran_prb_map)); for (elm_id = 0; elm_id < p_rb_map->nPrbElm; elm_id++){ struct xran_prb_elm *pPrbElem = &p_rb_map->prbMap[elm_id]; for(k = 0; k < XRAN_NUM_OF_SYMBOL_PER_SLOT; k++){ status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i], psBbuIo->nBufPoolIndex[nSectorIndex[i]][XRANFTHTX_SEC_DESC_OUT],&sd_ptr, &sd_mb); if(XRAN_STATUS_SUCCESS != status){ rte_panic("SD Failed at xran_bm_allocate_buffer , status %d\n",status); } pPrbElem->p_sec_desc[k] = sd_ptr; } } } } } } } for(i = 0; inInstanceHandle[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); if(XRAN_STATUS_SUCCESS != status) { printf("Failed at xran_bm_init, status %d\n", status); iAssert(status == XRAN_STATUS_SUCCESS); } for(j = 0;j < XRAN_N_FE_BUF_LEN; j++) { for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){ psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].bValid = 0; psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1; psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1; psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0; psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT; psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFrontHaulRxBuffers[j][i][z][0]; for(k = 0; k< XRAN_NUM_OF_SYMBOL_PER_SLOT; k++) { psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = nFpgaToSW_FTH_RxBufferLen; // 1 symbols 3200bytes psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1; psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0; status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i],psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb); if(XRAN_STATUS_SUCCESS != status) { rte_panic("Failed at xran_bm_allocate_buffer , status %d\n",status); } psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr; psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *) mb; if(ptr){ u32dptr = (uint32_t*)(ptr); uint8_t *ptr_temp = (uint8_t *)ptr; memset(u32dptr, 0x0, nFpgaToSW_FTH_RxBufferLen); // ptr_temp[0] = j; // TTI // ptr_temp[1] = i; // Sec // ptr_temp[2] = z; // Ant // ptr_temp[3] = k; // sym } } } } /* C-plane */ eInterfaceType = XRANFTHTX_SEC_DESC_IN; 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*XRAN_MAX_SECTIONS_PER_SYM, sizeof(struct xran_section_desc)); if(XRAN_STATUS_SUCCESS != status) { rte_panic("Failed at xran_bm_init , status %d\n", status); } eInterfaceType = XRANFTHRX_PRB_MAP_IN; 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, sizeof(struct xran_prb_map)); if(XRAN_STATUS_SUCCESS != status) { rte_panic("Failed at xran_bm_init, status %d\n", status); } for(j = 0;j < XRAN_N_FE_BUF_LEN; j++) { for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){ psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0; psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1; psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1; psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0; psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT; psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFrontHaulRxPrbMapBuffers[j][i][z]; { psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nElementLenInBytes = sizeof(struct xran_prb_map); psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nNumberOfElements = 1; psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nOffsetInBytes = 0; status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i],psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb); if(XRAN_STATUS_SUCCESS != status) { rte_panic("Failed at xran_bm_allocate_buffer , status %d\n",status); } psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pData = (uint8_t *)ptr; psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pCtrl = (void *)mb; if(ptr){ void *sd_ptr; void *sd_mb; int elm_id; struct xran_prb_map * p_rb_map = (struct xran_prb_map *)ptr; if (startupConfiguration.appMode == APP_O_DU) memcpy(ptr, &startupConfiguration.PrbMapUl, sizeof(struct xran_prb_map)); else memcpy(ptr, &startupConfiguration.PrbMapDl, sizeof(struct xran_prb_map)); for (elm_id = 0; elm_id < p_rb_map->nPrbElm; elm_id++){ struct xran_prb_elm *pPrbElem = &p_rb_map->prbMap[elm_id]; for(k = 0; k < XRAN_NUM_OF_SYMBOL_PER_SLOT; k++){ status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i], psBbuIo->nBufPoolIndex[nSectorIndex[i]][XRANFTHTX_SEC_DESC_IN],&sd_ptr, &sd_mb); if(XRAN_STATUS_SUCCESS != status){ rte_panic("SD Failed at xran_bm_allocate_buffer , status %d\n",status); } pPrbElem->p_sec_desc[k] = sd_ptr; } } } } } } } // add prach rx buffer for(i = 0; inInstanceHandle[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); if(XRAN_STATUS_SUCCESS != status) { rte_panic("Failed at xran_bm_init, status %d\n", status); } for(j = 0;j < XRAN_N_FE_BUF_LEN; j++) { for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){ psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].bValid = 0; psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1; psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1; psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0; psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_MAX_ANTENNA_NR; // ant number. psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFHPrachRxBuffers[j][i][z][0]; for(k = 0; k< XRAN_NUM_OF_SYMBOL_PER_SLOT; k++) { psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = FPGA_TO_SW_PRACH_RX_BUFFER_LEN; psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1; psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0; status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i],psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb); if(XRAN_STATUS_SUCCESS != status) { rte_panic("Failed at xran_bm_allocate_buffer, status %d\n",status); } psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr; psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *)mb; if(ptr){ u32dptr = (uint32_t*)(ptr); memset(u32dptr, 0x0, FPGA_TO_SW_PRACH_RX_BUFFER_LEN); } } } } } /* add SRS rx buffer */ for(i = 0; inInstanceHandle[0][i],&psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType], XRAN_N_FE_BUF_LEN*XRAN_MAX_ANT_ARRAY_ELM_NR*XRAN_MAX_NUM_OF_SRS_SYMBOL_PER_SLOT, nSW_ToFpga_FTH_TxBufferLen); if(XRAN_STATUS_SUCCESS != status) { rte_panic("Failed at xran_bm_init, status %d\n", status); } for(j = 0; j < XRAN_N_FE_BUF_LEN; j++) { for(z = 0; z < XRAN_MAX_ANT_ARRAY_ELM_NR; z++){ psBbuIo->sFHSrsRxBbuIoBufCtrl[j][i][z].bValid = 0; psBbuIo->sFHSrsRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1; psBbuIo->sFHSrsRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1; psBbuIo->sFHSrsRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0; psBbuIo->sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_MAX_ANT_ARRAY_ELM_NR; /* ant number */ psBbuIo->sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFHSrsRxBuffers[j][i][z][0]; for(k = 0; k < XRAN_MAX_NUM_OF_SRS_SYMBOL_PER_SLOT; k++) { psBbuIo->sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = nSW_ToFpga_FTH_TxBufferLen; psBbuIo->sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1; psBbuIo->sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0; status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i],psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb); if(XRAN_STATUS_SUCCESS != status) { rte_panic("Failed at xran_bm_allocate_buffer, status %d\n",status); } psBbuIo->sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr; psBbuIo->sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *)mb; if(ptr){ u32dptr = (uint32_t*)(ptr); memset(u32dptr, 0x0, nSW_ToFpga_FTH_TxBufferLen); } } } } } for(i=0; isFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList); pFthTxPrbMapBuffer[i][z][j] = &(psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList); pFthRxBuffer[i][z][j] = &(psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList); pFthRxPrbMapBuffer[i][z][j] = &(psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList); pFthRxRachBuffer[i][z][j] = &(psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList); } for(z = 0; z < XRAN_MAX_ANT_ARRAY_ELM_NR; z++){ pFthRxSrsBuffer[i][z][j] = &(psBbuIo->sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList); } } } if(NULL != psBbuIo->nInstanceHandle[0]) { /* add pusch callback */ for (i = 0; inInstanceHandle[0][i], pFthTxBuffer[i], pFthTxPrbMapBuffer[i], pFthRxBuffer[i], pFthRxPrbMapBuffer[i], xran_fh_rx_callback, &pFthRxBuffer[i][0]); } /* add prach callback here */ for (i = 0; inInstanceHandle[0][i], pFthRxRachBuffer[i], xran_fh_rx_prach_callback,&pFthRxRachBuffer[i][0]); } /* add SRS callback here */ for (i = 0; inInstanceHandle[0][i], pFthRxSrsBuffer[i], xran_fh_rx_srs_callback,&pFthRxSrsBuffer[i][0]); } ptrLibConfig->nFhBufIntFlag = 1; } return status; } int init_xran_iq_content(void) { BbuXranIoIfStruct *psBbuIo = xran_get_ctx(); xran_status_t status; int32_t nSectorIndex[XRAN_MAX_SECTOR_NR]; int32_t nSectorNum; int32_t cc_id, ant_id, sym_id, tti; int32_t flowId; uint8_t frame_id = 0; uint8_t subframe_id = 0; uint8_t slot_id = 0; uint8_t sym = 0; void *ptr; uint32_t *u32dptr; uint16_t *u16dptr; uint8_t *u8dptr; char *pos = NULL; struct xran_prb_map *pRbMap = NULL; for (nSectorNum = 0; nSectorNum < XRAN_MAX_SECTOR_NR; nSectorNum++) { nSectorIndex[nSectorNum] = nSectorNum; } nSectorNum = numCCPorts; printf ("init_xran_iq_content\n"); /* Init Memory */ for(cc_id = 0; cc_id sFrontHaulTxPrbMapBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers->pData; if(pRbMap){ if (xranInit.DynamicSectionEna == 0){ pRbMap->dir = XRAN_DIR_DL; pRbMap->xran_port = 0; pRbMap->band_id = 0; pRbMap->cc_id = cc_id; pRbMap->ru_port_id = ant_id; pRbMap->tti_id = tti; pRbMap->start_sym_id = 0; pRbMap->nPrbElm = 1; pRbMap->prbMap[0].nStartSymb = 0; pRbMap->prbMap[0].numSymb = 14; pRbMap->prbMap[0].nRBStart = 0; pRbMap->prbMap[0].nRBSize = pXranConf->nDLRBs; pRbMap->prbMap[0].nBeamIndex = 0; pRbMap->prbMap[0].compMethod = XRAN_COMPMETHOD_NONE; pRbMap->prbMap[0].iqWidth = 16; } else if(pXranConf->ru_conf.xranCat == XRAN_CATEGORY_B && startupConfiguration.appMode == APP_O_DU && sym_id == 0){ /* BF Ws are per slot */ int idxElm = 0; char* dl_bfw_pos = ((char*)p_tx_dl_bfw_buffer[flowId]) + tx_dl_bfw_buffer_position[flowId]; struct xran_prb_elm* p_pRbMapElm = NULL; for (idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++){ p_pRbMapElm = &pRbMap->prbMap[idxElm]; p_pRbMapElm->bf_weight.nAntElmTRx = pXranConf->nAntElmTRx; if(p_pRbMapElm->BeamFormingType == XRAN_BEAM_WEIGHT && p_pRbMapElm->bf_weight_update){ int16_t ext_len = 9600; int16_t ext_sec_total = 0; int8_t * ext_buf =(int8_t*) xran_malloc(ext_len); int idRb = 0; int16_t *ptr = NULL; int i; if (ext_buf){ ext_buf += (RTE_PKTMBUF_HEADROOM + sizeof (struct xran_ecpri_hdr) + sizeof(struct xran_cp_radioapp_section1)); ext_len -= (RTE_PKTMBUF_HEADROOM + sizeof (struct xran_ecpri_hdr) + sizeof(struct xran_cp_radioapp_section1)); ext_sec_total = xran_cp_populate_section_ext_1((int8_t *)ext_buf, ext_len, (int16_t *) (dl_bfw_pos + (p_pRbMapElm->nRBStart*pXranConf->nAntElmTRx)*4), p_pRbMapElm->nRBSize, pXranConf->nAntElmTRx, p_pRbMapElm->iqWidth, p_pRbMapElm->compMethod); if(ext_sec_total > 0){ p_pRbMapElm->bf_weight.p_ext_section = ext_buf; p_pRbMapElm->bf_weight.ext_section_sz = ext_sec_total; }else { rte_panic("xran_cp_populate_section_ext_1 return error [%d]\n", ext_sec_total); } } else { rte_panic("xran_malloc return NULL\n"); } } } } } else { printf("DL pRbMap ==NULL\n"); exit(-1); } pos = ((char*)p_tx_play_buffer[flowId]) + tx_play_buffer_position[flowId]; ptr = psBbuIo->sFrontHaulTxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData; if(ptr && pos){ int idxElm = 0; u8dptr = (uint8_t*)ptr; int16_t payload_len = 0; uint8_t *dst = (uint8_t *)u8dptr; uint8_t *src = (uint8_t *)pos; struct xran_prb_elm* p_prbMapElm = &pRbMap->prbMap[idxElm]; dst = xran_add_hdr_offset(dst, p_prbMapElm->compMethod); for (idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++) { struct xran_section_desc *p_sec_desc = NULL; p_prbMapElm = &pRbMap->prbMap[idxElm]; p_sec_desc = p_prbMapElm->p_sec_desc[sym_id]; if(p_sec_desc == NULL){ printf ("p_sec_desc == NULL\n"); exit(-1); } src = (uint8_t *)(pos + p_prbMapElm->nRBStart*N_SC_PER_PRB*4L); if(p_prbMapElm->compMethod == XRAN_COMPMETHOD_NONE) { payload_len = p_prbMapElm->nRBSize*N_SC_PER_PRB*4L; rte_memcpy(dst, src, payload_len); } else if (p_prbMapElm->compMethod == XRAN_COMPMETHOD_BLKFLOAT) { struct xranlib_compress_request bfp_com_req; struct xranlib_compress_response bfp_com_rsp; memset(&bfp_com_req, 0, sizeof(struct xranlib_compress_request)); memset(&bfp_com_rsp, 0, sizeof(struct xranlib_compress_response)); bfp_com_req.data_in = (int16_t*)src; bfp_com_req.numRBs = p_prbMapElm->nRBSize; bfp_com_req.len = p_prbMapElm->nRBSize*N_SC_PER_PRB*4L; bfp_com_req.compMethod = p_prbMapElm->compMethod; bfp_com_req.iqWidth = p_prbMapElm->iqWidth; bfp_com_rsp.data_out = (int8_t*)dst; bfp_com_rsp.len = 0; if(xranlib_compress_avx512(&bfp_com_req, &bfp_com_rsp) < 0){ printf ("compression failed [%d]\n", p_prbMapElm->compMethod); exit(-1); } else { payload_len = bfp_com_rsp.len; } }else { printf ("p_prbMapElm->compMethod == %d is not supported\n", p_prbMapElm->compMethod); exit(-1); } /* update RB map for given element */ p_sec_desc->iq_buffer_offset = RTE_PTR_DIFF(dst, u8dptr); p_sec_desc->iq_buffer_len = payload_len; /* add headroom for ORAN headers between IQs for chunk of RBs*/ dst += payload_len; dst = xran_add_hdr_offset(dst, p_prbMapElm->compMethod); } } else { exit(-1); printf("ptr ==NULL\n"); } /* c-plane UL */ pRbMap = (struct xran_prb_map *) psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers->pData; if(pRbMap){ if (xranInit.DynamicSectionEna == 0){ pRbMap->dir = XRAN_DIR_UL; pRbMap->xran_port = 0; pRbMap->band_id = 0; pRbMap->cc_id = cc_id; pRbMap->ru_port_id = ant_id; pRbMap->tti_id = tti; pRbMap->start_sym_id = 0; pRbMap->nPrbElm = 1; pRbMap->prbMap[0].nRBStart = 0; pRbMap->prbMap[0].nRBSize = pXranConf->nULRBs; pRbMap->prbMap[0].nStartSymb = 0; pRbMap->prbMap[0].numSymb = 14; pRbMap->prbMap[0].p_sec_desc[sym_id]->iq_buffer_offset = 0; pRbMap->prbMap[0].p_sec_desc[sym_id]->iq_buffer_len = pXranConf->nULRBs *4L; pRbMap->prbMap[0].nBeamIndex = 0; pRbMap->prbMap[0].compMethod = XRAN_COMPMETHOD_NONE; } else if(pXranConf->ru_conf.xranCat == XRAN_CATEGORY_B && startupConfiguration.appMode == APP_O_DU && sym_id == 0){ int idxElm = 0; char * ul_bfw_pos = ((char*)p_tx_ul_bfw_buffer[flowId]) + tx_ul_bfw_buffer_position[flowId]; struct xran_prb_elm* p_pRbMapElm = NULL; for (idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++){ p_pRbMapElm = &pRbMap->prbMap[idxElm]; p_pRbMapElm->bf_weight.nAntElmTRx = pXranConf->nAntElmTRx; if(p_pRbMapElm->BeamFormingType == XRAN_BEAM_WEIGHT && p_pRbMapElm->bf_weight_update){ int16_t ext_len = 9600; int16_t ext_sec_total = 0; int8_t * ext_buf =(int8_t*) xran_malloc(ext_len); int idRb = 0; int16_t *ptr = NULL; int i; if (ext_buf){ ext_buf += (RTE_PKTMBUF_HEADROOM + sizeof (struct xran_ecpri_hdr) + sizeof(struct xran_cp_radioapp_section1)); ext_len -= (RTE_PKTMBUF_HEADROOM + sizeof (struct xran_ecpri_hdr) + sizeof(struct xran_cp_radioapp_section1)); ptr = (int16_t*)(ul_bfw_pos +(p_pRbMapElm->nRBStart*pXranConf->nAntElmTRx)*4); ext_sec_total = xran_cp_populate_section_ext_1((int8_t *)ext_buf, ext_len, (int16_t *) (ul_bfw_pos + (p_pRbMapElm->nRBStart*pXranConf->nAntElmTRx)*4), p_pRbMapElm->nRBSize, pXranConf->nAntElmTRx, p_pRbMapElm->iqWidth, p_pRbMapElm->compMethod); if(ext_sec_total > 0){ p_pRbMapElm->bf_weight.p_ext_section = ext_buf; p_pRbMapElm->bf_weight.ext_section_sz = ext_sec_total; }else { rte_panic("xran_cp_populate_section_ext_1 return error [%d]\n", ext_sec_total); } } else { rte_panic("xran_malloc return NULL\n"); } } } } } else { printf("DL pRbMap ==NULL\n"); exit(-1); } tx_play_buffer_position[flowId] += pXranConf->nDLRBs*N_SC_PER_PRB*4; if(tx_play_buffer_position[flowId] >= tx_play_buffer_size[flowId]) tx_play_buffer_position[flowId] = 0; if(pXranConf->ru_conf.xranCat == XRAN_CATEGORY_B && startupConfiguration.appMode == APP_O_DU && sym_id == 0) { tx_dl_bfw_buffer_position[flowId] += (pXranConf->nDLRBs*pXranConf->nAntElmTRx)*4; if(tx_dl_bfw_buffer_position[flowId] >= tx_dl_bfw_buffer_size[flowId]) tx_dl_bfw_buffer_position[flowId] = 0; tx_ul_bfw_buffer_position[flowId] += (pXranConf->nULRBs*pXranConf->nAntElmTRx)*4; if(tx_ul_bfw_buffer_position[flowId] >= tx_ul_bfw_buffer_size[flowId]) tx_ul_bfw_buffer_position[flowId] = 0; } } else { //printf("flowId %d\n", flowId); } } } /* prach TX for RU only */ if(startupConfiguration.appMode == APP_O_RU && startupConfiguration.enablePrach){ for(ant_id = 0; ant_id < XRAN_MAX_ANTENNA_NR; ant_id++){ for(sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) { flowId = XRAN_MAX_ANTENNA_NR*cc_id + ant_id; if(p_tx_prach_play_buffer[flowId]){ pos = ((char*)p_tx_prach_play_buffer[flowId]); ptr = psBbuIo->sFHPrachRxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData; if(ptr && pos){ u32dptr = (uint32_t*)(ptr); /* duplicate full PRACH (repetition * occassions ) in every symbol */ memset(u32dptr,0 , PRACH_PLAYBACK_BUFFER_BYTES); rte_memcpy(u32dptr, pos, RTE_MIN(PRACH_PLAYBACK_BUFFER_BYTES, tx_prach_play_buffer_size[flowId])); } else { exit(-1); printf("ptr ==NULL\n"); } } else { //printf("flowId %d\n", flowId); } } } } /* SRS TX for RU only */ if(startupConfiguration.appMode == APP_O_RU && startupConfiguration.enableSrs){ for(ant_id = 0; ant_id < XRAN_MAX_ANT_ARRAY_ELM_NR; ant_id++){ for(sym_id = 0; sym_id < XRAN_MAX_NUM_OF_SRS_SYMBOL_PER_SLOT; sym_id++) { flowId = XRAN_MAX_ANT_ARRAY_ELM_NR*cc_id + ant_id; if(p_tx_srs_play_buffer[flowId]){ pos = ((char*)p_tx_srs_play_buffer[flowId]) + tx_srs_play_buffer_position[flowId]; ptr = psBbuIo->sFHSrsRxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData; if(startupConfiguration.srsSymMask & (1 << sym_id) ){ if(ptr && pos){ u32dptr = (uint32_t*)(ptr); memset(u32dptr,0 , pXranConf->nULRBs*N_SC_PER_PRB*4); rte_memcpy(u32dptr, pos, pXranConf->nULRBs*N_SC_PER_PRB*4); } else { exit(-1); printf("ptr ==NULL\n"); } } tx_srs_play_buffer_position[flowId] += pXranConf->nULRBs*N_SC_PER_PRB*4; if(tx_srs_play_buffer_position[flowId] >= tx_srs_play_buffer_size[flowId]) tx_srs_play_buffer_position[flowId] = 0; } else { //printf("flowId %d\n", flowId); } } } } } } return 0; } void stop_xran(void) { xran_status_t status = 0; SWXRANInterfaceTypeEnum eInterfaceType; free(gpXranLibConfig); gpXranLibConfig = NULL; status += xran_mm_destroy(xranHandle)*2; if(XRAN_STATUS_SUCCESS != status) { printf("Failed at xran_mm_destroy, status %d\n",status); iAssert(status == XRAN_STATUS_SUCCESS); } } int get_xran_iq_content(void) { BbuXranIoIfStruct *psBbuIo = xran_get_ctx(); xran_status_t status; int32_t nSectorIndex[XRAN_MAX_SECTOR_NR]; int32_t nSectorNum; int32_t cc_id, ant_id, sym_id, tti; int32_t flowId; uint8_t frame_id = 0; uint8_t subframe_id = 0; uint8_t slot_id = 0; uint8_t sym = 0; void *ptr; uint32_t *u32dptr; uint16_t *u16dptr; uint8_t *u8dptr; char *pos = NULL; for (nSectorNum = 0; nSectorNum < XRAN_MAX_SECTOR_NR; nSectorNum++) { nSectorIndex[nSectorNum] = nSectorNum; } nSectorNum = numCCPorts; printf ("get_xran_iq_content\n"); /* Init Memory */ for(cc_id = 0; cc_id sFrontHaulRxPrbMapBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers->pData; if(pRbMap == NULL) exit(-1); flowId = XRAN_MAX_ANTENNA_NR * cc_id + ant_id; for(sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) { pRbElm = &pRbMap->prbMap[0]; if(pRbMap->nPrbElm == 1){ if(p_rx_log_buffer[flowId]) { pos = ((char*)p_rx_log_buffer[flowId]) + rx_log_buffer_position[flowId]; ptr = psBbuIo->sFrontHaulRxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData; if(ptr){ u32dptr = (uint32_t*)(ptr); char* my_ptr =(char *)ptr; rte_memcpy(pos + pRbElm->nRBStart*N_SC_PER_PRB*4L , u32dptr, pRbElm->nRBSize*N_SC_PER_PRB*4L); }else { printf("[%d][%d][%d][%d]ptr ==NULL\n",tti,cc_id,ant_id, sym_id); } } } else { for(idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++ ) { pRbElm = &pRbMap->prbMap[idxElm]; p_sec_desc = pRbElm->p_sec_desc[sym_id]; if(p_rx_log_buffer[flowId] && p_sec_desc){ if(sym_id >= pRbElm->nStartSymb && sym_id < pRbElm->nStartSymb + pRbElm->numSymb){ pos = ((char*)p_rx_log_buffer[flowId]) + rx_log_buffer_position[flowId]; ptr = p_sec_desc->pData; if(ptr){ int32_t payload_len = 0; u32dptr = (uint32_t*)(ptr); if (pRbElm->compMethod != XRAN_COMPMETHOD_NONE){ struct xranlib_decompress_request bfp_decom_req; struct xranlib_decompress_response bfp_decom_rsp; memset(&bfp_decom_req, 0, sizeof(struct xranlib_decompress_request)); memset(&bfp_decom_rsp, 0, sizeof(struct xranlib_decompress_response)); bfp_decom_req.data_in = (int8_t *)u32dptr; bfp_decom_req.numRBs = pRbElm->nRBSize; bfp_decom_req.len = (3* pRbElm->iqWidth + 1)*pRbElm->nRBSize; bfp_decom_req.compMethod = pRbElm->compMethod; bfp_decom_req.iqWidth = pRbElm->iqWidth; bfp_decom_rsp.data_out = (int16_t *)(pos + pRbElm->nRBStart*N_SC_PER_PRB*4); bfp_decom_rsp.len = 0; if(xranlib_decompress_avx512(&bfp_decom_req, &bfp_decom_rsp) < 0){ printf ("compression failed [%d]\n", pRbElm->compMethod); exit(-1); } else { payload_len = bfp_decom_rsp.len; } } else { rte_memcpy(pos + pRbElm->nRBStart*N_SC_PER_PRB*4 , u32dptr, pRbElm->nRBSize*N_SC_PER_PRB*4); } } } } } } rx_log_buffer_position[flowId] += pXranConf->nULRBs*N_SC_PER_PRB*4; if(rx_log_buffer_position[flowId] >= rx_log_buffer_size[flowId]) rx_log_buffer_position[flowId] = 0; } /* prach RX for O-DU only */ if(startupConfiguration.appMode == APP_O_DU) { flowId = XRAN_MAX_ANTENNA_NR * cc_id + ant_id; for(sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++){ if(p_prach_log_buffer[flowId]){ /* (0-79 slots) 10ms of IQs */ pos = ((char*)p_prach_log_buffer[flowId]) + prach_log_buffer_position[flowId]; ptr = psBbuIo->sFHPrachRxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData; //8192 144 if(ptr){ u32dptr = (uint32_t*)(ptr); rte_memcpy(pos, u32dptr, PRACH_PLAYBACK_BUFFER_BYTES); }else printf("ptr ==NULL\n"); prach_log_buffer_position[flowId] += PRACH_PLAYBACK_BUFFER_BYTES; if(prach_log_buffer_position[flowId] >= prach_log_buffer_size[flowId]) prach_log_buffer_position[flowId] = 0; } else { //printf("flowId %d\n", flowId); } } } } /* SRS RX for O-DU only */ if(startupConfiguration.appMode == APP_O_DU) { for(ant_id = 0; ant_id < XRAN_MAX_ANT_ARRAY_ELM_NR; ant_id++){ flowId = XRAN_MAX_ANT_ARRAY_ELM_NR*cc_id + ant_id; for(sym_id = 0; sym_id < XRAN_MAX_NUM_OF_SRS_SYMBOL_PER_SLOT; sym_id++){ if(p_srs_log_buffer[flowId]){ pos = ((char*)p_srs_log_buffer[flowId]) + srs_log_buffer_position[flowId]; ptr = psBbuIo->sFHSrsRxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData; if(ptr){ u32dptr = (uint32_t*)(ptr); rte_memcpy(pos, u32dptr, pXranConf->nULRBs*N_SC_PER_PRB*4); }else printf("ptr ==NULL\n"); srs_log_buffer_position[flowId] += pXranConf->nULRBs*N_SC_PER_PRB*4; if(srs_log_buffer_position[flowId] >= srs_log_buffer_size[flowId]) srs_log_buffer_position[flowId] = 0; } else { //printf("flowId %d\n", flowId); } } } } } } return 0; } void version_print(void) { char sysversion[100]; char *compilation_date = __DATE__; char *compilation_time = __TIME__; uint32_t nLen; uint32_t i; snprintf(sysversion, 99, "Version: %s", VERSIONX); nLen = strlen(sysversion); printf("\n\n"); printf("===========================================================================================================\n"); printf("SAMPLE-APP VERSION\n"); printf("===========================================================================================================\n"); printf("%s\n", sysversion); printf("build-date: %s\n", compilation_date); printf("build-time: %s\n", compilation_time); } int main(int argc, char *argv[]) { int i; int j, len; int lcore_id = 0; char filename[256]; char prefix_name[256]; uint32_t nCenterFreq; int32_t xret = 0; struct stat st = {0}; uint32_t filenameLength = strlen(argv[1]); char *pCheckName1 = NULL, *pCheckName2 = NULL; enum xran_if_state xran_curr_if_state = XRAN_INIT; uint64_t nMask = (uint64_t)1; uint16_t nCoreUsage[4*64+1]; uint16_t nCoreId[4*64]; float nTotal = 0.0; uint64_t nTotalTime; uint64_t nUsedTime; uint32_t nCoreUsed; float nUsedPercent; if (argc == 3) errx(2, "Need two argument - the PCI address of the network port"); if (filenameLength >= 256) { printf("Config file name input is too long, exiting!\n"); exit(-1); } version_print(); //add for Klocworks len = strlen(argv[1]) + 1; if (len > (sizeof(filename) - 10)) len = (sizeof(filename) - 10); strncpy(filename, argv[1], (sizeof(filename) - 10)); filename[len] = '\0'; if (xran_is_synchronized() != 0) printf("Machine is not synchronized using PTP!\n"); else printf("Machine is synchronized using PTP!\n"); memset(&startupConfiguration, 0, sizeof(RuntimeConfig)); if (parseConfigFile(filename, (RuntimeConfig*)&startupConfiguration) != 0) { printf("Configuration file error.\n"); return -1; } if(startupConfiguration.ant_file[0] == NULL){ printf("it looks like test vector for antennas were not provided\n"); exit(-1); } if (startupConfiguration.numCC > XRAN_MAX_SECTOR_NR) { printf("Number of cells %d exceeds max number supported %d!\n", startupConfiguration.numCC, XRAN_MAX_SECTOR_NR); startupConfiguration.numCC = XRAN_MAX_SECTOR_NR; } if (startupConfiguration.antElmTRx > XRAN_MAX_ANT_ARRAY_ELM_NR) { printf("Number of Antenna elements %d exceeds max number supported %d!\n", startupConfiguration.antElmTRx, XRAN_MAX_ANT_ARRAY_ELM_NR); startupConfiguration.antElmTRx = XRAN_MAX_ANT_ARRAY_ELM_NR; } numCCPorts = startupConfiguration.numCC; num_eAxc = startupConfiguration.numAxc; printf("numCCPorts %d num_eAxc%d\n", numCCPorts, num_eAxc); if (startupConfiguration.mu_number <= 1){ nFpgaToSW_FTH_RxBufferLen = 13168; /* 273*12*4 + 64*/ nFpgaToSW_PRACH_RxBufferLen = 8192; nSW_ToFpga_FTH_TxBufferLen = 13168 + /* 273*12*4 + 64* + ETH AND ORAN HDRs */ XRAN_MAX_SECTIONS_PER_SYM* (RTE_PKTMBUF_HEADROOM + sizeof(struct ether_hdr) + sizeof(struct xran_ecpri_hdr) + sizeof(struct radio_app_common_hdr) + sizeof(struct data_section_hdr)); } else if (startupConfiguration.mu_number == 3){ nFpgaToSW_FTH_RxBufferLen = 3328; nFpgaToSW_PRACH_RxBufferLen = 8192; nSW_ToFpga_FTH_TxBufferLen = 3328 + XRAN_MAX_SECTIONS_PER_SYM * (RTE_PKTMBUF_HEADROOM + sizeof(struct ether_hdr) + sizeof(struct xran_ecpri_hdr) + sizeof(struct radio_app_common_hdr) + sizeof(struct data_section_hdr)); } else { printf("given numerology is not supported %d\n", startupConfiguration.mu_number); exit(-1); } printf("nSW_ToFpga_FTH_TxBufferLen %d\n", nSW_ToFpga_FTH_TxBufferLen); memset(&xranInit, 0, sizeof(struct xran_fh_init)); if(startupConfiguration.appMode == APP_O_DU) { printf("set O-DU\n"); xranInit.io_cfg.id = 0;/* O-DU */ xranInit.io_cfg.core = startupConfiguration.io_core; xranInit.io_cfg.system_core = 0; xranInit.io_cfg.pkt_proc_core = startupConfiguration.io_core+1; xranInit.io_cfg.pkt_aux_core = 0; /* do not start*/ xranInit.io_cfg.timing_core = startupConfiguration.io_core+2; } else { printf("set O-RU\n"); xranInit.io_cfg.id = 1; /* O-RU*/ xranInit.io_cfg.core = startupConfiguration.io_core; xranInit.io_cfg.system_core = 0; xranInit.io_cfg.pkt_proc_core = startupConfiguration.io_core+1; xranInit.io_cfg.pkt_aux_core = 0; /* do not start */ xranInit.io_cfg.timing_core = startupConfiguration.io_core+2; } xranInit.io_cfg.bbdev_mode = XRAN_BBDEV_NOT_USED; if(startupConfiguration.xranCat == XRAN_CATEGORY_A){ xranInit.eAxCId_conf.mask_cuPortId = 0xf000; xranInit.eAxCId_conf.mask_bandSectorId = 0x0f00; xranInit.eAxCId_conf.mask_ccId = 0x00f0; xranInit.eAxCId_conf.mask_ruPortId = 0x000f; xranInit.eAxCId_conf.bit_cuPortId = 12; xranInit.eAxCId_conf.bit_bandSectorId = 8; xranInit.eAxCId_conf.bit_ccId = 4; xranInit.eAxCId_conf.bit_ruPortId = 0; } else { xranInit.eAxCId_conf.mask_cuPortId = 0xf000; xranInit.eAxCId_conf.mask_bandSectorId = 0x0c00; xranInit.eAxCId_conf.mask_ccId = 0x0300; xranInit.eAxCId_conf.mask_ruPortId = 0x00ff; /* more than [0-127] eAxC */ xranInit.eAxCId_conf.bit_cuPortId = 12; xranInit.eAxCId_conf.bit_bandSectorId = 10; xranInit.eAxCId_conf.bit_ccId = 8; xranInit.eAxCId_conf.bit_ruPortId = 0; } xranInit.io_cfg.dpdk_dev[XRAN_UP_VF] = argv[2]; xranInit.io_cfg.dpdk_dev[XRAN_CP_VF] = argv[3]; xranInit.mtu = startupConfiguration.mtu; xranInit.p_o_du_addr = (int8_t *)&startupConfiguration.o_du_addr; xranInit.p_o_ru_addr = (int8_t *)&startupConfiguration.o_ru_addr; sprintf(prefix_name, "wls_%d",startupConfiguration.instance_id); xranInit.filePrefix = prefix_name; xranInit.totalBfWeights = startupConfiguration.totalBfWeights; xranInit.Tadv_cp_dl = startupConfiguration.Tadv_cp_dl; xranInit.T2a_min_cp_dl = startupConfiguration.T2a_min_cp_dl; xranInit.T2a_max_cp_dl = startupConfiguration.T2a_max_cp_dl; xranInit.T2a_min_cp_ul = startupConfiguration.T2a_min_cp_ul; xranInit.T2a_max_cp_ul = startupConfiguration.T2a_max_cp_ul; xranInit.T2a_min_up = startupConfiguration.T2a_min_up; xranInit.T2a_max_up = startupConfiguration.T2a_max_up; xranInit.Ta3_min = startupConfiguration.Ta3_min; xranInit.Ta3_max = startupConfiguration.Ta3_max; xranInit.T1a_min_cp_dl = startupConfiguration.T1a_min_cp_dl; xranInit.T1a_max_cp_dl = startupConfiguration.T1a_max_cp_dl; xranInit.T1a_min_cp_ul = startupConfiguration.T1a_min_cp_ul; xranInit.T1a_max_cp_ul = startupConfiguration.T1a_max_cp_ul; xranInit.T1a_min_up = startupConfiguration.T1a_min_up; xranInit.T1a_max_up = startupConfiguration.T1a_max_up; xranInit.Ta4_min = startupConfiguration.Ta4_min; xranInit.Ta4_max = startupConfiguration.Ta4_max; xranInit.enableCP = startupConfiguration.enableCP; xranInit.prachEnable = startupConfiguration.enablePrach; xranInit.srsEnable = startupConfiguration.enableSrs; xranInit.debugStop = startupConfiguration.debugStop; xranInit.debugStopCount = startupConfiguration.debugStopCount; xranInit.DynamicSectionEna = startupConfiguration.DynamicSectionEna; xranInit.io_cfg.bbdev_mode = XRAN_BBDEV_NOT_USED; xranInit.GPS_Alpha = startupConfiguration.GPS_Alpha; xranInit.GPS_Beta = startupConfiguration.GPS_Beta; xranInit.cp_vlan_tag = startupConfiguration.cp_vlan_tag; xranInit.up_vlan_tag = startupConfiguration.up_vlan_tag; printf("IQ files size is %d slots\n", startupConfiguration.numSlots); iq_playback_buffer_size_dl = (startupConfiguration.numSlots * N_SYM_PER_SLOT * N_SC_PER_PRB * app_xran_get_num_rbs(startupConfiguration.mu_number, startupConfiguration.nDLBandwidth, startupConfiguration.nDLAbsFrePointA) *4L); iq_playback_buffer_size_ul = (startupConfiguration.numSlots * N_SYM_PER_SLOT * N_SC_PER_PRB * app_xran_get_num_rbs(startupConfiguration.mu_number, startupConfiguration.nULBandwidth, startupConfiguration.nULAbsFrePointA) *4L); /* 10 * [14*32*273*2*2] = 4892160 bytes */ iq_bfw_buffer_size_dl = (startupConfiguration.numSlots * N_SYM_PER_SLOT * startupConfiguration.antElmTRx * app_xran_get_num_rbs(startupConfiguration.mu_number, startupConfiguration.nDLBandwidth, startupConfiguration.nDLAbsFrePointA) *4L); /* 10 * [14*32*273*2*2] = 4892160 bytes */ iq_bfw_buffer_size_ul = (startupConfiguration.numSlots * N_SYM_PER_SLOT * app_xran_get_num_rbs(startupConfiguration.mu_number, startupConfiguration.nULBandwidth, startupConfiguration.nULAbsFrePointA) *4L); /* 10 * [1*273*2*2] = 349440 bytes */ iq_srs_buffer_size_ul = (startupConfiguration.numSlots * N_SYM_PER_SLOT * N_SC_PER_PRB * app_xran_get_num_rbs(startupConfiguration.mu_number, startupConfiguration.nULBandwidth, startupConfiguration.nULAbsFrePointA) *4L); for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) { p_tx_play_buffer[i] = (int16_t*)malloc(iq_playback_buffer_size_dl); tx_play_buffer_size[i] = (int32_t)iq_playback_buffer_size_dl; if (p_tx_play_buffer[i] == NULL) exit(-1); tx_play_buffer_size[i] = sys_load_file_to_buff(startupConfiguration.ant_file[i], "DL IFFT IN IQ Samples in binary format", (uint8_t*) p_tx_play_buffer[i], tx_play_buffer_size[i], 1); tx_play_buffer_position[i] = 0; } if (startupConfiguration.appMode == APP_O_DU && startupConfiguration.xranCat == XRAN_CATEGORY_B){ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) { p_tx_dl_bfw_buffer[i] = (int16_t*)malloc(iq_bfw_buffer_size_dl); tx_dl_bfw_buffer_size[i] = (int32_t)iq_bfw_buffer_size_dl; if (p_tx_dl_bfw_buffer[i] == NULL) exit(-1); tx_dl_bfw_buffer_size[i] = sys_load_file_to_buff(startupConfiguration.dl_bfw_file[i], "DL BF weights IQ Samples in binary format", (uint8_t*) p_tx_dl_bfw_buffer[i], tx_dl_bfw_buffer_size[i], 1); tx_dl_bfw_buffer_position[i] = 0; } } if (startupConfiguration.appMode == APP_O_DU && startupConfiguration.xranCat == XRAN_CATEGORY_B){ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) { p_tx_ul_bfw_buffer[i] = (int16_t*)malloc(iq_bfw_buffer_size_ul); tx_ul_bfw_buffer_size[i] = (int32_t)iq_bfw_buffer_size_ul; if (p_tx_ul_bfw_buffer[i] == NULL) exit(-1); tx_ul_bfw_buffer_size[i] = sys_load_file_to_buff(startupConfiguration.ul_bfw_file[i], "UL BF weights IQ Samples in binary format", (uint8_t*) p_tx_ul_bfw_buffer[i], tx_ul_bfw_buffer_size[i], 1); tx_ul_bfw_buffer_position[i] = 0; } } if (startupConfiguration.appMode == APP_O_RU && startupConfiguration.enablePrach){ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) { p_tx_prach_play_buffer[i] = (int16_t*)malloc(PRACH_PLAYBACK_BUFFER_BYTES); tx_prach_play_buffer_size[i] = (int32_t)PRACH_PLAYBACK_BUFFER_BYTES; if (p_tx_prach_play_buffer[i] == NULL) exit(-1); memset(p_tx_prach_play_buffer[i], 0, PRACH_PLAYBACK_BUFFER_BYTES); tx_prach_play_buffer_size[i] = sys_load_file_to_buff(startupConfiguration.prach_file[i], "PRACH IQ Samples in binary format", (uint8_t*) p_tx_prach_play_buffer[i], tx_prach_play_buffer_size[i], 1); tx_prach_play_buffer_position[i] = 0; } } if (startupConfiguration.appMode == APP_O_RU && startupConfiguration.enableSrs){ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED_CAT_B && i < (uint32_t)(numCCPorts * startupConfiguration.antElmTRx); i++) { p_tx_srs_play_buffer[i] = (int16_t*)malloc(iq_srs_buffer_size_ul); tx_srs_play_buffer_size[i] = (int32_t)iq_srs_buffer_size_ul; if (p_tx_srs_play_buffer[i] == NULL) exit(-1); memset(p_tx_srs_play_buffer[i], 0, iq_srs_buffer_size_ul); tx_prach_play_buffer_size[i] = sys_load_file_to_buff(startupConfiguration.ul_srs_file[i], "SRS IQ Samples in binary format", (uint8_t*) p_tx_srs_play_buffer[i], tx_srs_play_buffer_size[i], 1); tx_srs_play_buffer_position[i] = 0; } } /* log of ul */ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) { p_rx_log_buffer[i] = (int16_t*)malloc(iq_playback_buffer_size_ul); rx_log_buffer_size[i] = (int32_t)iq_playback_buffer_size_ul; if (p_rx_log_buffer[i] == NULL) exit(-1); rx_log_buffer_position[i] = 0; memset(p_rx_log_buffer[i], 0, rx_log_buffer_size[i]); } /* log of prach */ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) { p_prach_log_buffer[i] = (int16_t*)malloc(startupConfiguration.numSlots*XRAN_NUM_OF_SYMBOL_PER_SLOT*PRACH_PLAYBACK_BUFFER_BYTES); prach_log_buffer_size[i] = (int32_t)startupConfiguration.numSlots*XRAN_NUM_OF_SYMBOL_PER_SLOT*PRACH_PLAYBACK_BUFFER_BYTES; if (p_prach_log_buffer[i] == NULL) exit(-1); memset(p_prach_log_buffer[i], 0, prach_log_buffer_size[i]); prach_log_buffer_position[i] = 0; } /* log of SRS */ if (startupConfiguration.appMode == APP_O_DU && startupConfiguration.enableSrs){ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED_CAT_B && i < (uint32_t)(numCCPorts * startupConfiguration.antElmTRx); i++) { p_srs_log_buffer[i] = (int16_t*)malloc(iq_srs_buffer_size_ul); srs_log_buffer_size[i] = (int32_t)iq_srs_buffer_size_ul; if (p_srs_log_buffer[i] == NULL) exit(-1); memset(p_srs_log_buffer[i], 0, iq_srs_buffer_size_ul); srs_log_buffer_position[i] = 0; } } if (stat("./logs", &st) == -1) { mkdir("./logs", 0777); } for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) { sprintf(filename, "./logs/%s-play_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i); sys_save_buf_to_file_txt(filename, "DL IFFT IN IQ Samples in human readable format", (uint8_t*) p_tx_play_buffer[i], tx_play_buffer_size[i], 1); sprintf(filename, "./logs/%s-play_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i); sys_save_buf_to_file(filename, "DL IFFT IN IQ Samples in binary format", (uint8_t*) p_tx_play_buffer[i], tx_play_buffer_size[i]/sizeof(short), sizeof(short)); if (startupConfiguration.appMode == APP_O_DU && startupConfiguration.xranCat == XRAN_CATEGORY_B){ sprintf(filename, "./logs/%s-dl_bfw_ue%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i); sys_save_buf_to_file_txt(filename, "DL Beamformig weights IQ Samples in human readable format", (uint8_t*) p_tx_dl_bfw_buffer[i], tx_dl_bfw_buffer_size[i], 1); sprintf(filename, "./logs/%s-dl_bfw_ue%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i); sys_save_buf_to_file(filename, "DL Beamformig weightsIQ Samples in binary format", (uint8_t*) p_tx_dl_bfw_buffer[i], tx_dl_bfw_buffer_size[i]/sizeof(short), sizeof(short)); sprintf(filename, "./logs/%s-ul_bfw_ue%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i); sys_save_buf_to_file_txt(filename, "UL Beamformig weights IQ Samples in human readable format", (uint8_t*) p_tx_ul_bfw_buffer[i], tx_ul_bfw_buffer_size[i], 1); sprintf(filename, "./logs/%s-ul_bfw_ue%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i); sys_save_buf_to_file(filename, "UL Beamformig weightsIQ Samples in binary format", (uint8_t*) p_tx_ul_bfw_buffer[i], tx_ul_bfw_buffer_size[i]/sizeof(short), sizeof(short)); } if (startupConfiguration.appMode == APP_O_RU && startupConfiguration.enablePrach){ sprintf(filename, "./logs/%s-play_prach_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i); sys_save_buf_to_file_txt(filename, "PRACH IQ Samples in human readable format", (uint8_t*) p_tx_prach_play_buffer[i], tx_prach_play_buffer_size[i], 1); sprintf(filename, "./logs/%s-play_prach_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i); sys_save_buf_to_file(filename, "PRACH IQ Samples in binary format", (uint8_t*) p_tx_prach_play_buffer[i], tx_prach_play_buffer_size[i]/sizeof(short), sizeof(short)); } } if (startupConfiguration.appMode == APP_O_RU && startupConfiguration.enableSrs && startupConfiguration.xranCat == XRAN_CATEGORY_B){ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED_CAT_B && i < (uint32_t)(numCCPorts * startupConfiguration.antElmTRx); i++) { sprintf(filename, "./logs/%s-play_srs_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i); sys_save_buf_to_file_txt(filename, "SRS IQ Samples in human readable format", (uint8_t*) p_tx_srs_play_buffer[i], tx_srs_play_buffer_size[i], 1); sprintf(filename, "./logs/%s-play_srs_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i); sys_save_buf_to_file(filename, "SRS IQ Samples in binary format", (uint8_t*) p_tx_srs_play_buffer[i], tx_srs_play_buffer_size[i]/sizeof(short), sizeof(short)); } } if (startupConfiguration.iqswap == 1){ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) { printf("TX: Swap I and Q to match RU format: [%d]\n",i); { /* swap I and Q */ int32_t j; signed short *ptr = (signed short *) p_tx_play_buffer[i]; signed short temp; for (j = 0; j < (int32_t)(tx_play_buffer_size[i]/sizeof(short)) ; j = j + 2){ temp = ptr[j]; ptr[j] = ptr[j + 1]; ptr[j + 1] = temp; } } if (startupConfiguration.appMode == APP_O_DU && startupConfiguration.xranCat == XRAN_CATEGORY_B){ printf("DL BFW: Swap I and Q to match RU format: [%d]\n",i); { /* swap I and Q */ int32_t j; signed short *ptr = (signed short *) p_tx_dl_bfw_buffer[i]; signed short temp; for (j = 0; j < (int32_t)(tx_dl_bfw_buffer_size[i]/sizeof(short)) ; j = j + 2){ temp = ptr[j]; ptr[j] = ptr[j + 1]; ptr[j + 1] = temp; } } printf("UL BFW: Swap I and Q to match RU format: [%d]\n",i); { /* swap I and Q */ int32_t j; signed short *ptr = (signed short *) p_tx_ul_bfw_buffer[i]; signed short temp; for (j = 0; j < (int32_t)(tx_ul_bfw_buffer_size[i]/sizeof(short)) ; j = j + 2){ temp = ptr[j]; ptr[j] = ptr[j + 1]; ptr[j + 1] = temp; } } } } if (startupConfiguration.appMode == APP_O_RU){ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) { printf("PRACH: Swap I and Q to match RU format: [%d]\n",i); { /* swap I and Q */ int32_t j; signed short *ptr = (signed short *) p_tx_prach_play_buffer[i]; signed short temp; for (j = 0; j < (int32_t)(tx_prach_play_buffer_size[i]/sizeof(short)) ; j = j + 2){ temp = ptr[j]; ptr[j] = ptr[j + 1]; ptr[j + 1] = temp; } } } } if (startupConfiguration.appMode == APP_O_RU){ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED_CAT_B && i < (uint32_t)(numCCPorts * startupConfiguration.antElmTRx); i++) { printf("SRS: Swap I and Q to match RU format: [%d]\n",i); { /* swap I and Q */ int32_t j; signed short *ptr = (signed short *) p_tx_srs_play_buffer[i]; signed short temp; for (j = 0; j < (int32_t)(tx_srs_play_buffer_size[i]/sizeof(short)) ; j = j + 2){ temp = ptr[j]; ptr[j] = ptr[j + 1]; ptr[j + 1] = temp; } } } } } #if 0 for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) { sprintf(filename, "./logs/swap_IQ_play_ant%d.txt", i); sys_save_buf_to_file_txt(filename, "DL IFFT IN IQ Samples in human readable format", (uint8_t*) p_tx_play_buffer[i], tx_play_buffer_size[i], 1); } #endif if (startupConfiguration.nebyteorderswap == 1 && startupConfiguration.compression == 0){ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) { printf("TX: Convert S16 I and S16 Q to network byte order for XRAN Ant: [%d]\n",i); for (j = 0; j < tx_play_buffer_size[i]/sizeof(short); j++){ p_tx_play_buffer[i][j] = rte_cpu_to_be_16(p_tx_play_buffer[i][j]); } if (startupConfiguration.appMode == APP_O_DU && startupConfiguration.xranCat == XRAN_CATEGORY_B){ printf("DL BFW: Convert S16 I and S16 Q to network byte order for XRAN Ant: [%d]\n",i); for (j = 0; j < tx_dl_bfw_buffer_size[i]/sizeof(short); j++){ p_tx_dl_bfw_buffer[i][j] = rte_cpu_to_be_16(p_tx_dl_bfw_buffer[i][j]); } printf("UL BFW: Convert S16 I and S16 Q to network byte order for XRAN Ant: [%d]\n",i); for (j = 0; j < tx_ul_bfw_buffer_size[i]/sizeof(short); j++){ p_tx_ul_bfw_buffer[i][j] = rte_cpu_to_be_16(p_tx_ul_bfw_buffer[i][j]); } } } if (startupConfiguration.appMode == APP_O_RU && startupConfiguration.enablePrach){ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) { printf("PRACH: Convert S16 I and S16 Q to network byte order for XRAN Ant: [%d]\n",i); for (j = 0; j < tx_prach_play_buffer_size[i]/sizeof(short); j++){ p_tx_prach_play_buffer[i][j] = rte_cpu_to_be_16(p_tx_prach_play_buffer[i][j]); } } } if (startupConfiguration.appMode == APP_O_RU && startupConfiguration.enableSrs){ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED_CAT_B && i < (uint32_t)(numCCPorts * startupConfiguration.antElmTRx); i++) { printf("SRS: Convert S16 I and S16 Q to network byte order for XRAN Ant: [%d]\n",i); for (j = 0; j < tx_srs_play_buffer_size[i]/sizeof(short); j++){ p_tx_srs_play_buffer[i][j] = rte_cpu_to_be_16(p_tx_srs_play_buffer[i][j]); } } } } #if 0 for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) { sprintf(filename, "./logs/swap_be_play_ant%d.txt", i); sys_save_buf_to_file_txt(filename, "DL IFFT IN IQ Samples in human readable format", (uint8_t*) p_tx_play_buffer[i], tx_play_buffer_size[i], 1); } #endif memset(&xranConf, 0, sizeof(struct xran_fh_config)); pXranConf = &xranConf; pXranConf->nDLRBs = app_xran_get_num_rbs(startupConfiguration.mu_number, startupConfiguration.nDLBandwidth, startupConfiguration.nDLAbsFrePointA); pXranConf->nULRBs = app_xran_get_num_rbs(startupConfiguration.mu_number, startupConfiguration.nULBandwidth, startupConfiguration.nULAbsFrePointA); if(startupConfiguration.DynamicSectionEna == 0){ struct xran_prb_map* pRbMap; pRbMap = &startupConfiguration.PrbMapDl; pRbMap->dir = XRAN_DIR_DL; pRbMap->xran_port = 0; pRbMap->band_id = 0; pRbMap->cc_id = 0; pRbMap->ru_port_id = 0; pRbMap->tti_id = 0; pRbMap->start_sym_id = 0; pRbMap->nPrbElm = 1; pRbMap->prbMap[0].nStartSymb = 0; pRbMap->prbMap[0].numSymb = 14; pRbMap->prbMap[0].nRBStart = 0; pRbMap->prbMap[0].nRBSize = pXranConf->nDLRBs; pRbMap->prbMap[0].nBeamIndex = 0; pRbMap->prbMap[0].compMethod = XRAN_COMPMETHOD_NONE; pRbMap->prbMap[0].iqWidth = 16; pRbMap = &startupConfiguration.PrbMapUl; pRbMap->dir = XRAN_DIR_UL; pRbMap->xran_port = 0; pRbMap->band_id = 0; pRbMap->cc_id = 0; pRbMap->ru_port_id = 0; pRbMap->tti_id = 0; pRbMap->start_sym_id = 0; pRbMap->nPrbElm = 1; pRbMap->prbMap[0].nStartSymb = 0; pRbMap->prbMap[0].numSymb = 14; pRbMap->prbMap[0].nRBStart = 0; pRbMap->prbMap[0].nRBSize = pXranConf->nULRBs; pRbMap->prbMap[0].nBeamIndex = 0; pRbMap->prbMap[0].compMethod = XRAN_COMPMETHOD_NONE; pRbMap->prbMap[0].iqWidth = 16; } timer_set_tsc_freq_from_clock(); xret = xran_init(argc, argv, &xranInit, argv[0], &xranHandle); if(xret != XRAN_STATUS_SUCCESS){ printf("xran_init failed %d\n", xret); exit(-1); } if(xranHandle == NULL) exit(1); pXranConf->sector_id = 0; pXranConf->nCC = numCCPorts; pXranConf->neAxc = num_eAxc; pXranConf->neAxcUl = startupConfiguration.numUlAxc; pXranConf->nAntElmTRx = startupConfiguration.antElmTRx; pXranConf->frame_conf.nFrameDuplexType = startupConfiguration.nFrameDuplexType; pXranConf->frame_conf.nNumerology = startupConfiguration.mu_number; pXranConf->frame_conf.nTddPeriod = startupConfiguration.nTddPeriod; for (i = 0; i < startupConfiguration.nTddPeriod; i++){ pXranConf->frame_conf.sSlotConfig[i] = startupConfiguration.sSlotConfig[i]; } pXranConf->prach_conf.nPrachSubcSpacing = startupConfiguration.mu_number; pXranConf->prach_conf.nPrachFreqStart = 0; pXranConf->prach_conf.nPrachFilterIdx = XRAN_FILTERINDEX_PRACH_ABC; pXranConf->prach_conf.nPrachConfIdx = startupConfiguration.prachConfigIndex; pXranConf->prach_conf.nPrachFreqOffset = -792; pXranConf->srs_conf.symbMask = startupConfiguration.srsSymMask; pXranConf->srs_conf.eAxC_offset = 2 * startupConfiguration.numAxc; /* PUSCH, PRACH, SRS */ pXranConf->ru_conf.xranCat = startupConfiguration.xranCat; pXranConf->ru_conf.iqWidth = startupConfiguration.PrbMapDl.prbMap[0].iqWidth; if (startupConfiguration.compression == 0) pXranConf->ru_conf.compMeth = XRAN_COMPMETHOD_NONE; else pXranConf->ru_conf.compMeth = XRAN_COMPMETHOD_BLKFLOAT; pXranConf->ru_conf.fftSize = 0; while (startupConfiguration.nULFftSize >>= 1) ++pXranConf->ru_conf.fftSize; pXranConf->ru_conf.byteOrder = (startupConfiguration.nebyteorderswap == 1) ? XRAN_NE_BE_BYTE_ORDER : XRAN_CPU_LE_BYTE_ORDER ; pXranConf->ru_conf.iqOrder = (startupConfiguration.iqswap == 1) ? XRAN_Q_I_ORDER : XRAN_I_Q_ORDER; printf("FFT Order %d\n", pXranConf->ru_conf.fftSize); nCenterFreq = startupConfiguration.nDLAbsFrePointA + (((pXranConf->nDLRBs * N_SC_PER_PRB) / 2) * app_xran_get_scs(startupConfiguration.mu_number)); pXranConf->nDLCenterFreqARFCN = app_xran_cal_nrarfcn(nCenterFreq); printf("DL center freq %d DL NR-ARFCN %d\n", nCenterFreq, pXranConf->nDLCenterFreqARFCN); nCenterFreq = startupConfiguration.nULAbsFrePointA + (((pXranConf->nULRBs * N_SC_PER_PRB) / 2) * app_xran_get_scs(startupConfiguration.mu_number)); pXranConf->nULCenterFreqARFCN = app_xran_cal_nrarfcn(nCenterFreq); printf("UL center freq %d UL NR-ARFCN %d\n", nCenterFreq, pXranConf->nULCenterFreqARFCN); pXranConf->bbdev_dec = NULL; pXranConf->bbdev_enc = NULL; pXranConf->log_level = 1; if(startupConfiguration.maxFrameId) pXranConf->ru_conf.xran_max_frame = startupConfiguration.maxFrameId; if(init_xran() != 0) exit(-1); xran_reg_physide_cb(xranHandle, physide_dl_tti_call_back, NULL, 10, XRAN_CB_TTI); xran_reg_physide_cb(xranHandle, physide_ul_half_slot_call_back, NULL, 10, XRAN_CB_HALF_SLOT_RX); xran_reg_physide_cb(xranHandle, physide_ul_full_slot_call_back, NULL, 10, XRAN_CB_FULL_SLOT_RX); init_xran_iq_content(); xret = xran_open(xranHandle, pXranConf); if(xret != XRAN_STATUS_SUCCESS){ printf("xran_open failed %d\n", xret); exit(-1); } sprintf(filename, "mlog-%s", startupConfiguration.appMode == 0 ? "o-du" : "o-ru"); /* MLogOpen(0, 32, 0, 0xFFFFFFFF, filename);*/ MLogOpen(256, 3, 20000, 0, filename); MLogSetMask(0); puts("----------------------------------------"); printf("MLog Info: virt=0x%016lx size=%d\n", MLogGetFileLocation(), MLogGetFileSize()); puts("----------------------------------------"); uint64_t nActiveCoreMask[MAX_BBU_POOL_CORE_MASK] = {0}; nActiveCoreMask[0] = 1 << xranInit.io_cfg.timing_core; uint32_t numCarriers = startupConfiguration.numCC; MLogAddTestCase(nActiveCoreMask, numCarriers); fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK); state = APP_RUNNING; printf("Start XRAN traffic\n"); xran_start(xranHandle); sleep(3); print_menu(); for (;;) { struct xran_common_counters x_counters; char input[10]; sleep(1); xran_curr_if_state = xran_get_if_state(); if(xran_get_common_counters(xranHandle, &x_counters) == XRAN_STATUS_SUCCESS) { xran_get_time_stats(&nTotalTime, &nUsedTime, &nCoreUsed, 1); nUsedPercent = ((float)nUsedTime * 100.0) / (float)nTotalTime; printf("[%s][rx %ld pps %ld kbps %ld][tx %ld pps %ld kbps %ld] [on_time %ld early %ld late %ld corrupt %ld pkt_dupl %ld Total %ld] IO Util: %5.2f %%\n", ((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), rx_counter, rx_counter-old_rx_counter, rx_bytes_per_sec*8/1000L, tx_counter, tx_counter-old_tx_counter, tx_bytes_per_sec*8/1000L, x_counters.Rx_on_time, x_counters.Rx_early, x_counters.Rx_late, x_counters.Rx_corrupt, x_counters.Rx_pkt_dupl, x_counters.Total_msgs_rcvd, nUsedPercent); if(rx_counter > old_rx_counter) old_rx_counter = rx_counter; if(tx_counter > old_tx_counter) old_tx_counter = tx_counter; if(rx_counter > 0 && tx_counter > 0) MLogSetMask(0xFFFFFFFF); } else { printf("error xran_get_common_counters\n"); } if (xran_curr_if_state == XRAN_STOPPED){ break; } if (NULL == fgets(input, 10, stdin)) { continue; } const int sel_opt = atoi(input); switch (sel_opt) { case 1: xran_start(xranHandle); printf("Start XRAN traffic\n"); break; case 2: break; case 3: xran_stop(xranHandle); printf("Stop XRAN traffic\n"); state = APP_STOPPED; break; default: puts("Wrong option passed!"); break; } if (APP_STOPPED == state) break; } get_xran_iq_content(); puts("Closing l1 app... Ending all threads..."); xran_close(xranHandle); MLogPrint(NULL); stop_xran(); puts("Dump IQs..."); if (startupConfiguration.iqswap == 1){ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) { printf("RX: Swap I and Q to match CPU format: [%d]\n",i); { /* swap I and Q */ int32_t j; signed short *ptr = (signed short *) p_rx_log_buffer[i]; signed short temp; for (j = 0; j < (int32_t)(rx_log_buffer_size[i]/sizeof(short)) ; j = j + 2){ temp = ptr[j]; ptr[j] = ptr[j + 1]; ptr[j + 1] = temp; } } } if (startupConfiguration.appMode == APP_O_DU && startupConfiguration.enableSrs){ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED_CAT_B && i < (uint32_t)(numCCPorts * startupConfiguration.antElmTRx); i++) { printf("SRS: Swap I and Q to match CPU format: [%d]\n",i); { /* swap I and Q */ int32_t j; signed short *ptr = (signed short *) p_srs_log_buffer[i]; signed short temp; for (j = 0; j < (int32_t)(srs_log_buffer_size[i]/sizeof(short)) ; j = j + 2){ temp = ptr[j]; ptr[j] = ptr[j + 1]; ptr[j + 1] = temp; } } } } } if (startupConfiguration.nebyteorderswap == 1 && startupConfiguration.compression == 0) { for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) { printf("RX: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [%d]\n",i); for (j = 0; j < rx_log_buffer_size[i]/sizeof(short); j++){ p_rx_log_buffer[i][j] = rte_be_to_cpu_16(p_rx_log_buffer[i][j]); } } if (startupConfiguration.appMode == APP_O_DU && startupConfiguration.enableSrs){ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED_CAT_B && i < (uint32_t)(numCCPorts * startupConfiguration.antElmTRx); i++) { printf("SRS: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [%d]\n",i); for (j = 0; j < srs_log_buffer_size[i]/sizeof(short); j++){ p_srs_log_buffer[i][j] = rte_be_to_cpu_16(p_srs_log_buffer[i][j]); } } } } for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) { sprintf(filename, "./logs/%s-rx_log_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i); sys_save_buf_to_file_txt(filename, "UL FFT OUT IQ Samples in human readable format", (uint8_t*) p_rx_log_buffer[i], rx_log_buffer_size[i], 1); sprintf(filename, "./logs/%s-rx_log_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i); sys_save_buf_to_file(filename, "UL FFT OUT IQ Samples in binary format", (uint8_t*) p_rx_log_buffer[i], rx_log_buffer_size[i]/sizeof(short), sizeof(short)); } if (startupConfiguration.appMode == APP_O_DU && startupConfiguration.enableSrs){ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED_CAT_B && i < (uint32_t)(numCCPorts * startupConfiguration.antElmTRx); i++) { sprintf(filename, "./logs/%s-srs_log_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i); sys_save_buf_to_file_txt(filename, "SRS UL FFT OUT IQ Samples in human readable format", (uint8_t*) p_srs_log_buffer[i], srs_log_buffer_size[i], 1); sprintf(filename, "./logs/%s-srs_log_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i); sys_save_buf_to_file(filename, "SRS UL FFT OUT IQ Samples in binary format", (uint8_t*) p_srs_log_buffer[i], srs_log_buffer_size[i]/sizeof(short), sizeof(short)); } } if (startupConfiguration.appMode == APP_O_DU && startupConfiguration.enablePrach){ if (startupConfiguration.iqswap == 1){ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) { printf("PRACH: Swap I and Q to match CPU format: [%d]\n",i); { /* swap I and Q */ int32_t j; signed short *ptr = (signed short *) p_prach_log_buffer[i]; signed short temp; for (j = 0; j < (int32_t)(prach_log_buffer_size[i]/sizeof(short)) ; j = j + 2){ temp = ptr[j]; ptr[j] = ptr[j + 1]; ptr[j + 1] = temp; } } } } if (startupConfiguration.nebyteorderswap == 1 && startupConfiguration.compression == 0){ for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) { printf("PRACH: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [%d]\n",i); for (j = 0; j < prach_log_buffer_size[i]/sizeof(short); j++){ p_prach_log_buffer[i][j] = rte_be_to_cpu_16(p_prach_log_buffer[i][j]); } } } for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) { sprintf(filename, "./logs/%s-prach_log_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i); sys_save_buf_to_file_txt(filename, "PRACH FFT OUT IQ Samples in human readable format", (uint8_t*) p_prach_log_buffer[i], prach_log_buffer_size[i], 1); sprintf(filename, "./logs/%s-prach_log_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i); sys_save_buf_to_file(filename, "PRACH FFT OUT IQ Samples in binary format", (uint8_t*) p_prach_log_buffer[i], prach_log_buffer_size[i]/sizeof(short), sizeof(short)); } } return 0; }