1 /******************************************************************************
3 * Copyright (c) 2019 Intel.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 *******************************************************************************/
21 * @brief XRAN main functionality module
23 * @ingroup group_source_xran
24 * @author Intel Corporation
39 #include <rte_errno.h>
40 #include <rte_lcore.h>
41 #include <rte_cycles.h>
42 #include <rte_memory.h>
43 #include <rte_memzone.h>
46 #include "xran_fh_lls_cu.h"
50 #include "xran_up_api.h"
51 #include "xran_cp_api.h"
52 #include "xran_sync_api.h"
53 #include "xran_lib_mlog_tasks_id.h"
54 #include "xran_timer.h"
55 #include "xran_common.h"
56 #include "xran_printf.h"
59 #include "mlog_lnx_xRAN.h"
64 #define DIV_ROUND_OFFSET(X,Y) ( X/Y + ((X%Y)?1:0) )
66 #define XranOffsetSym(offSym, otaSym, numSymTotal) (((int32_t)offSym > (int32_t)otaSym) ? \
67 ((int32_t)otaSym + ((int32_t)numSymTotal) - (uint32_t)offSym) : \
68 (((int32_t)otaSym - (int32_t)offSym) >= numSymTotal) ? \
69 (((int32_t)otaSym - (int32_t)offSym) - numSymTotal) : \
70 ((int32_t)otaSym - (int32_t)offSym))
72 #define MAX_NUM_OF_XRAN_CTX (2)
73 #define XranIncrementCtx(ctx) ((ctx >= (MAX_NUM_OF_XRAN_CTX-1)) ? 0 : (ctx+1))
74 #define XranDecrementCtx(ctx) ((ctx == 0) ? (MAX_NUM_OF_XRAN_CTX-1) : (ctx-1))
76 struct xran_timer_ctx {
77 uint32_t tti_to_process;
80 static XranLibHandleInfoStruct DevHandle;
81 static struct xran_lib_ctx g_xran_lib_ctx = { 0 };
83 struct xran_timer_ctx timer_ctx[MAX_NUM_OF_XRAN_CTX];
85 static struct rte_timer tti_to_phy_timer[10];
86 static struct rte_timer tti_timer;
87 static struct rte_timer sym_timer;
88 static struct rte_timer tx_cp_dl_timer;
89 static struct rte_timer tx_cp_ul_timer;
90 static struct rte_timer tx_up_timer;
92 static long interval_us = 125;
94 uint32_t xran_lib_ota_tti = 0; /* [0:7999] */
95 uint32_t xran_lib_ota_sym = 0; /* [0:7] */
96 uint32_t xran_lib_ota_sym_idx = 0; /* [0 : 14*8*1000-1] */
98 uint64_t xran_lib_gps_second = 0;
100 static uint8_t xran_cp_seq_id_num[XRAN_MAX_CELLS_PER_PORT][XRAN_DIR_MAX][XRAN_MAX_ANTENNA_NR];
101 static uint8_t xran_section_id_curslot[XRAN_MAX_CELLS_PER_PORT][XRAN_MAX_ANTENNA_NR];
102 static uint16_t xran_section_id[XRAN_MAX_CELLS_PER_PORT][XRAN_MAX_ANTENNA_NR];
104 void xran_timer_arm(struct rte_timer *tim, void* arg);
105 int xran_process_tx_sym(void *arg);
107 int xran_process_rx_sym(void *arg,
117 void tti_ota_cb(struct rte_timer *tim, void *arg);
118 void tti_to_phy_cb(struct rte_timer *tim, void *arg);
119 void xran_timer_arm_ex(struct rte_timer *tim, void* CbFct, void *CbArg, unsigned tim_lcore);
121 struct xran_lib_ctx *xran_lib_get_ctx(void)
123 return &g_xran_lib_ctx;
126 static inline XRANFHCONFIG *xran_lib_get_ctx_fhcfg(void)
128 return (&(xran_lib_get_ctx()->xran_fh_cfg));
131 inline uint16_t xran_get_beamid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id)
133 return (0); // NO BEAMFORMING
136 int xran_init_sectionid(void *pHandle)
140 for(cell=0; cell < XRAN_MAX_CELLS_PER_PORT; cell++) {
141 for(ant=0; ant < XRAN_MAX_ANTENNA_NR; ant++) {
142 xran_section_id[cell][ant] = 0;
143 xran_section_id_curslot[cell][ant] = 255;
150 int xran_init_seqid(void *pHandle)
154 for(cell=0; cell < XRAN_MAX_CELLS_PER_PORT; cell++) {
155 for(dir=0; dir < XRAN_DIR_MAX; dir++) {
156 for(ant=0; ant < XRAN_MAX_ANTENNA_NR; ant++) {
157 xran_cp_seq_id_num[cell][dir][ant] = 0;
165 inline uint16_t xran_alloc_sectionid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id)
167 if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
168 print_err("Invalid CC ID - %d", cc_id);
171 if(ant_id >= XRAN_MAX_ANTENNA_NR) {
172 print_err("Invalid antenna ID - %d", ant_id);
176 /* if new slot has been started,
177 * then initializes section id again for new start */
178 if(xran_section_id_curslot[cc_id][ant_id] != slot_id) {
179 xran_section_id[cc_id][ant_id] = 0;
180 xran_section_id_curslot[cc_id][ant_id] = slot_id;
183 return(xran_section_id[cc_id][ant_id]++);
186 inline uint8_t xran_get_seqid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id)
188 if(dir >= XRAN_DIR_MAX) {
189 print_err("Invalid direction - %d", dir);
192 if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
193 print_err("Invalid CC ID - %d", cc_id);
196 if(ant_id >= XRAN_MAX_ANTENNA_NR) {
197 print_err("Invalid antenna ID - %d", ant_id);
201 return(xran_cp_seq_id_num[cc_id][dir][ant_id]++);
204 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)
209 //////////////////////////////////////////
211 static struct xran_section_gen_info cpSections[255];
212 static struct xran_cp_gen_params cpInfo;
213 int process_cplane(struct rte_mbuf *pkt)
215 int xran_parse_cp_pkt(struct rte_mbuf *mbuf, struct xran_cp_gen_params *result);
217 cpInfo.sections = cpSections;
218 xran_parse_cp_pkt(pkt, &cpInfo);
222 //////////////////////////////////////////
224 void sym_ota_cb(struct rte_timer *tim, void *arg)
227 struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
228 struct xran_timer_ctx *pTCtx = (struct xran_timer_ctx *)arg;
229 long t1 = MLogTick();
231 if(XranGetSymNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT) == 0){
232 tti_ota_cb(NULL, arg);
235 if(XranGetSymNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT) == 1){
236 if(p_xran_lib_ctx->phy_tti_cb_done == 0){
237 uint64_t t3 = MLogTick();
238 /* rearm timer to deliver TTI event to PHY */
239 p_xran_lib_ctx->phy_tti_cb_done = 0;
240 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);
241 MLogTask(PID_TIME_ARM_TIMER, t3, MLogTick());
245 xran_process_tx_sym(timer_ctx);
246 /* check if there is call back to do something else on this symbol */
247 if(p_xran_lib_ctx->pSymCallback[0][xran_lib_ota_sym])
248 p_xran_lib_ctx->pSymCallback[0][xran_lib_ota_sym](&tx_cp_dl_timer, p_xran_lib_ctx->pSymCallbackTag[0][xran_lib_ota_sym]);
251 if(xran_lib_ota_sym >= N_SYM_PER_SLOT){
254 MLogTask(PID_SYM_OTA_CB, t1, MLogTick());
257 void tti_ota_cb(struct rte_timer *tim, void *arg)
259 uint32_t frame_id = 0;
260 uint32_t subframe_id = 0;
261 uint32_t slot_id = 0;
262 uint32_t next_tti = 0;
264 uint32_t mlogVar[10];
265 uint32_t mlogVarCnt = 0;
266 uint64_t t1 = MLogTick();
268 uint32_t reg_tti = 0;
269 struct xran_timer_ctx *pTCtx = (struct xran_timer_ctx *)arg;
270 struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
272 MLogTask(PID_TTI_TIMER, t1, MLogTick());
275 if(xran_lib_ota_tti == 0)
278 reg_tti = xran_lib_ota_tti -1;
279 MLogIncrementCounter();
280 /* subframe and slot */
281 MLogRegisterFrameSubframe(((reg_tti/SLOTNUM_PER_SUBFRAME) % SUBFRAMES_PER_SYSTEMFRAME),
282 reg_tti % (SLOTNUM_PER_SUBFRAME));
285 slot_id = XranGetSlotNum(xran_lib_ota_tti, SLOTNUM_PER_SUBFRAME);
286 subframe_id = XranGetSubFrameNum(xran_lib_ota_tti,SLOTNUM_PER_SUBFRAME, SUBFRAMES_PER_SYSTEMFRAME);
287 frame_id = XranGetFrameNum(xran_lib_ota_tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
289 pTCtx[(xran_lib_ota_tti & 1) ^ 1].tti_to_process = xran_lib_ota_tti;
291 mlogVar[mlogVarCnt++] = 0x11111111;
292 mlogVar[mlogVarCnt++] = xran_lib_ota_tti;
293 mlogVar[mlogVarCnt++] = xran_lib_ota_sym_idx;
294 mlogVar[mlogVarCnt++] = xran_lib_ota_sym_idx / 14;
295 mlogVar[mlogVarCnt++] = frame_id;
296 mlogVar[mlogVarCnt++] = subframe_id;
297 mlogVar[mlogVarCnt++] = slot_id;
298 mlogVar[mlogVarCnt++] = 0;
299 MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
301 if(p_xran_lib_ctx->xran_init_cfg.io_cfg.id == ID_LLS_CU)
302 next_tti = xran_lib_ota_tti + 1;
304 next_tti = xran_lib_ota_tti;
306 if(next_tti>= SLOTNUM_PER_SUBFRAME*1000){
307 print_dbg("[%d]SFN %d sf %d slot %d\n",next_tti, frame_id, subframe_id, slot_id);
311 slot_id = XranGetSlotNum(next_tti, SLOTNUM_PER_SUBFRAME);
313 subframe_id = XranGetSubFrameNum(next_tti,SLOTNUM_PER_SUBFRAME, SUBFRAMES_PER_SYSTEMFRAME);
314 /* frame [0 - 99] for now */
315 frame_id = XranGetFrameNum(next_tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
317 print_dbg("[%d]SFN %d sf %d slot %d\n",next_tti, frame_id, subframe_id, slot_id);
319 if(p_xran_lib_ctx->xran_init_cfg.io_cfg.id == ID_LLS_CU){
320 pTCtx[(xran_lib_ota_tti & 1)].tti_to_process = next_tti;
322 pTCtx[(xran_lib_ota_tti & 1)].tti_to_process = pTCtx[(xran_lib_ota_tti & 1)^1].tti_to_process;
326 p_xran_lib_ctx->phy_tti_cb_done = 0;
327 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);
328 MLogTask(PID_TIME_ARM_TIMER, t3, MLogTick());
331 /* within 1 sec we have 8000 TTIs as 1000ms/0.125ms where TTI is 125us*/
332 if(xran_lib_ota_tti >= SLOTNUM_PER_SUBFRAME*1000){
333 print_dbg("[%d]SFN %d sf %d slot %d\n",xran_lib_ota_tti, frame_id, subframe_id, slot_id);
336 MLogTask(PID_TTI_CB, t1, MLogTick());
339 void xran_timer_arm(struct rte_timer *tim, void* arg)
341 struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
342 if (xran_if_current_state == XRAN_RUNNING){
343 rte_timer_cb_t fct = (rte_timer_cb_t)arg;
344 rte_timer_reset_sync(tim, 0, SINGLE, p_xran_lib_ctx->xran_init_cfg.io_cfg.pkt_proc_core, fct, timer_ctx);
348 void xran_timer_arm_ex(struct rte_timer *tim, void* CbFct, void *CbArg, unsigned tim_lcore)
350 struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
351 if (xran_if_current_state == XRAN_RUNNING){
352 rte_timer_cb_t fct = (rte_timer_cb_t)CbFct;
354 rte_timer_reset_sync(tim, 0, SINGLE, tim_lcore, fct, CbArg);
358 void tx_cp_dl_cb(struct rte_timer *tim, void *arg)
360 long t1 = MLogTick();
362 uint32_t slot_id, subframe_id, frame_id;
366 uint8_t num_eAxc, num_CCPorts;
369 struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
370 struct xran_timer_ctx *pTCtx = (struct xran_timer_ctx *)arg;
373 pHandle = NULL; // TODO: temp implemantation
374 num_eAxc = xran_get_num_eAxc(pHandle);
375 num_CCPorts = xran_get_num_cc(pHandle);
377 if(p_xran_lib_ctx->enableCP) {
379 tti = pTCtx[(xran_lib_ota_tti & 1) ^ 1].tti_to_process;
381 slot_id = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME);
382 subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME, SUBFRAMES_PER_SYSTEMFRAME);
383 frame_id = XranGetFrameNum(tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
385 print_dbg("[%d]SFN %d sf %d slot %d\n", tti, frame_id, subframe_id, slot_id);
387 for(ant_id = 0; ant_id < num_eAxc; ++ant_id) {
388 for(cc_id = 0; cc_id < num_CCPorts; cc_id++ ) {
389 // start new section information list
390 xran_cp_reset_section_info(pHandle, XRAN_DIR_DL, cc_id, ant_id);
392 beam_id = xran_get_beamid(pHandle, XRAN_DIR_DL, cc_id, ant_id, slot_id);
394 send_cpmsg_dlul(pHandle, XRAN_DIR_DL,
395 frame_id, subframe_id, slot_id,
396 0, N_SYM_PER_SLOT, NUM_OF_PRB_IN_FULL_BAND,
397 beam_id, cc_id, ant_id,
398 xran_get_seqid(pHandle, XRAN_DIR_DL, cc_id, ant_id, slot_id));
402 MLogTask(PID_CP_DL_CB, t1, MLogTick());
405 void rx_ul_deadline_half_cb(struct rte_timer *tim, void *arg)
407 long t1 = MLogTick();
408 struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
409 XranStatusInt32 status;
410 /* half of RX for current TTI as measured against current OTA time */
411 int32_t rx_tti = (int32_t)XranGetTtiNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT);
413 if(p_xran_lib_ctx->xran2phy_mem_ready == 0)
416 if(p_xran_lib_ctx->rx_packet_callback_tracker[rx_tti % XRAN_N_FE_BUF_LEN][0] == 0){
417 status = (rx_tti << 16) | 0; /* base on PHY side implementation first 7 sym of slot */
418 if(p_xran_lib_ctx->pCallback[0])
419 p_xran_lib_ctx->pCallback[0](p_xran_lib_ctx->pCallbackTag[0], status);
421 p_xran_lib_ctx->rx_packet_callback_tracker[rx_tti % XRAN_N_FE_BUF_LEN][0] = 0;
423 MLogTask(PID_UP_UL_HALF_DEAD_LINE_CB, t1, MLogTick());
426 void rx_ul_deadline_full_cb(struct rte_timer *tim, void *arg)
428 long t1 = MLogTick();
429 struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
430 XranStatusInt32 status;
431 int32_t rx_tti = (int32_t)XranGetTtiNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT);
436 rx_tti -= 1; /* end of RX for prev TTI as measured against current OTA time */
438 if(p_xran_lib_ctx->xran2phy_mem_ready == 0)
441 if(p_xran_lib_ctx->rx_packet_callback_tracker[rx_tti % XRAN_N_FE_BUF_LEN][0] == 0){
442 status = (rx_tti << 16) | 7; /* last 7 sym means full slot of Symb */
443 if(p_xran_lib_ctx->pCallback[0])
444 p_xran_lib_ctx->pCallback[0](p_xran_lib_ctx->pCallbackTag[0], status);
446 p_xran_lib_ctx->rx_packet_callback_tracker[rx_tti % XRAN_N_FE_BUF_LEN][0] = 0;
449 MLogTask(PID_UP_UL_FULL_DEAD_LINE_CB, t1, MLogTick());
453 void tx_cp_ul_cb(struct rte_timer *tim, void *arg)
455 long t1 = MLogTick();
457 uint32_t frame_id = 0;
458 uint32_t subframe_id = 0;
459 uint32_t slot_id = 0;
462 int ant_id, prach_port_id;
464 uint8_t num_eAxc, num_CCPorts;
468 struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
469 xRANPrachCPConfigStruct *pPrachCPConfig = &(p_xran_lib_ctx->PrachCPConfig);
470 struct xran_timer_ctx *pTCtx = (struct xran_timer_ctx *)arg;
472 pHandle = NULL; // TODO: temp implemantation
473 num_eAxc = xran_get_num_eAxc(pHandle);
474 num_CCPorts = xran_get_num_cc(pHandle);
476 if (p_xran_lib_ctx->enableCP){
477 tti = pTCtx[(xran_lib_ota_tti & 1) ^ 1].tti_to_process;
478 slot_id = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME);
479 subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME, SUBFRAMES_PER_SYSTEMFRAME);
480 frame_id = XranGetFrameNum(tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
481 print_dbg("[%d]SFN %d sf %d slot %d\n", tti, frame_id, subframe_id, slot_id);
484 for(ant_id = 0; ant_id < num_eAxc; ++ant_id) {
485 for(cc_id = 0; cc_id < num_CCPorts; cc_id++ ) {
486 // start new section information list
487 xran_cp_reset_section_info(pHandle, XRAN_DIR_UL, cc_id, ant_id);
489 beam_id = xran_get_beamid(pHandle, XRAN_DIR_UL, cc_id, ant_id, slot_id);
490 send_cpmsg_dlul(pHandle, XRAN_DIR_UL,
491 frame_id, subframe_id, slot_id,
492 0, N_SYM_PER_SLOT, NUM_OF_PRB_IN_FULL_BAND,
493 beam_id, cc_id, ant_id,
494 xran_get_seqid(pHandle, XRAN_DIR_UL, cc_id, ant_id, slot_id));
498 if ((frame_id % pPrachCPConfig->x == pPrachCPConfig->y[0]) && (pPrachCPConfig->isPRACHslot[slot_id]==1)) //is prach slot
500 for(ant_id = 0; ant_id < num_eAxc; ant_id++) {
501 for(cc_id = 0; cc_id < num_CCPorts; cc_id++) {
502 #if !defined(PRACH_USES_SHARED_PORT)
503 prach_port_id = ant_id + num_eAxc;
504 // start new section information list
505 xran_cp_reset_section_info(pHandle, XRAN_DIR_UL, cc_id, prach_port_id);
507 prach_port_id = ant_id;
509 beam_id = xran_get_beamid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id, slot_id);
510 send_cpmsg_prach(pHandle,
511 frame_id, subframe_id, slot_id,
512 beam_id, cc_id, prach_port_id,
513 xran_get_seqid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id, slot_id));
519 MLogTask(PID_CP_UL_CB, t1, MLogTick());
522 void ul_up_full_slot_cb(struct rte_timer *tim, void *arg)
524 long t1 = MLogTick();
526 MLogTask(PID_TTI_CB_TO_PHY, t1, MLogTick());
529 void tti_to_phy_cb(struct rte_timer *tim, void *arg)
531 long t1 = MLogTick();
532 struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
534 static int first_call = 0;
535 p_xran_lib_ctx->phy_tti_cb_done = 1; /* DPDK called CB */
537 if(p_xran_lib_ctx->ttiCb[XRAN_CB_TTI]){
538 if(p_xran_lib_ctx->SkipTti[XRAN_CB_TTI] <= 0){
539 p_xran_lib_ctx->ttiCb[XRAN_CB_TTI](p_xran_lib_ctx->TtiCbParam[XRAN_CB_TTI]);
541 p_xran_lib_ctx->SkipTti[XRAN_CB_TTI]--;
545 if(p_xran_lib_ctx->ttiCb[XRAN_CB_TTI]){
546 int32_t tti = (int32_t)XranGetTtiNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT);
553 MLogTask(PID_TTI_CB_TO_PHY, t1, MLogTick());
556 int xran_timing_source_thread(void *args)
559 int32_t do_reset = 0;
563 uint32_t delay_cp_dl;
564 uint32_t delay_cp_ul;
566 uint32_t delay_up_ul;
567 uint32_t delay_cp2up;
572 struct sched_param sched_param;
573 struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
575 /* ToS = Top of Second start +- 1.5us */
580 printf("%s [CPU %2d] [PID: %6d]\n", __FUNCTION__, rte_lcore_id(), getpid());
582 /* set main thread affinity mask to CPU2 */
583 sched_param.sched_priority = 98;
586 CPU_SET(p_xran_lib_ctx->xran_init_cfg.io_cfg.timing_core, &cpuset);
587 if (result1 = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset))
589 printf("pthread_setaffinity_np failed: coreId = 2, result1 = %d\n",result1);
591 if ((result1 = pthread_setschedparam(pthread_self(), 1, &sched_param)))
593 printf("priority is not changed: coreId = 2, result1 = %d\n",result1);
596 if (p_xran_lib_ctx->xran_init_cfg.io_cfg.id == APP_LLS_CU) {
598 timespec_get(&ts, TIME_UTC);
599 }while (ts.tv_nsec >1500);
600 struct tm * ptm = gmtime(&ts.tv_sec);
602 strftime(buff, sizeof buff, "%D %T", ptm);
603 printf("lls-CU: thread_run start time: %s.%09ld UTC [%ld]\n", buff, ts.tv_nsec, interval_us);
606 delay_cp_dl = p_xran_lib_ctx->xran_init_cfg.ttiPeriod - p_xran_lib_ctx->xran_init_cfg.T1a_max_cp_dl;
607 delay_cp_ul = p_xran_lib_ctx->xran_init_cfg.ttiPeriod - p_xran_lib_ctx->xran_init_cfg.T1a_max_cp_ul;
608 delay_up = p_xran_lib_ctx->xran_init_cfg.T1a_max_up;
609 delay_up_ul = p_xran_lib_ctx->xran_init_cfg.Ta4_max;
611 delay_cp2up = delay_up-delay_cp_dl;
613 sym_cp_dl = delay_cp_dl*1000/(interval_us*1000/N_SYM_PER_SLOT)+1;
614 sym_cp_ul = delay_cp_ul*1000/(interval_us*1000/N_SYM_PER_SLOT)+1;
615 sym_up_ul = delay_up_ul*1000/(interval_us*1000/N_SYM_PER_SLOT);
616 p_xran_lib_ctx->sym_up = sym_up = -(delay_up*1000/(interval_us*1000/N_SYM_PER_SLOT)+1);
617 p_xran_lib_ctx->sym_up_ul = sym_up_ul = (delay_up_ul*1000/(interval_us*1000/N_SYM_PER_SLOT)+1);
619 printf("Start C-plane DL %d us after TTI [trigger on sym %d]\n", delay_cp_dl, sym_cp_dl);
620 printf("Start C-plane UL %d us after TTI [trigger on sym %d]\n", delay_cp_ul, sym_cp_ul);
621 printf("Start U-plane DL %d us before OTA [offset in sym %d]\n", delay_up, sym_up);
622 printf("Start U-plane UL %d us OTA [offset in sym %d]\n", delay_up_ul, sym_up_ul);
624 printf("C-plane to U-plane delay %d us after TTI\n", delay_cp2up);
625 printf("Start Sym timer %ld ns\n", TX_TIMER_INTERVAL/N_SYM_PER_SLOT);
627 p_xran_lib_ctx->pSymCallback[0][sym_cp_dl] = xran_timer_arm;
628 p_xran_lib_ctx->pSymCallbackTag[0][sym_cp_dl] = tx_cp_dl_cb;
630 p_xran_lib_ctx->pSymCallback[0][sym_cp_ul] = xran_timer_arm;
631 p_xran_lib_ctx->pSymCallbackTag[0][sym_cp_ul] = tx_cp_ul_cb;
633 /* Full slot UL OTA + delay_up_ul */
634 p_xran_lib_ctx->pSymCallback[0][sym_up_ul] = xran_timer_arm;
635 p_xran_lib_ctx->pSymCallbackTag[0][sym_up_ul] = rx_ul_deadline_full_cb;
637 /* Half slot UL OTA + delay_up_ul*/
638 p_xran_lib_ctx->pSymCallback[0][sym_up_ul + N_SYM_PER_SLOT/2] = xran_timer_arm;
639 p_xran_lib_ctx->pSymCallbackTag[0][sym_up_ul + N_SYM_PER_SLOT/2] = rx_ul_deadline_half_cb;
642 /* calcualte when to send UL U-plane */
643 delay_up = p_xran_lib_ctx->xran_init_cfg.Ta3_min;
644 p_xran_lib_ctx->sym_up = sym_up = delay_up*1000/(interval_us*1000/N_SYM_PER_SLOT)+1;
645 printf("Start UL U-plane %d us after OTA [offset in sym %d]\n", delay_up, sym_up);
647 timespec_get(&ts, TIME_UTC);
648 }while (ts.tv_nsec >1500);
649 struct tm * ptm = gmtime(&ts.tv_sec);
651 strftime(buff, sizeof buff, "%D %T", ptm);
652 printf("RU: thread_run start time: %s.%09ld UTC [%ld]\n", buff, ts.tv_nsec, interval_us);
657 timespec_get(&ts, TIME_UTC);
658 }while (ts.tv_nsec == 0);
661 delta = poll_next_tick(interval_us*1000L/N_SYM_PER_SLOT);
662 if (XRAN_STOPPED == xran_if_current_state)
664 sym_ota_cb(&sym_timer, timer_ctx);
666 printf("Closing timing source thread...\n");
671 /* Handle ecpri format. */
672 int handle_ecpri_ethertype(struct rte_mbuf *pkt, uint64_t rx_time)
674 const struct xran_ecpri_hdr *ecpri_hdr;
677 if (rte_pktmbuf_data_len(pkt) < sizeof(struct xran_ecpri_hdr)) {
678 wlog("Packet too short - %d bytes", rte_pktmbuf_data_len(pkt));
682 /* check eCPRI header. */
683 ecpri_hdr = rte_pktmbuf_mtod(pkt, struct xran_ecpri_hdr *);
684 if(ecpri_hdr == NULL)
687 switch(ecpri_hdr->ecpri_mesg_type) {
691 MLogTask(PID_PROCESS_UP_PKT, t1, MLogTick());
694 case ECPRI_RT_CONTROL_DATA:
696 if(xran_lib_get_ctx()->xran_init_cfg.io_cfg.id == APP_RU) {
699 print_err("LLS-CU recevied CP message!");
701 MLogTask(PID_PROCESS_CP_PKT, t1, MLogTick());
704 wlog("Invalid eCPRI message type - %d", ecpri_hdr->ecpri_mesg_type);
714 int xran_process_rx_sym(void *arg,
725 struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
727 XranStatusInt32 status;
728 void *pHandle = NULL;
730 if(p_xran_lib_ctx->xran2phy_mem_ready == 0)
733 tti = frame_id * SLOTS_PER_SYSTEMFRAME + subframe_id * SLOTNUM_PER_SUBFRAME + slot_id;
735 status = tti << 16 | symb_id;
737 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){
738 pos = (char*) p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pData;
739 if(pos && iq_data_start && size){
740 #ifdef XRAN_BYTE_ORDER_SWAP
742 uint16_t *restrict psrc = (uint16_t *)iq_data_start;
743 uint16_t *restrict pdst = (uint16_t *)pos;
744 /* network byte (be) order of IQ to CPU byte order (le) */
745 for (idx = 0; idx < size/sizeof(int16_t); idx++){
746 pdst[idx] = (psrc[idx]>>8) | (psrc[idx]<<8); //rte_be_to_cpu_16(psrc[idx]);
749 #error xran spec is network byte order
751 rte_memcpy(pdst, psrc, size);
753 #ifdef DEBUG_XRAN_BUFFERS
754 if (pos[0] != tti % XRAN_N_FE_BUF_LEN ||
758 printf("%d %d %d %d\n", pos[0], pos[1], pos[2], pos[3]);
762 print_err("pos %p iq_data_start %p size %d\n",pos, iq_data_start, size);
765 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);
767 if (symb_id == 7 || symb_id == 13){
768 p_xran_lib_ctx->rx_packet_symb_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID][symb_id]++;
770 if(p_xran_lib_ctx->rx_packet_symb_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID][symb_id] >= xran_get_num_eAxc(pHandle)){
771 if(p_xran_lib_ctx->pCallback[0])
772 p_xran_lib_ctx->pCallback[0](p_xran_lib_ctx->pCallbackTag[0], status);
773 p_xran_lib_ctx->rx_packet_callback_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID] = 1;
774 p_xran_lib_ctx->rx_packet_symb_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID][symb_id] = 0;
781 int xran_process_tx_sym(void *arg)
784 uint32_t mlogVar[10];
785 uint32_t mlogVarCnt = 0;
786 unsigned long t1 = MLogTick();
788 void *pHandle = NULL;
791 uint8_t num_eAxc = 0;
792 uint8_t num_CCPorts = 0;
794 uint32_t frame_id = 0;
795 uint32_t subframe_id = 0;
796 uint32_t slot_id = 0;
798 uint32_t sym_idx = 0;
803 struct xran_section_info *sectinfo;
806 enum xran_pkt_dir direction;
808 struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
809 struct xran_timer_ctx *pTCtx = (struct xran_timer_ctx *)arg;
812 if(p_xran_lib_ctx->xran2phy_mem_ready == 0)
815 if(p_xran_lib_ctx->xran_init_cfg.io_cfg.id == APP_LLS_CU) {
816 direction = XRAN_DIR_DL; /* lls-CU */
817 prb_num = NUM_OF_PRB_IN_FULL_BAND;
820 direction = XRAN_DIR_UL; /* RU */
821 prb_num = NUM_OF_PRB_IN_FULL_BAND; /*TODO: simulation on D-1541 @ 2.10GHz has issue with performace. reduce copy size */
824 /* RU: send symb after OTA time with delay (UL) */
825 /* lls-CU:send symb in advance of OTA time (DL) */
826 sym_idx = XranOffsetSym(p_xran_lib_ctx->sym_up, xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT*SLOTNUM_PER_SUBFRAME*1000);
828 tti = XranGetTtiNum(sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT);
829 slot_id = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME);
830 subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME, SUBFRAMES_PER_SYSTEMFRAME);
831 frame_id = XranGetFrameNum(tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
832 sym_id = XranGetSymNum(sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT);
834 print_dbg("[%d]SFN %d sf %d slot %d\n", tti, frame_id, subframe_id, slot_id);
836 mlogVar[mlogVarCnt++] = 0xAAAAAAAA;
837 mlogVar[mlogVarCnt++] = xran_lib_ota_sym_idx;
838 mlogVar[mlogVarCnt++] = sym_idx;
839 mlogVar[mlogVarCnt++] = abs(p_xran_lib_ctx->sym_up);
840 mlogVar[mlogVarCnt++] = tti;
841 mlogVar[mlogVarCnt++] = frame_id;
842 mlogVar[mlogVarCnt++] = subframe_id;
843 mlogVar[mlogVarCnt++] = slot_id;
844 mlogVar[mlogVarCnt++] = sym_id;
845 MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
848 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);
849 xran_if_current_state =XRAN_STOPPED;
852 num_eAxc = xran_get_num_eAxc(pHandle);
853 num_CCPorts = xran_get_num_cc(pHandle);
856 for(ant_id = 0; ant_id < num_eAxc; ant_id++) {
857 for(cc_id = 0; cc_id < num_CCPorts; cc_id++) {
858 if(p_xran_lib_ctx->xran_init_cfg.io_cfg.id == APP_LLS_CU && p_xran_lib_ctx->enableCP) {
860 while(next < xran_cp_getsize_section_info(pHandle, direction, cc_id, ant_id)) {
861 sectinfo = xran_cp_iterate_section_info(pHandle, direction,
862 cc_id, ant_id, subframe_id, slot_id, &next);
866 /* pointer to IQs input */
867 /* TODO: need to implement the case of partial RB assignment */
868 pos = (char*) p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
869 print_dbg(">>> [%d] type%d, id %d, startPrbc=%d, numPrbc=%d, numSymbol=%d\n", next,
870 sectinfo->type, sectinfo->id, sectinfo->startPrbc,
871 sectinfo->numPrbc, sectinfo->numSymbol);
873 if(sectinfo->type != XRAN_CP_SECTIONTYPE_1) {
874 print_err("Invalid section type in section DB - %d", sectinfo->type);
878 send_symbol_ex(direction, sectinfo->id,
879 (struct rb_map *)pos,
880 frame_id, subframe_id, slot_id, sym_id,
881 sectinfo->startPrbc, sectinfo->numPrbc,
883 xran_get_seqid(pHandle, direction, cc_id, ant_id, slot_id));
887 else { /* if(p_xran_lib_ctx->xran_init_cfg.io_cfg.id == APP_LLS_CU && p_xran_lib_ctx->enableCP) */
888 /* pointer to IQs input */
889 pos = (char*) p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
890 #ifdef DEBUG_XRAN_BUFFERS
891 if (pos[0] != tti % XRAN_N_FE_BUF_LEN ||
895 printf("%d %d %d %d\n", pos[0], pos[1], pos[2], pos[3]);
897 send_symbol_ex(direction,
898 xran_alloc_sectionid(pHandle, direction, cc_id, ant_id, slot_id),
899 (struct rb_map *)pos,
900 frame_id, subframe_id, slot_id, sym_id,
903 xran_get_seqid(pHandle, direction, cc_id, ant_id, slot_id));
908 MLogTask(PID_PROCESS_TX_SYM, t1, MLogTick());
912 int xran_packet_and_dpdk_timer_thread(void *args)
914 struct xran_ethdi_ctx *const ctx = xran_ethdi_get_ctx();
916 uint64_t prev_tsc = 0;
917 uint64_t cur_tsc = rte_rdtsc();
918 uint64_t diff_tsc = cur_tsc - prev_tsc;
920 struct sched_param sched_param;
922 printf("%s [CPU %2d] [PID: %6d]\n", __FUNCTION__, rte_lcore_id(), getpid());
924 sched_param.sched_priority = XRAN_THREAD_DEFAULT_PRIO;
926 if ((res = pthread_setschedparam(pthread_self(), 1, &sched_param)))
928 printf("priority is not changed: coreId = %d, result1 = %d\n",rte_lcore_id(), res);
933 cur_tsc = rte_rdtsc();
934 diff_tsc = cur_tsc - prev_tsc;
935 if (diff_tsc > TIMER_RESOLUTION_CYCLES) {
940 if (XRAN_STOPPED == xran_if_current_state)
944 printf("Closing pkts timer thread...\n");
949 int32_t xran_init(int argc, char *argv[], PXRANFHINIT p_xran_fh_init, char *appName, void ** pHandle)
954 struct xran_io_loop_cfg *p_io_cfg = (struct xran_io_loop_cfg *)&p_xran_fh_init->io_cfg;
955 struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
960 memset(p_xran_lib_ctx, 0, sizeof(struct xran_lib_ctx));
962 p_xran_lib_ctx->xran_init_cfg = *p_xran_fh_init;
964 xran_if_current_state = XRAN_RUNNING;
965 interval_us = p_xran_fh_init->ttiPeriod;
967 p_xran_lib_ctx->llscu_id = p_xran_fh_init->llscuId;
968 memcpy(&(p_xran_lib_ctx->eAxc_id_cfg), &(p_xran_fh_init->eAxCId_conf), sizeof(XRANEAXCIDCONFIG));
970 p_xran_lib_ctx->enableCP = p_xran_fh_init->enableCP;
972 xran_register_ethertype_handler(ETHER_TYPE_ECPRI, handle_ecpri_ethertype);
973 if (p_io_cfg->id == 0)
974 xran_ethdi_init_dpdk_io(basename(appName),
977 (struct ether_addr *)p_xran_fh_init->p_lls_cu_addr,
978 (struct ether_addr *)p_xran_fh_init->p_ru_addr,
979 p_xran_fh_init->cp_vlan_tag,
980 p_xran_fh_init->up_vlan_tag);
982 xran_ethdi_init_dpdk_io(basename(appName),
985 (struct ether_addr *)p_xran_fh_init->p_ru_addr,
986 (struct ether_addr *)p_xran_fh_init->p_lls_cu_addr,
987 p_xran_fh_init->cp_vlan_tag,
988 p_xran_fh_init->up_vlan_tag);
990 for(i = 0; i < 10; i++ )
991 rte_timer_init(&tti_to_phy_timer[i]);
993 rte_timer_init(&tti_timer);
994 rte_timer_init(&sym_timer);
995 rte_timer_init(&tx_cp_dl_timer);
996 rte_timer_init(&tx_cp_ul_timer);
997 rte_timer_init(&tx_up_timer);
999 for(i = 0; i < XRAN_MAX_SECTOR_NR; i++ ){
1000 unsigned n = snprintf(&p_xran_lib_ctx->ring_name[0][i][0], RTE_RING_NAMESIZE, "dl_sym_ring_%u", i);
1001 p_xran_lib_ctx->dl_sym_idx_ring[i] = rte_ring_create(&p_xran_lib_ctx->ring_name[0][i][0], XRAN_RING_SIZE,
1002 rte_lcore_to_socket_id(lcore_id), RING_F_SP_ENQ | RING_F_SC_DEQ);
1006 lcore_id = rte_get_next_lcore(lcore_id, 0, 0);
1007 PANIC_ON(lcore_id == RTE_MAX_LCORE, "out of lcores for io_loop()");
1009 /* Start packet processing thread */
1010 if (rte_eal_remote_launch(ring_processing_thread, NULL, lcore_id))
1011 rte_panic("ring_processing_thread() failed to start\n");
1013 if(p_io_cfg->pkt_aux_core > 0){
1014 lcore_id = rte_get_next_lcore(lcore_id, 0, 0);
1015 PANIC_ON(lcore_id == RTE_MAX_LCORE, "out of lcores for io_loop()");
1017 /* Start packet processing thread */
1018 if (rte_eal_remote_launch(xran_packet_and_dpdk_timer_thread, NULL, lcore_id))
1019 rte_panic("ring_processing_thread() failed to start\n");
1022 lcore_id = rte_get_next_lcore(lcore_id, 0, 0);
1023 PANIC_ON(lcore_id == RTE_MAX_LCORE, "out of lcores for io_loop()");
1025 /* Start packet processing thread */
1026 if (rte_eal_remote_launch(xran_timing_source_thread, xran_lib_get_ctx(), lcore_id))
1027 rte_panic("thread_run() failed to start\n");
1029 printf("Set debug stop %d\n", p_xran_fh_init->debugStop);
1030 timing_set_debug_stop(p_xran_fh_init->debugStop);
1032 memset(&DevHandle, 0, sizeof(XranLibHandleInfoStruct));
1034 *pHandle = &DevHandle;
1039 int32_t xran_sector_get_instances (void * pHandle, uint16_t nNumInstances,
1040 XranCcInstanceHandleVoidP * pSectorInstanceHandles)
1044 /* only one handle as only one CC is currently supported */
1045 for(i = 0; i < nNumInstances; i++ )
1046 pSectorInstanceHandles[i] = pHandle;
1051 int32_t xran_mm_init (void * pHandle, uint64_t nMemorySize,
1052 uint32_t nMemorySegmentSize)
1054 /* we use mbuf from dpdk memory */
1058 int32_t xran_bm_init (void * pHandle, uint32_t * pPoolIndex, uint32_t nNumberOfBuffers, uint32_t nBufferSize)
1060 XranLibHandleInfoStruct* pXran = (XranLibHandleInfoStruct*) pHandle;
1062 char pool_name[RTE_MEMPOOL_NAMESIZE];
1064 snprintf(pool_name, RTE_MEMPOOL_NAMESIZE, "bm_mempool_%ld", pPoolIndex);
1066 pXran->p_bufferPool[pXran->nBufferPoolIndex] = rte_pktmbuf_pool_create(pool_name, nNumberOfBuffers,
1067 MBUF_CACHE, 0, XRAN_MAX_MBUF_LEN, rte_socket_id());
1069 pXran->bufferPoolElmSz[pXran->nBufferPoolIndex] = nBufferSize;
1070 pXran->bufferPoolNumElm[pXran->nBufferPoolIndex] = nNumberOfBuffers;
1072 print_dbg("[nPoolIndex %d] mb pool %p \n", pXran->nBufferPoolIndex, pXran->p_bufferPool[pXran->nBufferPoolIndex]);
1074 *pPoolIndex = pXran->nBufferPoolIndex++;
1079 int32_t xran_bm_allocate_buffer(void * pHandle, uint32_t nPoolIndex, void **ppVirtAddr)
1081 XranLibHandleInfoStruct* pXran = (XranLibHandleInfoStruct*) pHandle;
1084 struct rte_mbuf * mb = rte_pktmbuf_alloc(pXran->p_bufferPool[nPoolIndex]);
1087 *ppVirtAddr = rte_pktmbuf_append(mb, pXran->bufferPoolElmSz[nPoolIndex]);
1090 print_err("[nPoolIndex %d] mb alloc failed \n", nPoolIndex );
1094 if (*ppVirtAddr == NULL){
1095 print_err("[nPoolIndex %d] rte_pktmbuf_append for %d failed \n", nPoolIndex, pXran->bufferPoolElmSz[nPoolIndex]);
1102 int32_t xran_bm_free_buffer(void * pHandle, void *pVirtAddr)
1104 XranLibHandleInfoStruct* pXran = (XranLibHandleInfoStruct*) pHandle;
1105 rte_pktmbuf_free(pVirtAddr);
1110 int32_t xran_5g_fronthault_config (void * pHandle,
1111 XRANBufferListStruct *pSrcBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
1112 XRANBufferListStruct *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
1113 XranTransportBlockCallbackFn pCallback,
1116 XranLibHandleInfoStruct *pInfo = (XranLibHandleInfoStruct *) pHandle;
1117 XranStatusInt32 nStatus = XRAN_STATUS_SUCCESS;
1119 struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
1121 print_dbg("%s\n", __FUNCTION__);
1125 printf("Handle is NULL!\n");
1126 return XRAN_STATUS_FAIL;
1128 if (pCallback == NULL)
1130 printf ("no callback\n");
1131 return XRAN_STATUS_FAIL;
1134 for(j=0; j<XRAN_N_FE_BUF_LEN; j++)
1136 for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
1137 p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].bValid = 0;
1138 p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
1139 p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
1140 p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
1141 p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
1142 p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_lib_ctx->sFrontHaulTxBuffers[j][i][z][0];
1144 p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList = *pSrcBuffer[z][j];
1146 p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].bValid = 0;
1147 p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
1148 p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
1149 p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
1150 p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
1151 p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_lib_ctx->sFrontHaulRxBuffers[j][i][z][0];
1152 p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList = *pDstBuffer[z][j];
1157 for(j=0; j<XRAN_N_FE_BUF_LEN; j++)
1158 for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
1159 printf("TTI:TX 0x%02x Sec %d Ant%d\n",j,i,z);
1160 for(k = 0; k <XRAN_NUM_OF_SYMBOL_PER_SLOT; k++){
1161 uint8_t *ptr = p_xran_lib_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData;
1162 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]);
1166 for(j=0; j<XRAN_N_FE_BUF_LEN; j++)
1167 for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
1168 printf("TTI:RX 0x%02x Sec %d Ant%d\n",j,i,z);
1169 for(k = 0; k <XRAN_NUM_OF_SYMBOL_PER_SLOT; k++){
1170 uint8_t *ptr = p_xran_lib_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData;
1171 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]);
1176 p_xran_lib_ctx->pCallback[i] = pCallback;
1177 p_xran_lib_ctx->pCallbackTag[i] = pCallbackTag;
1179 p_xran_lib_ctx->xran2phy_mem_ready = 1;
1184 int32_t xran_5g_prach_req (void * pHandle,
1185 XRANBufferListStruct *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
1186 XranTransportBlockCallbackFn pCallback,
1189 XranLibHandleInfoStruct *pInfo = (XranLibHandleInfoStruct *) pHandle;
1190 XranStatusInt32 nStatus = XRAN_STATUS_SUCCESS;
1192 struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
1196 printf("Handle is NULL!\n");
1197 return XRAN_STATUS_FAIL;
1199 if (pCallback == NULL)
1201 printf ("no callback\n");
1202 return XRAN_STATUS_FAIL;
1205 for(j=0; j<XRAN_N_FE_BUF_LEN; j++)
1207 for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
1208 p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].bValid = 0;
1209 p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
1210 p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
1211 p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
1212 p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_MAX_ANTENNA_NR; // ant number.
1213 p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_lib_ctx->sFHPrachRxBuffers[j][i][z][0];
1214 p_xran_lib_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList = *pDstBuffer[z][j];
1218 p_xran_lib_ctx->pPrachCallback[i] = pCallback;
1219 p_xran_lib_ctx->pPrachCallbackTag[i] = pCallbackTag;
1224 int32_t xran_5g_pre_compenstor_cfg(void* pHandle,
1225 uint32_t nTxPhaseCps,
1226 uint32_t nRxPhaseCps,
1229 /* functionality is not yet implemented */
1233 int32_t xran_open(void *pHandle, PXRANFHCONFIG pConf)
1237 XRANFHCONFIG *pFhCfg;
1238 xRANPrachCPConfigStruct *pPrachCPConfig = &(xran_lib_get_ctx()->PrachCPConfig);
1239 pFhCfg = &(xran_lib_get_ctx()->xran_fh_cfg);
1240 memcpy(pFhCfg, pConf, sizeof(XRANFHCONFIG));
1241 PXRANPRACHCONFIG pPRACHConfig = &pFhCfg->prach_conf;
1242 uint8_t nPrachConfIdx = pPRACHConfig->nPrachConfIdx;
1243 const xRANPrachConfigTableStruct *pxRANPrachConfigTable = &gxranPrachDataTable_mmw[nPrachConfIdx];
1244 uint8_t preambleFmrt = pxRANPrachConfigTable->preambleFmrt[0];
1245 const xRANPrachPreambleLRAStruct *pxranPreambleforLRA = &gxranPreambleforLRA[preambleFmrt - FORMAT_A1];
1246 memset(pPrachCPConfig, 0, sizeof(xRANPrachCPConfigStruct));
1248 //setup PRACH configuration for C-Plane
1249 pPrachCPConfig->filterIdx = XRAN_FILTERINDEX_PRACH_ABC; // 3, PRACH preamble format A1~3, B1~4, C0, C2
1250 pPrachCPConfig->startSymId = pxRANPrachConfigTable->startingSym;
1251 pPrachCPConfig->startPrbc = pPRACHConfig->nPrachFreqStart;
1252 pPrachCPConfig->numPrbc = (preambleFmrt >= FORMAT_A1)? 12 : 70;
1253 pPrachCPConfig->numSymbol = pxRANPrachConfigTable->duration;
1254 pPrachCPConfig->timeOffset = pxranPreambleforLRA->nRaCp;
1255 pPrachCPConfig->freqOffset = xran_get_freqoffset(pPRACHConfig->nPrachFreqOffset, pPRACHConfig->nPrachSubcSpacing);
1256 pPrachCPConfig->occassionsInPrachSlot = pxRANPrachConfigTable->occassionsInPrachSlot;
1257 pPrachCPConfig->x = pxRANPrachConfigTable->x;
1258 pPrachCPConfig->y[0] = pxRANPrachConfigTable->y[0];
1259 pPrachCPConfig->y[1] = pxRANPrachConfigTable->y[1];
1261 pPrachCPConfig->isPRACHslot[pxRANPrachConfigTable->slotNr[0]] = 1;
1262 for (i=1; i < XRAN_PRACH_CANDIDATE_SLOT; i++)
1264 slotNr = pxRANPrachConfigTable->slotNr[i];
1266 pPrachCPConfig->isPRACHslot[slotNr] = 1;
1269 xran_cp_init_sectiondb(pHandle);
1270 xran_init_sectionid(pHandle);
1271 xran_init_seqid(pHandle);
1276 int32_t xran_start(void *pHandle)
1278 xran_if_current_state = XRAN_RUNNING;
1282 int32_t xran_stop(void *pHandle)
1284 xran_if_current_state = XRAN_STOPPED;
1288 int32_t xran_close(void *pHandle)
1290 xran_if_current_state = XRAN_STOPPED;
1291 xran_cp_free_sectiondb(pHandle);
1292 rte_eal_mp_wait_lcore();
1296 int32_t xran_mm_destroy (void * pHandle)
1298 /* functionality is not yet implemented */
1302 int32_t xran_reg_sym_cb(void *pHandle, XRANFHSYMPROCCB symCb, void * symCbParam, uint8_t symb, uint8_t ant)
1304 /* functionality is not yet implemented */
1308 int32_t xran_reg_physide_cb(void *pHandle, XRANFHTTIPROCCB Cb, void *cbParam, int skipTtiNum, enum callback_to_phy_id id)
1310 struct xran_lib_ctx * p_xran_lib_ctx = xran_lib_get_ctx();
1312 p_xran_lib_ctx->ttiCb[id] = Cb;
1313 p_xran_lib_ctx->TtiCbParam[id] = cbParam;
1314 p_xran_lib_ctx->SkipTti[id] = skipTtiNum;
1319 int32_t xran_get_slot_idx (uint32_t *nFrameIdx, uint32_t *nSubframeIdx, uint32_t *nSlotIdx, uint64_t *nSecond)
1323 tti = (int32_t)XranGetTtiNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT);
1324 *nSlotIdx = (uint32_t)XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME);
1325 *nSubframeIdx = (uint32_t)XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME, SUBFRAMES_PER_SYSTEMFRAME);
1326 *nFrameIdx = (uint32_t)XranGetFrameNum(tti,SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
1327 *nSecond = timing_get_current_second();
1333 * @brief Get supported maximum number of sections
1335 * @return maximum number of sections
1337 inline uint8_t xran_get_max_sections(void *pHandle)
1339 return (XRAN_MAX_NUM_SECTIONS);
1343 * @brief Get the configuration of eAxC ID
1345 * @return the pointer of configuration
1347 inline XRANEAXCIDCONFIG *xran_get_conf_eAxC(void *pHandle)
1349 return (&(xran_lib_get_ctx()->eAxc_id_cfg));
1353 * @brief Get the configuration of subcarrier spacing for PRACH
1355 * @return subcarrier spacing value for PRACH
1357 inline uint8_t xran_get_conf_prach_scs(void *pHandle)
1359 return (xran_lib_get_ctx_fhcfg()->prach_conf.nPrachSubcSpacing);
1363 * @brief Get the configuration of FFT size for RU
1365 * @return FFT size value for RU
1367 inline uint8_t xran_get_conf_fftsize(void *pHandle)
1369 return (xran_lib_get_ctx_fhcfg()->ru_conf.fftSize);
1373 * @brief Get the configuration of nummerology
1375 * @return subcarrier spacing value for PRACH
1377 inline uint8_t xran_get_conf_numerology(void *pHandle)
1379 return (xran_lib_get_ctx_fhcfg()->frame_conf.nNumerology);
1383 * @brief Get the configuration of IQ bit width for RU
1385 * @return IQ bit width for RU
1387 inline uint8_t xran_get_conf_iqwidth(void *pHandle)
1389 XRANFHCONFIG *pFhCfg;
1391 pFhCfg = xran_lib_get_ctx_fhcfg();
1392 return ((pFhCfg->ru_conf.iqWidth==16)?0:pFhCfg->ru_conf.iqWidth);
1396 * @brief Get the configuration of compression method for RU
1398 * @return Compression method for RU
1400 inline uint8_t xran_get_conf_compmethod(void *pHandle)
1402 return (xran_lib_get_ctx_fhcfg()->ru_conf.compMeth);
1406 * @brief Get the configuration of lls-cu ID
1408 * @return Configured lls-cu ID
1410 inline uint8_t xran_get_llscuid(void *pHandle)
1412 return (xran_lib_get_ctx()->llscu_id);
1416 * @brief Get the configuration of lls-cu ID
1418 * @return Configured lls-cu ID
1420 inline uint8_t xran_get_sectorid(void *pHandle)
1422 return (xran_lib_get_ctx()->sector_id);
1426 * @brief Get the configuration of the number of component carriers
1428 * @return Configured the number of componen carriers
1430 inline uint8_t xran_get_num_cc(void *pHandle)
1432 return (xran_lib_get_ctx_fhcfg()->nCC);
1436 * @brief Get the configuration of the number of antenna
1438 * @return Configured the number of antenna
1440 inline uint8_t xran_get_num_eAxc(void *pHandle)
1442 return (xran_lib_get_ctx_fhcfg()->neAxc);