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