o-du/phy
Intel O-RAN/X-RAN Generated Doxygen Documentation
xran_main.c
Go to the documentation of this file.
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 
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 
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 
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;
112 uint32_t xran_lib_ota_sym = 0;
113 uint32_t xran_lib_ota_sym_idx = 0;
115 uint16_t xran_SFN_at_Sec_Start = 0;
116 uint16_t xran_max_frame = 1023;
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];
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];
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 }
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 
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 
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 
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 
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 }
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 
591  t3 = xran_tick();
592  tti_ota_cb(NULL, arg);
593  *used_tick += get_ticks_diff(xran_tick(), t3);
594  }
595 
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();
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
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 
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;
657  /* subframe and slot */
658  MLogRegisterFrameSubframe(reg_sfn, reg_tti % (SLOTNUM_PER_SUBFRAME));
659  MLogMark(1, t1);
660 
664 
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);
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 
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  }
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 
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  }
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);
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 */
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);
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 
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) */
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 */
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);
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  }
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;
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);
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 
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);
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  }
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();
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]){
1153  uint32_t slot_id = XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME);
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 
1163 }
1164 
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 
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 
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 */
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*/
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);
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  }
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 
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) */
2234 
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);
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 
2279  return retval;
2280 }
2281 
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 
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  int32_t lcore_id = 0;
2329  char filename[64];
2330  int64_t offset_sec, offset_nsec;
2331 
2332  memset(p_xran_dev_ctx, 0, sizeof(struct xran_device_ctx));
2333 
2334  /* copy init */
2335  p_xran_dev_ctx->fh_init = *p_xran_fh_init;
2336 
2337  printf(" %s: MTU %d\n", __FUNCTION__, p_xran_dev_ctx->fh_init.mtu);
2338 
2340 
2341  memcpy(&(p_xran_dev_ctx->eAxc_id_cfg), &(p_xran_fh_init->eAxCId_conf), sizeof(struct xran_eaxcid_config));
2342 
2343  p_xran_dev_ctx->enableCP = p_xran_fh_init->enableCP;
2344  p_xran_dev_ctx->enablePrach = p_xran_fh_init->prachEnable;
2345  p_xran_dev_ctx->enableSrs = p_xran_fh_init->srsEnable;
2346  p_xran_dev_ctx->DynamicSectionEna = p_xran_fh_init->DynamicSectionEna;
2347 
2348  /* To make sure to set default functions */
2349  p_xran_dev_ctx->send_upmbuf2ring = NULL;
2350  p_xran_dev_ctx->send_cpmbuf2ring = NULL;
2351 
2353  if (p_io_cfg->id == 0)
2354  xran_ethdi_init_dpdk_io(p_xran_fh_init->filePrefix,
2355  p_io_cfg,
2356  &lcore_id,
2357  (struct ether_addr *)p_xran_fh_init->p_o_du_addr,
2358  (struct ether_addr *)p_xran_fh_init->p_o_ru_addr,
2359  p_xran_fh_init->cp_vlan_tag,
2360  p_xran_fh_init->up_vlan_tag);
2361  else
2362  xran_ethdi_init_dpdk_io(p_xran_fh_init->filePrefix,
2363  p_io_cfg,
2364  &lcore_id,
2365  (struct ether_addr *)p_xran_fh_init->p_o_ru_addr,
2366  (struct ether_addr *)p_xran_fh_init->p_o_du_addr,
2367  p_xran_fh_init->cp_vlan_tag,
2368  p_xran_fh_init->up_vlan_tag);
2369 
2370  for(i = 0; i < 10; i++ )
2371  rte_timer_init(&tti_to_phy_timer[i]);
2372 
2373  rte_timer_init(&sym_timer);
2374  for (i = 0; i< MAX_NUM_OF_DPDK_TIMERS; i++)
2375  rte_timer_init(&dpdk_timer[i]);
2376 
2377  p_xran_dev_ctx->direct_pool = socket_direct_pool;
2378  p_xran_dev_ctx->indirect_pool = socket_indirect_pool;
2379 
2380  for (i = 0; i< XRAN_MAX_SECTOR_NR; i++){
2381  for (j = 0; j< XRAN_NUM_OF_SYMBOL_PER_SLOT; j++){
2382  LIST_INIT (&p_xran_dev_ctx->sym_cb_list_head[i][j]);
2383  }
2384  }
2385 
2386  printf("Set debug stop %d, debug stop count %d\n", p_xran_fh_init->debugStop, p_xran_fh_init->debugStopCount);
2387  timing_set_debug_stop(p_xran_fh_init->debugStop, p_xran_fh_init->debugStopCount);
2388 
2389  for (uint32_t nCellIdx = 0; nCellIdx < XRAN_MAX_SECTOR_NR; nCellIdx++){
2390  xran_fs_clear_slot_type(nCellIdx);
2391  }
2392 
2393  *pXranLayerHandle = p_xran_dev_ctx;
2394 
2395  if(p_xran_fh_init->GPS_Alpha || p_xran_fh_init->GPS_Beta ){
2396  offset_sec = p_xran_fh_init->GPS_Beta / 100; //resolution of beta is 10ms
2397  offset_nsec = (p_xran_fh_init->GPS_Beta - offset_sec * 100) * 1e7 + p_xran_fh_init->GPS_Alpha;
2398  p_xran_dev_ctx->offset_sec = offset_sec;
2399  p_xran_dev_ctx->offset_nsec = offset_nsec;
2400  }else {
2401  p_xran_dev_ctx->offset_sec = 0;
2402  p_xran_dev_ctx->offset_nsec = 0;
2403  }
2404 
2405  return 0;
2406 }
2407 
2408 int32_t xran_sector_get_instances (void * pDevHandle, uint16_t nNumInstances,
2409  xran_cc_handle_t * pSectorInstanceHandles)
2410 {
2411  xran_status_t nStatus = XRAN_STATUS_FAIL;
2412  struct xran_device_ctx *pDev = (struct xran_device_ctx *)pDevHandle;
2413  XranSectorHandleInfo *pCcHandle = NULL;
2414  int32_t i = 0;
2415 
2416  /* Check for the Valid Parameters */
2417  CHECK_NOT_NULL (pSectorInstanceHandles, XRAN_STATUS_INVALID_PARAM);
2418 
2419  if (!nNumInstances) {
2420  print_dbg("Instance is not assigned for this function !!! \n");
2422  }
2423 
2424  for (i = 0; i < nNumInstances; i++) {
2425 
2426  /* Allocate Memory for CC handles */
2427  pCcHandle = (XranSectorHandleInfo *) _mm_malloc( /*"xran_cc_handles",*/ sizeof (XranSectorHandleInfo), 64);
2428 
2429  if(pCcHandle == NULL)
2430  return XRAN_STATUS_RESOURCE;
2431 
2432  memset (pCcHandle, 0, (sizeof (XranSectorHandleInfo)));
2433 
2434  pCcHandle->nIndex = i;
2435  pCcHandle->nXranPort = pDev->xran_port_id;
2436 
2437  printf("%s [%d]: CC %d handle %p\n", __FUNCTION__, pDev->xran_port_id, i, pCcHandle);
2438  pLibInstanceHandles[pDev->xran_port_id][i] = pSectorInstanceHandles[i] = pCcHandle;
2439 
2440  printf("Handle: %p Instance: %p\n",
2441  &pSectorInstanceHandles[i], pSectorInstanceHandles[i]);
2442  }
2443 
2444  return XRAN_STATUS_SUCCESS;
2445 }
2446 
2447 int32_t xran_mm_init (void * pHandle, uint64_t nMemorySize,
2448  uint32_t nMemorySegmentSize)
2449 {
2450  /* we use mbuf from dpdk memory */
2451  return 0;
2452 }
2453 
2454 int32_t xran_bm_init (void * pHandle, uint32_t * pPoolIndex, uint32_t nNumberOfBuffers, uint32_t nBufferSize)
2455 {
2456  XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
2457  uint32_t nAllocBufferSize;
2458 
2459  char pool_name[RTE_MEMPOOL_NAMESIZE];
2460 
2461  snprintf(pool_name, RTE_MEMPOOL_NAMESIZE, "ru_%d_cc_%d_idx_%d",
2462  pXranCc->nXranPort, pXranCc->nIndex, pXranCc->nBufferPoolIndex);
2463 
2464  nAllocBufferSize = nBufferSize + sizeof(struct ether_hdr) +
2465  sizeof (struct xran_ecpri_hdr) +
2466  sizeof (struct radio_app_common_hdr) +
2467  sizeof(struct data_section_hdr) + 256;
2468 
2469  if(nAllocBufferSize >= UINT16_MAX) {
2470  rte_panic("nAllocBufferSize is failed [ handle %p %d %d ] [nPoolIndex %d] nNumberOfBuffers %d nBufferSize %d nAllocBufferSize %d\n",
2471  pXranCc, pXranCc->nXranPort, pXranCc->nIndex, pXranCc->nBufferPoolIndex, nNumberOfBuffers, nBufferSize, nAllocBufferSize);
2472  return -1;
2473  }
2474 
2475  printf("%s: [ handle %p %d %d ] [nPoolIndex %d] nNumberOfBuffers %d nBufferSize %d\n", pool_name,
2476  pXranCc, pXranCc->nXranPort, pXranCc->nIndex, pXranCc->nBufferPoolIndex, nNumberOfBuffers, nBufferSize);
2477 
2478  pXranCc->p_bufferPool[pXranCc->nBufferPoolIndex] = rte_pktmbuf_pool_create(pool_name, nNumberOfBuffers,
2479  MBUF_CACHE, 0, nAllocBufferSize, rte_socket_id());
2480 
2481  if(pXranCc->p_bufferPool[pXranCc->nBufferPoolIndex] == NULL){
2482  rte_panic("rte_pktmbuf_pool_create failed [ handle %p %d %d ] [nPoolIndex %d] nNumberOfBuffers %d nBufferSize %d errno %s\n",
2483  pXranCc, pXranCc->nXranPort, pXranCc->nIndex, pXranCc->nBufferPoolIndex, nNumberOfBuffers, nBufferSize, rte_strerror(rte_errno));
2484  return -1;
2485  }
2486 
2487  pXranCc->bufferPoolElmSz[pXranCc->nBufferPoolIndex] = nBufferSize;
2488  pXranCc->bufferPoolNumElm[pXranCc->nBufferPoolIndex] = nNumberOfBuffers;
2489 
2490  printf("CC:[ handle %p ru %d cc_idx %d ] [nPoolIndex %d] mb pool %p \n",
2491  pXranCc, pXranCc->nXranPort, pXranCc->nIndex,
2492  pXranCc->nBufferPoolIndex, pXranCc->p_bufferPool[pXranCc->nBufferPoolIndex]);
2493 
2494  *pPoolIndex = pXranCc->nBufferPoolIndex++;
2495 
2496  return 0;
2497 }
2498 
2499 int32_t xran_bm_allocate_buffer(void * pHandle, uint32_t nPoolIndex, void **ppData, void **ppCtrl)
2500 {
2501  XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
2502  *ppData = NULL;
2503  *ppCtrl = NULL;
2504 
2505  struct rte_mbuf * mb = rte_pktmbuf_alloc(pXranCc->p_bufferPool[nPoolIndex]);
2506 
2507  if(mb){
2508  char * start = rte_pktmbuf_append(mb, pXranCc->bufferPoolElmSz[nPoolIndex]);
2509  char * ethhdr = rte_pktmbuf_prepend(mb, sizeof(struct ether_hdr));
2510 
2511  if(start && ethhdr){
2512  char * iq_offset = rte_pktmbuf_mtod(mb, char * );
2513  /* skip headers */
2514  iq_offset = iq_offset + sizeof(struct ether_hdr) +
2515  sizeof (struct xran_ecpri_hdr) +
2516  sizeof (struct radio_app_common_hdr) +
2517  sizeof(struct data_section_hdr);
2518 
2519  if (0) /* if compression */
2520  iq_offset += sizeof (struct data_section_compression_hdr);
2521 
2522  *ppData = (void *)iq_offset;
2523  *ppCtrl = (void *)mb;
2524  } else {
2525  print_err("[nPoolIndex %d] start ethhdr failed \n", nPoolIndex );
2526  return -1;
2527  }
2528  } else {
2529  print_err("[nPoolIndex %d] mb alloc failed \n", nPoolIndex );
2530  return -1;
2531  }
2532 
2533  if (*ppData == NULL){
2534  print_err("[nPoolIndex %d] rte_pktmbuf_append for %d failed \n", nPoolIndex, pXranCc->bufferPoolElmSz[nPoolIndex]);
2535  return -1;
2536  }
2537 
2538  return 0;
2539 }
2540 
2541 int32_t xran_bm_free_buffer(void * pHandle, void *pData, void *pCtrl)
2542 {
2543  XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
2544 
2545  if(pCtrl)
2546  rte_pktmbuf_free(pCtrl);
2547 
2548  return 0;
2549 }
2550 
2551 int32_t xran_5g_fronthault_config (void * pHandle,
2553  struct xran_buffer_list *pSrcCpBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
2554  struct xran_buffer_list *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
2555  struct xran_buffer_list *pDstCpBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
2556  xran_transport_callback_fn pCallback,
2557  void *pCallbackTag)
2558 {
2559  XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
2561  int j, i = 0, z, k;
2562  struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
2563 
2564  print_dbg("%s\n", __FUNCTION__);
2565 
2566  if(NULL == pHandle)
2567  {
2568  printf("Handle is NULL!\n");
2569  return XRAN_STATUS_FAIL;
2570  }
2571 
2572  if (pCallback == NULL)
2573  {
2574  printf ("no callback\n");
2575  return XRAN_STATUS_FAIL;
2576  }
2577 
2578  i = pXranCc->nIndex;
2579 
2580  for(j=0; j<XRAN_N_FE_BUF_LEN; j++)
2581  {
2582  for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
2583  /* U-plane TX */
2584 
2585  p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].bValid = 0;
2586  p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
2587  p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
2588  p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
2590  p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFrontHaulTxBuffers[j][i][z][0];
2591 
2592  p_xran_dev_ctx->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList = *pSrcBuffer[z][j];
2593 
2594  /* C-plane TX */
2595  p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0;
2596  p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
2597  p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
2598  p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
2600  p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFrontHaulTxPrbMapBuffers[j][i][z][0];
2601 
2602  p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList = *pSrcCpBuffer[z][j];
2603 
2604  /* U-plane RX */
2605 
2606  p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].bValid = 0;
2607  p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
2608  p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
2609  p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
2611  p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFrontHaulRxBuffers[j][i][z][0];
2612 
2613  p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList = *pDstBuffer[z][j];
2614 
2615  /* C-plane RX */
2616  p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0;
2617  p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
2618  p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
2619  p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
2621  p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFrontHaulRxPrbMapBuffers[j][i][z][0];
2622 
2623  p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList = *pDstCpBuffer[z][j];
2624  }
2625  }
2626 
2627 
2628  p_xran_dev_ctx->pCallback[i] = pCallback;
2629  p_xran_dev_ctx->pCallbackTag[i] = pCallbackTag;
2630 
2631  p_xran_dev_ctx->xran2phy_mem_ready = 1;
2632 
2633  return nStatus;
2634 }
2635 
2636 int32_t xran_5g_prach_req (void * pHandle,
2639  void *pCallbackTag)
2640 {
2641  XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
2643  int j, i = 0, z;
2644  struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
2645 
2646  if(NULL == pHandle)
2647  {
2648  printf("Handle is NULL!\n");
2649  return XRAN_STATUS_FAIL;
2650  }
2651  if (pCallback == NULL)
2652  {
2653  printf ("no callback\n");
2654  return XRAN_STATUS_FAIL;
2655  }
2656 
2657  i = pXranCc->nIndex;
2658 
2659  for(j=0; j<XRAN_N_FE_BUF_LEN; j++)
2660  {
2661  for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
2662  p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].bValid = 0;
2663  p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
2664  p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
2665  p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
2666  p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_MAX_ANTENNA_NR; // ant number.
2667  p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFHPrachRxBuffers[j][i][z][0];
2668  p_xran_dev_ctx->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList = *pDstBuffer[z][j];
2669  }
2670  }
2671 
2672  p_xran_dev_ctx->pPrachCallback[i] = pCallback;
2673  p_xran_dev_ctx->pPrachCallbackTag[i] = pCallbackTag;
2674 
2675  return 0;
2676 }
2677 
2678 
2679 int32_t xran_5g_srs_req (void * pHandle,
2682  void *pCallbackTag)
2683 {
2684  XranSectorHandleInfo* pXranCc = (XranSectorHandleInfo*) pHandle;
2686  int j, i = 0, z;
2687  struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
2688 
2689  if(NULL == pHandle)
2690  {
2691  printf("Handle is NULL!\n");
2692  return XRAN_STATUS_FAIL;
2693  }
2694  if (pCallback == NULL)
2695  {
2696  printf ("no callback\n");
2697  return XRAN_STATUS_FAIL;
2698  }
2699 
2700  i = pXranCc->nIndex;
2701 
2702  for(j=0; j<XRAN_N_FE_BUF_LEN; j++)
2703  {
2704  for(z = 0; z < XRAN_MAX_ANT_ARRAY_ELM_NR; z++){
2705  p_xran_dev_ctx->sFHSrsRxBbuIoBufCtrl[j][i][z].bValid = 0;
2706  p_xran_dev_ctx->sFHSrsRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
2707  p_xran_dev_ctx->sFHSrsRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
2708  p_xran_dev_ctx->sFHSrsRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
2709  p_xran_dev_ctx->sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_MAX_ANT_ARRAY_ELM_NR; // ant number.
2710  p_xran_dev_ctx->sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &p_xran_dev_ctx->sFHSrsRxBuffers[j][i][z][0];
2711  p_xran_dev_ctx->sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList = *pDstBuffer[z][j];
2712  }
2713  }
2714 
2715  p_xran_dev_ctx->pSrsCallback[i] = pCallback;
2716  p_xran_dev_ctx->pSrsCallbackTag[i] = pCallbackTag;
2717 
2718  return 0;
2719 }
2720 
2721 uint32_t xran_get_time_stats(uint64_t *total_time, uint64_t *used_time, uint32_t *core_used, uint32_t clear)
2722 {
2723  *total_time = xran_total_tick;
2724  *used_time = xran_used_tick;
2725  *core_used = xran_core_used;
2726 
2727  if (clear)
2728  {
2729  xran_total_tick = 0;
2730  xran_used_tick = 0;
2731  }
2732 
2733  return 0;
2734 }
2735 
2736 void * xran_malloc(size_t buf_len)
2737 {
2738  return rte_malloc("External buffer", buf_len, RTE_CACHE_LINE_SIZE);
2739 }
2740 
2741 uint8_t *xran_add_hdr_offset(uint8_t *dst, int16_t compMethod)
2742 {
2743  dst+= (RTE_PKTMBUF_HEADROOM +
2744  sizeof (struct xran_ecpri_hdr) +
2745  sizeof (struct radio_app_common_hdr) +
2746  sizeof(struct data_section_hdr));
2747 
2748  if(compMethod != XRAN_COMPMETHOD_NONE)
2749  dst += sizeof (struct data_section_compression_hdr);
2750 
2751  dst = RTE_PTR_ALIGN_CEIL(dst, 64);
2752 
2753  return dst;
2754 }
2755 
2756 int32_t xran_open(void *pHandle, struct xran_fh_config* pConf)
2757 {
2758  int32_t i;
2759  uint8_t nNumerology = 0;
2760  int32_t lcore_id = 0;
2761  struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
2762  struct xran_fh_config *pFhCfg;
2763  pFhCfg = &(p_xran_dev_ctx->fh_cfg);
2764 
2765  memcpy(pFhCfg, pConf, sizeof(struct xran_fh_config));
2766 
2767  if(pConf->log_level)
2768  printf(" %s: O-RU Category %s\n", __FUNCTION__, (pFhCfg->ru_conf.xranCat == XRAN_CATEGORY_A) ? "A" : "B");
2769 
2770  nNumerology = xran_get_conf_numerology(pHandle);
2771 
2772  if (pConf->nCC > XRAN_MAX_SECTOR_NR)
2773  {
2774  if(pConf->log_level)
2775  printf("Number of cells %d exceeds max number supported %d!\n", pConf->nCC, XRAN_MAX_SECTOR_NR);
2776  pConf->nCC = XRAN_MAX_SECTOR_NR;
2777 
2778  }
2779  if(pConf->ru_conf.iqOrder != XRAN_I_Q_ORDER
2780  || pConf->ru_conf.byteOrder != XRAN_NE_BE_BYTE_ORDER ){
2781 
2782  print_err("Byte order and/or IQ order is not supported [IQ %d byte %d]\n", pConf->ru_conf.iqOrder, pConf->ru_conf.byteOrder);
2783  return XRAN_STATUS_FAIL;
2784  }
2785 
2786  /* setup PRACH configuration for C-Plane */
2787  xran_init_prach(pConf, p_xran_dev_ctx);
2788  xran_init_srs(pConf, p_xran_dev_ctx);
2789 
2790  xran_cp_init_sectiondb(pHandle);
2791  xran_init_sectionid(pHandle);
2792  xran_init_seqid(pHandle);
2793 
2794  if(pConf->ru_conf.xran_max_frame) {
2796  printf("xran_max_frame %d\n", xran_max_frame);
2797  }
2798 
2799  interval_us = xran_fs_get_tti_interval(nNumerology);
2800 
2801  if(pConf->log_level){
2802  printf("%s: interval_us=%ld\n", __FUNCTION__, interval_us);
2803  }
2804  timing_set_numerology(nNumerology);
2805 
2806  for(i = 0 ; i <pConf->nCC; i++){
2808  pConf->frame_conf.sSlotConfig);
2809  }
2810 
2812 
2813  if(xran_ethdi_get_ctx()->io_cfg.bbdev_mode != XRAN_BBDEV_NOT_USED){
2814  p_xran_dev_ctx->bbdev_dec = pConf->bbdev_dec;
2815  p_xran_dev_ctx->bbdev_enc = pConf->bbdev_enc;
2816  }
2817 
2818  /* if send_xpmbuf2ring needs to be changed from default functions,
2819  * then those should be set between xran_init and xran_open */
2820  if(p_xran_dev_ctx->send_cpmbuf2ring == NULL)
2821  p_xran_dev_ctx->send_cpmbuf2ring = xran_ethdi_mbuf_send_cp;
2822  if(p_xran_dev_ctx->send_upmbuf2ring == NULL)
2823  p_xran_dev_ctx->send_upmbuf2ring = xran_ethdi_mbuf_send;
2824 
2825  /* Start packet processing thread */
2826  if((uint16_t)xran_ethdi_get_ctx()->io_cfg.port[XRAN_UP_VF] != 0xFFFF &&
2827  (uint16_t)xran_ethdi_get_ctx()->io_cfg.port[XRAN_CP_VF] != 0xFFFF ){
2828  if(pConf->log_level){
2829  print_dbg("XRAN_UP_VF: 0x%04x\n", xran_ethdi_get_ctx()->io_cfg.port[XRAN_UP_VF]);
2830  print_dbg("XRAN_CP_VF: 0x%04x\n", xran_ethdi_get_ctx()->io_cfg.port[XRAN_CP_VF]);
2831  }
2832  if (rte_eal_remote_launch(xran_timing_source_thread, xran_dev_get_ctx(), xran_ethdi_get_ctx()->io_cfg.timing_core))
2833  rte_panic("thread_run() failed to start\n");
2834  } else if(pConf->log_level){
2835  printf("Eth port was not open. Processing thread was not started\n");
2836  }
2837 
2838  return 0;
2839 }
2840 
2841 int32_t xran_start(void *pHandle)
2842 {
2843  if(xran_get_if_state() == XRAN_RUNNING) {
2844  print_err("Already STARTED!!");
2845  return (-1);
2846  }
2847 
2849  return 0;
2850 }
2851 
2852 int32_t xran_stop(void *pHandle)
2853 {
2854  if(xran_get_if_state() == XRAN_STOPPED) {
2855  print_err("Already STOPPED!!");
2856  return (-1);
2857  }
2858 
2860  return 0;
2861 }
2862 
2863 int32_t xran_close(void *pHandle)
2864 {
2866  //TODO: fix memory leak xran_cp_free_sectiondb(pHandle);
2867  //rte_eal_mp_wait_lcore();
2868  //xran_ethdi_ports_stats();
2869 
2870 #ifdef RTE_LIBRTE_PDUMP
2871  /* uninitialize packet capture framework */
2872  rte_pdump_uninit();
2873 #endif
2874  return 0;
2875 }
2876 
2877 int32_t xran_mm_destroy (void * pHandle)
2878 {
2879  if(xran_get_if_state() == XRAN_RUNNING) {
2880  print_err("Please STOP first !!");
2881  return (-1);
2882  }
2883 
2884  /* functionality is not yet implemented */
2885  return -1;
2886 }
2887 
2888 int32_t xran_reg_sym_cb(void *pHandle, xran_callback_sym_fn symCb, void * symCbParam, uint8_t symb, uint8_t ant)
2889 {
2890  if(xran_get_if_state() == XRAN_RUNNING) {
2891  print_err("Cannot register callback while running!!\n");
2892  return (-1);
2893  }
2894 
2895  /* functionality is not yet implemented */
2896  print_err("Functionality is not yet implemented !");
2897  return -1;
2898 }
2899 
2900 int32_t xran_reg_physide_cb(void *pHandle, xran_fh_tti_callback_fn Cb, void *cbParam, int skipTtiNum, enum callback_to_phy_id id)
2901 {
2902  struct xran_device_ctx * p_xran_dev_ctx = xran_dev_get_ctx();
2903 
2904  if(xran_get_if_state() == XRAN_RUNNING) {
2905  print_err("Cannot register callback while running!!\n");
2906  return (-1);
2907  }
2908 
2909  p_xran_dev_ctx->ttiCb[id] = Cb;
2910  p_xran_dev_ctx->TtiCbParam[id] = cbParam;
2911  p_xran_dev_ctx->SkipTti[id] = skipTtiNum;
2912 
2913  return 0;
2914 }
2915 
2916 /* send_cpmbuf2ring and send_upmbuf2ring should be set between xran_init and xran_open
2917  * each cb will be set by default duing open if it is set by NULL */
2919 {
2920  struct xran_device_ctx *p_xran_dev_ctx;
2921 
2922  if(xran_get_if_state() == XRAN_RUNNING) {
2923  print_err("Cannot register callback while running!!\n");
2924  return (-1);
2925  }
2926 
2927  p_xran_dev_ctx = xran_dev_get_ctx();
2928 
2929  p_xran_dev_ctx->send_cpmbuf2ring = mbuf_send_cp;
2930  p_xran_dev_ctx->send_upmbuf2ring = mbuf_send_up;
2931 
2932  return (0);
2933 }
2934 
2935 
2936 int32_t xran_get_slot_idx (uint32_t *nFrameIdx, uint32_t *nSubframeIdx, uint32_t *nSlotIdx, uint64_t *nSecond)
2937 {
2938  int32_t tti = 0;
2939 
2941  *nSlotIdx = (uint32_t)XranGetSlotNum(tti, SLOTNUM_PER_SUBFRAME);
2942  *nSubframeIdx = (uint32_t)XranGetSubFrameNum(tti,SLOTNUM_PER_SUBFRAME, SUBFRAMES_PER_SYSTEMFRAME);
2943  *nFrameIdx = (uint32_t)XranGetFrameNum(tti,xran_getSfnSecStart(),SUBFRAMES_PER_SYSTEMFRAME, SLOTNUM_PER_SUBFRAME);
2944  *nSecond = timing_get_current_second();
2945 
2946  return tti;
2947 }
2948 
2949 
2955 inline struct xran_eaxcid_config *xran_get_conf_eAxC(void *pHandle)
2956 {
2957  return (&(xran_dev_get_ctx()->eAxc_id_cfg));
2958 }
2959 
2965 inline uint8_t xran_get_conf_num_bfweights(void *pHandle)
2966 {
2967  return (xran_dev_get_ctx()->fh_init.totalBfWeights);
2968 }
2969 
2975 inline uint8_t xran_get_conf_prach_scs(void *pHandle)
2976 {
2977  return (xran_lib_get_ctx_fhcfg()->prach_conf.nPrachSubcSpacing);
2978 }
2979 
2985 inline uint8_t xran_get_conf_fftsize(void *pHandle)
2986 {
2987  return (xran_lib_get_ctx_fhcfg()->ru_conf.fftSize);
2988 }
2989 
2995 inline uint8_t xran_get_conf_numerology(void *pHandle)
2996 {
2997  return (xran_lib_get_ctx_fhcfg()->frame_conf.nNumerology);
2998 }
2999 
3005 inline uint8_t xran_get_conf_iqwidth(void *pHandle)
3006 {
3007  struct xran_fh_config *pFhCfg;
3008 
3009  pFhCfg = xran_lib_get_ctx_fhcfg();
3010  return ((pFhCfg->ru_conf.iqWidth==16)?0:pFhCfg->ru_conf.iqWidth);
3011 }
3012 
3018 inline uint8_t xran_get_conf_compmethod(void *pHandle)
3019 {
3020  return (xran_lib_get_ctx_fhcfg()->ru_conf.compMeth);
3021 }
3022 
3023 
3029 inline uint8_t xran_get_num_cc(void *pHandle)
3030 {
3031  return (xran_lib_get_ctx_fhcfg()->nCC);
3032 }
3033 
3039 inline uint8_t xran_get_num_eAxc(void *pHandle)
3040 {
3041  return (xran_lib_get_ctx_fhcfg()->neAxc);
3042 }
3043 
3049 inline enum xran_category xran_get_ru_category(void *pHandle)
3050 {
3051  return (xran_lib_get_ctx_fhcfg()->ru_conf.xranCat);
3052 }
3053 
3059 inline uint8_t xran_get_num_eAxcUl(void *pHandle)
3060 {
3061  return (xran_lib_get_ctx_fhcfg()->neAxcUl);
3062 }
3063 
3069 inline uint8_t xran_get_num_ant_elm(void *pHandle)
3070 {
3071  return (xran_lib_get_ctx_fhcfg()->nAntElmTRx);
3072 }
3073 
3074 int32_t xran_get_common_counters(void *pXranLayerHandle, struct xran_common_counters *pStats)
3075 {
3076  struct xran_device_ctx* pDev = (struct xran_device_ctx*)pXranLayerHandle;
3077 
3078  if(pStats && pDev) {
3079  *pStats = pDev->fh_counters;
3080  return XRAN_STATUS_SUCCESS;
3081  } else {
3083  }
3084 }
3085 
int xran_cp_add_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id, struct xran_section_info *info)
Add a section information of C-Plane to dabase.
Definition: xran_cp_api.c:160
int generate_cpmsg_prach(void *pHandle, struct xran_cp_gen_params *params, struct xran_section_gen_info *sect_geninfo, struct rte_mbuf *mbuf, struct xran_device_ctx *pxran_lib_ctx, uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id, uint16_t beam_id, uint8_t cc_id, uint8_t prach_port_id, uint8_t seq_id)
Definition: xran_common.c:595
const xRANPrachConfigTableStruct gxranPrachDataTable_sub6_fdd[XRAN_PRACH_CONFIG_TABLE_SIZE]
uint32_t xran_fs_get_max_slot(void)
#define XranOffsetSym(offSym, otaSym, numSymTotal)
Definition: xran_main.c:67
int32_t debugStop
Definition: xran_fh_o_du.h:361
struct rte_mempool * socket_indirect_pool
Definition: ethernet.c:77
#define N_SC_PER_PRB
Definition: common.h:49
#define PID_PROCESS_CP_PKT
int timing_set_numerology(uint8_t value)
Definition: xran_timer.c:93
uint8_t enableCP
Definition: xran_fh_o_du.h:356
int32_t xran_init(int argc, char *argv[], struct xran_fh_init *p_xran_fh_init, char *appName, void **pXranLayerHandle)
Definition: xran_main.c:2319
phy_encoder_poll_fn bbdev_enc
Definition: xran_fh_o_du.h:520
void * TtiCbParam[XRAN_CB_MAX]
Definition: xran_common.h:253
int xran_init_seqid(void *pHandle)
Definition: xran_main.c:400
const xRANPrachConfigTableStruct gxranPrachDataTable_sub6_tdd[XRAN_PRACH_CONFIG_TABLE_SIZE]
int xran_timing_source_thread(void *args)
Definition: xran_main.c:1165
#define XRAN_MAX_ANT_ARRAY_ELM_NR
Definition: xran_fh_o_du.h:118
struct rte_mbuf * xran_ethdi_mbuf_alloc(void)
Definition: ethdi.c:77
#define XRAN_SYMBOL_TYPE_UL
Definition: xran_fh_o_du.h:147
int xran_init_prach(struct xran_fh_config *pConf, struct xran_device_ctx *p_xran_dev_ctx)
Definition: xran_main.c:308
int32_t timing_core
Definition: xran_fh_o_du.h:303
#define XRAN_N_FE_BUF_LEN
Definition: xran_fh_o_du.h:109
xran_pkt_dir
Definition: xran_pkt.h:146
int prach_last_symbol[XRAN_MAX_SECTOR_NR]
Definition: xran_common.h:263
#define PID_UP_UL_HALF_DEAD_LINE_CB
uint32_t rb
Definition: xran_pkt_cp.h:243
uint32_t tti_to_process
Definition: xran_main.c:97
struct xran_srs_config srs_cfg
Definition: xran_common.h:220
void * pPrachCallbackTag[XRAN_MAX_SECTOR_NR]
Definition: xran_common.h:242
#define XRAN_STATUS_SUCCESS
Definition: xran_fh_o_du.h:54
struct xran_common_counters fh_counters
Definition: xran_common.h:271
uint32_t nAntElmTRx
Definition: xran_fh_o_du.h:503
#define ETHER_TYPE_ECPRI
Definition: ethernet.h:42
#define print_dbg(fmt, args...)
Definition: xran_printf.h:54
int32_t nPrachFreqOffset
Definition: xran_fh_o_du.h:442
struct xran_device_ctx * xran_dev_get_ctx(void)
Definition: xran_main.c:223
uint16_t xran_alloc_sectionid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id)
Definition: xran_main.c:379
uint16_t T1a_max_up
Definition: xran_fh_o_du.h:352
uint8_t eAxC_offset
Definition: xran_fh_o_du.h:449
uint32_t xran_fs_slot_limit_init(int32_t tti_interval_us)
uint32_t nNumBuffers
Definition: xran_fh_o_du.h:594
end write files for IQ samples for ant
Definition: gen_test.m:166
uint8_t xran_port_id
Definition: xran_common.h:206
uint16_t nDLRBs
Definition: xran_fh_o_du.h:506
uint16_t len
Definition: xran_common.h:199
#define MLogMark(x, y)
Definition: xran_mlog_lnx.h:46
void rx_ul_deadline_half_cb(struct rte_timer *tim, void *arg)
Definition: xran_main.c:963
enum xran_if_state xran_if_current_state
Definition: ethdi.c:75
uint16_t nULRBs
Definition: xran_fh_o_du.h:507
uint8_t id
Definition: xran_fh_o_du.h:295
uint8_t y[XRAN_PRACH_CANDIDATE_Y]
Definition: xran_common.h:137
int32_t GPS_Beta
Definition: xran_fh_o_du.h:365
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, int32_t do_srs)
Definition: xran_main.c:1715
xran_category
Definition: xran_fh_o_du.h:262
int32_t xran_process_tx_sym(void *arg)
Definition: xran_main.c:2202
enum xran_category xran_get_ru_category(void *pHandle)
Get configuration of O-RU (Cat A or Cat B)
Definition: xran_main.c:3049
uint8_t seq_id
Definition: xran_pkt.h:99
uint8_t xran_get_num_cc(void *pHandle)
Get the configuration of the number of component carriers.
Definition: xran_main.c:3029
uint32_t xran_lib_ota_tti
Definition: xran_main.c:111
#define MLogRegisterFrameSubframe(x, y)
Definition: xran_mlog_lnx.h:48
struct cb_elem_entry * xran_create_cb(XranSymCallbackFn cb_fn, void *cb_data)
Definition: xran_common.c:125
int32_t xran_open(void *pHandle, struct xran_fh_config *pConf)
Definition: xran_main.c:2756
void xran_timer_arm(struct rte_timer *tim, void *arg)
Definition: xran_main.c:711
#define XRAN_SLOT_TYPE_DL
Definition: xran_fh_o_du.h:139
int16_t nRBStart
Definition: xran_fh_o_du.h:394
#define PID_TTI_TIMER
struct mbuf_table tx_mbufs[RTE_MAX_ETHPORTS]
Definition: xran_common.h:269
void * xran_malloc(size_t buf_len)
Definition: xran_main.c:2736
int32_t debugStopCount
Definition: xran_fh_o_du.h:362
int xran_ethdi_mbuf_send(struct rte_mbuf *mb, uint16_t ethertype)
Definition: ethdi.c:82
int16_t nBeamIndex
Definition: xran_fh_o_du.h:398
uint8_t prachEnable
Definition: xran_fh_o_du.h:357
enum xran_input_byte_order byteOrder
Definition: xran_fh_o_du.h:489
void * pSrsCallbackTag[XRAN_MAX_SECTOR_NR]
Definition: xran_common.h:245
uint8_t srsEnable
Definition: xran_fh_o_du.h:358
uint32_t nPrbElm
Definition: xran_fh_o_du.h:422
int32_t nSegTransferred
Definition: sample-app.c:127
int xran_ethdi_mbuf_send_cp(struct rte_mbuf *mb, uint16_t ethertype)
Definition: ethdi.c:94
#define XRAN_STATUS_FAIL
Definition: xran_fh_o_du.h:58
xran_ethdi_mbuf_send_fn send_upmbuf2ring
Definition: xran_common.h:277
long rx_counter
Definition: xran_common.c:117
int16_t nRBSize
Definition: xran_fh_o_du.h:395
void rx_ul_deadline_full_cb(struct rte_timer *tim, void *arg)
Definition: xran_main.c:999
xran_transport_callback_fn pCallback[XRAN_MAX_SECTOR_NR]
Definition: xran_common.h:238
uint8_t id
Definition: ethdi.h:83
void xran_updateSfnSecStart(void)
Definition: xran_main.c:201
BbuIoBufCtrlStruct sFrontHaulTxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR]
Definition: xran_common.h:223
struct rte_mempool * socket_direct_pool
Definition: ethernet.c:76
uint8_t xran_get_conf_numerology(void *pHandle)
Get the configuration of nummerology.
Definition: xran_main.c:2995
#define PID_UP_UL_FULL_DEAD_LINE_CB
#define XRAN_MAX_SECTOR_NR
Definition: xran_fh_o_du.h:110
#define DpdkTimerIncrementCtx(ctx)
Definition: xran_main.c:78
uint64_t xran_tick(void)
Definition: xran_timer.c:131
const xRANPrachConfigTableStruct gxranPrachDataTable_mmw[XRAN_PRACH_CONFIG_TABLE_SIZE]
uint16_t xran_get_beamid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id)
Definition: xran_main.c:233
xran_transport_callback_fn pPrachCallback[XRAN_MAX_SECTOR_NR]
Definition: xran_common.h:241
#define MLogAddVariables(x, y, z)
Definition: xran_mlog_lnx.h:49
struct xran_section_info info
Definition: xran_cp_api.h:296
xran_ethdi_mbuf_send_fn send_cpmbuf2ring
Definition: xran_common.h:276
struct rte_mempool * indirect_pool
Definition: xran_common.h:268
uint16_t xran_max_frame
Definition: xran_fh_o_du.h:491
int16_t ext_section_sz
Definition: xran_fh_o_du.h:372
struct xran_srs_config srs_conf
Definition: xran_fh_o_du.h:516
int send_cpmsg(void *pHandle, struct rte_mbuf *mbuf, struct xran_cp_gen_params *params, struct xran_section_gen_info *sect_geninfo, uint8_t cc_id, uint8_t ru_port_id, uint8_t seq_id)
Definition: xran_common.c:510
struct xran_eaxcid_config eAxCId_conf
Definition: xran_fh_o_du.h:325
int16_t iqWidth
Definition: xran_fh_o_du.h:401
uint16_t nPrachFreqStart
Definition: xran_fh_o_du.h:441
#define PID_TTI_CB
uint8_t xran_get_num_ant_elm(void *pHandle)
Get the configuration of the number of antenna elements.
Definition: xran_main.c:3069
uint16_t Ta3_min
Definition: xran_fh_o_du.h:345
struct xran_flat_buffer sFHSrsRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANT_ARRAY_ELM_NR][XRAN_MAX_NUM_OF_SRS_SYMBOL_PER_SLOT]
Definition: xran_common.h:236
#define XRAN_MAX_SECTIONDB_CTX
Definition: xran_cp_api.h:40
phy_decoder_poll_fn bbdev_dec
Definition: xran_fh_o_du.h:521
#define XRAN_MAX_ANTENNA_NR
Definition: xran_fh_o_du.h:111
#define TX_TIMER_INTERVAL
Definition: ethdi.h:64
uint8_t xran_get_conf_prach_scs(void *pHandle)
Get the configuration of subcarrier spacing for PRACH.
Definition: xran_main.c:2975
int8_t * p_ext_section
Definition: xran_fh_o_du.h:371
int8_t * p_o_ru_addr
Definition: xran_fh_o_du.h:334
#define XRAN_PORTS_NUM
Definition: xran_fh_o_du.h:108
int prach_start_symbol[XRAN_MAX_SECTOR_NR]
Definition: xran_common.h:262
void * xran_cc_handle_t
Definition: xran_fh_o_du.h:541
struct xran_cp_bf_weight bf_weight
Definition: xran_fh_o_du.h:405
int32_t xran_bm_allocate_buffer(void *pHandle, uint32_t nPoolIndex, void **ppData, void **ppCtrl)
Definition: xran_main.c:2499
uint8_t nFrameDuplexType
Definition: xran_fh_o_du.h:460
struct xran_flat_buffer sFrontHaulTxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT]
Definition: xran_common.h:230
int32_t xran_get_slot_idx(uint32_t *nFrameIdx, uint32_t *nSubframeIdx, uint32_t *nSlotIdx, uint64_t *nSecond)
Definition: xran_main.c:2936
unsigned long get_ticks_diff(unsigned long curr_tick, unsigned long last_tick)
Definition: xran_timer.c:138
void * pSymCallbackTag
Definition: xran_common.h:164
char * filePrefix
Definition: xran_fh_o_du.h:329
struct rte_mempool * p_bufferPool[XRAN_MAX_POOLS_PER_SECTOR_NR]
Definition: xran_common.h:154
struct xran_fh_config fh_cfg
Definition: xran_common.h:209
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, uint32_t slot_id, uint32_t sym_id)
Definition: xran_main.c:2000
uint32_t mtu
Definition: xran_fh_o_du.h:331
uint32_t xran_fs_get_tti_interval(uint8_t nMu)
int32_t prepare_symbol_ex(enum xran_pkt_dir direction, uint16_t section_id, struct rte_mbuf *mb, struct rb_map *data, uint8_t compMeth, uint8_t iqWidth, const enum xran_input_byte_order iq_buf_byte_order, uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id, uint8_t symbol_no, int prb_start, int prb_num, uint8_t CC_ID, uint8_t RU_Port_ID, uint8_t seq_id, uint32_t do_copy)
Definition: xran_common.c:348
int32_t xran_close(void *pHandle)
Definition: xran_main.c:2863
int32_t xran_sector_get_instances(void *pDevHandle, uint16_t nNumInstances, xran_cc_handle_t *pSectorInstanceHandles)
Definition: xran_main.c:2408
enum xran_input_i_q_order iqOrder
Definition: xran_fh_o_du.h:490
uint8_t occassionsInPrachSlot
Definition: xran_common.h:135
uint16_t T1a_max_cp_dl
Definition: xran_fh_o_du.h:348
uint8_t xran_get_num_eAxc(void *pHandle)
Get the configuration of the number of antenna for UL.
Definition: xran_main.c:3039
int32_t xran_get_freqoffset(int freqOffset, int scs)
int32_t xran_mm_destroy(void *pHandle)
Definition: xran_main.c:2877
struct xran_io_cfg io_cfg
Definition: xran_fh_o_du.h:324
xran_fh_tti_callback_fn ttiCb[XRAN_CB_MAX]
Definition: xran_common.h:252
struct xran_flat_buffer sFHPrachRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT]
Definition: xran_common.h:234
Definition: xran_common.h:162
uint8_t y[XRAN_PRACH_CANDIDATE_Y]
Definition: xran_common.h:107
#define XranGetTtiNum(symIdx, numSymPerTti)
Definition: xran_fh_o_du.h:98
int32_t xran_5g_fronthault_config(void *pHandle, struct xran_buffer_list *pSrcBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN], struct xran_buffer_list *pSrcCpBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN], struct xran_buffer_list *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN], struct xran_buffer_list *pDstCpBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN], xran_transport_callback_fn pCallback, void *pCallbackTag)
Definition: xran_main.c:2551
int32_t xran_process_rx_sym(void *arg, struct rte_mbuf *mbuf, void *iq_data_start, uint16_t size, uint8_t CC_ID, uint8_t Ant_ID, uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id, uint8_t symb_id, uint16_t num_prbu, uint16_t start_prbu, uint16_t sym_inc, uint16_t rb, uint16_t sect_id, uint32_t *mb_free)
Definition: xran_main.c:1578
int32_t xran_start(void *pHandle)
Definition: xran_main.c:2841
uint32_t log_level
Definition: xran_fh_o_du.h:523
#define XranGetSymNum(symIdx, numSymPerTti)
Definition: xran_fh_o_du.h:100
uint8_t xran_get_conf_num_bfweights(void *pHandle)
Get the configuration of the total number of beamforming weights on RU.
Definition: xran_main.c:2965
#define XRAN_PRACH_CANDIDATE_SLOT
Definition: xran_common.h:80
uint32_t bufferPoolElmSz[XRAN_MAX_POOLS_PER_SECTOR_NR]
Definition: xran_common.h:155
int32_t sym_up_ul
Definition: xran_common.h:250
int32_t xran_mm_init(void *pHandle, uint64_t nMemorySize, uint32_t nMemorySegmentSize)
Definition: xran_main.c:2447
int xran_destroy_cb(struct cb_elem_entry *cb_elm)
Definition: xran_common.c:136
void * pCallbackTag[XRAN_MAX_SECTOR_NR]
Definition: xran_common.h:239
long tx_counter
Definition: xran_common.c:118
#define print_err(fmt, args...)
Definition: xran_printf.h:62
#define XranGetSubFrameNum(tti, numSlotPerSubFrame, numSubFramePerSystemFrame)
Definition: xran_fh_o_du.h:104
uint8_t compMeth
Definition: xran_fh_o_du.h:487
struct rte_mempool * _eth_mbuf_pool_small
Definition: ethernet.c:73
uint16_t startPrbc
Definition: xran_cp_api.h:193
void ul_up_full_slot_cb(struct rte_timer *tim, void *arg)
Definition: xran_main.c:1129
#define PID_PROCESS_TX_SYM
int xran_parse_cp_pkt(struct rte_mbuf *mbuf, struct xran_cp_gen_params *result, struct xran_recv_packet_info *pkt_info)
Parse a C-Plane packet (for RU emulation) Transport layer fragmentation is not supported.
Definition: xran_cp_api.c:1749
int32_t xran_fs_set_slot_type(uint32_t nPhyInstanceId, uint32_t nFrameDuplexType, uint32_t nTddPeriod, struct xran_slot_config *psSlotConfig)
uint16_t xran_SFN_at_Sec_Start
Definition: xran_main.c:115
uint16_t Ta4_max
Definition: xran_fh_o_du.h:354
long poll_next_tick(long interval_ns, unsigned long *used_tick)
Definition: xran_timer.c:146
struct xran_frame_config frame_conf
Definition: xran_fh_o_du.h:517
#define SLOTS_PER_SYSTEMFRAME
Definition: xran_common.h:56
This file provides interface to synchronization related APIs (PTP/1588) for XRAN. ...
phy_decoder_poll_fn bbdev_dec
Definition: xran_common.h:274
uint32_t bufferPoolNumElm[XRAN_MAX_POOLS_PER_SECTOR_NR]
Definition: xran_common.h:156
uint32_t xran_fs_get_max_slot_SFN(void)
int32_t nSegGenerated
Definition: sample-app.c:125
uint32_t enableCP
Definition: xran_common.h:213
#define MBUF_TABLE_SIZE
Definition: xran_common.h:196
int process_cplane(struct rte_mbuf *pkt)
Definition: xran_main.c:571
int xran_packet_and_dpdk_timer_thread(void *args)
Definition: xran_main.c:2282
void tti_to_phy_cb(struct rte_timer *tim, void *arg)
Definition: xran_main.c:1136
long rx_bytes_per_sec
Definition: xran_common.c:122
struct rte_mbuf * m_table[MBUF_TABLE_SIZE]
Definition: xran_common.h:200
int timing_set_debug_stop(int value, int count)
Definition: xran_timer.c:99
#define XranGetSlotNum(tti, numSlotPerSfn)
Definition: xran_fh_o_du.h:106
void tx_cp_ul_cb(struct rte_timer *tim, void *arg)
Definition: xran_main.c:1045
This file provides interface to Timing for XRAN.
uint16_t nXranPort
Definition: xran_common.h:149
void tx_cp_dl_cb(struct rte_timer *tim, void *arg)
Definition: xran_main.c:910
xran_if_state
Definition: xran_fh_o_du.h:189
struct xran_flat_buffer sFrontHaulRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT]
Definition: xran_common.h:232
void tti_ota_cb(struct rte_timer *tim, void *arg)
Definition: xran_main.c:632
uint16_t symbMask
Definition: xran_fh_o_du.h:448
uint32_t xran_lib_ota_sym
Definition: xran_main.c:112
uint8_t up_vlan_tag
Definition: xran_fh_o_du.h:360
int32_t xran_pkt_validate(void *arg, struct rte_mbuf *mbuf, void *iq_data_start, uint16_t size, uint8_t CC_ID, uint8_t Ant_ID, uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id, uint8_t symb_id, struct ecpri_seq_id *seq_id, uint16_t num_prbu, uint16_t start_prbu, uint16_t sym_inc, uint16_t rb, uint16_t sect_id)
Definition: xran_main.c:1536
struct xran_flat_buffer * pBuffers
Definition: xran_fh_o_du.h:596
uint32_t enablePrach
Definition: xran_common.h:212
uint8_t xran_get_conf_compmethod(void *pHandle)
Get the configuration of compression method for RU.
Definition: xran_main.c:3018
BbuIoBufCtrlStruct sFHSrsRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANT_ARRAY_ELM_NR]
Definition: xran_common.h:227
int32_t xran_process_srs_sym(void *arg, struct rte_mbuf *mbuf, void *iq_data_start, uint16_t size, uint8_t CC_ID, uint8_t Ant_ID, uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id, uint8_t symb_id, uint16_t num_prbu, uint16_t start_prbu, uint16_t sym_inc, uint16_t rb, uint16_t sect_id, uint32_t *mb_free)
Definition: xran_main.c:1461
struct xran_cp_header_params hdr
Definition: xran_cp_api.h:320
Header file for function to work with 5G NR frame structure and related routines. ...
uint8_t slotNr[XRAN_PRACH_CANDIDATE_SLOT]
Definition: xran_common.h:108
struct xran_prach_config prach_conf
Definition: xran_fh_o_du.h:515
#define XRAN_SYMBOL_TYPE_DL
Definition: xran_fh_o_du.h:146
int16_t bf_weight_update
Definition: xran_fh_o_du.h:399
int xran_init_sectionid(void *pHandle)
Definition: xran_main.c:278
int xran_ethdi_init_dpdk_io(char *name, const struct xran_io_loop_cfg *io_cfg, int *lcore_id, struct ether_addr *p_lls_cu_addr, struct ether_addr *p_ru_addr, uint16_t cp_vlan, uint16_t up_vlan)
Definition: ethdi.c:288
const xRANPrachPreambleLRAStruct gxranPreambleforLRA[13]
int16_t compMethod
Definition: xran_fh_o_du.h:400
int32_t xran_5g_srs_req(void *pHandle, struct xran_buffer_list *pDstBuffer[XRAN_MAX_ANT_ARRAY_ELM_NR][XRAN_N_FE_BUF_LEN], xran_transport_callback_fn pCallback, void *pCallbackTag)
Definition: xran_main.c:2679
uint64_t timing_get_current_second(void)
Definition: xran_timer.c:88
uint8_t xran_get_num_eAxcUl(void *pHandle)
Get the configuration of the number of antenna.
Definition: xran_main.c:3059
uint8_t num_eAxc
Definition: common.c:47
BbuIoBufCtrlStruct sFrontHaulRxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR]
Definition: xran_common.h:225
uint32_t enableSrs
Definition: xran_common.h:219
int32_t xran_app_fragment_packet(struct rte_mbuf *pkt_in, struct rte_mbuf **pkts_out, uint16_t nb_pkts_out, uint16_t mtu_size, struct rte_mempool *pool_direct, struct rte_mempool *pool_indirect, struct xran_section_info *sectinfo, uint8_t *seqid)
struct xran_flat_buffer sFrontHaulTxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT]
Definition: xran_common.h:231
This file has all definitions for the Ethernet Data Interface Layer.
uint32_t neAxcUl
Definition: xran_fh_o_du.h:502
void xran_timer_arm_ex(struct rte_timer *tim, void *CbFct, void *CbArg, unsigned tim_lcore)
Definition: xran_main.c:724
void(* xran_callback_sym_fn)(void *)
Definition: xran_fh_o_du.h:239
BbuIoBufCtrlStruct sFrontHaulTxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR]
Definition: xran_common.h:222
enum xran_category xranCat
Definition: xran_fh_o_du.h:484
#define NUM_OF_FRAMES_PER_SECOND
Definition: xran_main.c:91
Header file for functions to perform application level fragmentation.
Modules provide debug prints and utility functions.
struct xran_slot_config sSlotConfig[XRAN_MAX_TDD_PERIODICITY]
Definition: xran_fh_o_du.h:465
#define PID_SYM_OTA_CB
struct xran_ecpri_cmn_hdr cmnhdr
Definition: xran_pkt.h:132
#define XRAN_SLOT_TYPE_FDD
Definition: xran_fh_o_du.h:142
int16_t iq_buffer_offset
Definition: xran_fh_o_du.h:385
uint32_t SkipTti[XRAN_CB_MAX]
Definition: xran_common.h:254
int16_t nStartSymb
Definition: xran_fh_o_du.h:396
uint8_t xran_get_conf_fftsize(void *pHandle)
Get the configuration of FFT size for RU.
Definition: xran_main.c:2985
This file provides the definitions for User Plane Messages APIs.
#define PID_TIME_ARM_TIMER
struct xran_flat_buffer sFrontHaulRxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT]
Definition: xran_common.h:233
#define XRAN_MAX_PKT_BURST_PER_SYM
Definition: xran_common.h:193
struct xran_eaxcid_config * xran_get_conf_eAxC(void *pHandle)
Get the configuration of eAxC ID.
Definition: xran_main.c:2955
struct xran_section_info * xran_cp_iterate_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id, uint32_t *next)
Iterate each section information of C-Plane from the database of eAxC by given information.
Definition: xran_cp_api.c:291
XRAN layer common functionality for both lls-CU and RU as well as C-plane and U-plane.
#define PID_CP_DL_CB
int xran_cp_getsize_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id)
Get the size of stored entries for the database of eAxC by given information.
Definition: xran_cp_api.c:334
int handle_ecpri_ethertype(struct rte_mbuf *pkt, uint64_t rx_time)
Definition: xran_main.c:1342
struct xran_ru_config ru_conf
Definition: xran_fh_o_du.h:518
int xran_register_cb_mbuf2ring(xran_ethdi_mbuf_send_fn mbuf_send_cp, xran_ethdi_mbuf_send_fn mbuf_send_up)
Definition: xran_main.c:2918
int xran_cp_reset_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id)
Reset a database of eAxC by given information.
Definition: xran_cp_api.c:366
int(* xran_fh_tti_callback_fn)(void *)
Definition: xran_fh_o_du.h:242
uint8_t cp_vlan_tag
Definition: xran_fh_o_du.h:359
struct xran_section_desc * p_sec_desc[XRAN_NUM_OF_SYMBOL_PER_SLOT]
Definition: xran_fh_o_du.h:404
#define XRAN_MAX_CELLS_PER_PORT
Definition: xran_fh_o_du.h:125
int32_t xran_reg_physide_cb(void *pHandle, xran_fh_tti_callback_fn Cb, void *cbParam, int skipTtiNum, enum callback_to_phy_id id)
Definition: xran_main.c:2900
callback_to_phy_id
Definition: xran_fh_o_du.h:219
#define UNIX_TO_GPS_SECONDS_OFFSET
Definition: xran_main.c:90
#define MBUF_CACHE
Definition: ethernet.h:47
long tx_bytes_per_sec
Definition: xran_common.c:121
uint32_t symbol
Definition: xran_fh_o_du.h:289
struct xran_fh_init fh_init
Definition: xran_common.h:208
uint32_t slotiId
Definition: xran_fh_o_du.h:290
int32_t xran_5g_prach_req(void *pHandle, struct xran_buffer_list *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN], xran_transport_callback_fn pCallback, void *pCallbackTag)
Definition: xran_main.c:2636
struct xran_timer_ctx timer_ctx[MAX_NUM_OF_XRAN_CTX]
Definition: xran_main.c:103
#define XRAN_NUM_OF_SYMBOL_PER_SLOT
Definition: xran_fh_o_du.h:122
xran_transport_callback_fn pSrsCallback[XRAN_MAX_SECTOR_NR]
Definition: xran_common.h:244
int32_t DynamicSectionEna
Definition: xran_fh_o_du.h:363
#define O_DU
Definition: xran_common.h:47
uint8_t * xran_add_hdr_offset(uint8_t *dst, int16_t compMethod)
Definition: xran_main.c:2741
int xran_is_prach_slot(uint32_t subframe_id, uint32_t slot_id)
Definition: xran_main.c:243
int xran_prepare_ctrl_pkt(struct rte_mbuf *mbuf, struct xran_cp_gen_params *params, uint8_t CC_ID, uint8_t Ant_ID, uint8_t seq_id)
Create a C-Plane packet Transport layer fragmentation is not supported.
Definition: xran_cp_api.c:1381
int32_t GPS_Alpha
Definition: xran_fh_o_du.h:364
uint32_t xran_lib_ota_sym_idx
Definition: xran_main.c:113
uint16_t xran_max_frame
Definition: xran_main.c:116
enum xran_if_state xran_get_if_state(void)
Definition: xran_main.c:238
Definitions and support functions to process XRAN packet.
uint8_t isPRACHslot[XRAN_PRACH_CANDIDATE_SLOT]
Definition: xran_common.h:138
uint32_t neAxc
Definition: xran_fh_o_du.h:501
This file provides public interface to xRAN Front Haul layer implementation as defined in the ORAN-WG...
int xran_init_srs(struct xran_fh_config *pConf, struct xran_device_ctx *p_xran_dev_ctx)
Definition: xran_main.c:294
void xran_fs_clear_slot_type(uint32_t nPhyInstanceId)
#define SLOTNUM_PER_SUBFRAME
Definition: xran_common.h:54
struct xran_prach_cp_config PrachCPConfig
Definition: xran_common.h:210
#define XRAN_STATUS_INVALID_PARAM
Definition: xran_fh_o_du.h:75
#define MAX_NUM_OF_DPDK_TIMERS
Definition: xran_main.c:77
struct xran_section_desc sec_desc[XRAN_NUM_OF_SYMBOL_PER_SLOT]
Definition: xran_cp_api.h:205
struct rte_mempool * direct_pool
Definition: xran_common.h:267
struct xran_buffer_list sBufferList
Definition: sample-app.c:129
#define XRAN_SLOT_TYPE_SP
Definition: xran_fh_o_du.h:141
XranSymCallbackFn pSymCallback
Definition: xran_common.h:163
uint8_t xran_get_conf_iqwidth(void *pHandle)
Get the configuration of IQ bit width for RU.
Definition: xran_main.c:3005
#define O_RU
Definition: xran_common.h:48
#define MLogIncrementCounter()
Definition: xran_mlog_lnx.h:43
uint8_t preambleFmrt[XRAN_PRACH_CANDIDATE_PREAMBLE]
Definition: xran_common.h:105
uint16_t T1a_max_cp_ul
Definition: xran_fh_o_du.h:350
struct xran_section_gen_info * sections
Definition: xran_cp_api.h:322
uint16_t numSections
Definition: xran_cp_api.h:318
int rx_packet_callback_tracker[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR]
Definition: xran_common.h:260
struct xran_section_gen_info::@2 exData[XRAN_MAX_NUM_EXTENSIONS]
BbuIoBufCtrlStruct sFHPrachRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR]
Definition: xran_common.h:226
int32_t xran_reg_sym_cb(void *pHandle, xran_callback_sym_fn symCb, void *symCbParam, uint8_t symb, uint8_t ant)
Definition: xran_main.c:2888
#define MLogTask(w, x, y)
Definition: xran_mlog_lnx.h:44
#define PID_CP_UL_CB
int32_t xran_stop(void *pHandle)
Definition: xran_main.c:2852
void sym_ota_cb(struct rte_timer *tim, void *arg, unsigned long *used_tick)
Definition: xran_main.c:582
def res
Definition: master.py:498
struct xran_prb_elm prbMap[XRAN_MAX_PRBS]
Definition: xran_fh_o_du.h:423
uint32_t xran_get_time_stats(uint64_t *total_time, uint64_t *used_time, uint32_t *core_used, uint32_t clear)
Definition: xran_main.c:2721
uint8_t ecpri_mesg_type
Definition: xran_pkt.h:118
#define PID_TTI_CB_TO_PHY
uint32_t nBufferPoolIndex
Definition: xran_common.h:152
int32_t xran_fs_get_slot_type(int32_t nCellIdx, int32_t nSlotdx, int32_t nType)
int(* xran_ethdi_mbuf_send_fn)(struct rte_mbuf *mb, uint16_t ethertype)
Definition: xran_common.h:169
int32_t xran_get_common_counters(void *pXranLayerHandle, struct xran_common_counters *pStats)
Definition: xran_main.c:3074
int process_mbuf(struct rte_mbuf *pkt)
Definition: xran_common.c:143
#define CHECK_NOT_NULL(param, returnValue)
Definition: xran_printf.h:111
void(* xran_transport_callback_fn)(void *, xran_status_t)
Definition: xran_fh_o_du.h:245
#define XRAN_THREAD_DEFAULT_PRIO
Definition: ethdi.h:52
#define N_SYM_PER_SLOT
Definition: common.h:50
#define XRAN_SYMBOL_TYPE_FDD
Definition: xran_fh_o_du.h:149
int xran_cp_init_sectiondb(void *pHandle)
Initialize section database. Allocate required memory space to store section information. Each eAxC allocates dedicated storage and the entry size is the maximum number of sections. Total entry size : number of CC * number of antenna * max number of sections * 2(direction)
Definition: xran_cp_api.c:66
#define XRAN_STATUS_RESOURCE
Definition: xran_fh_o_du.h:68
#define XranGetFrameNum(tti, SFNatSecStart, numSubFramePerSystemFrame, numSlotPerSubFrame)
Definition: xran_fh_o_du.h:102
This file provides the definitions for Control Plane Messages APIs.
uint64_t interval_us
Definition: xran_main.c:109
#define MLogTick()
Definition: xran_mlog_lnx.h:42
int32_t xran_process_prach_sym(void *arg, struct rte_mbuf *mbuf, void *iq_data_start, uint16_t size, uint8_t CC_ID, uint8_t Ant_ID, uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id, uint8_t symb_id, uint16_t num_prbu, uint16_t start_prbu, uint16_t sym_inc, uint16_t rb, uint16_t sect_id, uint32_t *mb_free)
Definition: xran_main.c:1384
int xran_cp_create_and_send_section(void *pHandle, uint8_t ru_port_id, int dir, int tti, int cc_id, struct xran_prb_map *prbMap, enum xran_category category, uint8_t ctx_id)
Definition: xran_main.c:737
long rx_bytes_counter
Definition: xran_common.c:120
int32_t xran_fs_get_symbol_type(int32_t nCellIdx, int32_t nSlotdx, int32_t nSymbIdx)
int16_t numSymb
Definition: xran_fh_o_du.h:397
int send_symbol_ex(enum xran_pkt_dir direction, uint16_t section_id, struct rte_mbuf *mb, struct rb_map *data, const enum xran_input_byte_order iq_buf_byte_order, uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id, uint8_t symbol_no, int prb_start, int prb_num, uint8_t CC_ID, uint8_t RU_Port_ID, uint8_t seq_id)
Definition: xran_common.c:436
BbuIoBufCtrlStruct sFrontHaulRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR]
Definition: xran_common.h:224
int xran_register_ethertype_handler(uint16_t ethertype, ethertype_handler callback)
Definition: ethdi.c:124
long tx_bytes_counter
Definition: xran_common.c:119
#define SUBFRAMES_PER_SYSTEMFRAME
Definition: common.h:57
phy_encoder_poll_fn bbdev_enc
Definition: xran_common.h:273
#define TIMER_RESOLUTION_CYCLES
Definition: xran_common.h:68
uint8_t nPrachSubcSpacing
Definition: xran_fh_o_du.h:433
#define XRAN_SLOT_TYPE_UL
Definition: xran_fh_o_du.h:140
int8_t * p_o_du_addr
Definition: xran_fh_o_du.h:333
int32_t xran_status_t
Definition: xran_fh_o_du.h:236
int32_t xran_bm_free_buffer(void *pHandle, void *pData, void *pCtrl)
Definition: xran_main.c:2541
int32_t xran_bm_init(void *pHandle, uint32_t *pPoolIndex, uint32_t nNumberOfBuffers, uint32_t nBufferSize)
Definition: xran_main.c:2454
#define MAX_NUM_OF_XRAN_CTX
Definition: xran_main.c:73