1 /******************************************************************************
3 * Copyright (c) 2019 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
29 #include <rte_branch_prediction.h>
31 #include "xran_common.h"
32 #include "xran_transport.h"
33 #include "xran_cp_api.h"
34 #include "xran_printf.h"
35 #include "xran_compression.h"
39 * This structure to store the section information of C-Plane
40 * in order to generate and parse corresponding U-Plane */
41 struct xran_sectioninfo_db {
42 uint32_t cur_index; /**< Current index to store for this eAXC */
43 struct xran_section_info list[XRAN_MAX_NUM_SECTIONS]; /**< The array of section information */
46 static struct xran_sectioninfo_db sectiondb[XRAN_MAX_SECTIONDB_CTX][XRAN_DIR_MAX][XRAN_COMPONENT_CARRIERS_MAX][XRAN_MAX_ANTENNA_NR*2 + XRAN_MAX_ANT_ARRAY_ELM_NR];
48 static const uint8_t zeropad[XRAN_SECTIONEXT_ALIGN] = { 0, 0, 0, 0 };
49 static const uint8_t bitmask[] = { 0x00, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
53 * @brief Initialize section database.
54 * Allocate required memory space to store section information.
55 * Each eAxC allocates dedicated storage and the entry size is the maximum number of sections.
56 * Total entry size : number of CC * number of antenna * max number of sections * 2(direction)
58 * @ingroup xran_cp_pkt
61 * handle for xRAN interface, currently not being used
63 * XRAN_STATUS_SUCCESS on success
64 * XRAN_STATUS_RESOURCE, if memory is not enough to allocate database area
66 int xran_cp_init_sectiondb(void *pHandle)
68 int ctx, dir, cc, ant;
70 for(ctx=0; ctx < XRAN_MAX_SECTIONDB_CTX; ctx++)
71 for(dir=0; dir < XRAN_DIR_MAX; dir++)
72 for(cc=0; cc < XRAN_COMPONENT_CARRIERS_MAX; cc++)
73 for(ant=0; ant < XRAN_MAX_ANTENNA_NR*2 + XRAN_MAX_ANT_ARRAY_ELM_NR; ant++)
74 sectiondb[ctx][dir][cc][ant].cur_index = 0;
76 return (XRAN_STATUS_SUCCESS);
80 * @brief Release and free section database
82 * @ingroup xran_cp_pkt
85 * handle for xRAN interface, currently not being used
87 * XRAN_STATUS_SUCCESS on success
89 int xran_cp_free_sectiondb(void *pHandle)
91 return (XRAN_STATUS_SUCCESS);
94 static inline struct xran_sectioninfo_db *xran_get_section_db(void *pHandle,
95 uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id)
97 struct xran_sectioninfo_db *ptr;
100 if(unlikely(ctx_id >= XRAN_MAX_SECTIONDB_CTX)) {
101 print_err("Invalid Context id - %d", ctx_id);
105 if(unlikely(dir >= XRAN_DIR_MAX)) {
106 print_err("Invalid direction - %d", dir);
110 if(unlikely(cc_id >= XRAN_COMPONENT_CARRIERS_MAX)) {
111 print_err("Invalid CC id - %d", cc_id);
115 if(unlikely(ruport_id >= XRAN_MAX_ANTENNA_NR*2 + XRAN_MAX_ANT_ARRAY_ELM_NR)) {
116 print_err("Invalid eAxC id - %d", ruport_id);
120 ptr = §iondb[ctx_id][dir][cc_id][ruport_id];
125 static inline struct xran_section_info *xran_get_section_info(struct xran_sectioninfo_db *ptr, uint16_t index)
127 if(unlikely(ptr == NULL))
130 if(unlikely(index > XRAN_MAX_NUM_SECTIONS)) {
131 print_err("Index is out of range - %d", index);
135 return(&(ptr->list[index]));
139 * @brief Add a section information of C-Plane to dabase.
141 * @ingroup xran_cp_pkt
144 * handle for xRAN interface, currently not being used
146 * Direction of C-Plane message for the section to store
148 * CC ID of C-Plane message for the section to store
150 * RU port ID of C-Plane message for the section to store
152 * Context index for the section database
154 * The information of this section to store
156 * XRAN_STATUS_SUCCESS on success
157 * XRAN_STATUS_INVALID_PARAM, if direction, CC ID or RU port ID is incorrect
158 * XRAN_STATUS_RESOURCE, if no more space to add on database
160 int xran_cp_add_section_info(void *pHandle,
161 uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id,
162 struct xran_section_info *info)
164 struct xran_sectioninfo_db *ptr;
165 struct xran_section_info *list;
168 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
169 if(unlikely(ptr == NULL)) {
170 return (XRAN_STATUS_INVALID_PARAM);
173 if(unlikely(ptr->cur_index >= XRAN_MAX_NUM_SECTIONS)) {
174 print_err("No more space to add section information!");
175 return (XRAN_STATUS_RESOURCE);
178 list = xran_get_section_info(ptr, ptr->cur_index);
180 rte_memcpy(list, info, sizeof(struct xran_section_info));
184 return (XRAN_STATUS_SUCCESS);
187 int xran_cp_add_multisection_info(void *pHandle,
188 uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id,
189 struct xran_cp_gen_params *gen_info)
192 uint8_t dir, num_sections;
193 struct xran_sectioninfo_db *ptr;
194 struct xran_section_info *list;
198 num_sections = gen_info->numSections;
200 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
201 if(unlikely(ptr == NULL)) {
202 return (XRAN_STATUS_INVALID_PARAM);
205 if(unlikely(ptr->cur_index+num_sections >= XRAN_MAX_NUM_SECTIONS)) {
206 print_err("No more space to add section information!");
207 return (XRAN_STATUS_RESOURCE);
210 list = xran_get_section_info(ptr, ptr->cur_index);
212 for(i=0; i<num_sections; i++) {
213 rte_memcpy(&list[i], &gen_info->sections[i].info, sizeof(struct xran_section_info));
217 return (XRAN_STATUS_SUCCESS);
221 * @brief Find a section information of C-Plane from dabase
222 * by given information
224 * @ingroup xran_cp_pkt
227 * handle for xRAN interface, currently not being used
229 * The direction of the section to find
231 * The CC ID of the section to find
233 * RU port ID of the section to find
235 * Context index for the section database
237 * The ID of section to find
239 * The pointer of section information if matched section is found
240 * NULL if failed to find matched section
242 struct xran_section_info *xran_cp_find_section_info(void *pHandle,
243 uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
244 uint8_t ctx_id, uint16_t section_id)
246 int index, num_index;
247 struct xran_sectioninfo_db *ptr;
250 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
251 if(unlikely(ptr == NULL))
254 if(ptr->cur_index > XRAN_MAX_NUM_SECTIONS)
255 num_index = XRAN_MAX_NUM_SECTIONS;
257 num_index = ptr->cur_index;
259 for(index=0; index < num_index; index++) {
260 if(ptr->list[index].id == section_id) {
261 return (xran_get_section_info(ptr, index));
265 print_dbg("No section ID in the list - %d", section_id);
270 * @brief Iterate each section information of C-Plane
271 * from the database of eAxC by given information
273 * @ingroup xran_cp_pkt
276 * handle for xRAN interface, currently not being used
278 * The direction of the section to find
280 * The CC ID of the section to find
282 * RU port ID of the section to find
284 * Context index for the section database
286 * The pointer to store the position of next entry
288 * The pointer of section information in the list
289 * NULL if reached at the end of the list
291 struct xran_section_info *xran_cp_iterate_section_info(void *pHandle,
292 uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
293 uint8_t ctx_id, uint32_t *next)
296 struct xran_sectioninfo_db *ptr;
299 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
300 if(unlikely(ptr == NULL))
304 if(*next < ptr->cur_index) {
306 return (xran_get_section_info(ptr, index));
309 print_dbg("No more sections in the list");
315 * @brief Get the size of stored entries
316 * for the database of eAxC by given information
318 * @ingroup xran_cp_pkt
321 * handle for xRAN interface, currently not being used
323 * The direction of the section to find
325 * The CC ID of the section to find
327 * RU port ID of the section to find
329 * Context index for the section database
331 * The size of stored entries
332 * -1 if failed to find matched database
334 int32_t xran_cp_getsize_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id)
337 struct xran_sectioninfo_db *ptr;
340 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
341 if(unlikely(ptr == NULL))
344 return (ptr->cur_index);
348 * @brief Reset a database of eAxC by given information
350 * @ingroup xran_cp_pkt
353 * handle for xRAN interface, currently not being used
355 * The direction of the section to find
357 * The CC ID of the section to find
359 * RU port ID of the section to find
361 * Context index for the section database
363 * XRAN_STATUS_SUCCESS on success
364 * XRAN_STATUS_INVALID_PARM if failed to find matched database
366 int xran_cp_reset_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id)
368 struct xran_sectioninfo_db *ptr;
370 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
371 if(unlikely(ptr == NULL)) {
372 return (XRAN_STATUS_INVALID_PARAM);
377 return (XRAN_STATUS_SUCCESS);
381 int xran_dump_sectiondb(void)
387 int32_t xran_cp_populate_section_ext_1(int8_t *p_ext1_dst, /**< destination buffer */
388 uint16_t ext1_dst_len, /**< dest buffer size */
389 int16_t *p_bfw_iq_src, /**< source buffer of IQs */
390 uint16_t rbNum, /* number RBs to ext1 chain */
391 uint16_t bfwNumPerRb, /* number of bf weights per RB (i.e. antenna elements) */
392 uint8_t bfwiqWidth, /* bit size of IQs */
393 uint8_t bfwCompMeth) /* compression method */
395 struct xran_cp_radioapp_section_ext1 *p_ext1;
397 uint8_t *p_bfw_content = NULL;
398 int32_t parm_size = 0;
399 int32_t bfw_iq_bits = 0;
400 int32_t total_len = 0;
401 int32_t comp_len = 0;
402 uint8_t ext_flag = XRAN_EF_F_ANOTHER_ONE;
404 int16_t cur_ext_len = 0;
405 int8_t *p_ext1_dst_cur = NULL;
407 struct xranlib_compress_request bfp_com_req;
408 struct xranlib_compress_response bfp_com_rsp;
410 memset(&bfp_com_req, 0, sizeof(struct xranlib_compress_request));
411 memset(&bfp_com_rsp, 0, sizeof(struct xranlib_compress_response));
413 print_dbg("%s comp %d\n", __FUNCTION__, bfwCompMeth);
414 print_dbg("bfwNumPerRb %d bfwiqWidth %d\n", bfwNumPerRb, bfwiqWidth);
417 p_ext1_dst_cur = p_ext1_dst;
419 return (XRAN_STATUS_INVALID_PARAM);
421 /* create extType=1 section for each RB */
422 for (idxRb = 0; idxRb < rbNum; idxRb++) {
423 print_dbg("%s RB %d\n", __FUNCTION__, idxRb);
425 if(total_len >= ext1_dst_len){
426 print_err("p_ext1_dst overflow\n");
430 cur_ext_len = 0; /** populate one extType=1 section with BFW for 1 RB */
431 parm_size = sizeof(struct xran_cp_radioapp_section_ext1);
432 p_ext1 = (struct xran_cp_radioapp_section_ext1 *)p_ext1_dst_cur;
434 print_err("p_ext1 is null!\n");
435 return (XRAN_STATUS_INVALID_PARAM);
438 cur_ext_len += parm_size;
441 ext_flag = XRAN_EF_F_LAST;
443 p_ext1->extType = XRAN_CP_SECTIONEXTCMD_1;
444 p_ext1->ef = ext_flag;
445 p_ext1->bfwCompMeth = bfwCompMeth;
446 p_ext1->bfwIqWidth = XRAN_CONVERT_BFWIQWIDTH(bfwiqWidth);
448 switch(bfwCompMeth) {
449 case XRAN_BFWCOMPMETHOD_BLKFLOAT:
450 p_bfw_content = (uint8_t *)(p_ext1+1);
451 if(p_bfw_content == NULL) {
452 print_err("Fail to allocate the space for section extension 1");
453 return (XRAN_STATUS_RESOURCE);
455 bfp_com_req.data_in = (int16_t*)p_bfw_iq_src;
456 bfp_com_req.numRBs = 1;
457 bfp_com_req.numDataElements = bfwNumPerRb*2;
458 bfp_com_req.len = bfwNumPerRb*4;
459 bfp_com_req.compMethod = p_ext1->bfwCompMeth;
460 bfp_com_req.iqWidth = p_ext1->bfwIqWidth;
462 print_dbg("req 0x%08p iqWidth %d\n",bfp_com_req.data_in, bfp_com_req.iqWidth);
464 parm_size = 1; /* exponent as part of bfwCompParam 1 octet */
466 case XRAN_BFWCOMPMETHOD_BLKSCALE:
467 rte_panic("XRAN_BFWCOMPMETHOD_BLKSCALE");
470 case XRAN_BFWCOMPMETHOD_ULAW:
471 rte_panic("XRAN_BFWCOMPMETHOD_BLKSCALE");
474 case XRAN_BFWCOMPMETHOD_BEAMSPACE:
475 rte_panic("XRAN_BFWCOMPMETHOD_BLKSCALE");
478 case XRAN_BFWCOMPMETHOD_NONE:
480 p_bfw_content = (uint8_t *)(p_ext1+1);
481 /* bfwCompParam is absent for no compression case */
485 if(p_bfw_content == NULL) {
486 print_err("Fail to allocate the space for section extension 1");
487 return (XRAN_STATUS_RESOURCE);
490 bfw_iq_bits = bfwNumPerRb* bfwiqWidth * 2;
492 parm_size += bfw_iq_bits>>3;
496 print_dbg("copy BF W %p -> %p size %d \n", p_bfw_iq_src, p_bfw_content, parm_size);
497 if (p_ext1->bfwIqWidth == 0 || p_ext1->bfwIqWidth == 16){
498 rte_memcpy(p_bfw_content, p_bfw_iq_src, parm_size);
500 bfp_com_rsp.data_out = (int8_t*)p_bfw_content;
501 if(xranlib_compress_avx512_bfw(&bfp_com_req, &bfp_com_rsp) == 0){
502 comp_len = bfp_com_rsp.len;
503 print_dbg("comp_len %d parm_size %d\n", comp_len, parm_size);
505 print_err("compression failed\n");
506 return (XRAN_STATUS_FAIL);
510 p_bfw_content = (uint8_t *)(p_bfw_content + parm_size);
512 cur_ext_len += parm_size;
513 parm_size = cur_ext_len % XRAN_SECTIONEXT_ALIGN;
515 parm_size = XRAN_SECTIONEXT_ALIGN - parm_size;
516 p_bfw_content = (uint8_t *)(p_bfw_content + parm_size);
517 rte_memcpy(p_bfw_content, zeropad, parm_size);
518 cur_ext_len += parm_size;
519 print_dbg("zeropad %d cur_ext_len %d\n", parm_size, cur_ext_len);
522 if(cur_ext_len % XRAN_SECTIONEXT_ALIGN)
523 rte_panic("ext1 should be aligned on 4-bytes boundary");
525 p_ext1->extLen = cur_ext_len / XRAN_SECTIONEXT_ALIGN;
526 print_dbg("[%d] %p iq %p p_ext1->extLen %d\n",idxRb, p_ext1, p_ext1+1, p_ext1->extLen);
528 /* update for next RB */
529 p_ext1_dst_cur += cur_ext_len;
530 p_bfw_iq_src = p_bfw_iq_src + bfwNumPerRb*2;
532 total_len += cur_ext_len;
535 print_dbg("total_len %d\n", total_len);
540 // Cyclic Prefix Length 5.4.4.14
541 // CP_length = cpLength * Ts, Ts = 1/30.72MHz
542 // i.e cpLength = CP_length / Ts ?
543 #define CPLEN_TS (30720000)
544 inline uint16_t xran_get_cplength(int CP_length)
549 // Frequency offset 5.4.5.11
550 // frequency_offset = freqOffset * SCS * 0.5
551 // i.e freqOffset = (frequency_offset *2 )/ SCS ?
552 inline int32_t xran_get_freqoffset(int32_t freqOffset, int32_t scs)
557 static int xran_append_sectionext_1(struct rte_mbuf *mbuf,
558 struct xran_sectionext1_info *params, int last_flag)
560 int32_t total_len = 0;
562 if(params->bfwIQ_sz) {
563 int8_t *p_dst = (int8_t *)rte_pktmbuf_append(mbuf, params->bfwIQ_sz);
566 print_err("Fail to allocate the space for section extension 1 [%d]", params->bfwIQ_sz);
567 return (XRAN_STATUS_RESOURCE);
570 /* extType1 with all the headers created by xran_cp_populate_section_ext_1() earlier */
571 total_len = params->bfwIQ_sz;
578 static int xran_prepare_sectionext_1(struct rte_mbuf *mbuf,
579 struct xran_sectionext1_info *params, int last_flag)
581 struct xran_cp_radioapp_section_ext1 *ext1;
583 int parm_size, iq_size;
588 print_dbg("%s %d\n", __FUNCTION__, last_flag);
590 parm_size = sizeof(struct xran_cp_radioapp_section_ext1);
591 ext1 = (struct xran_cp_radioapp_section_ext1 *)rte_pktmbuf_append(mbuf, parm_size);
593 print_err("Fail to allocate the space for section extension 1 [%d]", parm_size);
594 return (XRAN_STATUS_RESOURCE);
597 total_len += parm_size;
599 ext1->extType = XRAN_CP_SECTIONEXTCMD_1;
600 ext1->ef = last_flag;
601 ext1->bfwCompMeth = params->bfwCompMeth;
602 ext1->bfwIqWidth = XRAN_CONVERT_BFWIQWIDTH(params->bfwiqWidth);
604 switch(params->bfwCompMeth) {
605 case XRAN_BFWCOMPMETHOD_BLKFLOAT:
607 data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
609 print_err("Fail to allocate the space for section extension 1 [%d]", parm_size);
610 return (XRAN_STATUS_RESOURCE);
612 total_len += parm_size;
613 *data = (params->bfwCompParam.exponent & 0x0f);
616 case XRAN_BFWCOMPMETHOD_BLKSCALE:
618 data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
620 print_err("Fail to allocate the space for section extension 1 [%d]", parm_size);
621 return (XRAN_STATUS_RESOURCE);
623 total_len += parm_size;
624 *data = params->bfwCompParam.blockScaler;
627 case XRAN_BFWCOMPMETHOD_ULAW:
629 data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
631 print_err("Fail to allocate the space for section extension 1 [%d]", parm_size);
632 return (XRAN_STATUS_RESOURCE);
634 total_len += parm_size;
635 *data = params->bfwCompParam.compBitWidthShift;
638 case XRAN_BFWCOMPMETHOD_BEAMSPACE:
639 parm_size = params->bfwNumber>>3;
640 if(params->bfwNumber%8) parm_size++;
642 data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
644 print_err("Fail to allocate the space for section extension 1 [%d]", parm_size);
645 return (XRAN_STATUS_RESOURCE);
647 rte_memcpy(data, params->bfwCompParam.activeBeamspaceCoeffMask, parm_size);
648 total_len += parm_size;
651 case XRAN_BFWCOMPMETHOD_NONE:
656 print_dbg("params->bfwNumber %d params->bfwiqWidth %d\n", params->bfwNumber, params->bfwiqWidth);
658 iq_size = params->bfwNumber * params->bfwiqWidth * 2;
660 parm_size = iq_size>>3;
664 data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
666 print_err("Fail to allocate the space for section extension 1 BF W iq_size: [%d]", parm_size);
667 return (XRAN_STATUS_RESOURCE);
669 rte_memcpy(data, params->p_bfwIQ, parm_size);
671 total_len += parm_size;
672 parm_size = total_len % XRAN_SECTIONEXT_ALIGN;
674 parm_size = XRAN_SECTIONEXT_ALIGN - parm_size;
675 data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
677 print_err("Fail to allocate the space for section extension 1 [%d]", parm_size);
678 return (XRAN_STATUS_RESOURCE);
680 rte_memcpy(data, zeropad, parm_size);
681 total_len += parm_size;
684 ext1->extLen = total_len / XRAN_SECTIONEXT_ALIGN;
689 static int xran_prepare_sectionext_2(struct rte_mbuf *mbuf,
690 struct xran_sectionext2_info *params, int last_flag)
692 struct xran_cp_radioapp_section_ext2 *ext2;
696 uint32_t val, shift_val;
697 int val_size, pad_size;
702 parm_size = sizeof(struct xran_cp_radioapp_section_ext2);
703 ext2 = (struct xran_cp_radioapp_section_ext2 *)rte_pktmbuf_append(mbuf, parm_size);
705 print_err("Fail to allocate the space for section extension 2");
706 return (XRAN_STATUS_RESOURCE);
708 total_len += parm_size;
710 ext2->extType = XRAN_CP_SECTIONEXTCMD_2;
711 ext2->ef = last_flag;
712 ext2->bfZe3ddWidth = params->bfZe3ddWidth;
713 ext2->bfAz3ddWidth = params->bfAz3ddWidth;
714 ext2->bfZePtWidth = params->bfZePtWidth;
715 ext2->bfAzPtWidth = params->bfAzPtWidth;
716 ext2->bfaCompResv0 = 0;
717 ext2->bfaCompResv1 = 0;
721 if(params->bfAzPtWidth) {
722 val += params->bfAzPt & bitmask[params->bfAzPtWidth];
723 shift_val += 8 - (params->bfAzPtWidth+1);
728 if(params->bfZePtWidth) {
729 val = val << (params->bfZePtWidth+1);
730 val += params->bfZePt & bitmask[params->bfZePtWidth];
731 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);
744 if(params->bfZe3ddWidth) {
745 val = val << (params->bfZe3ddWidth+1);
746 val += params->bfZe3dd & bitmask[params->bfZe3ddWidth];
747 shift_val += 8 - (params->bfZe3ddWidth+1);
753 val = val << shift_val;
754 val = rte_cpu_to_be_32(val);
757 val_size = 4 - (shift_val/8); /* ceil(total bit/8) */
758 parm_size = val_size + 1; /* additional 1 byte for bfxxSI */
761 total_len += parm_size;
762 pad_size = total_len % XRAN_SECTIONEXT_ALIGN;
764 pad_size = XRAN_SECTIONEXT_ALIGN - pad_size;
765 parm_size += pad_size;
766 total_len += pad_size;
769 data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
771 print_err("Fail to allocate the space for section extension 2");
772 return (XRAN_STATUS_RESOURCE);
775 rte_memcpy(data, &val, val_size);
777 *data = ((params->bfAzSI) << 3) + (params->bfZeSI);
779 rte_memcpy(data, zeropad, pad_size);
781 ext2->extLen = total_len / XRAN_SECTIONEXT_ALIGN;
782 *(uint32_t *)ext2 = rte_cpu_to_be_32(*(uint32_t *)ext2);
787 static int xran_prepare_sectionext_3(struct rte_mbuf *mbuf,
788 struct xran_sectionext3_info *params, int last_flag)
794 if(params->layerId == XRAN_LAYERID_0
795 || params->layerId == XRAN_LAYERID_TXD) { /* first data layer */
797 struct xran_cp_radioapp_section_ext3_first *ext3_f;
800 total_len = sizeof(struct xran_cp_radioapp_section_ext3_first);
801 ext3_f = (struct 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->layerId = params->layerId;
808 ext3_f->ef = last_flag;
809 ext3_f->extType = XRAN_CP_SECTIONEXTCMD_3;
810 ext3_f->crsSymNum = params->crsSymNum;
811 ext3_f->crsShift = params->crsShift;
812 ext3_f->crsReMask = params->crsReMask;
813 ext3_f->txScheme = params->txScheme;
814 ext3_f->numLayers = params->numLayers;
815 ext3_f->codebookIndex = params->codebookIdx;
817 if(params->numAntPort == 2) {
818 ext3_f->beamIdAP3 = params->beamIdAP1;
819 ext3_f->beamIdAP2 = 0;
820 ext3_f->beamIdAP1 = 0;
826 ext3_f->beamIdAP3 = params->beamIdAP1;
827 ext3_f->beamIdAP2 = params->beamIdAP2;
828 ext3_f->beamIdAP1 = params->beamIdAP3;
832 ext3_f->reserved0 = 0;
833 ext3_f->reserved1 = 0;
834 ext3_f->reserved2 = 0;
836 /* convert byte order */
837 tmp = (uint64_t *)ext3_f;
838 *tmp = rte_cpu_to_be_64(*tmp); tmp++;
839 *tmp = rte_cpu_to_be_64(*tmp);
842 rte_pktmbuf_trim(mbuf, adj);
844 else { /* non-first data layer */
845 struct xran_cp_radioapp_section_ext3_non_first *ext3_nf;
847 total_len = sizeof(struct xran_cp_radioapp_section_ext3_non_first);
848 ext3_nf = (struct xran_cp_radioapp_section_ext3_non_first *)rte_pktmbuf_append(mbuf, total_len);
849 if(ext3_nf == NULL) {
850 print_err("Fail to allocate the space for section extension 3");
851 return (XRAN_STATUS_RESOURCE);
854 ext3_nf->layerId = params->layerId;
855 ext3_nf->ef = last_flag;
856 ext3_nf->extType = XRAN_CP_SECTIONEXTCMD_3;
857 ext3_nf->numLayers = params->numLayers;
858 ext3_nf->codebookIndex = params->codebookIdx;
860 ext3_nf->extLen = sizeof(struct xran_cp_radioapp_section_ext3_non_first)/XRAN_SECTIONEXT_ALIGN;
862 *(uint32_t *)ext3_nf = rte_cpu_to_be_32(*(uint32_t *)ext3_nf);
868 static int xran_prepare_sectionext_4(struct rte_mbuf *mbuf,
869 struct xran_sectionext4_info *params, int last_flag)
871 struct xran_cp_radioapp_section_ext4 *ext4;
879 parm_size = sizeof(struct xran_cp_radioapp_section_ext4);
880 ext4 = (struct xran_cp_radioapp_section_ext4 *)rte_pktmbuf_append(mbuf, parm_size);
882 print_err("Fail to allocate the space for section extension 4");
883 return(XRAN_STATUS_RESOURCE);
886 total_len += parm_size;
888 ext4->extType = XRAN_CP_SECTIONEXTCMD_4;
889 ext4->ef = last_flag;
890 ext4->modCompScaler = params->modCompScaler;
891 ext4->csf = params->csf?1:0;
892 ext4->extLen = total_len / XRAN_SECTIONEXT_ALIGN;
894 *(uint32_t *)ext4 = rte_cpu_to_be_32(*(uint32_t*)ext4);
900 static int xran_prepare_sectionext_5(struct rte_mbuf *mbuf,
901 struct xran_sectionext5_info *params, int last_flag)
903 struct xran_cp_radioapp_section_ext_hdr *ext_hdr;
904 struct xran_cp_radioapp_section_ext5 ext5;
911 if(params->num_sets > XRAN_MAX_MODCOMP_ADDPARMS) {
912 print_err("Exceeds maximum number of parameters(%d). Skipping.", params->num_sets);
916 total_len = sizeof(struct xran_cp_radioapp_section_ext_hdr)
917 + (sizeof(struct xran_cp_radioapp_section_ext5)*params->num_sets)/2
918 - (params->num_sets>>1); // 8bits are added by every two sets, so needs to adjust
921 padding = total_len % XRAN_SECTIONEXT_ALIGN;
923 padding = XRAN_SECTIONEXT_ALIGN - padding;
924 total_len += padding;
927 ext_hdr = (struct xran_cp_radioapp_section_ext_hdr *)rte_pktmbuf_append(mbuf, total_len);
928 if(ext_hdr == NULL) {
929 print_err("Fail to allocate the space for section extension 5");
930 return (XRAN_STATUS_RESOURCE);
933 ext_hdr->extType = XRAN_CP_SECTIONEXTCMD_5;
934 ext_hdr->ef = last_flag;
935 ext_hdr->extLen = total_len / XRAN_SECTIONEXT_ALIGN;
937 *(uint16_t *)ext_hdr = rte_cpu_to_be_16(*((uint16_t *)ext_hdr));
939 data = (uint8_t *)(ext_hdr + 1);
941 while(i < params->num_sets) {
942 if(i%2) { // odd index
943 ext5.mcScaleOffset2 = params->mc[i].mcScaleOffset;
944 ext5.csf2 = params->mc[i].csf;
945 ext5.mcScaleReMask2 = params->mc[i].mcScaleReMask;
949 // adding two sets at once (due to the definition of structure)
950 *((uint64_t *)&ext5) = rte_cpu_to_be_64(*((uint64_t *)&ext5));
951 rte_memcpy(data, &ext5, sizeof(struct xran_cp_radioapp_section_ext5));
952 data += sizeof(struct xran_cp_radioapp_section_ext5);
955 ext5.mcScaleOffset1 = params->mc[i].mcScaleOffset;
956 ext5.csf1 = params->mc[i].csf;
957 ext5.mcScaleReMask1 = params->mc[i].mcScaleReMask;
958 ext5.mcScaleReMask2 = 0;
961 if(i == params->num_sets) { // adding last even index
962 *((uint64_t *)&ext5) = rte_cpu_to_be_64(*((uint64_t *)&ext5));
963 rte_memcpy(data, &ext5, sizeof(struct xran_cp_radioapp_section_ext5)/2);
964 data += sizeof(struct xran_cp_radioapp_section_ext5)/2;
972 rte_memcpy(data, zeropad, padding);
978 * @brief add section extension to C-Plane packet
981 * A pointer to the packet buffer
983 * A porinter to the information to generate a C-Plane packet
985 * XRAN_STATUS_SUCCESS on success
986 * XRAN_STATUS_INVALID_PARM
987 * XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
989 int xran_append_section_extensions(struct rte_mbuf *mbuf, struct xran_section_gen_info *params)
996 if(unlikely(params->exDataSize > XRAN_MAX_NUM_EXTENSIONS)) {
997 print_err("Invalid total number of extensions - %d", params->exDataSize);
998 return (XRAN_STATUS_INVALID_PARAM);
1003 ret = XRAN_STATUS_SUCCESS;
1005 print_dbg("params->exDataSize %d\n", params->exDataSize);
1006 for(i=0; i < params->exDataSize; i++) {
1007 if(params->exData[i].data == NULL) {
1008 print_err("Invalid parameter - extension data %d is NULL", i);
1009 ret = XRAN_STATUS_INVALID_PARAM;
1013 last_flag = (params->exDataSize == (i+1))?0:1;
1015 switch(params->exData[i].type) {
1016 case XRAN_CP_SECTIONEXTCMD_1:
1017 ext_size = xran_append_sectionext_1(mbuf, params->exData[i].data, last_flag);
1019 case XRAN_CP_SECTIONEXTCMD_2:
1020 ext_size = xran_prepare_sectionext_2(mbuf, params->exData[i].data, last_flag);
1022 case XRAN_CP_SECTIONEXTCMD_3:
1023 ext_size = xran_prepare_sectionext_3(mbuf, params->exData[i].data, last_flag);
1025 case XRAN_CP_SECTIONEXTCMD_4:
1026 ext_size = xran_prepare_sectionext_4(mbuf, params->exData[i].data, last_flag);
1028 case XRAN_CP_SECTIONEXTCMD_5:
1029 ext_size = xran_prepare_sectionext_5(mbuf, params->exData[i].data, last_flag);
1032 print_err("Extension Type %d is not supported!", params->exData[i].type);
1033 ret = XRAN_STATUS_INVALID_PARAM;
1037 if(ext_size == XRAN_STATUS_RESOURCE) {
1041 totalen += ext_size;
1049 * @brief Fill the section body of type 0 in C-Plane packet
1052 * A pointer to the section in the packet buffer
1054 * A porinter to the information to generate a C-Plane packet
1056 * XRAN_STATUS_SUCCESS on success
1057 * XRAN_STATUS_INVALID_PARM if the number of symbol is invalid
1059 static int xran_prepare_section0(
1060 struct xran_cp_radioapp_section0 *section,
1061 struct xran_section_gen_info *params)
1063 #if (XRAN_STRICT_PARM_CHECK)
1064 if(unlikely(params->info.numSymbol > XRAN_SYMBOLNUMBER_MAX)) {
1065 print_err("Invalid number of Symbols - %d", params->info.numSymbol);
1066 return (XRAN_STATUS_INVALID_PARAM);
1070 section->hdr.sectionId = params->info.id;
1071 section->hdr.rb = params->info.rb;
1072 section->hdr.symInc = params->info.symInc;
1073 section->hdr.startPrbc = params->info.startPrbc;
1074 section->hdr.numPrbc = XRAN_CONVERT_NUMPRBC(params->info.numPrbc);
1076 section->hdr.u.s0.reMask = params->info.reMask;
1077 section->hdr.u.s0.numSymbol = params->info.numSymbol;
1078 section->hdr.u.s0.reserved = 0;
1080 // for network byte order
1081 *((uint64_t *)section) = rte_cpu_to_be_64(*((uint64_t *)section));
1083 return (XRAN_STATUS_SUCCESS);
1086 * @brief Fill the section header of type 0 in C-Plane packet
1089 * A pointer to the section header in the packet buffer
1091 * A porinter to the information to generate a C-Plane packet
1093 * XRAN_STATUS_SUCCESS always
1095 static int xran_prepare_section0_hdr(
1096 struct xran_cp_radioapp_section0_header *s0hdr,
1097 struct xran_cp_gen_params *params)
1100 s0hdr->timeOffset = rte_cpu_to_be_16(params->hdr.timeOffset);
1101 s0hdr->frameStructure.fftSize = params->hdr.fftSize;
1102 s0hdr->frameStructure.uScs = params->hdr.scs;
1103 s0hdr->cpLength = rte_cpu_to_be_16(params->hdr.cpLength);
1104 s0hdr->reserved = 0;
1106 return (XRAN_STATUS_SUCCESS);
1110 * @brief Fill the section body of type 1 in C-Plane packet
1111 * Extension is not supported.
1114 * A pointer to the section header in the packet buffer
1116 * A porinter to the information to generate a C-Plane packet
1118 * XRAN_STATUS_SUCCESS on success
1119 * XRAN_STATUS_INVALID_PARM if the number of symbol is invalid
1121 static int xran_prepare_section1(
1122 struct xran_cp_radioapp_section1 *section,
1123 struct xran_section_gen_info *params)
1125 #if (XRAN_STRICT_PARM_CHECK)
1126 if(unlikely(params->info.numSymbol > XRAN_SYMBOLNUMBER_MAX)) {
1127 print_err("Invalid number of Symbols - %d", params->info.numSymbol);
1128 return (XRAN_STATUS_INVALID_PARAM);
1132 section->hdr.sectionId = params->info.id;
1133 section->hdr.rb = params->info.rb;
1134 section->hdr.symInc = params->info.symInc;
1135 section->hdr.startPrbc = params->info.startPrbc;
1136 section->hdr.numPrbc = XRAN_CONVERT_NUMPRBC(params->info.numPrbc);
1138 section->hdr.u.s1.reMask = params->info.reMask;
1139 section->hdr.u.s1.numSymbol = params->info.numSymbol;
1140 section->hdr.u.s1.beamId = params->info.beamId;
1142 section->hdr.u.s1.ef = params->info.ef;
1144 // for network byte order
1145 *((uint64_t *)section) = rte_cpu_to_be_64(*((uint64_t *)section));
1147 return (XRAN_STATUS_SUCCESS);
1150 * @brief Fill the section header of type 1 in C-Plane packet
1153 * A pointer to the section header in the packet buffer
1155 * A porinter to the information to generate a C-Plane packet
1157 * XRAN_STATUS_SUCCESS always
1159 static int xran_prepare_section1_hdr(
1160 struct xran_cp_radioapp_section1_header *s1hdr,
1161 struct xran_cp_gen_params *params)
1163 s1hdr->udComp.udIqWidth = params->hdr.iqWidth;
1164 s1hdr->udComp.udCompMeth = params->hdr.compMeth;
1165 s1hdr->reserved = 0;
1167 return (XRAN_STATUS_SUCCESS);
1171 * @brief Fill the section body of type 3 in C-Plane packet
1172 * Extension is not supported.
1175 * A pointer to the section header in the packet buffer
1177 * A porinter to the information to generate a C-Plane packet
1179 * XRAN_STATUS_SUCCESS on success
1180 * XRAN_STATUS_INVALID_PARM if the number of symbol is invalid
1182 static int xran_prepare_section3(
1183 struct xran_cp_radioapp_section3 *section,
1184 struct xran_section_gen_info *params)
1186 #if (XRAN_STRICT_PARM_CHECK)
1187 if(unlikely(params->info.numSymbol > XRAN_SYMBOLNUMBER_MAX)) {
1188 print_err("Invalid number of Symbols - %d", params->info.numSymbol);
1189 return (XRAN_STATUS_INVALID_PARAM);
1193 section->hdr.sectionId = params->info.id;
1194 section->hdr.rb = params->info.rb;
1195 section->hdr.symInc = params->info.symInc;
1196 section->hdr.startPrbc = params->info.startPrbc;
1197 section->hdr.numPrbc = XRAN_CONVERT_NUMPRBC(params->info.numPrbc);
1199 section->hdr.u.s3.reMask = params->info.reMask;
1200 section->hdr.u.s3.numSymbol = params->info.numSymbol;
1201 section->hdr.u.s3.beamId = params->info.beamId;
1203 section->freqOffset = rte_cpu_to_be_32(params->info.freqOffset)>>8;
1204 section->reserved = 0;
1206 section->hdr.u.s3.ef = params->info.ef;
1208 // for network byte order (header, 8 bytes)
1209 *((uint64_t *)section) = rte_cpu_to_be_64(*((uint64_t *)section));
1211 return (XRAN_STATUS_SUCCESS);
1214 * @brief Fill the section header of type 3 in C-Plane packet
1217 * A pointer to the section header in the packet buffer
1219 * A porinter to the information to generate a C-Plane packet
1221 * XRAN_STATUS_SUCCESS always
1223 static int xran_prepare_section3_hdr(
1224 struct xran_cp_radioapp_section3_header *s3hdr,
1225 struct xran_cp_gen_params *params)
1228 s3hdr->timeOffset = rte_cpu_to_be_16(params->hdr.timeOffset);
1229 s3hdr->frameStructure.fftSize = params->hdr.fftSize;
1230 s3hdr->frameStructure.uScs = params->hdr.scs;
1231 s3hdr->cpLength = rte_cpu_to_be_16(params->hdr.cpLength);
1232 s3hdr->udComp.udIqWidth = params->hdr.iqWidth;
1233 s3hdr->udComp.udCompMeth = params->hdr.compMeth;
1235 return (XRAN_STATUS_SUCCESS);
1239 * @brief add sections to C-Plane packet
1240 * Section type 1 and 3 are supported.
1243 * A pointer to the packet buffer
1245 * A porinter to the information to generate a C-Plane packet
1247 * XRAN_STATUS_SUCCESS on success
1248 * XRAN_STATUS_INVALID_PARM if section type is not 1 or 3, or handler is NULL
1249 * XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
1251 int xran_append_control_section(struct rte_mbuf *mbuf, struct xran_cp_gen_params *params)
1253 int i, ret, ext_flag;
1257 int (*xran_prepare_section_func)(void *section, void *params);
1261 switch(params->sectionType) {
1262 case XRAN_CP_SECTIONTYPE_0: /* Unused RB or Symbols in DL or UL, not supportted */
1263 section_size = sizeof(struct xran_cp_radioapp_section0);
1264 xran_prepare_section_func = (int (*)(void *, void *))xran_prepare_section0;
1267 case XRAN_CP_SECTIONTYPE_1: /* Most DL/UL Radio Channels */
1268 section_size = sizeof(struct xran_cp_radioapp_section1);
1269 xran_prepare_section_func = (int (*)(void *, void *))xran_prepare_section1;
1272 case XRAN_CP_SECTIONTYPE_3: /* PRACH and Mixed-numerology Channels */
1273 section_size = sizeof(struct xran_cp_radioapp_section3);
1274 xran_prepare_section_func = (int (*)(void *, void *))xran_prepare_section3;
1277 case XRAN_CP_SECTIONTYPE_5: /* UE scheduling information, not supported */
1278 case XRAN_CP_SECTIONTYPE_6: /* Channel Information, not supported */
1279 case XRAN_CP_SECTIONTYPE_7: /* LAA, not supported */
1282 xran_prepare_section_func = NULL;
1283 print_err("Section Type %d is not supported!", params->sectionType);
1284 return (XRAN_STATUS_INVALID_PARAM);
1287 if(unlikely(xran_prepare_section_func == NULL)) {
1288 print_err("Section Type %d is not supported!", params->sectionType);
1289 return (XRAN_STATUS_INVALID_PARAM);
1292 for(i=0; i < params->numSections; i++) {
1293 section = rte_pktmbuf_append(mbuf, section_size);
1294 if(section == NULL) {
1295 print_err("Fail to allocate the space for section[%d]!", i);
1296 return (XRAN_STATUS_RESOURCE);
1298 print_dbg("%s %d ef %d\n", __FUNCTION__, i, params->sections[i].info.ef);
1299 ret = xran_prepare_section_func((void *)section,
1300 (void *)¶ms->sections[i]);
1302 print_err("%s %d\n", __FUNCTION__, ret);
1305 totalen += section_size;
1307 if(params->sections[i].info.ef) {
1308 print_dbg("sections[%d].info.ef %d exDataSize %d type %d\n", i, params->sections[i].info.ef,
1309 params->sections[i].exDataSize, params->sections[i].exData[0].type);
1310 ret = xran_append_section_extensions(mbuf, ¶ms->sections[i]);
1321 * @brief fill the information of a radio application header in a C-Plane packet
1324 * A pointer to the application header in the packet buffer
1326 * A porinter to the information to generate a C-Plane packet
1328 * XRAN_STATUS_SUCCESS on success
1329 * XRAN_STATUS_INVALID_PARM if direction, slot index or symbold index is invalid
1331 static inline int xran_prepare_radioapp_common_header(
1332 struct xran_cp_radioapp_common_header *apphdr,
1333 struct xran_cp_gen_params *params)
1336 #if (XRAN_STRICT_PARM_CHECK)
1337 if(unlikely(params->dir != XRAN_DIR_DL && params->dir != XRAN_DIR_UL)) {
1338 print_err("Invalid direction!");
1339 return (XRAN_STATUS_INVALID_PARAM);
1341 if(unlikely(params->hdr.slotId > XRAN_SLOTID_MAX)) {
1342 print_err("Invalid Slot ID!");
1343 return (XRAN_STATUS_INVALID_PARAM);
1345 if(unlikely(params->hdr.startSymId > XRAN_SYMBOLNUMBER_MAX)) {
1346 print_err("Invalid Symbol ID!");
1347 return (XRAN_STATUS_INVALID_PARAM);
1351 apphdr->dataDirection = params->dir;
1352 apphdr->payloadVer = XRAN_PAYLOAD_VER;
1353 apphdr->filterIndex = params->hdr.filterIdx;
1354 apphdr->frameId = params->hdr.frameId;
1355 apphdr->subframeId = params->hdr.subframeId;
1356 apphdr->slotId = xran_slotid_convert(params->hdr.slotId, 0);
1357 apphdr->startSymbolId = params->hdr.startSymId;
1358 apphdr->numOfSections = params->numSections;
1359 apphdr->sectionType = params->sectionType;
1361 /* radio app header has common parts of 4bytes for all section types */
1362 *((uint32_t *)apphdr) = rte_cpu_to_be_32(*((uint32_t *)apphdr));
1364 return (XRAN_STATUS_SUCCESS);
1368 * @brief add a radio application header in a C-Plane packet
1371 * A pointer to the packet buffer
1373 * A porinter to the information to generate a C-Plane packet
1375 * The length of added section (>0) on success
1376 * XRAN_STATUS_INVALID_PARM if section type is invalid, or handler is NULL
1377 * XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
1379 int xran_append_radioapp_header(struct rte_mbuf *mbuf, struct xran_cp_gen_params *params)
1383 struct xran_cp_radioapp_common_header *apphdr;
1384 int (*xran_prepare_radioapp_section_hdr_func)(void *hdr, void *params);
1387 #if (XRAN_STRICT_PARM_CHECK)
1388 if(unlikely(params->sectionType >= XRAN_CP_SECTIONTYPE_MAX)) {
1389 print_err("Invalid Section Type - %d", params->sectionType);
1390 return (XRAN_STATUS_INVALID_PARAM);
1394 switch(params->sectionType) {
1395 case XRAN_CP_SECTIONTYPE_0: /* Unused RB or Symbols in DL or UL, not supportted */
1396 xran_prepare_radioapp_section_hdr_func = (int (*)(void *, void*))xran_prepare_section0_hdr;
1397 totalen = sizeof(struct xran_cp_radioapp_section0_header);
1400 case XRAN_CP_SECTIONTYPE_1: /* Most DL/UL Radio Channels */
1401 xran_prepare_radioapp_section_hdr_func = (int (*)(void *, void*))xran_prepare_section1_hdr;
1402 totalen = sizeof(struct xran_cp_radioapp_section1_header);
1405 case XRAN_CP_SECTIONTYPE_3: /* PRACH and Mixed-numerology Channels */
1406 xran_prepare_radioapp_section_hdr_func = (int (*)(void *, void*))xran_prepare_section3_hdr;
1407 totalen = sizeof(struct xran_cp_radioapp_section3_header);
1410 case XRAN_CP_SECTIONTYPE_5: /* UE scheduling information, not supported */
1411 case XRAN_CP_SECTIONTYPE_6: /* Channel Information, not supported */
1412 case XRAN_CP_SECTIONTYPE_7: /* LAA, not supported */
1414 print_err("Section Type %d is not supported!", params->sectionType);
1415 xran_prepare_radioapp_section_hdr_func = NULL;
1417 return (XRAN_STATUS_INVALID_PARAM);
1420 apphdr = (struct xran_cp_radioapp_common_header *)rte_pktmbuf_append(mbuf, totalen);
1421 if(unlikely(apphdr == NULL)) {
1422 print_err("Fail to reserve the space for radio application header!");
1423 return (XRAN_STATUS_RESOURCE);
1426 ret = xran_prepare_radioapp_common_header(apphdr, params);
1427 if(unlikely(ret < 0)) {
1431 if(likely(xran_prepare_radioapp_section_hdr_func)) {
1432 totalen += xran_prepare_radioapp_section_hdr_func(apphdr, params);
1435 print_err("xran_prepare_radioapp_section_hdr_func is NULL!");
1436 return (XRAN_STATUS_INVALID_PARAM);
1443 * @brief Create a C-Plane packet
1444 * Transport layer fragmentation is not supported.
1446 * @ingroup xran_cp_pkt
1449 * A pointer to the packet buffer
1451 * A porinter to the information to generate a C-Plane packet
1453 * Component Carrier ID for this C-Plane message
1455 * Antenna ID(RU Port ID) for this C-Plane message
1457 * Sequence ID for this C-Plane message
1459 * XRAN_STATUS_SUCCESS on success
1460 * XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
1461 * XRAN_STATUS_INVALID_PARM if section type is invalid
1463 int xran_prepare_ctrl_pkt(struct rte_mbuf *mbuf,
1464 struct xran_cp_gen_params *params,
1465 uint8_t CC_ID, uint8_t Ant_ID,
1469 uint32_t payloadlen;
1470 struct xran_ecpri_hdr *ecpri_hdr;
1473 payloadlen = xran_build_ecpri_hdr(mbuf, CC_ID, Ant_ID, seq_id, &ecpri_hdr);
1475 ret = xran_append_radioapp_header(mbuf, params);
1477 print_err("%s %d\n", __FUNCTION__, ret);
1482 ret = xran_append_control_section(mbuf, params);
1484 print_err("%s %d\n", __FUNCTION__, ret);
1489 /* set payload length */
1490 ecpri_hdr->cmnhdr.ecpri_payl_size = rte_cpu_to_be_16(payloadlen);
1492 return (XRAN_STATUS_SUCCESS);
1496 ///////////////////////////////////////
1498 int xran_parse_section_ext1(void *ext,
1499 struct xran_sectionext1_info *extinfo)
1503 struct xran_cp_radioapp_section_ext1 *ext1;
1505 int parm_size, iq_size;
1510 N = xran_get_conf_num_bfweights(pHandle);
1511 extinfo->bfwNumber = N;
1513 ext1 = (struct xran_cp_radioapp_section_ext1 *)ext;
1514 data = (uint8_t *)ext;
1517 total_len = ext1->extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
1519 extinfo->bfwCompMeth = ext1->bfwCompMeth;
1520 extinfo->bfwiqWidth = (ext1->bfwIqWidth==0)?16:ext1->bfwIqWidth;
1522 len += sizeof(struct xran_cp_radioapp_section_ext1);
1523 data += sizeof(struct xran_cp_radioapp_section_ext1);
1525 switch(ext1->bfwCompMeth) {
1526 case XRAN_BFWCOMPMETHOD_NONE:
1530 case XRAN_BFWCOMPMETHOD_BLKFLOAT:
1532 extinfo->bfwCompParam.exponent = *data & 0x0f;
1535 case XRAN_BFWCOMPMETHOD_BLKSCALE:
1537 extinfo->bfwCompParam.blockScaler = *data;
1540 case XRAN_BFWCOMPMETHOD_ULAW:
1542 extinfo->bfwCompParam.compBitWidthShift = *data;
1545 case XRAN_BFWCOMPMETHOD_BEAMSPACE:
1546 parm_size = N>>3; if(N%8) parm_size++; parm_size *= 8;
1547 rte_memcpy(data, extinfo->bfwCompParam.activeBeamspaceCoeffMask, parm_size);
1551 print_err("Invalid BfComp method - %d", ext1->bfwCompMeth);
1558 /* Get BF weights */
1559 iq_size = N * extinfo->bfwiqWidth * 2; // total in bits
1560 parm_size = iq_size>>3; // total in bytes (/8)
1561 if(iq_size%8) parm_size++; // round up
1563 //rte_memcpy(data, extinfo->p_bfwIQ, parm_size);
1564 extinfo->p_bfwIQ = (int16_t*)data;
1568 parm_size = len % XRAN_SECTIONEXT_ALIGN;
1570 len += (XRAN_SECTIONEXT_ALIGN - parm_size);
1572 if(len != total_len) {
1573 // TODO: fix this print_err("The size of extension 1 is not correct! [%d:%d]", len, total_len);
1579 int xran_parse_section_ext2(void *ext,
1580 struct xran_sectionext2_info *extinfo)
1584 struct xran_cp_radioapp_section_ext2 *ext2;
1591 ext2 = (struct xran_cp_radioapp_section_ext2 *)ext;
1592 data = (uint8_t *)ext;
1593 *(uint32_t *)ext2 = rte_be_to_cpu_32(*(uint32_t *)ext2);
1596 total_len = ext2->extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
1598 parm_size = sizeof(struct xran_cp_radioapp_section_ext2);
1600 extinfo->bfAzPtWidth = ext2->bfAzPtWidth;
1601 extinfo->bfZePtWidth = ext2->bfZePtWidth;
1602 extinfo->bfAz3ddWidth = ext2->bfAz3ddWidth;
1603 extinfo->bfZe3ddWidth = ext2->bfZe3ddWidth;
1605 if(ext2->bfaCompResv0 || ext2->bfaCompResv1)
1606 print_err("Incorrect reserved field - %d, %d", ext2->bfaCompResv0, ext2->bfaCompResv1);
1611 val_size = (extinfo->bfAzPtWidth ? extinfo->bfAzPtWidth+1 : 0)
1612 + (extinfo->bfZePtWidth ? extinfo->bfZePtWidth+1 : 0)
1613 + (extinfo->bfAz3ddWidth ? extinfo->bfAz3ddWidth+1 : 0)
1614 + (extinfo->bfZe3ddWidth ? extinfo->bfZe3ddWidth+ 1: 0);
1616 val = rte_be_to_cpu_32(*(uint32_t *)data);
1617 val >>= (32 - val_size);
1619 if(extinfo->bfZe3ddWidth) {
1620 extinfo->bfZe3dd = val & bitmask[extinfo->bfZe3ddWidth];
1621 val >>= (extinfo->bfZe3ddWidth + 1);
1623 if(extinfo->bfAz3ddWidth) {
1624 extinfo->bfAz3dd = val & bitmask[extinfo->bfAz3ddWidth];
1625 val >>= (extinfo->bfAz3ddWidth + 1);
1627 if(extinfo->bfZePtWidth) {
1628 extinfo->bfZePt = val & bitmask[extinfo->bfZePtWidth];
1629 val >>= (extinfo->bfZePtWidth + 1);
1631 if(extinfo->bfAzPtWidth) {
1632 extinfo->bfAzPt = val & bitmask[extinfo->bfAzPtWidth];
1633 val >>= (extinfo->bfAzPtWidth + 1);
1637 parm_size = val_size/8;
1638 if(val_size%8) parm_size += 1;
1643 extinfo->bfAzSI = (*data >> 3) & 0x07;
1644 extinfo->bfZeSI = *data & 0x07;
1649 parm_size = len % XRAN_SECTIONEXT_ALIGN;
1651 len += (XRAN_SECTIONEXT_ALIGN - parm_size);
1653 if(len != total_len) {
1654 print_err("The size of extension 2 is not correct! [%d:%d]", len, total_len);
1661 int xran_parse_section_ext3(void *ext,
1662 struct xran_sectionext3_info *extinfo)
1668 len = *((uint8_t *)ext + 1);
1671 case 1: /* non-first data layer */
1673 struct xran_cp_radioapp_section_ext3_non_first *ext3_nf;
1675 ext3_nf = (struct xran_cp_radioapp_section_ext3_non_first *)ext;
1676 *(uint32_t *)ext3_nf = rte_be_to_cpu_32(*(uint32_t *)ext3_nf);
1678 total_len = ext3_nf->extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
1680 extinfo->codebookIdx= ext3_nf->codebookIndex;
1681 extinfo->layerId = ext3_nf->layerId;
1682 extinfo->numLayers = ext3_nf->numLayers;
1686 case 3: /* first data layer with two antenna */
1687 case 4: /* first data layer with four antenna */
1689 struct xran_cp_radioapp_section_ext3_first *ext3_f;
1692 ext3_f = (struct xran_cp_radioapp_section_ext3_first *)ext;
1693 *(uint64_t *)ext3_f = rte_be_to_cpu_64(*(uint64_t *)ext3_f);
1695 total_len = ext3_f->extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
1697 extinfo->codebookIdx= ext3_f->codebookIndex;
1698 extinfo->layerId = ext3_f->layerId;
1699 extinfo->numLayers = ext3_f->numLayers;
1700 extinfo->txScheme = ext3_f->txScheme;
1701 extinfo->crsReMask = ext3_f->crsReMask;
1702 extinfo->crsShift = ext3_f->crsShift;
1703 extinfo->crsSymNum = ext3_f->crsSymNum;
1705 /* beam IDs are stored from 10th octet */
1706 beamid = (uint16_t *)((uint8_t *)ext + 10);
1708 extinfo->beamIdAP1 = rte_be_to_cpu_16(*beamid++);
1710 extinfo->beamIdAP2 = rte_be_to_cpu_16(*beamid++);
1711 extinfo->beamIdAP3 = rte_be_to_cpu_16(*beamid);
1712 extinfo->numAntPort = 4;
1715 extinfo->numAntPort = 2;
1721 print_err("Invalid length of extension 3 - %d", len);
1727 int xran_parse_section_ext4(void *ext,
1728 struct xran_sectionext4_info *extinfo)
1731 struct xran_cp_radioapp_section_ext4 *ext4;
1735 ext4 = (struct xran_cp_radioapp_section_ext4 *)ext;
1737 *(uint32_t *)ext4 = rte_be_to_cpu_32(*(uint32_t *)ext4);
1740 total_len = ext4->extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
1742 extinfo->modCompScaler = ext4->modCompScaler;
1743 extinfo->csf = ext4->csf;
1745 len += sizeof(struct xran_cp_radioapp_section_ext4);
1746 if(len != total_len) {
1747 print_err("The size of extension 4 is not correct! [%d:%d]", len, total_len);
1753 int xran_parse_section_ext5(void *ext,
1754 struct xran_sectionext5_info *extinfo)
1757 struct xran_cp_radioapp_section_ext_hdr *ext_hdr;
1758 struct xran_cp_radioapp_section_ext5 ext5;
1764 ext_hdr = (struct xran_cp_radioapp_section_ext_hdr *)ext;
1765 *(uint16_t *)ext_hdr = rte_be_to_cpu_16(*(uint16_t *)ext_hdr);
1767 total_len = ext_hdr->extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
1769 /* one set has 3.5 bytes, so enforcing double to do integer calculation */
1770 parm_size = ((total_len-sizeof(struct xran_cp_radioapp_section_ext_hdr))*2) / 7;
1772 if(parm_size > XRAN_MAX_MODCOMP_ADDPARMS) {
1773 print_err("Exceeds maximum number of parameters - %d", parm_size);
1774 parm_size = XRAN_MAX_MODCOMP_ADDPARMS;
1778 data = (uint8_t *)(ext_hdr + 1);
1781 while(i < parm_size) {
1782 // For odd number set, more data can be copied
1783 *((uint64_t *)&ext5) = rte_be_to_cpu_64(*((uint64_t *)data));
1785 extinfo->mc[i].mcScaleOffset = ext5.mcScaleOffset1;
1786 extinfo->mc[i].csf = ext5.csf1;
1787 extinfo->mc[i].mcScaleReMask = ext5.mcScaleReMask1;
1790 extinfo->mc[i].mcScaleOffset = ext5.mcScaleOffset2;
1791 extinfo->mc[i].csf = ext5.csf2;
1792 extinfo->mc[i].mcScaleReMask = ext5.mcScaleReMask2;
1795 data += sizeof(struct xran_cp_radioapp_section_ext5);
1798 /* check the values of last set
1799 * due to alignment, it cannot be identified by the length that 3 or 4, 11 or 12 and etc
1800 * don't check mcScaleOffset might not be zero (some part is out of zero-padding) */
1802 if(i < XRAN_MAX_MODCOMP_ADDPARMS) {
1803 if(extinfo->mc[i].csf == 0 && extinfo->mc[i].mcScaleReMask == 0)
1804 extinfo->num_sets = i;
1806 extinfo->num_sets = i+1;
1808 print_err("Maximum total number %d is not correct!", i);
1814 int xran_parse_section_extension(struct rte_mbuf *mbuf,
1816 struct xran_section_gen_info *section)
1818 int total_len, len, numext;
1825 ptr = (uint8_t *)ext;
1833 flag_last = (*ptr & 0x80);
1835 ext_type = *ptr & 0x7f;
1836 section->exData[numext].type = ext_type;
1838 case XRAN_CP_SECTIONEXTCMD_1:
1839 section->exData[numext].data = §ion->m_ext1[numext];
1840 len = xran_parse_section_ext1(ptr, section->exData[numext].data);
1841 section->exData[numext].len = len;
1843 case XRAN_CP_SECTIONEXTCMD_2:
1844 section->exData[numext].data = §ion->m_ext2[numext];
1845 len = xran_parse_section_ext2(ptr, section->exData[numext].data);
1847 case XRAN_CP_SECTIONEXTCMD_3:
1848 section->exData[numext].data = §ion->m_ext3[numext];
1849 len = xran_parse_section_ext3(ptr, section->exData[numext].data);
1851 case XRAN_CP_SECTIONEXTCMD_4:
1852 section->exData[numext].data = §ion->m_ext4[numext];
1853 len = xran_parse_section_ext4(ptr, section->exData[numext].data);
1855 case XRAN_CP_SECTIONEXTCMD_5:
1856 section->exData[numext].data = §ion->m_ext5[numext];
1857 len = xran_parse_section_ext5(ptr, section->exData[numext].data);
1861 print_err("Extension %d is not supported!", ext_type);
1865 section->exData[numext].len = len;
1866 ptr += len; total_len += len;
1869 if(++numext < XRAN_MAX_NUM_EXTENSIONS) continue;
1871 /* exceeds maximum number of extensions */
1875 section->exDataSize = numext;
1882 * @brief Parse a C-Plane packet (for RU emulation)
1883 * Transport layer fragmentation is not supported.
1885 * @ingroup xran_cp_pkt
1888 * The pointer of the packet buffer to be parsed
1890 * The pointer of structure to store the information of parsed packet
1892 * The pointer of sturcture to store the decomposed information of ecpriRtcid/ecpriPcid
1894 * XRAN_STATUS_SUCCESS on success
1895 * XRAN_STATUS_INVALID_PACKET if failed to parse the packet
1897 int xran_parse_cp_pkt(struct rte_mbuf *mbuf,
1898 struct xran_cp_gen_params *result,
1899 struct xran_recv_packet_info *pkt_info)
1901 struct xran_ecpri_hdr *ecpri_hdr;
1902 struct xran_cp_radioapp_common_header *apphdr;
1907 ret = xran_parse_ecpri_hdr(mbuf, &ecpri_hdr, pkt_info);
1908 if(ret < 0 && ecpri_hdr == NULL)
1909 return (XRAN_STATUS_INVALID_PACKET);
1911 /* Process radio header. */
1912 apphdr = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_ecpri_hdr));
1913 if(apphdr == NULL) {
1914 print_err("Invalid packet - radio app hedaer!");
1915 return (XRAN_STATUS_INVALID_PACKET);
1918 *((uint32_t *)apphdr) = rte_be_to_cpu_32(*((uint32_t *)apphdr));
1920 if(apphdr->payloadVer != XRAN_PAYLOAD_VER) {
1921 print_err("Invalid Payload version - %d", apphdr->payloadVer);
1922 ret = XRAN_STATUS_INVALID_PACKET;
1925 result->dir = apphdr->dataDirection;
1926 result->hdr.filterIdx = apphdr->filterIndex;
1927 result->hdr.frameId = apphdr->frameId;
1928 result->hdr.subframeId = apphdr->subframeId;
1929 result->hdr.slotId = apphdr->slotId;
1930 result->hdr.startSymId = apphdr->startSymbolId;
1931 result->sectionType = apphdr->sectionType;
1932 result->numSections = apphdr->numOfSections;
1935 printf("[CP%5d] eAxC[%d:%d:%02d:%02d] %s seq[%03d-%03d-%d] sec[%d-%d] frame[%3d-%2d-%2d] sym%02d\n",
1936 pkt_info->payload_len,
1937 pkt_info->eaxc.cuPortId, pkt_info->eaxc.bandSectorId,
1938 pkt_info->eaxc.ccId, pkt_info->eaxc.ruPortId,
1939 result->dir?"DL":"UL",
1940 pkt_info->seq_id, pkt_info->subseq_id, pkt_info->ebit,
1941 result->sectionType, result->numSections,
1942 result->hdr.frameId, result->hdr.subframeId, result->hdr.slotId,
1943 result->hdr.startSymId
1947 switch(apphdr->sectionType) {
1948 case XRAN_CP_SECTIONTYPE_0: // Unused RB or Symbols in DL or UL, not supportted
1950 struct xran_cp_radioapp_section0_header *hdr;
1951 struct xran_cp_radioapp_section0 *section;
1953 hdr = (struct xran_cp_radioapp_section0_header*)apphdr;
1955 result->hdr.fftSize = rte_be_to_cpu_16(hdr->timeOffset);
1956 result->hdr.scs = hdr->frameStructure.fftSize;
1957 result->hdr.timeOffset = hdr->frameStructure.uScs;
1958 result->hdr.cpLength = rte_be_to_cpu_16(hdr->cpLength);
1959 //hdr->reserved; /* should be zero */
1961 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section0_header));
1962 if(section == NULL) {
1963 print_err("Invalid packet 0 - radio app hedaer!");
1964 return (XRAN_STATUS_INVALID_PACKET);
1966 for(i=0; i<result->numSections; i++) {
1967 *((uint64_t *)section) = rte_be_to_cpu_64(*((uint64_t *)section));
1969 result->sections[i].info.type = apphdr->sectionType;
1970 result->sections[i].info.id = section->hdr.sectionId;
1971 result->sections[i].info.rb = section->hdr.rb;
1972 result->sections[i].info.symInc = section->hdr.symInc;
1973 result->sections[i].info.startPrbc = section->hdr.startPrbc;
1974 result->sections[i].info.numPrbc = section->hdr.numPrbc,
1975 result->sections[i].info.numSymbol = section->hdr.u.s0.numSymbol;
1976 result->sections[i].info.reMask = section->hdr.u.s0.reMask;
1977 //section->hdr.u.s0.reserved; /* should be zero */
1979 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section0));
1980 if(section == NULL) {
1981 print_err("Invalid packet 0 - number of section [%d:%d]!",
1982 result->numSections, i);
1983 result->numSections = i;
1984 ret = XRAN_STATUS_INVALID_PACKET;
1991 case XRAN_CP_SECTIONTYPE_1: // Most DL/UL Radio Channels
1993 struct xran_cp_radioapp_section1_header *hdr;
1994 struct xran_cp_radioapp_section1 *section;
1996 hdr = (struct xran_cp_radioapp_section1_header*)apphdr;
1998 result->hdr.iqWidth = hdr->udComp.udIqWidth;
1999 result->hdr.compMeth = hdr->udComp.udCompMeth;
2001 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section1_header));
2002 if(section == NULL) {
2003 print_err("Invalid packet 1 - radio app hedaer!");
2004 return (XRAN_STATUS_INVALID_PACKET);
2007 for(i=0; i<result->numSections; i++) {
2008 *((uint64_t *)section) = rte_be_to_cpu_64(*((uint64_t *)section));
2010 result->sections[i].info.type = apphdr->sectionType;
2011 result->sections[i].info.id = section->hdr.sectionId;
2012 result->sections[i].info.rb = section->hdr.rb;
2013 result->sections[i].info.symInc = section->hdr.symInc;
2014 result->sections[i].info.startPrbc = section->hdr.startPrbc;
2015 result->sections[i].info.numPrbc = section->hdr.numPrbc,
2016 result->sections[i].info.numSymbol = section->hdr.u.s1.numSymbol;
2017 result->sections[i].info.reMask = section->hdr.u.s1.reMask;
2018 result->sections[i].info.beamId = section->hdr.u.s1.beamId;
2019 result->sections[i].info.ef = section->hdr.u.s1.ef;
2021 section = (void *)rte_pktmbuf_adj(mbuf,
2022 sizeof(struct xran_cp_radioapp_section1));
2023 if(section == NULL) {
2024 print_err("Invalid packet 1 - number of section [%d:%d]!",
2025 result->numSections, i);
2026 result->numSections = i;
2027 ret = XRAN_STATUS_INVALID_PACKET;
2031 if(result->sections[i].info.ef) {
2032 // parse section extension
2033 extlen = xran_parse_section_extension(mbuf, (void *)section, &result->sections[i]);
2035 section = (void *)rte_pktmbuf_adj(mbuf, extlen);
2036 if(section == NULL) {
2037 print_err("Invalid packet 1 - section extension [%d]!", i);
2038 ret = XRAN_STATUS_INVALID_PACKET;
2048 case XRAN_CP_SECTIONTYPE_3: // PRACH and Mixed-numerology Channels
2050 struct xran_cp_radioapp_section3_header *hdr;
2051 struct xran_cp_radioapp_section3 *section;
2053 hdr = (struct xran_cp_radioapp_section3_header*)apphdr;
2055 result->hdr.timeOffset = rte_be_to_cpu_16(hdr->timeOffset);
2056 result->hdr.scs = hdr->frameStructure.uScs;
2057 result->hdr.fftSize = hdr->frameStructure.fftSize;
2058 result->hdr.cpLength = rte_be_to_cpu_16(hdr->cpLength);
2059 result->hdr.iqWidth = hdr->udComp.udIqWidth;
2060 result->hdr.compMeth = hdr->udComp.udCompMeth;
2062 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section3_header));
2063 if(section == NULL) {
2064 print_err("Invalid packet 3 - radio app hedaer!");
2065 return (XRAN_STATUS_INVALID_PACKET);
2068 for(i=0; i<result->numSections; i++) {
2069 *((uint64_t *)section) = rte_be_to_cpu_64(*((uint64_t *)section));
2071 result->sections[i].info.type = apphdr->sectionType;
2072 result->sections[i].info.id = section->hdr.sectionId;
2073 result->sections[i].info.rb = section->hdr.rb;
2074 result->sections[i].info.symInc = section->hdr.symInc;
2075 result->sections[i].info.startPrbc = section->hdr.startPrbc;
2076 result->sections[i].info.numPrbc = section->hdr.numPrbc,
2077 result->sections[i].info.numSymbol = section->hdr.u.s3.numSymbol;
2078 result->sections[i].info.reMask = section->hdr.u.s3.reMask;
2079 result->sections[i].info.beamId = section->hdr.u.s3.beamId;
2080 result->sections[i].info.ef = section->hdr.u.s3.ef;
2081 result->sections[i].info.freqOffset = ((int32_t)rte_be_to_cpu_32(section->freqOffset))>>8;
2083 if(section->reserved) {
2084 print_err("Invalid packet 3 - section[%d:%d]", i, section->reserved);
2085 ret = XRAN_STATUS_INVALID_PACKET;
2088 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section3));
2089 if(section == NULL) {
2090 print_err("Invalid packet 3 - number of section [%d:%d]!",
2091 result->numSections, i);
2092 result->numSections = i;
2093 ret = XRAN_STATUS_INVALID_PACKET;
2097 if(result->sections[i].info.ef) {
2098 // parse section extension
2099 extlen = xran_parse_section_extension(mbuf, (void *)section, &result->sections[i]);
2101 section = (void *)rte_pktmbuf_adj(mbuf, extlen);
2102 if(section == NULL) {
2103 print_err("Invalid packet 3 - section extension [%d]!", i);
2104 ret = XRAN_STATUS_INVALID_PACKET;
2114 case XRAN_CP_SECTIONTYPE_5: // UE scheduling information, not supported
2115 case XRAN_CP_SECTIONTYPE_6: // Channel Information, not supported
2116 case XRAN_CP_SECTIONTYPE_7: // LAA, not supported
2118 ret = XRAN_STATUS_INVALID_PARAM;
2119 print_err("Non-supported Section Type - %d", apphdr->sectionType);
2123 printf("[CP-%s] [%3d:%2d:%2d] section%d[%d] startSym=%d filterIdx=%X IQwidth=%d CompMeth=%d\n",
2124 result->dir?"DL":"UL",
2125 result->hdr.frameId, result->hdr.subframeId, result->hdr.slotId,
2126 result->sectionType, result->numSections,
2127 result->hdr.startSymId,
2128 result->hdr.filterIdx,
2129 result->hdr.iqWidth, result->hdr.compMeth);
2131 for(i=0; i<result->numSections; i++) {
2132 printf(" || %3d:%04X| rb=%d symInc=%d numSym=%d startPrbc=%02d numPrbc=%d reMask=%03X beamId=%04X freqOffset=%d ef=%d\n",
2133 i, result->sections[i].info.id,
2134 result->sections[i].info.rb,
2135 result->sections[i].info.symInc, result->sections[i].info.numSymbol,
2136 result->sections[i].info.startPrbc, result->sections[i].info.numPrbc,
2137 result->sections[i].info.reMask,
2138 result->sections[i].info.beamId,
2139 result->sections[i].info.freqOffset,
2140 result->sections[i].info.ef);
2142 if(result->sections[i].info.ef) {
2143 for(int j=0; j<result->sections[i].exDataSize; j++) {
2144 printf(" || %2d : type=%d len=%d\n",
2145 j, result->sections[i].exData[j].type, result->sections[i].exData[j].len);
2146 switch(result->sections[i].exData[j].type) {
2147 case XRAN_CP_SECTIONEXTCMD_1:
2149 struct xran_sectionext1_info *ext1;
2150 ext1 = result->sections[i].exData[j].data;
2151 printf(" || bfwNumber=%d bfwiqWidth=%d bfwCompMeth=%d\n",
2152 ext1->bfwNumber, ext1->bfwiqWidth, ext1->bfwCompMeth);
2155 case XRAN_CP_SECTIONEXTCMD_2:
2157 struct xran_sectionext2_info *ext2;
2158 ext2 = result->sections[i].exData[j].data;
2159 printf(" || AzPt=%02x(%d) ZePt=%02x(%d) Az3dd=%02x(%d) Ze3dd=%02x(%d) AzSI=%02x ZeSI=%02x\n",
2160 ext2->bfAzPt, ext2->bfAzPtWidth,
2161 ext2->bfZePt, ext2->bfZePtWidth,
2162 ext2->bfAz3dd, ext2->bfAz3ddWidth,
2163 ext2->bfZe3dd, ext2->bfZe3ddWidth,
2164 ext2->bfAzSI, ext2->bfZeSI);
2167 case XRAN_CP_SECTIONEXTCMD_4:
2169 struct xran_sectionext4_info *ext4;
2170 ext4 = result->sections[i].exData[j].data;
2171 printf(" || csf=%d modCompScaler=%d\n",
2172 ext4->csf, ext4->modCompScaler);
2175 case XRAN_CP_SECTIONEXTCMD_5:
2177 struct xran_sectionext5_info *ext5;
2178 ext5 = result->sections[i].exData[j].data;
2179 printf(" || num_sets=%d\n", ext5->num_sets);
2180 for(int k=0; k<ext5->num_sets; k++) {
2181 printf(" || %d - csf=%d mcScaleReMask=%04x mcScaleOffset=%04x\n",
2183 ext5->mc[k].mcScaleReMask, ext5->mc[k].mcScaleOffset);
2188 case XRAN_CP_SECTIONEXTCMD_0:
2189 case XRAN_CP_SECTIONEXTCMD_3:
2191 printf("Invalid section extension type!\n");