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};
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 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)
287 uint8_t dir, num_sections;
288 struct xran_sectioninfo_db *ptr;
289 struct xran_section_info *list;
292 num_sections = gen_info->numSections;
294 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
295 if(unlikely(ptr == NULL)) {
296 return (XRAN_STATUS_INVALID_PARAM);
299 if(unlikely(ptr->cur_index+num_sections >= XRAN_MAX_NUM_SECTIONS)) {
300 print_err("No more space to add section information!");
301 return (XRAN_STATUS_RESOURCE);
304 list = xran_get_section_info(ptr, ptr->cur_index);
307 for(i=0; i<num_sections; i++) {
308 memcpy(&list[i], &gen_info->sections[i].info, sizeof(struct xran_section_info));
314 print_err("Null list in section db\n!");
315 return (XRAN_STATUS_INVALID_PARAM);
318 return (XRAN_STATUS_SUCCESS);
322 * @brief Find a section information of C-Plane from database
323 * by given information
325 * @ingroup xran_cp_pkt
328 * handle for xRAN interface, currently not being used
330 * The direction of the section to find
332 * The CC ID of the section to find
334 * RU port ID of the section to find
336 * Context index for the section database
338 * The ID of section to find
340 * The pointer of section information if matched section is found
341 * NULL if failed to find matched section
343 struct xran_section_info *
344 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)
346 int32_t index, num_index;
347 struct xran_sectioninfo_db *ptr;
349 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
350 if(unlikely(ptr == NULL))
353 if(ptr->cur_index > XRAN_MAX_NUM_SECTIONS)
354 num_index = XRAN_MAX_NUM_SECTIONS;
356 num_index = ptr->cur_index;
358 for(index=0; index < num_index; index++) {
359 if(ptr->list[index].id == section_id) {
360 return (xran_get_section_info(ptr, index));
364 print_dbg("No section ID in the list - %d", section_id);
369 * @brief Iterate each section information of C-Plane
370 * from the database of eAxC by given information
372 * @ingroup xran_cp_pkt
375 * handle for xRAN interface, currently not being used
377 * The direction of the section to find
379 * The CC ID of the section to find
381 * RU port ID of the section to find
383 * Context index for the section database
385 * The pointer to store the position of next entry
387 * The pointer of section information in the list
388 * NULL if reached at the end of the list
390 struct xran_section_info *
391 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)
394 struct xran_sectioninfo_db *ptr;
396 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
397 if(unlikely(ptr == NULL))
401 if(*next < ptr->cur_index) {
403 return (xran_get_section_info(ptr, index));
406 print_dbg("No more sections in the list");
412 * @brief Get the size of stored entries
413 * for the database of eAxC by given information
415 * @ingroup xran_cp_pkt
418 * handle for xRAN interface, currently not being used
420 * The direction of the section to find
422 * The CC ID of the section to find
424 * RU port ID of the section to find
426 * Context index for the section database
428 * The size of stored entries
429 * -1 if failed to find matched database
432 xran_cp_getsize_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id)
435 struct xran_sectioninfo_db *ptr;
437 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
438 if(unlikely(ptr == NULL))
441 return (ptr->cur_index);
445 * @brief Reset a database of eAxC by given information
447 * @ingroup xran_cp_pkt
450 * handle for xRAN interface, currently not being used
452 * The direction of the section to find
454 * The CC ID of the section to find
456 * RU port ID of the section to find
458 * Context index for the section database
460 * XRAN_STATUS_SUCCESS on success
461 * XRAN_STATUS_INVALID_PARM if failed to find matched database
464 xran_cp_reset_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id)
466 struct xran_sectioninfo_db *ptr;
468 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
469 if(unlikely(ptr == NULL)) {
470 return (XRAN_STATUS_INVALID_PARAM);
475 return (XRAN_STATUS_SUCCESS);
478 int32_t xran_cp_populate_section_ext_1(int8_t *p_ext1_dst, /**< destination buffer */
479 uint16_t ext1_dst_len, /**< dest buffer size */
480 int16_t *p_bfw_iq_src, /**< source buffer of IQs */
481 uint16_t rbNum, /* number RBs to ext1 chain */
482 uint16_t bfwNumPerRb, /* number of bf weights per RB (i.e. antenna elements) */
483 uint8_t bfwiqWidth, /* bit size of IQs */
484 uint8_t bfwCompMeth) /* compression method */
486 struct xran_cp_radioapp_section_ext1 *p_ext1;
488 uint8_t *p_bfw_content = NULL;
489 int32_t parm_size = 0;
490 int32_t bfw_iq_bits = 0;
491 int32_t total_len = 0;
492 int32_t comp_len = 0;
493 uint8_t ext_flag = XRAN_EF_F_ANOTHER_ONE;
495 int16_t cur_ext_len = 0;
496 int8_t *p_ext1_dst_cur = NULL;
498 struct xranlib_compress_request bfp_com_req;
499 struct xranlib_compress_response bfp_com_rsp;
501 memset(&bfp_com_req, 0, sizeof(struct xranlib_compress_request));
502 memset(&bfp_com_rsp, 0, sizeof(struct xranlib_compress_response));
504 print_dbg("%s comp %d\n", __FUNCTION__, bfwCompMeth);
505 print_dbg("bfwNumPerRb %d bfwiqWidth %d\n", bfwNumPerRb, bfwiqWidth);
508 p_ext1_dst_cur = p_ext1_dst;
510 return (XRAN_STATUS_INVALID_PARAM);
512 /* create extType=1 section for each RB */
513 for (idxRb = 0; idxRb < rbNum; idxRb++) {
514 print_dbg("%s RB %d\n", __FUNCTION__, idxRb);
516 if(total_len >= ext1_dst_len){
517 print_err("p_ext1_dst overflow\n");
521 cur_ext_len = 0; /** populate one extType=1 section with BFW for 1 RB */
522 parm_size = sizeof(struct xran_cp_radioapp_section_ext1);
523 p_ext1 = (struct xran_cp_radioapp_section_ext1 *)p_ext1_dst_cur;
525 print_err("p_ext1 is null!\n");
526 return (XRAN_STATUS_INVALID_PARAM);
529 cur_ext_len += parm_size;
532 ext_flag = XRAN_EF_F_LAST;
534 p_ext1->extType = XRAN_CP_SECTIONEXTCMD_1;
535 p_ext1->ef = ext_flag;
536 p_ext1->bfwCompMeth = bfwCompMeth;
537 p_ext1->bfwIqWidth = XRAN_CONVERT_BFWIQWIDTH(bfwiqWidth);
539 switch(bfwCompMeth) {
540 case XRAN_BFWCOMPMETHOD_BLKFLOAT:
541 p_bfw_content = (uint8_t *)(p_ext1+1);
542 if(p_bfw_content == NULL) {
543 print_err("Fail to allocate the space for section extension 1");
544 return (XRAN_STATUS_RESOURCE);
546 bfp_com_req.data_in = (int16_t*)p_bfw_iq_src;
547 bfp_com_req.numRBs = 1;
548 bfp_com_req.numDataElements = bfwNumPerRb*2;
549 bfp_com_req.len = bfwNumPerRb*4;
550 bfp_com_req.compMethod = p_ext1->bfwCompMeth;
551 bfp_com_req.iqWidth = p_ext1->bfwIqWidth;
553 print_dbg("req 0x%08p iqWidth %d\n",bfp_com_req.data_in, bfp_com_req.iqWidth);
555 parm_size = 1; /* exponent as part of bfwCompParam 1 octet */
557 case XRAN_BFWCOMPMETHOD_BLKSCALE:
558 rte_panic("XRAN_BFWCOMPMETHOD_BLKSCALE");
561 case XRAN_BFWCOMPMETHOD_ULAW:
562 rte_panic("XRAN_BFWCOMPMETHOD_ULAW");
565 case XRAN_BFWCOMPMETHOD_BEAMSPACE:
566 rte_panic("XRAN_BFWCOMPMETHOD_BEAMSPACE");
569 case XRAN_BFWCOMPMETHOD_NONE:
571 p_bfw_content = (uint8_t *)(p_ext1+1);
572 /* bfwCompParam is absent for no compression case */
576 if(p_bfw_content == NULL) {
577 print_err("Fail to allocate the space for section extension 1");
578 return (XRAN_STATUS_RESOURCE);
581 bfw_iq_bits = bfwNumPerRb* bfwiqWidth * 2;
583 parm_size += bfw_iq_bits>>3;
587 print_dbg("copy BF W %p -> %p size %d \n", p_bfw_iq_src, p_bfw_content, parm_size);
588 if (p_ext1->bfwIqWidth == 0 || p_ext1->bfwIqWidth == 16){
589 memcpy(p_bfw_content, p_bfw_iq_src, parm_size);
591 bfp_com_rsp.data_out = (int8_t*)p_bfw_content;
592 if(xranlib_compress_bfw(&bfp_com_req, &bfp_com_rsp) == 0){
593 comp_len = bfp_com_rsp.len;
594 print_dbg("comp_len %d parm_size %d\n", comp_len, parm_size);
596 print_err("compression failed\n");
597 return (XRAN_STATUS_FAIL);
601 p_bfw_content = (uint8_t *)(p_bfw_content + parm_size);
603 cur_ext_len += parm_size;
604 parm_size = cur_ext_len % XRAN_SECTIONEXT_ALIGN;
606 parm_size = XRAN_SECTIONEXT_ALIGN - parm_size;
607 p_bfw_content = (uint8_t *)(p_bfw_content + parm_size);
608 memcpy(p_bfw_content, zeropad, RTE_MIN(parm_size, sizeof(zeropad)));
609 cur_ext_len += parm_size;
610 print_dbg("zeropad %d cur_ext_len %d\n", parm_size, cur_ext_len);
613 if(cur_ext_len % XRAN_SECTIONEXT_ALIGN)
614 rte_panic("ext1 should be aligned on 4-bytes boundary");
616 p_ext1->extLen = cur_ext_len / XRAN_SECTIONEXT_ALIGN;
617 print_dbg("[%d] %p iq %p p_ext1->extLen %d\n",idxRb, p_ext1, p_ext1+1, p_ext1->extLen);
619 /* update for next RB */
620 p_ext1_dst_cur += cur_ext_len;
621 p_bfw_iq_src = p_bfw_iq_src + bfwNumPerRb*2;
623 total_len += cur_ext_len;
626 print_dbg("total_len %d\n", total_len);
630 // TODO: Need to decide to add calculation or not
631 // Frequency offset 5.4.5.11
632 // frequency_offset = freqOffset * SCS * 0.5
633 // i.e freqOffset = (frequency_offset *2 )/ SCS ?
635 xran_get_freqoffset(int32_t freqOffset, int32_t scs)
641 xran_append_sectionext_1(struct rte_mbuf *mbuf, struct xran_sectionext1_info *params, int32_t last_flag)
643 int32_t total_len = 0;
645 if(params->bfwIQ_sz) {
646 int8_t *p_dst = (int8_t *)rte_pktmbuf_append(mbuf, params->bfwIQ_sz);
649 print_err("Fail to allocate the space for section extension 1 [%d]", params->bfwIQ_sz);
650 return (XRAN_STATUS_RESOURCE);
653 /* extType1 with all the headers created by xran_cp_populate_section_ext_1() earlier */
654 total_len = params->bfwIQ_sz;
661 xran_prepare_sectionext_2(struct rte_mbuf *mbuf, struct xran_sectionext2_info *params, int32_t last_flag)
663 struct xran_cp_radioapp_section_ext2 *ext2;
667 uint32_t val, shift_val;
668 int32_t val_size, pad_size;
672 parm_size = sizeof(struct xran_cp_radioapp_section_ext2);
673 ext2 = (struct xran_cp_radioapp_section_ext2 *)rte_pktmbuf_append(mbuf, parm_size);
675 print_err("Fail to allocate the space for section extension 2");
676 return (XRAN_STATUS_RESOURCE);
678 total_len += parm_size;
680 ext2->extType = XRAN_CP_SECTIONEXTCMD_2;
681 ext2->ef = last_flag;
682 ext2->bfZe3ddWidth = params->bfZe3ddWidth;
683 ext2->bfAz3ddWidth = params->bfAz3ddWidth;
684 ext2->bfZePtWidth = params->bfZePtWidth;
685 ext2->bfAzPtWidth = params->bfAzPtWidth;
686 ext2->bfaCompResv0 = 0;
687 ext2->bfaCompResv1 = 0;
691 if(params->bfAzPtWidth) {
692 val += params->bfAzPt & bitmask[params->bfAzPtWidth];
693 shift_val += 8 - (params->bfAzPtWidth+1);
697 if(params->bfZePtWidth) {
698 val = val << (params->bfZePtWidth+1);
699 val += params->bfZePt & bitmask[params->bfZePtWidth];
700 shift_val += 8 - (params->bfZePtWidth+1);
704 if(params->bfAz3ddWidth) {
705 val = val << (params->bfAz3ddWidth+1);
706 val += params->bfAz3dd & bitmask[params->bfAz3ddWidth];
707 shift_val += 8 - (params->bfAz3ddWidth+1);
711 if(params->bfZe3ddWidth) {
712 val = val << (params->bfZe3ddWidth+1);
713 val += params->bfZe3dd & bitmask[params->bfZe3ddWidth];
714 shift_val += 8 - (params->bfZe3ddWidth+1);
719 val = val << shift_val;
720 val = rte_cpu_to_be_32(val);
723 val_size = 4 - (shift_val/8); /* ceil(total bit/8) */
724 parm_size = val_size + 1; /* additional 1 byte for bfxxSI */
727 total_len += parm_size;
728 pad_size = total_len % XRAN_SECTIONEXT_ALIGN;
730 pad_size = XRAN_SECTIONEXT_ALIGN - pad_size;
731 parm_size += pad_size;
732 total_len += pad_size;
735 data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
737 print_err("Fail to allocate the space for section extension 2");
738 return (XRAN_STATUS_RESOURCE);
741 memcpy(data, &val, val_size);
743 *data = ((params->bfAzSI) << 3) + (params->bfZeSI);
745 memcpy(data, zeropad, pad_size);
747 ext2->extLen = total_len / XRAN_SECTIONEXT_ALIGN;
748 *(uint32_t *)ext2 = rte_cpu_to_be_32(*(uint32_t *)ext2);
754 xran_prepare_sectionext_3(struct rte_mbuf *mbuf, struct xran_sectionext3_info *params, int32_t last_flag)
758 int32_t data_first_byte, data_second_byte;
759 int32_t data_third_byte, data_fourth_byte;
762 if(params->layerId == XRAN_LAYERID_0
763 || params->layerId == XRAN_LAYERID_TXD) { /* first data layer */
765 union xran_cp_radioapp_section_ext3_first *ext3_f;
768 total_len = sizeof(union xran_cp_radioapp_section_ext3_first);
769 ext3_f = (union xran_cp_radioapp_section_ext3_first *)rte_pktmbuf_append(mbuf, total_len);
771 print_err("Fail to allocate the space for section extension 3");
772 return (XRAN_STATUS_RESOURCE);
775 /*ext3_f->data_field.data_field1 = _mm_setzero_si128();
777 ext3_f->all_bits.layerId = params->layerId;
778 ext3_f->all_bits.ef = last_flag;
779 ext3_f->all_bits.extType = XRAN_CP_SECTIONEXTCMD_3;
780 ext3_f->all_bits.crsSymNum = params->crsSymNum;
781 ext3_f->all_bits.crsShift = params->crsShift;
782 ext3_f->all_bits.crsReMask = params->crsReMask;
783 ext3_f->all_bits.txScheme = params->txScheme;
784 ext3_f->all_bits.numLayers = params->numLayers;
785 ext3_f->all_bits.codebookIndex = params->codebookIdx;
787 if(params->numAntPort == 2) {
788 ext3_f->all_bits.beamIdAP3 = params->beamIdAP1;
789 ext3_f->all_bits.extLen = 3;
794 ext3_f->all_bits.beamIdAP3 = params->beamIdAP1;
795 ext3_f->all_bits.beamIdAP2 = params->beamIdAP2;
796 ext3_f->all_bits.beamIdAP1 = params->beamIdAP3;
797 ext3_f->all_bits.extLen = 4;
801 if(params->numAntPort == 2) {
808 data_third_byte = (params->beamIdAP2 << 16) | params->beamIdAP3;
813 data_first_byte = (params->txScheme << xran_cp_radioapp_sec_ext3_TxScheme)
814 | (params->crsReMask << xran_cp_radioapp_sec_ext3_CrcReMask)
815 | (params->crsShift << xran_cp_radioapp_sec_ext3_CrcShift)
816 | (params->crsSymNum << xran_cp_radioapp_sec_ext3_CrcSymNum);
817 data_second_byte = (last_flag << xran_cp_radioapp_sec_ext3_EF)
818 | (XRAN_CP_SECTIONEXTCMD_3 << xran_cp_radioapp_sec_ext3_ExtType)
819 | (extLen << xran_cp_radioapp_sec_ext3_ExtLen)
820 | (params->codebookIdx << xran_cp_radioapp_sec_ext3_CodebookIdx)
821 | (params->layerId << xran_cp_radioapp_sec_ext3_LayerId)
822 | (params->numLayers << xran_cp_radioapp_sec_ext3_NumLayers);
823 data_fourth_byte = params->beamIdAP1;
824 ext3_f->data_field.data_field1 = _mm_set_epi32(data_fourth_byte, data_third_byte, data_second_byte, data_first_byte);
826 /* convert byte order */
827 tmp = (uint64_t *)ext3_f;
828 *tmp = rte_cpu_to_be_64(*tmp); tmp++;
829 *tmp = rte_cpu_to_be_64(*tmp);
832 rte_pktmbuf_trim(mbuf, adj);
834 else { /* non-first data layer */
835 union xran_cp_radioapp_section_ext3_non_first *ext3_nf;
837 total_len = sizeof(union xran_cp_radioapp_section_ext3_non_first);
838 ext3_nf = (union xran_cp_radioapp_section_ext3_non_first *)rte_pktmbuf_append(mbuf, total_len);
839 if(ext3_nf == NULL) {
840 print_err("Fail to allocate the space for section extension 3");
841 return (XRAN_STATUS_RESOURCE);
844 /*ext3_nf->all_bits.layerId = params->layerId;
845 ext3_nf->all_bits.ef = last_flag;
846 ext3_nf->all_bits.extType = XRAN_CP_SECTIONEXTCMD_3;
847 ext3_nf->all_bits.numLayers = params->numLayers;
848 ext3_nf->all_bits.codebookIndex = params->codebookIdx;
850 ext3_nf->all_bits.extLen = sizeof(union xran_cp_radioapp_section_ext3_non_first)/XRAN_SECTIONEXT_ALIGN;*/
852 ext3_nf->data_field = (last_flag << xran_cp_radioapp_sec_ext3_EF)
853 | (XRAN_CP_SECTIONEXTCMD_3 << xran_cp_radioapp_sec_ext3_ExtType)
854 | ((sizeof(union xran_cp_radioapp_section_ext3_non_first)/XRAN_SECTIONEXT_ALIGN) << xran_cp_radioapp_sec_ext3_ExtLen)
855 | (params->codebookIdx << xran_cp_radioapp_sec_ext3_CodebookIdx)
856 | (params->layerId << xran_cp_radioapp_sec_ext3_LayerId)
857 | (params->numLayers << xran_cp_radioapp_sec_ext3_NumLayers);
859 *(uint32_t *)ext3_nf = rte_cpu_to_be_32(*(uint32_t *)ext3_nf);
866 xran_prepare_sectionext_4(struct rte_mbuf *mbuf, struct xran_sectionext4_info *params, int32_t last_flag)
868 struct xran_cp_radioapp_section_ext4 *ext4;
871 parm_size = sizeof(struct xran_cp_radioapp_section_ext4);
872 ext4 = (struct xran_cp_radioapp_section_ext4 *)rte_pktmbuf_append(mbuf, parm_size);
874 print_err("Fail to allocate the space for section extension 4");
875 return(XRAN_STATUS_RESOURCE);
878 ext4->extType = XRAN_CP_SECTIONEXTCMD_4;
879 ext4->ef = last_flag;
880 ext4->modCompScaler = params->modCompScaler;
881 ext4->csf = params->csf?1:0;
882 ext4->extLen = parm_size / XRAN_SECTIONEXT_ALIGN;
884 *(uint32_t *)ext4 = rte_cpu_to_be_32(*(uint32_t*)ext4);
890 xran_prepare_sectionext_5(struct rte_mbuf *mbuf, struct xran_sectionext5_info *params, int32_t last_flag)
892 struct xran_cp_radioapp_section_ext_hdr *ext_hdr;
893 struct xran_cp_radioapp_section_ext5 ext5;
899 if(params->num_sets > XRAN_MAX_MODCOMP_ADDPARMS) {
900 print_err("Exceeds maximum number of parameters(%d). Skipping.", params->num_sets);
904 total_len = sizeof(struct xran_cp_radioapp_section_ext_hdr)
905 + (sizeof(struct xran_cp_radioapp_section_ext5)*params->num_sets)/2
906 - (params->num_sets>>1); // 8bits are added by every two sets, so needs to adjust
909 padding = total_len % XRAN_SECTIONEXT_ALIGN;
911 padding = XRAN_SECTIONEXT_ALIGN - padding;
912 total_len += padding;
915 ext_hdr = (struct xran_cp_radioapp_section_ext_hdr *)rte_pktmbuf_append(mbuf, total_len);
916 if(ext_hdr == NULL) {
917 print_err("Fail to allocate the space for section extension 5");
918 return (XRAN_STATUS_RESOURCE);
921 ext_hdr->extType = XRAN_CP_SECTIONEXTCMD_5;
922 ext_hdr->ef = last_flag;
923 ext_hdr->extLen = total_len / XRAN_SECTIONEXT_ALIGN;
925 *(uint16_t *)ext_hdr = rte_cpu_to_be_16(*((uint16_t *)ext_hdr));
927 data = (uint8_t *)(ext_hdr + 1);
929 while(i < params->num_sets) {
930 if(i%2) { // odd index
931 ext5.mcScaleOffset2 = params->mc[i].mcScaleOffset;
932 ext5.csf2 = params->mc[i].csf;
933 ext5.mcScaleReMask2 = params->mc[i].mcScaleReMask;
937 // adding two sets at once (due to the definition of structure)
938 *((uint64_t *)&ext5) = rte_cpu_to_be_64(*((uint64_t *)&ext5));
939 memcpy(data, &ext5, sizeof(struct xran_cp_radioapp_section_ext5));
940 data += sizeof(struct xran_cp_radioapp_section_ext5);
943 ext5.mcScaleOffset1 = params->mc[i].mcScaleOffset;
944 ext5.csf1 = params->mc[i].csf;
945 ext5.mcScaleReMask1 = params->mc[i].mcScaleReMask;
946 ext5.mcScaleReMask2 = 0;
949 if(i == params->num_sets) { // adding last even index
950 *((uint64_t *)&ext5) = rte_cpu_to_be_64(*((uint64_t *)&ext5));
951 memcpy(data, &ext5, sizeof(struct xran_cp_radioapp_section_ext5)/2);
952 data += sizeof(struct xran_cp_radioapp_section_ext5)/2;
960 memcpy(data, zeropad, padding);
966 xran_prepare_sectionext_6(struct rte_mbuf *mbuf,
967 struct xran_sectionext6_info *params, int32_t last_flag)
969 union xran_cp_radioapp_section_ext6 *ext6;
972 parm_size = sizeof(union xran_cp_radioapp_section_ext6);
973 ext6 = (union xran_cp_radioapp_section_ext6 *)rte_pktmbuf_append(mbuf, parm_size);
975 print_err("Fail to allocate the space for section extension 6");
976 return(XRAN_STATUS_RESOURCE);
979 ext6->data_field.data_field1 = 0x0LL;
980 ext6->all_bits.extType = XRAN_CP_SECTIONEXTCMD_6;
981 ext6->all_bits.ef = last_flag;
982 ext6->all_bits.rbgSize = params->rbgSize;
983 ext6->all_bits.rbgMask = params->rbgMask;
984 ext6->all_bits.symbolMask = params->symbolMask;
985 ext6->all_bits.extLen = parm_size / XRAN_SECTIONEXT_ALIGN;
986 //ext6->reserved0 = 0;
987 //ext6->reserved1 = 0;
989 *(uint64_t *)ext6 = rte_cpu_to_be_64(*(uint64_t*)ext6);
995 xran_prepare_sectionext_10(struct rte_mbuf *mbuf,
996 struct xran_sectionext10_info *params, int32_t last_flag)
998 union xran_cp_radioapp_section_ext10 *ext10;
1006 #if (XRAN_STRICT_PARM_CHECK)
1007 if(params->beamGrpType != XRAN_BEAMGT_COMMON
1008 && params->beamGrpType != XRAN_BEAMGT_MATRIXIND
1009 && params->beamGrpType != XRAN_BEAMGT_VECTORLIST) {
1010 print_err("Invalid beam group Type - %d\n", params->beamGrpType);
1011 return (XRAN_STATUS_INVALID_PARAM);
1014 /* should be checked since it will be used for the index of array */
1015 if(params->numPortc > XRAN_MAX_NUMPORTC_EXT10) {
1016 print_err("Invalid Number of eAxC in extension 10 - %d\n", params->numPortc);
1017 return (XRAN_STATUS_INVALID_PARAM);
1020 parm_size = sizeof(union xran_cp_radioapp_section_ext10);
1021 ext10 = (union xran_cp_radioapp_section_ext10 *)rte_pktmbuf_append(mbuf, parm_size);
1023 print_err("Fail to allocate the space for section extension 10");
1024 return(XRAN_STATUS_RESOURCE);
1027 ext10->all_bits.extType = XRAN_CP_SECTIONEXTCMD_10;
1028 ext10->all_bits.ef = last_flag;
1029 ext10->all_bits.numPortc = params->numPortc;
1030 ext10->all_bits.beamGroupType = params->beamGrpType;
1031 ext10->all_bits.reserved = 0;
1033 total_len = parm_size;
1035 if(params->beamGrpType == XRAN_BEAMGT_VECTORLIST) {
1036 /* Calculate required size, it needs to be reduced by one byte
1037 * since beam ID starts from reserved field(fourth octet). */
1038 parm_size = params->numPortc * 2 - 1;
1041 padding = (parm_size + total_len) % XRAN_SECTIONEXT_ALIGN;
1043 padding = XRAN_SECTIONEXT_ALIGN - padding;
1044 parm_size += padding;
1047 id_ptr = (uint16_t *)rte_pktmbuf_append(mbuf, parm_size);
1048 if(id_ptr == NULL) {
1049 print_err("Fail to allocate the space for beam IDs in section extension 10");
1050 return(XRAN_STATUS_RESOURCE);
1053 /* Need to advance pointer by one-byte since beam IDs start from fourth octet */
1054 id_ptr = (uint16_t *)(((uint8_t *)id_ptr) - 1);
1056 /* this might not be optimal since the alignment is broken */
1057 for(i = 0; i < params->numPortc; i++)
1058 id_ptr[i] = rte_cpu_to_be_16(params->beamID[i]);
1062 memcpy((uint8_t *)&id_ptr[params->numPortc], zeropad, padding);
1065 total_len += parm_size;
1066 ext10->all_bits.extLen = total_len / XRAN_SECTIONEXT_ALIGN;
1068 ext10->data_field = 0;
1069 ext10->data_field = (XRAN_CP_SECTIONEXTCMD_10 << xran_cp_radioapp_sec_ext10_ExtType)
1070 | (last_flag << xran_cp_radioapp_sec_ext10_EF)
1071 | ((total_len / XRAN_SECTIONEXT_ALIGN) << xran_cp_radioapp_sec_ext10_ExtLen)
1072 | (params->numPortc << xran_cp_radioapp_sec_ext10_NumPortc)
1073 | (params->beamGrpType << xran_cp_radioapp_sec_ext10_BeamGroupType);
1080 * @brief Estimates how many BFW sets can be fit to given MTU size
1082 * @ingroup xran_cp_pkt
1084 * @param numBFW the number of BFW I/Qs
1085 * @param iqWidth the bitwidth of BFW
1086 * @param compMeth Compression method for BFW
1087 * @param mtu MTU size
1090 * the number of maximum set of BFWs on success
1091 * XRAN_STATUS_INVALID_PARAM, if compression method is not supported.
1094 xran_cp_estimate_max_set_bfws(uint8_t numBFWs, uint8_t iqWidth, uint8_t compMeth, uint16_t mtu)
1097 int32_t bfw_bitsize;
1098 int32_t bundle_size;
1100 /* Exclude headers can be present */
1101 avail_len = mtu - ( RTE_PKTMBUF_HEADROOM \
1102 + sizeof(struct xran_ecpri_hdr) \
1103 + sizeof(struct xran_cp_radioapp_common_header) \
1104 + sizeof(struct xran_cp_radioapp_section1) \
1105 + sizeof(union xran_cp_radioapp_section_ext6) \
1106 + sizeof(union xran_cp_radioapp_section_ext10) );
1108 /* Calculate the size of BFWs I/Q in bytes */
1109 bfw_bitsize = numBFWs * iqWidth * 2;
1110 bundle_size = bfw_bitsize>>3;
1111 if(bfw_bitsize%8) bundle_size++;
1113 bundle_size += 2; /* two bytes for Beam ID */
1115 case XRAN_BFWCOMPMETHOD_NONE:
1118 case XRAN_BFWCOMPMETHOD_BLKFLOAT:
1119 bundle_size += 1; /* for bfwCompParam */
1123 print_err("Compression method %d is not supported!", compMeth);
1124 return (XRAN_STATUS_INVALID_PARAM);
1127 return (avail_len / bundle_size);
1130 inline static uint32_t
1131 xran_cp_get_hdroffset_section1(uint32_t exthdr_size)
1135 hdr_len = ( RTE_PKTMBUF_HEADROOM \
1136 + sizeof(struct xran_ecpri_hdr) \
1137 + sizeof(struct xran_cp_radioapp_common_header) \
1138 + sizeof(struct xran_cp_radioapp_section1) \
1144 * @brief Prepare Beam Forming Weights(BFWs) for Section Extension 11
1145 * Copy sets of BFWs to buffer after compression if required.
1147 * @ingroup xran_cp_pkt
1149 * @param numSetBFW the number of set of BFWs
1150 * @param numBFW the number of BFWs in a set
1151 * @param iqWidth the bitwidth of BFW
1152 * @param compMeth Compression method for BFW
1153 * @param bfwIQ the array of BFW I/Q source
1154 * @param dst the pointer of destination buffer (external buffer)
1155 * @param dst_maxlen the maximum length of destination buffer
1156 * need to exclude headroom from MTU
1157 * @param bfwInfo Extension 11 PRB bundle information array.
1158 * BFW size, offset and pointer will be set.
1161 * XRAN_STATUS_SUCCESS on success
1162 * XRAN_STATUS_RESOURCE, if destination memory is not enough to store all BFWs
1164 int32_t xran_cp_prepare_ext11_bfws(uint8_t numSetBFW, uint8_t numBFW,
1165 uint8_t iqWidth, uint8_t compMeth,
1166 uint8_t *dst, int16_t dst_maxlen,
1167 struct xran_ext11_bfw_info bfwInfo[])
1170 int32_t iq_bitsize, iq_size;
1173 uint32_t hdr_offset;
1176 struct xranlib_compress_request bfpComp_req;
1177 struct xranlib_compress_response bfpComp_rsp;
1180 print_err("Invalid destination pointer!");
1181 return (XRAN_STATUS_INVALID_PARAM);
1184 /* Calculate the size of BFWs I/Q in bytes */
1185 iq_bitsize = numBFW * iqWidth * 2;
1186 iq_size = iq_bitsize>>3;
1190 /* Check maximum size */
1191 parm_size = ((compMeth == XRAN_BFWCOMPMETHOD_NONE)?0:1) + 2; /* bfwCompParam + beamID(2) */
1192 total_len = numSetBFW * (parm_size + iq_size);
1194 if(total_len >= dst_maxlen) {
1195 print_err("Exceed maximum length to fit the set of BFWs - (%d/%d)",
1196 total_len, dst_maxlen);
1197 return (XRAN_STATUS_RESOURCE);
1200 hdr_offset = xran_cp_get_hdroffset_section1(sizeof(union xran_cp_radioapp_section_ext11));
1202 /* Copy BFWs to destination buffer */
1203 ptr = dst + hdr_offset + 2;
1205 /* No compression */
1206 case XRAN_BFWCOMPMETHOD_NONE:
1207 for(i = 0; i < numSetBFW; i++) {
1208 *((uint16_t *)ptr) = rte_cpu_to_be_16((bfwInfo[i].beamId & 0x7fff));
1209 memcpy((ptr + 2), bfwInfo[i].pBFWs, iq_size);
1210 ptr += iq_size + 2; /* beam ID + IQ size */
1214 /* currently only supports BFP compression */
1215 case XRAN_BFWCOMPMETHOD_BLKFLOAT:
1216 memset(&bfpComp_req, 0, sizeof(struct xranlib_compress_request));
1217 memset(&bfpComp_rsp, 0, sizeof(struct xranlib_compress_response));
1219 for(i = 0; i < numSetBFW; i++) {
1220 bfpComp_req.numRBs = 1;
1221 bfpComp_req.numDataElements = numBFW*2;
1222 bfpComp_req.len = numBFW*2*2;
1223 bfpComp_req.compMethod = compMeth;
1224 bfpComp_req.iqWidth = iqWidth;
1225 bfpComp_req.data_in = (int16_t *)bfwInfo[i].pBFWs;
1226 bfpComp_rsp.data_out = (int8_t*)(ptr + 2); /* exponent will be stored at first byte */
1228 if(xranlib_compress_bfw(&bfpComp_req, &bfpComp_rsp) == 0) {
1229 print_dbg("comp_len %d iq_size %d\n", bfpComp_rsp.len, iq_size);
1231 print_err("compression failed\n");
1232 return (XRAN_STATUS_FAIL);
1234 /* move exponent, it is stored at first byte of output */
1238 *((uint16_t *)(ptr+1)) = rte_cpu_to_be_16((bfwInfo[i].beamId & 0x7fff));
1244 print_err("Compression method %d is not supported!", compMeth);
1245 return (XRAN_STATUS_INVALID_PARAM);
1248 /* Update the length of extension with padding */
1249 parm_size = (total_len + sizeof(union xran_cp_radioapp_section_ext11))
1250 % XRAN_SECTIONEXT_ALIGN;
1253 parm_size = XRAN_SECTIONEXT_ALIGN - parm_size;
1254 memcpy(ptr, zeropad, parm_size);
1255 total_len += parm_size;
1262 static void free_ext_buf(void *addr, void *opaque)
1264 /* free is not required for external buffers */
1268 * extbuf_start : the pointer of the external buffer,
1269 * It can be the start address of whole external buffer.
1270 * extbuf_len : total length of the external buffer (available space to access)
1271 * To use the length of the data, offset2data should be zero.
1273 int32_t xran_cp_attach_ext_buf(struct rte_mbuf *mbuf,
1274 uint8_t *extbuf_start, uint16_t extbuf_len,
1275 struct rte_mbuf_ext_shared_info *shinfo)
1277 rte_iova_t extbuf_iova;
1280 if(unlikely(mbuf == NULL)) {
1281 print_err("Invalid mbuf to attach!\n");
1282 return (XRAN_STATUS_INVALID_PARAM);
1285 /* Update shared information */
1286 shinfo->free_cb = free_ext_buf;
1287 rte_mbuf_ext_refcnt_update(shinfo, 1);
1289 extbuf_iova = rte_malloc_virt2iova(extbuf_start);
1290 if(unlikely(extbuf_iova == RTE_BAD_IOVA)) {
1291 print_err("Failed rte_mem_virt2iova RTE_BAD_IOVA \n");
1292 return (XRAN_STATUS_INVALID_PARAM);
1295 rte_pktmbuf_attach_extbuf(mbuf, extbuf_start, extbuf_iova, extbuf_len, shinfo);
1297 rte_pktmbuf_reset_headroom(mbuf);
1299 return (XRAN_STATUS_SUCCESS);
1304 xran_prepare_sectionext_11(struct rte_mbuf *mbuf,
1305 struct xran_sectionext11_info *params, int32_t last_flag)
1307 union xran_cp_radioapp_section_ext11 *ext11;
1311 #if (XRAN_STRICT_PARM_CHECK)
1312 if(unlikely((params->numSetBFWs == 0)
1313 || (params->numSetBFWs > XRAN_MAX_SET_BFWS))) {
1314 print_err("Invalid number of the set of PRB bundle [%d]", params->numSetBFWs);
1315 return (XRAN_STATUS_INVALID_PARAM);
1319 /* BFWs are already present in the external buffer, just update the length */
1320 total_len = sizeof(union xran_cp_radioapp_section_ext11) + params->totalBfwIQLen;
1322 ext11 = (union xran_cp_radioapp_section_ext11 *)rte_pktmbuf_append(mbuf, total_len);
1324 print_err("Fail to allocate the space for section extension 11 [%d]", total_len);
1325 return (XRAN_STATUS_RESOURCE);
1328 /*ext11->all_bits.extType = XRAN_CP_SECTIONEXTCMD_11;
1329 ext11->all_bits.ef = last_flag;
1330 ext11->all_bits.reserved = 0;
1331 ext11->all_bits.RAD = params->RAD;
1332 ext11->all_bits.disableBFWs = params->disableBFWs;
1333 ext11->all_bits.numBundPrb = params->numBundPrb;
1334 ext11->all_bits.bfwCompMeth = params->bfwCompMeth;
1335 ext11->all_bits.bfwIqWidth = XRAN_CONVERT_BFWIQWIDTH(params->bfwIqWidth);
1337 ext11->all_bits.extLen = total_len / XRAN_SECTIONEXT_ALIGN;*/
1339 ext11->data_field.data_field1 = (last_flag << xran_cp_radioapp_sec_ext11_bitfield_Ef)
1340 | (XRAN_CP_SECTIONEXTCMD_11 << xran_cp_radioapp_sec_ext11_bitfield_ExtType)
1341 | ((total_len / XRAN_SECTIONEXT_ALIGN) << xran_cp_radioapp_sec_ext11_bitfield_ExtLen)
1342 | (params->disableBFWs << xran_cp_radioapp_sec_ext11_bitfield_DisBFWs)
1343 | (params->RAD << xran_cp_radioapp_sec_ext11_bitfield_RAD);
1344 ext11->data_field.data_field2 = ((XRAN_CONVERT_BFWIQWIDTH(params->bfwIqWidth)) << xran_cp_radioapp_sec_ext11_bitfield_BFWIQWidth)
1345 | (params->bfwCompMeth << xran_cp_radioapp_sec_ext11_bitfield_BFWCompMeth)
1346 | params->numBundPrb;
1348 *(uint32_t *)ext11 = rte_cpu_to_be_32(*(uint32_t*)ext11);
1354 * @brief add section extension to C-Plane packet
1357 * A pointer to the packet buffer
1359 * A porinter to the information to generate a C-Plane packet
1361 * XRAN_STATUS_SUCCESS on success
1362 * XRAN_STATUS_INVALID_PARM
1363 * XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
1365 int32_t xran_append_section_extensions(struct rte_mbuf *mbuf, struct xran_section_gen_info *params)
1372 if(unlikely(params->exDataSize > XRAN_MAX_NUM_EXTENSIONS)) {
1373 print_err("Invalid total number of extensions - %d", params->exDataSize);
1374 return (XRAN_STATUS_INVALID_PARAM);
1379 ret = XRAN_STATUS_SUCCESS;
1381 print_dbg("params->exDataSize %d\n", params->exDataSize);
1382 for(i=0; i < params->exDataSize; i++) {
1383 if(params->exData[i].data == NULL) {
1384 print_err("Invalid parameter - extension data %d is NULL", i);
1385 ret = XRAN_STATUS_INVALID_PARAM;
1389 last_flag = (params->exDataSize == (i+1))?0:1;
1391 switch(params->exData[i].type) {
1392 case XRAN_CP_SECTIONEXTCMD_1:
1393 ext_size = xran_append_sectionext_1(mbuf, params->exData[i].data, last_flag);
1395 case XRAN_CP_SECTIONEXTCMD_2:
1396 ext_size = xran_prepare_sectionext_2(mbuf, params->exData[i].data, last_flag);
1398 case XRAN_CP_SECTIONEXTCMD_3:
1399 ext_size = xran_prepare_sectionext_3(mbuf, params->exData[i].data, last_flag);
1401 case XRAN_CP_SECTIONEXTCMD_4:
1402 ext_size = xran_prepare_sectionext_4(mbuf, params->exData[i].data, last_flag);
1404 case XRAN_CP_SECTIONEXTCMD_5:
1405 ext_size = xran_prepare_sectionext_5(mbuf, params->exData[i].data, last_flag);
1407 case XRAN_CP_SECTIONEXTCMD_6:
1408 ext_size = xran_prepare_sectionext_6(mbuf, params->exData[i].data, last_flag);
1410 case XRAN_CP_SECTIONEXTCMD_10:
1411 ext_size = xran_prepare_sectionext_10(mbuf, params->exData[i].data, last_flag);
1413 case XRAN_CP_SECTIONEXTCMD_11:
1414 ext_size = xran_prepare_sectionext_11(mbuf, params->exData[i].data, last_flag);
1417 print_err("Extension Type %d is not supported!", params->exData[i].type);
1418 ret = XRAN_STATUS_INVALID_PARAM;
1422 if(ext_size == XRAN_STATUS_RESOURCE) {
1426 totalen += ext_size;
1434 * @brief Fill the section body of type 0 in C-Plane packet
1437 * A pointer to the section in the packet buffer
1439 * A porinter to the information to generate a C-Plane packet
1441 * XRAN_STATUS_SUCCESS on success
1442 * XRAN_STATUS_INVALID_PARM if the number of symbol is invalid
1445 xran_prepare_section0(struct xran_cp_radioapp_section0 *section, struct xran_section_gen_info *params)
1447 #if (XRAN_STRICT_PARM_CHECK)
1448 if(unlikely(params->info.numSymbol > XRAN_SYMBOLNUMBER_MAX)) {
1449 print_err("Invalid number of Symbols - %d", params->info.numSymbol);
1450 return (XRAN_STATUS_INVALID_PARAM);
1454 section->hdr.u1.common.sectionId = params->info.id;
1455 section->hdr.u1.common.rb = params->info.rb;
1456 section->hdr.u1.common.symInc = params->info.symInc;
1457 section->hdr.u1.common.startPrbc = params->info.startPrbc;
1458 section->hdr.u1.common.numPrbc = XRAN_CONVERT_NUMPRBC(params->info.numPrbc);
1460 section->hdr.u.s0.reMask = params->info.reMask;
1461 section->hdr.u.s0.numSymbol = params->info.numSymbol;
1462 section->hdr.u.s0.reserved = 0;
1464 // for network byte order
1465 *((uint64_t *)section) = rte_cpu_to_be_64(*((uint64_t *)section));
1467 return (XRAN_STATUS_SUCCESS);
1471 * @brief Fill the section header of type 0 in C-Plane packet
1474 * A pointer to the section header in the packet buffer
1476 * A porinter to the information to generate a C-Plane packet
1478 * XRAN_STATUS_SUCCESS always
1481 xran_prepare_section0_hdr( struct xran_cp_radioapp_section0_header *s0hdr,
1482 struct xran_cp_gen_params *params)
1484 s0hdr->timeOffset = rte_cpu_to_be_16(params->hdr.timeOffset);
1485 s0hdr->frameStructure.fftSize = params->hdr.fftSize;
1486 s0hdr->frameStructure.uScs = params->hdr.scs;
1487 s0hdr->cpLength = rte_cpu_to_be_16(params->hdr.cpLength);
1488 s0hdr->reserved = 0;
1490 return (XRAN_STATUS_SUCCESS);
1494 * @brief Fill the section body of type 1 in C-Plane packet
1495 * Extension is not supported.
1498 * A pointer to the section header in the packet buffer
1500 * A porinter to the information to generate a C-Plane packet
1502 * XRAN_STATUS_SUCCESS on success
1503 * XRAN_STATUS_INVALID_PARM if the number of symbol is invalid
1506 xran_prepare_section1(struct xran_cp_radioapp_section1 *section,
1507 struct xran_section_gen_info *params)
1509 #if (XRAN_STRICT_PARM_CHECK)
1510 if(unlikely(params->info.numSymbol > XRAN_SYMBOLNUMBER_MAX)) {
1511 print_err("Invalid number of Symbols - %d", params->info.numSymbol);
1512 return (XRAN_STATUS_INVALID_PARAM);
1516 /*section->hdr.u1.common.sectionId = params->info.id;
1517 section->hdr.u1.common.rb = params->info.rb;
1518 section->hdr.u1.common.symInc = params->info.symInc;
1519 section->hdr.u1.common.startPrbc = params->info.startPrbc;
1520 section->hdr.u1.common.numPrbc = XRAN_CONVERT_NUMPRBC(params->info.numPrbc);
1522 section->hdr.u.s1.reMask = params->info.reMask;
1523 section->hdr.u.s1.numSymbol = params->info.numSymbol;
1524 section->hdr.u.s1.beamId = params->info.beamId;
1525 section->hdr.u.s1.ef = params->info.ef;*/
1527 section->hdr.u.first_4byte = (params->info.reMask << xran_cp_radioapp_sec_hdr_sc_ReMask)
1528 | (params->info.numSymbol << xran_cp_radioapp_sec_hdr_sc_NumSym)
1529 | (params->info.ef << xran_cp_radioapp_sec_hdr_sc_Ef)
1530 | (params->info.beamId << xran_cp_radioapp_sec_hdr_sc_BeamID);
1531 section->hdr.u1.second_4byte = (params->info.id << xran_cp_radioapp_sec_hdr_c_SecId)
1532 | (params->info.rb << xran_cp_radioapp_sec_hdr_c_RB)
1533 | (params->info.symInc << xran_cp_radioapp_sec_hdr_c_SymInc)
1534 | (params->info.startPrbc << xran_cp_radioapp_sec_hdr_c_StartPrbc)
1535 | ((XRAN_CONVERT_NUMPRBC(params->info.numPrbc)) << xran_cp_radioapp_sec_hdr_c_NumPrbc);
1537 // for network byte order
1538 *((uint64_t *)section) = rte_cpu_to_be_64(*((uint64_t *)section));
1540 return (XRAN_STATUS_SUCCESS);
1544 * @brief Fill the section header of type 1 in C-Plane packet
1547 * A pointer to the section header in the packet buffer
1549 * A porinter to the information to generate a C-Plane packet
1551 * XRAN_STATUS_SUCCESS always
1554 xran_prepare_section1_hdr(struct xran_cp_radioapp_section1_header *s1hdr,
1555 struct xran_cp_gen_params *params)
1557 s1hdr->udComp.udIqWidth = params->hdr.iqWidth;
1558 s1hdr->udComp.udCompMeth = params->hdr.compMeth;
1559 s1hdr->reserved = 0;
1561 return (XRAN_STATUS_SUCCESS);
1565 * @brief Fill the section body of type 3 in C-Plane packet
1566 * Extension is not supported.
1569 * A pointer to the section header in the packet buffer
1571 * A porinter to the information to generate a C-Plane packet
1573 * XRAN_STATUS_SUCCESS on success
1574 * XRAN_STATUS_INVALID_PARM if the number of symbol is invalid
1577 xran_prepare_section3(struct xran_cp_radioapp_section3 *section,
1578 struct xran_section_gen_info *params)
1580 #if (XRAN_STRICT_PARM_CHECK)
1581 if(unlikely(params->info.numSymbol > XRAN_SYMBOLNUMBER_MAX)) {
1582 print_err("Invalid number of Symbols - %d", params->info.numSymbol);
1583 return (XRAN_STATUS_INVALID_PARAM);
1587 /*section->hdr.u1.common.sectionId = params->info.id;
1588 section->hdr.u1.common.rb = params->info.rb;
1589 section->hdr.u1.common.symInc = params->info.symInc;
1590 section->hdr.u1.common.startPrbc = params->info.startPrbc;
1591 section->hdr.u1.common.numPrbc = XRAN_CONVERT_NUMPRBC(params->info.numPrbc);
1593 section->hdr.u.s3.reMask = params->info.reMask;
1594 section->hdr.u.s3.numSymbol = params->info.numSymbol;
1595 section->hdr.u.s3.beamId = params->info.beamId;
1596 section->hdr.u.s3.ef = params->info.ef;*/
1598 section->hdr.u.first_4byte = (params->info.reMask << xran_cp_radioapp_sec_hdr_sc_ReMask)
1599 | (params->info.numSymbol << xran_cp_radioapp_sec_hdr_sc_NumSym)
1600 | (params->info.ef << xran_cp_radioapp_sec_hdr_sc_Ef)
1601 | (params->info.beamId << xran_cp_radioapp_sec_hdr_sc_BeamID);
1602 section->hdr.u1.second_4byte = (params->info.id << xran_cp_radioapp_sec_hdr_c_SecId)
1603 | (params->info.rb << xran_cp_radioapp_sec_hdr_c_RB)
1604 | (params->info.symInc << xran_cp_radioapp_sec_hdr_c_SymInc)
1605 | (params->info.startPrbc << xran_cp_radioapp_sec_hdr_c_StartPrbc)
1606 | ((XRAN_CONVERT_NUMPRBC(params->info.numPrbc)) << xran_cp_radioapp_sec_hdr_c_NumPrbc);
1608 section->freqOffset = rte_cpu_to_be_32(params->info.freqOffset)>>8;
1609 section->reserved = 0;
1611 /* for network byte order (header, 8 bytes) */
1612 *((uint64_t *)section) = rte_cpu_to_be_64(*((uint64_t *)section));
1614 return (XRAN_STATUS_SUCCESS);
1618 * @brief Fill the section header of type 3 in C-Plane packet
1621 * A pointer to the section header in the packet buffer
1623 * A porinter to the information to generate a C-Plane packet
1625 * XRAN_STATUS_SUCCESS always
1628 xran_prepare_section3_hdr(struct xran_cp_radioapp_section3_header *s3hdr,
1629 struct xran_cp_gen_params *params)
1631 s3hdr->timeOffset = rte_cpu_to_be_16(params->hdr.timeOffset);
1632 s3hdr->frameStructure.fftSize = params->hdr.fftSize;
1633 s3hdr->frameStructure.uScs = params->hdr.scs;
1634 s3hdr->cpLength = rte_cpu_to_be_16(params->hdr.cpLength);
1635 s3hdr->udComp.udIqWidth = params->hdr.iqWidth;
1636 s3hdr->udComp.udCompMeth = params->hdr.compMeth;
1638 return (XRAN_STATUS_SUCCESS);
1642 * @brief add sections to C-Plane packet
1643 * Section type 1 and 3 are supported.
1646 * A pointer to the packet buffer
1648 * A porinter to the information to generate a C-Plane packet
1650 * XRAN_STATUS_SUCCESS on success
1651 * XRAN_STATUS_INVALID_PARM if section type is not 1 or 3, or handler is NULL
1652 * XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
1655 xran_append_control_section(struct rte_mbuf *mbuf, struct xran_cp_gen_params *params)
1657 int32_t i, ret, ext_flag;
1660 int32_t section_size;
1661 int32_t (*xran_prepare_section_func)(void *section, void *params);
1664 switch(params->sectionType) {
1665 case XRAN_CP_SECTIONTYPE_0: /* Unused RB or Symbols in DL or UL, not supportted */
1666 section_size = sizeof(struct xran_cp_radioapp_section0);
1667 xran_prepare_section_func = (int32_t (*)(void *, void *))xran_prepare_section0;
1670 case XRAN_CP_SECTIONTYPE_1: /* Most DL/UL Radio Channels */
1671 section_size = sizeof(struct xran_cp_radioapp_section1);
1672 xran_prepare_section_func = (int32_t (*)(void *, void *))xran_prepare_section1;
1675 case XRAN_CP_SECTIONTYPE_3: /* PRACH and Mixed-numerology Channels */
1676 section_size = sizeof(struct xran_cp_radioapp_section3);
1677 xran_prepare_section_func = (int32_t (*)(void *, void *))xran_prepare_section3;
1680 case XRAN_CP_SECTIONTYPE_5: /* UE scheduling information, not supported */
1681 case XRAN_CP_SECTIONTYPE_6: /* Channel Information, not supported */
1682 case XRAN_CP_SECTIONTYPE_7: /* LAA, not supported */
1685 xran_prepare_section_func = NULL;
1686 print_err("Section Type %d is not supported!", params->sectionType);
1687 return (XRAN_STATUS_INVALID_PARAM);
1690 if(unlikely(xran_prepare_section_func == NULL)) {
1691 print_err("Section Type %d is not supported!", params->sectionType);
1692 return (XRAN_STATUS_INVALID_PARAM);
1695 for(i=0; i < params->numSections; i++) {
1696 section = rte_pktmbuf_append(mbuf, section_size);
1697 if(section == NULL) {
1698 print_err("Fail to allocate the space for section[%d]!", i);
1699 return (XRAN_STATUS_RESOURCE);
1701 print_dbg("%s %d ef %d\n", __FUNCTION__, i, params->sections[i].info.ef);
1702 ret = xran_prepare_section_func((void *)section,
1703 (void *)¶ms->sections[i]);
1705 print_err("%s %d\n", __FUNCTION__, ret);
1708 totalen += section_size;
1710 if(params->sections[i].info.ef) {
1711 print_dbg("sections[%d].info.ef %d exDataSize %d type %d\n", i, params->sections[i].info.ef,
1712 params->sections[i].exDataSize, params->sections[i].exData[0].type);
1713 ret = xran_append_section_extensions(mbuf, ¶ms->sections[i]);
1724 * @brief fill the information of a radio application header in a C-Plane packet
1727 * A pointer to the application header in the packet buffer
1729 * A porinter to the information to generate a C-Plane packet
1731 * XRAN_STATUS_SUCCESS on success
1732 * XRAN_STATUS_INVALID_PARM if direction, slot index or symbold index is invalid
1734 static inline int32_t
1735 xran_prepare_radioapp_common_header(struct xran_cp_radioapp_common_header *apphdr,
1736 struct xran_cp_gen_params *params)
1739 #if (XRAN_STRICT_PARM_CHECK)
1740 if(unlikely(params->dir != XRAN_DIR_DL && params->dir != XRAN_DIR_UL)) {
1741 print_err("Invalid direction!");
1742 return (XRAN_STATUS_INVALID_PARAM);
1744 if(unlikely(params->hdr.slotId > XRAN_SLOTID_MAX)) {
1745 print_err("Invalid Slot ID!");
1746 return (XRAN_STATUS_INVALID_PARAM);
1748 if(unlikely(params->hdr.startSymId > XRAN_SYMBOLNUMBER_MAX)) {
1749 print_err("Invalid Symbol ID!");
1750 return (XRAN_STATUS_INVALID_PARAM);
1754 /*apphdr->field.all_bits = XRAN_PAYLOAD_VER << 28;
1755 apphdr->field.dataDirection = params->dir;
1756 //apphdr->field.payloadVer = XRAN_PAYLOAD_VER;
1757 apphdr->field.filterIndex = params->hdr.filterIdx;
1758 apphdr->field.frameId = params->hdr.frameId;
1759 apphdr->field.subframeId = params->hdr.subframeId;
1760 apphdr->field.slotId = xran_slotid_convert(params->hdr.slotId, 0);
1761 apphdr->field.startSymbolId = params->hdr.startSymId;*/
1763 apphdr->field.all_bits = (params->dir << xran_cp_radioapp_cmn_hdr_bitwidth_DataDir)
1764 | (XRAN_PAYLOAD_VER << xran_cp_radioapp_cmn_hdr_bitwidth_PayLoadVer)
1765 | (params->hdr.filterIdx << xran_cp_radioapp_cmn_hdr_bitwidth_FilterIdex)
1766 | (params->hdr.frameId << xran_cp_radioapp_cmn_hdr_bitwidth_FrameId)
1767 | (params->hdr.subframeId << xran_cp_radioapp_cmn_hdr_bitwidth_SubFrameId)
1768 | (xran_slotid_convert(params->hdr.slotId, 0) << xran_cp_radioapp_cmn_hdr_bitwidth_SlotId)
1769 | (params->hdr.startSymId << xran_cp_radioapp_cmn_hdr_bitwidth_StartSymId);
1771 apphdr->numOfSections = params->numSections;
1772 apphdr->sectionType = params->sectionType;
1774 /* radio app header has common parts of 4bytes for all section types */
1775 //*((uint32_t *)apphdr) = rte_cpu_to_be_32(*((uint32_t *)apphdr));
1776 *((uint32_t *)apphdr) = rte_cpu_to_be_32(apphdr->field.all_bits);
1777 return (XRAN_STATUS_SUCCESS);
1781 * @brief add a radio application header in a C-Plane packet
1784 * A pointer to the packet buffer
1786 * A porinter to the information to generate a C-Plane packet
1788 * The length of added section (>0) on success
1789 * XRAN_STATUS_INVALID_PARM if section type is invalid, or handler is NULL
1790 * XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
1793 xran_append_radioapp_header(struct rte_mbuf *mbuf, struct xran_cp_gen_params *params)
1797 struct xran_cp_radioapp_common_header *apphdr;
1798 int32_t (*xran_prepare_radioapp_section_hdr_func)(void *hdr, void *params);
1801 #if (XRAN_STRICT_PARM_CHECK)
1802 if(unlikely(params->sectionType >= XRAN_CP_SECTIONTYPE_MAX)) {
1803 print_err("Invalid Section Type - %d", params->sectionType);
1804 return (XRAN_STATUS_INVALID_PARAM);
1808 switch(params->sectionType) {
1809 case XRAN_CP_SECTIONTYPE_0: /* Unused RB or Symbols in DL or UL, not supportted */
1810 xran_prepare_radioapp_section_hdr_func = (int32_t (*)(void *, void*))xran_prepare_section0_hdr;
1811 totalen = sizeof(struct xran_cp_radioapp_section0_header);
1814 case XRAN_CP_SECTIONTYPE_1: /* Most DL/UL Radio Channels */
1815 xran_prepare_radioapp_section_hdr_func = (int32_t (*)(void *, void*))xran_prepare_section1_hdr;
1816 totalen = sizeof(struct xran_cp_radioapp_section1_header);
1819 case XRAN_CP_SECTIONTYPE_3: /* PRACH and Mixed-numerology Channels */
1820 xran_prepare_radioapp_section_hdr_func = (int32_t (*)(void *, void*))xran_prepare_section3_hdr;
1821 totalen = sizeof(struct xran_cp_radioapp_section3_header);
1824 case XRAN_CP_SECTIONTYPE_5: /* UE scheduling information, not supported */
1825 case XRAN_CP_SECTIONTYPE_6: /* Channel Information, not supported */
1826 case XRAN_CP_SECTIONTYPE_7: /* LAA, not supported */
1828 print_err("Section Type %d is not supported!", params->sectionType);
1829 xran_prepare_radioapp_section_hdr_func = NULL;
1831 return (XRAN_STATUS_INVALID_PARAM);
1834 apphdr = (struct xran_cp_radioapp_common_header *)rte_pktmbuf_append(mbuf, totalen);
1835 if(unlikely(apphdr == NULL)) {
1836 print_err("Fail to reserve the space for radio application header!");
1837 return (XRAN_STATUS_RESOURCE);
1840 ret = xran_prepare_radioapp_common_header(apphdr, params);
1841 if(unlikely(ret < 0)) {
1845 if(likely(xran_prepare_radioapp_section_hdr_func)) {
1846 totalen += xran_prepare_radioapp_section_hdr_func(apphdr, params);
1849 print_err("xran_prepare_radioapp_section_hdr_func is NULL!");
1850 return (XRAN_STATUS_INVALID_PARAM);
1857 * @brief Create a C-Plane packet
1858 * Transport layer fragmentation is not supported.
1860 * @ingroup xran_cp_pkt
1863 * A pointer to the packet buffer
1865 * A porinter to the information to generate a C-Plane packet
1867 * Component Carrier ID for this C-Plane message
1869 * Antenna ID(RU Port ID) for this C-Plane message
1871 * Sequence ID for this C-Plane message
1873 * XRAN_STATUS_SUCCESS on success
1874 * XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
1875 * XRAN_STATUS_INVALID_PARM if section type is invalid
1878 xran_prepare_ctrl_pkt(struct rte_mbuf *mbuf,
1879 struct xran_cp_gen_params *params,
1880 uint8_t CC_ID, uint8_t Ant_ID,
1884 uint32_t payloadlen;
1885 struct xran_ecpri_hdr *ecpri_hdr;
1887 payloadlen = xran_build_ecpri_hdr(mbuf, CC_ID, Ant_ID, seq_id, &ecpri_hdr);
1889 ret = xran_append_radioapp_header(mbuf, params);
1891 print_err("%s %d\n", __FUNCTION__, ret);
1896 ret = xran_append_control_section(mbuf, params);
1898 print_err("%s %d\n", __FUNCTION__, ret);
1903 /* set payload length */
1904 ecpri_hdr->cmnhdr.bits.ecpri_payl_size = rte_cpu_to_be_16(payloadlen);
1906 return (XRAN_STATUS_SUCCESS);
1909 ///////////////////////////////////////
1912 xran_parse_section_ext1(void *ext, struct xran_sectionext1_info *extinfo)
1916 struct xran_cp_radioapp_section_ext1 *ext1;
1918 int32_t parm_size, iq_size;
1923 N = xran_get_conf_num_bfweights(pHandle);
1924 extinfo->bfwNumber = N;
1926 ext1 = (struct xran_cp_radioapp_section_ext1 *)ext;
1927 data = (uint8_t *)ext;
1930 total_len = ext1->extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
1932 extinfo->bfwCompMeth = ext1->bfwCompMeth;
1933 extinfo->bfwIqWidth = (ext1->bfwIqWidth==0)?16:ext1->bfwIqWidth;
1935 len += sizeof(struct xran_cp_radioapp_section_ext1);
1936 data += sizeof(struct xran_cp_radioapp_section_ext1);
1938 switch(ext1->bfwCompMeth) {
1939 case XRAN_BFWCOMPMETHOD_NONE:
1943 case XRAN_BFWCOMPMETHOD_BLKFLOAT:
1945 extinfo->bfwCompParam.exponent = *data & 0x0f;
1948 case XRAN_BFWCOMPMETHOD_BLKSCALE:
1950 extinfo->bfwCompParam.blockScaler = *data;
1953 case XRAN_BFWCOMPMETHOD_ULAW:
1955 extinfo->bfwCompParam.compBitWidthShift = *data;
1958 case XRAN_BFWCOMPMETHOD_BEAMSPACE:
1959 parm_size = N>>3; if(N%8) parm_size++; parm_size *= 8;
1960 memcpy(data, extinfo->bfwCompParam.activeBeamspaceCoeffMask, parm_size);
1964 print_err("Invalid BfComp method - %d", ext1->bfwCompMeth);
1971 /* Get BF weights */
1972 iq_size = N * extinfo->bfwIqWidth * 2; // total in bits
1973 parm_size = iq_size>>3; // total in bytes (/8)
1974 if(iq_size%8) parm_size++; // round up
1976 //memcpy(data, extinfo->p_bfwIQ, parm_size);
1977 extinfo->p_bfwIQ = (int16_t*)data;
1981 parm_size = len % XRAN_SECTIONEXT_ALIGN;
1983 len += (XRAN_SECTIONEXT_ALIGN - parm_size);
1985 if(len != total_len) {
1986 // TODO: fix this print_err("The size of extension 1 is not correct! [%d:%d]", len, total_len);
1993 xran_parse_section_ext2(void *ext, struct xran_sectionext2_info *extinfo)
1997 struct xran_cp_radioapp_section_ext2 *ext2;
2003 ext2 = (struct xran_cp_radioapp_section_ext2 *)ext;
2004 data = (uint8_t *)ext;
2005 *(uint32_t *)ext2 = rte_be_to_cpu_32(*(uint32_t *)ext2);
2008 total_len = ext2->extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
2010 parm_size = sizeof(struct xran_cp_radioapp_section_ext2);
2012 extinfo->bfAzPtWidth = ext2->bfAzPtWidth;
2013 extinfo->bfZePtWidth = ext2->bfZePtWidth;
2014 extinfo->bfAz3ddWidth = ext2->bfAz3ddWidth;
2015 extinfo->bfZe3ddWidth = ext2->bfZe3ddWidth;
2017 if(ext2->bfaCompResv0 || ext2->bfaCompResv1)
2018 print_err("Incorrect reserved field - %d, %d", ext2->bfaCompResv0, ext2->bfaCompResv1);
2023 val_size = (extinfo->bfAzPtWidth ? extinfo->bfAzPtWidth+1 : 0)
2024 + (extinfo->bfZePtWidth ? extinfo->bfZePtWidth+1 : 0)
2025 + (extinfo->bfAz3ddWidth ? extinfo->bfAz3ddWidth+1 : 0)
2026 + (extinfo->bfZe3ddWidth ? extinfo->bfZe3ddWidth+ 1: 0);
2028 val = rte_be_to_cpu_32(*(uint32_t *)data);
2029 val >>= (32 - val_size);
2031 if(extinfo->bfZe3ddWidth) {
2032 extinfo->bfZe3dd = val & bitmask[extinfo->bfZe3ddWidth];
2033 val >>= (extinfo->bfZe3ddWidth + 1);
2035 if(extinfo->bfAz3ddWidth) {
2036 extinfo->bfAz3dd = val & bitmask[extinfo->bfAz3ddWidth];
2037 val >>= (extinfo->bfAz3ddWidth + 1);
2039 if(extinfo->bfZePtWidth) {
2040 extinfo->bfZePt = val & bitmask[extinfo->bfZePtWidth];
2041 val >>= (extinfo->bfZePtWidth + 1);
2043 if(extinfo->bfAzPtWidth) {
2044 extinfo->bfAzPt = val & bitmask[extinfo->bfAzPtWidth];
2045 val >>= (extinfo->bfAzPtWidth + 1);
2049 parm_size = val_size/8;
2050 if(val_size%8) parm_size += 1;
2055 extinfo->bfAzSI = (*data >> 3) & 0x07;
2056 extinfo->bfZeSI = *data & 0x07;
2061 parm_size = len % XRAN_SECTIONEXT_ALIGN;
2063 len += (XRAN_SECTIONEXT_ALIGN - parm_size);
2065 if(len != total_len) {
2066 print_err("The size of extension 2 is not correct! [%d:%d]", len, total_len);
2074 xran_parse_section_ext3(void *ext, struct xran_sectionext3_info *extinfo)
2080 len = *((uint8_t *)ext + 1);
2083 case 1: /* non-first data layer */
2085 union xran_cp_radioapp_section_ext3_non_first *ext3_nf;
2087 ext3_nf = (union xran_cp_radioapp_section_ext3_non_first *)ext;
2088 *(uint32_t *)ext3_nf = rte_be_to_cpu_32(*(uint32_t *)ext3_nf);
2090 total_len = ext3_nf->all_bits.extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
2092 extinfo->codebookIdx= ext3_nf->all_bits.codebookIndex;
2093 extinfo->layerId = ext3_nf->all_bits.layerId;
2094 extinfo->numLayers = ext3_nf->all_bits.numLayers;
2098 case 3: /* first data layer with two antenna */
2099 case 4: /* first data layer with four antenna */
2101 union xran_cp_radioapp_section_ext3_first *ext3_f;
2104 ext3_f = (union xran_cp_radioapp_section_ext3_first *)ext;
2105 *(uint64_t *)ext3_f = rte_be_to_cpu_64(*(uint64_t *)ext3_f);
2107 total_len = ext3_f->all_bits.extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
2109 extinfo->codebookIdx= ext3_f->all_bits.codebookIndex;
2110 extinfo->layerId = ext3_f->all_bits.layerId;
2111 extinfo->numLayers = ext3_f->all_bits.numLayers;
2112 extinfo->txScheme = ext3_f->all_bits.txScheme;
2113 extinfo->crsReMask = ext3_f->all_bits.crsReMask;
2114 extinfo->crsShift = ext3_f->all_bits.crsShift;
2115 extinfo->crsSymNum = ext3_f->all_bits.crsSymNum;
2117 /* beam IDs are stored from 10th octet */
2118 beamid = (uint16_t *)((uint8_t *)ext + 10);
2120 extinfo->beamIdAP1 = rte_be_to_cpu_16(*beamid++);
2122 extinfo->beamIdAP2 = rte_be_to_cpu_16(*beamid++);
2123 extinfo->beamIdAP3 = rte_be_to_cpu_16(*beamid);
2124 extinfo->numAntPort = 4;
2127 extinfo->numAntPort = 2;
2133 print_err("Invalid length of extension 3 - %d", len);
2140 xran_parse_section_ext4(void *ext, struct xran_sectionext4_info *extinfo)
2143 struct xran_cp_radioapp_section_ext4 *ext4;
2146 ext4 = (struct xran_cp_radioapp_section_ext4 *)ext;
2148 *(uint32_t *)ext4 = rte_be_to_cpu_32(*(uint32_t *)ext4);
2151 total_len = ext4->extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
2153 extinfo->modCompScaler = ext4->modCompScaler;
2154 extinfo->csf = ext4->csf;
2156 len += sizeof(struct xran_cp_radioapp_section_ext4);
2157 if(len != total_len) {
2158 print_err("The size of extension 4 is not correct! [%d:%d]", len, total_len);
2165 xran_parse_section_ext5(void *ext,
2166 struct xran_sectionext5_info *extinfo)
2169 struct xran_cp_radioapp_section_ext_hdr *ext_hdr;
2170 struct xran_cp_radioapp_section_ext5 ext5;
2176 ext_hdr = (struct xran_cp_radioapp_section_ext_hdr *)ext;
2177 *(uint16_t *)ext_hdr = rte_be_to_cpu_16(*(uint16_t *)ext_hdr);
2179 total_len = ext_hdr->extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
2181 /* one set has 3.5 bytes, so enforcing double to do integer calculation */
2182 parm_size = ((total_len-sizeof(struct xran_cp_radioapp_section_ext_hdr))*2) / 7;
2184 if(parm_size > XRAN_MAX_MODCOMP_ADDPARMS) {
2185 print_err("Exceeds maximum number of parameters - %d", parm_size);
2186 parm_size = XRAN_MAX_MODCOMP_ADDPARMS;
2190 data = (uint8_t *)(ext_hdr + 1);
2193 while(i < parm_size) {
2194 // For odd number set, more data can be copied
2195 *((uint64_t *)&ext5) = rte_be_to_cpu_64(*((uint64_t *)data));
2197 extinfo->mc[i].mcScaleOffset = ext5.mcScaleOffset1;
2198 extinfo->mc[i].csf = ext5.csf1;
2199 extinfo->mc[i].mcScaleReMask = ext5.mcScaleReMask1;
2202 extinfo->mc[i].mcScaleOffset = ext5.mcScaleOffset2;
2203 extinfo->mc[i].csf = ext5.csf2;
2204 extinfo->mc[i].mcScaleReMask = ext5.mcScaleReMask2;
2207 data += sizeof(struct xran_cp_radioapp_section_ext5);
2210 /* check the values of last set
2211 * due to alignment, it cannot be identified by the length that 3 or 4, 11 or 12 and etc
2212 * don't check mcScaleOffset might not be zero (some part is out of zero-padding) */
2214 if(i < XRAN_MAX_MODCOMP_ADDPARMS) {
2215 if(extinfo->mc[i].csf == 0 && extinfo->mc[i].mcScaleReMask == 0)
2216 extinfo->num_sets = i;
2218 extinfo->num_sets = i+1;
2220 print_err("Maximum total number %d is not correct!", i);
2227 xran_parse_section_ext6(void *ext,
2228 struct xran_sectionext6_info *extinfo)
2231 union xran_cp_radioapp_section_ext6 *ext6;
2234 ext6 = (union xran_cp_radioapp_section_ext6 *)ext;
2235 *(uint64_t *)ext6 = rte_be_to_cpu_64(*(uint64_t *)ext6);
2237 total_len = ext6->all_bits.extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
2239 extinfo->rbgSize = ext6->all_bits.rbgSize;
2240 extinfo->rbgMask = ext6->all_bits.rbgMask;
2241 extinfo->symbolMask = ext6->all_bits.symbolMask;
2243 len = sizeof(union xran_cp_radioapp_section_ext6);
2244 if(len != total_len) {
2245 print_err("The size of extension 6 is not correct! [%d:%d]", len, total_len);
2252 xran_parse_section_ext10(void *ext,
2253 struct xran_sectionext10_info *extinfo)
2255 int32_t len, padding;
2257 union xran_cp_radioapp_section_ext10 *ext10;
2261 ext10 = (union xran_cp_radioapp_section_ext10 *)ext;
2263 total_len = ext10->all_bits.extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
2265 extinfo->numPortc = ext10->all_bits.numPortc;
2266 extinfo->beamGrpType= ext10->all_bits.beamGroupType;
2268 len = sizeof(union xran_cp_radioapp_section_ext10);
2269 if(ext10->all_bits.beamGroupType == XRAN_BEAMGT_VECTORLIST) {
2270 len += extinfo->numPortc * 2 - 1;
2271 padding = len % XRAN_SECTIONEXT_ALIGN;
2273 padding = XRAN_SECTIONEXT_ALIGN - padding;
2277 ptr = (uint16_t *)&ext10->all_bits.reserved;
2278 for(i=0; i < extinfo->numPortc; i++)
2279 extinfo->beamID[i] = rte_be_to_cpu_16(ptr[i]);
2282 if(len != total_len) {
2283 print_err("The size of extension 10 is not correct! [%d:%d]", len, total_len);
2290 xran_parse_section_ext11(void *ext,
2291 struct xran_sectionext11_recv_info *extinfo)
2295 union xran_cp_radioapp_section_ext11 *ext11;
2297 int32_t parm_size, iq_size;
2302 N = xran_get_conf_num_bfweights(pHandle);
2304 ext11 = (union xran_cp_radioapp_section_ext11 *)ext;
2305 data = (uint8_t *)ext;
2307 *(uint32_t *)ext11 = rte_cpu_to_be_32(*(uint32_t*)ext11);
2308 total_len = ext11->all_bits.extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
2310 extinfo->RAD = ext11->all_bits.RAD;
2311 extinfo->disableBFWs = ext11->all_bits.disableBFWs;
2312 extinfo->numBundPrb = ext11->all_bits.numBundPrb;
2313 extinfo->bfwCompMeth = ext11->all_bits.bfwCompMeth;
2314 extinfo->bfwIqWidth = (ext11->all_bits.bfwIqWidth==0)?16:ext11->all_bits.bfwIqWidth;
2316 len = sizeof(union xran_cp_radioapp_section_ext11);
2317 data += sizeof(union xran_cp_radioapp_section_ext11);
2319 extinfo->numSetBFWs = 0;
2320 while((len+4) < total_len) { /* adding 4 is to consider zero pads */
2321 /* Get bfwCompParam */
2322 switch(ext11->all_bits.bfwCompMeth) {
2323 case XRAN_BFWCOMPMETHOD_NONE:
2327 case XRAN_BFWCOMPMETHOD_BLKFLOAT:
2329 extinfo->bundInfo[extinfo->numSetBFWs].bfwCompParam.exponent = *data & 0x0f;
2331 #if 0 /* Not supported */
2332 case XRAN_BFWCOMPMETHOD_BLKSCALE:
2334 extinfo->bundInfo[extinfo->numSetBFWs].bfwCompParam.blockScaler = *data;
2337 case XRAN_BFWCOMPMETHOD_ULAW:
2339 extinfo->bundInfo[extinfo->numSetBFWs].bfwCompParam.compBitWidthShift = *data;
2342 case XRAN_BFWCOMPMETHOD_BEAMSPACE:
2343 parm_size = N>>3; if(N%8) parm_size++; parm_size *= 8;
2344 memcpy(data, extinfo->bundInfo[extinfo->numSetBFWs].bfwCompParam.activeBeamspaceCoeffMask, parm_size);
2348 print_err("Invalid BfComp method - %d", ext11->all_bits.bfwCompMeth);
2355 extinfo->bundInfo[extinfo->numSetBFWs].beamId = rte_be_to_cpu_16(*((int16_t *)data));
2356 len += sizeof(int16_t);
2357 data += sizeof(int16_t);
2359 /* Get BF weights */
2360 iq_size = N * extinfo->bfwIqWidth * 2; // total in bits
2361 parm_size = iq_size>>3; // total in bytes (/8)
2362 if(iq_size%8) parm_size++; // round up
2364 if(extinfo->bundInfo[extinfo->numSetBFWs].pBFWs) {
2365 memcpy(extinfo->bundInfo[extinfo->numSetBFWs].pBFWs, data, parm_size);
2367 extinfo->bundInfo[extinfo->numSetBFWs].BFWSize = parm_size;
2371 extinfo->numSetBFWs++;
2374 parm_size = len % XRAN_SECTIONEXT_ALIGN;
2376 len += (XRAN_SECTIONEXT_ALIGN - parm_size);
2378 if(len != total_len) {
2379 print_err("The size of extension 11 is not correct! [%d:%d]", len, total_len);
2386 xran_parse_section_extension(struct rte_mbuf *mbuf,
2388 struct xran_section_recv_info *section)
2390 int32_t total_len, len, numext;
2397 ptr = (uint8_t *)ext;
2405 flag_last = (*ptr & 0x80);
2407 ext_type = *ptr & 0x7f;
2408 section->exts[numext].type = ext_type;
2410 case XRAN_CP_SECTIONEXTCMD_1:
2411 len = xran_parse_section_ext1(ptr, §ion->exts[numext].u.ext1);
2413 case XRAN_CP_SECTIONEXTCMD_2:
2414 len = xran_parse_section_ext2(ptr, §ion->exts[numext].u.ext2);
2416 case XRAN_CP_SECTIONEXTCMD_3:
2417 len = xran_parse_section_ext3(ptr, §ion->exts[numext].u.ext3);
2419 case XRAN_CP_SECTIONEXTCMD_4:
2420 len = xran_parse_section_ext4(ptr, §ion->exts[numext].u.ext4);
2422 case XRAN_CP_SECTIONEXTCMD_5:
2423 len = xran_parse_section_ext5(ptr, §ion->exts[numext].u.ext5);
2425 case XRAN_CP_SECTIONEXTCMD_6:
2426 len = xran_parse_section_ext6(ptr, §ion->exts[numext].u.ext6);
2428 case XRAN_CP_SECTIONEXTCMD_10:
2429 len = xran_parse_section_ext10(ptr, §ion->exts[numext].u.ext10);
2431 case XRAN_CP_SECTIONEXTCMD_11:
2432 len = xran_parse_section_ext11(ptr, §ion->exts[numext].u.ext11);
2436 print_err("Extension %d is not supported!", ext_type);
2440 section->exts[numext].size = len;
2441 ptr += len; total_len += len;
2444 if(++numext < XRAN_MAX_NUM_EXTENSIONS) continue;
2446 /* exceeds maximum number of extensions */
2450 section->numExts = numext;
2456 * @brief Parse a C-Plane packet (for RU emulation)
2457 * Transport layer fragmentation is not supported.
2459 * @ingroup xran_cp_pkt
2462 * The pointer of the packet buffer to be parsed
2464 * The pointer of structure to store the information of parsed packet
2466 * The pointer of sturcture to store the decomposed information of ecpriRtcid/ecpriPcid
2468 * XRAN_STATUS_SUCCESS on success
2469 * XRAN_STATUS_INVALID_PACKET if failed to parse the packet
2472 xran_parse_cp_pkt(struct rte_mbuf *mbuf,
2473 struct xran_cp_recv_params *result,
2474 struct xran_recv_packet_info *pkt_info)
2476 struct xran_ecpri_hdr *ecpri_hdr;
2477 struct xran_cp_radioapp_common_header *apphdr;
2481 ret = xran_parse_ecpri_hdr(mbuf, &ecpri_hdr, pkt_info);
2482 if(ret < 0 && ecpri_hdr == NULL)
2483 return (XRAN_STATUS_INVALID_PACKET);
2485 /* Process radio header. */
2486 apphdr = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_ecpri_hdr));
2487 if(apphdr == NULL) {
2488 print_err("Invalid packet - radio app hedaer!");
2489 return (XRAN_STATUS_INVALID_PACKET);
2492 *((uint32_t *)apphdr) = rte_be_to_cpu_32(*((uint32_t *)apphdr));
2494 if(apphdr->field.payloadVer != XRAN_PAYLOAD_VER) {
2495 print_err("Invalid Payload version - %d", apphdr->field.payloadVer);
2496 ret = XRAN_STATUS_INVALID_PACKET;
2499 result->dir = apphdr->field.dataDirection;
2500 result->hdr.filterIdx = apphdr->field.filterIndex;
2501 result->hdr.frameId = apphdr->field.frameId;
2502 result->hdr.subframeId = apphdr->field.subframeId;
2503 result->hdr.slotId = apphdr->field.slotId;
2504 result->hdr.startSymId = apphdr->field.startSymbolId;
2505 result->sectionType = apphdr->sectionType;
2506 result->numSections = apphdr->numOfSections;
2509 printf("[CP%5d] eAxC[%d:%d:%02d:%02d] %s seq[%03d-%03d-%d] sec[%d-%d] frame[%3d-%2d-%2d] sym%02d\n",
2510 pkt_info->payload_len,
2511 pkt_info->eaxc.cuPortId, pkt_info->eaxc.bandSectorId,
2512 pkt_info->eaxc.ccId, pkt_info->eaxc.ruPortId,
2513 result->dir?"DL":"UL",
2514 pkt_info->seq_id, pkt_info->subseq_id, pkt_info->ebit,
2515 result->sectionType, result->numSections,
2516 result->hdr.frameId, result->hdr.subframeId, result->hdr.slotId,
2517 result->hdr.startSymId
2521 switch(apphdr->sectionType) {
2522 case XRAN_CP_SECTIONTYPE_0: // Unused RB or Symbols in DL or UL, not supportted
2524 struct xran_cp_radioapp_section0_header *hdr;
2525 struct xran_cp_radioapp_section0 *section;
2527 hdr = (struct xran_cp_radioapp_section0_header*)apphdr;
2529 result->hdr.fftSize = rte_be_to_cpu_16(hdr->timeOffset);
2530 result->hdr.scs = hdr->frameStructure.fftSize;
2531 result->hdr.timeOffset = hdr->frameStructure.uScs;
2532 result->hdr.cpLength = rte_be_to_cpu_16(hdr->cpLength);
2533 //hdr->reserved; /* should be zero */
2535 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section0_header));
2536 if(section == NULL) {
2537 print_err("Invalid packet: section type0 - radio app hedaer!");
2538 return (XRAN_STATUS_INVALID_PACKET);
2540 for(i=0; i<result->numSections; i++) {
2541 *((uint64_t *)section) = rte_be_to_cpu_64(*((uint64_t *)section));
2543 result->sections[i].info.type = apphdr->sectionType;
2544 result->sections[i].info.id = section->hdr.u1.common.sectionId;
2545 result->sections[i].info.rb = section->hdr.u1.common.rb;
2546 result->sections[i].info.symInc = section->hdr.u1.common.symInc;
2547 result->sections[i].info.startPrbc = section->hdr.u1.common.startPrbc;
2548 result->sections[i].info.numPrbc = section->hdr.u1.common.numPrbc,
2549 result->sections[i].info.numSymbol = section->hdr.u.s0.numSymbol;
2550 result->sections[i].info.reMask = section->hdr.u.s0.reMask;
2551 //section->hdr.u.s0.reserved; /* should be zero */
2553 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section0));
2554 if(section == NULL) {
2555 print_err("Invalid packet: section type0 - number of section [%d:%d]!",
2556 result->numSections, i);
2557 result->numSections = i;
2558 ret = XRAN_STATUS_INVALID_PACKET;
2565 case XRAN_CP_SECTIONTYPE_1: // Most DL/UL Radio Channels
2567 struct xran_cp_radioapp_section1_header *hdr;
2568 struct xran_cp_radioapp_section1 *section;
2570 hdr = (struct xran_cp_radioapp_section1_header*)apphdr;
2572 result->hdr.iqWidth = hdr->udComp.udIqWidth;
2573 result->hdr.compMeth = hdr->udComp.udCompMeth;
2575 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section1_header));
2576 if(section == NULL) {
2577 print_err("Invalid packet: section type1 - radio app hedaer!");
2578 return (XRAN_STATUS_INVALID_PACKET);
2581 for(i=0; i<result->numSections; i++) {
2582 *((uint64_t *)section) = rte_be_to_cpu_64(*((uint64_t *)section));
2584 result->sections[i].info.type = apphdr->sectionType;
2585 result->sections[i].info.id = section->hdr.u1.common.sectionId;
2586 result->sections[i].info.rb = section->hdr.u1.common.rb;
2587 result->sections[i].info.symInc = section->hdr.u1.common.symInc;
2588 result->sections[i].info.startPrbc = section->hdr.u1.common.startPrbc;
2589 result->sections[i].info.numPrbc = section->hdr.u1.common.numPrbc,
2590 result->sections[i].info.numSymbol = section->hdr.u.s1.numSymbol;
2591 result->sections[i].info.reMask = section->hdr.u.s1.reMask;
2592 result->sections[i].info.beamId = section->hdr.u.s1.beamId;
2593 result->sections[i].info.ef = section->hdr.u.s1.ef;
2595 section = (void *)rte_pktmbuf_adj(mbuf,
2596 sizeof(struct xran_cp_radioapp_section1));
2597 if(section == NULL) {
2598 print_err("Invalid packet: section type1 - number of section [%d:%d]!",
2599 result->numSections, i);
2600 result->numSections = i;
2601 ret = XRAN_STATUS_INVALID_PACKET;
2605 if(result->sections[i].info.ef) {
2606 // parse section extension
2607 extlen = xran_parse_section_extension(mbuf, (void *)section, &result->sections[i]);
2609 section = (void *)rte_pktmbuf_adj(mbuf, extlen);
2610 if(section == NULL) {
2611 print_err("Invalid packet: section type1 - section extension [%d]!", i);
2612 ret = XRAN_STATUS_INVALID_PACKET;
2622 case XRAN_CP_SECTIONTYPE_3: // PRACH and Mixed-numerology Channels
2624 struct xran_cp_radioapp_section3_header *hdr;
2625 struct xran_cp_radioapp_section3 *section;
2627 hdr = (struct xran_cp_radioapp_section3_header*)apphdr;
2629 result->hdr.timeOffset = rte_be_to_cpu_16(hdr->timeOffset);
2630 result->hdr.scs = hdr->frameStructure.uScs;
2631 result->hdr.fftSize = hdr->frameStructure.fftSize;
2632 result->hdr.cpLength = rte_be_to_cpu_16(hdr->cpLength);
2633 result->hdr.iqWidth = hdr->udComp.udIqWidth;
2634 result->hdr.compMeth = hdr->udComp.udCompMeth;
2636 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section3_header));
2637 if(section == NULL) {
2638 print_err("Invalid packet: section type3 - radio app hedaer!");
2639 return (XRAN_STATUS_INVALID_PACKET);
2642 for(i=0; i<result->numSections; i++) {
2643 *((uint64_t *)section) = rte_be_to_cpu_64(*((uint64_t *)section));
2645 result->sections[i].info.type = apphdr->sectionType;
2646 result->sections[i].info.id = section->hdr.u1.common.sectionId;
2647 result->sections[i].info.rb = section->hdr.u1.common.rb;
2648 result->sections[i].info.symInc = section->hdr.u1.common.symInc;
2649 result->sections[i].info.startPrbc = section->hdr.u1.common.startPrbc;
2650 result->sections[i].info.numPrbc = section->hdr.u1.common.numPrbc,
2651 result->sections[i].info.numSymbol = section->hdr.u.s3.numSymbol;
2652 result->sections[i].info.reMask = section->hdr.u.s3.reMask;
2653 result->sections[i].info.beamId = section->hdr.u.s3.beamId;
2654 result->sections[i].info.ef = section->hdr.u.s3.ef;
2655 result->sections[i].info.freqOffset = ((int32_t)rte_be_to_cpu_32(section->freqOffset))>>8;
2657 if(section->reserved) {
2658 print_err("Invalid packet: section type3 - section[%d] reserved[%d]", i, section->reserved);
2659 ret = XRAN_STATUS_INVALID_PACKET;
2662 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section3));
2663 if(section == NULL) {
2664 print_err("Invalid packet: section type3 - number of section [%d:%d]!",
2665 result->numSections, i);
2666 result->numSections = i;
2667 ret = XRAN_STATUS_INVALID_PACKET;
2671 if(result->sections[i].info.ef) {
2672 // parse section extension
2673 extlen = xran_parse_section_extension(mbuf, (void *)section, &result->sections[i]);
2675 section = (void *)rte_pktmbuf_adj(mbuf, extlen);
2676 if(section == NULL) {
2677 print_err("Invalid packet: section type3 - section extension [%d]!", i);
2678 ret = XRAN_STATUS_INVALID_PACKET;
2688 case XRAN_CP_SECTIONTYPE_5: // UE scheduling information, not supported
2689 case XRAN_CP_SECTIONTYPE_6: // Channel Information, not supported
2690 case XRAN_CP_SECTIONTYPE_7: // LAA, not supported
2692 ret = XRAN_STATUS_INVALID_PARAM;
2693 print_err("Non-supported Section Type - %d", apphdr->sectionType);
2697 printf("[CP-%s] [%3d:%2d:%2d] section%d[%d] startSym=%d filterIdx=%X IQwidth=%d CompMeth=%d\n",
2698 result->dir?"DL":"UL",
2699 result->hdr.frameId, result->hdr.subframeId, result->hdr.slotId,
2700 result->sectionType, result->numSections,
2701 result->hdr.startSymId,
2702 result->hdr.filterIdx,
2703 result->hdr.iqWidth, result->hdr.compMeth);
2705 for(i=0; i<result->numSections; i++) {
2706 printf(" || %3d:%04X| rb=%d symInc=%d numSym=%d startPrbc=%02d numPrbc=%d reMask=%03X beamId=%04X freqOffset=%d ef=%d\n",
2707 i, result->sections[i].info.id,
2708 result->sections[i].info.rb,
2709 result->sections[i].info.symInc, result->sections[i].info.numSymbol,
2710 result->sections[i].info.startPrbc, result->sections[i].info.numPrbc,
2711 result->sections[i].info.reMask,
2712 result->sections[i].info.beamId,
2713 result->sections[i].info.freqOffset,
2714 result->sections[i].info.ef);
2716 if(result->sections[i].info.ef) {
2717 for(int32_t j=0; j<result->sections[i].exDataSize; j++) {
2718 printf(" || %2d : type=%d len=%d\n",
2719 j, result->sections[i].exData[j].type, result->sections[i].exData[j].len);
2720 switch(result->sections[i].exData[j].type) {
2721 case XRAN_CP_SECTIONEXTCMD_1:
2723 struct xran_sectionext1_info *ext1;
2724 ext1 = result->sections[i].exData[j].data;
2725 printf(" || bfwNumber=%d bfwIqWidth=%d bfwCompMeth=%d\n",
2726 ext1->bfwNumber, ext1->bfwIqWidth, ext1->bfwCompMeth);
2729 case XRAN_CP_SECTIONEXTCMD_2:
2731 struct xran_sectionext2_info *ext2;
2732 ext2 = result->sections[i].exData[j].data;
2733 printf(" || AzPt=%02x(%d) ZePt=%02x(%d) Az3dd=%02x(%d) Ze3dd=%02x(%d) AzSI=%02x ZeSI=%02x\n",
2734 ext2->bfAzPt, ext2->bfAzPtWidth,
2735 ext2->bfZePt, ext2->bfZePtWidth,
2736 ext2->bfAz3dd, ext2->bfAz3ddWidth,
2737 ext2->bfZe3dd, ext2->bfZe3ddWidth,
2738 ext2->bfAzSI, ext2->bfZeSI);
2741 case XRAN_CP_SECTIONEXTCMD_4:
2743 struct xran_sectionext4_info *ext4;
2744 ext4 = result->sections[i].exData[j].data;
2745 printf(" || csf=%d modCompScaler=%d\n",
2746 ext4->csf, ext4->modCompScaler);
2749 case XRAN_CP_SECTIONEXTCMD_5:
2751 struct xran_sectionext5_info *ext5;
2752 ext5 = result->sections[i].exData[j].data;
2753 printf(" || num_sets=%d\n", ext5->num_sets);
2754 for(int32_t k=0; k<ext5->num_sets; k++) {
2755 printf(" || %d - csf=%d mcScaleReMask=%04x mcScaleOffset=%04x\n",
2757 ext5->mc[k].mcScaleReMask, ext5->mc[k].mcScaleOffset);
2762 case XRAN_CP_SECTIONEXTCMD_0:
2763 case XRAN_CP_SECTIONEXTCMD_3:
2765 printf("Invalid section extension type!\n");