* INTC Contribution to the O-RAN F Release for O-DU Low
[o-du/phy.git] / fhi_lib / lib / src / xran_common.c
1 /******************************************************************************
2 *
3 *   Copyright (c) 2020 Intel.
4 *
5 *   Licensed under the Apache License, Version 2.0 (the "License");
6 *   you may not use this file except in compliance with the License.
7 *   You may obtain a copy of the License at
8 *
9 *       http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *   Unless required by applicable law or agreed to in writing, software
12 *   distributed under the License is distributed on an "AS IS" BASIS,
13 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *   See the License for the specific language governing permissions and
15 *   limitations under the License.
16 *
17 *******************************************************************************/
18
19 /**
20  * @brief XRAN layer common functionality for both O-DU and O-RU as well as C-plane and
21  *    U-plane
22  * @file xran_common.c
23  * @ingroup group_source_xran
24  * @author Intel Corporation
25  **/
26
27 #define _GNU_SOURCE
28 #include <assert.h>
29 #include <err.h>
30 #include <arpa/inet.h>
31 #include <sys/time.h>
32 #include <time.h>
33 #include <pthread.h>
34 #include <immintrin.h>
35 #include <rte_mbuf.h>
36 #include <stdio.h>
37 #include <stdbool.h>
38
39 #include "xran_common.h"
40 #include "ethdi.h"
41 #include "xran_pkt.h"
42 #include "xran_pkt_up.h"
43 #include "xran_cp_api.h"
44 #include "xran_up_api.h"
45 #include "xran_cp_proc.h"
46 #include "xran_dev.h"
47 #include "xran_lib_mlog_tasks_id.h"
48
49 #include "xran_printf.h"
50 #include "xran_mlog_lnx.h"
51
52 static struct timespec sleeptime = {.tv_nsec = 1E3 }; /* 1 us */
53
54 extern int32_t first_call;
55
56 #define MBUFS_CNT 16
57
58 extern int32_t xran_process_rx_sym(void *arg,
59                         struct rte_mbuf *mbuf,
60                         void *iq_data_start,
61                         uint16_t size,
62                         uint8_t CC_ID,
63                         uint8_t Ant_ID,
64                         uint8_t frame_id,
65                         uint8_t subframe_id,
66                         uint8_t slot_id,
67                         uint8_t symb_id,
68                         uint16_t num_prbu,
69                         uint16_t start_prbu,
70                         uint16_t sym_inc,
71                         uint16_t rb,
72                         uint16_t sect_id,
73                         uint32_t *mb_free,
74                         int8_t   expect_comp,
75                         uint8_t compMeth,
76                         uint8_t iqWidth);
77
78
79 extern int xran_process_prach_sym(void *arg,
80                         struct rte_mbuf *mbuf,
81                         void *iq_data_start,
82                         uint16_t size,
83                         uint8_t CC_ID,
84                         uint8_t Ant_ID,
85                         uint8_t frame_id,
86                         uint8_t subframe_id,
87                         uint8_t slot_id,
88                         uint8_t symb_id,
89                         uint16_t num_prbu,
90                         uint16_t start_prbu,
91                         uint16_t sym_inc,
92                         uint16_t rb,
93                         uint16_t sect_id,
94                         uint32_t *mb_free);
95
96 extern int32_t xran_process_srs_sym(void *arg,
97                         struct rte_mbuf *mbuf,
98                         void *iq_data_start,
99                         uint16_t size,
100                         uint8_t CC_ID,
101                         uint8_t Ant_ID,
102                         uint8_t frame_id,
103                         uint8_t subframe_id,
104                         uint8_t slot_id,
105                         uint8_t symb_id,
106                         uint16_t num_prbu,
107                         uint16_t start_prbu,
108                         uint16_t sym_inc,
109                         uint16_t rb,
110                         uint16_t sect_id,
111                         uint32_t *mb_free,
112                         int8_t  expect_comp,
113                         uint8_t compMeth,
114                         uint8_t iqWidth);
115
116 extern int32_t xran_pkt_validate(void *arg,
117                         struct rte_mbuf *mbuf,
118                         void *iq_data_start,
119                         uint16_t size,
120                         uint8_t CC_ID,
121                         uint8_t Ant_ID,
122                         uint8_t frame_id,
123                         uint8_t subframe_id,
124                         uint8_t slot_id,
125                         uint8_t symb_id,
126                         union ecpri_seq_id *seq_id,
127                         uint16_t num_prbu,
128                         uint16_t start_prbu,
129                         uint16_t sym_inc,
130                         uint16_t rb,
131                         uint16_t sect_id);
132
133 int process_mbuf_batch(struct rte_mbuf* pkt_q[], void* handle, int16_t num, struct xran_eaxc_info *p_cid, uint32_t* ret_data)
134 {
135     struct rte_mbuf* pkt;
136     struct xran_device_ctx* p_dev_ctx = (struct xran_device_ctx*)handle;
137     void* iq_samp_buf[MBUFS_CNT];
138     union ecpri_seq_id seq[MBUFS_CNT];
139     static int symbol_total_bytes[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR] = { 0 };
140     int num_bytes[MBUFS_CNT] = { 0 }, num_bytes_pusch[MBUFS_CNT] = { 0 };
141     int16_t i, j;
142
143     struct xran_common_counters* pCnt = &p_dev_ctx->fh_counters;
144
145     uint8_t CC_ID[MBUFS_CNT] = { 0 };
146     uint8_t Ant_ID[MBUFS_CNT] = { 0 };
147     uint8_t frame_id[MBUFS_CNT] = { 0 };
148     uint8_t subframe_id[MBUFS_CNT] = { 0 };
149     uint8_t slot_id[MBUFS_CNT] = { 0 };
150     uint8_t symb_id[MBUFS_CNT] = { 0 };
151
152     uint16_t num_prbu[MBUFS_CNT];
153     uint16_t start_prbu[MBUFS_CNT];
154     uint16_t sym_inc[MBUFS_CNT];
155     uint16_t rb[MBUFS_CNT];
156     uint16_t sect_id[MBUFS_CNT];
157     uint16_t prb_elem_id[MBUFS_CNT] = {0};
158
159     uint8_t compMeth[MBUFS_CNT] = { 0 };
160     uint8_t iqWidth[MBUFS_CNT] = { 0 };
161     uint8_t compMeth_ini = 0;
162     uint8_t iqWidth_ini = 0;
163
164     uint32_t pkt_size[MBUFS_CNT];
165
166     int expect_comp = (p_dev_ctx->fh_cfg.ru_conf.compMeth != XRAN_COMPMETHOD_NONE);
167     enum xran_comp_hdr_type staticComp = p_dev_ctx->fh_cfg.ru_conf.xranCompHdrType;
168
169     int16_t num_pusch = 0, num_prach = 0, num_srs = 0;
170     int16_t pusch_idx[MBUFS_CNT] = { 0 }, prach_idx[MBUFS_CNT] = { 0 }, srs_idx[MBUFS_CNT] = { 0 };
171     int8_t xran_port = xran_dev_ctx_get_port_id(p_dev_ctx);
172     int16_t max_ant_num = 0;
173     uint8_t *ptr_seq_id_num_port;
174     struct xran_eaxcid_config* conf;
175     uint8_t seq_id[MBUFS_CNT];
176     uint16_t cid[MBUFS_CNT];
177
178     struct xran_ecpri_hdr* ecpri_hdr[MBUFS_CNT];
179     struct radio_app_common_hdr* radio_hdr[MBUFS_CNT];
180     struct data_section_hdr* data_hdr[MBUFS_CNT];
181     struct data_section_compression_hdr* data_compr_hdr[MBUFS_CNT];
182
183     const int16_t ecpri_size = sizeof(struct xran_ecpri_hdr);
184     const int16_t rad_size = sizeof(struct radio_app_common_hdr);
185     const int16_t data_size = sizeof(struct data_section_hdr);
186     const int16_t compr_size = sizeof(struct data_section_compression_hdr);
187
188     char* buf_start[MBUFS_CNT];
189     uint16_t start_off[MBUFS_CNT];
190     uint16_t iq_offset[MBUFS_CNT];
191     uint16_t last[MBUFS_CNT];
192
193     uint32_t tti = 0;
194     struct rte_mbuf* mb = NULL;
195     struct xran_prb_map* pRbMap = NULL;
196     struct xran_prb_elm* prbMapElm = NULL;
197     //uint16_t iq_sample_size_bits;
198     uint16_t idxElm = 0, total_sections = 0;
199
200 #if XRAN_MLOG_VAR
201     uint32_t mlogVar[10];
202     uint32_t mlogVarCnt = 0;
203 #endif
204
205     if (xran_port < 0) {
206         print_err("Invalid pHandle");
207         return MBUF_FREE;
208     }
209
210     if (xran_port > XRAN_PORTS_NUM) {
211         print_err("Invalid port - %d", xran_port);
212         return MBUF_FREE;
213     }
214
215     if(first_call == 0) {
216         for(i = 0; i < num; i++ )
217             ret_data[i] = MBUF_FREE;
218         return MBUF_FREE;
219     }
220
221     conf = &(p_dev_ctx->eAxc_id_cfg);
222     if (conf == NULL) {
223         rte_panic("conf == NULL");
224     }
225
226     if (p_dev_ctx->fh_init.io_cfg.id == O_DU)
227     {
228         max_ant_num = XRAN_MAX_ANTENNA_NR * 2 + XRAN_MAX_ANT_ARRAY_ELM_NR;
229         ptr_seq_id_num_port = &xran_upul_seq_id_num[xran_port][0][0];
230     }
231     else if (p_dev_ctx->fh_init.io_cfg.id == O_RU)
232     {
233         max_ant_num = XRAN_MAX_ANTENNA_NR;
234         ptr_seq_id_num_port = &xran_updl_seq_id_num[xran_port][0][0];
235     }
236     else
237 {
238         rte_panic("incorrect fh_init.io_cfg.id");
239         }
240
241     if (staticComp == XRAN_COMP_HDR_TYPE_STATIC)
242     {
243         compMeth_ini = p_dev_ctx->fh_cfg.ru_conf.compMeth;
244         iqWidth_ini = p_dev_ctx->fh_cfg.ru_conf.iqWidth;
245 }
246
247     for (i = 0; i < MBUFS_CNT; i++)
248 {
249         pkt_size[i] = pkt_q[i]->pkt_len;
250         buf_start[i] = (char*)pkt_q[i]->buf_addr;
251         start_off[i] = pkt_q[i]->data_off;
252 }
253
254     if (expect_comp && (staticComp != XRAN_COMP_HDR_TYPE_STATIC))
255     {
256 #pragma vector always
257         for (i = 0; i < MBUFS_CNT; i++)
258         {
259 #if XRAN_MLOG_VAR
260             mlogVarCnt = 0;
261 #endif
262             ecpri_hdr[i] = (void*)(buf_start[i] + start_off[i]);
263             radio_hdr[i] = (void*)(buf_start[i] + start_off[i] + ecpri_size);
264             data_hdr[i] = (void*)(buf_start[i] + start_off[i] + ecpri_size + rad_size);
265             data_compr_hdr[i] = (void*)(buf_start[i] + start_off[i] + ecpri_size + rad_size + data_size);
266             seq[i] = ecpri_hdr[i]->ecpri_seq_id;
267             seq_id[i] = seq[i].bits.seq_id;
268             last[i] = seq[i].bits.e_bit;
269
270             iq_offset[i] = ecpri_size + rad_size + data_size + compr_size;
271
272             iq_samp_buf[i] = (void*)(buf_start[i] + start_off[i] + iq_offset[i]);
273             num_bytes[i] = pkt_size[i] - iq_offset[i];
274
275             if (ecpri_hdr[i] == NULL ||
276                 radio_hdr[i] == NULL ||
277                 data_hdr[i] == NULL ||
278                 data_compr_hdr[i] == NULL ||
279                 iq_samp_buf[i] == NULL)
280             {
281                 num_bytes[i] = 0;       /* packet too short */
282             }
283
284 #if XRAN_MLOG_VAR
285             if(radio_hdr[i] != NULL && data_hdr[i] != NULL)
286             {
287                 mlogVar[mlogVarCnt++] = 0xBBBBBBBB;
288                 mlogVar[mlogVarCnt++] = xran_lib_ota_tti;
289                 mlogVar[mlogVarCnt++] = radio_hdr[i]->frame_id;
290                 mlogVar[mlogVarCnt++] = radio_hdr[i]->sf_slot_sym.subframe_id;
291                 mlogVar[mlogVarCnt++] = radio_hdr[i]->sf_slot_sym.slot_id;
292                 mlogVar[mlogVarCnt++] = radio_hdr[i]->sf_slot_sym.symb_id;
293                 mlogVar[mlogVarCnt++] = data_hdr[i]->fields.sect_id;
294                 mlogVar[mlogVarCnt++] = data_hdr[i]->fields.start_prbu;
295                 mlogVar[mlogVarCnt++] = data_hdr[i]->fields.num_prbu;
296                 mlogVar[mlogVarCnt++] = rte_pktmbuf_pkt_len(pkt_q[i]);
297                 MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
298             }
299 #endif
300         }
301     }
302     else
303     {
304 #pragma vector always
305         for (i = 0; i < MBUFS_CNT; i++)
306         {
307 #if XRAN_MLOG_VAR
308             mlogVarCnt = 0;
309 #endif
310             ecpri_hdr[i] = (void*)(buf_start[i] + start_off[i]);
311             radio_hdr[i] = (void*)(buf_start[i] + start_off[i] + ecpri_size);
312             data_hdr[i] = (void*)(buf_start[i] + start_off[i] + ecpri_size + rad_size);
313             seq[i] = ecpri_hdr[i]->ecpri_seq_id;
314             seq_id[i] = seq[i].bits.seq_id;
315             last[i] = seq[i].bits.e_bit;
316
317             iq_offset[i] = ecpri_size + rad_size + data_size;
318             iq_samp_buf[i] = (void*)(buf_start[i] + start_off[i] + iq_offset[i]);
319             num_bytes[i] = pkt_size[i] - iq_offset[i];
320
321             if (ecpri_hdr[i] == NULL ||
322                 radio_hdr[i] == NULL ||
323                 data_hdr[i] == NULL ||
324                 iq_samp_buf[i] == NULL)
325             {
326                 num_bytes[i] = 0;       /* packet too short */
327             }
328
329 #if XRAN_MLOG_VAR
330             if (radio_hdr[i] != NULL && data_hdr[i] != NULL)
331             {
332                 mlogVar[mlogVarCnt++] = 0xBBBBBBBB;
333                 mlogVar[mlogVarCnt++] = xran_lib_ota_tti;
334                 mlogVar[mlogVarCnt++] = radio_hdr[i]->frame_id;
335                 mlogVar[mlogVarCnt++] = radio_hdr[i]->sf_slot_sym.subframe_id;
336                 mlogVar[mlogVarCnt++] = radio_hdr[i]->sf_slot_sym.slot_id;
337                 mlogVar[mlogVarCnt++] = radio_hdr[i]->sf_slot_sym.symb_id;
338                 mlogVar[mlogVarCnt++] = data_hdr[i]->fields.sect_id;
339                 mlogVar[mlogVarCnt++] = data_hdr[i]->fields.start_prbu;
340                 mlogVar[mlogVarCnt++] = data_hdr[i]->fields.num_prbu;
341                 mlogVar[mlogVarCnt++] = rte_pktmbuf_pkt_len(pkt_q[i]);
342                 MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
343             }
344 #endif
345         }
346     }
347
348     for (i = 0; i < MBUFS_CNT; i++) {
349         if(p_cid->ccId == 0xFF && p_cid->ruPortId == 0xFF) {
350             cid[i] = rte_be_to_cpu_16((uint16_t)ecpri_hdr[i]->ecpri_xtc_id);
351             if (num_bytes[i] > 0) {
352                 CC_ID[i]  = (cid[i] & conf->mask_ccId) >> conf->bit_ccId;
353                 Ant_ID[i] = (cid[i] & conf->mask_ruPortId) >> conf->bit_ruPortId;
354             }
355         } else {
356             if (num_bytes[i] > 0) {
357                 CC_ID[i]  = p_cid->ccId;
358                 Ant_ID[i] = p_cid->ruPortId;
359             }
360         }
361     }
362
363     for (i = 0; i < MBUFS_CNT; i++)
364     {
365         radio_hdr[i]->sf_slot_sym.value = rte_be_to_cpu_16(radio_hdr[i]->sf_slot_sym.value);
366         data_hdr[i]->fields.all_bits = rte_be_to_cpu_32(data_hdr[i]->fields.all_bits);
367     }
368
369     for (i = 0; i < MBUFS_CNT; i++)
370     {
371         if (num_bytes[i] > 0)
372         {
373             compMeth[i] = compMeth_ini;
374             iqWidth[i] = iqWidth_ini;
375
376             frame_id[i] = radio_hdr[i]->frame_id;
377             subframe_id[i] = radio_hdr[i]->sf_slot_sym.subframe_id;
378             slot_id[i] = radio_hdr[i]->sf_slot_sym.slot_id;
379             symb_id[i] = radio_hdr[i]->sf_slot_sym.symb_id;
380
381             num_prbu[i] = data_hdr[i]->fields.num_prbu;
382             start_prbu[i] = data_hdr[i]->fields.start_prbu;
383             sym_inc[i] = data_hdr[i]->fields.sym_inc;
384             rb[i] = data_hdr[i]->fields.rb;
385             sect_id[i] = data_hdr[i]->fields.sect_id;
386
387             if (num_prbu[i] == 0)
388                 num_prbu[i] = p_dev_ctx->fh_cfg.nULRBs;
389
390             if (expect_comp && (staticComp != XRAN_COMP_HDR_TYPE_STATIC))
391             {
392                 compMeth[i] = data_compr_hdr[i]->ud_comp_hdr.ud_comp_meth;
393                 iqWidth[i] = data_compr_hdr[i]->ud_comp_hdr.ud_iq_width;
394             }
395
396             if (CC_ID[i] >= XRAN_MAX_CELLS_PER_PORT || Ant_ID[i] >= max_ant_num || symb_id[i] >= XRAN_NUM_OF_SYMBOL_PER_SLOT)
397             {
398                 ptr_seq_id_num_port[CC_ID[i] * max_ant_num + Ant_ID[i]] = seq_id[i]; // for next
399                 pCnt->Rx_pkt_dupl++;
400 //                print_err("Invalid CC ID - %d or antenna ID or Symbol ID- %d", CC_ID[i], Ant_ID[i], symb_id[i]);
401             }
402             else
403             {
404                 ptr_seq_id_num_port[CC_ID[i] * max_ant_num + Ant_ID[i]]++;
405             }
406
407             pCnt->rx_counter++;
408             pCnt->Rx_on_time++;
409             pCnt->Total_msgs_rcvd++;
410             struct xran_prach_cp_config *PrachCfg = NULL;
411             if(p_dev_ctx->dssEnable){
412                 tti = frame_id[i] * SLOTS_PER_SYSTEMFRAME(p_dev_ctx->interval_us_local) +
413                       subframe_id[i] * SLOTNUM_PER_SUBFRAME(p_dev_ctx->interval_us_local) + slot_id[i];
414                 int techSlot = (tti % p_dev_ctx->dssPeriod);
415                 if(p_dev_ctx->technology[techSlot] == 1)
416                     PrachCfg  = &(p_dev_ctx->PrachCPConfig);
417                 else
418                     PrachCfg  = &(p_dev_ctx->PrachCPConfigLTE);
419             }
420             else{
421                 PrachCfg = &(p_dev_ctx->PrachCPConfig);
422             }
423
424             if (Ant_ID[i] >= p_dev_ctx->srs_cfg.eAxC_offset && p_dev_ctx->fh_cfg.srsEnable)
425             {
426                 Ant_ID[i] -= p_dev_ctx->srs_cfg.eAxC_offset;
427                 if (last[i] == 1)
428                 {
429                     srs_idx[num_srs] = i;
430                     num_srs += 1;
431                     pCnt->rx_srs_packets++;
432                 }
433             }
434             else if (Ant_ID[i] >= PrachCfg->eAxC_offset && p_dev_ctx->fh_cfg.prachEnable)
435             {
436                 Ant_ID[i] -= PrachCfg->eAxC_offset;
437                 if (last[i] == 1)
438                 {
439                     prach_idx[num_prach] = i;
440                     num_prach += 1;
441                     pCnt->rx_prach_packets[Ant_ID[i]]++;
442                 }
443             }
444             else
445             {
446                 if (last[i] == 1)
447                 {
448                     pusch_idx[num_pusch] = i;
449                     num_pusch += 1;
450                     pCnt->rx_pusch_packets[Ant_ID[i]]++;
451                 }
452             }
453             symbol_total_bytes[xran_port][CC_ID[i]][Ant_ID[i]] += num_bytes[i];
454             num_bytes_pusch[i] = symbol_total_bytes[xran_port][CC_ID[i]][Ant_ID[i]];
455             if (last[i] == 1)
456                 symbol_total_bytes[xran_port][CC_ID[i]][Ant_ID[i]] = 0;
457         }
458     }
459
460     for (j = 0; j < num_prach; j++)
461     {
462         i = prach_idx[j];
463         pkt = pkt_q[i];
464
465         print_dbg("Completed receiving PRACH symbol %d, size=%d bytes\n", symb_id[i], num_bytes[i]);
466
467         xran_process_prach_sym(p_dev_ctx,
468                 pkt,
469                 iq_samp_buf[i],
470                 num_bytes[i],
471                 CC_ID[i],
472                 Ant_ID[i],
473                 frame_id[i],
474                 subframe_id[i],
475                 slot_id[i],
476                 symb_id[i],
477                 num_prbu[i],
478                 start_prbu[i],
479                 sym_inc[i],
480                 rb[i],
481                 sect_id[i],
482                 &ret_data[i]);
483     }
484
485     for (j = 0; j < num_srs; j++)
486     {
487         i = srs_idx[j];
488         pkt = pkt_q[i];
489
490         print_dbg("SRS receiving symbol %d, size=%d bytes\n",
491                 symb_id[i], symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID[i]][Ant_ID[i]]);
492
493         uint64_t t1 = MLogXRANTick();
494         xran_process_srs_sym(p_dev_ctx,
495                 pkt,
496                 iq_samp_buf[i],
497                 num_bytes[i],
498                 CC_ID[i],
499                 Ant_ID[i],
500                 frame_id[i],
501                 subframe_id[i],
502                 slot_id[i],
503                 symb_id[i],
504                 num_prbu[i],
505                 start_prbu[i],
506                 sym_inc[i],
507                 rb[i],
508                 sect_id[i],
509                 &ret_data[i],
510                 expect_comp,
511                 compMeth[i],
512                 iqWidth[i]);
513         MLogXRANTask(PID_PROCESS_UP_PKT_SRS, t1, MLogXRANTick());
514     }
515
516     if (num_pusch == MBUFS_CNT)
517     {
518         for (i = 0; i < MBUFS_CNT; i++)
519         {
520             //iq_sample_size_bits = 16;
521             //if (expect_comp)
522             //    iq_sample_size_bits = iqWidth[i];
523
524             tti = frame_id[i] * SLOTS_PER_SYSTEMFRAME(p_dev_ctx->interval_us_local) +
525                 subframe_id[i] * SLOTNUM_PER_SUBFRAME(p_dev_ctx->interval_us_local) + slot_id[i];
526
527             pRbMap = (struct xran_prb_map*)p_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID[i]][Ant_ID[i]].sBufferList.pBuffers->pData;
528
529             if (pRbMap)
530             {
531                 /** Get the prb_elem_id */
532                 total_sections=0;
533                 if(pRbMap->prbMap[0].bf_weight.extType == 1)
534                 {
535                     for(idxElm=0 ; idxElm < pRbMap->nPrbElm ; idxElm++)
536                     {
537                         total_sections += pRbMap->prbMap[idxElm].bf_weight.numSetBFWs;
538                         if(total_sections >= (sect_id[i] + 1))
539                 {
540                             prb_elem_id[i] = idxElm;
541                             break;
542                         }
543                     }
544                 }
545                 else
546                 {
547                     prb_elem_id[i] = sect_id[i];
548                 }
549
550                 if (prb_elem_id[i] >= pRbMap->nPrbElm)
551                 {
552                     print_err("sect_id %d, prb_elem_id %d !=pRbMap->nPrbElm %d\n", sect_id[i], prb_elem_id[i], pRbMap->nPrbElm);
553                     ret_data[i] = MBUF_FREE;
554                     continue;
555                 }
556             }
557             else
558             {
559 //                print_err("pRbMap==NULL\n");
560                 ret_data[i] = MBUF_FREE;
561                 continue;
562             }
563
564             if (pRbMap->nPrbElm == 1)
565             {
566                 p_dev_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID[i]][Ant_ID[i]].sBufferList.pBuffers[symb_id[i]].pData = iq_samp_buf[i];
567                 p_dev_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID[i]][Ant_ID[i]].sBufferList.pBuffers[symb_id[i]].pCtrl = pkt_q[i];
568                 ret_data[i] = MBUF_KEEP;
569             }
570             else
571             {
572                 struct xran_section_desc* p_sec_desc = NULL;
573                 prbMapElm = &pRbMap->prbMap[prb_elem_id[i]];
574                 int16_t nSecDesc = prbMapElm->nSecDesc[symb_id[i]];
575                 p_sec_desc = &prbMapElm->sec_desc[symb_id[i]][nSecDesc];
576
577                 if (p_sec_desc)
578                 {
579                     mb = p_sec_desc->pCtrl;
580                     if (mb) {
581                         rte_pktmbuf_free(mb);
582                     }
583                     p_sec_desc->pCtrl = pkt_q[i];
584                     p_sec_desc->pData = iq_samp_buf[i];
585                     p_sec_desc->start_prbu = start_prbu[i];
586                     p_sec_desc->num_prbu = num_prbu[i];
587                     p_sec_desc->iq_buffer_len = num_bytes_pusch[i];
588                     p_sec_desc->iq_buffer_offset = iq_offset[i];
589                     ret_data[i] = MBUF_KEEP;
590                     prbMapElm->nSecDesc[symb_id[i]] += 1;
591                 }
592                 else
593 {
594 //                    print_err("p_sec_desc==NULL tti %u ant %d symb_id %d\n", tti, Ant_ID[i], symb_id[i]);
595                     ret_data[i] = MBUF_FREE;
596                 }
597             }
598         }
599     }
600     else
601     {
602         for (j = 0; j < num_pusch; j++)
603         {
604             i = pusch_idx[j];
605
606             //iq_sample_size_bits = 16;
607             //if (expect_comp)
608             //    iq_sample_size_bits = iqWidth[i];
609
610             tti = frame_id[i] * SLOTS_PER_SYSTEMFRAME(p_dev_ctx->interval_us_local) +
611                 subframe_id[i] * SLOTNUM_PER_SUBFRAME(p_dev_ctx->interval_us_local) + slot_id[i];
612
613             pRbMap = (struct xran_prb_map*)p_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID[i]][Ant_ID[i]].sBufferList.pBuffers->pData;
614
615             if (pRbMap)
616             {
617                 /** Get the prb_elem_id */
618                 total_sections=0;
619                 if(pRbMap->prbMap[0].bf_weight.extType == 1)
620                 {
621                     for(idxElm=0 ; idxElm < pRbMap->nPrbElm ; idxElm++)
622                     {
623                         total_sections += pRbMap->prbMap[idxElm].bf_weight.numSetBFWs;
624                         if(total_sections >= (sect_id[i] + 1))
625                         {
626                             prb_elem_id[i] = idxElm;
627                             break;
628                         }
629                     }
630                 }
631                 else
632                 {
633                     prb_elem_id[i] = sect_id[i];
634                 }
635
636                 if (prb_elem_id[i] >= pRbMap->nPrbElm)
637                 {
638                     print_err("sect_id %d, prb_elem_id %d !=pRbMap->nPrbElm %d\n", sect_id[i], prb_elem_id[i], pRbMap->nPrbElm);
639                     ret_data[i] = MBUF_FREE;
640                     continue;
641                 }
642             }
643             else
644             {
645 //                print_err("pRbMap==NULL\n");
646                 ret_data[i] = MBUF_FREE;
647                 continue;
648             }
649
650             if (pRbMap->nPrbElm == 1)
651             {
652                 p_dev_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID[i]][Ant_ID[i]].sBufferList.pBuffers[symb_id[i]].pData = iq_samp_buf[i];
653                 p_dev_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID[i]][Ant_ID[i]].sBufferList.pBuffers[symb_id[i]].pCtrl = pkt_q[i];
654                 ret_data[i] = MBUF_KEEP;
655             }
656             else
657             {
658                 struct xran_section_desc* p_sec_desc = NULL;
659                 prbMapElm = &pRbMap->prbMap[prb_elem_id[i]];
660                 int16_t nSecDesc = prbMapElm->nSecDesc[symb_id[i]];
661                 p_sec_desc = &prbMapElm->sec_desc[symb_id[i]][nSecDesc];
662
663                 if (p_sec_desc)
664                 {
665                     mb = p_sec_desc->pCtrl;
666                     if (mb) {
667                         rte_pktmbuf_free(mb);
668                     }
669                     p_sec_desc->pCtrl = pkt_q[i];
670                     p_sec_desc->pData = iq_samp_buf[i];
671                     p_sec_desc->start_prbu = start_prbu[i];
672                     p_sec_desc->num_prbu = num_prbu[i];
673                     p_sec_desc->iq_buffer_len = num_bytes_pusch[i];
674                     p_sec_desc->iq_buffer_offset = iq_offset[i];
675                     ret_data[i] = MBUF_KEEP;
676                     prbMapElm->nSecDesc[symb_id[i]] += 1;
677                 }
678                 else
679                 {
680 //                    print_err("p_sec_desc==NULL tti %u ant %d symb_id %d\n", tti, Ant_ID[i], symb_id[i]);
681                     ret_data[i] = MBUF_FREE;
682                 }
683             }
684         }
685     }
686     return MBUF_FREE;
687 }
688
689 int
690 process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid)
691 {
692     uint64_t tt1 = MLogXRANTick();
693     struct xran_device_ctx *p_dev_ctx = (struct xran_device_ctx *)handle;
694     void *iq_samp_buf;
695     union ecpri_seq_id seq;
696     static int symbol_total_bytes[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR] = {0};
697     int num_bytes = 0;
698
699     struct xran_common_counters *pCnt = &p_dev_ctx->fh_counters;
700
701     uint8_t CC_ID = p_cid->ccId;
702     uint8_t Ant_ID = p_cid->ruPortId;
703     uint8_t frame_id = 0;
704     uint8_t subframe_id = 0;
705     uint8_t slot_id = 0;
706     uint8_t symb_id = 0;
707
708     uint16_t num_prbu;
709     uint16_t start_prbu;
710     uint16_t sym_inc;
711     uint16_t rb;
712     uint16_t sect_id;
713
714     uint8_t compMeth = 0;
715     uint8_t iqWidth = 0;
716
717     int ret = MBUF_FREE;
718     uint32_t mb_free = 0;
719     int32_t valid_res = 0;
720     int expect_comp  = (p_dev_ctx->fh_cfg.ru_conf.compMeth != XRAN_COMPMETHOD_NONE);
721     enum xran_comp_hdr_type staticComp = p_dev_ctx->fh_cfg.ru_conf.xranCompHdrType;
722
723     if(first_call == 0)
724         return ret;
725
726     if (staticComp == XRAN_COMP_HDR_TYPE_STATIC)
727     {
728         compMeth = p_dev_ctx->fh_cfg.ru_conf.compMeth;
729         iqWidth = p_dev_ctx->fh_cfg.ru_conf.iqWidth;
730     }
731
732     if(p_dev_ctx->xran2phy_mem_ready == 0 || first_call == 0)
733         return MBUF_FREE;
734
735     num_bytes = xran_extract_iq_samples(pkt, &iq_samp_buf,
736                                 &CC_ID, &Ant_ID, &frame_id, &subframe_id, &slot_id, &symb_id, &seq,
737                                 &num_prbu, &start_prbu, &sym_inc, &rb, &sect_id,
738                                 expect_comp, staticComp, &compMeth, &iqWidth);
739     if (num_bytes <= 0)
740     {
741         print_err("num_bytes is wrong [%d]\n", num_bytes);
742         return MBUF_FREE;
743     }
744     if (num_prbu == 0)
745         num_prbu = p_dev_ctx->fh_cfg.nULRBs;
746
747     MLogXRANTask(PID_PROCESS_UP_PKT_PARSE, tt1, MLogXRANTick());
748     /* do not validate for NDM SRS */
749     if (Ant_ID >= p_dev_ctx->srs_cfg.eAxC_offset && p_dev_ctx->fh_cfg.srsEnable)
750     {
751         /* SRS packet has ruportid = 2*num_eAxc + ant_id */
752         Ant_ID -= p_dev_ctx->srs_cfg.eAxC_offset;
753         symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID][Ant_ID] += num_bytes;
754
755         if (seq.bits.e_bit == 1)
756         {
757             print_dbg("SRS receiving symbol %d, size=%d bytes\n",
758                 symb_id, symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID][Ant_ID]);
759
760             if (symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID][Ant_ID])
761             {
762                uint64_t t1 = MLogXRANTick();
763                int16_t res = xran_process_srs_sym(p_dev_ctx,
764                                 pkt, iq_samp_buf, num_bytes,
765                                 CC_ID, Ant_ID, frame_id, subframe_id, slot_id, symb_id,
766                                 num_prbu, start_prbu, sym_inc, rb, sect_id,
767                                 &mb_free, expect_comp, compMeth, iqWidth);
768                 if(res == symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID][Ant_ID])
769                     ret = mb_free;
770                 else
771                     print_err("res != symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID][Ant_ID]\n");
772
773                 pCnt->rx_srs_packets++;
774                 MLogXRANTask(PID_PROCESS_UP_PKT_SRS, t1, MLogXRANTick());
775             }
776             symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID][Ant_ID] = 0;
777         }
778         else
779             print_dbg("Transport layer fragmentation (eCPRI) is not supported\n");
780     } /* if (Ant_ID >= p_dev_ctx->srs_cfg.eAxC_offset && p_dev_ctx->fh_cfg.srsEnable) */
781
782     else
783     {
784         valid_res = xran_pkt_validate(p_dev_ctx,
785                                 pkt, iq_samp_buf, num_bytes,
786                                 CC_ID, Ant_ID, frame_id, subframe_id, slot_id, symb_id,
787                                 &seq, num_prbu, start_prbu, sym_inc, rb, sect_id);
788 #ifndef FCN_ADAPT
789         if(valid_res != 0)
790         {
791             print_dbg("valid_res is wrong [%d] ant %u (%u : %u : %u : %u) seq %u num_bytes %d\n", valid_res, Ant_ID, frame_id, subframe_id, slot_id, symb_id, seq.bits.seq_id, num_bytes);
792             return MBUF_FREE;
793         }
794 #endif
795         int tti = 0;
796         struct xran_prach_cp_config *PrachCfg = NULL;
797         if(p_dev_ctx->dssEnable){
798             tti = frame_id * SLOTS_PER_SYSTEMFRAME(p_dev_ctx->interval_us_local) +
799                     subframe_id * SLOTNUM_PER_SUBFRAME(p_dev_ctx->interval_us_local) + slot_id;
800             int techSlot = (tti % p_dev_ctx->dssPeriod);
801             if(p_dev_ctx->technology[techSlot] == 1)
802                 PrachCfg  = &(p_dev_ctx->PrachCPConfig);
803             else
804                 PrachCfg  = &(p_dev_ctx->PrachCPConfigLTE);
805         }
806         else{
807             PrachCfg = &(p_dev_ctx->PrachCPConfig);
808         }
809
810         if (Ant_ID >= PrachCfg->eAxC_offset && p_dev_ctx->fh_cfg.prachEnable)
811         {
812         /* PRACH packet has ruportid = num_eAxc + ant_id */
813             Ant_ID -= PrachCfg->eAxC_offset;
814         symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID][Ant_ID] += num_bytes;
815             if (seq.bits.e_bit == 1)
816             {
817             print_dbg("Completed receiving PRACH symbol %d, size=%d bytes\n",
818                 symb_id, num_bytes);
819
820                 if (symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID][Ant_ID])
821                 {
822                 int16_t res =  xran_process_prach_sym(p_dev_ctx,
823                                                           pkt, iq_samp_buf, num_bytes,
824                                                           CC_ID, Ant_ID, frame_id, subframe_id, slot_id, symb_id,
825                                                           num_prbu, start_prbu, sym_inc, rb, sect_id, &mb_free);
826                     if(res == symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID][Ant_ID])
827                     ret = mb_free;
828                     else
829                     print_err("res != symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID][Ant_ID]\n");
830
831                 pCnt->rx_prach_packets[Ant_ID]++;
832             }
833             symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID][Ant_ID] = 0;
834             }
835             else
836             print_dbg("Transport layer fragmentation (eCPRI) is not supported\n");
837         }
838         else
839         {
840             /* PUSCH */
841         symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID][Ant_ID] += num_bytes;
842
843             if (seq.bits.e_bit == 1)
844             {
845             print_dbg("Completed receiving symbol %d, size=%d bytes\n",
846                 symb_id, symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID][Ant_ID]);
847
848                 if (symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID][Ant_ID])
849                 {
850                     uint64_t t1 = MLogXRANTick();
851                 int res = xran_process_rx_sym(p_dev_ctx,
852                                     pkt, iq_samp_buf, symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID][Ant_ID],
853                                     CC_ID, Ant_ID, frame_id, subframe_id, slot_id, symb_id,
854                                     num_prbu, start_prbu, sym_inc, rb, sect_id,
855                                     &mb_free, expect_comp, compMeth, iqWidth);
856                     if(res == symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID][Ant_ID])
857                     ret = mb_free;
858                     else
859                     print_err("res != symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID][Ant_ID]\n");
860
861                 pCnt->rx_pusch_packets[Ant_ID]++;
862                     MLogXRANTask(PID_PROCESS_UP_PKT, t1, MLogXRANTick());
863             }
864             symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID][Ant_ID] = 0;
865         }
866             else
867                 print_dbg("Transport layer fragmentation (eCPRI) is not supported\n");
868     }
869     } /* else */
870
871     return ret;
872 }
873
874 #if 0
875 static int set_iq_bit_width(uint8_t iq_bit_width, struct data_section_compression_hdr *compr_hdr)
876 {
877     if (iq_bit_width == MAX_IQ_BIT_WIDTH)
878         compr_hdr->ud_comp_hdr.ud_iq_width = (uint8_t) 0;
879     else
880         compr_hdr->ud_comp_hdr.ud_iq_width = iq_bit_width;
881
882     return  0;
883
884 }
885 #endif
886
887 /* Send a single 5G symbol over multiple packets */
888 inline int32_t prepare_symbol_ex(enum xran_pkt_dir direction,
889                 uint16_t section_id_start,
890                 struct rte_mbuf *mb,
891                 uint8_t *data,
892                 uint8_t     compMeth,
893                 uint8_t     iqWidth,
894                 const enum xran_input_byte_order iq_buf_byte_order,
895                 uint8_t frame_id,
896                 uint8_t subframe_id,
897                 uint8_t slot_id,
898                 uint8_t symbol_no,
899                 int prb_start,
900                 int prb_num,
901                 uint8_t CC_ID,
902                 uint8_t RU_Port_ID,
903                 uint8_t seq_id,
904                 uint32_t do_copy,
905                 enum xran_comp_hdr_type staticEn,
906                 uint16_t num_sections,
907                 uint16_t iq_offset)
908 {
909     int32_t n_bytes , iq_len_aggr = 0;
910     int32_t prep_bytes;
911     int16_t nPktSize,idx, nprb_per_section;
912     uint32_t curr_sect_id;
913     int parm_size;
914     struct xran_up_pkt_gen_params xp[XRAN_MAX_SECTIONS_PER_SLOT] = { 0 };
915     bool prbElemBegin , prbElemEnd;
916
917     iqWidth = (iqWidth==0) ? 16 : iqWidth;
918     switch(compMeth) {
919         case XRAN_COMPMETHOD_BLKFLOAT:      parm_size = 1; break;
920         case XRAN_COMPMETHOD_MODULATION:    parm_size = 0; break;
921         default:
922             parm_size = 0;
923         }
924
925     nprb_per_section = prb_num/num_sections;
926     if(prb_num%num_sections)
927         nprb_per_section++;
928
929     n_bytes = (3 * iqWidth + parm_size)*nprb_per_section;
930     // n_bytes = RTE_MIN(n_bytes, XRAN_MAX_MBUF_LEN);
931
932     for(idx=0 ; idx < num_sections ; idx++)
933     {
934         prbElemBegin = (idx == 0) ? 1 : 0;
935         prbElemEnd   = (idx + 1 == num_sections) ? 1 : 0;
936         curr_sect_id = section_id_start + idx ;
937
938         iq_len_aggr += n_bytes;
939
940         if(prbElemBegin)
941         {
942              nPktSize = sizeof(struct rte_ether_hdr)
943                 + sizeof(struct xran_ecpri_hdr)
944                         + sizeof(struct radio_app_common_hdr) ;
945         }
946
947         if(prbElemEnd){
948             if(((idx+1)*nprb_per_section) > prb_num){
949                 nprb_per_section = (prb_num - idx*nprb_per_section);
950                 // n_bytes = (3 * iqWidth + parm_size)*(nprb_per_section);
951             }
952         }
953
954         nPktSize += sizeof(struct data_section_hdr);
955
956         if ((compMeth != XRAN_COMPMETHOD_NONE)&&(staticEn == XRAN_COMP_HDR_TYPE_DYNAMIC))
957             nPktSize += sizeof(struct data_section_compression_hdr);
958
959         nPktSize += n_bytes;
960
961         /** radio app header
962          *  Setting app_params is redundant , its needed only once to create common Radio app header.
963         */
964         xp[idx].app_params.data_feature.value = 0x10;
965         xp[idx].app_params.data_feature.data_direction = direction;
966         // xp[idx].app_params.payl_ver       = 1;
967         // xp[idx].app_params.filter_id      = 0;
968         xp[idx].app_params.frame_id       = frame_id;
969         xp[idx].app_params.sf_slot_sym.subframe_id    = subframe_id;
970         xp[idx].app_params.sf_slot_sym.slot_id        = xran_slotid_convert(slot_id, 0);
971         xp[idx].app_params.sf_slot_sym.symb_id        = symbol_no;
972
973     /* convert to network byte order */
974         xp[idx].app_params.sf_slot_sym.value = rte_cpu_to_be_16(xp[idx].app_params.sf_slot_sym.value);
975
976         // printf("start_prbu = %d, prb_num = %d,num_sections = %d, nprb_per_section = %d,curr_sect_id = %d\n",(prb_start + idx*nprb_per_section),prb_num,num_sections,nprb_per_section,curr_sect_id);
977         xp[idx].sec_hdr.fields.all_bits   = 0;
978         xp[idx].sec_hdr.fields.sect_id    = curr_sect_id;
979         xp[idx].sec_hdr.fields.num_prbu   = XRAN_CONVERT_NUMPRBC(nprb_per_section); //(uint8_t)prb_num;
980         xp[idx].sec_hdr.fields.start_prbu = prb_start;
981         xp[idx].sec_hdr.fields.sym_inc    = 0;
982         xp[idx].sec_hdr.fields.rb         = 0;
983
984     /* compression */
985         xp[idx].compr_hdr_param.ud_comp_hdr.ud_comp_meth = compMeth;
986         xp[idx].compr_hdr_param.ud_comp_hdr.ud_iq_width  = XRAN_CONVERT_IQWIDTH(iqWidth);
987         xp[idx].compr_hdr_param.rsrvd                    = 0;
988         prb_start += nprb_per_section;
989
990 #if 0
991         printf("\nidx %hu num_prbu %u sect_id %u start_prbu %u sym_inc %u curr_sec_id %u",idx,(uint32_t)xp[idx].sec_hdr.fields.num_prbu,
992                                                                            (uint32_t)xp[idx].sec_hdr.fields.sect_id,
993                                                                            (uint32_t)xp[idx].sec_hdr.fields.start_prbu,
994                                                                            (uint32_t)xp[idx].sec_hdr.fields.sym_inc,curr_sect_id);
995
996 #endif
997
998     /* network byte order */
999         xp[idx].sec_hdr.fields.all_bits  = rte_cpu_to_be_32(xp[idx].sec_hdr.fields.all_bits);
1000
1001     if (mb == NULL){
1002         MLogPrint(NULL);
1003         errx(1, "out of mbufs after %d packets", 1);
1004     }
1005     } /* for(idx=0 ; idx < num_sections ; idx++) */
1006
1007     //printf("\niq_len_aggr %u",iq_len_aggr);
1008
1009     prep_bytes = xran_prepare_iq_symbol_portion(mb,
1010                                                   data,
1011                                                   iq_buf_byte_order,
1012                                                   iq_len_aggr,
1013                                                   xp,
1014                                                   CC_ID,
1015                                                   RU_Port_ID,
1016                                                   seq_id,
1017                                                   staticEn,
1018                                                   do_copy,
1019                                                   num_sections,
1020                                                   section_id_start,
1021                                                   iq_offset);
1022     if (prep_bytes <= 0)
1023         errx(1, "failed preparing symbol");
1024
1025     rte_pktmbuf_pkt_len(mb)  = nPktSize;
1026     rte_pktmbuf_data_len(mb) = nPktSize;
1027
1028 #ifdef DEBUG
1029     printf("Symbol %2d prep_bytes (%d packets, %d bytes)\n", symbol_no, i, n_bytes);
1030 #endif
1031
1032     return prep_bytes;
1033 }
1034
1035 int32_t prepare_sf_slot_sym (enum xran_pkt_dir direction,
1036                 uint8_t frame_id,
1037                 uint8_t subframe_id,
1038                 uint8_t slot_id,
1039                 uint8_t symbol_no,
1040                 struct xran_up_pkt_gen_params *xp)
1041 {
1042     /* radio app header */
1043     xp->app_params.data_feature.value = 0x10;
1044     xp->app_params.data_feature.data_direction = direction;
1045     //xp->app_params.payl_ver       = 1;
1046     //xp->app_params.filter_id      = 0;
1047     xp->app_params.frame_id       = frame_id;
1048     xp->app_params.sf_slot_sym.subframe_id    = subframe_id;
1049     xp->app_params.sf_slot_sym.slot_id        = xran_slotid_convert(slot_id, 0);
1050     xp->app_params.sf_slot_sym.symb_id        = symbol_no;
1051
1052     /* convert to network byte order */
1053     xp->app_params.sf_slot_sym.value = rte_cpu_to_be_16(xp->app_params.sf_slot_sym.value);
1054
1055     return 0;
1056 }
1057
1058 int send_symbol_mult_section_ex(void *handle,
1059                 enum xran_pkt_dir direction,
1060                 uint16_t section_id,
1061                 struct rte_mbuf *mb, uint8_t *data,
1062                 uint8_t compMeth, uint8_t iqWidth,
1063                 const enum xran_input_byte_order iq_buf_byte_order,
1064                 uint8_t frame_id, uint8_t subframe_id,
1065                 uint8_t slot_id, uint8_t symbol_no,
1066                 int prb_start, int prb_num,
1067                 uint8_t CC_ID, uint8_t RU_Port_ID, uint8_t seq_id)
1068 {
1069     uint32_t do_copy = 0;
1070     int32_t n_bytes;
1071     int hdr_len, parm_size;
1072     int32_t sent=0;
1073     uint32_t loop = 0;
1074     struct xran_device_ctx *p_dev_ctx = (struct xran_device_ctx *)handle;
1075     struct xran_common_counters *pCnt = &p_dev_ctx->fh_counters;
1076     enum xran_comp_hdr_type staticEn= XRAN_COMP_HDR_TYPE_DYNAMIC;
1077
1078
1079     if (p_dev_ctx != NULL)
1080     {
1081         staticEn = p_dev_ctx->fh_cfg.ru_conf.xranCompHdrType;
1082
1083     hdr_len = sizeof(struct xran_ecpri_hdr)
1084                 + sizeof(struct radio_app_common_hdr)
1085                 + sizeof(struct data_section_hdr);
1086         if ((compMeth != XRAN_COMPMETHOD_NONE)&&(staticEn == XRAN_COMP_HDR_TYPE_DYNAMIC))
1087         hdr_len += sizeof(struct data_section_compression_hdr);
1088
1089     switch(compMeth) {
1090         case XRAN_COMPMETHOD_BLKFLOAT:      parm_size = 1; break;
1091         case XRAN_COMPMETHOD_MODULATION:    parm_size = 0; break;
1092         default:
1093             parm_size = 0;
1094         }
1095     int prb_num_pre_sec = (prb_num+2)/3;
1096     int prb_offset = 0;
1097     int data_offset = 0;
1098     int prb_num_sec;
1099     rte_iova_t ext_buff_iova = 0;
1100
1101     struct rte_mbuf *send_mb;
1102     char        *p_sec_iq = NULL;
1103     char        *ext_buff = NULL;
1104     uint16_t    ext_buff_len = 0;
1105     struct rte_mbuf_ext_shared_info * p_share_data = NULL;
1106     struct rte_mbuf *eth_oran_hdr = NULL;
1107     struct rte_mbuf *tmp = NULL;
1108     for (loop = 0; loop < 3;loop++)
1109     {
1110         seq_id = xran_get_upul_seqid(handle, CC_ID, RU_Port_ID);
1111         
1112         prb_num_sec = ((loop+1)*prb_num_pre_sec > prb_num) ? (prb_num - loop*prb_num_pre_sec) : prb_num_pre_sec;
1113         n_bytes = (3 * iqWidth + parm_size) * prb_num_sec;
1114         char * pChar = NULL;
1115
1116         send_mb = xran_ethdi_mbuf_alloc(); /* will be freede by ETH */
1117         if(send_mb ==  NULL) {
1118             MLogPrint(NULL);
1119             errx(1, "out of mbufs after %d packets", 1);
1120             }
1121         
1122         pChar = rte_pktmbuf_append(send_mb, hdr_len + n_bytes);
1123         if(pChar == NULL) {
1124             MLogPrint(NULL);
1125             errx(1, "incorrect mbuf size %d packets", 1);
1126             }
1127         pChar = rte_pktmbuf_prepend(send_mb, sizeof(struct rte_ether_hdr));
1128         if(pChar == NULL) {
1129             MLogPrint(NULL);
1130             errx(1, "incorrect mbuf size %d packets", 1);
1131             }
1132         do_copy = 1; /* new mbuf hence copy of IQs  */
1133         pChar = rte_pktmbuf_mtod(send_mb, char*);
1134         char *pdata_start = (pChar + sizeof(struct rte_ether_hdr) + hdr_len);
1135         memcpy(pdata_start,data  + data_offset,n_bytes);
1136         
1137
1138         sent = prepare_symbol_ex(direction,
1139                              section_id,
1140                              send_mb,
1141                              data  + data_offset,
1142                              compMeth,
1143                              iqWidth,
1144                              iq_buf_byte_order,
1145                              frame_id,
1146                              subframe_id,
1147                              slot_id,
1148                              symbol_no,
1149                              prb_start+prb_offset,
1150                              prb_num_sec,
1151                              CC_ID,
1152                              RU_Port_ID,
1153                              seq_id,
1154                              do_copy,
1155                              staticEn,
1156                              1,
1157                              0); /*Send a single section */
1158         prb_offset += prb_num_sec;
1159         data_offset += n_bytes;
1160         if(sent) {
1161             pCnt->tx_counter++;
1162             pCnt->tx_bytes_counter += rte_pktmbuf_pkt_len(send_mb);
1163             p_dev_ctx->send_upmbuf2ring(send_mb, ETHER_TYPE_ECPRI, xran_map_ecpriPcid_to_vf(p_dev_ctx, direction, CC_ID, RU_Port_ID));
1164             }
1165     
1166      }
1167
1168 #ifdef DEBUG
1169     printf("Symbol %2d sent (%d packets, %d bytes)\n", symbol_no, i, n_bytes);
1170 #endif
1171     }
1172     return sent;
1173 }
1174
1175
1176 /* Send a single 5G symbol over multiple packets */
1177 int send_symbol_ex(void *handle,
1178                 enum xran_pkt_dir direction,
1179                 uint16_t section_id,
1180                 struct rte_mbuf *mb, uint8_t *data,
1181                 uint8_t compMeth, uint8_t iqWidth,
1182                 const enum xran_input_byte_order iq_buf_byte_order,
1183                 uint8_t frame_id, uint8_t subframe_id,
1184                 uint8_t slot_id, uint8_t symbol_no,
1185                 int prb_start, int prb_num,
1186                 uint8_t CC_ID, uint8_t RU_Port_ID, uint8_t seq_id)
1187 {
1188     uint32_t do_copy = 0;
1189     int32_t n_bytes;
1190     int hdr_len, parm_size;
1191     int32_t sent=0;
1192     struct xran_device_ctx *p_dev_ctx = (struct xran_device_ctx *)handle;
1193     struct xran_common_counters *pCnt = &p_dev_ctx->fh_counters;
1194     enum xran_comp_hdr_type staticEn= XRAN_COMP_HDR_TYPE_DYNAMIC;
1195
1196
1197     if (p_dev_ctx != NULL)
1198     {
1199         staticEn = p_dev_ctx->fh_cfg.ru_conf.xranCompHdrType;
1200
1201     hdr_len = sizeof(struct xran_ecpri_hdr)
1202                 + sizeof(struct radio_app_common_hdr)
1203                 + sizeof(struct data_section_hdr);
1204         if ((compMeth != XRAN_COMPMETHOD_NONE)&&(staticEn == XRAN_COMP_HDR_TYPE_DYNAMIC))
1205         hdr_len += sizeof(struct data_section_compression_hdr);
1206
1207     switch(compMeth) {
1208         case XRAN_COMPMETHOD_BLKFLOAT:      parm_size = 1; break;
1209         case XRAN_COMPMETHOD_MODULATION:    parm_size = 0; break;
1210         default:
1211             parm_size = 0;
1212         }
1213     n_bytes = (3 * iqWidth + parm_size) * prb_num;
1214
1215     if (mb == NULL){
1216         char * pChar = NULL;
1217         mb = xran_ethdi_mbuf_alloc(); /* will be freede by ETH */
1218         if(mb ==  NULL){
1219             MLogPrint(NULL);
1220             errx(1, "out of mbufs after %d packets", 1);
1221         }
1222         pChar = rte_pktmbuf_append(mb, hdr_len + n_bytes);
1223         if(pChar == NULL){
1224                 MLogPrint(NULL);
1225                 errx(1, "incorrect mbuf size %d packets", 1);
1226         }
1227         pChar = rte_pktmbuf_prepend(mb, sizeof(struct rte_ether_hdr));
1228         if(pChar == NULL){
1229                 MLogPrint(NULL);
1230                 errx(1, "incorrect mbuf size %d packets", 1);
1231         }
1232         do_copy = 1; /* new mbuf hence copy of IQs  */
1233
1234         /**copy prach data start**/
1235         pChar = rte_pktmbuf_mtod(mb, char*);
1236         char *pdata_start = (pChar + sizeof(struct rte_ether_hdr) + hdr_len);
1237         memcpy(pdata_start,data,n_bytes);
1238         /**copy prach data end**/
1239
1240         
1241         }
1242     else {
1243         rte_pktmbuf_refcnt_update(mb, 1); /* make sure eth won't free our mbuf */
1244     }
1245
1246     sent = prepare_symbol_ex(direction,
1247                          section_id,
1248                          mb,
1249                          data,
1250                          compMeth,
1251                          iqWidth,
1252                          iq_buf_byte_order,
1253                          frame_id,
1254                          subframe_id,
1255                          slot_id,
1256                          symbol_no,
1257                          prb_start,
1258                          prb_num,
1259                          CC_ID,
1260                          RU_Port_ID,
1261                          seq_id,
1262                          do_copy,
1263                          staticEn,
1264                          1,
1265                          0); /*Send a single section */
1266
1267     if(sent){
1268         pCnt->tx_counter++;
1269         pCnt->tx_bytes_counter += rte_pktmbuf_pkt_len(mb);
1270         p_dev_ctx->send_upmbuf2ring(mb, ETHER_TYPE_ECPRI, xran_map_ecpriPcid_to_vf(p_dev_ctx, direction, CC_ID, RU_Port_ID));
1271     }
1272
1273 #ifdef DEBUG
1274     printf("Symbol %2d sent (%d packets, %d bytes)\n", symbol_no, i, n_bytes);
1275 #endif
1276     }
1277     return sent;
1278 }
1279
1280 int send_cpmsg(void *pHandle, struct rte_mbuf *mbuf,struct xran_cp_gen_params *params,
1281                 struct xran_section_gen_info *sect_geninfo, uint8_t cc_id, uint8_t ru_port_id, uint8_t seq_id)
1282 {
1283     int ret = 0, nsection, i;
1284     uint8_t subframe_id = params->hdr.subframeId;
1285     uint8_t slot_id = params->hdr.slotId;
1286     uint8_t dir = params->dir;
1287     struct xran_device_ctx *p_dev_ctx =(struct xran_device_ctx *) pHandle;
1288     struct xran_common_counters *pCnt = &p_dev_ctx->fh_counters;
1289
1290     nsection = params->numSections;
1291
1292     /* add in the ethernet header */
1293     struct rte_ether_hdr *const h = (void *)rte_pktmbuf_prepend(mbuf, sizeof(*h));
1294
1295     pCnt->tx_counter++;
1296     pCnt->tx_bytes_counter += rte_pktmbuf_pkt_len(mbuf);
1297     p_dev_ctx->send_cpmbuf2ring(mbuf, ETHER_TYPE_ECPRI, xran_map_ecpriRtcid_to_vf(p_dev_ctx, dir, cc_id, ru_port_id));
1298     for(i=0; i<nsection; i++)
1299         xran_cp_add_section_info(pHandle, dir, cc_id, ru_port_id,
1300                 (slot_id + subframe_id*SLOTNUM_PER_SUBFRAME(p_dev_ctx->interval_us_local))%XRAN_MAX_SECTIONDB_CTX,
1301                 sect_geninfo[i].info);
1302
1303     return (ret);
1304 }
1305
1306 int generate_cpmsg_dlul(void *pHandle, struct xran_cp_gen_params *params, struct xran_section_gen_info *sect_geninfo, struct rte_mbuf *mbuf,
1307     enum xran_pkt_dir dir, uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id,
1308     uint8_t startsym, uint8_t numsym, uint16_t prb_start, uint16_t prb_num,int16_t iq_buffer_offset, int16_t iq_buffer_len,
1309     uint16_t beam_id, uint8_t cc_id, uint8_t ru_port_id, uint8_t comp_method, uint8_t iqWidth,  uint8_t seq_id, uint8_t symInc)
1310 {
1311     int ret = 0, nsection, loc_sym;
1312
1313
1314     params->dir                  = dir;
1315     params->sectionType          = XRAN_CP_SECTIONTYPE_1;        // Most DL/UL Radio Channels
1316     params->hdr.filterIdx        = XRAN_FILTERINDEX_STANDARD;
1317     params->hdr.frameId          = frame_id;
1318     params->hdr.subframeId       = subframe_id;
1319     params->hdr.slotId           = slot_id;
1320     params->hdr.startSymId       = startsym;                     // start Symbol ID
1321     params->hdr.iqWidth          = iqWidth;
1322     params->hdr.compMeth         = comp_method;
1323
1324     nsection = 0;
1325     sect_geninfo[nsection].info->type        = params->sectionType;       // for database
1326     sect_geninfo[nsection].info->startSymId  = params->hdr.startSymId;    // for database
1327     sect_geninfo[nsection].info->iqWidth     = params->hdr.iqWidth;       // for database
1328     sect_geninfo[nsection].info->compMeth    = params->hdr.compMeth;      // for database
1329     sect_geninfo[nsection].info->id          = xran_alloc_sectionid(pHandle, dir, cc_id, ru_port_id, subframe_id, slot_id);
1330     sect_geninfo[nsection].info->rb          = XRAN_RBIND_EVERY;
1331     sect_geninfo[nsection].info->symInc      = symInc;
1332     sect_geninfo[nsection].info->startPrbc   = prb_start;
1333     sect_geninfo[nsection].info->numPrbc     = prb_num;
1334     sect_geninfo[nsection].info->numSymbol   = numsym;
1335     sect_geninfo[nsection].info->reMask      = 0xfff;
1336     sect_geninfo[nsection].info->beamId      = beam_id;
1337
1338     for (loc_sym = 0; loc_sym < XRAN_NUM_OF_SYMBOL_PER_SLOT; loc_sym++) {
1339         sect_geninfo[0].info->sec_desc[loc_sym].iq_buffer_offset = iq_buffer_offset;
1340         sect_geninfo[0].info->sec_desc[loc_sym].iq_buffer_len    = iq_buffer_len;
1341     }
1342
1343     sect_geninfo[nsection].info->ef          = 0;
1344     sect_geninfo[nsection].exDataSize       = 0;
1345 //    sect_geninfo[nsection].exData           = NULL;
1346     nsection++;
1347
1348     params->numSections          = nsection;
1349     params->sections             = sect_geninfo;
1350
1351     if(unlikely(mbuf == NULL)) {
1352         print_err("Alloc fail!\n");
1353         return (-1);
1354     }
1355
1356     ret = xran_prepare_ctrl_pkt(mbuf, params, cc_id, ru_port_id, seq_id,0);
1357     if(ret < 0){
1358         print_err("Fail to build control plane packet - [%d:%d:%d] dir=%d\n",
1359                     frame_id, subframe_id, slot_id, dir);
1360         rte_pktmbuf_free(mbuf);
1361     }
1362
1363     return (ret);
1364 }
1365
1366 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,
1367                 uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id, int tti,
1368                 uint16_t beam_id, uint8_t cc_id, uint8_t prach_port_id, uint16_t occasionid, uint8_t seq_id)
1369 {
1370     int nsection, ret;
1371     struct xran_prach_cp_config  *pPrachCPConfig = NULL;;
1372     int i=0;
1373     if(pxran_lib_ctx->dssEnable){
1374         i = tti % pxran_lib_ctx->dssPeriod;
1375         if(pxran_lib_ctx->technology[i]==1) {
1376             pPrachCPConfig = &(pxran_lib_ctx->PrachCPConfig);
1377         }
1378         else
1379         {
1380             pPrachCPConfig = &(pxran_lib_ctx->PrachCPConfigLTE);
1381         }
1382     }
1383     else
1384         pPrachCPConfig = &(pxran_lib_ctx->PrachCPConfig);
1385
1386     uint16_t timeOffset;
1387     uint16_t nNumerology = pxran_lib_ctx->fh_cfg.frame_conf.nNumerology;
1388     uint8_t startSymId;
1389
1390     if(unlikely(mbuf == NULL)) {
1391         print_err("Alloc fail!\n");
1392         return (-1);
1393     }
1394 #if 0
1395     printf("%d:%d:%d:%d - filter=%d, startSym=%d[%d:%d], numSym=%d, occasions=%d, freqOff=%d\n",
1396                 frame_id, subframe_id, slot_id, prach_port_id,
1397                 pPrachCPConfig->filterIdx,
1398                 pPrachCPConfig->startSymId,
1399                 pPrachCPConfig->startPrbc,
1400                 pPrachCPConfig->numPrbc,
1401                 pPrachCPConfig->numSymbol,
1402                 pPrachCPConfig->occassionsInPrachSlot,
1403                 pPrachCPConfig->freqOffset);
1404 #endif
1405     timeOffset = pPrachCPConfig->timeOffset; //this is the CP value per 38.211 tab 6.3.3.1-1&2
1406     startSymId = pPrachCPConfig->startSymId + occasionid * pPrachCPConfig->numSymbol;
1407     if (startSymId > 0)
1408     {
1409         timeOffset += startSymId * (2048 + 144);
1410     }
1411
1412     if(XRAN_FILTERINDEX_PRACH_ABC == pPrachCPConfig->filterIdx)
1413     {
1414     timeOffset = timeOffset >> nNumerology; //original number is Tc, convert to Ts based on mu
1415     if ((slot_id == 0) || (slot_id == (SLOTNUM_PER_SUBFRAME(pxran_lib_ctx->interval_us_local) >> 1)))
1416         timeOffset += 16;
1417     }
1418     else
1419     {
1420         //when prach scs lower than 15khz, timeOffset base 15khz not need to adjust.
1421     }
1422
1423     params->dir                  = XRAN_DIR_UL;
1424     params->sectionType          = XRAN_CP_SECTIONTYPE_3;
1425     params->hdr.filterIdx        = pPrachCPConfig->filterIdx;
1426     params->hdr.frameId          = frame_id;
1427     params->hdr.subframeId       = subframe_id;
1428     params->hdr.slotId           = slot_id;
1429     params->hdr.startSymId       = startSymId;
1430     params->hdr.iqWidth          = xran_get_conf_iqwidth_prach(pHandle);
1431     params->hdr.compMeth         = xran_get_conf_compmethod_prach(pHandle);
1432         /* use timeOffset field for the CP length value for prach sequence */
1433     params->hdr.timeOffset       = timeOffset;
1434     params->hdr.fftSize          = xran_get_conf_fftsize(pHandle);
1435         /*convert to o-ran ecpri specs scs index*/
1436     switch(pPrachCPConfig->filterIdx)
1437     {
1438         case XRAN_FILTERINDEX_PRACH_012:
1439             params->hdr.scs              = 12;
1440             break;
1441         case XRAN_FILTERINDEX_NPRACH:
1442             params->hdr.scs              = 13;
1443             break;
1444         case XRAN_FILTERINDEX_PRACH_3:
1445             params->hdr.scs              = 14;
1446             break;
1447         case XRAN_FILTERINDEX_LTE4:
1448             params->hdr.scs              = 15;
1449             break;
1450         case XRAN_FILTERINDEX_PRACH_ABC:
1451     params->hdr.scs              = xran_get_conf_prach_scs(pHandle);
1452             break;
1453         default:
1454             print_err("prach filterIdx error - [%d:%d:%d]--%d\n", frame_id, subframe_id, slot_id,pPrachCPConfig->filterIdx);
1455             params->hdr.scs              = 0;
1456             break;
1457     }
1458     params->hdr.cpLength         = 0;
1459
1460     nsection = 0;
1461     sect_geninfo[nsection].info->type        = params->sectionType;       // for database
1462     sect_geninfo[nsection].info->startSymId  = params->hdr.startSymId;    // for database
1463     sect_geninfo[nsection].info->iqWidth     = params->hdr.iqWidth;       // for database
1464     sect_geninfo[nsection].info->compMeth    = params->hdr.compMeth;      // for database
1465     sect_geninfo[nsection].info->id          = xran_alloc_sectionid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id, subframe_id, slot_id);
1466     sect_geninfo[nsection].info->rb          = XRAN_RBIND_EVERY;
1467     sect_geninfo[nsection].info->symInc      = XRAN_SYMBOLNUMBER_NOTINC;
1468     sect_geninfo[nsection].info->startPrbc   = pPrachCPConfig->startPrbc;
1469     sect_geninfo[nsection].info->numPrbc     = pPrachCPConfig->numPrbc,
1470     sect_geninfo[nsection].info->numSymbol   = pPrachCPConfig->numSymbol;
1471     sect_geninfo[nsection].info->reMask      = 0xfff;
1472     sect_geninfo[nsection].info->beamId      = beam_id;
1473     sect_geninfo[nsection].info->freqOffset  = pPrachCPConfig->freqOffset;
1474     sect_geninfo[nsection].info->prbElemBegin = 1;
1475     sect_geninfo[nsection].info->prbElemEnd   = 1;
1476
1477
1478     pxran_lib_ctx->prach_last_symbol[cc_id] = pPrachCPConfig->startSymId + pPrachCPConfig->numSymbol*pPrachCPConfig->occassionsInPrachSlot - 1;
1479
1480     sect_geninfo[nsection].info->ef          = 0;
1481     sect_geninfo[nsection].exDataSize       = 0;
1482 //    sect_geninfo[nsection].exData           = NULL;
1483     nsection++;
1484
1485     params->numSections          = nsection;
1486     params->sections             = sect_geninfo;
1487
1488     ret = xran_prepare_ctrl_pkt(mbuf, params, cc_id, prach_port_id, seq_id,0);
1489     if(ret < 0){
1490         print_err("Fail to build prach control packet - [%d:%d:%d]\n", frame_id, subframe_id, slot_id);
1491         rte_pktmbuf_free(mbuf);
1492     }
1493     return ret;
1494 }
1495
1496
1497 int process_ring(struct rte_ring *r, uint16_t ring_id, uint16_t q_id)
1498 {
1499     assert(r);
1500
1501     struct rte_mbuf *mbufs[MBUFS_CNT];
1502     uint32_t remaining;
1503     //uint64_t t1;
1504     const uint16_t dequeued = rte_ring_dequeue_burst(r, (void **)mbufs,
1505         RTE_DIM(mbufs), &remaining);
1506
1507     if (!dequeued)
1508         return 0;
1509
1510     //t1 = MLogTick();
1511
1512     xran_ethdi_filter_packet(mbufs, ring_id, q_id, dequeued);
1513     //MLogTask(PID_PROCESS_UP_PKT, t1, MLogTick());
1514
1515     return remaining;
1516 }
1517 /** FH RX AND BBDEV */
1518 int32_t ring_processing_func(void* args)
1519 {
1520     struct xran_ethdi_ctx *const ctx = xran_ethdi_get_ctx();
1521     int16_t retPoll = 0;
1522     int32_t i;
1523     queueid_t qi;
1524     uint64_t t1, t2;
1525
1526     rte_timer_manage();
1527
1528     if (ctx->bbdev_dec) {
1529         t1 = MLogXRANTick();
1530         retPoll = ctx->bbdev_dec();
1531         if (retPoll == 1)
1532         {
1533             t2 = MLogXRANTick();
1534             MLogXRANTask(PID_XRAN_BBDEV_UL_POLL + retPoll, t1, t2);
1535         }
1536     }
1537
1538     if (ctx->bbdev_enc) {
1539         t1 = MLogXRANTick();
1540         retPoll = ctx->bbdev_enc();
1541         if (retPoll == 1)
1542         {
1543             t2 = MLogXRANTick();
1544             MLogXRANTask(PID_XRAN_BBDEV_DL_POLL + retPoll, t1, t2);
1545         }
1546     }
1547
1548     for (i = 0; i < ctx->io_cfg.num_vfs && i < XRAN_VF_MAX; i++){
1549         for(qi = 0; qi < ctx->rxq_per_port[i]; qi++) {
1550             if (process_ring(ctx->rx_ring[i][qi], i, qi))
1551             return 0;
1552         }
1553     }
1554
1555     if (XRAN_STOPPED == xran_if_current_state)
1556         return -1;
1557
1558                 return 0;
1559     }
1560
1561 /** Generic thread to perform task on specific core */
1562 int32_t
1563 xran_generic_worker_thread(void *args)
1564 {
1565     int32_t res = 0;
1566     struct xran_worker_th_ctx* pThCtx = (struct xran_worker_th_ctx*)args;
1567     struct sched_param sched_param;
1568     struct xran_io_cfg * const p_io_cfg = &(xran_ethdi_get_ctx()->io_cfg);
1569
1570     memset(&sched_param, 0, sizeof(struct sched_param));
1571
1572     printf("%s [CPU %2d] [PID: %6d]\n", __FUNCTION__,  rte_lcore_id(), getpid());
1573     sched_param.sched_priority = XRAN_THREAD_DEFAULT_PRIO;
1574     if ((res = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sched_param))){
1575         printf("priority is not changed: coreId = %d, result1 = %d\n",rte_lcore_id(), res);
1576     }
1577     pThCtx->worker_policy = SCHED_FIFO;
1578     if ((res = pthread_setname_np(pthread_self(), pThCtx->worker_name))) {
1579         printf("[core %d] pthread_setname_np = %d\n",rte_lcore_id(), res);
1580     }
1581
1582     for (;;) {
1583         if(pThCtx->task_func) {
1584             if(pThCtx->task_func(pThCtx->task_arg) != 0)
1585                 break;
1586         }
1587
1588         if (XRAN_STOPPED == xran_if_current_state)
1589             return -1;
1590
1591         if(p_io_cfg->io_sleep)
1592             nanosleep(&sleeptime,NULL);
1593     }
1594
1595     printf("%s worker thread finished on core %d [worker id %d]\n",pThCtx->worker_name, rte_lcore_id(), pThCtx->worker_id);
1596     return 0;
1597 }
1598
1599 int ring_processing_thread(void *args)
1600 {
1601     struct sched_param sched_param;
1602     struct xran_io_cfg * const p_io_cfg = &(xran_ethdi_get_ctx()->io_cfg);
1603     int res = 0;
1604
1605     memset(&sched_param, 0, sizeof(struct sched_param));
1606
1607     printf("%s [CPU %2d] [PID: %6d]\n", __FUNCTION__,  rte_lcore_id(), getpid());
1608     sched_param.sched_priority = XRAN_THREAD_DEFAULT_PRIO;
1609     if ((res = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sched_param))){
1610         printf("priority is not changed: coreId = %d, result1 = %d\n",rte_lcore_id(), res);
1611     }
1612
1613     for (;;){
1614         if(ring_processing_func(args) != 0)
1615             break;
1616
1617         /* work around for some kernel */
1618         if(p_io_cfg->io_sleep)
1619             nanosleep(&sleeptime,NULL);
1620     }
1621
1622     puts("Pkt processing thread finished.");
1623     return 0;
1624 }