1 /******************************************************************************
3 * Copyright (c) 2020 Intel.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 *******************************************************************************/
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.
24 * @ingroup group_lte_source_xran
25 * @author Intel Corporation
28 #include <immintrin.h>
29 #include <rte_branch_prediction.h>
30 #include <rte_malloc.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"
40 PSECTION_DB_TYPE p_sectiondb[XRAN_PORTS_NUM] = {NULL, NULL, NULL, NULL,NULL, NULL, NULL, NULL};
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 };
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)
52 * @ingroup xran_cp_pkt
55 * handle for xRAN interface, currently not being used
57 * XRAN_STATUS_SUCCESS on success
58 * XRAN_STATUS_RESOURCE, if memory is not enough to allocate database area
61 xran_cp_init_sectiondb(void *pHandle)
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;
70 p_dev = (struct xran_device_ctx* )pHandle;
71 xran_port_id = p_dev->xran_port_id;
73 print_err("Invalid pHandle - %p", pHandle);
74 return (XRAN_STATUS_FAIL);
77 if (p_sectiondb[xran_port_id] == NULL){
78 p_sec_db = rte_zmalloc(NULL,sizeof(SECTION_DB_TYPE), 0);
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);
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;
92 print_err("Memory Allocation Failed [port %d sz %ld]\n", xran_port_id, sizeof(struct xran_sectioninfo_db));
93 return (XRAN_STATUS_RESOURCE);
100 print_err("Memory Allocation Failed [port %d sz %ld]\n", xran_port_id, sizeof(SECTION_DB_TYPE));
101 return (XRAN_STATUS_RESOURCE);
104 p_sec_db = p_sectiondb[xran_port_id];
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;
114 return (XRAN_STATUS_SUCCESS);
118 * @brief Release and free section database
120 * @ingroup xran_cp_pkt
123 * handle for xRAN interface, currently not being used
125 * XRAN_STATUS_SUCCESS on success
128 xran_cp_free_sectiondb(void *pHandle)
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;
136 p_dev = (struct xran_device_ctx* )pHandle;
137 xran_port_id = p_dev->xran_port_id;
139 print_err("Invalid pHandle - %p", pHandle);
140 return (XRAN_STATUS_FAIL);
143 if (p_sectiondb[xran_port_id] == NULL){
144 return (XRAN_STATUS_INVALID_PARAM);
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]);
158 p_sectiondb[xran_port_id] = NULL;
161 return (XRAN_STATUS_SUCCESS);
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)
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;
174 p_dev = (struct xran_device_ctx* )pHandle;
175 xran_port_id = p_dev->xran_port_id;
177 print_err("Invalid pHandle - %p", pHandle);
181 if(unlikely(xran_port_id >= XRAN_PORTS_NUM)) {
182 print_err("Invalid Port id - %d", p_dev->xran_port_id);
186 if (p_sectiondb[xran_port_id] == NULL){
187 print_err("p_sectiondb xran_port %d\n", xran_port_id);
190 p_sec_db = p_sectiondb[xran_port_id];
192 if(unlikely(ctx_id >= XRAN_MAX_SECTIONDB_CTX)) {
193 print_err("Invalid Context id - %d", ctx_id);
197 if(unlikely(dir >= XRAN_DIR_MAX)) {
198 print_err("Invalid direction - %d", dir);
202 if(unlikely(cc_id >= XRAN_COMPONENT_CARRIERS_MAX)) {
203 print_err("Invalid CC id - %d", cc_id);
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);
212 ptr = p_sec_db->p_sectiondb_elm[ctx_id][dir][cc_id][ruport_id];
217 static inline struct xran_section_info *
218 xran_get_section_info(struct xran_sectioninfo_db *ptr, uint16_t index)
220 if(unlikely(ptr == NULL))
223 if(unlikely(index > XRAN_MAX_NUM_SECTIONS)) {
224 print_err("Index is out of range - %d", index);
228 return(&(ptr->list[index]));
232 * @brief Add a section information of C-Plane to dabase.
234 * @ingroup xran_cp_pkt
237 * handle for xRAN interface, currently not being used
239 * Direction of C-Plane message for the section to store
241 * CC ID of C-Plane message for the section to store
243 * RU port ID of C-Plane message for the section to store
245 * Context index for the section database
247 * The information of this section to store
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
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)
256 struct xran_sectioninfo_db *ptr;
257 struct xran_section_info *list;
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);
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);
269 list = xran_get_section_info(ptr, ptr->cur_index);
271 memcpy(list, info, sizeof(struct xran_section_info));
274 print_err("Null list in section db\n!");
275 return (XRAN_STATUS_INVALID_PARAM);
280 return (XRAN_STATUS_SUCCESS);
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)
287 struct xran_sectioninfo_db *ptr;
288 struct xran_section_info *list;
290 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
291 if(unlikely(ptr == NULL)) {
295 if(unlikely(ptr->cur_index >= XRAN_MAX_NUM_SECTIONS)) {
296 print_err("No more space to add section information!");
300 list = xran_get_section_info(ptr, ptr->cur_index);
308 print_err("Null list in section db\n!");
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)
320 uint8_t dir, num_sections;
321 struct xran_sectioninfo_db *ptr;
322 struct xran_section_info *list;
325 num_sections = gen_info->numSections;
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);
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);
337 list = xran_get_section_info(ptr, ptr->cur_index);
340 for(i=0; i<num_sections; i++) {
341 memcpy(&list[i], gen_info->sections[i].info, sizeof(struct xran_section_info));
347 print_err("Null list in section db\n!");
348 return (XRAN_STATUS_INVALID_PARAM);
351 return (XRAN_STATUS_SUCCESS);
355 * @brief Find a section information of C-Plane from database
356 * by given information
358 * @ingroup xran_cp_pkt
361 * handle for xRAN interface, currently not being used
363 * The direction of the section to find
365 * The CC ID of the section to find
367 * RU port ID of the section to find
369 * Context index for the section database
371 * The ID of section to find
373 * The pointer of section information if matched section is found
374 * NULL if failed to find matched section
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)
379 struct xran_sectioninfo_db *ptr;
381 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
382 if(unlikely(ptr == NULL))
385 if(section_id > ptr->cur_index || section_id < 0)
387 print_err("No section ID in the list - %d, ptr->cur_index is %d", section_id, ptr->cur_index);
389 return (xran_get_section_info(ptr, section_id));
393 * @brief Iterate each section information of C-Plane
394 * from the database of eAxC by given information
396 * @ingroup xran_cp_pkt
399 * handle for xRAN interface, currently not being used
401 * The direction of the section to find
403 * The CC ID of the section to find
405 * RU port ID of the section to find
407 * Context index for the section database
409 * The pointer to store the position of next entry
411 * The pointer of section information in the list
412 * NULL if reached at the end of the list
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)
418 struct xran_sectioninfo_db *ptr;
420 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
421 if(unlikely(ptr == NULL))
425 if(*next < ptr->cur_index) {
427 return (xran_get_section_info(ptr, index));
430 print_dbg("No more sections in the list");
436 * @brief Get the size of stored entries
437 * for the database of eAxC by given information
439 * @ingroup xran_cp_pkt
442 * handle for xRAN interface, currently not being used
444 * The direction of the section to find
446 * The CC ID of the section to find
448 * RU port ID of the section to find
450 * Context index for the section database
452 * The size of stored entries
453 * -1 if failed to find matched database
456 xran_cp_getsize_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id)
458 struct xran_sectioninfo_db *ptr;
460 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
461 if(unlikely(ptr == NULL))
464 return (ptr->cur_index);
468 * @brief Reset a database of eAxC by given information
470 * @ingroup xran_cp_pkt
473 * handle for xRAN interface, currently not being used
475 * The direction of the section to find
477 * The CC ID of the section to find
479 * RU port ID of the section to find
481 * Context index for the section database
483 * XRAN_STATUS_SUCCESS on success
484 * XRAN_STATUS_INVALID_PARM if failed to find matched database
487 xran_cp_reset_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id)
489 struct xran_sectioninfo_db *ptr;
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);
498 return (XRAN_STATUS_SUCCESS);
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)
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);
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;
522 struct xranlib_compress_request bfp_com_req;
523 struct xranlib_compress_response bfp_com_rsp;
525 memset(&bfp_com_req, 0, sizeof(struct xranlib_compress_request));
526 memset(&bfp_com_rsp, 0, sizeof(struct xranlib_compress_response));
528 print_dbg("%s comp %d\n", __FUNCTION__, bfwCompMeth);
529 print_dbg("bfwNumPerRb %d bfwiqWidth %d\n", bfwNumPerRb, bfwiqWidth);
532 p_ext1_dst_cur = p_ext1_dst;
534 return (XRAN_STATUS_INVALID_PARAM);
536 /* create section for each PRB bundle */
537 for (idxSection = 0; idxSection < numCPSections ; idxSection++) {
538 print_dbg("%s Section %d\n", __FUNCTION__, idxSection);
540 if(total_len >= ext1_dst_len){
541 print_err("p_ext1_dst overflow\n");
542 return XRAN_STATUS_RESOURCE;
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);
552 section_len = sizeof(struct xran_cp_radioapp_section1);
554 p_ext1_dst_cur = p_ext1_dst_cur + section_len;
555 total_len += section_len;
557 parm_size = sizeof(struct xran_cp_radioapp_section_ext1);
558 p_ext1 = (struct xran_cp_radioapp_section_ext1 *)p_ext1_dst_cur;
560 print_err("p_ext1 is null!\n");
561 return (XRAN_STATUS_INVALID_PARAM);
564 cur_ext_len += parm_size;
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);
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);
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;
585 print_dbg("req 0x%08p iqWidth %d\n",bfp_com_req.data_in, bfp_com_req.iqWidth);
587 parm_size = 1; /* (reserved + exponent) as part of bfwCompParam 1 octet */
589 case XRAN_BFWCOMPMETHOD_BLKSCALE:
590 rte_panic("XRAN_BFWCOMPMETHOD_BLKSCALE");
593 case XRAN_BFWCOMPMETHOD_ULAW:
594 rte_panic("XRAN_BFWCOMPMETHOD_ULAW");
597 case XRAN_BFWCOMPMETHOD_BEAMSPACE:
598 rte_panic("XRAN_BFWCOMPMETHOD_BEAMSPACE");
601 case XRAN_BFWCOMPMETHOD_NONE:
603 p_bfw_content = (uint8_t *)(p_ext1+1);
604 /* bfwCompParam is absent for no compression case */
608 if(p_bfw_content == NULL) {
609 print_err("Fail to allocate the space for section extension 1");
610 return (XRAN_STATUS_RESOURCE);
613 bfw_iq_bits = bfwNumPerRb* bfwiqWidth * 2;
615 parm_size += bfw_iq_bits>>3;
619 print_dbg("copy BF W %p -> %p size %d \n", p_bfw_iq_src, p_bfw_content, parm_size);
621 if (p_ext1->bfwCompMeth == XRAN_BFWCOMPMETHOD_NONE){ //5.4.7.1.1
622 memcpy(p_bfw_content, p_bfw_iq_src, parm_size);
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);
628 print_err("compression failed\n");
629 return (XRAN_STATUS_FAIL);
633 p_bfw_content = (uint8_t *)(p_bfw_content + parm_size);
635 cur_ext_len += parm_size;
636 parm_size = cur_ext_len % XRAN_SECTIONEXT_ALIGN;
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);
645 if(cur_ext_len % XRAN_SECTIONEXT_ALIGN)
646 rte_panic("ext1 should be aligned on 4-bytes boundary");
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);
651 /* update for next RB */
652 p_ext1_dst_cur += cur_ext_len;
653 p_bfw_iq_src = p_bfw_iq_src + bfwNumPerRb*2;
655 total_len += cur_ext_len;
656 } /*for(idxSection < numCPSections */
658 print_dbg("total_len %d\n", total_len);
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 ?
667 xran_get_freqoffset(int32_t freqOffset, int32_t scs)
673 xran_append_sectionext_1(struct rte_mbuf *mbuf, struct xran_sectionext1_info *params, int32_t last_flag)
675 int32_t total_len = 0;
677 if(params->bfwIQ_sz) {
678 int8_t *p_dst = (int8_t *)rte_pktmbuf_append(mbuf, params->bfwIQ_sz);
681 print_err("Fail to allocate the space for section extension 1 [%d]", params->bfwIQ_sz);
682 return (XRAN_STATUS_RESOURCE);
685 /* extType1 with all the headers created by xran_cp_populate_section_ext_1() earlier */
686 total_len = params->bfwIQ_sz;
693 xran_prepare_sectionext_2(struct rte_mbuf *mbuf, struct xran_sectionext2_info *params, int32_t last_flag)
695 struct xran_cp_radioapp_section_ext2 *ext2;
699 uint32_t val, shift_val;
700 int32_t val_size, pad_size;
704 parm_size = sizeof(struct xran_cp_radioapp_section_ext2);
705 ext2 = (struct xran_cp_radioapp_section_ext2 *)rte_pktmbuf_append(mbuf, parm_size);
707 print_err("Fail to allocate the space for section extension 2");
708 return (XRAN_STATUS_RESOURCE);
710 total_len += parm_size;
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;
723 if(params->bfAzPtWidth) {
724 val += params->bfAzPt & bitmask[params->bfAzPtWidth];
725 shift_val += 8 - (params->bfAzPtWidth+1);
729 if(params->bfZePtWidth) {
730 val = val << (params->bfZePtWidth+1);
731 val += params->bfZePt & bitmask[params->bfZePtWidth];
732 shift_val += 8 - (params->bfZePtWidth+1);
736 if(params->bfAz3ddWidth) {
737 val = val << (params->bfAz3ddWidth+1);
738 val += params->bfAz3dd & bitmask[params->bfAz3ddWidth];
739 shift_val += 8 - (params->bfAz3ddWidth+1);
743 if(params->bfZe3ddWidth) {
744 val = val << (params->bfZe3ddWidth+1);
745 val += params->bfZe3dd & bitmask[params->bfZe3ddWidth];
746 shift_val += 8 - (params->bfZe3ddWidth+1);
751 val = val << shift_val;
752 val = rte_cpu_to_be_32(val);
755 val_size = 4 - (shift_val/8); /* ceil(total bit/8) */
756 parm_size = val_size + 1; /* additional 1 byte for bfxxSI */
759 total_len += parm_size;
760 pad_size = total_len % XRAN_SECTIONEXT_ALIGN;
762 pad_size = XRAN_SECTIONEXT_ALIGN - pad_size;
763 parm_size += pad_size;
764 total_len += pad_size;
767 data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
769 print_err("Fail to allocate the space for section extension 2");
770 return (XRAN_STATUS_RESOURCE);
773 memcpy(data, &val, val_size);
775 *data = ((params->bfAzSI) << 3) + (params->bfZeSI);
777 memcpy(data, zeropad, pad_size);
779 ext2->extLen = total_len / XRAN_SECTIONEXT_ALIGN;
780 *(uint32_t *)ext2 = rte_cpu_to_be_32(*(uint32_t *)ext2);
786 xran_prepare_sectionext_3(struct rte_mbuf *mbuf, struct xran_sectionext3_info *params, int32_t last_flag)
790 int32_t data_first_byte, data_second_byte;
791 int32_t data_third_byte, data_fourth_byte;
794 if(params->layerId == XRAN_LAYERID_0
795 || params->layerId == XRAN_LAYERID_TXD) { /* first data layer */
797 union xran_cp_radioapp_section_ext3_first *ext3_f;
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);
803 print_err("Fail to allocate the space for section extension 3");
804 return (XRAN_STATUS_RESOURCE);
807 /*ext3_f->data_field.data_field1 = _mm_setzero_si128();
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;
819 if(params->numAntPort == 2) {
820 ext3_f->all_bits.beamIdAP3 = params->beamIdAP1;
821 ext3_f->all_bits.extLen = 3;
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;
833 if(params->numAntPort == 2) {
840 data_third_byte = (params->beamIdAP2 << 16) | params->beamIdAP3;
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);
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);
864 rte_pktmbuf_trim(mbuf, adj);
866 else { /* non-first data layer */
867 union xran_cp_radioapp_section_ext3_non_first *ext3_nf;
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);
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;
882 ext3_nf->all_bits.extLen = sizeof(union xran_cp_radioapp_section_ext3_non_first)/XRAN_SECTIONEXT_ALIGN;*/
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);
891 *(uint32_t *)ext3_nf = rte_cpu_to_be_32(*(uint32_t *)ext3_nf);
898 xran_prepare_sectionext_4(struct rte_mbuf *mbuf, struct xran_sectionext4_info *params, int32_t last_flag)
900 struct xran_cp_radioapp_section_ext4 *ext4;
903 parm_size = sizeof(struct xran_cp_radioapp_section_ext4);
904 ext4 = (struct xran_cp_radioapp_section_ext4 *)rte_pktmbuf_append(mbuf, parm_size);
906 print_err("Fail to allocate the space for section extension 4");
907 return(XRAN_STATUS_RESOURCE);
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;
916 *(uint32_t *)ext4 = rte_cpu_to_be_32(*(uint32_t*)ext4);
922 xran_prepare_sectionext_9(struct rte_mbuf *mbuf, struct xran_sectionext9_info * params, int32_t last_flag)
924 struct xran_cp_radioapp_section_ext9 *ext9;
927 parm_size = sizeof(struct xran_cp_radioapp_section_ext9);
928 ext9 = (struct xran_cp_radioapp_section_ext9 *)rte_pktmbuf_append(mbuf, parm_size);
930 print_err("Fail to allocate the space for section extension 9");
931 return(XRAN_STATUS_RESOURCE);
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;
940 *(uint32_t *)ext9 = rte_cpu_to_be_32(*(uint32_t*)ext9);
946 xran_prepare_sectionext_5(struct rte_mbuf *mbuf, struct xran_sectionext5_info *params, int32_t last_flag)
948 struct xran_cp_radioapp_section_ext_hdr *ext_hdr;
949 struct xran_cp_radioapp_section_ext5 ext5;
955 if(params->num_sets > XRAN_MAX_MODCOMP_ADDPARMS) {
956 print_err("Exceeds maximum number of parameters(%d). Skipping.", params->num_sets);
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
965 padding = total_len % XRAN_SECTIONEXT_ALIGN;
967 padding = XRAN_SECTIONEXT_ALIGN - padding;
968 total_len += padding;
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);
977 ext_hdr->extType = XRAN_CP_SECTIONEXTCMD_5;
978 ext_hdr->ef = last_flag;
979 ext_hdr->extLen = total_len / XRAN_SECTIONEXT_ALIGN;
981 *(uint16_t *)ext_hdr = rte_cpu_to_be_16(*((uint16_t *)ext_hdr));
983 data = (uint8_t *)(ext_hdr + 1);
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;
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);
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;
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;
1016 memcpy(data, zeropad, padding);
1022 xran_prepare_sectionext_6(struct rte_mbuf *mbuf,
1023 struct xran_sectionext6_info *params, int32_t last_flag)
1025 union xran_cp_radioapp_section_ext6 *ext6;
1028 parm_size = sizeof(union xran_cp_radioapp_section_ext6);
1029 ext6 = (union xran_cp_radioapp_section_ext6 *)rte_pktmbuf_append(mbuf, parm_size);
1031 print_err("Fail to allocate the space for section extension 6");
1032 return(XRAN_STATUS_RESOURCE);
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;
1045 *(uint64_t *)ext6 = rte_cpu_to_be_64(*(uint64_t*)ext6);
1051 xran_prepare_sectionext_10(struct rte_mbuf *mbuf,
1052 struct xran_sectionext10_info *params, int32_t last_flag)
1054 union xran_cp_radioapp_section_ext10 *ext10;
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);
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);
1076 parm_size = sizeof(union xran_cp_radioapp_section_ext10);
1077 ext10 = (union xran_cp_radioapp_section_ext10 *)rte_pktmbuf_append(mbuf, parm_size);
1079 print_err("Fail to allocate the space for section extension 10");
1080 return(XRAN_STATUS_RESOURCE);
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;
1089 total_len = parm_size;
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;
1097 padding = (parm_size + total_len) % XRAN_SECTIONEXT_ALIGN;
1099 padding = XRAN_SECTIONEXT_ALIGN - padding;
1100 parm_size += padding;
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);
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);
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]);
1118 memcpy((uint8_t *)&id_ptr[params->numPortc], zeropad, padding);
1121 total_len += parm_size;
1122 ext10->all_bits.extLen = total_len / XRAN_SECTIONEXT_ALIGN;
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);
1136 * @brief Estimates how many BFW sets can be fit to given MTU size
1138 * @ingroup xran_cp_pkt
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
1146 * the number of maximum set of BFWs on success
1147 * XRAN_STATUS_INVALID_PARAM, if compression method is not supported.
1150 xran_cp_estimate_max_set_bfws(uint8_t numBFWs, uint8_t iqWidth, uint8_t compMeth, uint16_t mtu)
1153 int32_t bfw_bitsize;
1154 int32_t bundle_size;
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) );
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++;
1169 bundle_size += 2; /* two bytes for Beam ID */
1171 case XRAN_BFWCOMPMETHOD_NONE:
1174 case XRAN_BFWCOMPMETHOD_BLKFLOAT:
1175 bundle_size += 1; /* for bfwCompParam */
1179 print_err("Compression method %d is not supported!", compMeth);
1180 return (XRAN_STATUS_INVALID_PARAM);
1183 return (avail_len / bundle_size);
1186 inline static uint32_t
1187 xran_cp_get_hdroffset_section1(uint32_t exthdr_size)
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) \
1200 * @brief Prepare Beam Forming Weights(BFWs) for Section Extension 11
1201 * Copy sets of BFWs to buffer after compression if required.
1203 * @ingroup xran_cp_pkt
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.
1217 * XRAN_STATUS_SUCCESS on success
1218 * XRAN_STATUS_RESOURCE, if destination memory is not enough to store all BFWs
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[])
1226 int32_t iq_bitsize, iq_size;
1229 uint32_t hdr_offset;
1232 struct xranlib_compress_request bfpComp_req;
1233 struct xranlib_compress_response bfpComp_rsp;
1236 print_err("Invalid destination pointer!");
1237 return (XRAN_STATUS_INVALID_PARAM);
1240 /* Calculate the size of BFWs I/Q in bytes */
1241 iq_bitsize = numBFW * iqWidth * 2;
1242 iq_size = iq_bitsize>>3;
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);
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);
1256 hdr_offset = xran_cp_get_hdroffset_section1(sizeof(union xran_cp_radioapp_section_ext11));
1258 /* Copy BFWs to destination buffer */
1259 ptr = dst + hdr_offset;
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 */
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));
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 */
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);
1287 print_err("compression failed\n");
1288 return (XRAN_STATUS_FAIL);
1290 /* move exponent, it is stored at first byte of output */
1294 *((uint16_t *)(ptr+1)) = rte_cpu_to_be_16((bfwInfo[i].beamId & 0x7fff));
1300 print_err("Compression method %d is not supported!", compMeth);
1301 return (XRAN_STATUS_INVALID_PARAM);
1304 /* Update the length of extension with padding */
1305 parm_size = (total_len + sizeof(union xran_cp_radioapp_section_ext11))
1306 % XRAN_SECTIONEXT_ALIGN;
1309 parm_size = XRAN_SECTIONEXT_ALIGN - parm_size;
1310 memcpy(ptr, zeropad, parm_size);
1311 total_len += parm_size;
1318 static void free_ext_buf(void *addr, void *opaque)
1320 /* free is not required for external buffers */
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.
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)
1333 rte_iova_t extbuf_iova;
1336 if(unlikely(mbuf == NULL)) {
1337 print_err("Invalid mbuf to attach!\n");
1338 return (XRAN_STATUS_INVALID_PARAM);
1341 /* Update shared information */
1342 shinfo->free_cb = free_ext_buf;
1343 rte_mbuf_ext_refcnt_update(shinfo, 1);
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);
1351 rte_pktmbuf_attach_extbuf(mbuf, extbuf_start, extbuf_iova, extbuf_len, shinfo);
1353 rte_pktmbuf_reset_headroom(mbuf);
1355 return (XRAN_STATUS_SUCCESS);
1360 xran_prepare_sectionext_11(struct rte_mbuf *mbuf,
1361 struct xran_sectionext11_info *params, int32_t last_flag)
1363 union xran_cp_radioapp_section_ext11 *ext11;
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);
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;
1378 ext11 = (union xran_cp_radioapp_section_ext11 *)rte_pktmbuf_append(mbuf, total_len);
1380 print_err("Fail to allocate the space for section extension 11 [%d]", total_len);
1381 return (XRAN_STATUS_RESOURCE);
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);
1393 ext11->all_bits.extLen = total_len / XRAN_SECTIONEXT_ALIGN;*/
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;
1404 *(uint32_t *)ext11 = rte_cpu_to_be_32(*(uint32_t*)ext11);
1410 * @brief add section extension to C-Plane packet
1413 * A pointer to the packet buffer
1415 * A porinter to the information to generate a C-Plane packet
1417 * XRAN_STATUS_SUCCESS on success
1418 * XRAN_STATUS_INVALID_PARM
1419 * XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
1421 int32_t xran_append_section_extensions(struct rte_mbuf *mbuf, struct xran_section_gen_info *params)
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);
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);
1442 last_flag = (params->exDataSize == (i+1))?0:1;
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);
1448 case XRAN_CP_SECTIONEXTCMD_2:
1449 ext_size = xran_prepare_sectionext_2(mbuf, params->exData[i].data, last_flag);
1451 case XRAN_CP_SECTIONEXTCMD_3:
1452 ext_size = xran_prepare_sectionext_3(mbuf, params->exData[i].data, last_flag);
1454 case XRAN_CP_SECTIONEXTCMD_4:
1455 ext_size = xran_prepare_sectionext_4(mbuf, params->exData[i].data, last_flag);
1457 case XRAN_CP_SECTIONEXTCMD_5:
1458 ext_size = xran_prepare_sectionext_5(mbuf, params->exData[i].data, last_flag);
1460 case XRAN_CP_SECTIONEXTCMD_6:
1461 ext_size = xran_prepare_sectionext_6(mbuf, params->exData[i].data, last_flag);
1463 case XRAN_CP_SECTIONEXTCMD_9:
1464 ext_size = xran_prepare_sectionext_9(mbuf, params->exData[i].data, last_flag);
1466 case XRAN_CP_SECTIONEXTCMD_10:
1467 ext_size = xran_prepare_sectionext_10(mbuf, params->exData[i].data, last_flag);
1469 case XRAN_CP_SECTIONEXTCMD_11:
1470 ext_size = xran_prepare_sectionext_11(mbuf, params->exData[i].data, last_flag);
1473 print_err("Extension Type %d is not supported!", params->exData[i].type);
1477 if(ext_size == XRAN_STATUS_RESOURCE) {
1481 totalen += ext_size;
1489 * @brief Fill the section body of type 0 in C-Plane packet
1492 * A pointer to the section in the packet buffer
1494 * A porinter to the information to generate a C-Plane packet
1496 * XRAN_STATUS_SUCCESS on success
1497 * XRAN_STATUS_INVALID_PARM if the number of symbol is invalid
1500 xran_prepare_section0(struct xran_cp_radioapp_section0 *section, struct xran_section_gen_info *params)
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);
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);
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;
1519 // for network byte order
1520 *((uint64_t *)section) = rte_cpu_to_be_64(*((uint64_t *)section));
1522 return (XRAN_STATUS_SUCCESS);
1526 * @brief Fill the section header of type 0 in C-Plane packet
1529 * A pointer to the section header in the packet buffer
1531 * A porinter to the information to generate a C-Plane packet
1533 * XRAN_STATUS_SUCCESS always
1536 xran_prepare_section0_hdr( struct xran_cp_radioapp_section0_header *s0hdr,
1537 struct xran_cp_gen_params *params)
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;
1545 return (XRAN_STATUS_SUCCESS);
1549 * @brief Fill the section body of type 1 in C-Plane packet
1550 * Extension is not supported.
1553 * A pointer to the section header in the packet buffer
1555 * A porinter to the information to generate a C-Plane packet
1557 * XRAN_STATUS_SUCCESS on success
1558 * XRAN_STATUS_INVALID_PARM if the number of symbol is invalid
1561 xran_prepare_section1(struct xran_cp_radioapp_section1 *section,
1562 struct xran_section_gen_info *params)
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);
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);
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;*/
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);
1592 // for network byte order
1593 *((uint64_t *)section) = rte_cpu_to_be_64(*((uint64_t *)section));
1595 return (XRAN_STATUS_SUCCESS);
1599 * @brief Fill the section header of type 1 in C-Plane packet
1602 * A pointer to the section header in the packet buffer
1604 * A porinter to the information to generate a C-Plane packet
1606 * XRAN_STATUS_SUCCESS always
1609 xran_prepare_section1_hdr(struct xran_cp_radioapp_section1_header *s1hdr,
1610 struct xran_cp_gen_params *params)
1612 s1hdr->udComp.udIqWidth = params->hdr.iqWidth;
1613 s1hdr->udComp.udCompMeth = params->hdr.compMeth;
1614 s1hdr->reserved = 0;
1616 return (XRAN_STATUS_SUCCESS);
1620 * @brief Fill the section body of type 3 in C-Plane packet
1621 * Extension is not supported.
1624 * A pointer to the section header in the packet buffer
1626 * A porinter to the information to generate a C-Plane packet
1628 * XRAN_STATUS_SUCCESS on success
1629 * XRAN_STATUS_INVALID_PARM if the number of symbol is invalid
1632 xran_prepare_section3(struct xran_cp_radioapp_section3 *section,
1633 struct xran_section_gen_info *params)
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);
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);
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;*/
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);
1663 section->freqOffset = rte_cpu_to_be_32(params->info->freqOffset)>>8;
1664 section->reserved = 0;
1666 /* for network byte order (header, 8 bytes) */
1667 *((uint64_t *)section) = rte_cpu_to_be_64(*((uint64_t *)section));
1669 return (XRAN_STATUS_SUCCESS);
1673 * @brief Fill the section header of type 3 in C-Plane packet
1676 * A pointer to the section header in the packet buffer
1678 * A porinter to the information to generate a C-Plane packet
1680 * XRAN_STATUS_SUCCESS always
1683 xran_prepare_section3_hdr(struct xran_cp_radioapp_section3_header *s3hdr,
1684 struct xran_cp_gen_params *params)
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;
1693 return (XRAN_STATUS_SUCCESS);
1697 * @brief add sections to C-Plane packet
1698 * Section type 1 and 3 are supported.
1701 * A pointer to the packet buffer
1703 * A porinter to the information to generate a C-Plane packet
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
1710 xran_append_control_section(struct rte_mbuf *mbuf, struct xran_cp_gen_params *params,uint16_t start_sect_id)
1715 int32_t section_size;
1716 int32_t (*xran_prepare_section_func)(void *section, void *params);
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;
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;
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;
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 */
1740 xran_prepare_section_func = NULL;
1741 print_err("Section Type %d is not supported!", params->sectionType);
1742 return (XRAN_STATUS_INVALID_PARAM);
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);
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);
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 *)¶ms->sections[i]);
1760 print_err("%s %d\n", __FUNCTION__, ret);
1763 totalen += section_size;
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, ¶ms->sections[i]);
1779 * @brief fill the information of a radio application header in a C-Plane packet
1782 * A pointer to the application header in the packet buffer
1784 * A porinter to the information to generate a C-Plane packet
1786 * XRAN_STATUS_SUCCESS on success
1787 * XRAN_STATUS_INVALID_PARM if direction, slot index or symbold index is invalid
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)
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);
1799 if(unlikely(params->hdr.slotId > XRAN_SLOTID_MAX)) {
1800 print_err("Invalid Slot ID!");
1801 return (XRAN_STATUS_INVALID_PARAM);
1803 if(unlikely(params->hdr.startSymId > XRAN_SYMBOLNUMBER_MAX)) {
1804 print_err("Invalid Symbol ID!");
1805 return (XRAN_STATUS_INVALID_PARAM);
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;*/
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);
1826 apphdr->numOfSections = params->numSections;
1827 apphdr->sectionType = params->sectionType;
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);
1836 * @brief add a radio application header in a C-Plane packet
1839 * A pointer to the packet buffer
1841 * A porinter to the information to generate a C-Plane packet
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
1848 xran_append_radioapp_header(struct rte_mbuf *mbuf, struct xran_cp_gen_params *params)
1852 struct xran_cp_radioapp_common_header *apphdr;
1853 int32_t (*xran_prepare_radioapp_section_hdr_func)(void *hdr, void *params);
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);
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);
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);
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);
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 */
1883 print_err("Section Type %d is not supported!", params->sectionType);
1884 xran_prepare_radioapp_section_hdr_func = NULL;
1886 return (XRAN_STATUS_INVALID_PARAM);
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);
1895 ret = xran_prepare_radioapp_common_header(apphdr, params);
1896 if(unlikely(ret < 0)) {
1900 if(likely(xran_prepare_radioapp_section_hdr_func)) {
1901 totalen += xran_prepare_radioapp_section_hdr_func(apphdr, params);
1904 print_err("xran_prepare_radioapp_section_hdr_func is NULL!");
1905 return (XRAN_STATUS_INVALID_PARAM);
1912 * @brief Create a C-Plane packet
1913 * Transport layer fragmentation is not supported.
1915 * @ingroup xran_cp_pkt
1918 * A pointer to the packet buffer
1920 * A porinter to the information to generate a C-Plane packet
1922 * Component Carrier ID for this C-Plane message
1924 * Antenna ID(RU Port ID) for this C-Plane message
1926 * Sequence ID for this C-Plane message
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
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,
1937 uint16_t start_sect_id)
1940 uint32_t payloadlen;
1941 struct xran_ecpri_hdr *ecpri_hdr;
1943 payloadlen = xran_build_ecpri_hdr(mbuf, CC_ID, Ant_ID, seq_id, &ecpri_hdr);
1945 ret = xran_append_radioapp_header(mbuf, params);
1947 print_err("%s %d\n", __FUNCTION__, ret);
1952 ret = xran_append_control_section(mbuf, params,start_sect_id);
1954 print_err("%s %d\n", __FUNCTION__, ret);
1959 /* set payload length */
1960 ecpri_hdr->cmnhdr.bits.ecpri_payl_size = rte_cpu_to_be_16(payloadlen);
1962 return (XRAN_STATUS_SUCCESS);
1965 ///////////////////////////////////////
1968 xran_parse_section_ext1(void *ext, struct xran_sectionext1_info *extinfo)
1972 struct xran_cp_radioapp_section_ext1 *ext1;
1974 int32_t parm_size = 0, iq_size, iq_size_bytes;
1979 N = xran_get_conf_num_bfweights(pHandle);
1980 extinfo->bfwNumber = N;
1982 ext1 = (struct xran_cp_radioapp_section_ext1 *)ext;
1983 data = (uint8_t *)ext;
1986 total_len = ext1->extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
1988 extinfo->bfwCompMeth = ext1->bfwCompMeth;
1989 extinfo->bfwIqWidth = (ext1->bfwIqWidth==0)?16:ext1->bfwIqWidth;
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);
1995 switch(ext1->bfwCompMeth) {
1996 case XRAN_BFWCOMPMETHOD_NONE:
2000 case XRAN_BFWCOMPMETHOD_BLKFLOAT:
2002 extinfo->bfwCompParam.exponent = *data & 0x0f;
2005 case XRAN_BFWCOMPMETHOD_BLKSCALE:
2007 extinfo->bfwCompParam.blockScaler = *data;
2010 case XRAN_BFWCOMPMETHOD_ULAW:
2012 extinfo->bfwCompParam.compBitWidthShift = *data;
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);
2021 print_err("Invalid BfComp method - %d", ext1->bfwCompMeth);
2027 iq_size_bytes = parm_size;
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;
2035 //memcpy(data, extinfo->p_bfwIQ, parm_size);
2036 extinfo->bfwIQ_sz = iq_size_bytes;
2040 parm_size = len % XRAN_SECTIONEXT_ALIGN;
2042 len += (XRAN_SECTIONEXT_ALIGN - parm_size);
2044 if(len != total_len) {
2045 print_err("The size of extension 1 is not correct! [%d:%d]", len, total_len);
2052 xran_parse_section_ext2(void *ext, struct xran_sectionext2_info *extinfo)
2056 struct xran_cp_radioapp_section_ext2 *ext2;
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);
2067 total_len = ext2->extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
2069 parm_size = sizeof(struct xran_cp_radioapp_section_ext2);
2071 extinfo->bfAzPtWidth = ext2->bfAzPtWidth;
2072 extinfo->bfZePtWidth = ext2->bfZePtWidth;
2073 extinfo->bfAz3ddWidth = ext2->bfAz3ddWidth;
2074 extinfo->bfZe3ddWidth = ext2->bfZe3ddWidth;
2076 if(ext2->bfaCompResv0 || ext2->bfaCompResv1)
2077 print_err("Incorrect reserved field - %d, %d", ext2->bfaCompResv0, ext2->bfaCompResv1);
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);
2087 val = rte_be_to_cpu_32(*(uint32_t *)data);
2088 val >>= (32 - val_size);
2090 if(extinfo->bfZe3ddWidth) {
2091 extinfo->bfZe3dd = val & bitmask[extinfo->bfZe3ddWidth];
2092 val >>= (extinfo->bfZe3ddWidth + 1);
2094 if(extinfo->bfAz3ddWidth) {
2095 extinfo->bfAz3dd = val & bitmask[extinfo->bfAz3ddWidth];
2096 val >>= (extinfo->bfAz3ddWidth + 1);
2098 if(extinfo->bfZePtWidth) {
2099 extinfo->bfZePt = val & bitmask[extinfo->bfZePtWidth];
2100 val >>= (extinfo->bfZePtWidth + 1);
2102 if(extinfo->bfAzPtWidth) {
2103 extinfo->bfAzPt = val & bitmask[extinfo->bfAzPtWidth];
2104 val >>= (extinfo->bfAzPtWidth + 1);
2108 parm_size = val_size/8;
2109 if(val_size%8) parm_size += 1;
2114 extinfo->bfAzSI = (*data >> 3) & 0x07;
2115 extinfo->bfZeSI = *data & 0x07;
2120 parm_size = len % XRAN_SECTIONEXT_ALIGN;
2122 len += (XRAN_SECTIONEXT_ALIGN - parm_size);
2124 if(len != total_len) {
2125 print_err("The size of extension 2 is not correct! [%d:%d]", len, total_len);
2133 xran_parse_section_ext3(void *ext, struct xran_sectionext3_info *extinfo)
2139 len = *((uint8_t *)ext + 1);
2142 case 1: /* non-first data layer */
2144 union xran_cp_radioapp_section_ext3_non_first *ext3_nf;
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);
2149 total_len = ext3_nf->all_bits.extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
2151 extinfo->codebookIdx= ext3_nf->all_bits.codebookIndex;
2152 extinfo->layerId = ext3_nf->all_bits.layerId;
2153 extinfo->numLayers = ext3_nf->all_bits.numLayers;
2157 case 3: /* first data layer with two antenna */
2158 case 4: /* first data layer with four antenna */
2160 union xran_cp_radioapp_section_ext3_first *ext3_f;
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);
2166 total_len = ext3_f->all_bits.extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
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;
2176 /* beam IDs are stored from 10th octet */
2177 beamid = (uint16_t *)((uint8_t *)ext + 10);
2179 extinfo->beamIdAP1 = rte_be_to_cpu_16(*beamid++);
2181 extinfo->beamIdAP2 = rte_be_to_cpu_16(*beamid++);
2182 extinfo->beamIdAP3 = rte_be_to_cpu_16(*beamid);
2183 extinfo->numAntPort = 4;
2186 extinfo->numAntPort = 2;
2192 print_err("Invalid length of extension 3 - %d", len);
2199 xran_parse_section_ext4(void *ext, struct xran_sectionext4_info *extinfo)
2202 struct xran_cp_radioapp_section_ext4 *ext4;
2205 ext4 = (struct xran_cp_radioapp_section_ext4 *)ext;
2207 *(uint32_t *)ext4 = rte_be_to_cpu_32(*(uint32_t *)ext4);
2210 total_len = ext4->extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
2212 extinfo->modCompScaler = ext4->modCompScaler;
2213 extinfo->csf = ext4->csf;
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);
2224 xran_parse_section_ext5(void *ext,
2225 struct xran_sectionext5_info *extinfo)
2227 struct xran_cp_radioapp_section_ext_hdr *ext_hdr;
2228 struct xran_cp_radioapp_section_ext5 ext5;
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);
2237 total_len = ext_hdr->extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
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;
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;
2247 data = (uint8_t *)(ext_hdr + 1);
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));
2254 extinfo->mc[i].mcScaleOffset = ext5.mcScaleOffset1;
2255 extinfo->mc[i].csf = ext5.csf1;
2256 extinfo->mc[i].mcScaleReMask = ext5.mcScaleReMask1;
2259 extinfo->mc[i].mcScaleOffset = ext5.mcScaleOffset2;
2260 extinfo->mc[i].csf = ext5.csf2;
2261 extinfo->mc[i].mcScaleReMask = ext5.mcScaleReMask2;
2264 data += sizeof(struct xran_cp_radioapp_section_ext5);
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) */
2271 if(i < XRAN_MAX_MODCOMP_ADDPARMS) {
2272 if(extinfo->mc[i].csf == 0 && extinfo->mc[i].mcScaleReMask == 0)
2273 extinfo->num_sets = i;
2275 extinfo->num_sets = i+1;
2277 print_err("Maximum total number %d is not correct!", i);
2284 xran_parse_section_ext6(void *ext,
2285 struct xran_sectionext6_info *extinfo)
2288 union xran_cp_radioapp_section_ext6 *ext6;
2291 ext6 = (union xran_cp_radioapp_section_ext6 *)ext;
2292 *(uint64_t *)ext6 = rte_be_to_cpu_64(*(uint64_t *)ext6);
2294 total_len = ext6->all_bits.extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
2296 extinfo->rbgSize = ext6->all_bits.rbgSize;
2297 extinfo->rbgMask = ext6->all_bits.rbgMask;
2298 extinfo->symbolMask = ext6->all_bits.symbolMask;
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);
2309 xran_parse_section_ext9(void *ext,
2310 struct xran_sectionext9_info *extinfo, struct xran_cp_recv_params *result)
2315 int8_t presumed_technology = -1;
2316 struct xran_cp_radioapp_section_ext9 *ext9;
2318 ext9 = (struct xran_cp_radioapp_section_ext9 *)ext;
2319 *(uint32_t *)ext9 = rte_be_to_cpu_32(*(uint32_t *)ext9);
2321 total_len = ext9->extLen * XRAN_SECTIONEXT_ALIGN;
2324 dssSlot = result->tti % result->dssPeriod;
2325 presumed_technology = result->technology_arr[dssSlot];
2327 print_err("\nTechnology verification parameters not received");
2331 if(presumed_technology != ext9->technology) {
2332 print_err("\nWrong technology recieved! [%d,%d]", presumed_technology, ext9->technology);
2336 extinfo->technology = ext9->technology;
2337 extinfo->reserved = ext9->reserved;
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);
2349 xran_parse_section_ext10(void *ext,
2350 struct xran_sectionext10_info *extinfo)
2352 int32_t len, padding;
2354 union xran_cp_radioapp_section_ext10 *ext10;
2358 ext10 = (union xran_cp_radioapp_section_ext10 *)ext;
2360 total_len = ext10->all_bits.extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
2362 extinfo->numPortc = ext10->all_bits.numPortc;
2363 extinfo->beamGrpType= ext10->all_bits.beamGroupType;
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;
2370 padding = XRAN_SECTIONEXT_ALIGN - padding;
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]);
2379 if(len != total_len) {
2380 print_err("The size of extension 10 is not correct! [%d:%d]", len, total_len);
2387 xran_parse_section_ext11(void *ext,
2388 struct xran_sectionext11_recv_info *extinfo)
2392 union xran_cp_radioapp_section_ext11 *ext11;
2394 int32_t parm_size, iq_size;
2399 N = xran_get_conf_num_bfweights(pHandle);
2401 ext11 = (union xran_cp_radioapp_section_ext11 *)ext;
2402 data = (uint8_t *)ext;
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 */
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;
2413 len = sizeof(union xran_cp_radioapp_section_ext11);
2414 data += sizeof(union xran_cp_radioapp_section_ext11);
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:
2424 case XRAN_BFWCOMPMETHOD_BLKFLOAT:
2426 extinfo->bundInfo[extinfo->numSetBFWs].bfwCompParam.exponent = *data & 0x0f;
2428 #if 0 /* Not supported */
2429 case XRAN_BFWCOMPMETHOD_BLKSCALE:
2431 extinfo->bundInfo[extinfo->numSetBFWs].bfwCompParam.blockScaler = *data;
2434 case XRAN_BFWCOMPMETHOD_ULAW:
2436 extinfo->bundInfo[extinfo->numSetBFWs].bfwCompParam.compBitWidthShift = *data;
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);
2445 print_err("Invalid BfComp method - %d", ext11->all_bits.bfwCompMeth);
2452 extinfo->bundInfo[extinfo->numSetBFWs].beamId = rte_be_to_cpu_16(*((int16_t *)data));
2453 len += sizeof(int16_t);
2454 data += sizeof(int16_t);
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
2461 if(extinfo->bundInfo[extinfo->numSetBFWs].pBFWs) {
2462 memcpy(extinfo->bundInfo[extinfo->numSetBFWs].pBFWs, data, parm_size);
2464 extinfo->bundInfo[extinfo->numSetBFWs].BFWSize = parm_size;
2468 extinfo->numSetBFWs++;
2471 parm_size = len % XRAN_SECTIONEXT_ALIGN;
2473 len += (XRAN_SECTIONEXT_ALIGN - parm_size);
2475 if(len != total_len) {
2476 //print_err("The size of extension 11 is not correct! [%d:%d]", len, total_len);
2483 xran_parse_section_extension(struct rte_mbuf *mbuf,
2484 void *ext, struct xran_cp_recv_params *result,
2485 int32_t section_idx)
2487 struct xran_section_recv_info *section = &result->sections[section_idx];
2488 int32_t total_len, len, numext;
2495 ptr = (uint8_t *)ext;
2503 flag_last = (*ptr & 0x80);
2505 ext_type = *ptr & 0x7f;
2506 section->exts[numext].type = ext_type;
2508 case XRAN_CP_SECTIONEXTCMD_1:
2509 result->ext1count++;
2510 len = xran_parse_section_ext1(ptr, §ion->exts[numext].u.ext1);
2512 case XRAN_CP_SECTIONEXTCMD_2:
2513 len = xran_parse_section_ext2(ptr, §ion->exts[numext].u.ext2);
2515 case XRAN_CP_SECTIONEXTCMD_3:
2516 len = xran_parse_section_ext3(ptr, §ion->exts[numext].u.ext3);
2518 case XRAN_CP_SECTIONEXTCMD_4:
2519 len = xran_parse_section_ext4(ptr, §ion->exts[numext].u.ext4);
2521 case XRAN_CP_SECTIONEXTCMD_5:
2522 len = xran_parse_section_ext5(ptr, §ion->exts[numext].u.ext5);
2524 case XRAN_CP_SECTIONEXTCMD_6:
2525 len = xran_parse_section_ext6(ptr, §ion->exts[numext].u.ext6);
2527 case XRAN_CP_SECTIONEXTCMD_9:
2528 len = xran_parse_section_ext9(ptr, §ion->exts[numext].u.ext9, result);
2530 case XRAN_CP_SECTIONEXTCMD_10:
2531 len = xran_parse_section_ext10(ptr, §ion->exts[numext].u.ext10);
2533 case XRAN_CP_SECTIONEXTCMD_11:
2534 len = xran_parse_section_ext11(ptr, §ion->exts[numext].u.ext11);
2538 print_err("Extension %d is not supported!", ext_type);
2542 section->exts[numext].size = len;
2543 ptr += len; total_len += len;
2546 if(++numext < XRAN_MAX_NUM_EXTENSIONS) continue;
2548 /* exceeds maximum number of extensions */
2552 section->numExts = numext;
2558 * @brief Parse a C-Plane packet (for RU emulation)
2559 * Transport layer fragmentation is not supported.
2561 * @ingroup xran_cp_pkt
2564 * The pointer of the packet buffer to be parsed
2566 * The pointer of structure to store the information of parsed packet
2568 * The pointer of sturcture to store the decomposed information of ecpriRtcid/ecpriPcid
2570 * XRAN_STATUS_SUCCESS on success
2571 * XRAN_STATUS_INVALID_PACKET if failed to parse the packet
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)
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;
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);
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);
2608 *((uint32_t *)apphdr) = rte_be_to_cpu_32(*((uint32_t *)apphdr));
2610 if(apphdr->field.payloadVer != XRAN_PAYLOAD_VER) {
2611 print_err("Invalid Payload version - %d", apphdr->field.payloadVer);
2612 ret = XRAN_STATUS_INVALID_PACKET;
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;
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;
2628 ctx_id = tti % XRAN_MAX_SECTIONDB_CTX;
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
2642 switch(apphdr->sectionType) {
2643 case XRAN_CP_SECTIONTYPE_0: // Unused RB or Symbols in DL or UL, not supportted
2645 struct xran_cp_radioapp_section0_header *hdr;
2646 struct xran_cp_radioapp_section0 *section;
2648 hdr = (struct xran_cp_radioapp_section0_header*)apphdr;
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 */
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);
2661 for(i=0; i<result->numSections; i++) {
2662 *((uint64_t *)section) = rte_be_to_cpu_64(*((uint64_t *)section));
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 */
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;
2686 case XRAN_CP_SECTIONTYPE_1: // Most DL/UL Radio Channels
2688 struct xran_cp_radioapp_section1_header *hdr;
2689 struct xran_cp_radioapp_section1 *section;
2691 hdr = (struct xran_cp_radioapp_section1_header*)apphdr;
2693 result->hdr.iqWidth = hdr->udComp.udIqWidth;
2694 result->hdr.compMeth = hdr->udComp.udCompMeth;
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);
2702 for(i=0; i<result->numSections; i++) {
2703 *((uint64_t *)section) = rte_be_to_cpu_64(*((uint64_t *)section));
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;
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;
2725 if (eaxc.ruPortId < p_xran_dev_ctx->srs_cfg.eAxC_offset)
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;
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;
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);
2742 idx = p_xran_dev_ctx->sectiondb_elm[ctx_id][result->dir][eaxc.ccId][eaxc.ruPortId]++;
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;
2750 rte_pktmbuf_free(mb);
2752 prbMapElm->bf_weight.p_ext_start = mbuf;
2753 prbMapElm->bf_weight.p_ext_section = (void *)section;
2754 *mb_free = MBUF_KEEP;
2758 info = xran_cp_get_section_info_ptr(handle, result->dir, eaxc.ccId, eaxc.ruPortId, ctx_id);
2759 if(likely(info != NULL))
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;
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++)
2782 struct xran_section_desc *p_sec_desc = &prbMapElm->sec_desc[loc_sym][0];
2784 if(likely(p_sec_desc!=NULL))
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;
2789 p_sec_desc->section_id = info->id;
2793 print_err("section desc is NULL\n");
2795 } /* for(loc_sym = 0; loc_sym < XRAN_NUM_OF_SYMBOL_PER_SLOT; loc_sym++) */
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];
2804 extlen = xran_parse_section_extension(mbuf, (void *)section, result, i);
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;
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;
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);
2826 idx = p_xran_dev_ctx->sectiondb_elm[ctx_id][result->dir][eaxc.ccId][eaxc.ruPortId]++;
2828 info = xran_cp_get_section_info_ptr(handle, result->dir, eaxc.ccId, eaxc.ruPortId, ctx_id);
2829 if(likely(info != NULL))
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;
2845 if(likely(pRbMap_desc != NULL)){
2846 prbMapElm = &pRbMap_desc->prbMap[idx];
2847 info->startPrbc = prbMapElm->nRBStart;
2848 info->numPrbc = prbMapElm->nRBSize;
2850 struct xran_section_desc *p_sec_desc = NULL;
2851 for(loc_sym = 0; loc_sym < XRAN_NUM_OF_SYMBOL_PER_SLOT; loc_sym++)
2853 p_sec_desc = &prbMapElm->sec_desc[loc_sym][0];
2855 if(likely(p_sec_desc!=NULL))
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;
2863 print_err("section desc is NULL\n");
2865 } /* for(loc_sym = 0; loc_sym < XRAN_NUM_OF_SYMBOL_PER_SLOT; loc_sym++) */
2868 /*Assuming SRS CP will not have extension, removed the ef flag check and extension processing*/
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++;
2880 case XRAN_CP_SECTIONTYPE_3: // PRACH and Mixed-numerology Channels
2882 struct xran_cp_radioapp_section3_header *hdr;
2883 struct xran_cp_radioapp_section3 *section;
2885 hdr = (struct xran_cp_radioapp_section3_header*)apphdr;
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;
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);
2900 for(i=0; i<result->numSections; i++) {
2901 *((uint64_t *)section) = rte_be_to_cpu_64(*((uint64_t *)section));
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;
2915 if(section->reserved) {
2916 print_err("Invalid packet: section type3 - section[%d] reserved[%d]", i, section->reserved);
2917 ret = XRAN_STATUS_INVALID_PACKET;
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;
2929 if(result->sections[i].info.ef) {
2930 // parse section extension
2931 extlen = xran_parse_section_extension(mbuf, (void *)section, result, i);
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;
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
2950 ret = XRAN_STATUS_INVALID_PARAM;
2951 print_err("Non-supported Section Type - %d", apphdr->sectionType);
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);
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);
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:
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);
2987 case XRAN_CP_SECTIONEXTCMD_2:
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);
2999 case XRAN_CP_SECTIONEXTCMD_4:
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);
3007 case XRAN_CP_SECTIONEXTCMD_5:
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",
3015 ext5->mc[k].mcScaleReMask, ext5->mc[k].mcScaleOffset);
3020 case XRAN_CP_SECTIONEXTCMD_0:
3021 case XRAN_CP_SECTIONEXTCMD_3:
3023 printf("Invalid section extension type!\n");