X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?p=o-du%2Fphy.git;a=blobdiff_plain;f=fhi_lib%2Flib%2Fsrc%2Fxran_main.c;h=256457d3ad9dc538585a96b94e1cc7697f1ca201;hp=94751f6bd0cb70efc4c3f1f93b7272bbe5e1746d;hb=cef07f74965b1749dd909fc1322e211489fea2ea;hpb=bc60e3a69129edf1c21a01683f84a77483f6e3cc diff --git a/fhi_lib/lib/src/xran_main.c b/fhi_lib/lib/src/xran_main.c index 94751f6..256457d 100644 --- a/fhi_lib/lib/src/xran_main.c +++ b/fhi_lib/lib/src/xran_main.c @@ -16,7 +16,6 @@ * *******************************************************************************/ - /** * @brief XRAN main functionality module * @file xran_main.c @@ -34,6 +33,7 @@ #include #include #include +#include #include #include @@ -41,9 +41,10 @@ #include #include #include +#include #include -#include "xran_fh_lls_cu.h" +#include "xran_fh_o_du.h" #include "ethdi.h" #include "xran_pkt.h" @@ -53,13 +54,11 @@ #include "xran_lib_mlog_tasks_id.h" #include "xran_timer.h" #include "xran_common.h" +#include "xran_frame_struct.h" #include "xran_printf.h" +#include "xran_app_frag.h" -#ifndef MLOG_ENABLED -#include "mlog_lnx_xRAN.h" -#else -#include "mlog_lnx.h" -#endif +#include "xran_mlog_lnx.h" #define DIV_ROUND_OFFSET(X,Y) ( X/Y + ((X%Y)?1:0) ) @@ -69,42 +68,51 @@ (((int32_t)otaSym - (int32_t)offSym) - numSymTotal) : \ ((int32_t)otaSym - (int32_t)offSym)) -#define MAX_NUM_OF_XRAN_CTX (2) +#define MAX_NUM_OF_XRAN_CTX (2) #define XranIncrementCtx(ctx) ((ctx >= (MAX_NUM_OF_XRAN_CTX-1)) ? 0 : (ctx+1)) #define XranDecrementCtx(ctx) ((ctx == 0) ? (MAX_NUM_OF_XRAN_CTX-1) : (ctx-1)) +#define MAX_NUM_OF_DPDK_TIMERS (10) +#define DpdkTiemerIncrementCtx(ctx) ((ctx >= (MAX_NUM_OF_DPDK_TIMERS-1)) ? 0 : (ctx+1)) +#define DpdkTiemerDecrementCtx(ctx) ((ctx == 0) ? (MAX_NUM_OF_DPDK_TIMERS-1) : (ctx-1)) + + +//#define XRAN_CREATE_RBMAP /**< generate slot map base on symbols */ + + struct xran_timer_ctx { uint32_t tti_to_process; }; -static XranLibHandleInfoStruct DevHandle; -static struct xran_lib_ctx g_xran_lib_ctx = { 0 }; +static xran_cc_handle_t pLibInstanceHandles[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR] = {NULL}; +static struct xran_device_ctx g_xran_dev_ctx[XRAN_PORTS_NUM] = { 0 }; struct xran_timer_ctx timer_ctx[MAX_NUM_OF_XRAN_CTX]; static struct rte_timer tti_to_phy_timer[10]; -static struct rte_timer tti_timer; static struct rte_timer sym_timer; -static struct rte_timer tx_cp_dl_timer; -static struct rte_timer tx_cp_ul_timer; -static struct rte_timer tx_up_timer; +static struct rte_timer dpdk_timer[MAX_NUM_OF_DPDK_TIMERS]; -static long interval_us = 125; +long interval_us = 1000; -uint32_t xran_lib_ota_tti = 0; /* [0:7999] */ -uint32_t xran_lib_ota_sym = 0; /* [0:7] */ -uint32_t xran_lib_ota_sym_idx = 0; /* [0 : 14*8*1000-1] */ +uint32_t xran_lib_ota_tti = 0; /* [0:(1000000/TTI-1)] */ +uint32_t xran_lib_ota_sym = 0; /* [0:1000/TTI-1] */ +uint32_t xran_lib_ota_sym_idx = 0; /* [0 : 14*(1000000/TTI)-1] + where TTI is TTI interval in microseconds */ -uint64_t xran_lib_gps_second = 0; +static uint8_t xran_cp_seq_id_num[XRAN_MAX_CELLS_PER_PORT][XRAN_DIR_MAX][XRAN_MAX_ANTENNA_NR * 2]; //XRAN_MAX_ANTENNA_NR * 2 for PUSCH and PRACH +static uint8_t xran_updl_seq_id_num[XRAN_MAX_CELLS_PER_PORT][XRAN_MAX_ANTENNA_NR]; +static uint8_t xran_upul_seq_id_num[XRAN_MAX_CELLS_PER_PORT][XRAN_MAX_ANTENNA_NR * 2]; -static uint8_t xran_cp_seq_id_num[XRAN_MAX_CELLS_PER_PORT][XRAN_DIR_MAX][XRAN_MAX_ANTENNA_NR]; -static uint8_t xran_section_id_curslot[XRAN_MAX_CELLS_PER_PORT][XRAN_MAX_ANTENNA_NR]; -static uint16_t xran_section_id[XRAN_MAX_CELLS_PER_PORT][XRAN_MAX_ANTENNA_NR]; +static uint8_t xran_section_id_curslot[XRAN_MAX_CELLS_PER_PORT][XRAN_MAX_ANTENNA_NR * 2]; +static uint16_t xran_section_id[XRAN_MAX_CELLS_PER_PORT][XRAN_MAX_ANTENNA_NR * 2]; void xran_timer_arm(struct rte_timer *tim, void* arg); + int xran_process_tx_sym(void *arg); int xran_process_rx_sym(void *arg, + struct rte_mbuf *mbuf, void *iq_data_start, uint16_t size, uint8_t CC_ID, @@ -112,27 +120,91 @@ int xran_process_rx_sym(void *arg, uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id, - uint8_t symb_id); + uint8_t symb_id, + uint16_t num_prbu, + uint16_t start_prbu, + uint16_t sym_inc, + uint16_t rb, + uint16_t sect_id, + uint32_t *mb_free); + +int xran_process_prach_sym(void *arg, + struct rte_mbuf *mbuf, + void *iq_data_start, + uint16_t size, + uint8_t CC_ID, + uint8_t Ant_ID, + uint8_t frame_id, + uint8_t subframe_id, + uint8_t slot_id, + uint8_t symb_id, + uint16_t num_prbu, + uint16_t start_prbu, + uint16_t sym_inc, + uint16_t rb, + uint16_t sect_id); void tti_ota_cb(struct rte_timer *tim, void *arg); void tti_to_phy_cb(struct rte_timer *tim, void *arg); void xran_timer_arm_ex(struct rte_timer *tim, void* CbFct, void *CbArg, unsigned tim_lcore); -struct xran_lib_ctx *xran_lib_get_ctx(void) +struct xran_device_ctx *xran_dev_get_ctx(void) { - return &g_xran_lib_ctx; + return &g_xran_dev_ctx[0]; } -static inline XRANFHCONFIG *xran_lib_get_ctx_fhcfg(void) +static inline struct xran_fh_config *xran_lib_get_ctx_fhcfg(void) { - return (&(xran_lib_get_ctx()->xran_fh_cfg)); + return (&(xran_dev_get_ctx()->fh_cfg)); } -inline uint16_t xran_get_beamid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id) +uint16_t xran_get_beamid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id) { return (0); // NO BEAMFORMING } +enum xran_if_state xran_get_if_state(void) +{ + return xran_if_current_state; +} + +int xran_isPRACHSlot(uint32_t subframe_id, uint32_t slot_id) +{ + struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx(); + xRANPrachCPConfigStruct *pPrachCPConfig = &(p_xran_dev_ctx->PrachCPConfig); + int isPRACHslot = 0; + + if (p_xran_dev_ctx->fh_cfg.frame_conf.nNumerology < 2){ + //for FR1, in 38.211 tab 6.3.3.2-2&3 it is subframe index + if (pPrachCPConfig->isPRACHslot[subframe_id] == 1){ + if (pPrachCPConfig->nrofPrachInSlot != 1) + isPRACHslot = 1; + else{ + if (p_xran_dev_ctx->fh_cfg.frame_conf.nNumerology == 0) + isPRACHslot = 1; + else if (slot_id == 1) + isPRACHslot = 1; + } + } + } + else if (p_xran_dev_ctx->fh_cfg.frame_conf.nNumerology == 3){ + //for FR2, 38.211 tab 6.3.3.4 it is slot index of 60kHz slot + uint32_t slotidx; + slotidx = subframe_id * SLOTNUM_PER_SUBFRAME + slot_id; + if (pPrachCPConfig->nrofPrachInSlot == 2){ + if (pPrachCPConfig->isPRACHslot[slotidx>>1] == 1) + isPRACHslot = 1; + } + else{ + if ((pPrachCPConfig->isPRACHslot[slotidx>>1] == 1) && (slotidx % 2 == 1)) + isPRACHslot = 1; + } + } + else + print_err("Numerology %d not supported", p_xran_dev_ctx->fh_cfg.frame_conf.nNumerology); + return isPRACHslot; +} + int xran_init_sectionid(void *pHandle) { int cell, dir, ant; @@ -147,19 +219,72 @@ int xran_init_sectionid(void *pHandle) return (0); } -int xran_init_seqid(void *pHandle) +int xran_init_prach(struct xran_fh_config* pConf, struct xran_device_ctx * p_xran_dev_ctx) { - int cell, dir, ant; + int32_t i; + uint8_t slotNr; + struct xran_prach_config* pPRACHConfig = &(pConf->prach_conf); + const xRANPrachConfigTableStruct *pxRANPrachConfigTable; + uint8_t nNumerology = pConf->frame_conf.nNumerology; + uint8_t nPrachConfIdx = pPRACHConfig->nPrachConfIdx; + xRANPrachCPConfigStruct *pPrachCPConfig = &(p_xran_dev_ctx->PrachCPConfig); - for(cell=0; cell < XRAN_MAX_CELLS_PER_PORT; cell++) { - for(dir=0; dir < XRAN_DIR_MAX; dir++) { - for(ant=0; ant < XRAN_MAX_ANTENNA_NR; ant++) { - xran_cp_seq_id_num[cell][dir][ant] = 0; - } - } + if (nNumerology > 2) + pxRANPrachConfigTable = &gxranPrachDataTable_mmw[nPrachConfIdx]; + else if (pConf->frame_conf.nFrameDuplexType == 1) + pxRANPrachConfigTable = &gxranPrachDataTable_sub6_tdd[nPrachConfIdx]; + else + pxRANPrachConfigTable = &gxranPrachDataTable_sub6_fdd[nPrachConfIdx]; + + uint8_t preambleFmrt = pxRANPrachConfigTable->preambleFmrt[0]; + const xRANPrachPreambleLRAStruct *pxranPreambleforLRA = &gxranPreambleforLRA[preambleFmrt]; + memset(pPrachCPConfig, 0, sizeof(xRANPrachCPConfigStruct)); + if(pConf->log_level) + printf("xRAN open PRACH config: Numerology %u ConfIdx %u, preambleFmrt %u startsymb %u, numSymbol %u, occassionsInPrachSlot %u\n", nNumerology, nPrachConfIdx, preambleFmrt, pxRANPrachConfigTable->startingSym, pxRANPrachConfigTable->duration, pxRANPrachConfigTable->occassionsInPrachSlot); + + pPrachCPConfig->filterIdx = XRAN_FILTERINDEX_PRACH_ABC; // 3, PRACH preamble format A1~3, B1~4, C0, C2 + pPrachCPConfig->startSymId = pxRANPrachConfigTable->startingSym; + pPrachCPConfig->startPrbc = pPRACHConfig->nPrachFreqStart; + pPrachCPConfig->numPrbc = (preambleFmrt >= FORMAT_A1)? 12 : 70; + pPrachCPConfig->timeOffset = pxranPreambleforLRA->nRaCp; + pPrachCPConfig->freqOffset = xran_get_freqoffset(pPRACHConfig->nPrachFreqOffset, pPRACHConfig->nPrachSubcSpacing); + pPrachCPConfig->x = pxRANPrachConfigTable->x; + pPrachCPConfig->nrofPrachInSlot = pxRANPrachConfigTable->nrofPrachInSlot; + pPrachCPConfig->y[0] = pxRANPrachConfigTable->y[0]; + pPrachCPConfig->y[1] = pxRANPrachConfigTable->y[1]; + if (preambleFmrt >= FORMAT_A1) + { + pPrachCPConfig->numSymbol = pxRANPrachConfigTable->duration; + pPrachCPConfig->occassionsInPrachSlot = pxRANPrachConfigTable->occassionsInPrachSlot; + } + else + { + pPrachCPConfig->numSymbol = 1; + pPrachCPConfig->occassionsInPrachSlot = 1; + } + + if(pConf->log_level) + printf("PRACH: x %u y[0] %u, y[1] %u prach slot: %u ..", pPrachCPConfig->x, pPrachCPConfig->y[0], pPrachCPConfig->y[1], pxRANPrachConfigTable->slotNr[0]); + pPrachCPConfig->isPRACHslot[pxRANPrachConfigTable->slotNr[0]] = 1; + for (i=1; i < XRAN_PRACH_CANDIDATE_SLOT; i++) + { + slotNr = pxRANPrachConfigTable->slotNr[i]; + if (slotNr > 0){ + pPrachCPConfig->isPRACHslot[slotNr] = 1; + if(pConf->log_level) + printf(" %u ..", slotNr); } + } + printf("\n"); + for (i = 0; i < XRAN_MAX_SECTOR_NR; i++){ + p_xran_dev_ctx->prach_start_symbol[i] = pPrachCPConfig->startSymId; + p_xran_dev_ctx->prach_last_symbol[i] = pPrachCPConfig->startSymId + pPrachCPConfig->numSymbol * pPrachCPConfig->occassionsInPrachSlot - 1; + } + if(pConf->log_level){ + printf("PRACH start symbol %u lastsymbol %u\n", p_xran_dev_ctx->prach_start_symbol[0], p_xran_dev_ctx->prach_last_symbol[0]); + } - return (0); + return (XRAN_STATUS_SUCCESS); } inline uint16_t xran_alloc_sectionid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id) @@ -168,22 +293,40 @@ inline uint16_t xran_alloc_sectionid(void *pHandle, uint8_t dir, uint8_t cc_id, print_err("Invalid CC ID - %d", cc_id); return (0); } - if(ant_id >= XRAN_MAX_ANTENNA_NR) { + if(ant_id >= XRAN_MAX_ANTENNA_NR * 2) { //for PRACH, ant_id starts from num_ant print_err("Invalid antenna ID - %d", ant_id); return (0); - } + } /* if new slot has been started, * then initializes section id again for new start */ if(xran_section_id_curslot[cc_id][ant_id] != slot_id) { xran_section_id[cc_id][ant_id] = 0; xran_section_id_curslot[cc_id][ant_id] = slot_id; - } - + } + return(xran_section_id[cc_id][ant_id]++); } -inline uint8_t xran_get_seqid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id) +int xran_init_seqid(void *pHandle) +{ + int cell, dir, ant; + + for(cell=0; cell < XRAN_MAX_CELLS_PER_PORT; cell++) { + for(dir=0; dir < XRAN_DIR_MAX; dir++) { + for(ant=0; ant < XRAN_MAX_ANTENNA_NR * 2; ant++) + xran_cp_seq_id_num[cell][dir][ant] = 0; + } + for(ant=0; ant < XRAN_MAX_ANTENNA_NR; ant++) + xran_updl_seq_id_num[cell][ant] = 0; + for(ant=0; ant < XRAN_MAX_ANTENNA_NR * 2; ant++) + xran_upul_seq_id_num[cell][ant] = 0; + } + + return (0); +} + +static inline uint8_t xran_get_cp_seqid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id) { if(dir >= XRAN_DIR_MAX) { print_err("Invalid direction - %d", dir); @@ -193,64 +336,185 @@ inline uint8_t xran_get_seqid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t print_err("Invalid CC ID - %d", cc_id); return (0); } - if(ant_id >= XRAN_MAX_ANTENNA_NR) { + if(ant_id >= XRAN_MAX_ANTENNA_NR * 2) { print_err("Invalid antenna ID - %d", ant_id); return (0); } return(xran_cp_seq_id_num[cc_id][dir][ant_id]++); } +static inline uint8_t xran_get_updl_seqid(void *pHandle, uint8_t cc_id, uint8_t ant_id) +{ + if(cc_id >= XRAN_MAX_CELLS_PER_PORT) { + print_err("Invalid CC ID - %d", cc_id); + return (0); + } + if(ant_id >= XRAN_MAX_ANTENNA_NR) { + print_err("Invalid antenna ID - %d", ant_id); + return (0); + } -inline int xran_update_seqid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id, uint8_t seq_id) + /* Only U-Plane DL needs to get sequence ID in O-DU */ + return(xran_updl_seq_id_num[cc_id][ant_id]++); +} +static inline uint8_t *xran_get_updl_seqid_addr(void *pHandle, uint8_t cc_id, uint8_t ant_id) { - return (0); + if(cc_id >= XRAN_MAX_CELLS_PER_PORT) { + print_err("Invalid CC ID - %d", cc_id); + return (0); + } + if(ant_id >= XRAN_MAX_ANTENNA_NR) { + print_err("Invalid antenna ID - %d", ant_id); + return (0); + } + + /* Only U-Plane DL needs to get sequence ID in O-DU */ + return(&xran_updl_seq_id_num[cc_id][ant_id]); +} +static inline int8_t xran_check_upul_seqid(void *pHandle, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id, uint8_t seq_id) +{ + + if(cc_id >= XRAN_MAX_CELLS_PER_PORT) { + print_err("Invalid CC ID - %d", cc_id); + return (-1); + } + + if(ant_id >= XRAN_MAX_ANTENNA_NR * 2) { + print_err("Invalid antenna ID - %d", ant_id); + return (-1); + } + + /* O-DU needs to check the sequence ID of U-Plane UL from O-RU */ + xran_upul_seq_id_num[cc_id][ant_id]++; + if(xran_upul_seq_id_num[cc_id][ant_id] == seq_id) { /* expected sequence */ + return (XRAN_STATUS_SUCCESS); + } else { + print_err("expected seqid %u received %u, slot %u, ant %u cc %u", xran_upul_seq_id_num[cc_id][ant_id], seq_id, slot_id, ant_id, cc_id); + xran_upul_seq_id_num[cc_id][ant_id] = seq_id; // for next + return (-1); + } } ////////////////////////////////////////// // For RU emulation -static struct xran_section_gen_info cpSections[255]; +static inline uint8_t xran_get_upul_seqid(void *pHandle, uint8_t cc_id, uint8_t ant_id) +{ + if(cc_id >= XRAN_MAX_CELLS_PER_PORT) { + print_err("Invalid CC ID - %d", cc_id); + return (0); + } + if(ant_id >= XRAN_MAX_ANTENNA_NR * 2) { + print_err("Invalid antenna ID - %d", ant_id); + return (0); + } + + return(xran_upul_seq_id_num[cc_id][ant_id]++); +} +static inline uint8_t *xran_get_upul_seqid_addr(void *pHandle, uint8_t cc_id, uint8_t ant_id) +{ + if(cc_id >= XRAN_MAX_CELLS_PER_PORT) { + print_err("Invalid CC ID - %d", cc_id); + return (0); + } + if(ant_id >= XRAN_MAX_ANTENNA_NR * 2) { + print_err("Invalid antenna ID - %d", ant_id); + return (0); + } + + return(&xran_upul_seq_id_num[cc_id][ant_id]); +} +static inline int8_t xran_check_cp_seqid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t seq_id) +{ + if(dir >= XRAN_DIR_MAX) { + print_err("Invalid direction - %d", dir); + return (-1); + } + if(cc_id >= XRAN_MAX_CELLS_PER_PORT) { + print_err("Invalid CC ID - %d", cc_id); + return (-1); + } + if(ant_id >= XRAN_MAX_ANTENNA_NR * 2) { + print_err("Invalid antenna ID - %d", ant_id); + return (-1); + } + + xran_cp_seq_id_num[cc_id][dir][ant_id]++; + if(xran_cp_seq_id_num[cc_id][dir][ant_id] == seq_id) { /* expected sequence */ + return (0); + } + else { + xran_cp_seq_id_num[cc_id][dir][ant_id] = seq_id; + return (-1); + } +} +static inline int8_t xran_check_updl_seqid(void *pHandle, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id, uint8_t seq_id) +{ + if(cc_id >= XRAN_MAX_CELLS_PER_PORT) { + print_err("Invalid CC ID - %d", cc_id); + return (-1); + } + + if(ant_id >= XRAN_MAX_ANTENNA_NR) { + print_err("Invalid antenna ID - %d", ant_id); + return (-1); + } + + /* O-RU needs to check the sequence ID of U-Plane DL from O-DU */ + xran_updl_seq_id_num[cc_id][ant_id]++; + if(xran_updl_seq_id_num[cc_id][ant_id] == seq_id) { + /* expected sequence */ + return (0); + } else { + xran_updl_seq_id_num[cc_id][ant_id] = seq_id; + return (-1); + } +} + + +static struct xran_section_gen_info cpSections[XRAN_MAX_NUM_SECTIONS]; static struct xran_cp_gen_params cpInfo; int process_cplane(struct rte_mbuf *pkt) { - int xran_parse_cp_pkt(struct rte_mbuf *mbuf, struct xran_cp_gen_params *result); + struct xran_recv_packet_info recv; cpInfo.sections = cpSections; - xran_parse_cp_pkt(pkt, &cpInfo); + xran_parse_cp_pkt(pkt, &cpInfo, &recv); - return (0); + return (MBUF_FREE); } ////////////////////////////////////////// void sym_ota_cb(struct rte_timer *tim, void *arg) { - uint8_t offset = 0; - struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx(); + struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx(); struct xran_timer_ctx *pTCtx = (struct xran_timer_ctx *)arg; long t1 = MLogTick(); + static int32_t ctx = 0; if(XranGetSymNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT) == 0){ tti_ota_cb(NULL, arg); } - if(XranGetSymNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT) == 1){ - if(p_xran_lib_ctx->phy_tti_cb_done == 0){ - uint64_t t3 = MLogTick(); + if(XranGetSymNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT) == 3){ + if(p_xran_dev_ctx->phy_tti_cb_done == 0){ /* rearm timer to deliver TTI event to PHY */ - p_xran_lib_ctx->phy_tti_cb_done = 0; - xran_timer_arm_ex(&tti_to_phy_timer[xran_lib_ota_tti % 10], tti_to_phy_cb, (void*)pTCtx, p_xran_lib_ctx->xran_init_cfg.io_cfg.pkt_proc_core); - MLogTask(PID_TIME_ARM_TIMER, t3, MLogTick()); + p_xran_dev_ctx->phy_tti_cb_done = 0; + xran_timer_arm_ex(&tti_to_phy_timer[xran_lib_ota_tti % 10], tti_to_phy_cb, (void*)pTCtx, p_xran_dev_ctx->fh_init.io_cfg.timing_core); } } xran_process_tx_sym(timer_ctx); /* check if there is call back to do something else on this symbol */ - if(p_xran_lib_ctx->pSymCallback[0][xran_lib_ota_sym]) - p_xran_lib_ctx->pSymCallback[0][xran_lib_ota_sym](&tx_cp_dl_timer, p_xran_lib_ctx->pSymCallbackTag[0][xran_lib_ota_sym]); + if(p_xran_dev_ctx->pSymCallback[0][xran_lib_ota_sym]){ + p_xran_dev_ctx->pSymCallback[0][xran_lib_ota_sym](&dpdk_timer[ctx], p_xran_dev_ctx->pSymCallbackTag[0][xran_lib_ota_sym]); + ctx = DpdkTiemerIncrementCtx(ctx); + } xran_lib_ota_sym++; if(xran_lib_ota_sym >= N_SYM_PER_SLOT){ xran_lib_ota_sym=0; } + MLogTask(PID_SYM_OTA_CB, t1, MLogTick()); } @@ -267,13 +531,13 @@ void tti_ota_cb(struct rte_timer *tim, void *arg) uint64_t t3 = 0; uint32_t reg_tti = 0; struct xran_timer_ctx *pTCtx = (struct xran_timer_ctx *)arg; - struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx(); + struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx(); MLogTask(PID_TTI_TIMER, t1, MLogTick()); /* To match TTbox */ if(xran_lib_ota_tti == 0) - reg_tti = 8000-1; + reg_tti = xran_fs_get_max_slot() - 1; else reg_tti = xran_lib_ota_tti -1; MLogIncrementCounter(); @@ -298,38 +562,33 @@ void tti_ota_cb(struct rte_timer *tim, void *arg) mlogVar[mlogVarCnt++] = 0; MLogAddVariables(mlogVarCnt, mlogVar, MLogTick()); - if(p_xran_lib_ctx->xran_init_cfg.io_cfg.id == ID_LLS_CU) + if(p_xran_dev_ctx->fh_init.io_cfg.id == ID_LLS_CU) next_tti = xran_lib_ota_tti + 1; else next_tti = xran_lib_ota_tti; - if(next_tti>= SLOTNUM_PER_SUBFRAME*1000){ + if(next_tti>= xran_fs_get_max_slot()){ print_dbg("[%d]SFN %d sf %d slot %d\n",next_tti, frame_id, subframe_id, slot_id); next_tti=0; } - /* [0 - 7] */ + slot_id = XranGetSlotNum(next_tti, SLOTNUM_PER_SUBFRAME); - /* sf [0 - 9] */ subframe_id = XranGetSubFrameNum(next_tti,SLOTNUM_PER_SUBFRAME, SUBFRAMES_PER_SYSTEMFRAME); - /* frame [0 - 99] for now */ frame_id = XranGetFrameNum(next_tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME); print_dbg("[%d]SFN %d sf %d slot %d\n",next_tti, frame_id, subframe_id, slot_id); - if(p_xran_lib_ctx->xran_init_cfg.io_cfg.id == ID_LLS_CU){ + if(p_xran_dev_ctx->fh_init.io_cfg.id == ID_LLS_CU){ pTCtx[(xran_lib_ota_tti & 1)].tti_to_process = next_tti; } else { pTCtx[(xran_lib_ota_tti & 1)].tti_to_process = pTCtx[(xran_lib_ota_tti & 1)^1].tti_to_process; } - t3 = MLogTick(); - p_xran_lib_ctx->phy_tti_cb_done = 0; - xran_timer_arm_ex(&tti_to_phy_timer[xran_lib_ota_tti % 10], tti_to_phy_cb, (void*)pTCtx, p_xran_lib_ctx->xran_init_cfg.io_cfg.pkt_proc_core); - MLogTask(PID_TIME_ARM_TIMER, t3, MLogTick()); + p_xran_dev_ctx->phy_tti_cb_done = 0; + xran_timer_arm_ex(&tti_to_phy_timer[xran_lib_ota_tti % 10], tti_to_phy_cb, (void*)pTCtx, p_xran_dev_ctx->fh_init.io_cfg.timing_core); xran_lib_ota_tti++; - /* within 1 sec we have 8000 TTIs as 1000ms/0.125ms where TTI is 125us*/ - if(xran_lib_ota_tti >= SLOTNUM_PER_SUBFRAME*1000){ + if(xran_lib_ota_tti >= xran_fs_get_max_slot()){ print_dbg("[%d]SFN %d sf %d slot %d\n",xran_lib_ota_tti, frame_id, subframe_id, slot_id); xran_lib_ota_tti=0; } @@ -338,87 +597,309 @@ void tti_ota_cb(struct rte_timer *tim, void *arg) void xran_timer_arm(struct rte_timer *tim, void* arg) { - struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx(); + struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx(); + uint64_t t3 = MLogTick(); + if (xran_if_current_state == XRAN_RUNNING){ rte_timer_cb_t fct = (rte_timer_cb_t)arg; - rte_timer_reset_sync(tim, 0, SINGLE, p_xran_lib_ctx->xran_init_cfg.io_cfg.pkt_proc_core, fct, timer_ctx); + rte_timer_init(tim); + rte_timer_reset_sync(tim, 0, SINGLE, p_xran_dev_ctx->fh_init.io_cfg.timing_core, fct, &timer_ctx[0]); } + MLogTask(PID_TIME_ARM_TIMER, t3, MLogTick()); } void xran_timer_arm_ex(struct rte_timer *tim, void* CbFct, void *CbArg, unsigned tim_lcore) { - struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx(); + struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx(); + uint64_t t3 = MLogTick(); + if (xran_if_current_state == XRAN_RUNNING){ rte_timer_cb_t fct = (rte_timer_cb_t)CbFct; rte_timer_init(tim); rte_timer_reset_sync(tim, 0, SINGLE, tim_lcore, fct, CbArg); } + MLogTask(PID_TIME_ARM_TIMER, t3, MLogTick()); } +int xran_cp_create_and_send_section(void *pHandle, uint8_t ru_port_id, int dir, int tti, int cc_id, + struct xran_prb_map *prbMapElem) +{ + struct xran_cp_gen_params params; + struct xran_section_gen_info sect_geninfo[XRAN_MAX_NUM_SECTIONS]; + struct rte_mbuf *mbuf; + int ret = 0; + uint32_t i; + uint32_t nsection = prbMapElem->nPrbElm; + struct xran_prb_elm *pPrbMapElem = &prbMapElem->prbMap[0]; + struct xran_prb_elm *pPrbMapElemPrev; + uint32_t slot_id = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME); + uint32_t subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME, SUBFRAMES_PER_SYSTEMFRAME); + uint32_t frame_id = XranGetFrameNum(tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME); + uint8_t seq_id = xran_get_cp_seqid(pHandle, XRAN_DIR_DL, cc_id, ru_port_id); + + params.dir = dir; + params.sectionType = XRAN_CP_SECTIONTYPE_1; // Most DL/UL Radio Channels + params.hdr.filterIdx = XRAN_FILTERINDEX_STANDARD; + params.hdr.frameId = frame_id; + params.hdr.subframeId = subframe_id; + params.hdr.slotId = slot_id; + params.hdr.startSymId = pPrbMapElem->nStartSymb; + params.hdr.iqWidth = xran_get_conf_iqwidth(pHandle); + params.hdr.compMeth = pPrbMapElem->compMethod; + + for (i=0; iprbMap[i]; + sect_geninfo[i].info.type = params.sectionType; // for database + sect_geninfo[i].info.startSymId = params.hdr.startSymId; // for database + sect_geninfo[i].info.iqWidth = params.hdr.iqWidth; // for database + sect_geninfo[i].info.compMeth = params.hdr.compMeth; // for database + sect_geninfo[i].info.id = xran_alloc_sectionid(pHandle, dir, cc_id, ru_port_id, slot_id); + sect_geninfo[i].info.rb = XRAN_RBIND_EVERY; + sect_geninfo[i].info.startPrbc = pPrbMapElem->nRBStart; + sect_geninfo[i].info.numPrbc = pPrbMapElem->nRBSize; + sect_geninfo[i].info.numSymbol = pPrbMapElem->numSymb; + sect_geninfo[i].info.reMask = 0xfff; + sect_geninfo[i].info.beamId = pPrbMapElem->nBeamIndex; + if (i==0) + sect_geninfo[i].info.symInc = XRAN_SYMBOLNUMBER_NOTINC; + else + { + pPrbMapElemPrev = &prbMapElem->prbMap[i-1]; + if (pPrbMapElemPrev->nStartSymb == pPrbMapElem->nStartSymb) + { + sect_geninfo[i].info.symInc = XRAN_SYMBOLNUMBER_NOTINC; + if (pPrbMapElemPrev->numSymb != pPrbMapElem->numSymb) + print_err("section info error: previous numSymb %d not equal to current numSymb %d\n", pPrbMapElemPrev->numSymb, pPrbMapElem->numSymb); + } + else + { + sect_geninfo[i].info.symInc = XRAN_SYMBOLNUMBER_INC; + if (pPrbMapElem->nStartSymb != (pPrbMapElemPrev->nStartSymb + pPrbMapElemPrev->numSymb)) + print_err("section info error: current startSym %d not equal to previous endSymb %d\n", pPrbMapElem->nStartSymb, pPrbMapElemPrev->nStartSymb + pPrbMapElemPrev->numSymb); + } + } + + /* extension is not supported */ + sect_geninfo[nsection].info.ef = 0; + sect_geninfo[nsection].exDataSize = 0; + //sect_geninfo[nsection].exData = NULL; + } + params.numSections = nsection; + params.sections = sect_geninfo; + + mbuf = xran_ethdi_mbuf_alloc(); + if(unlikely(mbuf == NULL)) { + print_err("Alloc fail!\n"); + return (-1); + } + + ret = xran_prepare_ctrl_pkt(mbuf, ¶ms, cc_id, ru_port_id, seq_id); + if(ret < 0) { + print_err("Fail to build control plane packet - [%d:%d:%d] dir=%d\n", + frame_id, subframe_id, slot_id, dir); + } else { + /* add in the ethernet header */ + struct ether_hdr *const h = (void *)rte_pktmbuf_prepend(mbuf, sizeof(*h)); + xran_ethdi_mbuf_send_cp(mbuf, ETHER_TYPE_ECPRI); + tx_counter++; + for(i=0; icc_id; + tti = prb_map->tti_id; + dir = prb_map->dir; + + + list_index = -1; + for(sym_id = 0; sym_id < N_SYM_PER_SLOT; sym_id++) { + /* skip symbol, if not matched with given direction */ + int type_sym = xran_fs_get_symbol_type(cc_id, tti, sym_id); + if(type_sym != XRAN_SYMBOL_TYPE_FDD && type_sym != dir) + continue; + + /* retrieve the information of RB allocation */ + prb_map = (struct xran_prb_map *)prbMapElem[sym_id].pData; + if(unlikely(prb_map == NULL)) { + print_err("RB allocation table is NULL! (tti:%d, cc:%d, sym_id:%d)", tti, cc_id, sym_id); + continue; + } + + /* creating 2D mapping */ + for(i=0; i < prb_map->nPrbElm; i++) { + if(list_index < 0) { /* create first entry */ + list_index = 0; + rbMapList[list_index].grp_id = 0; + rbMapList[list_index].sym_start = sym_id; // prb_map->sym_id + rbMapList[list_index].sym_num = 1; + rbMapList[list_index].rb_start = prb_map->prbMap[i].nRBStart; + rbMapList[list_index].rb_num = prb_map->prbMap[i].nRBSize; + rbMapList[list_index].beam_id = prb_map->prbMap[i].nBeamIndex; + rbMapList[list_index].comp_meth = prb_map->prbMap[i].compMethod; + } + else { + /* find consecutive allocation from list */ + for(j=0; jprbMap[i].nRBStart != rbMapList[j].rb_start + || prb_map->prbMap[i].nRBSize != rbMapList[j].rb_num + || prb_map->prbMap[i].nBeamIndex != rbMapList[j].beam_id + || prb_map->prbMap[i].compMethod != rbMapList[j].comp_meth + || sym_id != (rbMapList[j].sym_start+rbMapList[j].sym_num)) { + /* move to next */ + continue; + } + else { + /* consecutive allocation has been found */ + rbMapList[j].sym_num++; + break; + } + } + + if(j == list_index+1) { /* different allocation, create new entry */ + list_index++; + rbMapList[list_index].grp_id = 0; + rbMapList[list_index].sym_start = sym_id; // prb_map->sym_id + rbMapList[list_index].sym_num = 1; + rbMapList[list_index].rb_start = prb_map->prbMap[i].nRBStart; + rbMapList[list_index].rb_num = prb_map->prbMap[i].nRBSize; + rbMapList[list_index].beam_id = prb_map->prbMap[i].nBeamIndex; + rbMapList[list_index].comp_meth = prb_map->prbMap[i].compMethod; + } + } + } /* for(i=0; i < prb_map->nPrbElm; i++) */ + } /* for(sym_id = 0; sym_id < N_SYM_PER_SLOT; sym_id++) */ + + list_index++; + +#if 0 + for(i=0; ienableCP) { + if(p_xran_dev_ctx->enableCP) { tti = pTCtx[(xran_lib_ota_tti & 1) ^ 1].tti_to_process; + buf_id = tti % XRAN_N_FE_BUF_LEN; slot_id = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME); subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME, SUBFRAMES_PER_SYSTEMFRAME); frame_id = XranGetFrameNum(tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME); + ctx_id = XranGetSlotNum(tti, SLOTS_PER_SYSTEMFRAME) % XRAN_MAX_SECTIONDB_CTX; print_dbg("[%d]SFN %d sf %d slot %d\n", tti, frame_id, subframe_id, slot_id); for(ant_id = 0; ant_id < num_eAxc; ++ant_id) { for(cc_id = 0; cc_id < num_CCPorts; cc_id++ ) { - // start new section information list - xran_cp_reset_section_info(pHandle, XRAN_DIR_DL, cc_id, ant_id); - beam_id = xran_get_beamid(pHandle, XRAN_DIR_DL, cc_id, ant_id, slot_id); + /* start new section information list */ + xran_cp_reset_section_info(pHandle, XRAN_DIR_DL, cc_id, ant_id, ctx_id); + + if(xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_DL) == 1) { // 1 when FDD, DL slot or DL symbol is present in SP slot + if (p_xran_dev_ctx->DynamicSectionEna){ + num_list = xran_cp_create_and_send_section(pHandle, ant_id, XRAN_SYMBOL_TYPE_DL, tti, cc_id, + (struct xran_prb_map *)p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[buf_id][cc_id][ant_id].sBufferList.pBuffers->pData); + } + else{ + struct xran_cp_gen_params params; + struct xran_section_gen_info sect_geninfo[8]; + struct rte_mbuf *mbuf = xran_ethdi_mbuf_alloc(); + + /* use symb 0 only with constant RBs for full slot */ + struct xran_prb_map *prb_map = (struct xran_prb_map *)p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[buf_id][cc_id][ant_id].sBufferList.pBuffers->pData; + num_list = 1; + rb_map_list[0].sym_start = 0; + rb_map_list[0].sym_num = 14; + rb_map_list[0].rb_start = prb_map->prbMap[0].nRBStart; + rb_map_list[0].rb_num = prb_map->prbMap[0].nRBSize; + rb_map_list[0].beam_id = prb_map->prbMap[0].nBeamIndex; + rb_map_list[0].comp_meth = prb_map->prbMap[0].compMethod; + + for(i=0; ienableCP) */ - send_cpmsg_dlul(pHandle, XRAN_DIR_DL, - frame_id, subframe_id, slot_id, - 0, N_SYM_PER_SLOT, NUM_OF_PRB_IN_FULL_BAND, - beam_id, cc_id, ant_id, - xran_get_seqid(pHandle, XRAN_DIR_DL, cc_id, ant_id, slot_id)); - } - } - } MLogTask(PID_CP_DL_CB, t1, MLogTick()); } void rx_ul_deadline_half_cb(struct rte_timer *tim, void *arg) { long t1 = MLogTick(); - struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx(); - XranStatusInt32 status; + struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx(); + xran_status_t status; /* half of RX for current TTI as measured against current OTA time */ int32_t rx_tti = (int32_t)XranGetTtiNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT); + int32_t cc_id; - if(p_xran_lib_ctx->xran2phy_mem_ready == 0) + if(p_xran_dev_ctx->xran2phy_mem_ready == 0) return; - if(p_xran_lib_ctx->rx_packet_callback_tracker[rx_tti % XRAN_N_FE_BUF_LEN][0] == 0){ - status = (rx_tti << 16) | 0; /* base on PHY side implementation first 7 sym of slot */ - if(p_xran_lib_ctx->pCallback[0]) - p_xran_lib_ctx->pCallback[0](p_xran_lib_ctx->pCallbackTag[0], status); - } else { - p_xran_lib_ctx->rx_packet_callback_tracker[rx_tti % XRAN_N_FE_BUF_LEN][0] = 0; + for(cc_id = 0; cc_id < xran_get_num_cc(p_xran_dev_ctx); cc_id++) { + if(p_xran_dev_ctx->rx_packet_callback_tracker[rx_tti % XRAN_N_FE_BUF_LEN][cc_id] == 0){ + status = (rx_tti << 16) | 0; /* base on PHY side implementation first 7 sym of slot */ + if(p_xran_dev_ctx->pCallback[cc_id]) + p_xran_dev_ctx->pCallback[cc_id](p_xran_dev_ctx->pCallbackTag[cc_id], status); + } else { + p_xran_dev_ctx->rx_packet_callback_tracker[rx_tti % XRAN_N_FE_BUF_LEN][cc_id] = 0; + } } MLogTask(PID_UP_UL_HALF_DEAD_LINE_CB, t1, MLogTick()); } @@ -426,24 +907,28 @@ void rx_ul_deadline_half_cb(struct rte_timer *tim, void *arg) void rx_ul_deadline_full_cb(struct rte_timer *tim, void *arg) { long t1 = MLogTick(); - struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx(); - XranStatusInt32 status; + struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx(); + xran_status_t status = 0; int32_t rx_tti = (int32_t)XranGetTtiNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT); + int32_t cc_id = 0; - if(rx_tti >= 8000-1) - rx_tti = 0; + if(rx_tti == 0) + rx_tti = (xran_fs_get_max_slot()-1); else rx_tti -= 1; /* end of RX for prev TTI as measured against current OTA time */ - if(p_xran_lib_ctx->xran2phy_mem_ready == 0) + if(p_xran_dev_ctx->xran2phy_mem_ready == 0) return; - if(p_xran_lib_ctx->rx_packet_callback_tracker[rx_tti % XRAN_N_FE_BUF_LEN][0] == 0){ + /* U-Plane */ + for(cc_id = 0; cc_id < xran_get_num_cc(p_xran_dev_ctx); cc_id++) { status = (rx_tti << 16) | 7; /* last 7 sym means full slot of Symb */ - if(p_xran_lib_ctx->pCallback[0]) - p_xran_lib_ctx->pCallback[0](p_xran_lib_ctx->pCallbackTag[0], status); - } else { - p_xran_lib_ctx->rx_packet_callback_tracker[rx_tti % XRAN_N_FE_BUF_LEN][0] = 0; + if(p_xran_dev_ctx->pCallback[cc_id]) + p_xran_dev_ctx->pCallback[cc_id](p_xran_dev_ctx->pCallbackTag[cc_id], status); + + if(p_xran_dev_ctx->pPrachCallback[cc_id]) + p_xran_dev_ctx->pPrachCallback[cc_id](p_xran_dev_ctx->pPrachCallbackTag[cc_id], status); + } MLogTask(PID_UP_UL_FULL_DEAD_LINE_CB, t1, MLogTick()); @@ -453,69 +938,105 @@ void rx_ul_deadline_full_cb(struct rte_timer *tim, void *arg) void tx_cp_ul_cb(struct rte_timer *tim, void *arg) { long t1 = MLogTick(); - int sym, tti; - uint32_t frame_id = 0; - uint32_t subframe_id = 0; - uint32_t slot_id = 0; - + int tti, buf_id; + int i, ret; + uint32_t slot_id, subframe_id, frame_id; int32_t cc_id; int ant_id, prach_port_id; uint16_t beam_id; uint8_t num_eAxc, num_CCPorts; + uint8_t ctx_id; void *pHandle; + int num_list; + struct xran_cp_rbmap_list rb_map_list[XRAN_MAX_PRBS*N_SYM_PER_SLOT]; /* array size can be reduced */ - struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx(); - xRANPrachCPConfigStruct *pPrachCPConfig = &(p_xran_lib_ctx->PrachCPConfig); + struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx(); + xRANPrachCPConfigStruct *pPrachCPConfig = &(p_xran_dev_ctx->PrachCPConfig); struct xran_timer_ctx *pTCtx = (struct xran_timer_ctx *)arg; pHandle = NULL; // TODO: temp implemantation num_eAxc = xran_get_num_eAxc(pHandle); num_CCPorts = xran_get_num_cc(pHandle); + tti = pTCtx[(xran_lib_ota_tti & 1) ^ 1].tti_to_process; + buf_id = tti % XRAN_N_FE_BUF_LEN; + slot_id = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME); + subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME, SUBFRAMES_PER_SYSTEMFRAME); + frame_id = XranGetFrameNum(tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME); + ctx_id = XranGetSlotNum(tti, SLOTS_PER_SYSTEMFRAME) % XRAN_MAX_SECTIONDB_CTX; - if (p_xran_lib_ctx->enableCP){ - tti = pTCtx[(xran_lib_ota_tti & 1) ^ 1].tti_to_process; - slot_id = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME); - subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME, SUBFRAMES_PER_SYSTEMFRAME); - frame_id = XranGetFrameNum(tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME); - print_dbg("[%d]SFN %d sf %d slot %d\n", tti, frame_id, subframe_id, slot_id); + if(p_xran_dev_ctx->enableCP) { + print_dbg("[%d]SFN %d sf %d slot %d\n", tti, frame_id, subframe_id, slot_id); for(ant_id = 0; ant_id < num_eAxc; ++ant_id) { - for(cc_id = 0; cc_id < num_CCPorts; cc_id++ ) { - // start new section information list - xran_cp_reset_section_info(pHandle, XRAN_DIR_UL, cc_id, ant_id); + for(cc_id = 0; cc_id < num_CCPorts; cc_id++) { + if(xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_UL) == 1 || + xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_SP) == 1 ){ + /* start new section information list */ + xran_cp_reset_section_info(pHandle, XRAN_DIR_UL, cc_id, ant_id, ctx_id); + if (p_xran_dev_ctx->DynamicSectionEna){ + /* create a map of RB allocation to generate proper C-Plane */ + num_list = xran_cp_create_and_send_section(pHandle, ant_id, XRAN_SYMBOL_TYPE_UL, tti, cc_id, + (struct xran_prb_map *)p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[buf_id][cc_id][ant_id].sBufferList.pBuffers->pData); + } + else{ + struct xran_cp_gen_params params; + struct xran_section_gen_info sect_geninfo[8]; + struct rte_mbuf *mbuf = xran_ethdi_mbuf_alloc(); + /* use symb 0 only with constant RBs for full slot */ + struct xran_prb_map *prb_map = (struct xran_prb_map *)p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[buf_id][cc_id][ant_id].sBufferList.pBuffers->pData; + num_list = 1; + rb_map_list[0].sym_start = 0; + rb_map_list[0].sym_num = 14; + rb_map_list[0].rb_start = prb_map->prbMap[0].nRBStart; + rb_map_list[0].rb_num = prb_map->prbMap[0].nRBSize; + rb_map_list[0].beam_id = prb_map->prbMap[0].nBeamIndex; + rb_map_list[0].comp_meth = prb_map->prbMap[0].compMethod; + + for(i=0; ienableCP) */ - if ((frame_id % pPrachCPConfig->x == pPrachCPConfig->y[0]) && (pPrachCPConfig->isPRACHslot[slot_id]==1)) //is prach slot - { - for(ant_id = 0; ant_id < num_eAxc; ant_id++) { + if(p_xran_dev_ctx->enablePrach) { + uint32_t isPRACHslot = xran_isPRACHSlot(subframe_id, slot_id); + if((frame_id % pPrachCPConfig->x == pPrachCPConfig->y[0]) && (isPRACHslot==1)) { //is prach slot + for(ant_id = 0; ant_id < num_eAxc; ++ant_id) { for(cc_id = 0; cc_id < num_CCPorts; cc_id++) { -#if !defined(PRACH_USES_SHARED_PORT) + struct xran_cp_gen_params params; + struct xran_section_gen_info sect_geninfo[8]; + struct rte_mbuf *mbuf = xran_ethdi_mbuf_alloc(); prach_port_id = ant_id + num_eAxc; - // start new section information list - xran_cp_reset_section_info(pHandle, XRAN_DIR_UL, cc_id, prach_port_id); -#else - prach_port_id = ant_id; -#endif - beam_id = xran_get_beamid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id, slot_id); - send_cpmsg_prach(pHandle, - frame_id, subframe_id, slot_id, - beam_id, cc_id, prach_port_id, - xran_get_seqid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id, slot_id)); + /* start new section information list */ + xran_cp_reset_section_info(pHandle, XRAN_DIR_UL, cc_id, prach_port_id, ctx_id); + + beam_id = xran_get_beamid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id, slot_id); /* TODO: */ + ret = generate_cpmsg_prach(pHandle, ¶ms, sect_geninfo, mbuf, p_xran_dev_ctx, + frame_id, subframe_id, slot_id, + beam_id, cc_id, prach_port_id, + xran_get_cp_seqid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id)); + if (ret == XRAN_STATUS_SUCCESS) + send_cpmsg(pHandle, mbuf, ¶ms, sect_geninfo, + cc_id, prach_port_id, xran_get_cp_seqid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id)); } } } - } + MLogTask(PID_CP_UL_CB, t1, MLogTick()); } @@ -529,22 +1050,22 @@ void ul_up_full_slot_cb(struct rte_timer *tim, void *arg) void tti_to_phy_cb(struct rte_timer *tim, void *arg) { long t1 = MLogTick(); - struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx(); + struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx(); static int first_call = 0; - p_xran_lib_ctx->phy_tti_cb_done = 1; /* DPDK called CB */ + p_xran_dev_ctx->phy_tti_cb_done = 1; /* DPDK called CB */ if (first_call){ - if(p_xran_lib_ctx->ttiCb[XRAN_CB_TTI]){ - if(p_xran_lib_ctx->SkipTti[XRAN_CB_TTI] <= 0){ - p_xran_lib_ctx->ttiCb[XRAN_CB_TTI](p_xran_lib_ctx->TtiCbParam[XRAN_CB_TTI]); + if(p_xran_dev_ctx->ttiCb[XRAN_CB_TTI]){ + if(p_xran_dev_ctx->SkipTti[XRAN_CB_TTI] <= 0){ + p_xran_dev_ctx->ttiCb[XRAN_CB_TTI](p_xran_dev_ctx->TtiCbParam[XRAN_CB_TTI]); }else{ - p_xran_lib_ctx->SkipTti[XRAN_CB_TTI]--; + p_xran_dev_ctx->SkipTti[XRAN_CB_TTI]--; } } } else { - if(p_xran_lib_ctx->ttiCb[XRAN_CB_TTI]){ + if(p_xran_dev_ctx->ttiCb[XRAN_CB_TTI]){ int32_t tti = (int32_t)XranGetTtiNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT); - if(tti == 8000-1) + if(tti == xran_fs_get_max_slot()-1) first_call = 1; } } @@ -570,7 +1091,7 @@ int xran_timing_source_thread(void *args) uint32_t sym_up_ul; int32_t sym_up; struct sched_param sched_param; - struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx(); + struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx(); /* ToS = Top of Second start +- 1.5us */ struct timespec ts; @@ -583,7 +1104,7 @@ int xran_timing_source_thread(void *args) sched_param.sched_priority = 98; CPU_ZERO(&cpuset); - CPU_SET(p_xran_lib_ctx->xran_init_cfg.io_cfg.timing_core, &cpuset); + CPU_SET(p_xran_dev_ctx->fh_init.io_cfg.timing_core, &cpuset); if (result1 = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset)) { printf("pthread_setaffinity_np failed: coreId = 2, result1 = %d\n",result1); @@ -593,7 +1114,7 @@ int xran_timing_source_thread(void *args) printf("priority is not changed: coreId = 2, result1 = %d\n",result1); } - if (p_xran_lib_ctx->xran_init_cfg.io_cfg.id == APP_LLS_CU) { + if (p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) { do { timespec_get(&ts, TIME_UTC); }while (ts.tv_nsec >1500); @@ -603,18 +1124,18 @@ int xran_timing_source_thread(void *args) printf("lls-CU: thread_run start time: %s.%09ld UTC [%ld]\n", buff, ts.tv_nsec, interval_us); } - delay_cp_dl = p_xran_lib_ctx->xran_init_cfg.ttiPeriod - p_xran_lib_ctx->xran_init_cfg.T1a_max_cp_dl; - delay_cp_ul = p_xran_lib_ctx->xran_init_cfg.ttiPeriod - p_xran_lib_ctx->xran_init_cfg.T1a_max_cp_ul; - delay_up = p_xran_lib_ctx->xran_init_cfg.T1a_max_up; - delay_up_ul = p_xran_lib_ctx->xran_init_cfg.Ta4_max; + delay_cp_dl = interval_us - p_xran_dev_ctx->fh_init.T1a_max_cp_dl; + delay_cp_ul = interval_us - p_xran_dev_ctx->fh_init.T1a_max_cp_ul; + delay_up = p_xran_dev_ctx->fh_init.T1a_max_up; + delay_up_ul = p_xran_dev_ctx->fh_init.Ta4_max; delay_cp2up = delay_up-delay_cp_dl; sym_cp_dl = delay_cp_dl*1000/(interval_us*1000/N_SYM_PER_SLOT)+1; sym_cp_ul = delay_cp_ul*1000/(interval_us*1000/N_SYM_PER_SLOT)+1; sym_up_ul = delay_up_ul*1000/(interval_us*1000/N_SYM_PER_SLOT); - p_xran_lib_ctx->sym_up = sym_up = -(delay_up*1000/(interval_us*1000/N_SYM_PER_SLOT)+1); - p_xran_lib_ctx->sym_up_ul = sym_up_ul = (delay_up_ul*1000/(interval_us*1000/N_SYM_PER_SLOT)+1); + p_xran_dev_ctx->sym_up = sym_up = -(delay_up*1000/(interval_us*1000/N_SYM_PER_SLOT)+1); + p_xran_dev_ctx->sym_up_ul = sym_up_ul = (delay_up_ul*1000/(interval_us*1000/N_SYM_PER_SLOT)+1); printf("Start C-plane DL %d us after TTI [trigger on sym %d]\n", delay_cp_dl, sym_cp_dl); printf("Start C-plane UL %d us after TTI [trigger on sym %d]\n", delay_cp_ul, sym_cp_ul); @@ -624,24 +1145,24 @@ int xran_timing_source_thread(void *args) printf("C-plane to U-plane delay %d us after TTI\n", delay_cp2up); printf("Start Sym timer %ld ns\n", TX_TIMER_INTERVAL/N_SYM_PER_SLOT); - p_xran_lib_ctx->pSymCallback[0][sym_cp_dl] = xran_timer_arm; - p_xran_lib_ctx->pSymCallbackTag[0][sym_cp_dl] = tx_cp_dl_cb; + p_xran_dev_ctx->pSymCallback[0][sym_cp_dl] = xran_timer_arm; + p_xran_dev_ctx->pSymCallbackTag[0][sym_cp_dl] = tx_cp_dl_cb; - p_xran_lib_ctx->pSymCallback[0][sym_cp_ul] = xran_timer_arm; - p_xran_lib_ctx->pSymCallbackTag[0][sym_cp_ul] = tx_cp_ul_cb; + p_xran_dev_ctx->pSymCallback[0][sym_cp_ul] = xran_timer_arm; + p_xran_dev_ctx->pSymCallbackTag[0][sym_cp_ul] = tx_cp_ul_cb; /* Full slot UL OTA + delay_up_ul */ - p_xran_lib_ctx->pSymCallback[0][sym_up_ul] = xran_timer_arm; - p_xran_lib_ctx->pSymCallbackTag[0][sym_up_ul] = rx_ul_deadline_full_cb; + p_xran_dev_ctx->pSymCallback[0][sym_up_ul] = xran_timer_arm; + p_xran_dev_ctx->pSymCallbackTag[0][sym_up_ul] = rx_ul_deadline_full_cb; /* Half slot UL OTA + delay_up_ul*/ - p_xran_lib_ctx->pSymCallback[0][sym_up_ul + N_SYM_PER_SLOT/2] = xran_timer_arm; - p_xran_lib_ctx->pSymCallbackTag[0][sym_up_ul + N_SYM_PER_SLOT/2] = rx_ul_deadline_half_cb; + p_xran_dev_ctx->pSymCallback[0][sym_up_ul + N_SYM_PER_SLOT/2] = xran_timer_arm; + p_xran_dev_ctx->pSymCallbackTag[0][sym_up_ul + N_SYM_PER_SLOT/2] = rx_ul_deadline_half_cb; - } else { // APP_RU + } else { // APP_O_RU /* calcualte when to send UL U-plane */ - delay_up = p_xran_lib_ctx->xran_init_cfg.Ta3_min; - p_xran_lib_ctx->sym_up = sym_up = delay_up*1000/(interval_us*1000/N_SYM_PER_SLOT)+1; + delay_up = p_xran_dev_ctx->fh_init.Ta3_min; + p_xran_dev_ctx->sym_up = sym_up = delay_up*1000/(interval_us*1000/N_SYM_PER_SLOT)+1; printf("Start UL U-plane %d us after OTA [offset in sym %d]\n", delay_up, sym_up); do { timespec_get(&ts, TIME_UTC); @@ -653,6 +1174,7 @@ int xran_timing_source_thread(void *args) } } + printf("interval_us %ld\n", interval_us); do { timespec_get(&ts, TIME_UTC); }while (ts.tv_nsec == 0); @@ -661,9 +1183,11 @@ int xran_timing_source_thread(void *args) delta = poll_next_tick(interval_us*1000L/N_SYM_PER_SLOT); if (XRAN_STOPPED == xran_if_current_state) break; - sym_ota_cb(&sym_timer, timer_ctx); + + if (likely(XRAN_RUNNING == xran_if_current_state)) + sym_ota_cb(&sym_timer, timer_ctx); } - printf("Closing timing source thread...\n"); + printf("Closing timing source thread...tx counter %lu, rx counter %lu\n", tx_counter, rx_counter); return 0; } @@ -673,45 +1197,45 @@ int handle_ecpri_ethertype(struct rte_mbuf *pkt, uint64_t rx_time) { const struct xran_ecpri_hdr *ecpri_hdr; unsigned long t1; + int32_t ret = MBUF_FREE; if (rte_pktmbuf_data_len(pkt) < sizeof(struct xran_ecpri_hdr)) { - wlog("Packet too short - %d bytes", rte_pktmbuf_data_len(pkt)); + print_err("Packet too short - %d bytes", rte_pktmbuf_data_len(pkt)); return 0; } /* check eCPRI header. */ ecpri_hdr = rte_pktmbuf_mtod(pkt, struct xran_ecpri_hdr *); - if(ecpri_hdr == NULL) + if(ecpri_hdr == NULL){ + print_err("ecpri_hdr error\n"); return MBUF_FREE; + } - switch(ecpri_hdr->ecpri_mesg_type) { + switch(ecpri_hdr->cmnhdr.ecpri_mesg_type) { case ECPRI_IQ_DATA: - t1 = MLogTick(); - process_mbuf(pkt); - MLogTask(PID_PROCESS_UP_PKT, t1, MLogTick()); + // t1 = MLogTick(); + ret = process_mbuf(pkt); + // MLogTask(PID_PROCESS_UP_PKT, t1, MLogTick()); break; // For RU emulation case ECPRI_RT_CONTROL_DATA: t1 = MLogTick(); - if(xran_lib_get_ctx()->xran_init_cfg.io_cfg.id == APP_RU) { - process_cplane(pkt); + if(xran_dev_get_ctx()->fh_init.io_cfg.id == O_RU) { + ret = process_cplane(pkt); } else { - print_err("LLS-CU recevied CP message!"); + print_err("O-DU recevied C-Plane message!"); } MLogTask(PID_PROCESS_CP_PKT, t1, MLogTick()); break; default: - wlog("Invalid eCPRI message type - %d", ecpri_hdr->ecpri_mesg_type); + print_err("Invalid eCPRI message type - %d", ecpri_hdr->cmnhdr.ecpri_mesg_type); } -#if 0 -//def DEBUG - return MBUF_KEEP; -#else - return MBUF_FREE; -#endif + + return ret; } -int xran_process_rx_sym(void *arg, +int xran_process_prach_sym(void *arg, + struct rte_mbuf *mbuf, void *iq_data_start, uint16_t size, uint8_t CC_ID, @@ -719,37 +1243,48 @@ int xran_process_rx_sym(void *arg, uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id, - uint8_t symb_id) + uint8_t symb_id, + uint16_t num_prbu, + uint16_t start_prbu, + uint16_t sym_inc, + uint16_t rb, + uint16_t sect_id) { char *pos = NULL; - struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx(); - uint32_t tti=0; - XranStatusInt32 status; + struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx(); + uint8_t symb_id_offset; + uint32_t tti = 0; + xran_status_t status; void *pHandle = NULL; + struct rte_mbuf *mb; - if(p_xran_lib_ctx->xran2phy_mem_ready == 0) + uint16_t iq_sample_size_bits = 16; + + if(p_xran_dev_ctx->xran2phy_mem_ready == 0) return 0; tti = frame_id * SLOTS_PER_SYSTEMFRAME + subframe_id * SLOTNUM_PER_SUBFRAME + slot_id; status = tti << 16 | symb_id; - if(tti < 8000 && CC_ID < XRAN_MAX_SECTOR_NR && CC_ID == 0 && Ant_ID < XRAN_MAX_ANTENNA_NR && symb_id < XRAN_NUM_OF_SYMBOL_PER_SLOT){ - pos = (char*) p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pData; + if(tti < xran_fs_get_max_slot() && CC_ID < XRAN_MAX_SECTOR_NR && Ant_ID < XRAN_MAX_ANTENNA_NR && symb_id < XRAN_NUM_OF_SYMBOL_PER_SLOT){ + symb_id_offset = symb_id - p_xran_dev_ctx->prach_start_symbol[CC_ID]; //make the storing of prach packets to start from 0 for easy of processing within PHY + pos = (char*) p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id_offset].pData; if(pos && iq_data_start && size){ -#ifdef XRAN_BYTE_ORDER_SWAP - int idx = 0; - uint16_t *restrict psrc = (uint16_t *)iq_data_start; - uint16_t *restrict pdst = (uint16_t *)pos; - /* network byte (be) order of IQ to CPU byte order (le) */ - for (idx = 0; idx < size/sizeof(int16_t); idx++){ - pdst[idx] = (psrc[idx]>>8) | (psrc[idx]<<8); //rte_be_to_cpu_16(psrc[idx]); + if (p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder == XRAN_CPU_LE_BYTE_ORDER) { + int idx = 0; + uint16_t *psrc = (uint16_t *)iq_data_start; + uint16_t *pdst = (uint16_t *)pos; + /* network byte (be) order of IQ to CPU byte order (le) */ + for (idx = 0; idx < size/sizeof(int16_t); idx++){ + pdst[idx] = (psrc[idx]>>8) | (psrc[idx]<<8); //rte_be_to_cpu_16(psrc[idx]); + } + }else { + mb = p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id_offset].pCtrl; + rte_pktmbuf_free(mb); + p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id_offset].pData = iq_data_start; + p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id_offset].pCtrl = mbuf; } -#else -#error xran spec is network byte order - /* for debug */ - rte_memcpy(pdst, psrc, size); -#endif #ifdef DEBUG_XRAN_BUFFERS if (pos[0] != tti % XRAN_N_FE_BUF_LEN || pos[1] != CC_ID || @@ -764,25 +1299,176 @@ int xran_process_rx_sym(void *arg, } else { print_err("TTI %d(f_%d sf_%d slot_%d) CC %d Ant_ID %d symb_id %d\n",tti, frame_id, subframe_id, slot_id, CC_ID, Ant_ID, symb_id); } - if (symb_id == 7 || symb_id == 13){ - p_xran_lib_ctx->rx_packet_symb_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID][symb_id]++; - if(p_xran_lib_ctx->rx_packet_symb_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID][symb_id] >= xran_get_num_eAxc(pHandle)){ - if(p_xran_lib_ctx->pCallback[0]) - p_xran_lib_ctx->pCallback[0](p_xran_lib_ctx->pCallbackTag[0], status); - p_xran_lib_ctx->rx_packet_callback_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID] = 1; - p_xran_lib_ctx->rx_packet_symb_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID][symb_id] = 0; +/* if (symb_id == p_xran_dev_ctx->prach_last_symbol[CC_ID] ){ + p_xran_dev_ctx->rx_packet_prach_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID][symb_id]++; + if(p_xran_dev_ctx->rx_packet_prach_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID][symb_id] >= xran_get_num_eAxc(pHandle)){ + if(p_xran_dev_ctx->pPrachCallback[0]) + p_xran_dev_ctx->pPrachCallback[0](p_xran_dev_ctx->pPrachCallbackTag[0], status); + p_xran_dev_ctx->rx_packet_prach_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID][symb_id] = 0; } } +*/ return size; } +int32_t xran_pkt_validate(void *arg, + struct rte_mbuf *mbuf, + void *iq_data_start, + uint16_t size, + uint8_t CC_ID, + uint8_t Ant_ID, + uint8_t frame_id, + uint8_t subframe_id, + uint8_t slot_id, + uint8_t symb_id, + struct ecpri_seq_id *seq_id, + uint16_t num_prbu, + uint16_t start_prbu, + uint16_t sym_inc, + uint16_t rb, + uint16_t sect_id) +{ + struct xran_device_ctx * pctx = xran_dev_get_ctx(); + struct xran_common_counters *pCnt = &pctx->fh_counters; + + if(pctx->fh_init.io_cfg.id == O_DU) { + if(xran_check_upul_seqid(NULL, CC_ID, Ant_ID, slot_id, seq_id->seq_id) != XRAN_STATUS_SUCCESS) { + pCnt->Rx_pkt_dupl++; + return (XRAN_STATUS_FAIL); + } + }else if(pctx->fh_init.io_cfg.id == O_RU) { + if(xran_check_updl_seqid(NULL, CC_ID, Ant_ID, slot_id, seq_id->seq_id) != XRAN_STATUS_SUCCESS) { + pCnt->Rx_pkt_dupl++; + return (XRAN_STATUS_FAIL); + } + }else { + print_err("incorrect dev type %d\n", pctx->fh_init.io_cfg.id); + } + + rx_counter++; + + pCnt->Rx_on_time++; + pCnt->Total_msgs_rcvd++; + + return XRAN_STATUS_SUCCESS; +} + +int xran_process_rx_sym(void *arg, + struct rte_mbuf *mbuf, + void *iq_data_start, + uint16_t size, + uint8_t CC_ID, + uint8_t Ant_ID, + uint8_t frame_id, + uint8_t subframe_id, + uint8_t slot_id, + uint8_t symb_id, + uint16_t num_prbu, + uint16_t start_prbu, + uint16_t sym_inc, + uint16_t rb, + uint16_t sect_id, + uint32_t *mb_free) +{ + char *pos = NULL; + struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx(); + uint32_t tti = 0; + xran_status_t status; + void *pHandle = NULL; + struct rte_mbuf *mb = NULL; + + uint16_t iq_sample_size_bits = 16; + + tti = frame_id * SLOTS_PER_SYSTEMFRAME + subframe_id * SLOTNUM_PER_SUBFRAME + slot_id; + + status = tti << 16 | symb_id; + + if(tti < xran_fs_get_max_slot() && CC_ID < XRAN_MAX_SECTOR_NR && Ant_ID < XRAN_MAX_ANTENNA_NR && symb_id < XRAN_NUM_OF_SYMBOL_PER_SLOT){ + pos = (char*) p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pData; + pos += start_prbu * N_SC_PER_PRB*(iq_sample_size_bits/8)*2; + if(pos && iq_data_start && size){ + if (p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder == XRAN_CPU_LE_BYTE_ORDER) { + int idx = 0; + uint16_t *psrc = (uint16_t *)iq_data_start; + uint16_t *pdst = (uint16_t *)pos; + rte_panic("XRAN_CPU_LE_BYTE_ORDER is not supported 0x16%lx\n", (long)mb); + /* network byte (be) order of IQ to CPU byte order (le) */ + for (idx = 0; idx < size/sizeof(int16_t); idx++){ + pdst[idx] = (psrc[idx]>>8) | (psrc[idx]<<8); //rte_be_to_cpu_16(psrc[idx]); + } + } else if (likely(p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder == XRAN_NE_BE_BYTE_ORDER)){ + if (likely (p_xran_dev_ctx->fh_init.mtu >= + p_xran_dev_ctx->fh_cfg.nULRBs * N_SC_PER_PRB*(iq_sample_size_bits/8)*2)) { + /* no fragmentation */ + mb = p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pCtrl; + if(mb){ + rte_pktmbuf_free(mb); + }else{ + print_err("mb==NULL\n"); + } + p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pData = iq_data_start; + p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pCtrl = mbuf; + *mb_free = MBUF_KEEP; + } else { + /* packet can be fragmented copy RBs */ + rte_memcpy(pos, iq_data_start, size); + *mb_free = MBUF_FREE; + } + } +#ifdef DEBUG_XRAN_BUFFERS + if (pos[0] != tti % XRAN_N_FE_BUF_LEN || + pos[1] != CC_ID || + pos[2] != Ant_ID || + pos[3] != symb_id){ + printf("%d %d %d %d\n", pos[0], pos[1], pos[2], pos[3]); + } +#endif + } else { + print_err("pos %p iq_data_start %p size %d\n",pos, iq_data_start, size); + } + } else { + print_err("TTI %d(f_%d sf_%d slot_%d) CC %d Ant_ID %d symb_id %d\n",tti, frame_id, subframe_id, slot_id, CC_ID, Ant_ID, symb_id); + } + + return size; +} + +/* Send burst of packets on an output interface */ +static inline int +xran_send_burst(struct xran_device_ctx *dev, uint16_t n, uint16_t port) +{ + struct rte_mbuf **m_table; + struct rte_mbuf *m; + int32_t i = 0; + int j; + int32_t ret = 0; + + m_table = (struct rte_mbuf **)dev->tx_mbufs[port].m_table; + + for(i = 0; i < n; i++){ + rte_mbuf_sanity_check(m_table[i], 0); + /*rte_pktmbuf_dump(stdout, m_table[i], 256);*/ + tx_counter++; + ret += xran_ethdi_mbuf_send(m_table[i], ETHER_TYPE_ECPRI); + } + + + if (unlikely(ret < n)) { + print_err("ret < n\n"); + } + + return 0; +} + int xran_process_tx_sym(void *arg) { uint32_t tti=0; +#if XRAN_MLOG_VAR uint32_t mlogVar[10]; uint32_t mlogVarCnt = 0; +#endif unsigned long t1 = MLogTick(); void *pHandle = NULL; @@ -798,56 +1484,61 @@ int xran_process_tx_sym(void *arg) uint32_t sym_idx = 0; char *pos = NULL; + void *mb = NULL; int prb_num = 0; + uint16_t iq_sample_size_bits = 16; // TODO: make dynamic per struct xran_section_info *sectinfo; uint32_t next; + uint32_t num_sections; + uint8_t ctx_id; enum xran_pkt_dir direction; - struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx(); + struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx(); struct xran_timer_ctx *pTCtx = (struct xran_timer_ctx *)arg; - - if(p_xran_lib_ctx->xran2phy_mem_ready == 0) + if(p_xran_dev_ctx->xran2phy_mem_ready == 0) return 0; - if(p_xran_lib_ctx->xran_init_cfg.io_cfg.id == APP_LLS_CU) { + if(p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) { direction = XRAN_DIR_DL; /* lls-CU */ - prb_num = NUM_OF_PRB_IN_FULL_BAND; - } - else { + prb_num = p_xran_dev_ctx->fh_cfg.nDLRBs; + } else { direction = XRAN_DIR_UL; /* RU */ - prb_num = NUM_OF_PRB_IN_FULL_BAND; /*TODO: simulation on D-1541 @ 2.10GHz has issue with performace. reduce copy size */ - } + prb_num = p_xran_dev_ctx->fh_cfg.nULRBs; + } /* RU: send symb after OTA time with delay (UL) */ /* lls-CU:send symb in advance of OTA time (DL) */ - sym_idx = XranOffsetSym(p_xran_lib_ctx->sym_up, xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT*SLOTNUM_PER_SUBFRAME*1000); + sym_idx = XranOffsetSym(p_xran_dev_ctx->sym_up, xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT*SLOTNUM_PER_SUBFRAME*1000); tti = XranGetTtiNum(sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT); slot_id = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME); subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME, SUBFRAMES_PER_SYSTEMFRAME); frame_id = XranGetFrameNum(tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME); sym_id = XranGetSymNum(sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT); + ctx_id = XranGetSlotNum(tti, SLOTS_PER_SYSTEMFRAME) % XRAN_MAX_SECTIONDB_CTX; print_dbg("[%d]SFN %d sf %d slot %d\n", tti, frame_id, subframe_id, slot_id); +#if XRAN_MLOG_VAR mlogVar[mlogVarCnt++] = 0xAAAAAAAA; mlogVar[mlogVarCnt++] = xran_lib_ota_sym_idx; mlogVar[mlogVarCnt++] = sym_idx; - mlogVar[mlogVarCnt++] = abs(p_xran_lib_ctx->sym_up); + mlogVar[mlogVarCnt++] = abs(p_xran_dev_ctx->sym_up); mlogVar[mlogVarCnt++] = tti; mlogVar[mlogVarCnt++] = frame_id; mlogVar[mlogVarCnt++] = subframe_id; mlogVar[mlogVarCnt++] = slot_id; mlogVar[mlogVarCnt++] = sym_id; MLogAddVariables(mlogVarCnt, mlogVar, MLogTick()); +#endif if(frame_id > 99) { print_err("OTA %d: TX:[sym_idx %d: TTI %d] fr %d sf %d slot %d sym %d\n",xran_lib_ota_sym_idx, sym_idx, tti, frame_id, subframe_id, slot_id, sym_id); - xran_if_current_state =XRAN_STOPPED; - } + xran_if_current_state = XRAN_STOPPED; + } num_eAxc = xran_get_num_eAxc(pHandle); num_CCPorts = xran_get_num_cc(pHandle); @@ -855,55 +1546,208 @@ int xran_process_tx_sym(void *arg) /* U-Plane */ for(ant_id = 0; ant_id < num_eAxc; ant_id++) { for(cc_id = 0; cc_id < num_CCPorts; cc_id++) { - if(p_xran_lib_ctx->xran_init_cfg.io_cfg.id == APP_LLS_CU && p_xran_lib_ctx->enableCP) { + if(p_xran_dev_ctx->fh_init.io_cfg.id == O_DU + && p_xran_dev_ctx->enableCP) { + /*==== lls-CU and C-Plane has been enabled ===*/ next = 0; - while(next < xran_cp_getsize_section_info(pHandle, direction, cc_id, ant_id)) { - sectinfo = xran_cp_iterate_section_info(pHandle, direction, - cc_id, ant_id, subframe_id, slot_id, &next); + num_sections = xran_cp_getsize_section_info(pHandle, direction, cc_id, ant_id, ctx_id); + /* iterate C-Plane configuration to generate corresponding U-Plane */ + while(next < num_sections) { + sectinfo = xran_cp_iterate_section_info(pHandle, direction, cc_id, ant_id, ctx_id, &next); + if(sectinfo == NULL) break; - /* pointer to IQs input */ - /* TODO: need to implement the case of partial RB assignment */ - pos = (char*) p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData; - print_dbg(">>> [%d] type%d, id %d, startPrbc=%d, numPrbc=%d, numSymbol=%d\n", next, - sectinfo->type, sectinfo->id, sectinfo->startPrbc, - sectinfo->numPrbc, sectinfo->numSymbol); - - if(sectinfo->type != XRAN_CP_SECTIONTYPE_1) { + if(sectinfo->type != XRAN_CP_SECTIONTYPE_1) { /* only supports type 1 */ print_err("Invalid section type in section DB - %d", sectinfo->type); continue; + } + + /* skip, if not scheduled */ + if(sym_id < sectinfo->startSymId || sym_id >= sectinfo->startSymId + sectinfo->numSymbol) + continue; + + /* if(sectinfo->compMeth) + iq_sample_size_bits = sectinfo->iqWidth;*/ + + if(iq_sample_size_bits != 16) {/* TODO: support for compression */ + print_err("Incorrect iqWidth %d", iq_sample_size_bits); + iq_sample_size_bits = 16; + } + + print_dbg(">>> sym %2d [%d] type%d, id %d, startPrbc=%d, numPrbc=%d, numSymbol=%d\n", sym_id, next, + sectinfo->type, sectinfo->id, sectinfo->startPrbc, + sectinfo->numPrbc, sectinfo->numSymbol); + + p_xran_dev_ctx->tx_mbufs[0].len = 0; + uint16_t len = p_xran_dev_ctx->tx_mbufs[0].len; + int16_t len2 = 0; + uint16_t i = 0; + + //Added for Klocworks + if (len >= MBUF_TABLE_SIZE) + len = MBUF_TABLE_SIZE - 1; + + pos = (char*) p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData; + mb = p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_id].pCtrl; + + /* first all PRBs */ + prepare_symbol_ex(direction, sectinfo->id, + mb, + (struct rb_map *)pos, + p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder, + frame_id, subframe_id, slot_id, sym_id, + sectinfo->startPrbc, sectinfo->numPrbc, + cc_id, ant_id, + xran_get_updl_seqid(pHandle, cc_id, ant_id), + 0); + + /* if we don't need to do any fragmentation */ + if (likely (p_xran_dev_ctx->fh_init.mtu >= + sectinfo->numPrbc * N_SC_PER_PRB*(iq_sample_size_bits/8)*2)) { + /* no fragmentation */ + p_xran_dev_ctx->tx_mbufs[0].m_table[len] = mb; + len2 = 1; + } else { + /* fragmentation */ + len2 = xran_app_fragment_packet(mb, + &p_xran_dev_ctx->tx_mbufs[0].m_table[len], + (uint16_t)(MBUF_TABLE_SIZE - len), + p_xran_dev_ctx->fh_init.mtu, + p_xran_dev_ctx->direct_pool, + p_xran_dev_ctx->indirect_pool, + sectinfo, + xran_get_updl_seqid_addr(pHandle, cc_id, ant_id)); + + /* Free input packet */ + rte_pktmbuf_free(mb); + + /* If we fail to fragment the packet */ + if (unlikely (len2 < 0)){ + print_err("len2= %d\n", len2); + return 0; } + } - send_symbol_ex(direction, sectinfo->id, - (struct rb_map *)pos, - frame_id, subframe_id, slot_id, sym_id, - sectinfo->startPrbc, sectinfo->numPrbc, - cc_id, ant_id, - xran_get_seqid(pHandle, direction, cc_id, ant_id, slot_id)); + if(len2 > 1){ + for (i = len; i < len + len2; i ++) { + struct rte_mbuf *m; + m = p_xran_dev_ctx->tx_mbufs[0].m_table[i]; + struct ether_hdr *eth_hdr = (struct ether_hdr *) + rte_pktmbuf_prepend(m, (uint16_t)sizeof(struct ether_hdr)); + if (eth_hdr == NULL) { + rte_panic("No headroom in mbuf.\n"); + } + } } - } - else { /* if(p_xran_lib_ctx->xran_init_cfg.io_cfg.id == APP_LLS_CU && p_xran_lib_ctx->enableCP) */ - /* pointer to IQs input */ - pos = (char*) p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData; + len += len2; + + if (unlikely(len > XRAN_MAX_PKT_BURST_PER_SYM)) { + rte_panic("XRAN_MAX_PKT_BURST_PER_SYM\n"); + } + + /* Transmit packets */ + xran_send_burst(p_xran_dev_ctx, (uint16_t)len, 0); + p_xran_dev_ctx->tx_mbufs[0].len = 0; + } /* while(section) */ + + } + else { + /*==== RU or C-Plane is disabled ===*/ + xRANPrachCPConfigStruct *pPrachCPConfig = &(p_xran_dev_ctx->PrachCPConfig); + + if(xran_fs_get_slot_type(cc_id, tti, ((p_xran_dev_ctx->fh_init.io_cfg.id == O_DU)? XRAN_SLOT_TYPE_DL : XRAN_SLOT_TYPE_UL)) == 1 + || xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_SP) == 1 + || xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_FDD) == 1){ + + if(xran_fs_get_symbol_type(cc_id, tti, sym_id) == ((p_xran_dev_ctx->fh_init.io_cfg.id == O_DU)? XRAN_SYMBOL_TYPE_DL : XRAN_SYMBOL_TYPE_UL) + || xran_fs_get_symbol_type(cc_id, tti, sym_id) == XRAN_SYMBOL_TYPE_FDD){ + + if(iq_sample_size_bits != 16) + print_err("Incorrect iqWidth %d\n", iq_sample_size_bits ); + + pos = (char*) p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData; + mb = (void*) p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_id].pCtrl; + + if( prb_num > 136 || prb_num == 0) { + uint16_t sec_id = xran_alloc_sectionid(pHandle, direction, cc_id, ant_id, slot_id); + /* first 136 PRBs */ + send_symbol_ex(direction, + sec_id, + NULL, + (struct rb_map *)pos, + p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder, + frame_id, subframe_id, slot_id, sym_id, + 0, 136, + cc_id, ant_id, + (p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) ? + xran_get_updl_seqid(pHandle, cc_id, ant_id) : + xran_get_upul_seqid(pHandle, cc_id, ant_id)); + + pos += 136 * N_SC_PER_PRB * (iq_sample_size_bits/8)*2; + /* last 137 PRBs */ + send_symbol_ex(direction, sec_id, + NULL, + (struct rb_map *)pos, + p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder, + frame_id, subframe_id, slot_id, sym_id, + 136, 137, + cc_id, ant_id, + (p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) ? + xran_get_updl_seqid(pHandle, cc_id, ant_id) : + xran_get_upul_seqid(pHandle, cc_id, ant_id)); + } else { #ifdef DEBUG_XRAN_BUFFERS - if (pos[0] != tti % XRAN_N_FE_BUF_LEN || - pos[1] != cc_id || - pos[2] != ant_id || - pos[3] != sym_id) - printf("%d %d %d %d\n", pos[0], pos[1], pos[2], pos[3]); + if (pos[0] != tti % XRAN_N_FE_BUF_LEN || + pos[1] != cc_id || + pos[2] != ant_id || + pos[3] != sym_id) + printf("%d %d %d %d\n", pos[0], pos[1], pos[2], pos[3]); #endif - send_symbol_ex(direction, - xran_alloc_sectionid(pHandle, direction, cc_id, ant_id, slot_id), - (struct rb_map *)pos, - frame_id, subframe_id, slot_id, sym_id, - 0, prb_num, - cc_id, ant_id, - xran_get_seqid(pHandle, direction, cc_id, ant_id, slot_id)); + send_symbol_ex(direction, + xran_alloc_sectionid(pHandle, direction, cc_id, ant_id, slot_id), + (struct rte_mbuf *)mb, + (struct rb_map *)pos, + p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder, + frame_id, subframe_id, slot_id, sym_id, + 0, prb_num, + cc_id, ant_id, + (p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) ? + xran_get_updl_seqid(pHandle, cc_id, ant_id) : + xran_get_upul_seqid(pHandle, cc_id, ant_id)); + } + + if(p_xran_dev_ctx->enablePrach + && (p_xran_dev_ctx->fh_init.io_cfg.id == O_RU)) { /* Only RU needs to send PRACH I/Q */ + uint32_t isPRACHslot = xran_isPRACHSlot(subframe_id, slot_id); + if((frame_id % pPrachCPConfig->x == pPrachCPConfig->y[0]) + && (isPRACHslot == 1) + && (sym_id >= p_xran_dev_ctx->prach_start_symbol[cc_id]) + && (sym_id <= p_xran_dev_ctx->prach_last_symbol[cc_id])) { //is prach slot + for(ant_id = 0; ant_id < num_eAxc; ant_id++) { + int prach_port_id = ant_id + num_eAxc; + pos = (char*) p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[0].pData; + pos += (sym_id - p_xran_dev_ctx->prach_start_symbol[cc_id]) * pPrachCPConfig->numPrbc * N_SC_PER_PRB * 4; + mb = NULL;//(void*) p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[0].pCtrl; + send_symbol_ex(direction, + xran_alloc_sectionid(pHandle, direction, cc_id, prach_port_id, slot_id), + (struct rte_mbuf *)mb, + (struct rb_map *)pos, + p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder, + frame_id, subframe_id, slot_id, sym_id, + pPrachCPConfig->startPrbc, pPrachCPConfig->numPrbc, + cc_id, prach_port_id, + xran_get_upul_seqid(pHandle, cc_id, prach_port_id)); + } + } /* if((frame_id % pPrachCPConfig->x == pPrachCPConfig->y[0]) .... */ + } /* if(p_xran_dev_ctx->enablePrach ..... */ + + } /* RU mode or C-Plane is not used */ } } - } + } /* for(cc_id = 0; cc_id < num_CCPorts; cc_id++) */ + } /* for(ant_id = 0; ant_id < num_eAxc; ant_id++) */ MLogTask(PID_PROCESS_TX_SYM, t1, MLogTick()); return 0; @@ -946,106 +1790,111 @@ int xran_packet_and_dpdk_timer_thread(void *args) } -int32_t xran_init(int argc, char *argv[], PXRANFHINIT p_xran_fh_init, char *appName, void ** pHandle) +int32_t +xran_init(int argc, char *argv[], + struct xran_fh_init *p_xran_fh_init, char *appName, void ** pXranLayerHandle) { - int i; - int j; + int32_t i; + int32_t j; struct xran_io_loop_cfg *p_io_cfg = (struct xran_io_loop_cfg *)&p_xran_fh_init->io_cfg; - struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx(); + struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx(); - int lcore_id = 0; + int32_t lcore_id = 0; char filename[64]; - memset(p_xran_lib_ctx, 0, sizeof(struct xran_lib_ctx)); + memset(p_xran_dev_ctx, 0, sizeof(struct xran_device_ctx)); + /* copy init */ - p_xran_lib_ctx->xran_init_cfg = *p_xran_fh_init; + p_xran_dev_ctx->fh_init = *p_xran_fh_init; - xran_if_current_state = XRAN_RUNNING; - interval_us = p_xran_fh_init->ttiPeriod; + printf(" %s: MTU %d\n", __FUNCTION__, p_xran_dev_ctx->fh_init.mtu); - p_xran_lib_ctx->llscu_id = p_xran_fh_init->llscuId; - memcpy(&(p_xran_lib_ctx->eAxc_id_cfg), &(p_xran_fh_init->eAxCId_conf), sizeof(XRANEAXCIDCONFIG)); + xran_if_current_state = XRAN_INIT; - p_xran_lib_ctx->enableCP = p_xran_fh_init->enableCP; + memcpy(&(p_xran_dev_ctx->eAxc_id_cfg), &(p_xran_fh_init->eAxCId_conf), sizeof(struct xran_eaxcid_config)); + + p_xran_dev_ctx->enableCP = p_xran_fh_init->enableCP; + p_xran_dev_ctx->enablePrach = p_xran_fh_init->prachEnable; + p_xran_dev_ctx->DynamicSectionEna = p_xran_fh_init->DynamicSectionEna; xran_register_ethertype_handler(ETHER_TYPE_ECPRI, handle_ecpri_ethertype); if (p_io_cfg->id == 0) - xran_ethdi_init_dpdk_io(basename(appName), + xran_ethdi_init_dpdk_io(p_xran_fh_init->filePrefix, p_io_cfg, &lcore_id, - (struct ether_addr *)p_xran_fh_init->p_lls_cu_addr, - (struct ether_addr *)p_xran_fh_init->p_ru_addr, + (struct ether_addr *)p_xran_fh_init->p_o_du_addr, + (struct ether_addr *)p_xran_fh_init->p_o_ru_addr, p_xran_fh_init->cp_vlan_tag, p_xran_fh_init->up_vlan_tag); else - xran_ethdi_init_dpdk_io(basename(appName), + xran_ethdi_init_dpdk_io(p_xran_fh_init->filePrefix, p_io_cfg, &lcore_id, - (struct ether_addr *)p_xran_fh_init->p_ru_addr, - (struct ether_addr *)p_xran_fh_init->p_lls_cu_addr, + (struct ether_addr *)p_xran_fh_init->p_o_ru_addr, + (struct ether_addr *)p_xran_fh_init->p_o_du_addr, p_xran_fh_init->cp_vlan_tag, p_xran_fh_init->up_vlan_tag); for(i = 0; i < 10; i++ ) rte_timer_init(&tti_to_phy_timer[i]); - rte_timer_init(&tti_timer); rte_timer_init(&sym_timer); - rte_timer_init(&tx_cp_dl_timer); - rte_timer_init(&tx_cp_ul_timer); - rte_timer_init(&tx_up_timer); + for (i = 0; i< MAX_NUM_OF_DPDK_TIMERS; i++) + rte_timer_init(&dpdk_timer[i]); + + p_xran_dev_ctx->direct_pool = socket_direct_pool; + p_xran_dev_ctx->indirect_pool = socket_indirect_pool; - for(i = 0; i < XRAN_MAX_SECTOR_NR; i++ ){ - unsigned n = snprintf(&p_xran_lib_ctx->ring_name[0][i][0], RTE_RING_NAMESIZE, "dl_sym_ring_%u", i); - p_xran_lib_ctx->dl_sym_idx_ring[i] = rte_ring_create(&p_xran_lib_ctx->ring_name[0][i][0], XRAN_RING_SIZE, - rte_lcore_to_socket_id(lcore_id), RING_F_SP_ENQ | RING_F_SC_DEQ); + printf("Set debug stop %d, debug stop count %d\n", p_xran_fh_init->debugStop, p_xran_fh_init->debugStopCount); + timing_set_debug_stop(p_xran_fh_init->debugStop, p_xran_fh_init->debugStopCount); + + for (uint32_t nCellIdx = 0; nCellIdx < XRAN_MAX_SECTOR_NR; nCellIdx++){ + xran_fs_clear_slot_type(nCellIdx); } + *pXranLayerHandle = p_xran_dev_ctx; - lcore_id = rte_get_next_lcore(lcore_id, 0, 0); - PANIC_ON(lcore_id == RTE_MAX_LCORE, "out of lcores for io_loop()"); + return 0; +} - /* Start packet processing thread */ - if (rte_eal_remote_launch(ring_processing_thread, NULL, lcore_id)) - rte_panic("ring_processing_thread() failed to start\n"); +int32_t xran_sector_get_instances (void * pDevHandle, uint16_t nNumInstances, + xran_cc_handle_t * pSectorInstanceHandles) +{ + xran_status_t nStatus = XRAN_STATUS_FAIL; + struct xran_device_ctx *pDev = (struct xran_device_ctx *)pDevHandle; + XranSectorHandleInfo *pCcHandle = NULL; + int32_t i = 0; - if(p_io_cfg->pkt_aux_core > 0){ - lcore_id = rte_get_next_lcore(lcore_id, 0, 0); - PANIC_ON(lcore_id == RTE_MAX_LCORE, "out of lcores for io_loop()"); + /* Check for the Valid Parameters */ + CHECK_NOT_NULL (pSectorInstanceHandles, XRAN_STATUS_INVALID_PARAM); - /* Start packet processing thread */ - if (rte_eal_remote_launch(xran_packet_and_dpdk_timer_thread, NULL, lcore_id)) - rte_panic("ring_processing_thread() failed to start\n"); + if (!nNumInstances) { + print_dbg("Instance is not assigned for this function !!! \n"); + return XRAN_STATUS_INVALID_PARAM; } - lcore_id = rte_get_next_lcore(lcore_id, 0, 0); - PANIC_ON(lcore_id == RTE_MAX_LCORE, "out of lcores for io_loop()"); - - /* Start packet processing thread */ - if (rte_eal_remote_launch(xran_timing_source_thread, xran_lib_get_ctx(), lcore_id)) - rte_panic("thread_run() failed to start\n"); + for (i = 0; i < nNumInstances; i++) { - printf("Set debug stop %d\n", p_xran_fh_init->debugStop); - timing_set_debug_stop(p_xran_fh_init->debugStop); + /* Allocate Memory for CC handles */ + pCcHandle = (XranSectorHandleInfo *) _mm_malloc( /*"xran_cc_handles",*/ sizeof (XranSectorHandleInfo), 64); - memset(&DevHandle, 0, sizeof(XranLibHandleInfoStruct)); + if(pCcHandle == NULL) + return XRAN_STATUS_RESOURCE; - *pHandle = &DevHandle; + memset (pCcHandle, 0, (sizeof (XranSectorHandleInfo))); - return 0; -} + pCcHandle->nIndex = i; + pCcHandle->nXranPort = pDev->xran_port_id; -int32_t xran_sector_get_instances (void * pHandle, uint16_t nNumInstances, - XranCcInstanceHandleVoidP * pSectorInstanceHandles) -{ - int i; + printf("%s [%d]: CC %d handle %p\n", __FUNCTION__, pDev->xran_port_id, i, pCcHandle); + pLibInstanceHandles[pDev->xran_port_id][i] = pSectorInstanceHandles[i] = pCcHandle; - /* only one handle as only one CC is currently supported */ - for(i = 0; i < nNumInstances; i++ ) - pSectorInstanceHandles[i] = pHandle; + printf("Handle: %p Instance: %p\n", + &pSectorInstanceHandles[i], pSectorInstanceHandles[i]); + } - return 0; + return XRAN_STATUS_SUCCESS; } int32_t xran_mm_init (void * pHandle, uint64_t nMemorySize, @@ -1057,66 +1906,109 @@ int32_t xran_mm_init (void * pHandle, uint64_t nMemorySize, int32_t xran_bm_init (void * pHandle, uint32_t * pPoolIndex, uint32_t nNumberOfBuffers, uint32_t nBufferSize) { - XranLibHandleInfoStruct* pXran = (XranLibHandleInfoStruct*) pHandle; + XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle; + uint32_t nAllocBufferSize; char pool_name[RTE_MEMPOOL_NAMESIZE]; - snprintf(pool_name, RTE_MEMPOOL_NAMESIZE, "bm_mempool_%ld", pPoolIndex); + snprintf(pool_name, RTE_MEMPOOL_NAMESIZE, "ru_%d_cc_%d_idx_%d", + pXranCc->nXranPort, pXranCc->nIndex, pXranCc->nBufferPoolIndex); + + nAllocBufferSize = nBufferSize + sizeof(struct ether_hdr) + + sizeof (struct xran_ecpri_hdr) + + sizeof (struct radio_app_common_hdr) + + sizeof(struct data_section_hdr) + 256; + + + printf("%s: [ handle %p %d %d ] [nPoolIndex %d] nNumberOfBuffers %d nBufferSize %d\n", pool_name, + pXranCc, pXranCc->nXranPort, pXranCc->nIndex, pXranCc->nBufferPoolIndex, nNumberOfBuffers, nBufferSize); - pXran->p_bufferPool[pXran->nBufferPoolIndex] = rte_pktmbuf_pool_create(pool_name, nNumberOfBuffers, - MBUF_CACHE, 0, XRAN_MAX_MBUF_LEN, rte_socket_id()); + pXranCc->p_bufferPool[pXranCc->nBufferPoolIndex] = rte_pktmbuf_pool_create(pool_name, nNumberOfBuffers, + MBUF_CACHE, 0, nAllocBufferSize, rte_socket_id()); + + if(pXranCc->p_bufferPool[pXranCc->nBufferPoolIndex] == NULL){ + rte_panic("rte_pktmbuf_pool_create failed [ handle %p %d %d ] [nPoolIndex %d] nNumberOfBuffers %d nBufferSize %d errno %s\n", + pXranCc, pXranCc->nXranPort, pXranCc->nIndex, pXranCc->nBufferPoolIndex, nNumberOfBuffers, nBufferSize, rte_strerror(rte_errno)); + return -1; + } - pXran->bufferPoolElmSz[pXran->nBufferPoolIndex] = nBufferSize; - pXran->bufferPoolNumElm[pXran->nBufferPoolIndex] = nNumberOfBuffers; + pXranCc->bufferPoolElmSz[pXranCc->nBufferPoolIndex] = nBufferSize; + pXranCc->bufferPoolNumElm[pXranCc->nBufferPoolIndex] = nNumberOfBuffers; - print_dbg("[nPoolIndex %d] mb pool %p \n", pXran->nBufferPoolIndex, pXran->p_bufferPool[pXran->nBufferPoolIndex]); + printf("CC:[ handle %p ru %d cc_idx %d ] [nPoolIndex %d] mb pool %p \n", + pXranCc, pXranCc->nXranPort, pXranCc->nIndex, + pXranCc->nBufferPoolIndex, pXranCc->p_bufferPool[pXranCc->nBufferPoolIndex]); - *pPoolIndex = pXran->nBufferPoolIndex++; + *pPoolIndex = pXranCc->nBufferPoolIndex++; return 0; } -int32_t xran_bm_allocate_buffer(void * pHandle, uint32_t nPoolIndex, void **ppVirtAddr) +int32_t xran_bm_allocate_buffer(void * pHandle, uint32_t nPoolIndex, void **ppData, void **ppCtrl) { - XranLibHandleInfoStruct* pXran = (XranLibHandleInfoStruct*) pHandle; - *ppVirtAddr = NULL; + XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle; + *ppData = NULL; + *ppCtrl = NULL; - struct rte_mbuf * mb = rte_pktmbuf_alloc(pXran->p_bufferPool[nPoolIndex]); + struct rte_mbuf * mb = rte_pktmbuf_alloc(pXranCc->p_bufferPool[nPoolIndex]); if(mb){ - *ppVirtAddr = rte_pktmbuf_append(mb, pXran->bufferPoolElmSz[nPoolIndex]); - + char * start = rte_pktmbuf_append(mb, pXranCc->bufferPoolElmSz[nPoolIndex]); + char * ethhdr = rte_pktmbuf_prepend(mb, sizeof(struct ether_hdr)); + + if(start && ethhdr){ + char * iq_offset = rte_pktmbuf_mtod(mb, char * ); + /* skip headers */ + iq_offset = iq_offset + sizeof(struct ether_hdr) + + sizeof (struct xran_ecpri_hdr) + + sizeof (struct radio_app_common_hdr) + + sizeof(struct data_section_hdr); + + if (0) /* if compression */ + iq_offset += sizeof (struct data_section_compression_hdr); + + *ppData = (void *)iq_offset; + *ppCtrl = (void *)mb; + } + else { + print_err("[nPoolIndex %d] start ethhdr failed \n", nPoolIndex ); + return -1; + } }else { print_err("[nPoolIndex %d] mb alloc failed \n", nPoolIndex ); return -1; } - if (*ppVirtAddr == NULL){ - print_err("[nPoolIndex %d] rte_pktmbuf_append for %d failed \n", nPoolIndex, pXran->bufferPoolElmSz[nPoolIndex]); + if (*ppData == NULL){ + print_err("[nPoolIndex %d] rte_pktmbuf_append for %d failed \n", nPoolIndex, pXranCc->bufferPoolElmSz[nPoolIndex]); return -1; } return 0; } -int32_t xran_bm_free_buffer(void * pHandle, void *pVirtAddr) +int32_t xran_bm_free_buffer(void * pHandle, void *pData, void *pCtrl) { - XranLibHandleInfoStruct* pXran = (XranLibHandleInfoStruct*) pHandle; - rte_pktmbuf_free(pVirtAddr); + XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle; + + if(pCtrl) + rte_pktmbuf_free(pCtrl); return 0; } int32_t xran_5g_fronthault_config (void * pHandle, - XRANBufferListStruct *pSrcBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN], - XRANBufferListStruct *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN], - XranTransportBlockCallbackFn pCallback, + struct xran_buffer_list *pSrcBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN], + struct xran_buffer_list *pSrcCpBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN], + struct xran_buffer_list *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN], + struct xran_buffer_list *pDstCpBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN], + xran_transport_callback_fn pCallback, void *pCallbackTag) { - XranLibHandleInfoStruct *pInfo = (XranLibHandleInfoStruct *) pHandle; - XranStatusInt32 nStatus = XRAN_STATUS_SUCCESS; + XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle; + xran_status_t nStatus = XRAN_STATUS_SUCCESS; int j, i = 0, z, k; - struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx(); + struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx(); print_dbg("%s\n", __FUNCTION__); @@ -1125,31 +2017,59 @@ int32_t xran_5g_fronthault_config (void * pHandle, printf("Handle is NULL!\n"); return XRAN_STATUS_FAIL; } + if (pCallback == NULL) { printf ("no callback\n"); return XRAN_STATUS_FAIL; } + i = pXranCc->nIndex; + for(j=0; jsFrontHaulTxBbuIoBufCtrl[j][i][z].bValid = 0; - p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegGenerated = -1; - p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1; - p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegTransferred = 0; - p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT; - p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_lib_ctx->sFrontHaulTxBuffers[j][i][z][0]; - - p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList = *pSrcBuffer[z][j]; - - p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].bValid = 0; - p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1; - p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1; - p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0; - p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT; - p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_lib_ctx->sFrontHaulRxBuffers[j][i][z][0]; - p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList = *pDstBuffer[z][j]; + /* U-plane TX */ + + p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].bValid = 0; + p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegGenerated = -1; + p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1; + p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegTransferred = 0; + p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT; + p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFrontHaulTxBuffers[j][i][z][0]; + + p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList = *pSrcBuffer[z][j]; + + /* C-plane TX */ + p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0; + p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1; + p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1; + p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0; + p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT; + p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFrontHaulTxPrbMapBuffers[j][i][z][0]; + + p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList = *pSrcCpBuffer[z][j]; + + /* U-plane RX */ + + p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].bValid = 0; + p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1; + p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1; + p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0; + p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT; + p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFrontHaulRxBuffers[j][i][z][0]; + + p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList = *pDstBuffer[z][j]; + + /* C-plane RX */ + p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0; + p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1; + p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1; + p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0; + p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT; + p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFrontHaulRxPrbMapBuffers[j][i][z][0]; + + p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList = *pDstCpBuffer[z][j]; } } @@ -1158,7 +2078,7 @@ int32_t xran_5g_fronthault_config (void * pHandle, for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){ printf("TTI:TX 0x%02x Sec %d Ant%d\n",j,i,z); for(k = 0; k sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData; + uint8_t *ptr = p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData; printf(" sym: %2d %p 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", k, ptr, ptr[0],ptr[1], ptr[2], ptr[3], ptr[4]); } } @@ -1167,29 +2087,29 @@ int32_t xran_5g_fronthault_config (void * pHandle, for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){ printf("TTI:RX 0x%02x Sec %d Ant%d\n",j,i,z); for(k = 0; k sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData; + uint8_t *ptr = p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData; printf(" sym: %2d %p 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", k, ptr, ptr[0],ptr[1], ptr[2], ptr[3], ptr[4]); } } #endif - p_xran_lib_ctx->pCallback[i] = pCallback; - p_xran_lib_ctx->pCallbackTag[i] = pCallbackTag; + p_xran_dev_ctx->pCallback[i] = pCallback; + p_xran_dev_ctx->pCallbackTag[i] = pCallbackTag; - p_xran_lib_ctx->xran2phy_mem_ready = 1; + p_xran_dev_ctx->xran2phy_mem_ready = 1; return nStatus; } int32_t xran_5g_prach_req (void * pHandle, - XRANBufferListStruct *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN], - XranTransportBlockCallbackFn pCallback, + struct xran_buffer_list *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN], + xran_transport_callback_fn pCallback, void *pCallbackTag) { - XranLibHandleInfoStruct *pInfo = (XranLibHandleInfoStruct *) pHandle; - XranStatusInt32 nStatus = XRAN_STATUS_SUCCESS; + XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle; + xran_status_t nStatus = XRAN_STATUS_SUCCESS; int j, i = 0, z; - struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx(); + struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx(); if(NULL == pHandle) { @@ -1202,74 +2122,96 @@ int32_t xran_5g_prach_req (void * pHandle, return XRAN_STATUS_FAIL; } + i = pXranCc->nIndex; + for(j=0; jsFHPrachRxBbuIoBufCtrl[j][i][z].bValid = 0; - p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1; - p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1; - p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0; - p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_MAX_ANTENNA_NR; // ant number. - p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_lib_ctx->sFHPrachRxBuffers[j][i][z][0]; - p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList = *pDstBuffer[z][j]; + p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].bValid = 0; + p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1; + p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1; + p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0; + p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_MAX_ANTENNA_NR; // ant number. + p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFHPrachRxBuffers[j][i][z][0]; + p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList = *pDstBuffer[z][j]; } } - p_xran_lib_ctx->pPrachCallback[i] = pCallback; - p_xran_lib_ctx->pPrachCallbackTag[i] = pCallbackTag; + p_xran_dev_ctx->pPrachCallback[i] = pCallback; + p_xran_dev_ctx->pPrachCallbackTag[i] = pCallbackTag; return 0; } -int32_t xran_5g_pre_compenstor_cfg(void* pHandle, - uint32_t nTxPhaseCps, - uint32_t nRxPhaseCps, - uint8_t nSectorId) +int32_t xran_open(void *pHandle, struct xran_fh_config* pConf) { - /* functionality is not yet implemented */ - return 0; -} + int32_t i; + uint8_t nNumerology = 0; + int32_t lcore_id = 0; + struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx(); + struct xran_fh_config *pFhCfg; + pFhCfg = &(p_xran_dev_ctx->fh_cfg); -int32_t xran_open(void *pHandle, PXRANFHCONFIG pConf) -{ - int i; - uint8_t slotNr; - XRANFHCONFIG *pFhCfg; - xRANPrachCPConfigStruct *pPrachCPConfig = &(xran_lib_get_ctx()->PrachCPConfig); - pFhCfg = &(xran_lib_get_ctx()->xran_fh_cfg); - memcpy(pFhCfg, pConf, sizeof(XRANFHCONFIG)); - PXRANPRACHCONFIG pPRACHConfig = &pFhCfg->prach_conf; - uint8_t nPrachConfIdx = pPRACHConfig->nPrachConfIdx; - const xRANPrachConfigTableStruct *pxRANPrachConfigTable = &gxranPrachDataTable_mmw[nPrachConfIdx]; - uint8_t preambleFmrt = pxRANPrachConfigTable->preambleFmrt[0]; - const xRANPrachPreambleLRAStruct *pxranPreambleforLRA = &gxranPreambleforLRA[preambleFmrt - FORMAT_A1]; - memset(pPrachCPConfig, 0, sizeof(xRANPrachCPConfigStruct)); + memcpy(pFhCfg, pConf, sizeof(struct xran_fh_config)); - //setup PRACH configuration for C-Plane - pPrachCPConfig->filterIdx = XRAN_FILTERINDEX_PRACH_ABC; // 3, PRACH preamble format A1~3, B1~4, C0, C2 - pPrachCPConfig->startSymId = pxRANPrachConfigTable->startingSym; - pPrachCPConfig->startPrbc = pPRACHConfig->nPrachFreqStart; - pPrachCPConfig->numPrbc = (preambleFmrt >= FORMAT_A1)? 12 : 70; - pPrachCPConfig->numSymbol = pxRANPrachConfigTable->duration; - pPrachCPConfig->timeOffset = pxranPreambleforLRA->nRaCp; - pPrachCPConfig->freqOffset = xran_get_freqoffset(pPRACHConfig->nPrachFreqOffset, pPRACHConfig->nPrachSubcSpacing); - pPrachCPConfig->occassionsInPrachSlot = pxRANPrachConfigTable->occassionsInPrachSlot; - pPrachCPConfig->x = pxRANPrachConfigTable->x; - pPrachCPConfig->y[0] = pxRANPrachConfigTable->y[0]; - pPrachCPConfig->y[1] = pxRANPrachConfigTable->y[1]; + nNumerology = xran_get_conf_numerology(pHandle); - pPrachCPConfig->isPRACHslot[pxRANPrachConfigTable->slotNr[0]] = 1; - for (i=1; i < XRAN_PRACH_CANDIDATE_SLOT; i++) + if (pConf->nCC > XRAN_MAX_SECTOR_NR) { - slotNr = pxRANPrachConfigTable->slotNr[i]; - if (slotNr > 0) - pPrachCPConfig->isPRACHslot[slotNr] = 1; + if(pConf->log_level) + printf("Number of cells %d exceeds max number supported %d!\n", pConf->nCC, XRAN_MAX_SECTOR_NR); + pConf->nCC = XRAN_MAX_SECTOR_NR; + + } + if(pConf->ru_conf.iqOrder != XRAN_I_Q_ORDER + || pConf->ru_conf.byteOrder != XRAN_NE_BE_BYTE_ORDER ){ + + print_err("Byte order and/or IQ order is not suppirted [IQ %d byte %d]\n", pConf->ru_conf.iqOrder, pConf->ru_conf.byteOrder); + return XRAN_STATUS_FAIL; } + //setup PRACH configuration for C-Plane + xran_init_prach(pConf, p_xran_dev_ctx); + xran_cp_init_sectiondb(pHandle); xran_init_sectionid(pHandle); xran_init_seqid(pHandle); + interval_us = xran_fs_get_tti_interval(nNumerology); + + if(pConf->log_level){ + printf("%s: interval_us=%ld\n", __FUNCTION__, interval_us); + } + timing_set_numerology(nNumerology); + + for(i = 0 ; i nCC; i++){ + xran_fs_set_slot_type(i, pConf->frame_conf.nFrameDuplexType, pConf->frame_conf.nTddPeriod, + pConf->frame_conf.sSlotConfig); + } + + xran_fs_slot_limit_init(xran_fs_get_tti_interval(nNumerology)); + + if(xran_ethdi_get_ctx()->io_cfg.bbdev_mode != XRAN_BBDEV_NOT_USED){ + p_xran_dev_ctx->bbdev_dec = pConf->bbdev_dec; + p_xran_dev_ctx->bbdev_enc = pConf->bbdev_enc; + } + + /* Start packet processing thread */ + if((uint16_t)xran_ethdi_get_ctx()->io_cfg.port[XRAN_UP_VF] != 0xFFFF && + (uint16_t)xran_ethdi_get_ctx()->io_cfg.port[XRAN_CP_VF] != 0xFFFF ){ + if(pConf->log_level){ + print_dbg("XRAN_UP_VF: 0x%04x\n", xran_ethdi_get_ctx()->io_cfg.port[XRAN_UP_VF]); + print_dbg("XRAN_CP_VF: 0x%04x\n", xran_ethdi_get_ctx()->io_cfg.port[XRAN_CP_VF]); + } + if (rte_eal_remote_launch(xran_timing_source_thread, xran_dev_get_ctx(), xran_ethdi_get_ctx()->io_cfg.timing_core)) + rte_panic("thread_run() failed to start\n"); + } else + if(pConf->log_level){ + printf("Eth port was not open. Processing thread was not started\n"); + } + + + return 0; } @@ -1288,8 +2230,10 @@ int32_t xran_stop(void *pHandle) int32_t xran_close(void *pHandle) { xran_if_current_state = XRAN_STOPPED; - xran_cp_free_sectiondb(pHandle); - rte_eal_mp_wait_lcore(); + //TODO: fix memory leak xran_cp_free_sectiondb(pHandle); + //rte_eal_mp_wait_lcore(); + //xran_ethdi_ports_stats(); + return 0; } @@ -1299,19 +2243,19 @@ int32_t xran_mm_destroy (void * pHandle) return -1; } -int32_t xran_reg_sym_cb(void *pHandle, XRANFHSYMPROCCB symCb, void * symCbParam, uint8_t symb, uint8_t ant) +int32_t xran_reg_sym_cb(void *pHandle, xran_callback_sym_fn symCb, void * symCbParam, uint8_t symb, uint8_t ant) { /* functionality is not yet implemented */ return -1; } -int32_t xran_reg_physide_cb(void *pHandle, XRANFHTTIPROCCB Cb, void *cbParam, int skipTtiNum, enum callback_to_phy_id id) +int32_t xran_reg_physide_cb(void *pHandle, xran_fh_tti_callback_fn Cb, void *cbParam, int skipTtiNum, enum callback_to_phy_id id) { - struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx(); + struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx(); - p_xran_lib_ctx->ttiCb[id] = Cb; - p_xran_lib_ctx->TtiCbParam[id] = cbParam; - p_xran_lib_ctx->SkipTti[id] = skipTtiNum; + p_xran_dev_ctx->ttiCb[id] = Cb; + p_xran_dev_ctx->TtiCbParam[id] = cbParam; + p_xran_dev_ctx->SkipTti[id] = skipTtiNum; return 0; } @@ -1329,24 +2273,15 @@ int32_t xran_get_slot_idx (uint32_t *nFrameIdx, uint32_t *nSubframeIdx, uint32_ return tti; } -/** - * @brief Get supported maximum number of sections - * - * @return maximum number of sections - */ -inline uint8_t xran_get_max_sections(void *pHandle) -{ - return (XRAN_MAX_NUM_SECTIONS); -} /** * @brief Get the configuration of eAxC ID * * @return the pointer of configuration */ -inline XRANEAXCIDCONFIG *xran_get_conf_eAxC(void *pHandle) +inline struct xran_eaxcid_config *xran_get_conf_eAxC(void *pHandle) { - return (&(xran_lib_get_ctx()->eAxc_id_cfg)); + return (&(xran_dev_get_ctx()->eAxc_id_cfg)); } /** @@ -1372,7 +2307,7 @@ inline uint8_t xran_get_conf_fftsize(void *pHandle) /** * @brief Get the configuration of nummerology * - * @return subcarrier spacing value for PRACH + * @return Configured numerology */ inline uint8_t xran_get_conf_numerology(void *pHandle) { @@ -1386,7 +2321,7 @@ inline uint8_t xran_get_conf_numerology(void *pHandle) */ inline uint8_t xran_get_conf_iqwidth(void *pHandle) { - XRANFHCONFIG *pFhCfg; + struct xran_fh_config *pFhCfg; pFhCfg = xran_lib_get_ctx_fhcfg(); return ((pFhCfg->ru_conf.iqWidth==16)?0:pFhCfg->ru_conf.iqWidth); @@ -1402,30 +2337,11 @@ inline uint8_t xran_get_conf_compmethod(void *pHandle) return (xran_lib_get_ctx_fhcfg()->ru_conf.compMeth); } -/** - * @brief Get the configuration of lls-cu ID - * - * @return Configured lls-cu ID - */ -inline uint8_t xran_get_llscuid(void *pHandle) -{ - return (xran_lib_get_ctx()->llscu_id); -} - -/** - * @brief Get the configuration of lls-cu ID - * - * @return Configured lls-cu ID - */ -inline uint8_t xran_get_sectorid(void *pHandle) -{ - return (xran_lib_get_ctx()->sector_id); -} /** * @brief Get the configuration of the number of component carriers * - * @return Configured the number of componen carriers + * @return Configured the number of component carriers */ inline uint8_t xran_get_num_cc(void *pHandle) { @@ -1442,4 +2358,15 @@ inline uint8_t xran_get_num_eAxc(void *pHandle) return (xran_lib_get_ctx_fhcfg()->neAxc); } +int32_t xran_get_common_counters(void *pXranLayerHandle, struct xran_common_counters *pStats) +{ + struct xran_device_ctx* pDev = (struct xran_device_ctx*)pXranLayerHandle; + + if(pStats && pDev) { + *pStats = pDev->fh_counters; + return XRAN_STATUS_SUCCESS; + } else { + return XRAN_STATUS_INVALID_PARAM; + } +}