8a2fbbf2b41492c28a588f08067009b2059e49b7
[o-du/phy.git] / fhi_lib / lib / src / xran_main.c
1 /******************************************************************************
2 *
3 *   Copyright (c) 2019 Intel.
4 *
5 *   Licensed under the Apache License, Version 2.0 (the "License");
6 *   you may not use this file except in compliance with the License.
7 *   You may obtain a copy of the License at
8 *
9 *       http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *   Unless required by applicable law or agreed to in writing, software
12 *   distributed under the License is distributed on an "AS IS" BASIS,
13 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *   See the License for the specific language governing permissions and
15 *   limitations under the License.
16 *
17 *******************************************************************************/
18
19 /**
20  * @brief XRAN main functionality module
21  * @file xran_main.c
22  * @ingroup group_source_xran
23  * @author Intel Corporation
24  **/
25
26 #define _GNU_SOURCE
27 #include <sched.h>
28 #include <assert.h>
29 #include <err.h>
30 #include <libgen.h>
31 #include <sys/time.h>
32 #include <sys/queue.h>
33 #include <time.h>
34 #include <unistd.h>
35 #include <stdio.h>
36 #include <pthread.h>
37 #include <malloc.h>
38
39 #include <rte_common.h>
40 #include <rte_eal.h>
41 #include <rte_errno.h>
42 #include <rte_lcore.h>
43 #include <rte_cycles.h>
44 #include <rte_memory.h>
45 #include <rte_memzone.h>
46 #include <rte_mbuf.h>
47 #include <rte_ring.h>
48
49 #include "xran_fh_o_du.h"
50
51 #include "ethdi.h"
52 #include "xran_pkt.h"
53 #include "xran_up_api.h"
54 #include "xran_cp_api.h"
55 #include "xran_sync_api.h"
56 #include "xran_lib_mlog_tasks_id.h"
57 #include "xran_timer.h"
58 #include "xran_common.h"
59 #include "xran_frame_struct.h"
60 #include "xran_printf.h"
61 #include "xran_app_frag.h"
62
63 #include "xran_mlog_lnx.h"
64
65 #define DIV_ROUND_OFFSET(X,Y) ( X/Y + ((X%Y)?1:0) )
66
67 #define XranOffsetSym(offSym, otaSym, numSymTotal)  (((int32_t)offSym > (int32_t)otaSym) ? \
68                             ((int32_t)otaSym + ((int32_t)numSymTotal) - (uint32_t)offSym) : \
69                             (((int32_t)otaSym - (int32_t)offSym) >= numSymTotal) ?  \
70                                     (((int32_t)otaSym - (int32_t)offSym) - numSymTotal) : \
71                                     ((int32_t)otaSym - (int32_t)offSym))
72
73 #define MAX_NUM_OF_XRAN_CTX          (2)
74 #define XranIncrementCtx(ctx)                             ((ctx >= (MAX_NUM_OF_XRAN_CTX-1)) ? 0 : (ctx+1))
75 #define XranDecrementCtx(ctx)                             ((ctx == 0) ? (MAX_NUM_OF_XRAN_CTX-1) : (ctx-1))
76
77 #define MAX_NUM_OF_DPDK_TIMERS       (10)
78 #define DpdkTimerIncrementCtx(ctx)           ((ctx >= (MAX_NUM_OF_DPDK_TIMERS-1)) ? 0 : (ctx+1))
79 #define DpdkTimerDecrementCtx(ctx)           ((ctx == 0) ? (MAX_NUM_OF_DPDK_TIMERS-1) : (ctx-1))
80
81 /* Difference between Unix seconds to GPS seconds
82    GPS epoch: 1980.1.6 00:00:00 (UTC); Unix time epoch: 1970:1.1 00:00:00 UTC
83    Value is calculated on Sep.6 2019. Need to be change if International
84    Earth Rotation and Reference Systems Service (IERS) adds more leap seconds
85    1970:1.1 - 1980.1.6: 3657 days
86    3657*24*3600=315 964 800 seconds (unix seconds value at 1980.1.6 00:00:00 (UTC))
87    There are 18 leap seconds inserted after 1980.1.6 00:00:00 (UTC), which means
88    GPS is 18 larger. 315 964 800 - 18 = 315 964 782
89 */
90 #define UNIX_TO_GPS_SECONDS_OFFSET 315964782UL
91 #define NUM_OF_FRAMES_PER_SECOND 100
92
93 //#define XRAN_CREATE_RBMAP /**< generate slot map base on symbols */
94
95
96 struct xran_timer_ctx {
97     uint32_t    tti_to_process;
98 };
99
100 static xran_cc_handle_t pLibInstanceHandles[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR] = {NULL};
101 static struct xran_device_ctx g_xran_dev_ctx[XRAN_PORTS_NUM] = { 0 };
102
103 struct xran_timer_ctx timer_ctx[MAX_NUM_OF_XRAN_CTX];
104
105 static struct rte_timer tti_to_phy_timer[10];
106 static struct rte_timer sym_timer;
107 static struct rte_timer dpdk_timer[MAX_NUM_OF_DPDK_TIMERS];
108
109 uint64_t interval_us = 1000;
110
111 uint32_t xran_lib_ota_tti        = 0; /**< Slot index in a second [0:(1000000/TTI-1)] */
112 uint32_t xran_lib_ota_sym        = 0; /**< Symbol index in a slot [0:13] */
113 uint32_t xran_lib_ota_sym_idx    = 0; /**< Symbol index in a second [0 : 14*(1000000/TTI)-1]
114                                                 where TTI is TTI interval in microseconds */
115 uint16_t xran_SFN_at_Sec_Start   = 0; /**< SFN at current second start */
116 uint16_t xran_max_frame          = 1023; /**< value of max frame used. expected to be 99 (old compatibility mode) and 1023 as per section 9.7.2 System Frame Number Calculation */
117
118 static uint8_t xran_cp_seq_id_num[XRAN_MAX_CELLS_PER_PORT][XRAN_DIR_MAX][XRAN_MAX_ANTENNA_NR * 2 + XRAN_MAX_ANT_ARRAY_ELM_NR]; /* XRAN_MAX_ANTENNA_NR * 2 for PUSCH and PRACH */
119 static uint8_t xran_updl_seq_id_num[XRAN_MAX_CELLS_PER_PORT][XRAN_MAX_ANTENNA_NR];
120 static uint8_t xran_upul_seq_id_num[XRAN_MAX_CELLS_PER_PORT][XRAN_MAX_ANTENNA_NR * 2 + XRAN_MAX_ANT_ARRAY_ELM_NR]; /**< PUSCH, PRACH, SRS for Cat B */
121
122 static uint8_t xran_section_id_curslot[XRAN_DIR_MAX][XRAN_MAX_CELLS_PER_PORT][XRAN_MAX_ANTENNA_NR * 2+ XRAN_MAX_ANT_ARRAY_ELM_NR];
123 static uint16_t xran_section_id[XRAN_DIR_MAX][XRAN_MAX_CELLS_PER_PORT][XRAN_MAX_ANTENNA_NR * 2+ XRAN_MAX_ANT_ARRAY_ELM_NR];
124 static uint64_t xran_total_tick = 0, xran_used_tick = 0;
125 static uint32_t xran_core_used = 0;
126 static int32_t first_call = 0;
127
128
129 static void
130 extbuf_free_callback(void *addr __rte_unused, void *opaque __rte_unused)
131 {
132 }
133
134 static struct rte_mbuf_ext_shared_info share_data[XRAN_N_FE_BUF_LEN];
135
136 void xran_timer_arm(struct rte_timer *tim, void* arg);
137
138 int32_t xran_process_tx_sym(void *arg);
139
140 int32_t xran_process_rx_sym(void *arg,
141                         struct rte_mbuf *mbuf,
142                         void *iq_data_start,
143                         uint16_t size,
144                         uint8_t CC_ID,
145                         uint8_t Ant_ID,
146                         uint8_t frame_id,
147                         uint8_t subframe_id,
148                         uint8_t slot_id,
149                         uint8_t symb_id,
150                         uint16_t num_prbu,
151                         uint16_t start_prbu,
152                         uint16_t sym_inc,
153                         uint16_t rb,
154                         uint16_t sect_id,
155                         uint32_t *mb_free);
156
157 int32_t xran_process_prach_sym(void *arg,
158                         struct rte_mbuf *mbuf,
159                         void *iq_data_start,
160                         uint16_t size,
161                         uint8_t CC_ID,
162                         uint8_t Ant_ID,
163                         uint8_t frame_id,
164                         uint8_t subframe_id,
165                         uint8_t slot_id,
166                         uint8_t symb_id,
167                         uint16_t num_prbu,
168                         uint16_t start_prbu,
169                         uint16_t sym_inc,
170                         uint16_t rb,
171                         uint16_t sect_id,
172                         uint32_t *mb_free);
173
174 int32_t xran_process_srs_sym(void *arg,
175                         struct rte_mbuf *mbuf,
176                         void *iq_data_start,
177                         uint16_t size,
178                         uint8_t CC_ID,
179                         uint8_t Ant_ID,
180                         uint8_t frame_id,
181                         uint8_t subframe_id,
182                         uint8_t slot_id,
183                         uint8_t symb_id,
184                         uint16_t num_prbu,
185                         uint16_t start_prbu,
186                         uint16_t sym_inc,
187                         uint16_t rb,
188                         uint16_t sect_id,
189                         uint32_t *mb_free);
190
191
192 void tti_ota_cb(struct rte_timer *tim, void *arg);
193 void tti_to_phy_cb(struct rte_timer *tim, void *arg);
194 void xran_timer_arm_ex(struct rte_timer *tim, void* CbFct, void *CbArg, unsigned tim_lcore);
195
196 // Return SFN at current second start, 10 bits, [0, 1023]
197 static inline uint16_t xran_getSfnSecStart(void)
198 {
199     return xran_SFN_at_Sec_Start;
200 }
201 void xran_updateSfnSecStart(void)
202 {
203     uint64_t currentSecond = timing_get_current_second();
204     // Assume always positive
205     uint64_t gpsSecond = currentSecond - UNIX_TO_GPS_SECONDS_OFFSET;
206     uint64_t nFrames = gpsSecond * NUM_OF_FRAMES_PER_SECOND;
207     uint16_t sfn = (uint16_t)(nFrames % (xran_max_frame + 1));
208     xran_SFN_at_Sec_Start = sfn;
209
210     tx_bytes_per_sec = tx_bytes_counter;
211     rx_bytes_per_sec = rx_bytes_counter;
212     tx_bytes_counter = 0;
213     rx_bytes_counter = 0;
214 }
215
216 static inline int32_t xran_getSlotIdxSecond(void)
217 {
218     int32_t frameIdxSecond = xran_getSfnSecStart();
219     int32_t slotIndxSecond = frameIdxSecond * SLOTS_PER_SYSTEMFRAME;
220     return slotIndxSecond;
221 }
222
223 struct xran_device_ctx *xran_dev_get_ctx(void)
224 {
225     return &g_xran_dev_ctx[0];
226 }
227
228 static inline struct xran_fh_config *xran_lib_get_ctx_fhcfg(void)
229 {
230     return (&(xran_dev_get_ctx()->fh_cfg));
231 }
232
233 uint16_t xran_get_beamid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id)
234 {
235     return (0);     // NO BEAMFORMING
236 }
237
238 enum xran_if_state xran_get_if_state(void)
239 {
240     return xran_if_current_state;
241 }
242
243 int xran_is_prach_slot(uint32_t subframe_id, uint32_t slot_id)
244 {
245     struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
246     struct xran_prach_cp_config *pPrachCPConfig = &(p_xran_dev_ctx->PrachCPConfig);
247     int32_t is_prach_slot = 0;
248
249     if (p_xran_dev_ctx->fh_cfg.frame_conf.nNumerology < 2){
250         //for FR1, in 38.211 tab 6.3.3.2-2&3 it is subframe index
251         if (pPrachCPConfig->isPRACHslot[subframe_id] == 1){
252             if (pPrachCPConfig->nrofPrachInSlot != 1)
253                 is_prach_slot = 1;
254             else{
255                 if (p_xran_dev_ctx->fh_cfg.frame_conf.nNumerology == 0)
256                     is_prach_slot = 1;
257                 else if (slot_id == 1)
258                     is_prach_slot = 1;
259             }
260         }
261     } else if (p_xran_dev_ctx->fh_cfg.frame_conf.nNumerology == 3){
262         //for FR2, 38.211 tab 6.3.3.4 it is slot index of 60kHz slot
263         uint32_t slotidx;
264         slotidx = subframe_id * SLOTNUM_PER_SUBFRAME + slot_id;
265         if (pPrachCPConfig->nrofPrachInSlot == 2){
266             if (pPrachCPConfig->isPRACHslot[slotidx>>1] == 1)
267                 is_prach_slot = 1;
268         } else {
269             if ((pPrachCPConfig->isPRACHslot[slotidx>>1] == 1) && ((slotidx % 2) == 1)){
270                 is_prach_slot = 1;
271             }
272         }
273     } else
274         print_err("Numerology %d not supported", p_xran_dev_ctx->fh_cfg.frame_conf.nNumerology);
275     return is_prach_slot;
276 }
277
278 int xran_init_sectionid(void *pHandle)
279 {
280   int cell, ant, dir;
281
282     for (dir = 0; dir < XRAN_DIR_MAX; dir++){
283         for(cell=0; cell < XRAN_MAX_CELLS_PER_PORT; cell++) {
284             for(ant=0; ant < XRAN_MAX_ANTENNA_NR; ant++) {
285                 xran_section_id[dir][cell][ant] = 0;
286                 xran_section_id_curslot[dir][cell][ant] = 255;
287             }
288         }
289     }
290
291     return (0);
292 }
293
294 int xran_init_srs(struct xran_fh_config* pConf, struct xran_device_ctx * p_xran_dev_ctx)
295 {
296     struct xran_srs_config *p_srs = &(p_xran_dev_ctx->srs_cfg);
297
298     if(p_srs){
299         p_srs->symbMask = pConf->srs_conf.symbMask;
300         p_srs->eAxC_offset = pConf->srs_conf.eAxC_offset;
301         print_dbg("SRS sym         %d\n", p_srs->symbMask );
302         print_dbg("SRS eAxC_offset %d\n", p_srs->eAxC_offset);
303     }
304     return (XRAN_STATUS_SUCCESS);
305 }
306
307
308 int xran_init_prach(struct xran_fh_config* pConf, struct xran_device_ctx * p_xran_dev_ctx)
309 {
310     int32_t i;
311     uint8_t slotNr;
312     struct xran_prach_config* pPRACHConfig = &(pConf->prach_conf);
313     const xRANPrachConfigTableStruct *pxRANPrachConfigTable;
314     uint8_t nNumerology = pConf->frame_conf.nNumerology;
315     uint8_t nPrachConfIdx = pPRACHConfig->nPrachConfIdx;
316     struct xran_prach_cp_config *pPrachCPConfig = &(p_xran_dev_ctx->PrachCPConfig);
317
318     if (nNumerology > 2)
319         pxRANPrachConfigTable = &gxranPrachDataTable_mmw[nPrachConfIdx];
320     else if (pConf->frame_conf.nFrameDuplexType == 1)
321         pxRANPrachConfigTable = &gxranPrachDataTable_sub6_tdd[nPrachConfIdx];
322     else
323         pxRANPrachConfigTable = &gxranPrachDataTable_sub6_fdd[nPrachConfIdx];
324
325     uint8_t preambleFmrt = pxRANPrachConfigTable->preambleFmrt[0];
326     const xRANPrachPreambleLRAStruct *pxranPreambleforLRA = &gxranPreambleforLRA[preambleFmrt];
327     memset(pPrachCPConfig, 0, sizeof(struct xran_prach_cp_config));
328     if(pConf->log_level)
329         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);
330
331     pPrachCPConfig->filterIdx = XRAN_FILTERINDEX_PRACH_ABC;         // 3, PRACH preamble format A1~3, B1~4, C0, C2
332     pPrachCPConfig->startSymId = pxRANPrachConfigTable->startingSym;
333     pPrachCPConfig->startPrbc = pPRACHConfig->nPrachFreqStart;
334     pPrachCPConfig->numPrbc = (preambleFmrt >= FORMAT_A1)? 12 : 70;
335     pPrachCPConfig->timeOffset = pxranPreambleforLRA->nRaCp;
336     pPrachCPConfig->freqOffset = xran_get_freqoffset(pPRACHConfig->nPrachFreqOffset, pPRACHConfig->nPrachSubcSpacing);
337     pPrachCPConfig->x = pxRANPrachConfigTable->x;
338     pPrachCPConfig->nrofPrachInSlot = pxRANPrachConfigTable->nrofPrachInSlot;
339     pPrachCPConfig->y[0] = pxRANPrachConfigTable->y[0];
340     pPrachCPConfig->y[1] = pxRANPrachConfigTable->y[1];
341     if (preambleFmrt >= FORMAT_A1)
342     {
343         pPrachCPConfig->numSymbol = pxRANPrachConfigTable->duration;
344         pPrachCPConfig->occassionsInPrachSlot = pxRANPrachConfigTable->occassionsInPrachSlot;
345     }
346     else
347     {
348         pPrachCPConfig->numSymbol = 1;
349         pPrachCPConfig->occassionsInPrachSlot = 1;
350     }
351
352     if(pConf->log_level)
353         printf("PRACH: x %u y[0] %u, y[1] %u prach slot: %u ..", pPrachCPConfig->x, pPrachCPConfig->y[0], pPrachCPConfig->y[1], pxRANPrachConfigTable->slotNr[0]);
354     pPrachCPConfig->isPRACHslot[pxRANPrachConfigTable->slotNr[0]] = 1;
355     for (i=1; i < XRAN_PRACH_CANDIDATE_SLOT; i++)
356     {
357         slotNr = pxRANPrachConfigTable->slotNr[i];
358         if (slotNr > 0){
359             pPrachCPConfig->isPRACHslot[slotNr] = 1;
360             if(pConf->log_level)
361                 printf(" %u ..", slotNr);
362         }
363     }
364     printf("\n");
365     for (i = 0; i < XRAN_MAX_SECTOR_NR; i++){
366         p_xran_dev_ctx->prach_start_symbol[i] = pPrachCPConfig->startSymId;
367         p_xran_dev_ctx->prach_last_symbol[i] = pPrachCPConfig->startSymId + pPrachCPConfig->numSymbol * pPrachCPConfig->occassionsInPrachSlot - 1;
368     }
369     if(pConf->log_level){
370         printf("PRACH start symbol %u lastsymbol %u\n", p_xran_dev_ctx->prach_start_symbol[0], p_xran_dev_ctx->prach_last_symbol[0]);
371     }
372
373     pPrachCPConfig->eAxC_offset = xran_get_num_eAxc(NULL);
374     print_dbg("PRACH eAxC_offset %d\n",  pPrachCPConfig->eAxC_offset);
375
376     return (XRAN_STATUS_SUCCESS);
377 }
378
379 inline uint16_t xran_alloc_sectionid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id)
380 {
381     if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
382         print_err("Invalid CC ID - %d", cc_id);
383         return (0);
384         }
385     if(ant_id >= XRAN_MAX_ANTENNA_NR * 2 + XRAN_MAX_ANT_ARRAY_ELM_NR) {  //for PRACH, ant_id starts from num_ant
386         print_err("Invalid antenna ID - %d", ant_id);
387         return (0);
388     }
389
390     /* if new slot has been started,
391      * then initializes section id again for new start */
392     if(xran_section_id_curslot[dir][cc_id][ant_id] != slot_id) {
393         xran_section_id[dir][cc_id][ant_id] = 0;
394         xran_section_id_curslot[dir][cc_id][ant_id] = slot_id;
395     }
396
397     return(xran_section_id[dir][cc_id][ant_id]++);
398 }
399
400 int xran_init_seqid(void *pHandle)
401 {
402     int cell, dir, ant;
403
404     for(cell=0; cell < XRAN_MAX_CELLS_PER_PORT; cell++) {
405         for(dir=0; dir < XRAN_DIR_MAX; dir++) {
406             for(ant=0; ant < XRAN_MAX_ANTENNA_NR * 2; ant++)
407                 xran_cp_seq_id_num[cell][dir][ant] = 0;
408             }
409         for(ant=0; ant < XRAN_MAX_ANTENNA_NR; ant++)
410                 xran_updl_seq_id_num[cell][ant] = 0;
411         for(ant=0; ant < XRAN_MAX_ANTENNA_NR * 2 + XRAN_MAX_ANT_ARRAY_ELM_NR; ant++)
412                 xran_upul_seq_id_num[cell][ant] = 0;
413         }
414
415     return (0);
416 }
417
418 static inline uint8_t xran_get_cp_seqid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id)
419 {
420     if(dir >= XRAN_DIR_MAX) {
421         print_err("Invalid direction - %d", dir);
422         return (0);
423         }
424     if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
425         print_err("Invalid CC ID - %d", cc_id);
426         return (0);
427         }
428     if(ant_id >= XRAN_MAX_ANTENNA_NR * 2 + XRAN_MAX_ANT_ARRAY_ELM_NR) {
429         print_err("Invalid antenna ID - %d", ant_id);
430         return (0);
431         }
432
433     return(xran_cp_seq_id_num[cc_id][dir][ant_id]++);
434 }
435 static inline uint8_t xran_get_updl_seqid(void *pHandle, uint8_t cc_id, uint8_t ant_id)
436 {
437     if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
438         print_err("Invalid CC ID - %d", cc_id);
439         return (0);
440         }
441     if(ant_id >= XRAN_MAX_ANTENNA_NR) {
442         print_err("Invalid antenna ID - %d", ant_id);
443         return (0);
444         }
445
446     /* Only U-Plane DL needs to get sequence ID in O-DU */
447     return(xran_updl_seq_id_num[cc_id][ant_id]++);
448 }
449 static inline uint8_t *xran_get_updl_seqid_addr(void *pHandle, uint8_t cc_id, uint8_t ant_id)
450 {
451     if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
452         print_err("Invalid CC ID - %d", cc_id);
453         return (NULL);
454     }
455     if(ant_id >= XRAN_MAX_ANTENNA_NR) {
456         print_err("Invalid antenna ID - %d", ant_id);
457         return (NULL);
458     }
459
460     /* Only U-Plane DL needs to get sequence ID in O-DU */
461     return(&xran_updl_seq_id_num[cc_id][ant_id]);
462 }
463 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)
464 {
465
466     if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
467         print_err("Invalid CC ID - %d", cc_id);
468         return (-1);
469     }
470
471     if(ant_id >= XRAN_MAX_ANTENNA_NR * 2 + XRAN_MAX_ANT_ARRAY_ELM_NR) {
472         print_err("Invalid antenna ID - %d", ant_id);
473         return (-1);
474     }
475
476     /* O-DU needs to check the sequence ID of U-Plane UL from O-RU */
477     xran_upul_seq_id_num[cc_id][ant_id]++;
478     if(xran_upul_seq_id_num[cc_id][ant_id] == seq_id) { /* expected sequence */
479         return (XRAN_STATUS_SUCCESS);
480     } else {
481         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);
482         xran_upul_seq_id_num[cc_id][ant_id] = seq_id; // for next
483         return (-1);
484     }
485 }
486
487 //////////////////////////////////////////
488 // For RU emulation
489 static inline uint8_t xran_get_upul_seqid(void *pHandle, uint8_t cc_id, uint8_t ant_id)
490 {
491     if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
492         print_err("Invalid CC ID - %d", cc_id);
493         return (0);
494         }
495     if(ant_id >= XRAN_MAX_ANTENNA_NR * 2 + XRAN_MAX_ANT_ARRAY_ELM_NR) {
496         print_err("Invalid antenna ID - %d", ant_id);
497         return (0);
498         }
499
500     return(xran_upul_seq_id_num[cc_id][ant_id]++);
501 }
502 static inline uint8_t *xran_get_upul_seqid_addr(void *pHandle, uint8_t cc_id, uint8_t ant_id)
503 {
504     if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
505         print_err("Invalid CC ID - %d", cc_id);
506         return (0);
507         }
508     if(ant_id >= XRAN_MAX_ANTENNA_NR * 2) {
509         print_err("Invalid antenna ID - %d", ant_id);
510         return (0);
511         }
512
513     return(&xran_upul_seq_id_num[cc_id][ant_id]);
514 }
515 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)
516 {
517     if(dir >= XRAN_DIR_MAX) {
518         print_err("Invalid direction - %d", dir);
519         return (-1);
520         }
521     if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
522         print_err("Invalid CC ID - %d", cc_id);
523         return (-1);
524         }
525     if(ant_id >= XRAN_MAX_ANTENNA_NR * 2) {
526         print_err("Invalid antenna ID - %d", ant_id);
527         return (-1);
528         }
529
530     xran_cp_seq_id_num[cc_id][dir][ant_id]++;
531     if(xran_cp_seq_id_num[cc_id][dir][ant_id] == seq_id) { /* expected sequence */
532         return (0);
533         }
534     else {
535         xran_cp_seq_id_num[cc_id][dir][ant_id] = seq_id;
536         return (-1);
537         }
538 }
539 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)
540 {
541     if(cc_id >= XRAN_MAX_CELLS_PER_PORT) {
542         print_err("Invalid CC ID - %d", cc_id);
543         return (-1);
544     }
545
546     if(ant_id >= XRAN_MAX_ANTENNA_NR) {
547         print_err("Invalid antenna ID - %d", ant_id);
548         return (-1);
549     }
550
551     /* O-RU needs to check the sequence ID of U-Plane DL from O-DU */
552     xran_updl_seq_id_num[cc_id][ant_id]++;
553     if(xran_updl_seq_id_num[cc_id][ant_id] == seq_id) {
554         /* expected sequence */
555         /*print_dbg("ant %u  cc_id %u : slot_id %u : seq_id %u : expected seq_id %u\n",
556             ant_id, cc_id, slot_id, seq_id, xran_updl_seq_id_num[cc_id][ant_id]);*/
557         return (0);
558     } else {
559        /* print_err("ant %u  cc_id %u : slot_id %u : seq_id %u : expected seq_id %u\n",
560             ant_id, cc_id, slot_id, seq_id, xran_updl_seq_id_num[cc_id][ant_id]);*/
561
562         xran_updl_seq_id_num[cc_id][ant_id] = seq_id;
563
564         return (-1);
565     }
566 }
567
568
569 static struct xran_section_gen_info cpSections[XRAN_MAX_NUM_SECTIONS];
570 static struct xran_cp_gen_params cpInfo;
571 int process_cplane(struct rte_mbuf *pkt)
572 {
573   struct xran_recv_packet_info recv;
574
575     cpInfo.sections = cpSections;
576     xran_parse_cp_pkt(pkt, &cpInfo, &recv);
577
578     return (MBUF_FREE);
579 }
580 //////////////////////////////////////////
581
582 void sym_ota_cb(struct rte_timer *tim, void *arg, unsigned long *used_tick)
583 {
584     struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
585     struct xran_timer_ctx *pTCtx = (struct xran_timer_ctx *)arg;
586     long t1 = MLogTick(), t2;
587     long t3;
588     static int32_t ctx = 0;
589
590     if(XranGetSymNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT) == 0){
591         t3 = xran_tick();
592         tti_ota_cb(NULL, arg);
593         *used_tick += get_ticks_diff(xran_tick(), t3);
594     }
595
596     if(XranGetSymNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT) == 3){
597         if(p_xran_dev_ctx->phy_tti_cb_done == 0){
598             /* rearm timer to deliver TTI event to PHY */
599             t3 = xran_tick();
600             p_xran_dev_ctx->phy_tti_cb_done = 0;
601             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);
602             *used_tick += get_ticks_diff(xran_tick(), t3);
603         }
604     }
605
606     t3 = xran_tick();
607     if (xran_process_tx_sym(timer_ctx))
608     {
609         *used_tick += get_ticks_diff(xran_tick(), t3);
610     }
611
612     /* check if there is call back to do something else on this symbol */
613
614     struct cb_elem_entry *cb_elm;
615     LIST_FOREACH(cb_elm, &p_xran_dev_ctx->sym_cb_list_head[0][xran_lib_ota_sym], pointers){
616         if(cb_elm){
617             cb_elm->pSymCallback(&dpdk_timer[ctx], cb_elm->pSymCallbackTag);
618             ctx = DpdkTimerIncrementCtx(ctx);
619         }
620     }
621
622     // This counter is incremented in advance before it is the time for the next symbol
623     xran_lib_ota_sym++;
624     if(xran_lib_ota_sym >= N_SYM_PER_SLOT){
625         xran_lib_ota_sym=0;
626     }
627
628     t2 = MLogTick();
629     MLogTask(PID_SYM_OTA_CB, t1, t2);
630 }
631
632 void tti_ota_cb(struct rte_timer *tim, void *arg)
633 {
634     uint32_t    frame_id    = 0;
635     uint32_t    subframe_id = 0;
636     uint32_t    slot_id     = 0;
637     uint32_t    next_tti    = 0;
638
639     uint32_t mlogVar[10];
640     uint32_t mlogVarCnt = 0;
641     uint64_t t1 = MLogTick();
642     uint64_t t3 = 0;
643     uint32_t reg_tti  = 0;
644     uint32_t reg_sfn  = 0;
645     struct xran_timer_ctx *pTCtx = (struct xran_timer_ctx *)arg;
646     struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
647
648     MLogTask(PID_TTI_TIMER, t1, MLogTick());
649
650     /* To match TTbox */
651     if(xran_lib_ota_tti == 0)
652         reg_tti = xran_fs_get_max_slot() - 1;
653     else
654         reg_tti = xran_lib_ota_tti -1;
655     MLogIncrementCounter();
656     reg_sfn    = XranGetFrameNum(reg_tti,xran_getSfnSecStart(),SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME)*10 + XranGetSubFrameNum(reg_tti,SLOTNUM_PER_SUBFRAME,  SUBFRAMES_PER_SYSTEMFRAME);;
657     /* subframe and slot */
658     MLogRegisterFrameSubframe(reg_sfn, reg_tti % (SLOTNUM_PER_SUBFRAME));
659     MLogMark(1, t1);
660
661     slot_id     = XranGetSlotNum(xran_lib_ota_tti, SLOTNUM_PER_SUBFRAME);
662     subframe_id = XranGetSubFrameNum(xran_lib_ota_tti,SLOTNUM_PER_SUBFRAME,  SUBFRAMES_PER_SYSTEMFRAME);
663     frame_id    = XranGetFrameNum(xran_lib_ota_tti,xran_getSfnSecStart(),SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
664
665     pTCtx[(xran_lib_ota_tti & 1) ^ 1].tti_to_process = xran_lib_ota_tti;
666
667     mlogVar[mlogVarCnt++] = 0x11111111;
668     mlogVar[mlogVarCnt++] = xran_lib_ota_tti;
669     mlogVar[mlogVarCnt++] = xran_lib_ota_sym_idx;
670     mlogVar[mlogVarCnt++] = xran_lib_ota_sym_idx / 14;
671     mlogVar[mlogVarCnt++] = frame_id;
672     mlogVar[mlogVarCnt++] = subframe_id;
673     mlogVar[mlogVarCnt++] = slot_id;
674     mlogVar[mlogVarCnt++] = 0;
675     MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
676
677     if(p_xran_dev_ctx->fh_init.io_cfg.id == ID_LLS_CU)
678         next_tti = xran_lib_ota_tti + 1;
679     else
680         next_tti = xran_lib_ota_tti;
681
682     if(next_tti>= xran_fs_get_max_slot()){
683         print_dbg("[%d]SFN %d sf %d slot %d\n",next_tti, frame_id, subframe_id, slot_id);
684         next_tti=0;
685     }
686
687     slot_id     = XranGetSlotNum(next_tti, SLOTNUM_PER_SUBFRAME);
688     subframe_id = XranGetSubFrameNum(next_tti,SLOTNUM_PER_SUBFRAME,  SUBFRAMES_PER_SYSTEMFRAME);
689     frame_id    = XranGetFrameNum(next_tti,xran_getSfnSecStart(),SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
690
691     print_dbg("[%d]SFN %d sf %d slot %d\n",next_tti, frame_id, subframe_id, slot_id);
692
693     if(p_xran_dev_ctx->fh_init.io_cfg.id == ID_LLS_CU){
694         pTCtx[(xran_lib_ota_tti & 1)].tti_to_process = next_tti;
695     } else {
696         pTCtx[(xran_lib_ota_tti & 1)].tti_to_process = pTCtx[(xran_lib_ota_tti & 1)^1].tti_to_process;
697     }
698
699     p_xran_dev_ctx->phy_tti_cb_done = 0;
700     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);
701
702     //slot index is increased to next slot at the beginning of current OTA slot
703     xran_lib_ota_tti++;
704     if(xran_lib_ota_tti >= xran_fs_get_max_slot()){
705         print_dbg("[%d]SFN %d sf %d slot %d\n",xran_lib_ota_tti, frame_id, subframe_id, slot_id);
706         xran_lib_ota_tti=0;
707     }
708     MLogTask(PID_TTI_CB, t1, MLogTick());
709 }
710
711 void xran_timer_arm(struct rte_timer *tim, void* arg)
712 {
713     struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
714     uint64_t t3 = MLogTick();
715
716     if (xran_if_current_state == XRAN_RUNNING){
717         rte_timer_cb_t fct = (rte_timer_cb_t)arg;
718         rte_timer_init(tim);
719         rte_timer_reset_sync(tim, 0, SINGLE, p_xran_dev_ctx->fh_init.io_cfg.timing_core, fct, &timer_ctx[0]);
720     }
721     MLogTask(PID_TIME_ARM_TIMER, t3, MLogTick());
722 }
723
724 void xran_timer_arm_ex(struct rte_timer *tim, void* CbFct, void *CbArg, unsigned tim_lcore)
725 {
726     struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
727     uint64_t t3 = MLogTick();
728
729     if (xran_if_current_state == XRAN_RUNNING){
730         rte_timer_cb_t fct = (rte_timer_cb_t)CbFct;
731         rte_timer_init(tim);
732         rte_timer_reset_sync(tim, 0, SINGLE, tim_lcore, fct, CbArg);
733     }
734     MLogTask(PID_TIME_ARM_TIMER, t3, MLogTick());
735 }
736
737 int xran_cp_create_and_send_section(void *pHandle, uint8_t ru_port_id, int dir, int tti, int cc_id,
738         struct xran_prb_map *prbMap, enum xran_category category,  uint8_t ctx_id)
739 {
740     struct xran_device_ctx *p_x_ctx = xran_dev_get_ctx();
741     struct xran_cp_gen_params params;
742     struct xran_section_gen_info sect_geninfo[1];
743     struct rte_mbuf *mbuf;
744     int ret = 0;
745     uint32_t i, j, loc_sym;
746     uint32_t nsection = 0;
747     struct xran_prb_elm *pPrbMapElem = NULL;
748     struct xran_prb_elm *pPrbMapElemPrev = NULL;
749     uint32_t slot_id     = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME);
750     uint32_t subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME,  SUBFRAMES_PER_SYSTEMFRAME);
751     uint32_t frame_id    = XranGetFrameNum(tti,xran_getSfnSecStart(),SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
752
753     frame_id = (frame_id & 0xff); /* ORAN frameId, 8 bits, [0, 255] */
754     uint8_t seq_id = 0;
755
756     struct xran_sectionext1_info m_ext1;
757
758     if(prbMap) {
759         nsection = prbMap->nPrbElm;
760         pPrbMapElem = &prbMap->prbMap[0];
761         if (nsection < 1){
762             print_dbg("cp[%d:%d:%d] ru_port_id %d dir=%d nsection %d\n",
763                                    frame_id, subframe_id, slot_id, ru_port_id, dir, nsection);
764         }
765     } else {
766         print_err("prbMap is NULL\n");
767         return (-1);
768     }
769     for (i=0; i<nsection; i++)
770     {
771         pPrbMapElem                 = &prbMap->prbMap[i];
772         params.dir                  = dir;
773         params.sectionType          = XRAN_CP_SECTIONTYPE_1;        /* Most DL/UL Radio Channels */
774         params.hdr.filterIdx        = XRAN_FILTERINDEX_STANDARD;
775         params.hdr.frameId          = frame_id;
776         params.hdr.subframeId       = subframe_id;
777         params.hdr.slotId           = slot_id;
778         params.hdr.startSymId       = pPrbMapElem->nStartSymb;
779         params.hdr.iqWidth          = pPrbMapElem->iqWidth; /*xran_get_conf_iqwidth(pHandle);*/
780         params.hdr.compMeth         = pPrbMapElem->compMethod;
781
782         print_dbg("cp[%d:%d:%d] ru_port_id %d dir=%d\n",
783                                frame_id, subframe_id, slot_id, ru_port_id, dir);
784
785         seq_id = xran_get_cp_seqid(pHandle, XRAN_DIR_DL, cc_id, ru_port_id);
786
787         sect_geninfo[0].info.type        = params.sectionType;       // for database
788         sect_geninfo[0].info.startSymId  = params.hdr.startSymId;    // for database
789         sect_geninfo[0].info.iqWidth     = params.hdr.iqWidth;       // for database
790         sect_geninfo[0].info.compMeth    = params.hdr.compMeth;      // for database
791         sect_geninfo[0].info.id          = i; /*xran_alloc_sectionid(pHandle, dir, cc_id, ru_port_id, slot_id);*/
792
793         if(sect_geninfo[0].info.id > 7)
794             print_err("sectinfo->id %d\n", sect_geninfo[0].info.id);
795
796         if (dir == XRAN_DIR_UL) {
797             for (loc_sym = 0; loc_sym < XRAN_NUM_OF_SYMBOL_PER_SLOT; loc_sym++){
798                 struct xran_section_desc *p_sec_desc =  pPrbMapElem->p_sec_desc[loc_sym];
799                 if(p_sec_desc) {
800                     p_sec_desc->section_id   = sect_geninfo[0].info.id;
801                     if(p_sec_desc->pCtrl) {
802                         rte_pktmbuf_free(p_sec_desc->pCtrl);
803                         p_sec_desc->pCtrl = NULL;
804                         p_sec_desc->pData = NULL;
805                     }
806                 } else {
807                     print_err("section desc is NULL\n");
808                 }
809             }
810         }
811
812         sect_geninfo[0].info.rb          = XRAN_RBIND_EVERY;
813         sect_geninfo[0].info.startPrbc   = pPrbMapElem->nRBStart;
814         sect_geninfo[0].info.numPrbc     = pPrbMapElem->nRBSize;
815         sect_geninfo[0].info.numSymbol   = pPrbMapElem->numSymb;
816         sect_geninfo[0].info.reMask      = 0xfff;
817         sect_geninfo[0].info.beamId      = pPrbMapElem->nBeamIndex;
818
819         for (loc_sym = 0; loc_sym < XRAN_NUM_OF_SYMBOL_PER_SLOT; loc_sym++){
820             struct xran_section_desc *p_sec_desc =  pPrbMapElem->p_sec_desc[loc_sym];
821             if(p_sec_desc) {
822                 p_sec_desc->section_id   = sect_geninfo[0].info.id;
823
824                 sect_geninfo[0].info.sec_desc[loc_sym].iq_buffer_offset = p_sec_desc->iq_buffer_offset;
825                 sect_geninfo[0].info.sec_desc[loc_sym].iq_buffer_len    = p_sec_desc->iq_buffer_len;
826             } else {
827                 print_err("section desc is NULL\n");
828             }
829         }
830
831         if (i==0)
832             sect_geninfo[0].info.symInc      = XRAN_SYMBOLNUMBER_NOTINC;
833         else
834         {
835             pPrbMapElemPrev = &prbMap->prbMap[i-1];
836             if (pPrbMapElemPrev->nStartSymb == pPrbMapElem->nStartSymb)
837             {
838                 sect_geninfo[0].info.symInc      = XRAN_SYMBOLNUMBER_NOTINC;
839                 if (pPrbMapElemPrev->numSymb != pPrbMapElem->numSymb)
840                     print_err("section info error: previous numSymb %d not equal to current numSymb %d\n", pPrbMapElemPrev->numSymb, pPrbMapElem->numSymb);
841             }
842             else
843             {
844                 sect_geninfo[0].info.symInc      = XRAN_SYMBOLNUMBER_INC;
845                 if (pPrbMapElem->nStartSymb != (pPrbMapElemPrev->nStartSymb + pPrbMapElemPrev->numSymb))
846                     print_err("section info error: current startSym %d not equal to previous endSymb %d\n", pPrbMapElem->nStartSymb, pPrbMapElemPrev->nStartSymb + pPrbMapElemPrev->numSymb);
847             }
848         }
849
850         if(category == XRAN_CATEGORY_A){
851             /* no extention sections for category */
852             sect_geninfo[0].info.ef          = 0;
853             sect_geninfo[0].exDataSize       = 0;
854         } else if (category == XRAN_CATEGORY_B) {
855             /*add extantion section for BF Weights if update is needed */
856             if(pPrbMapElem->bf_weight_update){
857                 memset(&m_ext1, 0, sizeof (struct xran_sectionext1_info));
858                 m_ext1.bfwNumber      = pPrbMapElem->bf_weight.nAntElmTRx;
859                 m_ext1.bfwiqWidth     = pPrbMapElem->iqWidth;
860                 m_ext1.bfwCompMeth    = pPrbMapElem->compMethod;
861                 m_ext1.p_bfwIQ        = (int16_t*)pPrbMapElem->bf_weight.p_ext_section;
862                 m_ext1.bfwIQ_sz       = pPrbMapElem->bf_weight.ext_section_sz;
863
864                 sect_geninfo[0].exData[0].type = XRAN_CP_SECTIONEXTCMD_1;
865                 sect_geninfo[0].exData[0].len  = sizeof(m_ext1);
866                 sect_geninfo[0].exData[0].data = &m_ext1;
867
868                 sect_geninfo[0].info.ef       = 1;
869                 sect_geninfo[0].exDataSize    = 1;
870             } else {
871                 sect_geninfo[0].info.ef          = 0;
872                 sect_geninfo[0].exDataSize       = 0;
873             }
874         } else {
875             print_err("Unsupported Category %d\n", category);
876             return (-1);
877         }
878
879         params.numSections          = 1;//nsection;
880         params.sections             = sect_geninfo;
881
882         mbuf = xran_ethdi_mbuf_alloc();
883         if(unlikely(mbuf == NULL)) {
884             print_err("Alloc fail!\n");
885             return (-1);
886         }
887
888         ret = xran_prepare_ctrl_pkt(mbuf, &params, cc_id, ru_port_id, seq_id);
889         if(ret < 0) {
890             print_err("Fail to build control plane packet - [%d:%d:%d] dir=%d\n",
891                         frame_id, subframe_id, slot_id, dir);
892         } else {
893             /* add in the ethernet header */
894             struct ether_hdr *const h = (void *)rte_pktmbuf_prepend(mbuf, sizeof(*h));
895             tx_counter++;
896             tx_bytes_counter += rte_pktmbuf_pkt_len(mbuf);
897             p_x_ctx->send_cpmbuf2ring(mbuf, ETHER_TYPE_ECPRI);
898
899             /*for(i=0; i<nsection; i++)*/
900                 xran_cp_add_section_info(pHandle,
901                         dir, cc_id, ru_port_id,
902                         ctx_id,
903                         &sect_geninfo[0].info);
904         }
905     }
906
907     return ret;
908 }
909
910 void tx_cp_dl_cb(struct rte_timer *tim, void *arg)
911 {
912     long t1 = MLogTick();
913     int tti, buf_id;
914     int i, ret;
915     uint32_t slot_id, subframe_id, frame_id;
916     int cc_id;
917     uint8_t ctx_id;
918     uint8_t ant_id, num_eAxc, num_CCPorts;
919     void *pHandle;
920     int num_list;
921     struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
922     struct xran_timer_ctx *pTCtx = (struct xran_timer_ctx *)arg;
923
924     pHandle = NULL;     // TODO: temp implemantation
925     num_eAxc    = xran_get_num_eAxc(pHandle);
926     num_CCPorts = xran_get_num_cc(pHandle);
927
928     if(first_call && p_xran_dev_ctx->enableCP) {
929
930         tti = pTCtx[(xran_lib_ota_tti & 1) ^ 1].tti_to_process;
931         buf_id = tti % XRAN_N_FE_BUF_LEN;
932
933         slot_id     = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME);
934         subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME,  SUBFRAMES_PER_SYSTEMFRAME);
935         frame_id    = XranGetFrameNum(tti,xran_getSfnSecStart(),SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
936         if (tti == 0){
937             /* Wrap around to next second */
938             frame_id = (frame_id + NUM_OF_FRAMES_PER_SECOND) & 0x3ff;
939         }
940
941         ctx_id      = XranGetSlotNum(tti, SLOTS_PER_SYSTEMFRAME) % XRAN_MAX_SECTIONDB_CTX;
942
943         print_dbg("[%d]SFN %d sf %d slot %d\n", tti, frame_id, subframe_id, slot_id);
944         for(ant_id = 0; ant_id < num_eAxc; ++ant_id) {
945             for(cc_id = 0; cc_id < num_CCPorts; cc_id++ ) {
946                 /* start new section information list */
947                 xran_cp_reset_section_info(pHandle, XRAN_DIR_DL, cc_id, ant_id, ctx_id);
948                 if(xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_DL) == 1) {
949                     if(p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[buf_id][cc_id][ant_id].sBufferList.pBuffers->pData){
950                         num_list = xran_cp_create_and_send_section(pHandle, ant_id, XRAN_DIR_DL, tti, cc_id,
951                             (struct xran_prb_map *)p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[buf_id][cc_id][ant_id].sBufferList.pBuffers->pData,
952                             p_xran_dev_ctx->fh_cfg.ru_conf.xranCat, ctx_id);
953                     } else {
954                         print_err("[%d]SFN %d sf %d slot %d: ant_id %d cc_id %d \n", tti, frame_id, subframe_id, slot_id, ant_id, cc_id);
955                     }
956                 } /* if(xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_DL) == 1) */
957             } /* for(cc_id = 0; cc_id < num_CCPorts; cc_id++) */
958         } /* for(ant_id = 0; ant_id < num_eAxc; ++ant_id) */
959         MLogTask(PID_CP_DL_CB, t1, MLogTick());
960     }
961 }
962
963 void rx_ul_deadline_half_cb(struct rte_timer *tim, void *arg)
964 {
965     long t1 = MLogTick();
966     struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
967     xran_status_t status;
968     /* half of RX for current TTI as measured against current OTA time */
969     int32_t rx_tti = (int32_t)XranGetTtiNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT);
970     int32_t cc_id;
971     uint32_t nFrameIdx;
972     uint32_t nSubframeIdx;
973     uint32_t nSlotIdx;
974     uint64_t nSecond;
975
976     uint32_t nXranTime  = xran_get_slot_idx(&nFrameIdx, &nSubframeIdx, &nSlotIdx, &nSecond);
977     rx_tti = nFrameIdx*SUBFRAMES_PER_SYSTEMFRAME*SLOTNUM_PER_SUBFRAME
978            + nSubframeIdx*SLOTNUM_PER_SUBFRAME
979            + nSlotIdx;
980
981     if(p_xran_dev_ctx->xran2phy_mem_ready == 0)
982         return;
983
984     for(cc_id = 0; cc_id < xran_get_num_cc(p_xran_dev_ctx); cc_id++) {
985         if(p_xran_dev_ctx->rx_packet_callback_tracker[rx_tti % XRAN_N_FE_BUF_LEN][cc_id] == 0){
986             struct xran_cb_tag *pTag = p_xran_dev_ctx->pCallbackTag[cc_id];
987             pTag->slotiId = rx_tti;
988             pTag->symbol  = 0; /* last 7 sym means full slot of Symb */
989             status = XRAN_STATUS_SUCCESS;
990             if(p_xran_dev_ctx->pCallback[cc_id])
991                p_xran_dev_ctx->pCallback[cc_id](p_xran_dev_ctx->pCallbackTag[cc_id], status);
992         } else {
993             p_xran_dev_ctx->rx_packet_callback_tracker[rx_tti % XRAN_N_FE_BUF_LEN][cc_id] = 0;
994         }
995     }
996     MLogTask(PID_UP_UL_HALF_DEAD_LINE_CB, t1, MLogTick());
997 }
998
999 void rx_ul_deadline_full_cb(struct rte_timer *tim, void *arg)
1000 {
1001     long t1 = MLogTick();
1002     struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
1003     xran_status_t status = 0;
1004     int32_t rx_tti = (int32_t)XranGetTtiNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT);
1005     int32_t cc_id = 0;
1006     uint32_t nFrameIdx;
1007     uint32_t nSubframeIdx;
1008     uint32_t nSlotIdx;
1009     uint64_t nSecond;
1010
1011     uint32_t nXranTime  = xran_get_slot_idx(&nFrameIdx, &nSubframeIdx, &nSlotIdx, &nSecond);
1012     rx_tti = nFrameIdx*SUBFRAMES_PER_SYSTEMFRAME*SLOTNUM_PER_SUBFRAME
1013         + nSubframeIdx*SLOTNUM_PER_SUBFRAME
1014         + nSlotIdx;
1015
1016     if(rx_tti == 0)
1017        rx_tti = (xran_fs_get_max_slot_SFN()-1);
1018     else
1019        rx_tti -= 1; /* end of RX for prev TTI as measured against current OTA time */
1020
1021     if(p_xran_dev_ctx->xran2phy_mem_ready == 0)
1022         return;
1023
1024     /* U-Plane */
1025     for(cc_id = 0; cc_id < xran_get_num_cc(p_xran_dev_ctx); cc_id++) {
1026         struct xran_cb_tag *pTag = p_xran_dev_ctx->pCallbackTag[cc_id];
1027         pTag->slotiId = rx_tti;
1028         pTag->symbol  = 7; /* last 7 sym means full slot of Symb */
1029         status = XRAN_STATUS_SUCCESS;
1030         if(p_xran_dev_ctx->pCallback[cc_id])
1031             p_xran_dev_ctx->pCallback[cc_id](p_xran_dev_ctx->pCallbackTag[cc_id], status);
1032
1033         if(p_xran_dev_ctx->pPrachCallback[cc_id]){
1034             struct xran_cb_tag *pTag = p_xran_dev_ctx->pPrachCallbackTag[cc_id];
1035             pTag->slotiId = rx_tti;
1036             pTag->symbol  = 7; /* last 7 sym means full slot of Symb */
1037             p_xran_dev_ctx->pPrachCallback[cc_id](p_xran_dev_ctx->pPrachCallbackTag[cc_id], status);
1038         }
1039     }
1040
1041     MLogTask(PID_UP_UL_FULL_DEAD_LINE_CB, t1, MLogTick());
1042 }
1043
1044
1045 void tx_cp_ul_cb(struct rte_timer *tim, void *arg)
1046 {
1047     long t1 = MLogTick();
1048     int tti, buf_id;
1049     int i, ret;
1050     uint32_t slot_id, subframe_id, frame_id;
1051     int32_t cc_id;
1052     int ant_id, prach_port_id;
1053     uint16_t beam_id;
1054     uint8_t num_eAxc, num_CCPorts;
1055     uint8_t ctx_id;
1056
1057     void *pHandle;
1058     int num_list;
1059
1060     struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
1061     struct xran_prach_cp_config *pPrachCPConfig = &(p_xran_dev_ctx->PrachCPConfig);
1062     struct xran_timer_ctx *pTCtx = (struct xran_timer_ctx *)arg;
1063
1064     pHandle     = NULL;     // TODO: temp implemantation
1065
1066     if(xran_get_ru_category(pHandle) == XRAN_CATEGORY_A)
1067         num_eAxc    = xran_get_num_eAxc(pHandle);
1068     else
1069         num_eAxc    = xran_get_num_eAxcUl(pHandle);
1070
1071     num_CCPorts = xran_get_num_cc(pHandle);
1072     tti = pTCtx[(xran_lib_ota_tti & 1) ^ 1].tti_to_process;
1073     buf_id = tti % XRAN_N_FE_BUF_LEN;
1074     slot_id     = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME);
1075     subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME,  SUBFRAMES_PER_SYSTEMFRAME);
1076     frame_id    = XranGetFrameNum(tti,xran_getSfnSecStart(),SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
1077     if (tti == 0) {
1078         //Wrap around to next second
1079         frame_id = (frame_id + NUM_OF_FRAMES_PER_SECOND) & 0x3ff;
1080     }
1081     ctx_id      = XranGetSlotNum(tti, SLOTS_PER_SYSTEMFRAME) % XRAN_MAX_SECTIONDB_CTX;
1082
1083     if(first_call && p_xran_dev_ctx->enableCP) {
1084
1085         print_dbg("[%d]SFN %d sf %d slot %d\n", tti, frame_id, subframe_id, slot_id);
1086
1087         for(ant_id = 0; ant_id < num_eAxc; ++ant_id) {
1088             for(cc_id = 0; cc_id < num_CCPorts; cc_id++) {
1089                 if(xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_UL) == 1 ||
1090                     xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_SP) == 1 ){
1091                     /* start new section information list */
1092                     xran_cp_reset_section_info(pHandle, XRAN_DIR_UL, cc_id, ant_id, ctx_id);
1093                     num_list = xran_cp_create_and_send_section(pHandle, ant_id, XRAN_DIR_UL, tti, cc_id,
1094                         (struct xran_prb_map *)p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[buf_id][cc_id][ant_id].sBufferList.pBuffers->pData,
1095                         p_xran_dev_ctx->fh_cfg.ru_conf.xranCat, ctx_id);
1096                 } /* if(xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_UL) == 1 */
1097             } /* for(cc_id = 0; cc_id < num_CCPorts; cc_id++) */
1098         } /* for(ant_id = 0; ant_id < num_eAxc; ++ant_id) */
1099
1100         if(p_xran_dev_ctx->enablePrach) {
1101             uint32_t is_prach_slot = xran_is_prach_slot(subframe_id, slot_id);
1102             if(((frame_id % pPrachCPConfig->x) == pPrachCPConfig->y[0]) && (is_prach_slot==1)) {   //is prach slot
1103                 for(ant_id = 0; ant_id < num_eAxc; ++ant_id) {
1104                     for(cc_id = 0; cc_id < num_CCPorts; cc_id++) {
1105                         struct xran_cp_gen_params params;
1106                         struct xran_section_gen_info sect_geninfo[8];
1107                         struct rte_mbuf *mbuf = xran_ethdi_mbuf_alloc();
1108                         prach_port_id = ant_id + num_eAxc;
1109                         /* start new section information list */
1110                         xran_cp_reset_section_info(pHandle, XRAN_DIR_UL, cc_id, prach_port_id, ctx_id);
1111
1112                         beam_id = xran_get_beamid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id, slot_id);
1113                         ret = generate_cpmsg_prach(pHandle, &params, sect_geninfo, mbuf, p_xran_dev_ctx,
1114                                     frame_id, subframe_id, slot_id,
1115                                     beam_id, cc_id, prach_port_id,
1116                                     xran_get_cp_seqid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id));
1117                         if (ret == XRAN_STATUS_SUCCESS)
1118                             send_cpmsg(pHandle, mbuf, &params, sect_geninfo,
1119                                 cc_id, prach_port_id, xran_get_cp_seqid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id));
1120                     }
1121                 }
1122             }
1123         }
1124     } /* if(p_xran_dev_ctx->enableCP) */
1125
1126     MLogTask(PID_CP_UL_CB, t1, MLogTick());
1127 }
1128
1129 void ul_up_full_slot_cb(struct rte_timer *tim, void *arg)
1130 {
1131     long t1 = MLogTick();
1132     rte_pause();
1133     MLogTask(PID_TTI_CB_TO_PHY, t1, MLogTick());
1134 }
1135
1136 void tti_to_phy_cb(struct rte_timer *tim, void *arg)
1137 {
1138     long t1 = MLogTick();
1139     struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
1140
1141     p_xran_dev_ctx->phy_tti_cb_done = 1; /* DPDK called CB */
1142     if (first_call){
1143         if(p_xran_dev_ctx->ttiCb[XRAN_CB_TTI]){
1144             if(p_xran_dev_ctx->SkipTti[XRAN_CB_TTI] <= 0){
1145                 p_xran_dev_ctx->ttiCb[XRAN_CB_TTI](p_xran_dev_ctx->TtiCbParam[XRAN_CB_TTI]);
1146             }else{
1147                 p_xran_dev_ctx->SkipTti[XRAN_CB_TTI]--;
1148             }
1149         }
1150     } else {
1151         if(p_xran_dev_ctx->ttiCb[XRAN_CB_TTI]){
1152             int32_t tti = (int32_t)XranGetTtiNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT);
1153             uint32_t slot_id     = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME);
1154             uint32_t subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME,  SUBFRAMES_PER_SYSTEMFRAME);
1155             uint32_t frame_id = XranGetFrameNum(tti,xran_getSfnSecStart(),SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
1156             if((frame_id == xran_max_frame)&&(subframe_id==9)&&(slot_id == SLOTNUM_PER_SUBFRAME-1)) {  //(tti == xran_fs_get_max_slot()-1)
1157                 first_call = 1;
1158             }
1159         }
1160     }
1161
1162     MLogTask(PID_TTI_CB_TO_PHY, t1, MLogTick());
1163 }
1164
1165 int xran_timing_source_thread(void *args)
1166 {
1167     int res = 0;
1168     cpu_set_t cpuset;
1169     int32_t   do_reset = 0;
1170     uint64_t  t1 = 0;
1171     uint64_t  delta;
1172     int32_t   result1,i,j;
1173     uint32_t delay_cp_dl;
1174     uint32_t delay_cp_ul;
1175     uint32_t delay_up;
1176     uint32_t delay_up_ul;
1177     uint32_t delay_cp2up;
1178     uint32_t sym_cp_dl;
1179     uint32_t sym_cp_ul;
1180     uint32_t sym_up_ul;
1181     int32_t sym_up;
1182     struct sched_param sched_param;
1183     struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
1184     uint64_t tWake = 0, tWakePrev = 0, tUsed = 0;
1185     struct cb_elem_entry * cb_elm = NULL;
1186
1187     /* ToS = Top of Second start +- 1.5us */
1188     struct timespec ts;
1189
1190     char buff[100];
1191
1192     xran_core_used = rte_lcore_id();
1193     printf("%s [CPU %2d] [PID: %6d]\n", __FUNCTION__,  rte_lcore_id(), getpid());
1194
1195     /* set main thread affinity mask to CPU2 */
1196     sched_param.sched_priority = 98;
1197
1198     CPU_ZERO(&cpuset);
1199     CPU_SET(p_xran_dev_ctx->fh_init.io_cfg.timing_core, &cpuset);
1200     if (result1 = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset))
1201     {
1202         printf("pthread_setaffinity_np failed: coreId = 2, result1 = %d\n",result1);
1203     }
1204     if ((result1 = pthread_setschedparam(pthread_self(), 1, &sched_param)))
1205     {
1206         printf("priority is not changed: coreId = 2, result1 = %d\n",result1);
1207     }
1208
1209     if (p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) {
1210         do {
1211            timespec_get(&ts, TIME_UTC);
1212         }while (ts.tv_nsec >1500);
1213         struct tm * ptm = gmtime(&ts.tv_sec);
1214         if(ptm){
1215             strftime(buff, sizeof buff, "%D %T", ptm);
1216             printf("O-DU: thread_run start time: %s.%09ld UTC [%ld]\n", buff, ts.tv_nsec, interval_us);
1217         }
1218
1219         delay_cp_dl = interval_us - p_xran_dev_ctx->fh_init.T1a_max_cp_dl;
1220         delay_cp_ul = interval_us - p_xran_dev_ctx->fh_init.T1a_max_cp_ul;
1221         delay_up    = p_xran_dev_ctx->fh_init.T1a_max_up;
1222         delay_up_ul = p_xran_dev_ctx->fh_init.Ta4_max;
1223
1224         delay_cp2up = delay_up-delay_cp_dl;
1225
1226         sym_cp_dl = delay_cp_dl*1000/(interval_us*1000/N_SYM_PER_SLOT)+1;
1227         sym_cp_ul = delay_cp_ul*1000/(interval_us*1000/N_SYM_PER_SLOT)+1;
1228         sym_up_ul = delay_up_ul*1000/(interval_us*1000/N_SYM_PER_SLOT);
1229         p_xran_dev_ctx->sym_up = sym_up = -(delay_up*1000/(interval_us*1000/N_SYM_PER_SLOT));
1230         p_xran_dev_ctx->sym_up_ul = sym_up_ul = (delay_up_ul*1000/(interval_us*1000/N_SYM_PER_SLOT)+1);
1231
1232         printf("Start C-plane DL %d us after TTI  [trigger on sym %d]\n", delay_cp_dl, sym_cp_dl);
1233         printf("Start C-plane UL %d us after TTI  [trigger on sym %d]\n", delay_cp_ul, sym_cp_ul);
1234         printf("Start U-plane DL %d us before OTA [offset  in sym %d]\n", delay_up, sym_up);
1235         printf("Start U-plane UL %d us OTA        [offset  in sym %d]\n", delay_up_ul, sym_up_ul);
1236
1237         printf("C-plane to U-plane delay %d us after TTI\n", delay_cp2up);
1238         printf("Start Sym timer %ld ns\n", TX_TIMER_INTERVAL/N_SYM_PER_SLOT);
1239
1240         cb_elm = xran_create_cb(xran_timer_arm, tx_cp_dl_cb);
1241         if(cb_elm){
1242             LIST_INSERT_HEAD(&p_xran_dev_ctx->sym_cb_list_head[0][sym_cp_dl],
1243                              cb_elm,
1244                              pointers);
1245         } else {
1246             print_err("cb_elm is NULL\n");
1247             res =  -1;
1248             goto err0;
1249         }
1250
1251         cb_elm = xran_create_cb(xran_timer_arm, tx_cp_ul_cb);
1252         if(cb_elm){
1253             LIST_INSERT_HEAD(&p_xran_dev_ctx->sym_cb_list_head[0][sym_cp_ul],
1254                              cb_elm,
1255                              pointers);
1256         } else {
1257             print_err("cb_elm is NULL\n");
1258             res =  -1;
1259             goto err0;
1260         }
1261
1262         /* Full slot UL OTA + delay_up_ul */
1263         cb_elm = xran_create_cb(xran_timer_arm, rx_ul_deadline_full_cb);
1264         if(cb_elm){
1265             LIST_INSERT_HEAD(&p_xran_dev_ctx->sym_cb_list_head[0][sym_up_ul],
1266                              cb_elm,
1267                              pointers);
1268         } else {
1269             print_err("cb_elm is NULL\n");
1270             res =  -1;
1271             goto err0;
1272         }
1273
1274         /* Half slot UL OTA + delay_up_ul*/
1275         cb_elm = xran_create_cb(xran_timer_arm, rx_ul_deadline_half_cb);
1276         if(cb_elm){
1277             LIST_INSERT_HEAD(&p_xran_dev_ctx->sym_cb_list_head[0][sym_up_ul + N_SYM_PER_SLOT/2],
1278                          cb_elm,
1279                          pointers);
1280         } else {
1281             print_err("cb_elm is NULL\n");
1282             res =  -1;
1283             goto err0;
1284         }
1285     } else {    // APP_O_RU
1286         /* calcualte when to send UL U-plane */
1287         delay_up = p_xran_dev_ctx->fh_init.Ta3_min;
1288         p_xran_dev_ctx->sym_up = sym_up = delay_up*1000/(interval_us*1000/N_SYM_PER_SLOT)+1;
1289         printf("Start UL U-plane %d us after OTA [offset in sym %d]\n", delay_up, sym_up);
1290         do {
1291            timespec_get(&ts, TIME_UTC);
1292         }while (ts.tv_nsec >1500);
1293         struct tm * ptm = gmtime(&ts.tv_sec);
1294         if(ptm){
1295             strftime(buff, sizeof buff, "%D %T", ptm);
1296             printf("RU: thread_run start time: %s.%09ld UTC [%ld]\n", buff, ts.tv_nsec, interval_us);
1297         }
1298     }
1299
1300     printf("interval_us %ld\n", interval_us);
1301     do {
1302        timespec_get(&ts, TIME_UTC);
1303     }while (ts.tv_nsec == 0);
1304
1305     while(1) {
1306         /* Update Usage Stats */
1307         tWake = xran_tick();
1308         xran_used_tick += tUsed;
1309         if (tWakePrev)
1310         {
1311             xran_total_tick += get_ticks_diff(tWake, tWakePrev);
1312         }
1313         tWakePrev = tWake;
1314         tUsed = 0;
1315
1316         delta = poll_next_tick(interval_us*1000L/N_SYM_PER_SLOT, &tUsed);
1317         if (XRAN_STOPPED == xran_if_current_state)
1318             break;
1319
1320         if (likely(XRAN_RUNNING == xran_if_current_state))
1321             sym_ota_cb(&sym_timer, timer_ctx, &tUsed);
1322     }
1323
1324     err0:
1325     for (i = 0; i< XRAN_MAX_SECTOR_NR; i++){
1326         for (j = 0; j< XRAN_NUM_OF_SYMBOL_PER_SLOT; j++){
1327             struct cb_elem_entry *cb_elm;
1328             LIST_FOREACH(cb_elm, &p_xran_dev_ctx->sym_cb_list_head[i][j], pointers){
1329                 if(cb_elm){
1330                     LIST_REMOVE(cb_elm, pointers);
1331                     xran_destroy_cb(cb_elm);
1332                 }
1333             }
1334         }
1335     }
1336
1337     printf("Closing timing source thread...tx counter %lu, rx counter %lu\n", tx_counter, rx_counter);
1338     return res;
1339 }
1340
1341 /* Handle ecpri format. */
1342 int handle_ecpri_ethertype(struct rte_mbuf *pkt, uint64_t rx_time)
1343 {
1344     const struct xran_ecpri_hdr *ecpri_hdr;
1345     unsigned long t1;
1346     int32_t ret = MBUF_FREE;
1347
1348     if (rte_pktmbuf_data_len(pkt) < sizeof(struct xran_ecpri_hdr)) {
1349         print_err("Packet too short - %d bytes", rte_pktmbuf_data_len(pkt));
1350         return 0;
1351     }
1352
1353     /* check eCPRI header. */
1354     ecpri_hdr = rte_pktmbuf_mtod(pkt, struct xran_ecpri_hdr *);
1355     if(ecpri_hdr == NULL){
1356         print_err("ecpri_hdr error\n");
1357         return MBUF_FREE;
1358     }
1359
1360     rx_bytes_counter += rte_pktmbuf_pkt_len(pkt);
1361     switch(ecpri_hdr->cmnhdr.ecpri_mesg_type) {
1362         case ECPRI_IQ_DATA:
1363            // t1 = MLogTick();
1364             ret = process_mbuf(pkt);
1365           //  MLogTask(PID_PROCESS_UP_PKT, t1, MLogTick());
1366             break;
1367         // For RU emulation
1368         case ECPRI_RT_CONTROL_DATA:
1369             t1 = MLogTick();
1370             if(xran_dev_get_ctx()->fh_init.io_cfg.id == O_RU) {
1371                 ret = process_cplane(pkt);
1372             } else {
1373                 print_err("O-DU recevied C-Plane message!");
1374             }
1375             MLogTask(PID_PROCESS_CP_PKT, t1, MLogTick());
1376             break;
1377         default:
1378             print_err("Invalid eCPRI message type - %d", ecpri_hdr->cmnhdr.ecpri_mesg_type);
1379         }
1380
1381     return ret;
1382 }
1383
1384 int xran_process_prach_sym(void *arg,
1385                         struct rte_mbuf *mbuf,
1386                         void *iq_data_start,
1387                         uint16_t size,
1388                         uint8_t CC_ID,
1389                         uint8_t Ant_ID,
1390                         uint8_t frame_id,
1391                         uint8_t subframe_id,
1392                         uint8_t slot_id,
1393                         uint8_t symb_id,
1394                         uint16_t num_prbu,
1395                         uint16_t start_prbu,
1396                         uint16_t sym_inc,
1397                         uint16_t rb,
1398                         uint16_t sect_id,
1399                         uint32_t *mb_free)
1400 {
1401     char        *pos = NULL;
1402     struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
1403     uint8_t symb_id_offset;
1404     uint32_t tti = 0;
1405     xran_status_t status;
1406     void *pHandle = NULL;
1407     struct rte_mbuf *mb;
1408
1409     uint16_t iq_sample_size_bits = 16;
1410
1411     if(p_xran_dev_ctx->xran2phy_mem_ready == 0)
1412         return 0;
1413
1414     tti = frame_id * SLOTS_PER_SYSTEMFRAME + subframe_id * SLOTNUM_PER_SUBFRAME + slot_id;
1415
1416     status = tti << 16 | symb_id;
1417
1418     if(CC_ID < XRAN_MAX_SECTOR_NR && Ant_ID < XRAN_MAX_ANTENNA_NR && symb_id < XRAN_NUM_OF_SYMBOL_PER_SLOT){
1419         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
1420         pos = (char*) p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id_offset].pData;
1421         if(pos && iq_data_start && size){
1422             if (p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder == XRAN_CPU_LE_BYTE_ORDER) {
1423                 int idx = 0;
1424                 uint16_t *psrc = (uint16_t *)iq_data_start;
1425                 uint16_t *pdst = (uint16_t *)pos;
1426                 /* network byte (be) order of IQ to CPU byte order (le) */
1427                 for (idx = 0; idx < size/sizeof(int16_t); idx++){
1428                     pdst[idx]  = (psrc[idx]>>8) | (psrc[idx]<<8); //rte_be_to_cpu_16(psrc[idx]);
1429                 }
1430                 *mb_free = MBUF_FREE;
1431             }else {
1432                 mb = p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id_offset].pCtrl;
1433                 if(mb){
1434                    rte_pktmbuf_free(mb);
1435                 }else{
1436                    print_err("mb==NULL\n");
1437                 }
1438                 p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id_offset].pData = iq_data_start;
1439                 p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id_offset].pCtrl = mbuf;
1440                 *mb_free = MBUF_KEEP;
1441             }
1442         } else {
1443             print_err("pos %p iq_data_start %p size %d\n",pos, iq_data_start, size);
1444         }
1445     } else {
1446         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);
1447     }
1448
1449 /*    if (symb_id == p_xran_dev_ctx->prach_last_symbol[CC_ID] ){
1450         p_xran_dev_ctx->rx_packet_prach_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID][symb_id]++;
1451         if(p_xran_dev_ctx->rx_packet_prach_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID][symb_id] >= xran_get_num_eAxc(pHandle)){
1452             if(p_xran_dev_ctx->pPrachCallback[0])
1453                p_xran_dev_ctx->pPrachCallback[0](p_xran_dev_ctx->pPrachCallbackTag[0], status);
1454             p_xran_dev_ctx->rx_packet_prach_tracker[tti % XRAN_N_FE_BUF_LEN][CC_ID][symb_id] = 0;
1455         }
1456     }
1457 */
1458     return size;
1459 }
1460
1461 int32_t xran_process_srs_sym(void *arg,
1462                         struct rte_mbuf *mbuf,
1463                         void *iq_data_start,
1464                         uint16_t size,
1465                         uint8_t CC_ID,
1466                         uint8_t Ant_ID,
1467                         uint8_t frame_id,
1468                         uint8_t subframe_id,
1469                         uint8_t slot_id,
1470                         uint8_t symb_id,
1471                         uint16_t num_prbu,
1472                         uint16_t start_prbu,
1473                         uint16_t sym_inc,
1474                         uint16_t rb,
1475                         uint16_t sect_id,
1476                         uint32_t *mb_free)
1477 {
1478     char        *pos = NULL;
1479     struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
1480     uint32_t tti = 0;
1481     xran_status_t status;
1482     void *pHandle = NULL;
1483     struct rte_mbuf *mb = NULL;
1484
1485     uint16_t iq_sample_size_bits = 16;
1486
1487     if(p_xran_dev_ctx->xran2phy_mem_ready == 0)
1488         return 0;
1489
1490     tti = frame_id * SLOTS_PER_SYSTEMFRAME + subframe_id * SLOTNUM_PER_SUBFRAME + slot_id;
1491
1492     status = tti << 16 | symb_id;
1493
1494     if(CC_ID < XRAN_MAX_SECTOR_NR && Ant_ID < p_xran_dev_ctx->fh_cfg.nAntElmTRx && symb_id < XRAN_NUM_OF_SYMBOL_PER_SLOT) {
1495         pos = (char*) p_xran_dev_ctx->sFHSrsRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pData;
1496         pos += start_prbu * N_SC_PER_PRB*(iq_sample_size_bits/8)*2;
1497         if(pos && iq_data_start && size){
1498             if (p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder == XRAN_CPU_LE_BYTE_ORDER) {
1499                 int idx = 0;
1500                 uint16_t *psrc = (uint16_t *)iq_data_start;
1501                 uint16_t *pdst = (uint16_t *)pos;
1502                 rte_panic("XRAN_CPU_LE_BYTE_ORDER is not supported 0x16%lx\n", (long)mb);
1503                 /* network byte (be) order of IQ to CPU byte order (le) */
1504                 for (idx = 0; idx < size/sizeof(int16_t); idx++){
1505                     pdst[idx]  = (psrc[idx]>>8) | (psrc[idx]<<8); //rte_be_to_cpu_16(psrc[idx]);
1506                 }
1507             } else if (likely(p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder == XRAN_NE_BE_BYTE_ORDER)){
1508                 if (likely (p_xran_dev_ctx->fh_init.mtu >=
1509                               p_xran_dev_ctx->fh_cfg.nULRBs * N_SC_PER_PRB*(iq_sample_size_bits/8)*2)) {
1510                     /* no fragmentation */
1511                     mb = p_xran_dev_ctx->sFHSrsRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pCtrl;
1512                     if(mb){
1513                        rte_pktmbuf_free(mb);
1514                     }else{
1515                        print_err("mb==NULL\n");
1516                     }
1517                     p_xran_dev_ctx->sFHSrsRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pData = iq_data_start;
1518                     p_xran_dev_ctx->sFHSrsRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pCtrl = mbuf;
1519                     *mb_free = MBUF_KEEP;
1520                 } else {
1521                     /* packet can be fragmented copy RBs */
1522                     rte_memcpy(pos, iq_data_start, size);
1523                     *mb_free = MBUF_FREE;
1524                 }
1525             }
1526         } else {
1527             print_err("pos %p iq_data_start %p size %d\n",pos, iq_data_start, size);
1528         }
1529     } else {
1530         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);
1531     }
1532
1533     return size;
1534 }
1535
1536 int32_t xran_pkt_validate(void *arg,
1537                         struct rte_mbuf *mbuf,
1538                         void *iq_data_start,
1539                         uint16_t size,
1540                         uint8_t CC_ID,
1541                         uint8_t Ant_ID,
1542                         uint8_t frame_id,
1543                         uint8_t subframe_id,
1544                         uint8_t slot_id,
1545                         uint8_t symb_id,
1546                         struct ecpri_seq_id *seq_id,
1547                         uint16_t num_prbu,
1548                         uint16_t start_prbu,
1549                         uint16_t sym_inc,
1550                         uint16_t rb,
1551                         uint16_t sect_id)
1552 {
1553     struct xran_device_ctx * pctx = xran_dev_get_ctx();
1554     struct xran_common_counters *pCnt = &pctx->fh_counters;
1555
1556     if(pctx->fh_init.io_cfg.id == O_DU) {
1557         if(xran_check_upul_seqid(NULL, CC_ID, Ant_ID, slot_id, seq_id->seq_id) != XRAN_STATUS_SUCCESS) {
1558             pCnt->Rx_pkt_dupl++;
1559             return (XRAN_STATUS_FAIL);
1560         }
1561     }else if(pctx->fh_init.io_cfg.id == O_RU) {
1562         if(xran_check_updl_seqid(NULL, CC_ID, Ant_ID, slot_id, seq_id->seq_id) != XRAN_STATUS_SUCCESS) {
1563             pCnt->Rx_pkt_dupl++;
1564             return (XRAN_STATUS_FAIL);
1565         }
1566     }else {
1567         print_err("incorrect dev type %d\n", pctx->fh_init.io_cfg.id);
1568     }
1569
1570     rx_counter++;
1571
1572     pCnt->Rx_on_time++;
1573     pCnt->Total_msgs_rcvd++;
1574
1575     return XRAN_STATUS_SUCCESS;
1576 }
1577
1578 int32_t xran_process_rx_sym(void *arg,
1579                         struct rte_mbuf *mbuf,
1580                         void *iq_data_start,
1581                         uint16_t size,
1582                         uint8_t CC_ID,
1583                         uint8_t Ant_ID,
1584                         uint8_t frame_id,
1585                         uint8_t subframe_id,
1586                         uint8_t slot_id,
1587                         uint8_t symb_id,
1588                         uint16_t num_prbu,
1589                         uint16_t start_prbu,
1590                         uint16_t sym_inc,
1591                         uint16_t rb,
1592                         uint16_t sect_id,
1593                         uint32_t *mb_free)
1594 {
1595     char        *pos = NULL;
1596     struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
1597     uint32_t tti = 0;
1598     xran_status_t status;
1599     void *pHandle = NULL;
1600     struct rte_mbuf *mb = NULL;
1601     struct xran_prb_map * pRbMap    = NULL;
1602     struct xran_prb_elm * prbMapElm = NULL;
1603
1604     uint16_t iq_sample_size_bits = 16;
1605
1606     tti = frame_id * SLOTS_PER_SYSTEMFRAME + subframe_id * SLOTNUM_PER_SUBFRAME + slot_id;
1607
1608     status = tti << 16 | symb_id;
1609
1610     if(CC_ID < XRAN_MAX_SECTOR_NR && Ant_ID < XRAN_MAX_ANTENNA_NR && symb_id < XRAN_NUM_OF_SYMBOL_PER_SLOT){
1611         pos = (char*) p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pData;
1612         pRbMap = (struct xran_prb_map *) p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers->pData;
1613         if(pRbMap){
1614             prbMapElm = &pRbMap->prbMap[sect_id];
1615             if(sect_id >= pRbMap->nPrbElm) {
1616                 print_err("sect_id %d !=pRbMap->nPrbElm %d\n", sect_id,pRbMap->nPrbElm);
1617                 *mb_free = MBUF_FREE;
1618                 return size;
1619             }
1620         } else {
1621             print_err("pRbMap==NULL\n");
1622             *mb_free = MBUF_FREE;
1623             return size;
1624         }
1625
1626         pos += start_prbu * N_SC_PER_PRB*(iq_sample_size_bits/8)*2;
1627         if(pos && iq_data_start && size){
1628             if (p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder == XRAN_CPU_LE_BYTE_ORDER) {
1629                 int idx = 0;
1630                 uint16_t *psrc = (uint16_t *)iq_data_start;
1631                 uint16_t *pdst = (uint16_t *)pos;
1632                 rte_panic("XRAN_CPU_LE_BYTE_ORDER is not supported 0x16%lx\n", (long)mb);
1633                 /* network byte (be) order of IQ to CPU byte order (le) */
1634                 for (idx = 0; idx < size/sizeof(int16_t); idx++){
1635                     pdst[idx]  = (psrc[idx]>>8) | (psrc[idx]<<8); //rte_be_to_cpu_16(psrc[idx]);
1636                 }
1637             } else if (likely(p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder == XRAN_NE_BE_BYTE_ORDER)){
1638                 if (/*likely (p_xran_dev_ctx->fh_init.mtu >=
1639                               p_xran_dev_ctx->fh_cfg.nULRBs * N_SC_PER_PRB*(iq_sample_size_bits/8)*2)
1640                               &&  p_xran_dev_ctx->fh_init.io_cfg.id == O_DU*/ 1) {
1641                     if (pRbMap->nPrbElm == 1){
1642                         /* no fragmentation */
1643                         mb = p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pCtrl;
1644                         if(mb){
1645                            rte_pktmbuf_free(mb);
1646                         }else{
1647                            print_err("mb==NULL\n");
1648                         }
1649                         p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pData = iq_data_start;
1650                         p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pCtrl = mbuf;
1651                         *mb_free = MBUF_KEEP;
1652                     } else {
1653                         prbMapElm = &pRbMap->prbMap[sect_id];
1654                         struct xran_section_desc *p_sec_desc =  prbMapElm->p_sec_desc[symb_id];
1655                         if(p_sec_desc){
1656                             mb = p_sec_desc->pCtrl;
1657                             if(mb){
1658                                rte_pktmbuf_free(mb);
1659                             }
1660                             p_sec_desc->pData         = iq_data_start;
1661                             p_sec_desc->pCtrl         = mbuf;
1662                             p_sec_desc->iq_buffer_len = size;
1663                             p_sec_desc->iq_buffer_offset = RTE_PTR_DIFF(iq_data_start, mbuf);
1664                         } else {
1665                             print_err("p_sec_desc==NULL\n");
1666                             *mb_free = MBUF_FREE;
1667                             return size;
1668                         }
1669                         *mb_free = MBUF_KEEP;
1670                     }
1671                 } else {
1672                     /* packet can be fragmented copy RBs */
1673                     rte_memcpy(pos, iq_data_start, size);
1674                     *mb_free = MBUF_FREE;
1675                 }
1676             }
1677         } else {
1678             print_err("pos %p iq_data_start %p size %d\n",pos, iq_data_start, size);
1679         }
1680     } else {
1681         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);
1682     }
1683
1684     return size;
1685 }
1686
1687 /* Send burst of packets on an output interface */
1688 static inline int
1689 xran_send_burst(struct xran_device_ctx *dev, uint16_t n, uint16_t port)
1690 {
1691     struct rte_mbuf **m_table;
1692     struct rte_mbuf *m;
1693     int32_t i   = 0;
1694     int j;
1695     int32_t ret = 0;
1696
1697     m_table = (struct rte_mbuf **)dev->tx_mbufs[port].m_table;
1698
1699     for(i = 0; i < n; i++){
1700         rte_mbuf_sanity_check(m_table[i], 0);
1701         /*rte_pktmbuf_dump(stdout, m_table[i], 256);*/
1702         tx_counter++;
1703         tx_bytes_counter += rte_pktmbuf_pkt_len(m_table[i]);
1704         ret += dev->send_upmbuf2ring(m_table[i], ETHER_TYPE_ECPRI);
1705     }
1706
1707
1708     if (unlikely(ret < n)) {
1709         print_err("ret < n\n");
1710     }
1711
1712     return 0;
1713 }
1714
1715 int32_t xran_process_tx_sym_cp_off(uint8_t ctx_id, uint32_t tti, int32_t cc_id, int32_t ant_id, uint32_t frame_id, uint32_t subframe_id, uint32_t slot_id, uint32_t sym_id,
1716     int32_t do_srs)
1717 {
1718     int32_t     retval = 0;
1719     uint64_t    t1 = MLogTick();
1720
1721     void        *pHandle = NULL;
1722     char        *pos = NULL;
1723     char        *p_sec_iq = NULL;
1724     char        *p_sect_iq = NULL;
1725     void        *mb  = NULL;
1726     int         prb_num = 0;
1727     uint16_t    iq_sample_size_bits = 16; // TODO: make dynamic per
1728
1729     struct xran_prb_map *prb_map = NULL;
1730     uint8_t  num_ant_elm  = 0;
1731
1732     struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
1733     struct xran_prach_cp_config *pPrachCPConfig = &(p_xran_dev_ctx->PrachCPConfig);
1734     struct xran_srs_config *p_srs_cfg = &(p_xran_dev_ctx->srs_cfg);
1735     num_ant_elm = xran_get_num_ant_elm(pHandle);
1736     enum xran_pkt_dir direction;
1737
1738     struct rte_mbuf *eth_oran_hdr = NULL;
1739     char        *ext_buff = NULL;
1740     uint16_t    ext_buff_len = 0;
1741     struct rte_mbuf *tmp = NULL;
1742     rte_iova_t ext_buff_iova = 0;
1743
1744     struct rte_mbuf_ext_shared_info * p_share_data = &share_data[tti % XRAN_N_FE_BUF_LEN];
1745
1746     if(p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) {
1747         direction = XRAN_DIR_DL; /* O-DU */
1748         prb_num = p_xran_dev_ctx->fh_cfg.nDLRBs;
1749     } else {
1750         direction = XRAN_DIR_UL; /* RU */
1751         prb_num = p_xran_dev_ctx->fh_cfg.nULRBs;
1752     }
1753
1754     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
1755             || xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_SP) ==  1
1756             || xran_fs_get_slot_type(cc_id, tti, XRAN_SLOT_TYPE_FDD) ==  1){
1757
1758         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)
1759            || xran_fs_get_symbol_type(cc_id, tti, sym_id) == XRAN_SYMBOL_TYPE_FDD){
1760
1761             if(iq_sample_size_bits != 16)
1762                 print_err("Incorrect iqWidth %d\n", iq_sample_size_bits );
1763
1764             pos = (char*) p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
1765             mb  = (void*) p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_id].pCtrl;
1766             prb_map  = (struct xran_prb_map *) p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers->pData;
1767
1768
1769             if(prb_map){
1770                 int32_t elmIdx = 0;
1771                 for (elmIdx = 0; elmIdx < prb_map->nPrbElm; elmIdx++){
1772                     uint16_t sec_id  = elmIdx;
1773                     struct xran_prb_elm * prb_map_elm = &prb_map->prbMap[elmIdx];
1774                     struct xran_section_desc * p_sec_desc = NULL;
1775
1776                     if(prb_map_elm == NULL){
1777                         rte_panic("p_sec_desc == NULL\n");
1778                     }
1779
1780                     p_sec_desc =  prb_map_elm->p_sec_desc[sym_id];
1781
1782                     if(p_sec_desc == NULL){
1783                         rte_panic("p_sec_desc == NULL\n");
1784                     }
1785
1786 #if 1
1787                     p_sec_iq = ((char*)pos + p_sec_desc->iq_buffer_offset);
1788
1789                     /* calculete offset for external buffer */
1790                     ext_buff_len = p_sec_desc->iq_buffer_len;
1791                     ext_buff = p_sec_iq - (RTE_PKTMBUF_HEADROOM +
1792                                     sizeof (struct xran_ecpri_hdr) +
1793                                     sizeof (struct radio_app_common_hdr) +
1794                                     sizeof(struct data_section_hdr));
1795
1796                     ext_buff_len += RTE_PKTMBUF_HEADROOM +
1797                                     sizeof (struct xran_ecpri_hdr) +
1798                                     sizeof (struct radio_app_common_hdr) +
1799                                     sizeof(struct data_section_hdr) + 18;
1800
1801                     if(prb_map_elm->compMethod != XRAN_COMPMETHOD_NONE){
1802                         ext_buff     -= sizeof (struct data_section_compression_hdr);
1803                         ext_buff_len += sizeof (struct data_section_compression_hdr);
1804                     }
1805
1806                     eth_oran_hdr =  rte_pktmbuf_alloc(_eth_mbuf_pool_small);
1807
1808                     if (unlikely (( eth_oran_hdr) == NULL)) {
1809                         rte_panic("Failed rte_pktmbuf_alloc\n");
1810                     }
1811
1812                     p_share_data->free_cb = extbuf_free_callback;
1813                     p_share_data->fcb_opaque = NULL;
1814                     rte_mbuf_ext_refcnt_set(p_share_data, 1);
1815
1816                     ext_buff_iova = rte_mempool_virt2iova(mb);
1817                     if (unlikely (( ext_buff_iova) == 0)) {
1818                         rte_panic("Failed rte_mem_virt2iova \n");
1819                     }
1820
1821                     if (unlikely (( (rte_iova_t)ext_buff_iova) == RTE_BAD_IOVA)) {
1822                         rte_panic("Failed rte_mem_virt2iova RTE_BAD_IOVA \n");
1823                     }
1824
1825                     rte_pktmbuf_attach_extbuf(eth_oran_hdr,
1826                                               ext_buff,
1827                                               ext_buff_iova + RTE_PTR_DIFF(ext_buff , mb),
1828                                               ext_buff_len,
1829                                               p_share_data);
1830
1831                     rte_pktmbuf_reset_headroom(eth_oran_hdr);
1832
1833                     tmp = (struct rte_mbuf *)rte_pktmbuf_prepend(eth_oran_hdr, sizeof(struct ether_hdr));
1834                     if (unlikely (( tmp) == NULL)) {
1835                         rte_panic("Failed rte_pktmbuf_prepend \n");
1836                     }
1837                     mb = eth_oran_hdr;
1838
1839                     /* first all PRBs */
1840                     prepare_symbol_ex(direction, sec_id,
1841                                       mb,
1842                                       (struct rb_map *)p_sec_iq,
1843                                       prb_map_elm->compMethod,
1844                                       prb_map_elm->iqWidth,
1845                                       p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder,
1846                                       frame_id, subframe_id, slot_id, sym_id,
1847                                       prb_map_elm->nRBStart, prb_map_elm->nRBSize,
1848                                       cc_id, ant_id,
1849                                       (p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) ?
1850                                           xran_get_updl_seqid(pHandle, cc_id, ant_id) :
1851                                           xran_get_upul_seqid(pHandle, cc_id, ant_id),
1852                                       0);
1853
1854                     rte_mbuf_sanity_check((struct rte_mbuf *)mb, 0);
1855                     tx_counter++;
1856                     tx_bytes_counter += rte_pktmbuf_pkt_len((struct rte_mbuf *)mb);
1857                     p_xran_dev_ctx->send_upmbuf2ring((struct rte_mbuf *)mb, ETHER_TYPE_ECPRI);
1858 #else
1859         p_sect_iq = pos + p_sec_desc->iq_buffer_offset;
1860         prb_num = prb_map_elm->nRBSize;
1861
1862         if( prb_num > 136 || prb_num == 0) {
1863             /* first 136 PRBs */
1864             rte_panic("first 136 PRBs\n");
1865             send_symbol_ex(direction,
1866                             sec_id,
1867                             NULL,
1868                             (struct rb_map *)p_sect_iq,
1869                             p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder,
1870                             frame_id, subframe_id, slot_id, sym_id,
1871                             0, 136,
1872                             cc_id, ant_id,
1873                             (p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) ?
1874                                 xran_get_updl_seqid(pHandle, cc_id, ant_id) :
1875                                 xran_get_upul_seqid(pHandle, cc_id, ant_id));
1876
1877              pos += 136 * N_SC_PER_PRB * (iq_sample_size_bits/8)*2;
1878              /* last 137 PRBs */
1879              send_symbol_ex(direction, sec_id,
1880                              NULL,
1881                              (struct rb_map *)p_sect_iq,
1882                              p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder,
1883                              frame_id, subframe_id, slot_id, sym_id,
1884                              136, 137,
1885                              cc_id, ant_id,
1886                              (p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) ?
1887                                 xran_get_updl_seqid(pHandle, cc_id, ant_id) :
1888                                 xran_get_upul_seqid(pHandle,  cc_id, ant_id));
1889             retval = 1;
1890         } else {
1891             send_symbol_ex(direction,
1892                     sec_id, /* xran_alloc_sectionid(pHandle, direction, cc_id, ant_id, slot_id)*/
1893                     /*(struct rte_mbuf *)mb*/ NULL,
1894                     (struct rb_map *)p_sect_iq,
1895                     p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder,
1896                     frame_id, subframe_id, slot_id, sym_id,
1897                     prb_map_elm->nRBStart, prb_map_elm->nRBSize,
1898                     cc_id, ant_id,
1899                     (p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) ?
1900                         xran_get_updl_seqid(pHandle, cc_id, ant_id) :
1901                         xran_get_upul_seqid(pHandle, cc_id, ant_id));
1902             retval = 1;
1903         }
1904
1905 #endif
1906
1907                 }
1908             } else {
1909                 printf("(%d %d %d %d) prb_map == NULL\n", tti % XRAN_N_FE_BUF_LEN, cc_id, ant_id, sym_id);
1910             }
1911
1912             if(p_xran_dev_ctx->enablePrach
1913               && (p_xran_dev_ctx->fh_init.io_cfg.id == O_RU)) {   /* Only RU needs to send PRACH I/Q */
1914                 uint32_t is_prach_slot = xran_is_prach_slot(subframe_id, slot_id);
1915                 if(((frame_id % pPrachCPConfig->x) == pPrachCPConfig->y[0])
1916                         && (is_prach_slot == 1)
1917                         && (sym_id >= p_xran_dev_ctx->prach_start_symbol[cc_id])
1918                         && (sym_id <= p_xran_dev_ctx->prach_last_symbol[cc_id])) {  //is prach slot
1919                         int prach_port_id = ant_id + pPrachCPConfig->eAxC_offset;
1920                         pos = (char*) p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[0].pData;
1921                         pos += (sym_id - p_xran_dev_ctx->prach_start_symbol[cc_id]) * pPrachCPConfig->numPrbc * N_SC_PER_PRB * 4;
1922                         mb  = NULL;//(void*) p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[0].pCtrl;
1923
1924                         send_symbol_ex(direction,
1925                                 xran_alloc_sectionid(pHandle, direction, cc_id, prach_port_id, slot_id),
1926                                 (struct rte_mbuf *)mb,
1927                                 (struct rb_map *)pos,
1928                                 p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder,
1929                                 frame_id, subframe_id, slot_id, sym_id,
1930                                 pPrachCPConfig->startPrbc, pPrachCPConfig->numPrbc,
1931                                 cc_id, prach_port_id,
1932                                 xran_get_upul_seqid(pHandle, cc_id, prach_port_id));
1933                         retval = 1;
1934                 } /* if((frame_id % pPrachCPConfig->x == pPrachCPConfig->y[0]) .... */
1935             } /* if(p_xran_dev_ctx->enablePrach ..... */
1936
1937
1938             if(p_xran_dev_ctx->enableSrs && (p_xran_dev_ctx->fh_init.io_cfg.id == O_RU)){
1939                 if( p_srs_cfg->symbMask & (1 << sym_id) /* is SRS symbol */
1940                     && do_srs) {
1941                     int32_t ant_elm_id = 0;
1942
1943                     for (ant_elm_id = 0; ant_elm_id < num_ant_elm; ant_elm_id++){
1944                         int32_t ant_elm_eAxC_id = ant_elm_id + p_srs_cfg->eAxC_offset;
1945
1946                         pos = (char*) p_xran_dev_ctx->sFHSrsRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_elm_id].sBufferList.pBuffers[sym_id].pData;
1947                         mb  = (void*) p_xran_dev_ctx->sFHSrsRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_elm_id].sBufferList.pBuffers[sym_id].pCtrl;
1948
1949                         if( prb_num > 136 || prb_num == 0) {
1950                             uint16_t sec_id  = xran_alloc_sectionid(pHandle, direction, cc_id, ant_id, slot_id);
1951                             /* first 136 PRBs */
1952                             send_symbol_ex(direction,
1953                                             sec_id,
1954                                             NULL,
1955                                             (struct rb_map *)pos,
1956                                             p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder,
1957                                             frame_id, subframe_id, slot_id, sym_id,
1958                                             0, 136,
1959                                             cc_id, ant_elm_eAxC_id,
1960                                             (p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) ?
1961                                                 xran_get_updl_seqid(pHandle, cc_id, ant_elm_eAxC_id) :
1962                                                 xran_get_upul_seqid(pHandle, cc_id, ant_elm_eAxC_id));
1963
1964                              pos += 136 * N_SC_PER_PRB * (iq_sample_size_bits/8)*2;
1965                              /* last 137 PRBs */
1966                              send_symbol_ex(direction, sec_id,
1967                                              NULL,
1968                                              (struct rb_map *)pos,
1969                                              p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder,
1970                                              frame_id, subframe_id, slot_id, sym_id,
1971                                              136, 137,
1972                                              cc_id, ant_elm_eAxC_id,
1973                                              (p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) ?
1974                                                 xran_get_updl_seqid(pHandle, cc_id, ant_elm_eAxC_id) :
1975                                                 xran_get_upul_seqid(pHandle, cc_id, ant_elm_eAxC_id));
1976                         } else {
1977                             send_symbol_ex(direction,
1978                                     xran_alloc_sectionid(pHandle, direction, cc_id, ant_elm_eAxC_id, slot_id),
1979                                     (struct rte_mbuf *)mb,
1980                                     (struct rb_map *)pos,
1981                                     p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder,
1982                                     frame_id, subframe_id, slot_id, sym_id,
1983                                     0, prb_num,
1984                                     cc_id, ant_elm_eAxC_id,
1985                                     (p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) ?
1986                                         xran_get_updl_seqid(pHandle, cc_id, ant_elm_eAxC_id) :
1987                                         xran_get_upul_seqid(pHandle, cc_id, ant_elm_eAxC_id));
1988                             retval = 1;
1989                         }
1990                     } /* for ant elem */
1991                 } /* SRS symbol */
1992             } /* SRS enabled */
1993         } /* RU mode or C-Plane is not used */
1994     }
1995
1996     return retval;
1997 }
1998
1999
2000 int32_t xran_process_tx_sym_cp_on(uint8_t ctx_id, uint32_t tti, int32_t cc_id, int32_t ant_id, uint32_t frame_id, uint32_t subframe_id,
2001     uint32_t slot_id, uint32_t sym_id)
2002 {
2003     int32_t     retval = 0;
2004     uint64_t    t1 = MLogTick();
2005
2006     struct rte_mbuf *eth_oran_hdr = NULL;
2007     char        *ext_buff = NULL;
2008     uint16_t    ext_buff_len = 0;
2009     struct rte_mbuf *tmp = NULL;
2010     rte_iova_t ext_buff_iova = 0;
2011     void        *pHandle  = NULL;
2012     char        *pos      = NULL;
2013     char        *p_sec_iq = NULL;
2014     void        *mb  = NULL;
2015     int         prb_num = 0;
2016     uint16_t    iq_sample_size_bits = 16; // TODO: make dynamic per
2017     uint32_t    next = 0;
2018     int32_t     num_sections = 0;
2019
2020     struct xran_section_info *sectinfo = NULL;
2021     struct xran_device_ctx   *p_xran_dev_ctx = xran_dev_get_ctx();
2022
2023     struct xran_prach_cp_config *pPrachCPConfig = &(p_xran_dev_ctx->PrachCPConfig);
2024     struct xran_srs_config *p_srs_cfg = &(p_xran_dev_ctx->srs_cfg);
2025     enum xran_pkt_dir direction;
2026
2027     struct rte_mbuf_ext_shared_info * p_share_data = &share_data[tti % XRAN_N_FE_BUF_LEN];
2028
2029     if(p_xran_dev_ctx->fh_init.io_cfg.id == O_DU) {
2030         direction = XRAN_DIR_DL; /* O-DU */
2031         prb_num = p_xran_dev_ctx->fh_cfg.nDLRBs;
2032     } else {
2033         direction = XRAN_DIR_UL; /* RU */
2034         prb_num = p_xran_dev_ctx->fh_cfg.nULRBs;
2035     }
2036
2037     next = 0;
2038     num_sections = xran_cp_getsize_section_info(pHandle, direction, cc_id, ant_id, ctx_id);
2039     /* iterate C-Plane configuration to generate corresponding U-Plane */
2040     while(next < num_sections) {
2041         sectinfo = xran_cp_iterate_section_info(pHandle, direction, cc_id, ant_id, ctx_id, &next);
2042
2043         if(sectinfo == NULL)
2044             break;
2045
2046         if(sectinfo->type != XRAN_CP_SECTIONTYPE_1) {   /* only supports type 1 */
2047             print_err("Invalid section type in section DB - %d", sectinfo->type);
2048             continue;
2049         }
2050
2051         /* skip, if not scheduled */
2052         if(sym_id < sectinfo->startSymId || sym_id >= sectinfo->startSymId + sectinfo->numSymbol)
2053             continue;
2054
2055         if(sectinfo->compMeth)
2056             iq_sample_size_bits = sectinfo->iqWidth;
2057
2058         print_dbg(">>> sym %2d [%d] type%d, id %d, startPrbc=%d, numPrbc=%d, numSymbol=%d\n", sym_id, next,
2059                         sectinfo->type, sectinfo->id, sectinfo->startPrbc,
2060                         sectinfo->numPrbc, sectinfo->numSymbol);
2061
2062         p_xran_dev_ctx->tx_mbufs[0].len = 0;
2063         uint16_t len  = p_xran_dev_ctx->tx_mbufs[0].len;
2064         int16_t len2 = 0;
2065         uint16_t i    = 0;
2066
2067         //Added for Klocworks
2068         if (len >= MBUF_TABLE_SIZE)
2069             len = MBUF_TABLE_SIZE - 1;
2070
2071         pos = (char*) p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
2072         mb  = p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_id].pCtrl;
2073
2074 #if 1
2075         p_sec_iq = ((char*)pos + sectinfo->sec_desc[sym_id].iq_buffer_offset);
2076
2077         /* calculete offset for external buffer */
2078         ext_buff_len = sectinfo->sec_desc[sym_id].iq_buffer_len;
2079         ext_buff = p_sec_iq - (RTE_PKTMBUF_HEADROOM +
2080                         sizeof (struct xran_ecpri_hdr) +
2081                         sizeof (struct radio_app_common_hdr) +
2082                         sizeof(struct data_section_hdr));
2083
2084         ext_buff_len += RTE_PKTMBUF_HEADROOM +
2085                         sizeof (struct xran_ecpri_hdr) +
2086                         sizeof (struct radio_app_common_hdr) +
2087                         sizeof(struct data_section_hdr) + 18;
2088
2089         if(sectinfo->compMeth != XRAN_COMPMETHOD_NONE){
2090             ext_buff     -= sizeof (struct data_section_compression_hdr);
2091             ext_buff_len += sizeof (struct data_section_compression_hdr);
2092         }
2093
2094         eth_oran_hdr =  rte_pktmbuf_alloc(_eth_mbuf_pool_small);
2095
2096         if (unlikely (( eth_oran_hdr) == NULL)) {
2097             rte_panic("Failed rte_pktmbuf_alloc\n");
2098         }
2099
2100         p_share_data->free_cb = extbuf_free_callback;
2101         p_share_data->fcb_opaque = NULL;
2102         rte_mbuf_ext_refcnt_set(p_share_data, 1);
2103
2104         ext_buff_iova = rte_mempool_virt2iova(mb);
2105         if (unlikely (( ext_buff_iova) == 0)) {
2106             rte_panic("Failed rte_mem_virt2iova \n");
2107         }
2108
2109         if (unlikely (( (rte_iova_t)ext_buff_iova) == RTE_BAD_IOVA)) {
2110             rte_panic("Failed rte_mem_virt2iova RTE_BAD_IOVA \n");
2111         }
2112
2113         rte_pktmbuf_attach_extbuf(eth_oran_hdr,
2114                                   ext_buff,
2115                                   ext_buff_iova + RTE_PTR_DIFF(ext_buff , mb),
2116                                   ext_buff_len,
2117                                   p_share_data);
2118
2119         rte_pktmbuf_reset_headroom(eth_oran_hdr);
2120
2121         tmp = (struct rte_mbuf *)rte_pktmbuf_prepend(eth_oran_hdr, sizeof(struct ether_hdr));
2122         if (unlikely (( tmp) == NULL)) {
2123             rte_panic("Failed rte_pktmbuf_prepend \n");
2124         }
2125         mb = eth_oran_hdr;
2126 #else
2127         rte_pktmbuf_refcnt_update(mb, 1); /* make sure eth won't free our mbuf */
2128 #endif
2129         /* first all PRBs */
2130         prepare_symbol_ex(direction, sectinfo->id,
2131                           mb,
2132                           (struct rb_map *)p_sec_iq,
2133                           sectinfo->compMeth,
2134                           sectinfo->iqWidth,
2135                           p_xran_dev_ctx->fh_cfg.ru_conf.byteOrder,
2136                           frame_id, subframe_id, slot_id, sym_id,
2137                           sectinfo->startPrbc, sectinfo->numPrbc,
2138                           cc_id, ant_id,
2139                           xran_get_updl_seqid(pHandle, cc_id, ant_id),
2140                           0);
2141
2142         /* if we don't need to do any fragmentation */
2143         if (likely (p_xran_dev_ctx->fh_init.mtu >=
2144                         sectinfo->numPrbc * (3*iq_sample_size_bits + 1))) {
2145             /* no fragmentation */
2146             p_xran_dev_ctx->tx_mbufs[0].m_table[len] = mb;
2147             len2 = 1;
2148         } else {
2149             /* fragmentation */
2150             uint8_t * seq_num = xran_get_updl_seqid_addr(pHandle, cc_id, ant_id);
2151             if(seq_num)
2152                 (*seq_num)--;
2153             else
2154                 rte_panic("pointer to seq number is NULL [CC %d Ant %d]\n", cc_id, ant_id);
2155
2156             len2 = xran_app_fragment_packet(mb,
2157                                         &p_xran_dev_ctx->tx_mbufs[0].m_table[len],
2158                                         (uint16_t)(MBUF_TABLE_SIZE - len),
2159                                         p_xran_dev_ctx->fh_init.mtu,
2160                                         p_xran_dev_ctx->direct_pool,
2161                                         p_xran_dev_ctx->indirect_pool,
2162                                         sectinfo,
2163                                         seq_num);
2164
2165             /* Free input packet */
2166             rte_pktmbuf_free(mb);
2167
2168             /* If we fail to fragment the packet */
2169             if (unlikely (len2 < 0)){
2170                 print_err("len2= %d\n", len2);
2171                 return 0;
2172             }
2173         }
2174
2175         if(len2 > 1){
2176             for (i = len; i < len + len2; i ++) {
2177                 struct rte_mbuf *m;
2178                 m = p_xran_dev_ctx->tx_mbufs[0].m_table[i];
2179                 struct ether_hdr *eth_hdr = (struct ether_hdr *)
2180                     rte_pktmbuf_prepend(m, (uint16_t)sizeof(struct ether_hdr));
2181                 if (eth_hdr == NULL) {
2182                     rte_panic("No headroom in mbuf.\n");
2183                 }
2184             }
2185         }
2186
2187         len += len2;
2188
2189         if (unlikely(len > XRAN_MAX_PKT_BURST_PER_SYM)) {
2190               rte_panic("XRAN_MAX_PKT_BURST_PER_SYM\n");
2191         }
2192
2193         /* Transmit packets */
2194         xran_send_burst(p_xran_dev_ctx, (uint16_t)len, 0);
2195         p_xran_dev_ctx->tx_mbufs[0].len = 0;
2196         retval = 1;
2197     } /* while(section) */
2198
2199     return retval;
2200 }
2201
2202 int32_t xran_process_tx_sym(void *arg)
2203 {
2204     int32_t     retval = 0;
2205     uint32_t    tti=0;
2206 #if XRAN_MLOG_VAR
2207     uint32_t    mlogVar[10];
2208     uint32_t    mlogVarCnt = 0;
2209 #endif
2210     unsigned long t1 = MLogTick();
2211
2212     void        *pHandle = NULL;
2213     int32_t     ant_id   = 0;
2214     int32_t     cc_id    = 0;
2215     uint8_t     num_eAxc = 0;
2216     uint8_t     num_CCPorts = 0;
2217     uint8_t     num_ant_elm = 0;
2218     uint32_t    frame_id    = 0;
2219     uint32_t    subframe_id = 0;
2220     uint32_t    slot_id     = 0;
2221     uint32_t    sym_id      = 0;
2222     uint32_t    sym_idx     = 0;
2223
2224     uint8_t     ctx_id;
2225     enum xran_pkt_dir  direction;
2226     struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
2227
2228     if(p_xran_dev_ctx->xran2phy_mem_ready == 0)
2229         return 0;
2230
2231     /* O-RU: send symb after OTA time with delay (UL) */
2232     /* O-DU: send symb in advance of OTA time (DL) */
2233     sym_idx     = XranOffsetSym(p_xran_dev_ctx->sym_up, xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT*SLOTNUM_PER_SUBFRAME*1000);
2234
2235     tti         = XranGetTtiNum(sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT);
2236     slot_id     = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME);
2237     subframe_id = XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME,  SUBFRAMES_PER_SYSTEMFRAME);
2238     frame_id    = XranGetFrameNum(tti,xran_getSfnSecStart(),SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
2239     // ORAN frameId, 8 bits, [0, 255]
2240     frame_id = (frame_id & 0xff);
2241
2242     sym_id      = XranGetSymNum(sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT);
2243     ctx_id      = XranGetSlotNum(tti, SLOTS_PER_SYSTEMFRAME) % XRAN_MAX_SECTIONDB_CTX;
2244
2245     print_dbg("[%d]SFN %d sf %d slot %d\n", tti, frame_id, subframe_id, slot_id);
2246
2247 #if XRAN_MLOG_VAR
2248     mlogVar[mlogVarCnt++] = 0xAAAAAAAA;
2249     mlogVar[mlogVarCnt++] = xran_lib_ota_sym_idx;
2250     mlogVar[mlogVarCnt++] = sym_idx;
2251     mlogVar[mlogVarCnt++] = abs(p_xran_dev_ctx->sym_up);
2252     mlogVar[mlogVarCnt++] = tti;
2253     mlogVar[mlogVarCnt++] = frame_id;
2254     mlogVar[mlogVarCnt++] = subframe_id;
2255     mlogVar[mlogVarCnt++] = slot_id;
2256     mlogVar[mlogVarCnt++] = sym_id;
2257     MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
2258 #endif
2259
2260     if(p_xran_dev_ctx->fh_init.io_cfg.id == O_RU && xran_get_ru_category(pHandle) == XRAN_CATEGORY_B) {
2261             num_eAxc    = xran_get_num_eAxcUl(pHandle);
2262     } else {
2263             num_eAxc    = xran_get_num_eAxc(pHandle);
2264     }
2265
2266     num_CCPorts = xran_get_num_cc(pHandle);
2267     /* U-Plane */
2268     for(ant_id = 0; ant_id < num_eAxc; ant_id++) {
2269         for(cc_id = 0; cc_id < num_CCPorts; cc_id++) {
2270             if(p_xran_dev_ctx->fh_init.io_cfg.id == O_DU && p_xran_dev_ctx->enableCP){
2271                 retval = xran_process_tx_sym_cp_on(ctx_id, tti, cc_id, ant_id, frame_id, subframe_id, slot_id, sym_id);
2272             } else {
2273                 retval = xran_process_tx_sym_cp_off(ctx_id, tti, cc_id, ant_id, frame_id, subframe_id, slot_id, sym_id, (ant_id == (num_eAxc - 1)));
2274             }
2275         } /* for(cc_id = 0; cc_id < num_CCPorts; cc_id++) */
2276     } /* for(ant_id = 0; ant_id < num_eAxc; ant_id++) */
2277
2278     MLogTask(PID_PROCESS_TX_SYM, t1, MLogTick());
2279     return retval;
2280 }
2281
2282 int xran_packet_and_dpdk_timer_thread(void *args)
2283 {
2284     struct xran_ethdi_ctx *const ctx = xran_ethdi_get_ctx();
2285
2286     uint64_t prev_tsc = 0;
2287     uint64_t cur_tsc = rte_rdtsc();
2288     uint64_t diff_tsc = cur_tsc - prev_tsc;
2289     cpu_set_t cpuset;
2290     struct sched_param sched_param;
2291     int res = 0;
2292     printf("%s [CPU %2d] [PID: %6d]\n", __FUNCTION__,  rte_lcore_id(), getpid());
2293
2294     sched_param.sched_priority = XRAN_THREAD_DEFAULT_PRIO;
2295
2296     if ((res  = pthread_setschedparam(pthread_self(), 1, &sched_param)))
2297     {
2298         printf("priority is not changed: coreId = %d, result1 = %d\n",rte_lcore_id(), res);
2299     }
2300
2301     while(1){
2302
2303         cur_tsc  = rte_rdtsc();
2304         diff_tsc = cur_tsc - prev_tsc;
2305         if (diff_tsc > TIMER_RESOLUTION_CYCLES) {
2306             rte_timer_manage();
2307             prev_tsc = cur_tsc;
2308         }
2309
2310         if (XRAN_STOPPED == xran_if_current_state)
2311             break;
2312     }
2313
2314     printf("Closing pkts timer thread...\n");
2315     return 0;
2316 }
2317
2318
2319 int32_t xran_init(int argc, char *argv[],
2320            struct xran_fh_init *p_xran_fh_init, char *appName, void ** pXranLayerHandle)
2321 {
2322     int32_t i;
2323     int32_t j;
2324
2325     struct xran_io_loop_cfg *p_io_cfg = (struct xran_io_loop_cfg *)&p_xran_fh_init->io_cfg;
2326     struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
2327
2328     cpu_set_t system_cpuset;
2329     pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &system_cpuset);
2330     for (j = 0; j < CPU_SETSIZE; j++)
2331         if (CPU_ISSET(j, &system_cpuset))
2332             break;
2333
2334     int32_t  lcore_id = j;
2335
2336     char filename[64];
2337     int64_t offset_sec, offset_nsec;
2338
2339     memset(p_xran_dev_ctx, 0, sizeof(struct xran_device_ctx));
2340
2341     /* copy init */
2342     p_xran_dev_ctx->fh_init = *p_xran_fh_init;
2343
2344     printf(" %s: MTU %d\n", __FUNCTION__, p_xran_dev_ctx->fh_init.mtu);
2345
2346     xran_if_current_state = XRAN_INIT;
2347
2348     memcpy(&(p_xran_dev_ctx->eAxc_id_cfg), &(p_xran_fh_init->eAxCId_conf), sizeof(struct xran_eaxcid_config));
2349
2350     p_xran_dev_ctx->enableCP    = p_xran_fh_init->enableCP;
2351     p_xran_dev_ctx->enablePrach = p_xran_fh_init->prachEnable;
2352     p_xran_dev_ctx->enableSrs   = p_xran_fh_init->srsEnable;
2353     p_xran_dev_ctx->DynamicSectionEna = p_xran_fh_init->DynamicSectionEna;
2354
2355     /* To make sure to set default functions */
2356     p_xran_dev_ctx->send_upmbuf2ring    = NULL;
2357     p_xran_dev_ctx->send_cpmbuf2ring    = NULL;
2358
2359     xran_register_ethertype_handler(ETHER_TYPE_ECPRI, handle_ecpri_ethertype);
2360     if (p_io_cfg->id == 0)
2361         xran_ethdi_init_dpdk_io(p_xran_fh_init->filePrefix,
2362                            p_io_cfg,
2363                            &lcore_id,
2364                            (struct ether_addr *)p_xran_fh_init->p_o_du_addr,
2365                            (struct ether_addr *)p_xran_fh_init->p_o_ru_addr,
2366                            p_xran_fh_init->cp_vlan_tag,
2367                            p_xran_fh_init->up_vlan_tag);
2368     else
2369         xran_ethdi_init_dpdk_io(p_xran_fh_init->filePrefix,
2370                            p_io_cfg,
2371                            &lcore_id,
2372                            (struct ether_addr *)p_xran_fh_init->p_o_ru_addr,
2373                            (struct ether_addr *)p_xran_fh_init->p_o_du_addr,
2374                            p_xran_fh_init->cp_vlan_tag,
2375                            p_xran_fh_init->up_vlan_tag);
2376
2377     for(i = 0; i < 10; i++ )
2378         rte_timer_init(&tti_to_phy_timer[i]);
2379
2380     rte_timer_init(&sym_timer);
2381     for (i = 0; i< MAX_NUM_OF_DPDK_TIMERS; i++)
2382         rte_timer_init(&dpdk_timer[i]);
2383
2384     p_xran_dev_ctx->direct_pool   = socket_direct_pool;
2385     p_xran_dev_ctx->indirect_pool = socket_indirect_pool;
2386
2387     for (i = 0; i< XRAN_MAX_SECTOR_NR; i++){
2388         for (j = 0; j< XRAN_NUM_OF_SYMBOL_PER_SLOT; j++){
2389             LIST_INIT (&p_xran_dev_ctx->sym_cb_list_head[i][j]);
2390         }
2391     }
2392
2393     printf("Set debug stop %d, debug stop count %d\n", p_xran_fh_init->debugStop, p_xran_fh_init->debugStopCount);
2394     timing_set_debug_stop(p_xran_fh_init->debugStop, p_xran_fh_init->debugStopCount);
2395
2396     for (uint32_t nCellIdx = 0; nCellIdx < XRAN_MAX_SECTOR_NR; nCellIdx++){
2397         xran_fs_clear_slot_type(nCellIdx);
2398     }
2399
2400     *pXranLayerHandle = p_xran_dev_ctx;
2401
2402     if(p_xran_fh_init->GPS_Alpha || p_xran_fh_init->GPS_Beta ){
2403         offset_sec = p_xran_fh_init->GPS_Beta / 100;    //resolution of beta is 10ms
2404         offset_nsec = (p_xran_fh_init->GPS_Beta - offset_sec * 100) * 1e7 + p_xran_fh_init->GPS_Alpha;
2405         p_xran_dev_ctx->offset_sec = offset_sec;
2406         p_xran_dev_ctx->offset_nsec = offset_nsec;
2407     }else {
2408         p_xran_dev_ctx->offset_sec  = 0;
2409         p_xran_dev_ctx->offset_nsec = 0;
2410     }
2411
2412     return 0;
2413 }
2414
2415 int32_t xran_sector_get_instances (void * pDevHandle, uint16_t nNumInstances,
2416                xran_cc_handle_t * pSectorInstanceHandles)
2417 {
2418     xran_status_t nStatus = XRAN_STATUS_FAIL;
2419     struct xran_device_ctx *pDev = (struct xran_device_ctx *)pDevHandle;
2420     XranSectorHandleInfo *pCcHandle = NULL;
2421     int32_t i = 0;
2422
2423     /* Check for the Valid Parameters */
2424     CHECK_NOT_NULL (pSectorInstanceHandles, XRAN_STATUS_INVALID_PARAM);
2425
2426     if (!nNumInstances) {
2427         print_dbg("Instance is not assigned for this function !!! \n");
2428         return XRAN_STATUS_INVALID_PARAM;
2429     }
2430
2431     for (i = 0; i < nNumInstances; i++) {
2432
2433         /* Allocate Memory for CC handles */
2434         pCcHandle = (XranSectorHandleInfo *) _mm_malloc( /*"xran_cc_handles",*/ sizeof (XranSectorHandleInfo), 64);
2435
2436         if(pCcHandle == NULL)
2437             return XRAN_STATUS_RESOURCE;
2438
2439         memset (pCcHandle, 0, (sizeof (XranSectorHandleInfo)));
2440
2441         pCcHandle->nIndex    = i;
2442         pCcHandle->nXranPort = pDev->xran_port_id;
2443
2444         printf("%s [%d]: CC %d handle %p\n", __FUNCTION__, pDev->xran_port_id, i, pCcHandle);
2445         pLibInstanceHandles[pDev->xran_port_id][i] = pSectorInstanceHandles[i] = pCcHandle;
2446
2447         printf("Handle: %p Instance: %p\n",
2448             &pSectorInstanceHandles[i], pSectorInstanceHandles[i]);
2449     }
2450
2451     return XRAN_STATUS_SUCCESS;
2452 }
2453
2454 int32_t xran_mm_init (void * pHandle, uint64_t nMemorySize,
2455             uint32_t nMemorySegmentSize)
2456 {
2457     /* we use mbuf from dpdk memory */
2458     return 0;
2459 }
2460
2461 int32_t xran_bm_init (void * pHandle, uint32_t * pPoolIndex, uint32_t nNumberOfBuffers, uint32_t nBufferSize)
2462 {
2463     XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
2464     uint32_t nAllocBufferSize;
2465
2466     char pool_name[RTE_MEMPOOL_NAMESIZE];
2467
2468     snprintf(pool_name, RTE_MEMPOOL_NAMESIZE, "ru_%d_cc_%d_idx_%d",
2469         pXranCc->nXranPort, pXranCc->nIndex, pXranCc->nBufferPoolIndex);
2470
2471     nAllocBufferSize = nBufferSize + sizeof(struct ether_hdr) +
2472         sizeof (struct xran_ecpri_hdr) +
2473         sizeof (struct radio_app_common_hdr) +
2474         sizeof(struct data_section_hdr) + 256;
2475
2476     if(nAllocBufferSize >= UINT16_MAX) {
2477         rte_panic("nAllocBufferSize is failed [ handle %p %d %d ] [nPoolIndex %d] nNumberOfBuffers %d nBufferSize %d nAllocBufferSize %d\n",
2478                     pXranCc, pXranCc->nXranPort, pXranCc->nIndex, pXranCc->nBufferPoolIndex, nNumberOfBuffers, nBufferSize, nAllocBufferSize);
2479         return -1;
2480     }
2481
2482     printf("%s: [ handle %p %d %d ] [nPoolIndex %d] nNumberOfBuffers %d nBufferSize %d\n", pool_name,
2483                         pXranCc, pXranCc->nXranPort, pXranCc->nIndex, pXranCc->nBufferPoolIndex, nNumberOfBuffers, nBufferSize);
2484
2485     pXranCc->p_bufferPool[pXranCc->nBufferPoolIndex] = rte_pktmbuf_pool_create(pool_name, nNumberOfBuffers,
2486                                                                                MBUF_CACHE, 0, nAllocBufferSize, rte_socket_id());
2487
2488     if(pXranCc->p_bufferPool[pXranCc->nBufferPoolIndex] == NULL){
2489         rte_panic("rte_pktmbuf_pool_create failed [ handle %p %d %d ] [nPoolIndex %d] nNumberOfBuffers %d nBufferSize %d errno %s\n",
2490                     pXranCc, pXranCc->nXranPort, pXranCc->nIndex, pXranCc->nBufferPoolIndex, nNumberOfBuffers, nBufferSize, rte_strerror(rte_errno));
2491         return -1;
2492     }
2493
2494     pXranCc->bufferPoolElmSz[pXranCc->nBufferPoolIndex]  = nBufferSize;
2495     pXranCc->bufferPoolNumElm[pXranCc->nBufferPoolIndex] = nNumberOfBuffers;
2496
2497     printf("CC:[ handle %p ru %d cc_idx %d ] [nPoolIndex %d] mb pool %p \n",
2498                 pXranCc, pXranCc->nXranPort, pXranCc->nIndex,
2499                     pXranCc->nBufferPoolIndex,  pXranCc->p_bufferPool[pXranCc->nBufferPoolIndex]);
2500
2501     *pPoolIndex = pXranCc->nBufferPoolIndex++;
2502
2503     return 0;
2504 }
2505
2506 int32_t xran_bm_allocate_buffer(void * pHandle, uint32_t nPoolIndex, void **ppData,  void **ppCtrl)
2507 {
2508     XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
2509     *ppData = NULL;
2510     *ppCtrl = NULL;
2511
2512     struct rte_mbuf * mb =  rte_pktmbuf_alloc(pXranCc->p_bufferPool[nPoolIndex]);
2513
2514     if(mb){
2515         char * start     = rte_pktmbuf_append(mb, pXranCc->bufferPoolElmSz[nPoolIndex]);
2516         char * ethhdr    = rte_pktmbuf_prepend(mb, sizeof(struct ether_hdr));
2517
2518         if(start && ethhdr){
2519             char * iq_offset = rte_pktmbuf_mtod(mb, char * );
2520             /* skip headers */
2521             iq_offset = iq_offset + sizeof(struct ether_hdr) +
2522                                     sizeof (struct xran_ecpri_hdr) +
2523                                     sizeof (struct radio_app_common_hdr) +
2524                                     sizeof(struct data_section_hdr);
2525
2526             if (0) /* if compression */
2527                 iq_offset += sizeof (struct data_section_compression_hdr);
2528
2529             *ppData = (void *)iq_offset;
2530             *ppCtrl  = (void *)mb;
2531         } else {
2532             print_err("[nPoolIndex %d] start ethhdr failed \n", nPoolIndex );
2533             return -1;
2534         }
2535     } else {
2536         print_err("[nPoolIndex %d] mb alloc failed \n", nPoolIndex );
2537         return -1;
2538     }
2539
2540     if (*ppData ==  NULL){
2541         print_err("[nPoolIndex %d] rte_pktmbuf_append for %d failed \n", nPoolIndex, pXranCc->bufferPoolElmSz[nPoolIndex]);
2542         return -1;
2543     }
2544
2545     return 0;
2546 }
2547
2548 int32_t xran_bm_free_buffer(void * pHandle, void *pData, void *pCtrl)
2549 {
2550     XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
2551
2552     if(pCtrl)
2553         rte_pktmbuf_free(pCtrl);
2554
2555     return 0;
2556 }
2557
2558 int32_t xran_5g_fronthault_config (void * pHandle,
2559                 struct xran_buffer_list *pSrcBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
2560                 struct xran_buffer_list *pSrcCpBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
2561                 struct xran_buffer_list *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
2562                 struct xran_buffer_list *pDstCpBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
2563                 xran_transport_callback_fn pCallback,
2564                 void *pCallbackTag)
2565 {
2566     XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
2567     xran_status_t nStatus = XRAN_STATUS_SUCCESS;
2568     int j, i = 0, z, k;
2569     struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
2570
2571     print_dbg("%s\n", __FUNCTION__);
2572
2573     if(NULL == pHandle)
2574     {
2575         printf("Handle is NULL!\n");
2576         return XRAN_STATUS_FAIL;
2577     }
2578
2579     if (pCallback == NULL)
2580     {
2581         printf ("no callback\n");
2582         return XRAN_STATUS_FAIL;
2583     }
2584
2585     i = pXranCc->nIndex;
2586
2587     for(j=0; j<XRAN_N_FE_BUF_LEN; j++)
2588     {
2589         for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
2590             /* U-plane TX */
2591
2592             p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].bValid = 0;
2593             p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
2594             p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
2595             p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
2596             p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
2597             p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFrontHaulTxBuffers[j][i][z][0];
2598
2599             p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList =   *pSrcBuffer[z][j];
2600
2601             /* C-plane TX */
2602             p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0;
2603             p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
2604             p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
2605             p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
2606             p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
2607             p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFrontHaulTxPrbMapBuffers[j][i][z][0];
2608
2609             p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList =   *pSrcCpBuffer[z][j];
2610
2611             /* U-plane RX */
2612
2613             p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].bValid = 0;
2614             p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
2615             p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
2616             p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
2617             p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
2618             p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFrontHaulRxBuffers[j][i][z][0];
2619
2620             p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList =   *pDstBuffer[z][j];
2621
2622             /* C-plane RX */
2623             p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0;
2624             p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
2625             p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
2626             p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
2627             p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
2628             p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFrontHaulRxPrbMapBuffers[j][i][z][0];
2629
2630             p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList =   *pDstCpBuffer[z][j];
2631         }
2632     }
2633
2634
2635     p_xran_dev_ctx->pCallback[i]    = pCallback;
2636     p_xran_dev_ctx->pCallbackTag[i] = pCallbackTag;
2637
2638     p_xran_dev_ctx->xran2phy_mem_ready = 1;
2639
2640     return nStatus;
2641 }
2642
2643 int32_t xran_5g_prach_req (void *  pHandle,
2644                 struct xran_buffer_list *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
2645                 xran_transport_callback_fn pCallback,
2646                 void *pCallbackTag)
2647 {
2648     XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
2649     xran_status_t nStatus = XRAN_STATUS_SUCCESS;
2650     int j, i = 0, z;
2651     struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
2652
2653     if(NULL == pHandle)
2654     {
2655         printf("Handle is NULL!\n");
2656         return XRAN_STATUS_FAIL;
2657     }
2658     if (pCallback == NULL)
2659     {
2660         printf ("no callback\n");
2661         return XRAN_STATUS_FAIL;
2662     }
2663
2664     i = pXranCc->nIndex;
2665
2666     for(j=0; j<XRAN_N_FE_BUF_LEN; j++)
2667     {
2668         for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
2669            p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].bValid = 0;
2670            p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
2671            p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
2672            p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
2673            p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_MAX_ANTENNA_NR; // ant number.
2674            p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFHPrachRxBuffers[j][i][z][0];
2675            p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList =   *pDstBuffer[z][j];
2676         }
2677     }
2678
2679     p_xran_dev_ctx->pPrachCallback[i]    = pCallback;
2680     p_xran_dev_ctx->pPrachCallbackTag[i] = pCallbackTag;
2681
2682     return 0;
2683 }
2684
2685
2686 int32_t xran_5g_srs_req (void *  pHandle,
2687                 struct xran_buffer_list *pDstBuffer[XRAN_MAX_ANT_ARRAY_ELM_NR][XRAN_N_FE_BUF_LEN],
2688                 xran_transport_callback_fn pCallback,
2689                 void *pCallbackTag)
2690 {
2691     XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
2692     xran_status_t nStatus = XRAN_STATUS_SUCCESS;
2693     int j, i = 0, z;
2694     struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
2695
2696     if(NULL == pHandle)
2697     {
2698         printf("Handle is NULL!\n");
2699         return XRAN_STATUS_FAIL;
2700     }
2701     if (pCallback == NULL)
2702     {
2703         printf ("no callback\n");
2704         return XRAN_STATUS_FAIL;
2705     }
2706
2707     i = pXranCc->nIndex;
2708
2709     for(j=0; j<XRAN_N_FE_BUF_LEN; j++)
2710     {
2711         for(z = 0; z < XRAN_MAX_ANT_ARRAY_ELM_NR; z++){
2712            p_xran_dev_ctx->sFHSrsRxBbuIoBufCtrl[j][i][z].bValid = 0;
2713            p_xran_dev_ctx->sFHSrsRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
2714            p_xran_dev_ctx->sFHSrsRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
2715            p_xran_dev_ctx->sFHSrsRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
2716            p_xran_dev_ctx->sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_MAX_ANT_ARRAY_ELM_NR; // ant number.
2717            p_xran_dev_ctx->sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFHSrsRxBuffers[j][i][z][0];
2718            p_xran_dev_ctx->sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList =   *pDstBuffer[z][j];
2719         }
2720     }
2721
2722     p_xran_dev_ctx->pSrsCallback[i]    = pCallback;
2723     p_xran_dev_ctx->pSrsCallbackTag[i] = pCallbackTag;
2724
2725     return 0;
2726 }
2727
2728 uint32_t xran_get_time_stats(uint64_t *total_time, uint64_t *used_time, uint32_t *core_used, uint32_t clear)
2729 {
2730     *total_time = xran_total_tick;
2731     *used_time = xran_used_tick;
2732     *core_used = xran_core_used;
2733
2734     if (clear)
2735     {
2736         xran_total_tick = 0;
2737         xran_used_tick = 0;
2738     }
2739
2740     return 0;
2741 }
2742
2743 void * xran_malloc(size_t buf_len)
2744 {
2745     return rte_malloc("External buffer", buf_len, RTE_CACHE_LINE_SIZE);
2746 }
2747
2748 uint8_t  *xran_add_hdr_offset(uint8_t  *dst, int16_t compMethod)
2749 {
2750     dst+= (RTE_PKTMBUF_HEADROOM +
2751           sizeof (struct xran_ecpri_hdr) +
2752           sizeof (struct radio_app_common_hdr) +
2753           sizeof(struct data_section_hdr));
2754
2755     if(compMethod != XRAN_COMPMETHOD_NONE)
2756           dst += sizeof (struct data_section_compression_hdr);
2757
2758     dst = RTE_PTR_ALIGN_CEIL(dst, 64);
2759
2760     return dst;
2761 }
2762
2763 int32_t xran_open(void *pHandle, struct xran_fh_config* pConf)
2764 {
2765     int32_t i;
2766     uint8_t nNumerology = 0;
2767     int32_t  lcore_id = 0;
2768     struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
2769     struct xran_fh_config *pFhCfg;
2770     pFhCfg = &(p_xran_dev_ctx->fh_cfg);
2771
2772     memcpy(pFhCfg, pConf, sizeof(struct xran_fh_config));
2773
2774     if(pConf->log_level)
2775         printf(" %s: O-RU Category %s\n", __FUNCTION__, (pFhCfg->ru_conf.xranCat == XRAN_CATEGORY_A) ? "A" : "B");
2776
2777     nNumerology = xran_get_conf_numerology(pHandle);
2778
2779     if (pConf->nCC > XRAN_MAX_SECTOR_NR)
2780     {
2781         if(pConf->log_level)
2782             printf("Number of cells %d exceeds max number supported %d!\n", pConf->nCC, XRAN_MAX_SECTOR_NR);
2783         pConf->nCC = XRAN_MAX_SECTOR_NR;
2784
2785     }
2786     if(pConf->ru_conf.iqOrder != XRAN_I_Q_ORDER
2787         || pConf->ru_conf.byteOrder != XRAN_NE_BE_BYTE_ORDER ){
2788
2789         print_err("Byte order and/or IQ order is not supported [IQ %d byte %d]\n", pConf->ru_conf.iqOrder, pConf->ru_conf.byteOrder);
2790         return XRAN_STATUS_FAIL;
2791     }
2792
2793     /* setup PRACH configuration for C-Plane */
2794     xran_init_prach(pConf, p_xran_dev_ctx);
2795     xran_init_srs(pConf, p_xran_dev_ctx);
2796
2797     xran_cp_init_sectiondb(pHandle);
2798     xran_init_sectionid(pHandle);
2799     xran_init_seqid(pHandle);
2800
2801     if(pConf->ru_conf.xran_max_frame) {
2802        xran_max_frame = pConf->ru_conf.xran_max_frame;
2803        printf("xran_max_frame %d\n", xran_max_frame);
2804     }
2805
2806     interval_us = xran_fs_get_tti_interval(nNumerology);
2807
2808     if(pConf->log_level){
2809         printf("%s: interval_us=%ld\n", __FUNCTION__, interval_us);
2810     }
2811     timing_set_numerology(nNumerology);
2812
2813     for(i = 0 ; i <pConf->nCC; i++){
2814         xran_fs_set_slot_type(i, pConf->frame_conf.nFrameDuplexType, pConf->frame_conf.nTddPeriod,
2815             pConf->frame_conf.sSlotConfig);
2816     }
2817
2818     xran_fs_slot_limit_init(xran_fs_get_tti_interval(nNumerology));
2819
2820     if(xran_ethdi_get_ctx()->io_cfg.bbdev_mode != XRAN_BBDEV_NOT_USED){
2821         p_xran_dev_ctx->bbdev_dec = pConf->bbdev_dec;
2822         p_xran_dev_ctx->bbdev_enc = pConf->bbdev_enc;
2823     }
2824
2825     /* if send_xpmbuf2ring needs to be changed from default functions,
2826      * then those should be set between xran_init and xran_open */
2827     if(p_xran_dev_ctx->send_cpmbuf2ring == NULL)
2828         p_xran_dev_ctx->send_cpmbuf2ring    = xran_ethdi_mbuf_send_cp;
2829     if(p_xran_dev_ctx->send_upmbuf2ring == NULL)
2830         p_xran_dev_ctx->send_upmbuf2ring    = xran_ethdi_mbuf_send;
2831
2832     /* Start packet processing thread */
2833     if((uint16_t)xran_ethdi_get_ctx()->io_cfg.port[XRAN_UP_VF] != 0xFFFF &&
2834         (uint16_t)xran_ethdi_get_ctx()->io_cfg.port[XRAN_CP_VF] != 0xFFFF ){
2835         if(pConf->log_level){
2836             print_dbg("XRAN_UP_VF: 0x%04x\n", xran_ethdi_get_ctx()->io_cfg.port[XRAN_UP_VF]);
2837             print_dbg("XRAN_CP_VF: 0x%04x\n", xran_ethdi_get_ctx()->io_cfg.port[XRAN_CP_VF]);
2838         }
2839         if (rte_eal_remote_launch(xran_timing_source_thread, xran_dev_get_ctx(), xran_ethdi_get_ctx()->io_cfg.timing_core))
2840             rte_panic("thread_run() failed to start\n");
2841     } else if(pConf->log_level){
2842             printf("Eth port was not open. Processing thread was not started\n");
2843     }
2844
2845     return 0;
2846 }
2847
2848 int32_t xran_start(void *pHandle)
2849 {
2850     if(xran_get_if_state() == XRAN_RUNNING) {
2851         print_err("Already STARTED!!");
2852         return (-1);
2853         }
2854
2855     xran_if_current_state = XRAN_RUNNING;
2856     return 0;
2857 }
2858
2859 int32_t xran_stop(void *pHandle)
2860 {
2861     if(xran_get_if_state() == XRAN_STOPPED) {
2862         print_err("Already STOPPED!!");
2863         return (-1);
2864         }
2865
2866     xran_if_current_state = XRAN_STOPPED;
2867     return 0;
2868 }
2869
2870 int32_t xran_close(void *pHandle)
2871 {
2872     xran_if_current_state = XRAN_STOPPED;
2873     //TODO: fix memory leak xran_cp_free_sectiondb(pHandle);
2874     //rte_eal_mp_wait_lcore();
2875     //xran_ethdi_ports_stats();
2876
2877 #ifdef RTE_LIBRTE_PDUMP
2878     /* uninitialize packet capture framework */
2879     rte_pdump_uninit();
2880 #endif
2881     return 0;
2882 }
2883
2884 int32_t xran_mm_destroy (void * pHandle)
2885 {
2886     if(xran_get_if_state() == XRAN_RUNNING) {
2887         print_err("Please STOP first !!");
2888         return (-1);
2889         }
2890
2891     /* functionality is not yet implemented */
2892     return -1;
2893 }
2894
2895 int32_t xran_reg_sym_cb(void *pHandle, xran_callback_sym_fn symCb, void * symCbParam, uint8_t symb,  uint8_t ant)
2896 {
2897     if(xran_get_if_state() == XRAN_RUNNING) {
2898         print_err("Cannot register callback while running!!\n");
2899         return (-1);
2900         }
2901
2902     /* functionality is not yet implemented */
2903     print_err("Functionality is not yet implemented !");
2904     return -1;
2905 }
2906
2907 int32_t xran_reg_physide_cb(void *pHandle, xran_fh_tti_callback_fn Cb, void *cbParam, int skipTtiNum, enum callback_to_phy_id id)
2908 {
2909     struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
2910
2911     if(xran_get_if_state() == XRAN_RUNNING) {
2912         print_err("Cannot register callback while running!!\n");
2913         return (-1);
2914         }
2915
2916     p_xran_dev_ctx->ttiCb[id]      = Cb;
2917     p_xran_dev_ctx->TtiCbParam[id] = cbParam;
2918     p_xran_dev_ctx->SkipTti[id]    = skipTtiNum;
2919
2920     return 0;
2921 }
2922
2923 /* send_cpmbuf2ring and send_upmbuf2ring should be set between xran_init and xran_open
2924  * each cb will be set by default duing open if it is set by NULL */
2925 int xran_register_cb_mbuf2ring(xran_ethdi_mbuf_send_fn mbuf_send_cp, xran_ethdi_mbuf_send_fn mbuf_send_up)
2926 {
2927     struct xran_device_ctx *p_xran_dev_ctx;
2928
2929     if(xran_get_if_state() == XRAN_RUNNING) {
2930         print_err("Cannot register callback while running!!\n");
2931         return (-1);
2932         }
2933
2934     p_xran_dev_ctx = xran_dev_get_ctx();
2935
2936     p_xran_dev_ctx->send_cpmbuf2ring    = mbuf_send_cp;
2937     p_xran_dev_ctx->send_upmbuf2ring    = mbuf_send_up;
2938
2939     return (0);
2940 }
2941
2942
2943 int32_t xran_get_slot_idx (uint32_t *nFrameIdx, uint32_t *nSubframeIdx,  uint32_t *nSlotIdx, uint64_t *nSecond)
2944 {
2945     int32_t tti = 0;
2946
2947     tti           = (int32_t)XranGetTtiNum(xran_lib_ota_sym_idx, XRAN_NUM_OF_SYMBOL_PER_SLOT);
2948     *nSlotIdx     = (uint32_t)XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME);
2949     *nSubframeIdx = (uint32_t)XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME,  SUBFRAMES_PER_SYSTEMFRAME);
2950     *nFrameIdx    = (uint32_t)XranGetFrameNum(tti,xran_getSfnSecStart(),SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
2951     *nSecond      = timing_get_current_second();
2952
2953     return tti;
2954 }
2955
2956
2957 /**
2958  * @brief Get the configuration of eAxC ID
2959  *
2960  * @return the pointer of configuration
2961  */
2962 inline struct xran_eaxcid_config *xran_get_conf_eAxC(void *pHandle)
2963 {
2964     return (&(xran_dev_get_ctx()->eAxc_id_cfg));
2965 }
2966
2967 /**
2968  * @brief Get the configuration of the total number of beamforming weights on RU
2969  *
2970  * @return Configured the number of beamforming weights
2971  */
2972 inline uint8_t xran_get_conf_num_bfweights(void *pHandle)
2973 {
2974     return (xran_dev_get_ctx()->fh_init.totalBfWeights);
2975 }
2976
2977 /**
2978  * @brief Get the configuration of subcarrier spacing for PRACH
2979  *
2980  * @return subcarrier spacing value for PRACH
2981  */
2982 inline uint8_t xran_get_conf_prach_scs(void *pHandle)
2983 {
2984     return (xran_lib_get_ctx_fhcfg()->prach_conf.nPrachSubcSpacing);
2985 }
2986
2987 /**
2988  * @brief Get the configuration of FFT size for RU
2989  *
2990  * @return FFT size value for RU
2991  */
2992 inline uint8_t xran_get_conf_fftsize(void *pHandle)
2993 {
2994     return (xran_lib_get_ctx_fhcfg()->ru_conf.fftSize);
2995 }
2996
2997 /**
2998  * @brief Get the configuration of nummerology
2999  *
3000  * @return Configured numerology
3001  */
3002 inline uint8_t xran_get_conf_numerology(void *pHandle)
3003 {
3004     return (xran_lib_get_ctx_fhcfg()->frame_conf.nNumerology);
3005 }
3006
3007 /**
3008  * @brief Get the configuration of IQ bit width for RU
3009  *
3010  * @return IQ bit width for RU
3011  */
3012 inline uint8_t xran_get_conf_iqwidth(void *pHandle)
3013 {
3014     struct xran_fh_config *pFhCfg;
3015
3016     pFhCfg = xran_lib_get_ctx_fhcfg();
3017     return ((pFhCfg->ru_conf.iqWidth==16)?0:pFhCfg->ru_conf.iqWidth);
3018 }
3019
3020 /**
3021  * @brief Get the configuration of compression method for RU
3022  *
3023  * @return Compression method for RU
3024  */
3025 inline uint8_t xran_get_conf_compmethod(void *pHandle)
3026 {
3027     return (xran_lib_get_ctx_fhcfg()->ru_conf.compMeth);
3028 }
3029
3030
3031 /**
3032  * @brief Get the configuration of the number of component carriers
3033  *
3034  * @return Configured the number of component carriers
3035  */
3036 inline uint8_t xran_get_num_cc(void *pHandle)
3037 {
3038     return (xran_lib_get_ctx_fhcfg()->nCC);
3039 }
3040
3041 /**
3042  * @brief Get the configuration of the number of antenna for UL
3043  *
3044  * @return Configured the number of antenna
3045  */
3046 inline uint8_t xran_get_num_eAxc(void *pHandle)
3047 {
3048     return (xran_lib_get_ctx_fhcfg()->neAxc);
3049 }
3050
3051 /**
3052  * @brief Get configuration of O-RU (Cat A or Cat B)
3053  *
3054  * @return Configured the number of antenna
3055  */
3056 inline enum xran_category xran_get_ru_category(void *pHandle)
3057 {
3058     return (xran_lib_get_ctx_fhcfg()->ru_conf.xranCat);
3059 }
3060
3061 /**
3062  * @brief Get the configuration of the number of antenna
3063  *
3064  * @return Configured the number of antenna
3065  */
3066 inline uint8_t xran_get_num_eAxcUl(void *pHandle)
3067 {
3068     return (xran_lib_get_ctx_fhcfg()->neAxcUl);
3069 }
3070
3071 /**
3072  * @brief Get the configuration of the number of antenna elements
3073  *
3074  * @return Configured the number of antenna
3075  */
3076 inline uint8_t xran_get_num_ant_elm(void *pHandle)
3077 {
3078     return (xran_lib_get_ctx_fhcfg()->nAntElmTRx);
3079 }
3080
3081 int32_t xran_get_common_counters(void *pXranLayerHandle, struct xran_common_counters *pStats)
3082 {
3083     struct xran_device_ctx* pDev = (struct xran_device_ctx*)pXranLayerHandle;
3084
3085     if(pStats && pDev) {
3086         *pStats  =  pDev->fh_counters;
3087         return XRAN_STATUS_SUCCESS;
3088     } else {
3089         return XRAN_STATUS_INVALID_PARAM;
3090     }
3091 }
3092