* INTC Contribution to the O-RAN F Release for O-DU Low
[o-du/phy.git] / fhi_lib / lib / src / xran_cp_api.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 This file provides the API functions to build Control Plane Messages
21  *      for XRAN Front Haul layer as defined in XRAN-FH.CUS.0-v02.01.
22  *
23  * @file xran_cp_api.c
24  * @ingroup group_lte_source_xran
25  * @author Intel Corporation
26  *
27  **/
28 #include <immintrin.h>
29 #include <rte_branch_prediction.h>
30 #include <rte_malloc.h>
31
32 #include "ethdi.h"
33 #include "xran_common.h"
34 #include "xran_transport.h"
35 #include "xran_cp_api.h"
36 #include "xran_printf.h"
37 #include "xran_compression.h"
38 #include "xran_dev.h"
39
40 PSECTION_DB_TYPE p_sectiondb[XRAN_PORTS_NUM] = {NULL, NULL, NULL, NULL,NULL, NULL, NULL, NULL};
41
42 static const uint8_t zeropad[XRAN_SECTIONEXT_ALIGN] = { 0, 0, 0, 0 };
43 static const uint8_t bitmask[] = { 0x00, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
44
45
46 /**
47  * @brief Initialize section database.
48  *   Allocate required memory space to store section information.
49  *   Each eAxC allocates dedicated storage and the entry size is the maximum number of sections.
50  *   Total entry size : number of CC * number of antenna * max number of sections * 2(direction)
51  *
52  * @ingroup xran_cp_pkt
53  *
54  * @param pHandle
55  *  handle for xRAN interface, currently not being used
56  * @return
57  *  XRAN_STATUS_SUCCESS on success
58  *  XRAN_STATUS_RESOURCE, if memory is not enough to allocate database area
59  */
60 int32_t
61 xran_cp_init_sectiondb(void *pHandle)
62 {
63     int32_t ctx, dir, cc, ant;
64     struct xran_device_ctx* p_dev = NULL;
65     uint8_t xran_port_id = 0;
66     PSECTION_DB_TYPE p_sec_db =  NULL;
67     struct xran_sectioninfo_db* p_sec_db_elm = NULL;
68
69     if(pHandle) {
70         p_dev = (struct xran_device_ctx* )pHandle;
71         xran_port_id = p_dev->xran_port_id;
72     } else {
73         print_err("Invalid pHandle - %p", pHandle);
74         return (XRAN_STATUS_FAIL);
75     }
76
77     if (p_sectiondb[xran_port_id] == NULL){
78         p_sec_db = rte_zmalloc(NULL,sizeof(SECTION_DB_TYPE), 0);
79         if(p_sec_db){
80             p_sectiondb[xran_port_id] = p_sec_db;
81             memset(p_sec_db, 0, sizeof(SECTION_DB_TYPE));
82             print_dbg("xran_port_id %d %p\n",xran_port_id,  p_sectiondb[xran_port_id]);
83             for (ctx = 0; ctx < XRAN_MAX_SECTIONDB_CTX; ctx++) {
84                 for (dir = 0; dir < XRAN_DIR_MAX; dir++) {
85                     for (cc = 0; cc < p_dev->fh_cfg.nCC && cc < XRAN_COMPONENT_CARRIERS_MAX; cc++) {
86                         for (ant = 0; ant < (p_dev->fh_cfg.neAxc*2 + p_dev->fh_cfg.nAntElmTRx) && ant < (XRAN_MAX_ANTENNA_NR*2 + XRAN_MAX_ANT_ARRAY_ELM_NR); ant++) {
87                             p_sec_db_elm = (struct xran_sectioninfo_db*)rte_zmalloc(NULL,sizeof(struct xran_sectioninfo_db), 0);
88                             if(p_sec_db_elm) {
89                                 memset(p_sec_db_elm, 0, sizeof(struct xran_sectioninfo_db));
90                                 p_sec_db->p_sectiondb_elm[ctx][dir][cc][ant] = p_sec_db_elm;
91                             } else {
92                                 print_err("Memory Allocation Failed [port %d sz %ld]\n", xran_port_id, sizeof(struct xran_sectioninfo_db));
93                                 return (XRAN_STATUS_RESOURCE);
94                             }
95                         }
96                     }
97                 }
98             }
99         } else {
100             print_err("Memory Allocation Failed [port %d sz %ld]\n", xran_port_id, sizeof(SECTION_DB_TYPE));
101             return (XRAN_STATUS_RESOURCE);
102         }
103     }else {
104         p_sec_db = p_sectiondb[xran_port_id];
105     }
106
107     for(ctx=0; ctx < XRAN_MAX_SECTIONDB_CTX; ctx++)
108         for(dir=0; dir < XRAN_DIR_MAX; dir++)
109             for (cc = 0; cc < p_dev->fh_cfg.nCC && cc < XRAN_COMPONENT_CARRIERS_MAX; cc++)
110                 for (ant = 0; ant < (p_dev->fh_cfg.neAxc*2 + p_dev->fh_cfg.nAntElmTRx) && ant < (XRAN_MAX_ANTENNA_NR*2 + XRAN_MAX_ANT_ARRAY_ELM_NR); ant++)
111                     if(p_sec_db->p_sectiondb_elm[ctx][dir][cc][ant])
112                         p_sec_db->p_sectiondb_elm[ctx][dir][cc][ant]->cur_index = 0;
113
114     return (XRAN_STATUS_SUCCESS);
115 }
116
117 /**
118  * @brief Release and free section database
119  *
120  * @ingroup xran_cp_pkt
121  *
122  * @param pHandle
123  *  handle for xRAN interface, currently not being used
124  * @return
125  *  XRAN_STATUS_SUCCESS on success
126  */
127 int32_t
128 xran_cp_free_sectiondb(void *pHandle)
129 {
130     int32_t ctx, dir, cc, ant;
131     struct xran_device_ctx* p_dev = NULL;
132     uint8_t xran_port_id = 0;
133     PSECTION_DB_TYPE p_sec_db =  NULL;
134
135     if(pHandle) {
136         p_dev = (struct xran_device_ctx* )pHandle;
137         xran_port_id = p_dev->xran_port_id;
138     } else {
139         print_err("Invalid pHandle - %p", pHandle);
140         return (XRAN_STATUS_FAIL);
141     }
142
143     if (p_sectiondb[xran_port_id] == NULL){
144         return (XRAN_STATUS_INVALID_PARAM);
145     } else {
146         p_sec_db = p_sectiondb[xran_port_id];
147         for (ctx = 0; ctx < XRAN_MAX_SECTIONDB_CTX; ctx++) {
148             for (dir = 0; dir < XRAN_DIR_MAX; dir++) {
149                 for (cc = 0; cc < XRAN_COMPONENT_CARRIERS_MAX; cc++) {
150                     for (ant = 0; ant < (XRAN_MAX_ANTENNA_NR*2 + XRAN_MAX_ANT_ARRAY_ELM_NR); ant++) {
151                         if(p_sec_db->p_sectiondb_elm[ctx][dir][cc][ant])
152                             rte_free(p_sec_db->p_sectiondb_elm[ctx][dir][cc][ant]);
153                     }
154                 }
155             }
156         }
157         rte_free(p_sec_db);
158         p_sectiondb[xran_port_id] = NULL;
159     }
160
161     return (XRAN_STATUS_SUCCESS);
162 }
163
164 static inline struct xran_sectioninfo_db *
165 xran_get_section_db(void *pHandle,
166         uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id)
167 {
168   struct xran_sectioninfo_db *ptr;
169     struct xran_device_ctx* p_dev = NULL;
170     uint8_t xran_port_id = 0;
171     PSECTION_DB_TYPE p_sec_db =  NULL;
172
173     if(pHandle) {
174         p_dev = (struct xran_device_ctx* )pHandle;
175         xran_port_id = p_dev->xran_port_id;
176     } else {
177         print_err("Invalid pHandle - %p", pHandle);
178         return (NULL);
179     }
180
181     if(unlikely(xran_port_id >= XRAN_PORTS_NUM)) {
182         print_err("Invalid Port id - %d", p_dev->xran_port_id);
183         return (NULL);
184     }
185
186     if (p_sectiondb[xran_port_id] == NULL){
187         print_err("p_sectiondb xran_port %d\n", xran_port_id);
188         return (NULL);
189     }else {
190         p_sec_db = p_sectiondb[xran_port_id];
191     }
192     if(unlikely(ctx_id >= XRAN_MAX_SECTIONDB_CTX)) {
193         print_err("Invalid Context id - %d", ctx_id);
194         return (NULL);
195         }
196
197     if(unlikely(dir >= XRAN_DIR_MAX)) {
198         print_err("Invalid direction - %d", dir);
199         return (NULL);
200         }
201
202     if(unlikely(cc_id >= XRAN_COMPONENT_CARRIERS_MAX)) {
203         print_err("Invalid CC id - %d", cc_id);
204         return (NULL);
205         }
206
207     if(unlikely(ruport_id >= XRAN_MAX_ANTENNA_NR*2 + XRAN_MAX_ANT_ARRAY_ELM_NR)) {
208         print_err("Invalid eAxC id - %d", ruport_id);
209         return (NULL);
210         }
211
212     ptr = p_sec_db->p_sectiondb_elm[ctx_id][dir][cc_id][ruport_id];
213
214     return(ptr);
215 }
216
217 static inline struct xran_section_info *
218 xran_get_section_info(struct xran_sectioninfo_db *ptr, uint16_t index)
219 {
220     if(unlikely(ptr == NULL))
221         return (NULL);
222
223     if(unlikely(index > XRAN_MAX_NUM_SECTIONS)) {
224         print_err("Index is out of range - %d", index);
225         return (NULL);
226         }
227
228     return(&(ptr->list[index]));
229 }
230
231 /**
232  * @brief Add a section information of C-Plane to dabase.
233  *
234  * @ingroup xran_cp_pkt
235  *
236  * @param pHandle
237  *  handle for xRAN interface, currently not being used
238  * @param dir
239  *  Direction of C-Plane message for the section to store
240  * @param cc_id
241  *  CC ID of C-Plane message for the section to store
242  * @param ruport_id
243  *  RU port ID of C-Plane message for the section to store
244  * @param ctx_id
245  *  Context index for the section database
246  * @param info
247  *  The information of this section to store
248  * @return
249  *  XRAN_STATUS_SUCCESS on success
250  *  XRAN_STATUS_INVALID_PARAM, if direction, CC ID or RU port ID is incorrect
251  *  XRAN_STATUS_RESOURCE, if no more space to add on database
252  */
253 int32_t
254 xran_cp_add_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id, struct xran_section_info *info)
255 {
256   struct xran_sectioninfo_db *ptr;
257   struct xran_section_info *list;
258
259     ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
260     if(unlikely(ptr == NULL)) {
261         return (XRAN_STATUS_INVALID_PARAM);
262         }
263
264     if(unlikely(ptr->cur_index >= XRAN_MAX_NUM_SECTIONS)) {
265         print_err("No more space to add section information!");
266         return (XRAN_STATUS_RESOURCE);
267         }
268
269     list = xran_get_section_info(ptr, ptr->cur_index);
270     if (list)
271         memcpy(list, info, sizeof(struct xran_section_info));
272     else
273     {
274         print_err("Null list in section db\n!");
275         return (XRAN_STATUS_INVALID_PARAM);
276     }
277
278     ptr->cur_index++;
279
280     return (XRAN_STATUS_SUCCESS);
281 }
282
283
284 struct xran_section_info *
285 xran_cp_get_section_info_ptr(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id)
286 {
287     struct xran_sectioninfo_db *ptr;
288     struct xran_section_info *list;
289
290     ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
291     if(unlikely(ptr == NULL)) {
292         return NULL;
293         }
294
295     if(unlikely(ptr->cur_index >= XRAN_MAX_NUM_SECTIONS)) {
296         print_err("No more space to add section information!");
297         return NULL;
298         }
299
300     list = xran_get_section_info(ptr, ptr->cur_index);
301     if (list)
302     {
303         ptr->cur_index++;
304         return list;
305     }
306     else
307     {
308         print_err("Null list in section db\n!");
309         return NULL;
310     }
311
312 }
313
314
315
316 int32_t
317 xran_cp_add_multisection_info(void *pHandle, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id, struct xran_cp_gen_params *gen_info)
318 {
319     int32_t i;
320   uint8_t dir, num_sections;
321   struct xran_sectioninfo_db *ptr;
322   struct xran_section_info *list;
323
324     dir             = gen_info->dir;
325     num_sections    = gen_info->numSections;
326
327     ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
328     if(unlikely(ptr == NULL)) {
329         return (XRAN_STATUS_INVALID_PARAM);
330         }
331
332     if(unlikely(ptr->cur_index+num_sections >= XRAN_MAX_NUM_SECTIONS)) {
333         print_err("No more space to add section information!");
334         return (XRAN_STATUS_RESOURCE);
335         }
336
337     list = xran_get_section_info(ptr, ptr->cur_index);
338     if (list)
339     {
340     for(i=0; i<num_sections; i++) {
341             memcpy(&list[i], gen_info->sections[i].info, sizeof(struct xran_section_info));
342         ptr->cur_index++;
343         }
344     }
345     else
346     {
347         print_err("Null list in section db\n!");
348         return (XRAN_STATUS_INVALID_PARAM);
349     }
350
351     return (XRAN_STATUS_SUCCESS);
352 }
353
354 /**
355  * @brief Find a section information of C-Plane from database
356  *   by given information
357  *
358  * @ingroup xran_cp_pkt
359  *
360  * @param pHandle
361  *  handle for xRAN interface, currently not being used
362  * @param dir
363  *  The direction of the section to find
364  * @param cc_id
365  *  The CC ID of the section to find
366  * @param ruport_id
367  *  RU port ID of the section to find
368  * @param ctx_id
369  *  Context index for the section database
370  * @param section_id
371  *  The ID of section to find
372  * @return
373  *  The pointer of section information if matched section is found
374  *  NULL if failed to find matched section
375  */
376 struct xran_section_info *
377 xran_cp_find_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id, uint16_t section_id)
378 {
379   struct xran_sectioninfo_db *ptr;
380
381     ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
382     if(unlikely(ptr == NULL))
383         return (NULL);
384
385     if(section_id > ptr->cur_index || section_id < 0)
386     {
387         print_err("No section ID in the list - %d, ptr->cur_index is %d", section_id, ptr->cur_index);
388             }
389     return (xran_get_section_info(ptr, section_id));
390 }
391
392 /**
393  * @brief Iterate each section information of C-Plane
394  *  from the database of eAxC by given information
395  *
396  * @ingroup xran_cp_pkt
397  *
398  * @param pHandle
399  *  handle for xRAN interface, currently not being used
400  * @param dir
401  *  The direction of the section to find
402  * @param cc_id
403  *  The CC ID of the section to find
404  * @param ruport_id
405  *  RU port ID of the section to find
406  * @param ctx_id
407  *  Context index for the section database
408  * @param next
409  *  The pointer to store the position of next entry
410  * @return
411  *  The pointer of section information in the list
412  *  NULL if reached at the end of the list
413  */
414 struct xran_section_info *
415 xran_cp_iterate_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id, uint32_t *next)
416 {
417     int32_t index;
418   struct xran_sectioninfo_db *ptr;
419
420     ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
421     if(unlikely(ptr == NULL))
422         return (NULL);
423
424     index = *next;
425     if(*next < ptr->cur_index) {
426         (*next)++;
427         return (xran_get_section_info(ptr, index));
428         }
429     else {
430         print_dbg("No more sections in the list");
431         return (NULL);
432         }
433 }
434
435 /**
436  * @brief Get the size of stored entries
437  *  for the database of eAxC by given information
438  *
439  * @ingroup xran_cp_pkt
440  *
441  * @param pHandle
442  *  handle for xRAN interface, currently not being used
443  * @param dir
444  *  The direction of the section to find
445  * @param cc_id
446  *  The CC ID of the section to find
447  * @param ruport_id
448  *  RU port ID of the section to find
449  * @param ctx_id
450  *  Context index for the section database
451  * @return
452  *  The size of stored entries
453  *  -1 if failed to find matched database
454  */
455 int32_t
456 xran_cp_getsize_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id)
457 {
458   struct xran_sectioninfo_db *ptr;
459
460     ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
461     if(unlikely(ptr == NULL))
462         return (-1);
463
464     return (ptr->cur_index);
465 }
466
467 /**
468  * @brief Reset a database of eAxC by given information
469  *
470  * @ingroup xran_cp_pkt
471  *
472  * @param pHandle
473  *  handle for xRAN interface, currently not being used
474  * @param dir
475  *  The direction of the section to find
476  * @param cc_id
477  *  The CC ID of the section to find
478  * @param ruport_id
479  *  RU port ID of the section to find
480  * @param ctx_id
481  *  Context index for the section database
482  * @return
483  *  XRAN_STATUS_SUCCESS on success
484  *  XRAN_STATUS_INVALID_PARM if failed to find matched database
485  */
486 int32_t
487 xran_cp_reset_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id)
488 {
489   struct xran_sectioninfo_db *ptr;
490
491     ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
492     if(unlikely(ptr == NULL)) {
493         return (XRAN_STATUS_INVALID_PARAM);
494         }
495
496     ptr->cur_index = 0;
497
498     return (XRAN_STATUS_SUCCESS);
499 }
500
501 int32_t xran_cp_populate_section_ext_1(int8_t  *p_ext1_dst,    /**< destination buffer */
502                                        uint16_t  ext1_dst_len, /**< dest buffer size */
503                                        int16_t  *p_bfw_iq_src, /**< source buffer of IQs */
504                                        struct xran_prb_elm *p_pRbMapElm)
505 {
506     struct xran_cp_radioapp_section_ext1 *p_ext1;
507     uint8_t *p_bfw_content = NULL;
508     int32_t parm_size   = 0;
509     int32_t bfw_iq_bits = 0;
510     int32_t total_len   = 0;
511     uint16_t idxSection  = 0;
512     int32_t section_len = 0;
513     int16_t numCPSections = (p_pRbMapElm->bf_weight.numSetBFWs == 0 ? 1 : p_pRbMapElm->bf_weight.numSetBFWs);
514
515     int16_t cur_ext_len = 0;
516     int8_t  *p_ext1_dst_cur = NULL;
517     int16_t  bfwNumPerRb = p_pRbMapElm->bf_weight.nAntElmTRx;
518     uint8_t   bfwiqWidth = p_pRbMapElm->bf_weight.bfwIqWidth;
519     uint8_t   bfwCompMeth = p_pRbMapElm->bf_weight.bfwCompMeth;
520     struct xran_cp_radioapp_section1 *p_section1;
521
522     struct xranlib_compress_request  bfp_com_req;
523     struct xranlib_compress_response bfp_com_rsp;
524
525     memset(&bfp_com_req, 0, sizeof(struct xranlib_compress_request));
526     memset(&bfp_com_rsp, 0, sizeof(struct xranlib_compress_response));
527
528     print_dbg("%s comp %d\n", __FUNCTION__, bfwCompMeth);
529     print_dbg("bfwNumPerRb %d bfwiqWidth %d\n", bfwNumPerRb, bfwiqWidth);
530
531     if(p_ext1_dst)
532         p_ext1_dst_cur = p_ext1_dst;
533     else
534         return (XRAN_STATUS_INVALID_PARAM);
535
536     /* create section for each PRB bundle */
537     for (idxSection = 0; idxSection < numCPSections ; idxSection++) {
538         print_dbg("%s Section %d\n", __FUNCTION__, idxSection);
539
540         if(total_len >= ext1_dst_len){
541             print_err("p_ext1_dst overflow\n");
542             return XRAN_STATUS_RESOURCE;
543         }
544
545         cur_ext_len = 0;
546         p_section1 = (struct xran_cp_radioapp_section1 *)p_ext1_dst_cur;
547         if(p_section1 == NULL) {
548             print_err("p_section is null!\n");
549             return (XRAN_STATUS_INVALID_PARAM);
550         }
551
552         section_len = sizeof(struct xran_cp_radioapp_section1);
553         
554         p_ext1_dst_cur = p_ext1_dst_cur + section_len;
555         total_len += section_len;
556
557         parm_size = sizeof(struct xran_cp_radioapp_section_ext1);
558         p_ext1 = (struct xran_cp_radioapp_section_ext1 *)p_ext1_dst_cur;
559         if(p_ext1 == NULL) {
560             print_err("p_ext1 is null!\n");
561             return (XRAN_STATUS_INVALID_PARAM);
562         }
563
564         cur_ext_len += parm_size;
565
566         p_ext1->extType       = XRAN_CP_SECTIONEXTCMD_1;
567         p_ext1->ef            = XRAN_EF_F_LAST; //only one ext-1 per CP section
568         p_ext1->bfwCompMeth   = bfwCompMeth;
569         p_ext1->bfwIqWidth    = XRAN_CONVERT_BFWIQWIDTH(bfwiqWidth);
570
571         switch(bfwCompMeth) {
572             case XRAN_BFWCOMPMETHOD_BLKFLOAT:
573                 p_bfw_content = (uint8_t *)(p_ext1+1);
574                 if(p_bfw_content == NULL) {
575                     print_err("Fail to allocate the space for section extension 1");
576                     return (XRAN_STATUS_RESOURCE);
577                 }
578                 bfp_com_req.data_in         = (int16_t*)p_bfw_iq_src;
579                 bfp_com_req.numRBs          = 1;
580                 bfp_com_req.numDataElements = bfwNumPerRb*2;
581                 bfp_com_req.len             = bfwNumPerRb*4;
582                 bfp_com_req.compMethod      = p_ext1->bfwCompMeth;
583                 bfp_com_req.iqWidth         = p_ext1->bfwIqWidth;
584
585                 print_dbg("req 0x%08p iqWidth %d\n",bfp_com_req.data_in, bfp_com_req.iqWidth);
586
587                 parm_size = 1; /* (reserved + exponent) as part of bfwCompParam 1 octet */
588                 break;
589             case XRAN_BFWCOMPMETHOD_BLKSCALE:
590                 rte_panic("XRAN_BFWCOMPMETHOD_BLKSCALE");
591                 break;
592
593             case XRAN_BFWCOMPMETHOD_ULAW:
594                 rte_panic("XRAN_BFWCOMPMETHOD_ULAW");
595                 break;
596
597             case XRAN_BFWCOMPMETHOD_BEAMSPACE:
598                 rte_panic("XRAN_BFWCOMPMETHOD_BEAMSPACE");
599                 break;
600
601             case XRAN_BFWCOMPMETHOD_NONE:
602             default:
603                 p_bfw_content = (uint8_t *)(p_ext1+1);
604                 /* bfwCompParam is absent for no compression case */
605                 parm_size = 0;
606         }
607
608         if(p_bfw_content == NULL) {
609             print_err("Fail to allocate the space for section extension 1");
610             return (XRAN_STATUS_RESOURCE);
611             }
612
613         bfw_iq_bits = bfwNumPerRb* bfwiqWidth * 2;
614
615         parm_size += bfw_iq_bits>>3;
616         if(bfw_iq_bits%8)
617             parm_size++;
618
619         print_dbg("copy BF W %p -> %p size %d \n", p_bfw_iq_src, p_bfw_content, parm_size);
620
621         if (p_ext1->bfwCompMeth == XRAN_BFWCOMPMETHOD_NONE){ //5.4.7.1.1 
622             memcpy(p_bfw_content, p_bfw_iq_src, parm_size);
623         } else {
624             bfp_com_rsp.data_out = (int8_t*)p_bfw_content;
625             if(xranlib_compress_bfw(&bfp_com_req, &bfp_com_rsp) == 0){
626                 print_dbg("comp_len %d parm_size %d\n", bfp_com_rsp.len, parm_size);
627             } else {
628                 print_err("compression failed\n");
629                 return (XRAN_STATUS_FAIL);
630             }
631         }
632
633         p_bfw_content = (uint8_t *)(p_bfw_content + parm_size);
634
635         cur_ext_len += parm_size;
636         parm_size = cur_ext_len % XRAN_SECTIONEXT_ALIGN;
637         if(parm_size) {
638             parm_size = XRAN_SECTIONEXT_ALIGN - parm_size;
639             memcpy(p_bfw_content, zeropad, RTE_MIN(parm_size, sizeof(zeropad)));
640             p_bfw_content += parm_size;
641             cur_ext_len += parm_size;
642             print_dbg("zeropad %d cur_ext_len %d\n", parm_size, cur_ext_len);
643         }
644
645         if(cur_ext_len % XRAN_SECTIONEXT_ALIGN)
646             rte_panic("ext1 should be aligned on 4-bytes boundary");
647
648         p_ext1->extLen = cur_ext_len / XRAN_SECTIONEXT_ALIGN;
649         print_dbg("%p iq %p p_ext1->extLen %d\n",p_ext1, p_ext1+1,  p_ext1->extLen);
650
651         /* update for next RB */
652         p_ext1_dst_cur += cur_ext_len;
653         p_bfw_iq_src   = p_bfw_iq_src + bfwNumPerRb*2;
654
655         total_len += cur_ext_len;
656     } /*for(idxSection < numCPSections */
657
658     print_dbg("total_len %d\n", total_len);
659     return (total_len);
660 }
661
662 // TODO: Need to decide to add calculation or not
663 // Frequency offset 5.4.5.11
664 //   frequency_offset = freqOffset * SCS * 0.5
665 //    i.e freqOffset = (frequency_offset *2 )/ SCS ?
666 inline int32_t
667 xran_get_freqoffset(int32_t freqOffset, int32_t scs)
668 {
669     return (freqOffset);
670 }
671
672 static int32_t
673 xran_append_sectionext_1(struct rte_mbuf *mbuf, struct xran_sectionext1_info *params, int32_t last_flag)
674 {
675     int32_t total_len = 0;
676
677     if(params->bfwIQ_sz) {
678         int8_t *p_dst = (int8_t *)rte_pktmbuf_append(mbuf, params->bfwIQ_sz);
679
680         if(p_dst == NULL) {
681             print_err("Fail to allocate the space for section extension 1 [%d]", params->bfwIQ_sz);
682             return (XRAN_STATUS_RESOURCE);
683         }
684
685         /* extType1 with all the headers created by xran_cp_populate_section_ext_1() earlier */
686         total_len = params->bfwIQ_sz;
687     }
688
689     return (total_len);
690 }
691
692 static int32_t
693 xran_prepare_sectionext_2(struct rte_mbuf *mbuf, struct xran_sectionext2_info *params, int32_t last_flag)
694 {
695   struct xran_cp_radioapp_section_ext2 *ext2;
696   uint8_t *data;
697     int32_t total_len;
698     int32_t parm_size;
699   uint32_t val, shift_val;
700     int32_t val_size, pad_size;
701
702     total_len = 0;
703
704     parm_size = sizeof(struct xran_cp_radioapp_section_ext2);
705     ext2 = (struct xran_cp_radioapp_section_ext2 *)rte_pktmbuf_append(mbuf, parm_size);
706     if(ext2 == NULL) {
707         print_err("Fail to allocate the space for section extension 2");
708         return (XRAN_STATUS_RESOURCE);
709         }
710     total_len += parm_size;
711
712     ext2->extType           = XRAN_CP_SECTIONEXTCMD_2;
713     ext2->ef                = last_flag;
714     ext2->bfZe3ddWidth      = params->bfZe3ddWidth;
715     ext2->bfAz3ddWidth      = params->bfAz3ddWidth;
716     ext2->bfZePtWidth       = params->bfZePtWidth;
717     ext2->bfAzPtWidth       = params->bfAzPtWidth;
718     ext2->bfaCompResv0      = 0;
719     ext2->bfaCompResv1      = 0;
720
721     val = 0;
722     shift_val = 0;
723     if(params->bfAzPtWidth) {
724         val += params->bfAzPt & bitmask[params->bfAzPtWidth];
725         shift_val += 8 - (params->bfAzPtWidth+1);
726     } else
727         shift_val += 8;
728
729     if(params->bfZePtWidth) {
730         val = val << (params->bfZePtWidth+1);
731         val += params->bfZePt & bitmask[params->bfZePtWidth];
732         shift_val += 8 - (params->bfZePtWidth+1);
733     } else
734         shift_val += 8;
735
736     if(params->bfAz3ddWidth) {
737         val = val << (params->bfAz3ddWidth+1);
738         val += params->bfAz3dd & bitmask[params->bfAz3ddWidth];
739         shift_val += 8 - (params->bfAz3ddWidth+1);
740     } else
741         shift_val += 8;
742
743     if(params->bfZe3ddWidth) {
744         val = val << (params->bfZe3ddWidth+1);
745         val += params->bfZe3dd & bitmask[params->bfZe3ddWidth];
746         shift_val += 8 - (params->bfZe3ddWidth+1);
747     } else
748         shift_val += 8;
749
750     if(val) {
751         val = val << shift_val;
752         val = rte_cpu_to_be_32(val);
753         }
754
755     val_size = 4 - (shift_val/8);   /* ceil(total bit/8) */
756     parm_size = val_size + 1;       /* additional 1 byte for bfxxSI */
757
758     // alignment
759     total_len += parm_size;
760     pad_size = total_len % XRAN_SECTIONEXT_ALIGN;
761     if(pad_size) {
762         pad_size = XRAN_SECTIONEXT_ALIGN - pad_size;
763         parm_size += pad_size;
764         total_len += pad_size;
765         }
766
767     data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
768     if(data == NULL) {
769         print_err("Fail to allocate the space for section extension 2");
770         return (XRAN_STATUS_RESOURCE);
771         }
772
773     memcpy(data, &val, val_size);
774     data += val_size;
775     *data = ((params->bfAzSI) << 3) + (params->bfZeSI);
776     data++;
777     memcpy(data, zeropad, pad_size);
778
779     ext2->extLen = total_len / XRAN_SECTIONEXT_ALIGN;
780     *(uint32_t *)ext2 = rte_cpu_to_be_32(*(uint32_t *)ext2);
781
782     return (total_len);
783 }
784
785 static int32_t
786 xran_prepare_sectionext_3(struct rte_mbuf *mbuf, struct xran_sectionext3_info *params, int32_t last_flag)
787 {
788     int32_t total_len;
789     int32_t adj;
790     int32_t data_first_byte, data_second_byte;
791     int32_t data_third_byte, data_fourth_byte;
792     int32_t extLen;
793
794     if(params->layerId == XRAN_LAYERID_0
795         || params->layerId == XRAN_LAYERID_TXD) {   /* first data layer */
796
797         union xran_cp_radioapp_section_ext3_first *ext3_f;
798         uint64_t *tmp;
799
800         total_len = sizeof(union xran_cp_radioapp_section_ext3_first);
801         ext3_f = (union xran_cp_radioapp_section_ext3_first *)rte_pktmbuf_append(mbuf, total_len);
802         if(ext3_f == NULL) {
803             print_err("Fail to allocate the space for section extension 3");
804             return (XRAN_STATUS_RESOURCE);
805             }
806
807         /*ext3_f->data_field.data_field1 = _mm_setzero_si128();
808
809         ext3_f->all_bits.layerId         = params->layerId;
810         ext3_f->all_bits.ef              = last_flag;
811         ext3_f->all_bits.extType         = XRAN_CP_SECTIONEXTCMD_3;
812         ext3_f->all_bits.crsSymNum       = params->crsSymNum;
813         ext3_f->all_bits.crsShift        = params->crsShift;
814         ext3_f->all_bits.crsReMask       = params->crsReMask;
815         ext3_f->all_bits.txScheme        = params->txScheme;
816         ext3_f->all_bits.numLayers       = params->numLayers;
817         ext3_f->all_bits.codebookIndex   = params->codebookIdx;
818
819         if(params->numAntPort == 2) {
820             ext3_f->all_bits.beamIdAP3   = params->beamIdAP1;
821             ext3_f->all_bits.extLen      = 3;
822             adj = 4;
823             total_len -= adj;
824             }
825         else {
826             ext3_f->all_bits.beamIdAP3   = params->beamIdAP1;
827             ext3_f->all_bits.beamIdAP2   = params->beamIdAP2;
828             ext3_f->all_bits.beamIdAP1   = params->beamIdAP3;
829             ext3_f->all_bits.extLen      = 4;
830             adj = 0;
831             }*/
832
833         if(params->numAntPort == 2) {
834             data_third_byte = 0;
835             extLen = 3;
836             adj = 4;
837             total_len -= adj;
838         }else
839         {
840             data_third_byte = (params->beamIdAP2 << 16) | params->beamIdAP3;
841             extLen = 4;
842             adj = 0;
843             }
844
845         data_first_byte  = (params->txScheme << xran_cp_radioapp_sec_ext3_TxScheme)
846                          | (params->crsReMask << xran_cp_radioapp_sec_ext3_CrcReMask)
847                          | (params->crsShift << xran_cp_radioapp_sec_ext3_CrcShift)
848                          | (params->crsSymNum << xran_cp_radioapp_sec_ext3_CrcSymNum);
849         data_second_byte = (last_flag << xran_cp_radioapp_sec_ext3_EF)
850                          | (XRAN_CP_SECTIONEXTCMD_3 << xran_cp_radioapp_sec_ext3_ExtType)
851                          | (extLen << xran_cp_radioapp_sec_ext3_ExtLen)
852                          | (params->codebookIdx << xran_cp_radioapp_sec_ext3_CodebookIdx)
853                          | (params->layerId << xran_cp_radioapp_sec_ext3_LayerId)
854                          | (params->numLayers << xran_cp_radioapp_sec_ext3_NumLayers);
855         data_fourth_byte  = params->beamIdAP1;
856         ext3_f->data_field.data_field1 = _mm_set_epi32(data_fourth_byte, data_third_byte, data_second_byte, data_first_byte);
857
858         /* convert byte order */
859         tmp = (uint64_t *)ext3_f;
860         *tmp = rte_cpu_to_be_64(*tmp); tmp++;
861         *tmp = rte_cpu_to_be_64(*tmp);
862
863         if(adj)
864             rte_pktmbuf_trim(mbuf, adj);
865         }
866     else {  /* non-first data layer */
867         union xran_cp_radioapp_section_ext3_non_first *ext3_nf;
868
869         total_len = sizeof(union xran_cp_radioapp_section_ext3_non_first);
870         ext3_nf = (union xran_cp_radioapp_section_ext3_non_first *)rte_pktmbuf_append(mbuf, total_len);
871         if(ext3_nf == NULL) {
872             print_err("Fail to allocate the space for section extension 3");
873             return (XRAN_STATUS_RESOURCE);
874             }
875
876         /*ext3_nf->all_bits.layerId        = params->layerId;
877         ext3_nf->all_bits.ef             = last_flag;
878         ext3_nf->all_bits.extType        = XRAN_CP_SECTIONEXTCMD_3;
879         ext3_nf->all_bits.numLayers      = params->numLayers;
880         ext3_nf->all_bits.codebookIndex  = params->codebookIdx;
881
882         ext3_nf->all_bits.extLen         = sizeof(union xran_cp_radioapp_section_ext3_non_first)/XRAN_SECTIONEXT_ALIGN;*/
883
884         ext3_nf->data_field = (last_flag << xran_cp_radioapp_sec_ext3_EF)
885                             | (XRAN_CP_SECTIONEXTCMD_3 << xran_cp_radioapp_sec_ext3_ExtType)
886                             | ((sizeof(union xran_cp_radioapp_section_ext3_non_first)/XRAN_SECTIONEXT_ALIGN) << xran_cp_radioapp_sec_ext3_ExtLen)
887                             | (params->codebookIdx << xran_cp_radioapp_sec_ext3_CodebookIdx)
888                             | (params->layerId << xran_cp_radioapp_sec_ext3_LayerId)
889                             | (params->numLayers << xran_cp_radioapp_sec_ext3_NumLayers);
890
891         *(uint32_t *)ext3_nf = rte_cpu_to_be_32(*(uint32_t *)ext3_nf);
892         }
893
894     return (total_len);
895 }
896
897 static int32_t
898 xran_prepare_sectionext_4(struct rte_mbuf *mbuf, struct xran_sectionext4_info *params, int32_t last_flag)
899 {
900   struct xran_cp_radioapp_section_ext4 *ext4;
901     int32_t parm_size;
902
903     parm_size = sizeof(struct xran_cp_radioapp_section_ext4);
904     ext4 = (struct xran_cp_radioapp_section_ext4 *)rte_pktmbuf_append(mbuf, parm_size);
905     if(ext4 == NULL) {
906         print_err("Fail to allocate the space for section extension 4");
907         return(XRAN_STATUS_RESOURCE);
908         }
909
910         ext4->extType       = XRAN_CP_SECTIONEXTCMD_4;
911         ext4->ef            = last_flag;
912         ext4->modCompScaler = params->modCompScaler;
913         ext4->csf           = params->csf?1:0;
914     ext4->extLen        = parm_size / XRAN_SECTIONEXT_ALIGN;
915
916         *(uint32_t *)ext4 = rte_cpu_to_be_32(*(uint32_t*)ext4);
917
918     return (parm_size);
919 }
920
921 static int32_t
922 xran_prepare_sectionext_9(struct rte_mbuf *mbuf, struct xran_sectionext9_info * params, int32_t last_flag)
923 {
924     struct xran_cp_radioapp_section_ext9 *ext9;
925     int32_t parm_size;
926
927     parm_size = sizeof(struct xran_cp_radioapp_section_ext9);
928     ext9 = (struct xran_cp_radioapp_section_ext9 *)rte_pktmbuf_append(mbuf, parm_size);
929     if(ext9 == NULL) {
930         print_err("Fail to allocate the space for section extension 9");
931         return(XRAN_STATUS_RESOURCE);
932     }
933
934     ext9->extType       = XRAN_CP_SECTIONEXTCMD_9;
935     ext9->ef            = last_flag;
936     ext9->extLen        = parm_size / XRAN_SECTIONEXT_ALIGN;
937     ext9->technology    = params->technology;
938     ext9->reserved      = params->reserved;
939     
940     *(uint32_t *)ext9 = rte_cpu_to_be_32(*(uint32_t*)ext9);
941
942     return (parm_size);
943 }
944
945 static int32_t
946 xran_prepare_sectionext_5(struct rte_mbuf *mbuf, struct xran_sectionext5_info *params, int32_t last_flag)
947 {
948   struct xran_cp_radioapp_section_ext_hdr *ext_hdr;
949   struct xran_cp_radioapp_section_ext5 ext5;
950     int32_t padding;
951     int32_t total_len;
952   uint8_t *data;
953     int32_t i;
954
955     if(params->num_sets > XRAN_MAX_MODCOMP_ADDPARMS) {
956         print_err("Exceeds maximum number of parameters(%d). Skipping.", params->num_sets);
957         return (0);
958         }
959
960     total_len = sizeof(struct xran_cp_radioapp_section_ext_hdr)
961                 + (sizeof(struct xran_cp_radioapp_section_ext5)*params->num_sets)/2
962                 - (params->num_sets>>1); // 8bits are added by every two sets, so needs to adjust
963
964     /* for alignment */
965     padding = total_len % XRAN_SECTIONEXT_ALIGN;
966     if(padding) {
967         padding = XRAN_SECTIONEXT_ALIGN - padding;
968         total_len += padding;
969         }
970
971     ext_hdr = (struct xran_cp_radioapp_section_ext_hdr *)rte_pktmbuf_append(mbuf, total_len);
972     if(ext_hdr == NULL) {
973         print_err("Fail to allocate the space for section extension 5");
974         return (XRAN_STATUS_RESOURCE);
975         }
976
977     ext_hdr->extType    = XRAN_CP_SECTIONEXTCMD_5;
978     ext_hdr->ef         = last_flag;
979     ext_hdr->extLen     = total_len / XRAN_SECTIONEXT_ALIGN;
980
981     *(uint16_t *)ext_hdr    = rte_cpu_to_be_16(*((uint16_t *)ext_hdr));
982
983     data = (uint8_t *)(ext_hdr + 1);
984     i = 0;
985     while(i < params->num_sets) {
986         if(i%2) { // odd index
987             ext5.mcScaleOffset2 = params->mc[i].mcScaleOffset;
988             ext5.csf2           = params->mc[i].csf;
989             ext5.mcScaleReMask2 = params->mc[i].mcScaleReMask;
990             ext5.reserved0      = 0;
991             i++;
992
993             // adding two sets at once (due to the definition of structure)
994             *((uint64_t *)&ext5) = rte_cpu_to_be_64(*((uint64_t *)&ext5));
995             memcpy(data, &ext5, sizeof(struct xran_cp_radioapp_section_ext5));
996             data += sizeof(struct xran_cp_radioapp_section_ext5);
997             }
998         else { // even index
999             ext5.mcScaleOffset1 = params->mc[i].mcScaleOffset;
1000             ext5.csf1           = params->mc[i].csf;
1001             ext5.mcScaleReMask1 = params->mc[i].mcScaleReMask;
1002             ext5.mcScaleReMask2 = 0;
1003             i++;
1004
1005             if(i == params->num_sets) { // adding last even index
1006                 *((uint64_t *)&ext5) = rte_cpu_to_be_64(*((uint64_t *)&ext5));
1007                 memcpy(data, &ext5, sizeof(struct xran_cp_radioapp_section_ext5)/2);
1008                 data += sizeof(struct xran_cp_radioapp_section_ext5)/2;
1009                 break;
1010                 }
1011             }
1012         }
1013
1014     /* zero padding */
1015     if(padding)
1016         memcpy(data, zeropad, padding);
1017
1018     return (total_len);
1019 }
1020
1021 static int32_t
1022 xran_prepare_sectionext_6(struct rte_mbuf *mbuf,
1023                 struct xran_sectionext6_info *params, int32_t last_flag)
1024 {
1025     union xran_cp_radioapp_section_ext6 *ext6;
1026     int32_t parm_size;
1027
1028     parm_size = sizeof(union xran_cp_radioapp_section_ext6);
1029     ext6 = (union xran_cp_radioapp_section_ext6 *)rte_pktmbuf_append(mbuf, parm_size);
1030     if(ext6 == NULL) {
1031         print_err("Fail to allocate the space for section extension 6");
1032         return(XRAN_STATUS_RESOURCE);
1033         }
1034
1035     ext6->data_field.data_field1 = 0x0LL;
1036     ext6->all_bits.extType       = XRAN_CP_SECTIONEXTCMD_6;
1037     ext6->all_bits.ef            = last_flag;
1038     ext6->all_bits.rbgSize       = params->rbgSize;
1039     ext6->all_bits.rbgMask       = params->rbgMask;
1040     ext6->all_bits.symbolMask    = params->symbolMask;
1041     ext6->all_bits.extLen        = parm_size / XRAN_SECTIONEXT_ALIGN;
1042     //ext6->reserved0     = 0;
1043     //ext6->reserved1     = 0;
1044
1045     *(uint64_t *)ext6 = rte_cpu_to_be_64(*(uint64_t*)ext6);
1046
1047     return (parm_size);
1048 }
1049
1050 static int32_t
1051 xran_prepare_sectionext_10(struct rte_mbuf *mbuf,
1052                 struct xran_sectionext10_info *params, int32_t last_flag)
1053 {
1054   union xran_cp_radioapp_section_ext10 *ext10;
1055   int32_t parm_size;
1056   int32_t total_len;
1057   int32_t padding;
1058   int32_t i;
1059   uint16_t *id_ptr;
1060
1061
1062 #if (XRAN_STRICT_PARM_CHECK)
1063     if(params->beamGrpType != XRAN_BEAMGT_COMMON
1064         && params->beamGrpType != XRAN_BEAMGT_MATRIXIND
1065         && params->beamGrpType != XRAN_BEAMGT_VECTORLIST) {
1066         print_err("Invalid beam group Type - %d\n", params->beamGrpType);
1067         return (XRAN_STATUS_INVALID_PARAM);
1068         }
1069 #endif
1070     /* should be checked since it will be used for the index of array */
1071     if(params->numPortc > XRAN_MAX_NUMPORTC_EXT10) {
1072         print_err("Invalid Number of eAxC in extension 10 - %d\n", params->numPortc);
1073         return (XRAN_STATUS_INVALID_PARAM);
1074         }
1075
1076     parm_size = sizeof(union xran_cp_radioapp_section_ext10);
1077     ext10 = (union xran_cp_radioapp_section_ext10 *)rte_pktmbuf_append(mbuf, parm_size);
1078     if(ext10 == NULL) {
1079         print_err("Fail to allocate the space for section extension 10");
1080         return(XRAN_STATUS_RESOURCE);
1081         }
1082
1083     ext10->all_bits.extType          = XRAN_CP_SECTIONEXTCMD_10;
1084     ext10->all_bits.ef               = last_flag;
1085     ext10->all_bits.numPortc         = params->numPortc;
1086     ext10->all_bits.beamGroupType    = params->beamGrpType;
1087     ext10->all_bits.reserved         = 0;
1088
1089     total_len = parm_size;
1090
1091     if(params->beamGrpType == XRAN_BEAMGT_VECTORLIST) {
1092         /* Calculate required size, it needs to be reduced by one byte
1093          * since beam ID starts from reserved field(fourth octet). */
1094         parm_size = params->numPortc * 2 - 1;
1095
1096         /* for alignment */
1097         padding = (parm_size + total_len) % XRAN_SECTIONEXT_ALIGN;
1098         if(padding) {
1099             padding = XRAN_SECTIONEXT_ALIGN - padding;
1100             parm_size += padding;
1101             }
1102
1103         id_ptr = (uint16_t *)rte_pktmbuf_append(mbuf, parm_size);
1104         if(id_ptr == NULL) {
1105             print_err("Fail to allocate the space for beam IDs in section extension 10");
1106             return(XRAN_STATUS_RESOURCE);
1107             }
1108
1109         /* Need to advance pointer by one-byte since beam IDs start from fourth octet */
1110         id_ptr = (uint16_t *)(((uint8_t *)id_ptr) - 1);
1111
1112         /* this might not be optimal since the alignment is broken */
1113         for(i = 0; i < params->numPortc; i++)
1114             id_ptr[i] = rte_cpu_to_be_16(params->beamID[i]);
1115
1116         /* zero padding */
1117         if(padding)
1118             memcpy((uint8_t *)&id_ptr[params->numPortc], zeropad, padding);
1119         }
1120
1121     total_len += parm_size;
1122     ext10->all_bits.extLen = total_len / XRAN_SECTIONEXT_ALIGN;
1123
1124     ext10->data_field = 0;
1125     ext10->data_field = (XRAN_CP_SECTIONEXTCMD_10 << xran_cp_radioapp_sec_ext10_ExtType)
1126                       | (last_flag << xran_cp_radioapp_sec_ext10_EF)
1127                       | ((total_len / XRAN_SECTIONEXT_ALIGN) << xran_cp_radioapp_sec_ext10_ExtLen)
1128                       | (params->numPortc << xran_cp_radioapp_sec_ext10_NumPortc)
1129                       | (params->beamGrpType << xran_cp_radioapp_sec_ext10_BeamGroupType);
1130
1131
1132     return (total_len);
1133 }
1134
1135 /**
1136  * @brief Estimates how many BFW sets can be fit to given MTU size
1137  *
1138  * @ingroup xran_cp_pkt
1139  *
1140  * @param numBFW        the number of BFW I/Qs
1141  * @param iqWidth       the bitwidth of BFW
1142  * @param compMeth      Compression method for BFW
1143  * @param mtu           MTU size
1144  *
1145  * @return
1146  *  the number of maximum set of BFWs on success
1147  *  XRAN_STATUS_INVALID_PARAM, if compression method is not supported.
1148  */
1149 int32_t
1150 xran_cp_estimate_max_set_bfws(uint8_t numBFWs, uint8_t iqWidth, uint8_t compMeth, uint16_t mtu)
1151 {
1152     int32_t avail_len;
1153     int32_t bfw_bitsize;
1154     int32_t bundle_size;
1155
1156     /* Exclude headers can be present */
1157     avail_len = mtu - ( RTE_PKTMBUF_HEADROOM \
1158                         + sizeof(struct xran_ecpri_hdr)                    \
1159                         + sizeof(struct xran_cp_radioapp_section1_header)   \
1160                         + sizeof(struct xran_cp_radioapp_section1)         \
1161                         + sizeof(union xran_cp_radioapp_section_ext6)     \
1162                         + sizeof(union xran_cp_radioapp_section_ext10) );
1163
1164     /* Calculate the size of BFWs I/Q in bytes */
1165     bfw_bitsize = numBFWs * iqWidth * 2;
1166     bundle_size = bfw_bitsize>>3;
1167     if(bfw_bitsize%8) bundle_size++;
1168
1169     bundle_size += 2;           /* two bytes for Beam ID */
1170     switch(compMeth) {
1171         case XRAN_BFWCOMPMETHOD_NONE:
1172             break;
1173
1174         case XRAN_BFWCOMPMETHOD_BLKFLOAT:
1175             bundle_size += 1;   /* for bfwCompParam */
1176             break;
1177
1178         default:
1179             print_err("Compression method %d is not supported!", compMeth);
1180             return (XRAN_STATUS_INVALID_PARAM);
1181         }
1182
1183     return (avail_len / bundle_size);
1184 }
1185
1186 inline static uint32_t
1187 xran_cp_get_hdroffset_section1(uint32_t exthdr_size)
1188 {
1189   uint32_t hdr_len;
1190
1191     hdr_len = ( RTE_PKTMBUF_HEADROOM                                \
1192                 + sizeof(struct xran_ecpri_hdr)                     \
1193                 + sizeof(struct xran_cp_radioapp_section1_header)   \
1194                 + sizeof(struct xran_cp_radioapp_section1)          \
1195                 + exthdr_size );
1196     return (hdr_len);
1197 }
1198
1199 /**
1200  * @brief Prepare Beam Forming Weights(BFWs) for Section Extension 11
1201  *   Copy sets of BFWs to buffer after compression if required.
1202  *
1203  * @ingroup xran_cp_pkt
1204  *
1205  * @param numSetBFW     the number of set of BFWs
1206  * @param numBFW        the number of BFWs in a set
1207  * @param iqWidth       the bitwidth of BFW
1208  * @param compMeth      Compression method for BFW
1209  * @param bfwIQ         the array of BFW I/Q source
1210  * @param dst           the pointer of destination buffer (external buffer)
1211  * @param dst_maxlen    the maximum length of destination buffer
1212  *                      need to exclude headroom from MTU
1213  * @param bfwInfo       Extension 11 PRB bundle information array.
1214  *                      BFW size, offset and pointer will be set.
1215  *
1216  * @return
1217  *  XRAN_STATUS_SUCCESS on success
1218  *  XRAN_STATUS_RESOURCE, if destination memory is not enough to store all BFWs
1219  */
1220 int32_t xran_cp_prepare_ext11_bfws(uint8_t numSetBFW, uint8_t numBFW,
1221                         uint8_t iqWidth, uint8_t compMeth,
1222                         uint8_t *dst, int16_t dst_maxlen,
1223                         struct xran_ext11_bfw_info bfwInfo[])
1224 {
1225     int32_t   i;
1226     int32_t   iq_bitsize, iq_size;
1227     int32_t   parm_size;
1228     int32_t   total_len;
1229     uint32_t  hdr_offset;
1230     uint8_t   *ptr;
1231
1232     struct xranlib_compress_request  bfpComp_req;
1233     struct xranlib_compress_response bfpComp_rsp;
1234
1235     if(dst == NULL) {
1236         print_err("Invalid destination pointer!");
1237         return (XRAN_STATUS_INVALID_PARAM);
1238     }
1239
1240     /* Calculate the size of BFWs I/Q in bytes */
1241     iq_bitsize = numBFW * iqWidth * 2;
1242     iq_size = iq_bitsize>>3;
1243     if(iq_bitsize%8)
1244         iq_size++;
1245
1246     /* Check maximum size */
1247     parm_size = ((compMeth == XRAN_BFWCOMPMETHOD_NONE)?0:1) + 2; /* bfwCompParam + beamID(2) */
1248     total_len = numSetBFW * (parm_size + iq_size);
1249
1250     if(total_len >= dst_maxlen) {
1251         print_err("Exceed maximum length to fit the set of BFWs - (%d/%d)",
1252                     total_len, dst_maxlen);
1253         return (XRAN_STATUS_RESOURCE);
1254     }
1255
1256     hdr_offset = xran_cp_get_hdroffset_section1(sizeof(union xran_cp_radioapp_section_ext11));
1257
1258     /* Copy BFWs to destination buffer */
1259     ptr = dst + hdr_offset;
1260     switch(compMeth) {
1261         /* No compression */
1262         case XRAN_BFWCOMPMETHOD_NONE:
1263             for(i = 0; i < numSetBFW; i++) {
1264                 *((uint16_t *)ptr) = rte_cpu_to_be_16((bfwInfo[i].beamId & 0x7fff));
1265                 memcpy((ptr + 2), bfwInfo[i].pBFWs, iq_size);
1266                 ptr += iq_size + 2; /* beam ID + IQ size */
1267             }
1268             break;
1269
1270         /* currently only supports BFP compression */
1271         case XRAN_BFWCOMPMETHOD_BLKFLOAT:
1272             memset(&bfpComp_req, 0, sizeof(struct xranlib_compress_request));
1273             memset(&bfpComp_rsp, 0, sizeof(struct xranlib_compress_response));
1274
1275             for(i = 0; i < numSetBFW; i++) {
1276                 bfpComp_req.numRBs          = 1;
1277                 bfpComp_req.numDataElements = numBFW*2;
1278                 bfpComp_req.len             = numBFW*2*2;
1279                 bfpComp_req.compMethod      = compMeth;
1280                 bfpComp_req.iqWidth         = iqWidth;
1281                 bfpComp_req.data_in         = (int16_t *)bfwInfo[i].pBFWs;
1282                 bfpComp_rsp.data_out        = (int8_t*)(ptr + 2);   /* exponent will be stored at first byte */
1283
1284                 if(xranlib_compress_bfw(&bfpComp_req, &bfpComp_rsp) == 0) {
1285                     print_dbg("comp_len %d iq_size %d\n", bfpComp_rsp.len, iq_size);
1286                 } else {
1287                     print_err("compression failed\n");
1288                     return (XRAN_STATUS_FAIL);
1289                     }
1290                 /* move exponent, it is stored at first byte of output */
1291                 *ptr = *(ptr + 2);
1292
1293                 /* beamId */
1294                 *((uint16_t *)(ptr+1)) = rte_cpu_to_be_16((bfwInfo[i].beamId & 0x7fff));
1295                 ptr += iq_size + 3;
1296             }
1297             break;
1298
1299         default:
1300             print_err("Compression method %d is not supported!", compMeth);
1301             return (XRAN_STATUS_INVALID_PARAM);
1302     }
1303
1304     /* Update the length of extension with padding */
1305     parm_size = (total_len + sizeof(union xran_cp_radioapp_section_ext11))
1306                     % XRAN_SECTIONEXT_ALIGN;
1307     if(parm_size) {
1308         /* Add padding */
1309         parm_size = XRAN_SECTIONEXT_ALIGN - parm_size;
1310         memcpy(ptr, zeropad, parm_size);
1311         total_len += parm_size;
1312         }
1313
1314     return (total_len);
1315 }
1316
1317
1318 static void free_ext_buf(void *addr, void *opaque)
1319 {
1320     /* free is not required for external buffers */
1321 }
1322
1323 /*
1324  * extbuf_start : the pointer of the external buffer,
1325  *          It can be the start address of whole external buffer.
1326  * extbuf_len : total length of the external buffer (available space to access)
1327  *          To use the length of the data, offset2data should be zero.
1328  * */
1329 int32_t xran_cp_attach_ext_buf(struct rte_mbuf *mbuf,
1330                 uint8_t *extbuf_start, uint16_t extbuf_len,
1331                 struct rte_mbuf_ext_shared_info *shinfo)
1332 {
1333     rte_iova_t extbuf_iova;
1334
1335
1336     if(unlikely(mbuf == NULL)) {
1337         print_err("Invalid mbuf to attach!\n");
1338         return (XRAN_STATUS_INVALID_PARAM);
1339         }
1340
1341     /* Update shared information */
1342     shinfo->free_cb = free_ext_buf;
1343     rte_mbuf_ext_refcnt_update(shinfo, 1);
1344
1345     extbuf_iova = rte_malloc_virt2iova(extbuf_start);
1346     if(unlikely(extbuf_iova == RTE_BAD_IOVA)) {
1347         print_err("Failed rte_mem_virt2iova RTE_BAD_IOVA \n");
1348         return (XRAN_STATUS_INVALID_PARAM);
1349         }
1350
1351     rte_pktmbuf_attach_extbuf(mbuf, extbuf_start, extbuf_iova, extbuf_len, shinfo);
1352
1353     rte_pktmbuf_reset_headroom(mbuf);
1354
1355     return (XRAN_STATUS_SUCCESS);
1356 }
1357
1358
1359 static int32_t
1360 xran_prepare_sectionext_11(struct rte_mbuf *mbuf,
1361                 struct xran_sectionext11_info *params, int32_t last_flag)
1362 {
1363     union xran_cp_radioapp_section_ext11 *ext11;
1364     int32_t total_len;
1365
1366
1367 #if (XRAN_STRICT_PARM_CHECK)
1368     if(unlikely((params->numSetBFWs == 0)
1369             || (params->numSetBFWs > XRAN_MAX_SET_BFWS))) {
1370         print_err("Invalid number of the set of PRB bundle [%d]", params->numSetBFWs);
1371         return (XRAN_STATUS_INVALID_PARAM);
1372         }
1373 #endif
1374
1375     /* BFWs are already present in the external buffer, just update the length */
1376     total_len = sizeof(union xran_cp_radioapp_section_ext11) + params->totalBfwIQLen;
1377
1378     ext11 = (union xran_cp_radioapp_section_ext11 *)rte_pktmbuf_append(mbuf, total_len);
1379     if(ext11 == NULL) {
1380         print_err("Fail to allocate the space for section extension 11 [%d]", total_len);
1381         return (XRAN_STATUS_RESOURCE);
1382         }
1383
1384     /*ext11->all_bits.extType      = XRAN_CP_SECTIONEXTCMD_11;
1385     ext11->all_bits.ef           = last_flag;
1386     ext11->all_bits.reserved     = 0;
1387     ext11->all_bits.RAD          = params->RAD;
1388     ext11->all_bits.disableBFWs  = params->disableBFWs;
1389     ext11->all_bits.numBundPrb   = params->numBundPrb;
1390     ext11->all_bits.bfwCompMeth  = params->bfwCompMeth;
1391     ext11->all_bits.bfwIqWidth   = XRAN_CONVERT_BFWIQWIDTH(params->bfwIqWidth);
1392
1393     ext11->all_bits.extLen        = total_len / XRAN_SECTIONEXT_ALIGN;*/
1394
1395     ext11->data_field.data_field1 = (last_flag << xran_cp_radioapp_sec_ext11_bitfield_Ef)
1396                                   | (XRAN_CP_SECTIONEXTCMD_11 << xran_cp_radioapp_sec_ext11_bitfield_ExtType)
1397                                   | ((total_len / XRAN_SECTIONEXT_ALIGN) << xran_cp_radioapp_sec_ext11_bitfield_ExtLen)
1398                                   | (params->disableBFWs << xran_cp_radioapp_sec_ext11_bitfield_DisBFWs)
1399                                   | (params->RAD << xran_cp_radioapp_sec_ext11_bitfield_RAD);
1400     ext11->data_field.data_field2 = ((XRAN_CONVERT_BFWIQWIDTH(params->bfwIqWidth)) << xran_cp_radioapp_sec_ext11_bitfield_BFWIQWidth)
1401                                   | (params->bfwCompMeth << xran_cp_radioapp_sec_ext11_bitfield_BFWCompMeth)
1402                                   | params->numBundPrb;
1403
1404     *(uint32_t *)ext11 = rte_cpu_to_be_32(*(uint32_t*)ext11);
1405
1406     return (total_len);
1407 }
1408
1409 /**
1410  * @brief add section extension to C-Plane packet
1411  *
1412  * @param mbuf
1413  *  A pointer to the packet buffer
1414  * @param params
1415  *  A porinter to the information to generate a C-Plane packet
1416  * @return
1417  *  XRAN_STATUS_SUCCESS on success
1418  *  XRAN_STATUS_INVALID_PARM
1419  *  XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
1420  */
1421 int32_t xran_append_section_extensions(struct rte_mbuf *mbuf, struct xran_section_gen_info *params)
1422 {
1423     int32_t i;
1424     uint32_t totalen;
1425     int32_t last_flag;
1426     int32_t ext_size;
1427
1428     if(unlikely(params->exDataSize > XRAN_MAX_NUM_EXTENSIONS)) {
1429         print_err("Invalid total number of extensions - %d", params->exDataSize);
1430         return (XRAN_STATUS_INVALID_PARAM);
1431     }
1432
1433     totalen = 0;
1434
1435     print_dbg("params->exDataSize %d\n", params->exDataSize);
1436     for(i=0; i < params->exDataSize; i++) {
1437         if(params->exData[i].data == NULL) {
1438             print_err("Invalid parameter - extension data %d is NULL", i);
1439             continue;
1440         }
1441
1442         last_flag = (params->exDataSize == (i+1))?0:1;
1443
1444         switch(params->exData[i].type) {
1445             case XRAN_CP_SECTIONEXTCMD_1:
1446                 ext_size = xran_append_sectionext_1(mbuf, params->exData[i].data, last_flag);
1447                 break;
1448             case XRAN_CP_SECTIONEXTCMD_2:
1449                 ext_size = xran_prepare_sectionext_2(mbuf, params->exData[i].data, last_flag);
1450                 break;
1451             case XRAN_CP_SECTIONEXTCMD_3:
1452                 ext_size = xran_prepare_sectionext_3(mbuf, params->exData[i].data, last_flag);
1453                 break;
1454             case XRAN_CP_SECTIONEXTCMD_4:
1455                 ext_size = xran_prepare_sectionext_4(mbuf, params->exData[i].data, last_flag);
1456                 break;
1457             case XRAN_CP_SECTIONEXTCMD_5:
1458                 ext_size = xran_prepare_sectionext_5(mbuf, params->exData[i].data, last_flag);
1459                 break;
1460             case XRAN_CP_SECTIONEXTCMD_6:
1461                 ext_size = xran_prepare_sectionext_6(mbuf, params->exData[i].data, last_flag);
1462                 break;
1463             case XRAN_CP_SECTIONEXTCMD_9:
1464                 ext_size = xran_prepare_sectionext_9(mbuf, params->exData[i].data, last_flag);
1465                 break;
1466             case XRAN_CP_SECTIONEXTCMD_10:
1467                 ext_size = xran_prepare_sectionext_10(mbuf, params->exData[i].data, last_flag);
1468                 break;
1469             case XRAN_CP_SECTIONEXTCMD_11:
1470                 ext_size = xran_prepare_sectionext_11(mbuf, params->exData[i].data, last_flag);
1471                 break;
1472             default:
1473                 print_err("Extension Type %d is not supported!", params->exData[i].type);
1474                 ext_size = 0;
1475             }
1476
1477         if(ext_size == XRAN_STATUS_RESOURCE) {
1478             break;
1479         }
1480
1481         totalen += ext_size;
1482     }
1483
1484     return (totalen);
1485 }
1486
1487
1488 /**
1489  * @brief Fill the section body of type 0 in C-Plane packet
1490  *
1491  * @param section
1492  *  A pointer to the section in the packet buffer
1493  * @param params
1494  *  A porinter to the information to generate a C-Plane packet
1495  * @return
1496  *  XRAN_STATUS_SUCCESS on success
1497  *  XRAN_STATUS_INVALID_PARM if the number of symbol is invalid
1498  */
1499 static int32_t
1500 xran_prepare_section0(struct xran_cp_radioapp_section0 *section, struct xran_section_gen_info *params)
1501 {
1502 #if (XRAN_STRICT_PARM_CHECK)
1503     if(unlikely(params->info->numSymbol > XRAN_SYMBOLNUMBER_MAX)) {
1504         print_err("Invalid number of Symbols - %d", params->info->numSymbol);
1505         return (XRAN_STATUS_INVALID_PARAM);
1506         }
1507 #endif
1508
1509     section->hdr.u1.common.sectionId      = params->info->id;
1510     section->hdr.u1.common.rb             = params->info->rb;
1511     section->hdr.u1.common.symInc         = params->info->symInc;
1512     section->hdr.u1.common.startPrbc      = params->info->startPrbc;
1513     section->hdr.u1.common.numPrbc        = XRAN_CONVERT_NUMPRBC(params->info->numPrbc);
1514
1515     section->hdr.u.s0.reMask    = params->info->reMask;
1516     section->hdr.u.s0.numSymbol = params->info->numSymbol;
1517     section->hdr.u.s0.reserved  = 0;
1518
1519     // for network byte order
1520     *((uint64_t *)section) = rte_cpu_to_be_64(*((uint64_t *)section));
1521
1522     return (XRAN_STATUS_SUCCESS);
1523 }
1524
1525 /**
1526  * @brief Fill the section header of type 0 in C-Plane packet
1527  *
1528  * @param s0hdr
1529  *  A pointer to the section header in the packet buffer
1530  * @param params
1531  *  A porinter to the information to generate a C-Plane packet
1532  * @return
1533  *  XRAN_STATUS_SUCCESS always
1534  */
1535 static int32_t
1536 xran_prepare_section0_hdr( struct xran_cp_radioapp_section0_header *s0hdr,
1537                 struct xran_cp_gen_params *params)
1538 {
1539     s0hdr->timeOffset               = rte_cpu_to_be_16(params->hdr.timeOffset);
1540     s0hdr->frameStructure.fftSize   = params->hdr.fftSize;
1541     s0hdr->frameStructure.uScs      = params->hdr.scs;
1542     s0hdr->cpLength                 = rte_cpu_to_be_16(params->hdr.cpLength);
1543     s0hdr->reserved                 = 0;
1544
1545     return (XRAN_STATUS_SUCCESS);
1546 }
1547
1548 /**
1549  * @brief Fill the section body of type 1 in C-Plane packet
1550  *  Extension is not supported.
1551  *
1552  * @param section
1553  *  A pointer to the section header in the packet buffer
1554  * @param params
1555  *  A porinter to the information to generate a C-Plane packet
1556  * @return
1557  *  XRAN_STATUS_SUCCESS on success
1558  *  XRAN_STATUS_INVALID_PARM if the number of symbol is invalid
1559  */
1560 static int32_t
1561 xran_prepare_section1(struct xran_cp_radioapp_section1 *section,
1562                 struct xran_section_gen_info *params)
1563 {
1564 #if (XRAN_STRICT_PARM_CHECK)
1565     if(unlikely(params->info->numSymbol > XRAN_SYMBOLNUMBER_MAX)) {
1566         print_err("Invalid number of Symbols - %d", params->info->numSymbol);
1567         return (XRAN_STATUS_INVALID_PARAM);
1568         }
1569 #endif
1570
1571     /*section->hdr.u1.common.sectionId      = params->info->id;
1572     section->hdr.u1.common.rb             = params->info->rb;
1573     section->hdr.u1.common.symInc         = params->info->symInc;
1574     section->hdr.u1.common.startPrbc      = params->info->startPrbc;
1575     section->hdr.u1.common.numPrbc        = XRAN_CONVERT_NUMPRBC(params->info->numPrbc);
1576
1577     section->hdr.u.s1.reMask    = params->info->reMask;
1578     section->hdr.u.s1.numSymbol = params->info->numSymbol;
1579     section->hdr.u.s1.beamId    = params->info->beamId;
1580     section->hdr.u.s1.ef        = params->info->ef;*/
1581
1582     section->hdr.u.first_4byte   = (params->info->reMask << xran_cp_radioapp_sec_hdr_sc_ReMask)
1583                                  | (params->info->numSymbol << xran_cp_radioapp_sec_hdr_sc_NumSym)
1584                                  | (params->info->ef << xran_cp_radioapp_sec_hdr_sc_Ef)
1585                                  | (params->info->beamId << xran_cp_radioapp_sec_hdr_sc_BeamID);
1586     section->hdr.u1.second_4byte = (params->info->id << xran_cp_radioapp_sec_hdr_c_SecId)
1587                                  | (params->info->rb << xran_cp_radioapp_sec_hdr_c_RB)
1588                                  | (params->info->symInc << xran_cp_radioapp_sec_hdr_c_SymInc)
1589                                  | (params->info->startPrbc << xran_cp_radioapp_sec_hdr_c_StartPrbc)
1590                                  | ((XRAN_CONVERT_NUMPRBC(params->info->numPrbc)) << xran_cp_radioapp_sec_hdr_c_NumPrbc);
1591
1592     // for network byte order
1593     *((uint64_t *)section) = rte_cpu_to_be_64(*((uint64_t *)section));
1594
1595     return (XRAN_STATUS_SUCCESS);
1596 }
1597
1598 /**
1599  * @brief Fill the section header of type 1 in C-Plane packet
1600  *
1601  * @param s1hdr
1602  *  A pointer to the section header in the packet buffer
1603  * @param params
1604  *  A porinter to the information to generate a C-Plane packet
1605  * @return
1606  *  XRAN_STATUS_SUCCESS always
1607  */
1608 static int32_t
1609 xran_prepare_section1_hdr(struct xran_cp_radioapp_section1_header *s1hdr,
1610                 struct xran_cp_gen_params *params)
1611 {
1612     s1hdr->udComp.udIqWidth         = params->hdr.iqWidth;
1613     s1hdr->udComp.udCompMeth        = params->hdr.compMeth;
1614     s1hdr->reserved                 = 0;
1615
1616     return (XRAN_STATUS_SUCCESS);
1617 }
1618
1619 /**
1620  * @brief Fill the section body of type 3 in C-Plane packet
1621  *  Extension is not supported.
1622  *
1623  * @param section
1624  *  A pointer to the section header in the packet buffer
1625  * @param params
1626  *  A porinter to the information to generate a C-Plane packet
1627  * @return
1628  *  XRAN_STATUS_SUCCESS on success
1629  *  XRAN_STATUS_INVALID_PARM if the number of symbol is invalid
1630  */
1631 static int32_t
1632 xran_prepare_section3(struct xran_cp_radioapp_section3 *section,
1633                 struct xran_section_gen_info *params)
1634 {
1635 #if (XRAN_STRICT_PARM_CHECK)
1636     if(unlikely(params->info->numSymbol > XRAN_SYMBOLNUMBER_MAX)) {
1637         print_err("Invalid number of Symbols - %d", params->info->numSymbol);
1638         return (XRAN_STATUS_INVALID_PARAM);
1639         }
1640 #endif
1641
1642     /*section->hdr.u1.common.sectionId      = params->info->id;
1643     section->hdr.u1.common.rb             = params->info->rb;
1644     section->hdr.u1.common.symInc         = params->info->symInc;
1645     section->hdr.u1.common.startPrbc      = params->info->startPrbc;
1646     section->hdr.u1.common.numPrbc        = XRAN_CONVERT_NUMPRBC(params->info->numPrbc);
1647
1648     section->hdr.u.s3.reMask    = params->info->reMask;
1649     section->hdr.u.s3.numSymbol = params->info->numSymbol;
1650     section->hdr.u.s3.beamId    = params->info->beamId;
1651     section->hdr.u.s3.ef        = params->info->ef;*/
1652
1653     section->hdr.u.first_4byte   = (params->info->reMask << xran_cp_radioapp_sec_hdr_sc_ReMask)
1654                                  | (params->info->numSymbol << xran_cp_radioapp_sec_hdr_sc_NumSym)
1655                                  | (params->info->ef << xran_cp_radioapp_sec_hdr_sc_Ef)
1656                                  | (params->info->beamId << xran_cp_radioapp_sec_hdr_sc_BeamID);
1657     section->hdr.u1.second_4byte = (params->info->id << xran_cp_radioapp_sec_hdr_c_SecId)
1658                                  | (params->info->rb << xran_cp_radioapp_sec_hdr_c_RB)
1659                                  | (params->info->symInc << xran_cp_radioapp_sec_hdr_c_SymInc)
1660                                  | (params->info->startPrbc << xran_cp_radioapp_sec_hdr_c_StartPrbc)
1661                                  | ((XRAN_CONVERT_NUMPRBC(params->info->numPrbc)) << xran_cp_radioapp_sec_hdr_c_NumPrbc);
1662
1663     section->freqOffset         = rte_cpu_to_be_32(params->info->freqOffset)>>8;
1664     section->reserved           = 0;
1665
1666     /* for network byte order (header, 8 bytes) */
1667     *((uint64_t *)section) = rte_cpu_to_be_64(*((uint64_t *)section));
1668
1669     return (XRAN_STATUS_SUCCESS);
1670 }
1671
1672 /**
1673  * @brief Fill the section header of type 3 in C-Plane packet
1674  *
1675  * @param s3hdr
1676  *  A pointer to the section header in the packet buffer
1677  * @param params
1678  *  A porinter to the information to generate a C-Plane packet
1679  * @return
1680  *  XRAN_STATUS_SUCCESS always
1681  */
1682 static int32_t
1683 xran_prepare_section3_hdr(struct xran_cp_radioapp_section3_header *s3hdr,
1684                 struct xran_cp_gen_params *params)
1685 {
1686     s3hdr->timeOffset               = rte_cpu_to_be_16(params->hdr.timeOffset);
1687     s3hdr->frameStructure.fftSize   = params->hdr.fftSize;
1688     s3hdr->frameStructure.uScs      = params->hdr.scs;
1689     s3hdr->cpLength                 = rte_cpu_to_be_16(params->hdr.cpLength);
1690     s3hdr->udComp.udIqWidth         = params->hdr.iqWidth;
1691     s3hdr->udComp.udCompMeth        = params->hdr.compMeth;
1692
1693     return (XRAN_STATUS_SUCCESS);
1694 }
1695
1696 /**
1697  * @brief add sections to C-Plane packet
1698  *  Section type 1 and 3 are supported.
1699  *
1700  * @param mbuf
1701  *  A pointer to the packet buffer
1702  * @param params
1703  *  A porinter to the information to generate a C-Plane packet
1704  * @return
1705  *  XRAN_STATUS_SUCCESS on success
1706  *  XRAN_STATUS_INVALID_PARM if section type is not 1 or 3, or handler is NULL
1707  *  XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
1708  */
1709 int32_t
1710 xran_append_control_section(struct rte_mbuf *mbuf, struct xran_cp_gen_params *params,uint16_t start_sect_id)
1711 {
1712     int32_t i, ret;
1713   uint32_t totalen;
1714   void *section;
1715     int32_t section_size;
1716     int32_t (*xran_prepare_section_func)(void *section, void *params);
1717
1718     totalen = 0;
1719     switch(params->sectionType) {
1720         case XRAN_CP_SECTIONTYPE_0: /* Unused RB or Symbols in DL or UL, not supportted */
1721             section_size                = sizeof(struct xran_cp_radioapp_section0);
1722             xran_prepare_section_func   = (int32_t (*)(void *, void *))xran_prepare_section0;
1723             break;
1724
1725         case XRAN_CP_SECTIONTYPE_1: /* Most DL/UL Radio Channels */
1726             section_size                = sizeof(struct xran_cp_radioapp_section1);
1727             xran_prepare_section_func   = (int32_t (*)(void *, void *))xran_prepare_section1;
1728             break;
1729
1730         case XRAN_CP_SECTIONTYPE_3: /* PRACH and Mixed-numerology Channels */
1731             section_size                = sizeof(struct xran_cp_radioapp_section3);
1732             xran_prepare_section_func   = (int32_t (*)(void *, void *))xran_prepare_section3;
1733             break;
1734
1735         case XRAN_CP_SECTIONTYPE_5: /* UE scheduling information, not supported */
1736         case XRAN_CP_SECTIONTYPE_6: /* Channel Information, not supported */
1737         case XRAN_CP_SECTIONTYPE_7: /* LAA, not supported */
1738         default:
1739             section_size                = 0;
1740             xran_prepare_section_func   = NULL;
1741             print_err("Section Type %d is not supported!", params->sectionType);
1742             return (XRAN_STATUS_INVALID_PARAM);
1743         }
1744
1745     if(unlikely(xran_prepare_section_func == NULL)) {
1746        print_err("Section Type %d is not supported!", params->sectionType);
1747        return (XRAN_STATUS_INVALID_PARAM);
1748     }
1749
1750     for(i=start_sect_id; i < (start_sect_id + params->numSections); i++) {
1751         section = rte_pktmbuf_append(mbuf, section_size);
1752         if(section == NULL) {
1753             print_err("Fail to allocate the space for section[%d]!", i);
1754             return (XRAN_STATUS_RESOURCE);
1755         }
1756         print_dbg("%s %d ef %d\n", __FUNCTION__, i, params->sections[i].info->ef);
1757         ret = xran_prepare_section_func((void *)section,
1758                             (void *)&params->sections[i]);
1759         if(ret < 0){
1760             print_err("%s %d\n", __FUNCTION__, ret);
1761             return (ret);
1762         }
1763         totalen += section_size;
1764
1765         if(params->sections[i].info->ef) {
1766             print_dbg("sections[%d].info.ef %d exDataSize %d  type %d\n", i, params->sections[i].info->ef,
1767                 params->sections[i].exDataSize, params->sections[i].exData[0].type);
1768             ret = xran_append_section_extensions(mbuf, &params->sections[i]);
1769             if(ret < 0)
1770                 return (ret);
1771             totalen += ret;
1772        }
1773     }
1774
1775     return (totalen);
1776 }
1777
1778 /**
1779  * @brief fill the information of a radio application header in a C-Plane packet
1780  *
1781  * @param apphdr
1782  *  A pointer to the application header in the packet buffer
1783  * @param params
1784  *  A porinter to the information to generate a C-Plane packet
1785  * @return
1786  *  XRAN_STATUS_SUCCESS on success
1787  *  XRAN_STATUS_INVALID_PARM if direction, slot index or symbold index is invalid
1788  */
1789 static inline int32_t
1790 xran_prepare_radioapp_common_header(struct xran_cp_radioapp_common_header *apphdr,
1791                 struct xran_cp_gen_params *params)
1792 {
1793
1794 #if (XRAN_STRICT_PARM_CHECK)
1795     if(unlikely(params->dir != XRAN_DIR_DL && params->dir != XRAN_DIR_UL)) {
1796         print_err("Invalid direction!");
1797         return (XRAN_STATUS_INVALID_PARAM);
1798         }
1799     if(unlikely(params->hdr.slotId > XRAN_SLOTID_MAX)) {
1800         print_err("Invalid Slot ID!");
1801         return (XRAN_STATUS_INVALID_PARAM);
1802         }
1803     if(unlikely(params->hdr.startSymId > XRAN_SYMBOLNUMBER_MAX)) {
1804         print_err("Invalid Symbol ID!");
1805         return (XRAN_STATUS_INVALID_PARAM);
1806         }
1807 #endif
1808
1809     /*apphdr->field.all_bits = XRAN_PAYLOAD_VER << 28;
1810     apphdr->field.dataDirection   = params->dir;
1811     //apphdr->field.payloadVer      = XRAN_PAYLOAD_VER;
1812     apphdr->field.filterIndex     = params->hdr.filterIdx;
1813     apphdr->field.frameId         = params->hdr.frameId;
1814     apphdr->field.subframeId      = params->hdr.subframeId;
1815     apphdr->field.slotId          = xran_slotid_convert(params->hdr.slotId, 0);
1816     apphdr->field.startSymbolId   = params->hdr.startSymId;*/
1817
1818     apphdr->field.all_bits   = (params->dir << xran_cp_radioapp_cmn_hdr_bitwidth_DataDir)
1819                              | (XRAN_PAYLOAD_VER << xran_cp_radioapp_cmn_hdr_bitwidth_PayLoadVer)
1820                              | (params->hdr.filterIdx << xran_cp_radioapp_cmn_hdr_bitwidth_FilterIdex)
1821                              | (params->hdr.frameId << xran_cp_radioapp_cmn_hdr_bitwidth_FrameId)
1822                              | (params->hdr.subframeId << xran_cp_radioapp_cmn_hdr_bitwidth_SubFrameId)
1823                              | (xran_slotid_convert(params->hdr.slotId, 0) << xran_cp_radioapp_cmn_hdr_bitwidth_SlotId)
1824                              | (params->hdr.startSymId << xran_cp_radioapp_cmn_hdr_bitwidth_StartSymId);
1825
1826     apphdr->numOfSections   = params->numSections;
1827     apphdr->sectionType     = params->sectionType;
1828
1829     /* radio app header has common parts of 4bytes for all section types */
1830     //*((uint32_t *)apphdr) = rte_cpu_to_be_32(*((uint32_t *)apphdr));
1831     *((uint32_t *)apphdr) = rte_cpu_to_be_32(apphdr->field.all_bits);
1832     return (XRAN_STATUS_SUCCESS);
1833 }
1834
1835 /**
1836  * @brief add a radio application header in a C-Plane packet
1837  *
1838  * @param mbuf
1839  *  A pointer to the packet buffer
1840  * @param params
1841  *  A porinter to the information to generate a C-Plane packet
1842  * @return
1843  *  The length of added section (>0) on success
1844  *  XRAN_STATUS_INVALID_PARM if section type is invalid, or handler is NULL
1845  *  XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
1846  */
1847 int32_t
1848 xran_append_radioapp_header(struct rte_mbuf *mbuf, struct xran_cp_gen_params *params)
1849 {
1850   int32_t ret;
1851   uint32_t totalen;
1852   struct xran_cp_radioapp_common_header *apphdr;
1853   int32_t (*xran_prepare_radioapp_section_hdr_func)(void *hdr, void *params);
1854
1855
1856 #if (XRAN_STRICT_PARM_CHECK)
1857     if(unlikely(params->sectionType >= XRAN_CP_SECTIONTYPE_MAX)) {
1858         print_err("Invalid Section Type - %d", params->sectionType);
1859         return (XRAN_STATUS_INVALID_PARAM);
1860         }
1861 #endif
1862
1863     switch(params->sectionType) {
1864         case XRAN_CP_SECTIONTYPE_0: /* Unused RB or Symbols in DL or UL, not supportted */
1865             xran_prepare_radioapp_section_hdr_func = (int32_t (*)(void *, void*))xran_prepare_section0_hdr;
1866             totalen = sizeof(struct xran_cp_radioapp_section0_header);
1867             break;
1868
1869         case XRAN_CP_SECTIONTYPE_1: /* Most DL/UL Radio Channels */
1870             xran_prepare_radioapp_section_hdr_func = (int32_t (*)(void *, void*))xran_prepare_section1_hdr;
1871             totalen = sizeof(struct xran_cp_radioapp_section1_header);
1872             break;
1873
1874         case XRAN_CP_SECTIONTYPE_3: /* PRACH and Mixed-numerology Channels */
1875             xran_prepare_radioapp_section_hdr_func = (int32_t (*)(void *, void*))xran_prepare_section3_hdr;
1876             totalen = sizeof(struct xran_cp_radioapp_section3_header);
1877             break;
1878
1879         case XRAN_CP_SECTIONTYPE_5: /* UE scheduling information, not supported */
1880         case XRAN_CP_SECTIONTYPE_6: /* Channel Information, not supported */
1881         case XRAN_CP_SECTIONTYPE_7: /* LAA, not supported */
1882         default:
1883             print_err("Section Type %d is not supported!", params->sectionType);
1884             xran_prepare_radioapp_section_hdr_func = NULL;
1885             totalen = 0;
1886             return (XRAN_STATUS_INVALID_PARAM);
1887         }
1888
1889     apphdr = (struct xran_cp_radioapp_common_header *)rte_pktmbuf_append(mbuf, totalen);
1890     if(unlikely(apphdr == NULL)) {
1891         print_err("Fail to reserve the space for radio application header!");
1892         return (XRAN_STATUS_RESOURCE);
1893         }
1894
1895     ret = xran_prepare_radioapp_common_header(apphdr, params);
1896     if(unlikely(ret < 0)) {
1897         return (ret);
1898         }
1899
1900     if(likely(xran_prepare_radioapp_section_hdr_func)) {
1901         totalen += xran_prepare_radioapp_section_hdr_func(apphdr, params);
1902         }
1903     else {
1904         print_err("xran_prepare_radioapp_section_hdr_func is NULL!");
1905         return (XRAN_STATUS_INVALID_PARAM);
1906         }
1907
1908     return (totalen);
1909 }
1910
1911 /**
1912  * @brief Create a C-Plane packet
1913  *  Transport layer fragmentation is not supported.
1914  *
1915  * @ingroup xran_cp_pkt
1916  *
1917  * @param mbuf
1918  *  A pointer to the packet buffer
1919  * @param params
1920  *  A porinter to the information to generate a C-Plane packet
1921  * @param CC_ID
1922  *  Component Carrier ID for this C-Plane message
1923  * @param Ant_ID
1924  *  Antenna ID(RU Port ID) for this C-Plane message
1925  * @param seq_id
1926  *  Sequence ID for this C-Plane message
1927  * @return
1928  *  XRAN_STATUS_SUCCESS on success
1929  *  XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
1930  *  XRAN_STATUS_INVALID_PARM if section type is invalid
1931  */
1932 int32_t
1933 xran_prepare_ctrl_pkt(struct rte_mbuf *mbuf,
1934                         struct xran_cp_gen_params *params,
1935                         uint8_t CC_ID, uint8_t Ant_ID,
1936                         uint8_t seq_id,
1937                         uint16_t start_sect_id)
1938 {
1939     int32_t ret;
1940   uint32_t payloadlen;
1941   struct xran_ecpri_hdr *ecpri_hdr;
1942
1943     payloadlen = xran_build_ecpri_hdr(mbuf, CC_ID, Ant_ID, seq_id, &ecpri_hdr);
1944
1945     ret = xran_append_radioapp_header(mbuf, params);
1946     if(ret < 0) {
1947         print_err("%s %d\n", __FUNCTION__, ret);
1948         return (ret);
1949     }
1950     payloadlen += ret;
1951
1952     ret = xran_append_control_section(mbuf, params,start_sect_id);
1953     if(ret < 0) {
1954         print_err("%s %d\n", __FUNCTION__, ret);
1955         return (ret);
1956     }
1957     payloadlen += ret;
1958
1959     /* set payload length */
1960     ecpri_hdr->cmnhdr.bits.ecpri_payl_size = rte_cpu_to_be_16(payloadlen);
1961
1962     return (XRAN_STATUS_SUCCESS);
1963 }
1964
1965 ///////////////////////////////////////
1966 // for RU emulation
1967 int32_t
1968 xran_parse_section_ext1(void *ext, struct xran_sectionext1_info *extinfo)
1969 {
1970     int32_t len;
1971     int32_t total_len;
1972   struct xran_cp_radioapp_section_ext1 *ext1;
1973   uint8_t *data;
1974     int32_t parm_size = 0, iq_size, iq_size_bytes;
1975     int32_t N;
1976   void *pHandle;
1977
1978     pHandle = NULL;
1979     N = xran_get_conf_num_bfweights(pHandle);
1980     extinfo->bfwNumber = N;
1981
1982     ext1 = (struct xran_cp_radioapp_section_ext1 *)ext;
1983     data = (uint8_t *)ext;
1984
1985     len = 0;
1986     total_len = ext1->extLen * XRAN_SECTIONEXT_ALIGN;   /* from word to byte */
1987
1988     extinfo->bfwCompMeth    = ext1->bfwCompMeth;
1989     extinfo->bfwIqWidth     = (ext1->bfwIqWidth==0)?16:ext1->bfwIqWidth;
1990
1991     len     += sizeof(struct xran_cp_radioapp_section_ext1);
1992     data    += sizeof(struct xran_cp_radioapp_section_ext1);
1993     extinfo->p_bfwIQ =  (int8_t*)(data);
1994
1995     switch(ext1->bfwCompMeth) {
1996         case XRAN_BFWCOMPMETHOD_NONE:
1997             parm_size = 0;
1998             break;
1999
2000         case XRAN_BFWCOMPMETHOD_BLKFLOAT:
2001             parm_size = 1;
2002             extinfo->bfwCompParam.exponent = *data & 0x0f;
2003             break;
2004
2005         case XRAN_BFWCOMPMETHOD_BLKSCALE:
2006             parm_size = 1;
2007             extinfo->bfwCompParam.blockScaler = *data;
2008             break;
2009
2010         case XRAN_BFWCOMPMETHOD_ULAW:
2011             parm_size = 1;
2012             extinfo->bfwCompParam.compBitWidthShift = *data;
2013             break;
2014
2015         case XRAN_BFWCOMPMETHOD_BEAMSPACE:
2016             parm_size = N>>3; if(N%8) parm_size++; parm_size *= 8;
2017             memcpy(data, extinfo->bfwCompParam.activeBeamspaceCoeffMask, parm_size);
2018             break;
2019
2020         default:
2021             print_err("Invalid BfComp method - %d", ext1->bfwCompMeth);
2022             parm_size = 0;
2023         }
2024
2025     len     += parm_size;
2026     data    += parm_size;
2027     iq_size_bytes = parm_size;
2028
2029     /* Get BF weights */
2030     iq_size = N * extinfo->bfwIqWidth * 2;  // total in bits
2031     parm_size = iq_size>>3;                 // total in bytes (/8)
2032     if(iq_size%8) parm_size++;              // round up
2033     iq_size_bytes += parm_size;
2034
2035     //memcpy(data, extinfo->p_bfwIQ, parm_size);
2036     extinfo->bfwIQ_sz = iq_size_bytes;
2037
2038     len += parm_size;
2039
2040     parm_size = len % XRAN_SECTIONEXT_ALIGN;
2041     if(parm_size)
2042         len += (XRAN_SECTIONEXT_ALIGN - parm_size);
2043
2044     if(len != total_len) {
2045         print_err("The size of extension 1 is not correct! [%d:%d]", len, total_len);
2046     }
2047
2048     return (total_len);
2049 }
2050
2051 int32_t
2052 xran_parse_section_ext2(void *ext, struct xran_sectionext2_info *extinfo)
2053 {
2054     int32_t len;
2055     int32_t total_len;
2056   struct xran_cp_radioapp_section_ext2 *ext2;
2057   uint8_t *data;
2058     int32_t parm_size;
2059   uint32_t val;
2060     int32_t val_size;
2061
2062     ext2 = (struct xran_cp_radioapp_section_ext2 *)ext;
2063     data = (uint8_t *)ext;
2064     *(uint32_t *)ext2 = rte_be_to_cpu_32(*(uint32_t *)ext2);
2065
2066     len = 0;
2067     total_len = ext2->extLen * XRAN_SECTIONEXT_ALIGN;   /* from word to byte */
2068
2069     parm_size = sizeof(struct xran_cp_radioapp_section_ext2);
2070
2071     extinfo->bfAzPtWidth    = ext2->bfAzPtWidth;
2072     extinfo->bfZePtWidth    = ext2->bfZePtWidth;
2073     extinfo->bfAz3ddWidth   = ext2->bfAz3ddWidth;
2074     extinfo->bfZe3ddWidth   = ext2->bfZe3ddWidth;
2075
2076     if(ext2->bfaCompResv0 || ext2->bfaCompResv1)
2077         print_err("Incorrect reserved field - %d, %d", ext2->bfaCompResv0, ext2->bfaCompResv1);
2078
2079     data    += parm_size;
2080     len     += parm_size;
2081
2082     val_size = (extinfo->bfAzPtWidth ? extinfo->bfAzPtWidth+1 : 0)
2083                 + (extinfo->bfZePtWidth ? extinfo->bfZePtWidth+1 : 0)
2084                 + (extinfo->bfAz3ddWidth ? extinfo->bfAz3ddWidth+1 : 0)
2085                 + (extinfo->bfZe3ddWidth ? extinfo->bfZe3ddWidth+ 1: 0);
2086     if(val_size) {
2087         val = rte_be_to_cpu_32(*(uint32_t *)data);
2088         val >>= (32 - val_size);
2089
2090         if(extinfo->bfZe3ddWidth) {
2091             extinfo->bfZe3dd    = val & bitmask[extinfo->bfZe3ddWidth];
2092             val >>= (extinfo->bfZe3ddWidth + 1);
2093             }
2094         if(extinfo->bfAz3ddWidth) {
2095             extinfo->bfAz3dd    = val & bitmask[extinfo->bfAz3ddWidth];
2096             val >>= (extinfo->bfAz3ddWidth + 1);
2097             }
2098         if(extinfo->bfZePtWidth) {
2099             extinfo->bfZePt     = val & bitmask[extinfo->bfZePtWidth];
2100             val >>= (extinfo->bfZePtWidth + 1);
2101             }
2102         if(extinfo->bfAzPtWidth) {
2103             extinfo->bfAzPt     = val & bitmask[extinfo->bfAzPtWidth];
2104             val >>= (extinfo->bfAzPtWidth + 1);
2105             }
2106         }
2107
2108     parm_size = val_size/8;
2109     if(val_size%8) parm_size += 1;
2110
2111     data    += parm_size;
2112     len     += parm_size;
2113
2114     extinfo->bfAzSI = (*data >> 3) & 0x07;
2115     extinfo->bfZeSI = *data & 0x07;
2116
2117     data++;
2118     len++;
2119
2120     parm_size = len % XRAN_SECTIONEXT_ALIGN;
2121     if(parm_size)
2122         len += (XRAN_SECTIONEXT_ALIGN - parm_size);
2123
2124     if(len != total_len) {
2125         print_err("The size of extension 2 is not correct! [%d:%d]", len, total_len);
2126         }
2127
2128     return (total_len);
2129
2130 }
2131
2132 int32_t
2133 xran_parse_section_ext3(void *ext, struct xran_sectionext3_info *extinfo)
2134 {
2135     int32_t len;
2136     int32_t total_len;
2137
2138     total_len = 0;
2139     len = *((uint8_t *)ext + 1);
2140
2141     switch(len) {
2142         case 1:     /* non-first data layer */
2143             {
2144             union xran_cp_radioapp_section_ext3_non_first *ext3_nf;
2145
2146             ext3_nf = (union xran_cp_radioapp_section_ext3_non_first *)ext;
2147             *(uint32_t *)ext3_nf = rte_be_to_cpu_32(*(uint32_t *)ext3_nf);
2148
2149             total_len = ext3_nf->all_bits.extLen * XRAN_SECTIONEXT_ALIGN;    /* from word to byte */
2150
2151             extinfo->codebookIdx= ext3_nf->all_bits.codebookIndex;
2152             extinfo->layerId    = ext3_nf->all_bits.layerId;
2153             extinfo->numLayers  = ext3_nf->all_bits.numLayers;
2154             }
2155             break;
2156
2157         case 3:     /* first data layer with two antenna */
2158         case 4:     /* first data layer with four antenna */
2159             {
2160             union xran_cp_radioapp_section_ext3_first *ext3_f;
2161             uint16_t *beamid;
2162
2163             ext3_f = (union xran_cp_radioapp_section_ext3_first *)ext;
2164             *(uint64_t *)ext3_f = rte_be_to_cpu_64(*(uint64_t *)ext3_f);
2165
2166             total_len = ext3_f->all_bits.extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
2167
2168             extinfo->codebookIdx= ext3_f->all_bits.codebookIndex;
2169             extinfo->layerId    = ext3_f->all_bits.layerId;
2170             extinfo->numLayers  = ext3_f->all_bits.numLayers;
2171             extinfo->txScheme   = ext3_f->all_bits.txScheme;
2172             extinfo->crsReMask  = ext3_f->all_bits.crsReMask;
2173             extinfo->crsShift   = ext3_f->all_bits.crsShift;
2174             extinfo->crsSymNum  = ext3_f->all_bits.crsSymNum;
2175
2176             /* beam IDs are stored from 10th octet */
2177             beamid = (uint16_t *)((uint8_t *)ext + 10);
2178
2179             extinfo->beamIdAP1  = rte_be_to_cpu_16(*beamid++);
2180             if(len == 4) {
2181                 extinfo->beamIdAP2  = rte_be_to_cpu_16(*beamid++);
2182                 extinfo->beamIdAP3  = rte_be_to_cpu_16(*beamid);
2183                 extinfo->numAntPort = 4;
2184                 }
2185             else {
2186                 extinfo->numAntPort = 2;
2187                 }
2188             }
2189             break;
2190
2191         default:
2192             print_err("Invalid length of extension 3 - %d", len);
2193         }
2194
2195     return (total_len);
2196 }
2197
2198 int32_t
2199 xran_parse_section_ext4(void *ext, struct xran_sectionext4_info *extinfo)
2200 {
2201     int32_t len;
2202   struct xran_cp_radioapp_section_ext4 *ext4;
2203     int32_t total_len;
2204
2205     ext4 = (struct xran_cp_radioapp_section_ext4 *)ext;
2206
2207     *(uint32_t *)ext4 = rte_be_to_cpu_32(*(uint32_t *)ext4);
2208
2209     len = 0;
2210     total_len = ext4->extLen * XRAN_SECTIONEXT_ALIGN;   /* from word to byte */
2211
2212     extinfo->modCompScaler  = ext4->modCompScaler;
2213     extinfo->csf            = ext4->csf;
2214
2215     len += sizeof(struct xran_cp_radioapp_section_ext4);
2216     if(len != total_len) {
2217         print_err("The size of extension 4 is not correct! [%d:%d]", len, total_len);
2218         }
2219
2220     return (total_len);
2221 }
2222
2223 int32_t
2224 xran_parse_section_ext5(void *ext,
2225                 struct xran_sectionext5_info *extinfo)
2226 {
2227   struct xran_cp_radioapp_section_ext_hdr *ext_hdr;
2228   struct xran_cp_radioapp_section_ext5 ext5;
2229     int32_t parm_size;
2230     int32_t total_len;
2231   uint8_t *data;
2232   uint16_t i;
2233
2234     ext_hdr = (struct xran_cp_radioapp_section_ext_hdr *)ext;
2235     *(uint16_t *)ext_hdr = rte_be_to_cpu_16(*(uint16_t *)ext_hdr);
2236
2237     total_len = ext_hdr->extLen * XRAN_SECTIONEXT_ALIGN;   /* from word to byte */
2238
2239     /* one set has 3.5 bytes, so enforcing double to do integer calculation */
2240     parm_size = ((total_len-sizeof(struct xran_cp_radioapp_section_ext_hdr))*2) / 7;
2241
2242     if(parm_size > XRAN_MAX_MODCOMP_ADDPARMS) {
2243         print_err("Exceeds maximum number of parameters - %d", parm_size);
2244         parm_size = XRAN_MAX_MODCOMP_ADDPARMS;
2245     }
2246
2247     data = (uint8_t *)(ext_hdr + 1);
2248
2249     i = 0;
2250     while(i < parm_size) {
2251         // For odd number set, more data can be copied
2252         *((uint64_t *)&ext5) = rte_be_to_cpu_64(*((uint64_t *)data));
2253
2254         extinfo->mc[i].mcScaleOffset    = ext5.mcScaleOffset1;
2255         extinfo->mc[i].csf              = ext5.csf1;
2256         extinfo->mc[i].mcScaleReMask    = ext5.mcScaleReMask1;
2257         i++;
2258
2259         extinfo->mc[i].mcScaleOffset    = ext5.mcScaleOffset2;
2260         extinfo->mc[i].csf              = ext5.csf2;
2261         extinfo->mc[i].mcScaleReMask    = ext5.mcScaleReMask2;
2262         i++;
2263
2264         data += sizeof(struct xran_cp_radioapp_section_ext5);
2265         }
2266
2267     /* check the values of last set
2268      * due to alignment, it cannot be identified by the length that 3 or 4, 11 or 12 and etc
2269      * don't check mcScaleOffset might not be zero (some part is out of zero-padding) */
2270     i--;
2271     if(i < XRAN_MAX_MODCOMP_ADDPARMS) {
2272         if(extinfo->mc[i].csf == 0 && extinfo->mc[i].mcScaleReMask == 0)
2273             extinfo->num_sets = i;
2274         else
2275             extinfo->num_sets = i+1;
2276     }else {
2277         print_err("Maximum total number %d is not correct!", i);
2278     }
2279
2280     return (total_len);
2281 }
2282
2283 int32_t
2284 xran_parse_section_ext6(void *ext,
2285                 struct xran_sectionext6_info *extinfo)
2286 {
2287     int32_t len;
2288     union xran_cp_radioapp_section_ext6 *ext6;
2289     int32_t total_len;
2290
2291     ext6 = (union xran_cp_radioapp_section_ext6 *)ext;
2292     *(uint64_t *)ext6 = rte_be_to_cpu_64(*(uint64_t *)ext6);
2293
2294     total_len = ext6->all_bits.extLen * XRAN_SECTIONEXT_ALIGN;   /* from word to byte */
2295
2296     extinfo->rbgSize    = ext6->all_bits.rbgSize;
2297     extinfo->rbgMask    = ext6->all_bits.rbgMask;
2298     extinfo->symbolMask = ext6->all_bits.symbolMask;
2299
2300     len = sizeof(union xran_cp_radioapp_section_ext6);
2301     if(len != total_len) {
2302         print_err("The size of extension 6 is not correct! [%d:%d]", len, total_len);
2303         }
2304
2305     return (total_len);
2306 }
2307
2308 int32_t
2309 xran_parse_section_ext9(void *ext,
2310                  struct xran_sectionext9_info *extinfo, struct xran_cp_recv_params *result)
2311 {
2312     int32_t len = 0;
2313     int32_t total_len;
2314     int8_t dssSlot = 0;
2315     int8_t presumed_technology = -1;
2316     struct xran_cp_radioapp_section_ext9 *ext9;
2317
2318     ext9 = (struct xran_cp_radioapp_section_ext9 *)ext;
2319     *(uint32_t *)ext9 = rte_be_to_cpu_32(*(uint32_t *)ext9);
2320
2321     total_len = ext9->extLen * XRAN_SECTIONEXT_ALIGN;
2322     
2323     if(result) {
2324         dssSlot = result->tti % result->dssPeriod;
2325         presumed_technology = result->technology_arr[dssSlot];
2326     } else {
2327         print_err("\nTechnology verification parameters not received");
2328         // return (-1);
2329     }
2330
2331     if(presumed_technology != ext9->technology) {
2332         print_err("\nWrong technology recieved! [%d,%d]", presumed_technology, ext9->technology);
2333         // return (-1);
2334     }
2335
2336     extinfo->technology = ext9->technology;
2337     extinfo->reserved = ext9->reserved;
2338
2339     len += sizeof(struct xran_cp_radioapp_section_ext9);
2340     if(len != total_len) {
2341         print_err("\nThe size of extension 9 is not correct! [%d:%d]", len, total_len);
2342     }
2343
2344     return (total_len);
2345 }
2346
2347
2348 int32_t
2349 xran_parse_section_ext10(void *ext,
2350                 struct xran_sectionext10_info *extinfo)
2351 {
2352     int32_t len, padding;
2353     int32_t i;
2354     union xran_cp_radioapp_section_ext10 *ext10;
2355     int32_t total_len;
2356     uint16_t *ptr;
2357
2358     ext10 = (union xran_cp_radioapp_section_ext10 *)ext;
2359
2360     total_len = ext10->all_bits.extLen * XRAN_SECTIONEXT_ALIGN;   /* from word to byte */
2361
2362     extinfo->numPortc   = ext10->all_bits.numPortc;
2363     extinfo->beamGrpType= ext10->all_bits.beamGroupType;
2364
2365     len = sizeof(union xran_cp_radioapp_section_ext10);
2366     if(ext10->all_bits.beamGroupType == XRAN_BEAMGT_VECTORLIST) {
2367         len += extinfo->numPortc * 2 - 1;
2368         padding = len % XRAN_SECTIONEXT_ALIGN;
2369         if(padding) {
2370             padding = XRAN_SECTIONEXT_ALIGN - padding;
2371             len += padding;
2372             }
2373
2374         ptr = (uint16_t *)&ext10->all_bits.reserved;
2375         for(i=0; i < extinfo->numPortc; i++)
2376             extinfo->beamID[i] = rte_be_to_cpu_16(ptr[i]);
2377         }
2378
2379     if(len != total_len) {
2380         print_err("The size of extension 10 is not correct! [%d:%d]", len, total_len);
2381         }
2382
2383     return (total_len);
2384 }
2385
2386 int32_t
2387 xran_parse_section_ext11(void *ext,
2388                          struct xran_sectionext11_recv_info *extinfo)
2389 {
2390     int32_t len;
2391     int32_t total_len;
2392     union xran_cp_radioapp_section_ext11 *ext11;
2393     uint8_t *data;
2394     int32_t parm_size, iq_size;
2395     int32_t N;
2396     void *pHandle;
2397
2398     pHandle = NULL;
2399     N = xran_get_conf_num_bfweights(pHandle);
2400
2401     ext11 = (union xran_cp_radioapp_section_ext11 *)ext;
2402     data = (uint8_t *)ext;
2403
2404     *(uint32_t *)ext11 = rte_cpu_to_be_32(*(uint32_t*)ext11);
2405     total_len = ext11->all_bits.extLen * XRAN_SECTIONEXT_ALIGN;   /* from word to byte */
2406
2407     extinfo->RAD            = ext11->all_bits.RAD;
2408     extinfo->disableBFWs    = ext11->all_bits.disableBFWs;
2409     extinfo->numBundPrb     = ext11->all_bits.numBundPrb;
2410     extinfo->bfwCompMeth    = ext11->all_bits.bfwCompMeth;
2411     extinfo->bfwIqWidth     = (ext11->all_bits.bfwIqWidth==0)?16:ext11->all_bits.bfwIqWidth;
2412
2413     len     = sizeof(union xran_cp_radioapp_section_ext11);
2414     data    += sizeof(union xran_cp_radioapp_section_ext11);
2415
2416     extinfo->numSetBFWs = 0;
2417     while((len+4) < total_len) {    /* adding 4 is to consider zero pads */
2418         /* Get bfwCompParam */
2419         switch(ext11->all_bits.bfwCompMeth) {
2420             case XRAN_BFWCOMPMETHOD_NONE:
2421                 parm_size = 0;
2422                 break;
2423
2424             case XRAN_BFWCOMPMETHOD_BLKFLOAT:
2425                 parm_size = 1;
2426                 extinfo->bundInfo[extinfo->numSetBFWs].bfwCompParam.exponent = *data & 0x0f;
2427                 break;
2428 #if 0   /* Not supported */
2429             case XRAN_BFWCOMPMETHOD_BLKSCALE:
2430                 parm_size = 1;
2431                 extinfo->bundInfo[extinfo->numSetBFWs].bfwCompParam.blockScaler = *data;
2432                 break;
2433
2434             case XRAN_BFWCOMPMETHOD_ULAW:
2435                 parm_size = 1;
2436                 extinfo->bundInfo[extinfo->numSetBFWs].bfwCompParam.compBitWidthShift = *data;
2437                 break;
2438
2439             case XRAN_BFWCOMPMETHOD_BEAMSPACE:
2440                 parm_size = N>>3; if(N%8) parm_size++; parm_size *= 8;
2441                 memcpy(data, extinfo->bundInfo[extinfo->numSetBFWs].bfwCompParam.activeBeamspaceCoeffMask, parm_size);
2442                 break;
2443 #endif
2444             default:
2445                 print_err("Invalid BfComp method - %d", ext11->all_bits.bfwCompMeth);
2446                 parm_size = 0;
2447             }
2448         len     += parm_size;
2449         data    += parm_size;
2450
2451         /* Get beam ID */
2452         extinfo->bundInfo[extinfo->numSetBFWs].beamId = rte_be_to_cpu_16(*((int16_t *)data));
2453         len     += sizeof(int16_t);
2454         data    += sizeof(int16_t);
2455
2456         /* Get BF weights */
2457         iq_size = N * extinfo->bfwIqWidth * 2;  // total in bits
2458         parm_size = iq_size>>3;                 // total in bytes (/8)
2459         if(iq_size%8) parm_size++;              // round up
2460
2461         if(extinfo->bundInfo[extinfo->numSetBFWs].pBFWs) {
2462             memcpy(extinfo->bundInfo[extinfo->numSetBFWs].pBFWs, data, parm_size);
2463             }
2464         extinfo->bundInfo[extinfo->numSetBFWs].BFWSize  = parm_size;
2465
2466         len     += parm_size;
2467         data    += parm_size;
2468         extinfo->numSetBFWs++;
2469         }
2470
2471     parm_size = len % XRAN_SECTIONEXT_ALIGN;
2472     if(parm_size)
2473         len += (XRAN_SECTIONEXT_ALIGN - parm_size);
2474
2475     if(len != total_len) {
2476         //print_err("The size of extension 11 is not correct! [%d:%d]", len, total_len);
2477         }
2478
2479     return (total_len);
2480 }
2481
2482 int32_t
2483 xran_parse_section_extension(struct rte_mbuf *mbuf,
2484                              void *ext, struct xran_cp_recv_params *result,
2485                              int32_t section_idx)
2486 {
2487     struct xran_section_recv_info *section = &result->sections[section_idx];
2488     int32_t total_len, len, numext;
2489   uint8_t *ptr;
2490     int32_t flag_last;
2491     int32_t ext_type;
2492     int32_t i;
2493
2494     total_len = 0;
2495     ptr = (uint8_t *)ext;
2496
2497     numext = 0;
2498
2499     flag_last = 1;
2500     i = 0;
2501     while(flag_last) {
2502         /* check ef */
2503         flag_last = (*ptr & 0x80);
2504
2505         ext_type = *ptr & 0x7f;
2506         section->exts[numext].type = ext_type;
2507         switch(ext_type) {
2508             case XRAN_CP_SECTIONEXTCMD_1:
2509                 result->ext1count++;
2510                 len = xran_parse_section_ext1(ptr, &section->exts[numext].u.ext1);
2511                 break;
2512             case XRAN_CP_SECTIONEXTCMD_2:
2513                 len = xran_parse_section_ext2(ptr, &section->exts[numext].u.ext2);
2514                 break;
2515             case XRAN_CP_SECTIONEXTCMD_3:
2516                 len = xran_parse_section_ext3(ptr, &section->exts[numext].u.ext3);
2517                 break;
2518             case XRAN_CP_SECTIONEXTCMD_4:
2519                 len = xran_parse_section_ext4(ptr, &section->exts[numext].u.ext4);
2520                 break;
2521             case XRAN_CP_SECTIONEXTCMD_5:
2522                 len = xran_parse_section_ext5(ptr, &section->exts[numext].u.ext5);
2523                 break;
2524             case XRAN_CP_SECTIONEXTCMD_6:
2525                 len = xran_parse_section_ext6(ptr, &section->exts[numext].u.ext6);
2526                 break;
2527             case XRAN_CP_SECTIONEXTCMD_9:
2528                 len = xran_parse_section_ext9(ptr, &section->exts[numext].u.ext9, result);
2529                 break;
2530             case XRAN_CP_SECTIONEXTCMD_10:
2531                 len = xran_parse_section_ext10(ptr, &section->exts[numext].u.ext10);
2532                 break;
2533             case XRAN_CP_SECTIONEXTCMD_11:
2534                 len = xran_parse_section_ext11(ptr, &section->exts[numext].u.ext11);
2535                 break;
2536
2537             default:
2538                 print_err("Extension %d is not supported!", ext_type);
2539                 len = 0;
2540             }
2541
2542         section->exts[numext].size = len;
2543         ptr += len; total_len += len;
2544
2545         i++;
2546         if(++numext < XRAN_MAX_NUM_EXTENSIONS) continue;
2547
2548         /* exceeds maximum number of extensions */
2549         break;
2550         }
2551
2552     section->numExts = numext;
2553
2554     return (total_len);
2555 }
2556
2557 /**
2558  * @brief Parse a C-Plane packet (for RU emulation)
2559  *  Transport layer fragmentation is not supported.
2560  *
2561  * @ingroup xran_cp_pkt
2562  *
2563  * @param mbuf
2564  *  The pointer of the packet buffer to be parsed
2565  * @param params
2566  *  The pointer of structure to store the information of parsed packet
2567  * @param eaxc
2568  *  The pointer of sturcture to store the decomposed information of ecpriRtcid/ecpriPcid
2569  * @return
2570  *  XRAN_STATUS_SUCCESS on success
2571  *  XRAN_STATUS_INVALID_PACKET if failed to parse the packet
2572  */
2573 int32_t
2574 xran_parse_cp_pkt(struct rte_mbuf *mbuf,
2575                     struct xran_cp_recv_params *result,
2576                     struct xran_recv_packet_info *pkt_info, void* handle, uint32_t *mb_free)
2577 {
2578   struct xran_ecpri_hdr *ecpri_hdr;
2579   struct xran_cp_radioapp_common_header *apphdr;
2580     struct xran_common_counters* pCnt = NULL;
2581     struct xran_prb_map *pRbMap = NULL;
2582     struct xran_prb_map *pRbMap_desc = NULL;
2583     struct xran_prb_elm * prbMapElm = NULL;
2584     struct rte_mbuf *mb = NULL;
2585     int32_t i, j, ret, extlen;
2586     int tti = 0,interval = 0;
2587     uint8_t idx = 0, ctx_id = 0;
2588     struct xran_device_ctx * p_dev_ctx = NULL;
2589     struct xran_device_ctx * p_xran_dev_ctx = (struct xran_device_ctx *)handle;
2590     if(unlikely(p_xran_dev_ctx == NULL)){
2591         print_err("p_xran_dev_ctx is NULL\n");
2592         return XRAN_STATUS_INVALID_PARAM;
2593     }
2594     p_dev_ctx = xran_dev_get_ctx();
2595     ret = xran_parse_ecpri_hdr(mbuf, &ecpri_hdr, pkt_info);
2596     struct xran_eaxc_info eaxc = pkt_info->eaxc;
2597     struct xran_section_info *info = NULL;
2598     if(ret < 0 && ecpri_hdr == NULL)
2599         return (XRAN_STATUS_INVALID_PACKET);
2600
2601     /* Process radio header. */
2602     apphdr = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_ecpri_hdr));
2603     if(unlikely(apphdr == NULL)) {
2604         print_err("Invalid packet - radio app header!");
2605         return (XRAN_STATUS_INVALID_PACKET);
2606         }
2607
2608     *((uint32_t *)apphdr) = rte_be_to_cpu_32(*((uint32_t *)apphdr));
2609
2610     if(apphdr->field.payloadVer != XRAN_PAYLOAD_VER) {
2611         print_err("Invalid Payload version - %d", apphdr->field.payloadVer);
2612         ret = XRAN_STATUS_INVALID_PACKET;
2613         }
2614
2615     result->dir             = apphdr->field.dataDirection;
2616     result->hdr.filterIdx   = apphdr->field.filterIndex;
2617     result->hdr.frameId     = apphdr->field.frameId;
2618     result->hdr.subframeId  = apphdr->field.subframeId;
2619     result->hdr.slotId      = apphdr->field.slotId;
2620     result->hdr.startSymId  = apphdr->field.startSymbolId;
2621     result->sectionType     = apphdr->sectionType;
2622     result->numSections     = apphdr->numOfSections;
2623     result->ext1count       = 0;
2624
2625     interval = p_xran_dev_ctx->interval_us_local;
2626     tti = apphdr->field.frameId * SLOTS_PER_SYSTEMFRAME(interval) + apphdr->field.subframeId * SLOTNUM_PER_SUBFRAME(interval) + apphdr->field.slotId;
2627     result->tti = tti;
2628     ctx_id      = tti % XRAN_MAX_SECTIONDB_CTX;
2629 #if 0
2630     printf("[CP%5d] eAxC[%d:%d:%02d:%02d] %s seq[%03d-%03d-%d] sec[%d-%d] frame[%3d-%2d-%2d] sym%02d\n",
2631         pkt_info->payload_len,
2632         pkt_info->eaxc.cuPortId, pkt_info->eaxc.bandSectorId,
2633         pkt_info->eaxc.ccId, pkt_info->eaxc.ruPortId,
2634         result->dir?"DL":"UL",
2635         pkt_info->seq_id, pkt_info->subseq_id, pkt_info->ebit,
2636         result->sectionType, result->numSections,
2637         result->hdr.frameId, result->hdr.subframeId, result->hdr.slotId,
2638         result->hdr.startSymId
2639         );
2640 #endif
2641
2642     switch(apphdr->sectionType) {
2643         case XRAN_CP_SECTIONTYPE_0: // Unused RB or Symbols in DL or UL, not supportted
2644             {
2645             struct xran_cp_radioapp_section0_header *hdr;
2646             struct xran_cp_radioapp_section0 *section;
2647
2648                 hdr = (struct xran_cp_radioapp_section0_header*)apphdr;
2649
2650                 result->hdr.fftSize     = rte_be_to_cpu_16(hdr->timeOffset);
2651                 result->hdr.scs         = hdr->frameStructure.fftSize;
2652                 result->hdr.timeOffset  = hdr->frameStructure.uScs;
2653                 result->hdr.cpLength    = rte_be_to_cpu_16(hdr->cpLength);
2654                 //hdr->reserved;    /* should be zero */
2655
2656                 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section0_header));
2657                 if(section == NULL) {
2658                     print_err("Invalid packet: section type0 - radio app hedaer!");
2659                     return (XRAN_STATUS_INVALID_PACKET);
2660                     }
2661                 for(i=0; i<result->numSections; i++) {
2662                     *((uint64_t *)section) = rte_be_to_cpu_64(*((uint64_t *)section));
2663
2664                     result->sections[i].info.type       = apphdr->sectionType;
2665                     result->sections[i].info.id         = section->hdr.u1.common.sectionId;
2666                     result->sections[i].info.rb         = section->hdr.u1.common.rb;
2667                     result->sections[i].info.symInc     = section->hdr.u1.common.symInc;
2668                     result->sections[i].info.startPrbc  = section->hdr.u1.common.startPrbc;
2669                     result->sections[i].info.numPrbc    = section->hdr.u1.common.numPrbc,
2670                     result->sections[i].info.numSymbol  = section->hdr.u.s0.numSymbol;
2671                     result->sections[i].info.reMask     = section->hdr.u.s0.reMask;
2672                     //section->hdr.u.s0.reserved;   /* should be zero */
2673
2674                     section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section0));
2675                     if(section == NULL) {
2676                         print_err("Invalid packet: section type0 - number of section [%d:%d]!",
2677                                     result->numSections, i);
2678                         result->numSections = i;
2679                         ret = XRAN_STATUS_INVALID_PACKET;
2680                         break;
2681                         }
2682                     }
2683             }
2684             break;
2685
2686         case XRAN_CP_SECTIONTYPE_1: // Most DL/UL Radio Channels
2687             {
2688             struct xran_cp_radioapp_section1_header *hdr;
2689             struct xran_cp_radioapp_section1 *section;
2690
2691                 hdr = (struct xran_cp_radioapp_section1_header*)apphdr;
2692
2693                 result->hdr.iqWidth     = hdr->udComp.udIqWidth;
2694                 result->hdr.compMeth    = hdr->udComp.udCompMeth;
2695
2696                 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section1_header));
2697                 if(unlikely(section == NULL)) {
2698                     print_err("Invalid packet: section type1 - radio app hedaer!");
2699                     return (XRAN_STATUS_INVALID_PACKET);
2700                     }
2701
2702                 for(i=0; i<result->numSections; i++) {
2703                     *((uint64_t *)section) = rte_be_to_cpu_64(*((uint64_t *)section));
2704
2705                     result->sections[i].info.type       = apphdr->sectionType;
2706                     result->sections[i].info.id         = section->hdr.u1.common.sectionId;
2707                     result->sections[i].info.rb         = section->hdr.u1.common.rb;
2708                     result->sections[i].info.symInc     = section->hdr.u1.common.symInc;
2709                     result->sections[i].info.startPrbc  = section->hdr.u1.common.startPrbc;
2710                     result->sections[i].info.numPrbc    = section->hdr.u1.common.numPrbc,
2711                     result->sections[i].info.numSymbol  = section->hdr.u.s1.numSymbol;
2712                     result->sections[i].info.reMask     = section->hdr.u.s1.reMask;
2713                     result->sections[i].info.beamId     = section->hdr.u.s1.beamId;
2714                     result->sections[i].info.ef         = section->hdr.u.s1.ef;
2715
2716                     section = (void *)rte_pktmbuf_adj(mbuf,
2717                                     sizeof(struct xran_cp_radioapp_section1));
2718                     if(unlikely(section == NULL)) {
2719                         print_err("Invalid packet: section type1 - number of section [%d:%d]!",
2720                                     result->numSections, i);
2721                         result->numSections = i;
2722                         ret = XRAN_STATUS_INVALID_PACKET;
2723                         break;
2724                         }
2725                     if (eaxc.ruPortId < p_xran_dev_ctx->srs_cfg.eAxC_offset)
2726                     {
2727                         struct xran_flat_buffer *pBuffer = NULL;
2728                         if(result->dir == 1)
2729                             pBuffer = p_xran_dev_ctx->sFHCpRxPrbMapBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][eaxc.ccId][eaxc.ruPortId].sBufferList.pBuffers;
2730                         else if(result->dir == 0)
2731                             pBuffer = p_xran_dev_ctx->sFHCpTxPrbMapBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][eaxc.ccId][eaxc.ruPortId].sBufferList.pBuffers;
2732                         if(pBuffer)
2733                             pRbMap = (struct xran_prb_map *)pBuffer->pData;
2734                         if(p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][eaxc.ccId][eaxc.ruPortId].sBufferList.pBuffers)
2735                             pRbMap_desc = (struct xran_prb_map *) p_xran_dev_ctx->sFrontHaulTxPrbMapBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][eaxc.ccId][eaxc.ruPortId].sBufferList.pBuffers->pData;
2736
2737                         if(i == 0){
2738                             if((pRbMap_desc != NULL) && (pRbMap_desc->nPrbElm <= p_xran_dev_ctx->sectiondb_elm[ctx_id][result->dir][eaxc.ccId][eaxc.ruPortId])){
2739                                 p_xran_dev_ctx->sectiondb_elm[ctx_id][result->dir][eaxc.ccId][eaxc.ruPortId]=0;
2740                                 xran_cp_reset_section_info(handle, result->dir, eaxc.ccId, eaxc.ruPortId, ctx_id);
2741                             }
2742                             idx = p_xran_dev_ctx->sectiondb_elm[ctx_id][result->dir][eaxc.ccId][eaxc.ruPortId]++;  
2743
2744                             if(p_dev_ctx){
2745                                 result->numSetBFW = p_dev_ctx->numSetBFWs_arr[idx];
2746                                 if(likely(pRbMap!=NULL)){
2747                                     prbMapElm = &pRbMap->prbMap[idx];
2748                                     mb = prbMapElm->bf_weight.p_ext_start;
2749                                     if(mb){
2750                                         rte_pktmbuf_free(mb);
2751                                     }
2752                                     prbMapElm->bf_weight.p_ext_start = mbuf;
2753                                     prbMapElm->bf_weight.p_ext_section = (void *)section;
2754                                     *mb_free = MBUF_KEEP;
2755                                 }
2756                             }
2757                         }
2758                         info = xran_cp_get_section_info_ptr(handle, result->dir, eaxc.ccId, eaxc.ruPortId, ctx_id);
2759                         if(likely(info != NULL))
2760                         {
2761                             info->prbElemBegin = (i == 0 ) ?  1 : 0;
2762                             info->prbElemEnd   = (i == (result->numSections -1)) ?  1 : 0;
2763                             info->ef           = result->sections[i].info.ef;
2764                             info->startPrbc    = result->sections[i].info.startPrbc;
2765                             info->numPrbc      = result->sections[i].info.numPrbc;
2766                             info->type         = result->sections[i].info.type;
2767                             info->startSymId   = result->hdr.startSymId;
2768                             info->iqWidth      = result->hdr.iqWidth;
2769                             info->compMeth     = result->hdr.compMeth;
2770                             info->id           = result->sections[i].info.id;
2771                             info->rb           = XRAN_RBIND_EVERY;
2772                             info->numSymbol    = result->sections[i].info.numSymbol;
2773                             info->reMask       = 0xfff;
2774                             info->beamId       = result->sections[i].info.beamId;
2775                             info->symInc       = XRAN_SYMBOLNUMBER_NOTINC;
2776
2777                             int loc_sym=0;
2778                             if(likely(pRbMap_desc != NULL)){
2779                                 prbMapElm = &pRbMap_desc->prbMap[idx];
2780                                 for(loc_sym = 0; loc_sym < XRAN_NUM_OF_SYMBOL_PER_SLOT; loc_sym++)
2781                                 {
2782                                     struct xran_section_desc *p_sec_desc =  &prbMapElm->sec_desc[loc_sym][0];
2783
2784                                     if(likely(p_sec_desc!=NULL))
2785                                     {
2786                                         info->sec_desc[loc_sym].iq_buffer_offset = p_sec_desc->iq_buffer_offset;
2787                                         info->sec_desc[loc_sym].iq_buffer_len    = p_sec_desc->iq_buffer_len;
2788                                         
2789                                         p_sec_desc->section_id   = info->id;
2790                                     }
2791                                     else
2792                                     {
2793                                         print_err("section desc is NULL\n");
2794                                     }
2795                                 } /* for(loc_sym = 0; loc_sym < XRAN_NUM_OF_SYMBOL_PER_SLOT; loc_sym++) */
2796                             }
2797                         }
2798
2799                     if(result->sections[i].info.ef) {
2800                             result->dssPeriod = p_xran_dev_ctx->dssPeriod;
2801                             for( j=0; j< p_xran_dev_ctx->dssPeriod; j++) {
2802                                 result->technology_arr[j] = p_xran_dev_ctx->technology[j];
2803                             }
2804                             extlen = xran_parse_section_extension(mbuf, (void *)section, result, i);
2805                         if(extlen > 0) {
2806                             section = (void *)rte_pktmbuf_adj(mbuf, extlen);
2807                                 if(unlikely(section == NULL)) {
2808                                 print_err("Invalid packet: section type1 - section extension [%d]!", i);
2809                                 ret = XRAN_STATUS_INVALID_PACKET;
2810                                 break;
2811                                 }
2812                             }
2813                         }
2814                     else extlen = 0;
2815                     }
2816                     else if((eaxc.ruPortId >= p_xran_dev_ctx->srs_cfg.eAxC_offset) && p_xran_dev_ctx->fh_cfg.srsEnable){
2817                         int32_t ant_id = ((eaxc.ruPortId - p_xran_dev_ctx->srs_cfg.eAxC_offset) & 0x3F); /*Klocwork fix*/
2818                         if(p_xran_dev_ctx->sFHSrsRxPrbMapBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][eaxc.ccId][ant_id].sBufferList.pBuffers){
2819                             pRbMap_desc = (struct xran_prb_map *) p_xran_dev_ctx->sFHSrsRxPrbMapBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][eaxc.ccId][ant_id].sBufferList.pBuffers->pData;
2820                         }
2821                         if(i == 0){
2822                             if((pRbMap_desc != NULL) && (pRbMap_desc->nPrbElm <= p_xran_dev_ctx->sectiondb_elm[ctx_id][result->dir][eaxc.ccId][eaxc.ruPortId])){
2823                                 p_xran_dev_ctx->sectiondb_elm[ctx_id][result->dir][eaxc.ccId][eaxc.ruPortId]=0;
2824                                 xran_cp_reset_section_info(handle, result->dir, eaxc.ccId, eaxc.ruPortId, ctx_id);
2825                             }
2826                             idx = p_xran_dev_ctx->sectiondb_elm[ctx_id][result->dir][eaxc.ccId][eaxc.ruPortId]++;  
2827                         }
2828                         info = xran_cp_get_section_info_ptr(handle, result->dir, eaxc.ccId, eaxc.ruPortId, ctx_id);
2829                         if(likely(info != NULL))
2830                         {
2831                             info->prbElemBegin = (i == 0 ) ?  1 : 0;
2832                             info->prbElemEnd   = (i == (result->numSections -1)) ?  1 : 0;
2833                             info->ef           = result->sections[i].info.ef;
2834                             info->type         = result->sections[i].info.type;
2835                             info->startSymId   = result->hdr.startSymId;
2836                             info->iqWidth      = result->hdr.iqWidth;
2837                             info->compMeth     = result->hdr.compMeth;
2838                             info->id           = result->sections[i].info.id;
2839                             info->rb           = XRAN_RBIND_EVERY;
2840                             info->numSymbol    = result->sections[i].info.numSymbol;
2841                             info->reMask       = 0xfff;
2842                             info->beamId       = result->sections[i].info.beamId;
2843                             info->symInc       = XRAN_SYMBOLNUMBER_NOTINC;
2844                             int loc_sym=0;
2845                             if(likely(pRbMap_desc != NULL)){
2846                                 prbMapElm = &pRbMap_desc->prbMap[idx];
2847                                 info->startPrbc    = prbMapElm->nRBStart;
2848                                 info->numPrbc      = prbMapElm->nRBSize;
2849
2850                                 struct xran_section_desc *p_sec_desc = NULL;
2851                                 for(loc_sym = 0; loc_sym < XRAN_NUM_OF_SYMBOL_PER_SLOT; loc_sym++)
2852                                 {
2853                                     p_sec_desc =  &prbMapElm->sec_desc[loc_sym][0];
2854
2855                                     if(likely(p_sec_desc!=NULL))
2856                                     {
2857                                         info->sec_desc[loc_sym].iq_buffer_offset = p_sec_desc->iq_buffer_offset;
2858                                         info->sec_desc[loc_sym].iq_buffer_len    = p_sec_desc->iq_buffer_len;                                    
2859                                         p_sec_desc->section_id   = info->id;
2860                                     }
2861                                     else
2862                                     {
2863                                         print_err("section desc is NULL\n");
2864                                     }
2865                                 } /* for(loc_sym = 0; loc_sym < XRAN_NUM_OF_SYMBOL_PER_SLOT; loc_sym++) */
2866                             }
2867                         }
2868                         /*Assuming SRS CP will not have extension, removed the ef flag check and extension processing*/
2869                     }    
2870                 }  
2871                 pCnt = &p_xran_dev_ctx->fh_counters;
2872                 /* SRS should not have extension */
2873                 if(pCnt && (result->sections[0].info.ef) && (result->sections[0].exts[0].type == 1) && (result->numSections != result->numSetBFW) && (result->ext1count != result->numSetBFW)){
2874                     print_err("extension 1 is not Valid! [%d:%d:%d]", result->numSections, result->numSetBFW, result->ext1count);
2875                     pCnt->rx_invalid_ext1_packets++;
2876                 }
2877             }
2878             break;
2879
2880         case XRAN_CP_SECTIONTYPE_3: // PRACH and Mixed-numerology Channels
2881             {
2882             struct xran_cp_radioapp_section3_header *hdr;
2883             struct xran_cp_radioapp_section3 *section;
2884
2885                 hdr = (struct xran_cp_radioapp_section3_header*)apphdr;
2886
2887                 result->hdr.timeOffset  = rte_be_to_cpu_16(hdr->timeOffset);
2888                 result->hdr.scs         = hdr->frameStructure.uScs;
2889                 result->hdr.fftSize     = hdr->frameStructure.fftSize;
2890                 result->hdr.cpLength    = rte_be_to_cpu_16(hdr->cpLength);
2891                 result->hdr.iqWidth     = hdr->udComp.udIqWidth;
2892                 result->hdr.compMeth    = hdr->udComp.udCompMeth;
2893
2894                 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section3_header));
2895                 if(section == NULL) {
2896                     print_err("Invalid packet: section type3 - radio app hedaer!");
2897                     return (XRAN_STATUS_INVALID_PACKET);
2898                     }
2899
2900                 for(i=0; i<result->numSections; i++) {
2901                     *((uint64_t *)section) = rte_be_to_cpu_64(*((uint64_t *)section));
2902
2903                     result->sections[i].info.type       = apphdr->sectionType;
2904                     result->sections[i].info.id         = section->hdr.u1.common.sectionId;
2905                     result->sections[i].info.rb         = section->hdr.u1.common.rb;
2906                     result->sections[i].info.symInc     = section->hdr.u1.common.symInc;
2907                     result->sections[i].info.startPrbc  = section->hdr.u1.common.startPrbc;
2908                     result->sections[i].info.numPrbc    = section->hdr.u1.common.numPrbc,
2909                     result->sections[i].info.numSymbol  = section->hdr.u.s3.numSymbol;
2910                     result->sections[i].info.reMask     = section->hdr.u.s3.reMask;
2911                     result->sections[i].info.beamId     = section->hdr.u.s3.beamId;
2912                     result->sections[i].info.ef         = section->hdr.u.s3.ef;
2913                     result->sections[i].info.freqOffset = ((int32_t)rte_be_to_cpu_32(section->freqOffset))>>8;
2914
2915                     if(section->reserved) {
2916                         print_err("Invalid packet: section type3 - section[%d] reserved[%d]", i, section->reserved);
2917                         ret = XRAN_STATUS_INVALID_PACKET;
2918                         }
2919
2920                     section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section3));
2921                     if(section == NULL) {
2922                         print_err("Invalid packet: section type3 - number of section [%d:%d]!",
2923                                     result->numSections, i);
2924                         result->numSections = i;
2925                         ret = XRAN_STATUS_INVALID_PACKET;
2926                         break;
2927                         }
2928
2929                     if(result->sections[i].info.ef) {
2930                         // parse section extension
2931                         extlen = xran_parse_section_extension(mbuf, (void *)section, result, i);
2932                         if(extlen > 0) {
2933                             section = (void *)rte_pktmbuf_adj(mbuf, extlen);
2934                             if(section == NULL) {
2935                                 print_err("Invalid packet: section type3 - section extension [%d]!", i);
2936                                 ret = XRAN_STATUS_INVALID_PACKET;
2937                                 break;
2938                                 }
2939                             }
2940                         }
2941                     else extlen = 0;
2942                     }
2943             }
2944             break;
2945
2946         case XRAN_CP_SECTIONTYPE_5: // UE scheduling information, not supported
2947         case XRAN_CP_SECTIONTYPE_6: // Channel Information, not supported
2948         case XRAN_CP_SECTIONTYPE_7: // LAA, not supported
2949         default:
2950             ret = XRAN_STATUS_INVALID_PARAM;
2951             print_err("Non-supported Section Type - %d", apphdr->sectionType);
2952         }
2953
2954 #if 0
2955     printf("[CP-%s] [%3d:%2d:%2d] section%d[%d] startSym=%d filterIdx=%X IQwidth=%d CompMeth=%d\n",
2956             result->dir?"DL":"UL",
2957             result->hdr.frameId, result->hdr.subframeId, result->hdr.slotId,
2958             result->sectionType, result->numSections,
2959             result->hdr.startSymId,
2960             result->hdr.filterIdx,
2961             result->hdr.iqWidth, result->hdr.compMeth);
2962
2963     for(i=0; i<result->numSections; i++) {
2964         printf("  || %3d:%04X| rb=%d symInc=%d numSym=%d startPrbc=%02d numPrbc=%d reMask=%03X beamId=%04X freqOffset=%d ef=%d\n",
2965             i, result->sections[i].info.id,
2966             result->sections[i].info.rb,
2967             result->sections[i].info.symInc, result->sections[i].info.numSymbol,
2968             result->sections[i].info.startPrbc, result->sections[i].info.numPrbc,
2969             result->sections[i].info.reMask,
2970             result->sections[i].info.beamId,
2971             result->sections[i].info.freqOffset,
2972             result->sections[i].info.ef);
2973
2974         if(result->sections[i].info.ef) {
2975             for(int32_t j=0; j<result->sections[i].exDataSize; j++) {
2976                 printf("      || %2d : type=%d len=%d\n",
2977                         j, result->sections[i].exData[j].type, result->sections[i].exData[j].len);
2978                 switch(result->sections[i].exData[j].type) {
2979                     case XRAN_CP_SECTIONEXTCMD_1:
2980                         {
2981                         struct xran_sectionext1_info *ext1;
2982                         ext1 = result->sections[i].exData[j].data;
2983                         printf("      ||    bfwNumber=%d bfwIqWidth=%d bfwCompMeth=%d\n",
2984                                 ext1->bfwNumber, ext1->bfwIqWidth, ext1->bfwCompMeth);
2985                         }
2986                         break;
2987                     case XRAN_CP_SECTIONEXTCMD_2:
2988                         {
2989                         struct xran_sectionext2_info *ext2;
2990                         ext2 = result->sections[i].exData[j].data;
2991                         printf("      ||    AzPt=%02x(%d) ZePt=%02x(%d) Az3dd=%02x(%d) Ze3dd=%02x(%d) AzSI=%02x ZeSI=%02x\n",
2992                                 ext2->bfAzPt, ext2->bfAzPtWidth,
2993                                 ext2->bfZePt, ext2->bfZePtWidth,
2994                                 ext2->bfAz3dd, ext2->bfAz3ddWidth,
2995                                 ext2->bfZe3dd, ext2->bfZe3ddWidth,
2996                                 ext2->bfAzSI, ext2->bfZeSI);
2997                         }
2998                         break;
2999                     case XRAN_CP_SECTIONEXTCMD_4:
3000                         {
3001                         struct xran_sectionext4_info *ext4;
3002                         ext4 = result->sections[i].exData[j].data;
3003                         printf("      ||    csf=%d modCompScaler=%d\n",
3004                                 ext4->csf, ext4->modCompScaler);
3005                         }
3006                         break;
3007                     case XRAN_CP_SECTIONEXTCMD_5:
3008                         {
3009                         struct xran_sectionext5_info *ext5;
3010                         ext5 = result->sections[i].exData[j].data;
3011                         printf("      ||    num_sets=%d\n", ext5->num_sets);
3012                         for(int32_t k=0; k<ext5->num_sets; k++) {
3013                             printf("          || %d - csf=%d mcScaleReMask=%04x mcScaleOffset=%04x\n",
3014                                 k, ext5->mc[k].csf,
3015                                 ext5->mc[k].mcScaleReMask, ext5->mc[k].mcScaleOffset);
3016                             }
3017                         }
3018                         break;
3019
3020                     case XRAN_CP_SECTIONEXTCMD_0:
3021                     case XRAN_CP_SECTIONEXTCMD_3:
3022                     default:
3023                         printf("Invalid section extension type!\n");
3024                     }
3025                 }
3026             }
3027         }
3028 #endif
3029
3030     return(ret);
3031 }