1 /******************************************************************************
\r
3 * Copyright (c) 2019 Intel.
\r
5 * Licensed under the Apache License, Version 2.0 (the "License");
\r
6 * you may not use this file except in compliance with the License.
\r
7 * You may obtain a copy of the License at
\r
9 * http://www.apache.org/licenses/LICENSE-2.0
\r
11 * Unless required by applicable law or agreed to in writing, software
\r
12 * distributed under the License is distributed on an "AS IS" BASIS,
\r
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
14 * See the License for the specific language governing permissions and
\r
15 * limitations under the License.
\r
17 *******************************************************************************/
\r
20 * @brief This file provides the API functions to build Control Plane Messages
\r
21 * for XRAN Front Haul layer as defined in XRAN-FH.CUS.0-v02.01.
\r
23 * @file xran_cp_api.c
\r
24 * @ingroup group_lte_source_xran
\r
25 * @author Intel Corporation
\r
29 #include <rte_branch_prediction.h>
\r
31 #include "xran_common.h"
\r
32 #include "xran_transport.h"
\r
33 #include "xran_cp_api.h"
\r
34 #include "xran_printf.h"
\r
35 #include "xran_compression.h"
\r
39 * This structure to store the section information of C-Plane
\r
40 * in order to generate and parse corresponding U-Plane */
\r
41 struct xran_sectioninfo_db {
\r
42 uint32_t cur_index; /**< Current index to store for this eAXC */
\r
43 struct xran_section_info list[XRAN_MAX_NUM_SECTIONS]; /**< The array of section information */
\r
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];
\r
48 static const uint8_t zeropad[XRAN_SECTIONEXT_ALIGN] = { 0, 0, 0, 0 };
\r
49 static const uint8_t bitmask[] = { 0x00, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
\r
53 * @brief Initialize section database.
\r
54 * Allocate required memory space to store section information.
\r
55 * Each eAxC allocates dedicated storage and the entry size is the maximum number of sections.
\r
56 * Total entry size : number of CC * number of antenna * max number of sections * 2(direction)
\r
58 * @ingroup xran_cp_pkt
\r
61 * handle for xRAN interface, currently not being used
\r
63 * XRAN_STATUS_SUCCESS on success
\r
64 * XRAN_STATUS_RESOURCE, if memory is not enough to allocate database area
\r
66 int xran_cp_init_sectiondb(void *pHandle)
\r
68 int ctx, dir, cc, ant;
\r
70 for(ctx=0; ctx < XRAN_MAX_SECTIONDB_CTX; ctx++)
\r
71 for(dir=0; dir < XRAN_DIR_MAX; dir++)
\r
72 for(cc=0; cc < XRAN_COMPONENT_CARRIERS_MAX; cc++)
\r
73 for(ant=0; ant < XRAN_MAX_ANTENNA_NR*2 + XRAN_MAX_ANT_ARRAY_ELM_NR; ant++)
\r
74 sectiondb[ctx][dir][cc][ant].cur_index = 0;
\r
76 return (XRAN_STATUS_SUCCESS);
\r
80 * @brief Release and free section database
\r
82 * @ingroup xran_cp_pkt
\r
85 * handle for xRAN interface, currently not being used
\r
87 * XRAN_STATUS_SUCCESS on success
\r
89 int xran_cp_free_sectiondb(void *pHandle)
\r
91 return (XRAN_STATUS_SUCCESS);
\r
94 static inline struct xran_sectioninfo_db *xran_get_section_db(void *pHandle,
\r
95 uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id)
\r
97 struct xran_sectioninfo_db *ptr;
\r
100 if(unlikely(ctx_id >= XRAN_MAX_SECTIONDB_CTX)) {
\r
101 print_err("Invalid Context id - %d", ctx_id);
\r
105 if(unlikely(dir >= XRAN_DIR_MAX)) {
\r
106 print_err("Invalid direction - %d", dir);
\r
110 if(unlikely(cc_id >= XRAN_COMPONENT_CARRIERS_MAX)) {
\r
111 print_err("Invalid CC id - %d", cc_id);
\r
115 if(unlikely(ruport_id >= XRAN_MAX_ANTENNA_NR*2 + XRAN_MAX_ANT_ARRAY_ELM_NR)) {
\r
116 print_err("Invalid eAxC id - %d", ruport_id);
\r
120 ptr = §iondb[ctx_id][dir][cc_id][ruport_id];
\r
125 static inline struct xran_section_info *xran_get_section_info(struct xran_sectioninfo_db *ptr, uint16_t index)
\r
127 if(unlikely(ptr == NULL))
\r
130 if(unlikely(index > XRAN_MAX_NUM_SECTIONS)) {
\r
131 print_err("Index is out of range - %d", index);
\r
135 return(&(ptr->list[index]));
\r
139 * @brief Add a section information of C-Plane to dabase.
\r
141 * @ingroup xran_cp_pkt
\r
144 * handle for xRAN interface, currently not being used
\r
146 * Direction of C-Plane message for the section to store
\r
148 * CC ID of C-Plane message for the section to store
\r
150 * RU port ID of C-Plane message for the section to store
\r
152 * Context index for the section database
\r
154 * The information of this section to store
\r
156 * XRAN_STATUS_SUCCESS on success
\r
157 * XRAN_STATUS_INVALID_PARAM, if direction, CC ID or RU port ID is incorrect
\r
158 * XRAN_STATUS_RESOURCE, if no more space to add on database
\r
160 int xran_cp_add_section_info(void *pHandle,
\r
161 uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id,
\r
162 struct xran_section_info *info)
\r
164 struct xran_sectioninfo_db *ptr;
\r
165 struct xran_section_info *list;
\r
168 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
\r
169 if(unlikely(ptr == NULL)) {
\r
170 return (XRAN_STATUS_INVALID_PARAM);
\r
173 if(unlikely(ptr->cur_index >= XRAN_MAX_NUM_SECTIONS)) {
\r
174 print_err("No more space to add section information!");
\r
175 return (XRAN_STATUS_RESOURCE);
\r
178 list = xran_get_section_info(ptr, ptr->cur_index);
\r
180 rte_memcpy(list, info, sizeof(struct xran_section_info));
\r
184 return (XRAN_STATUS_SUCCESS);
\r
187 int xran_cp_add_multisection_info(void *pHandle,
\r
188 uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id,
\r
189 struct xran_cp_gen_params *gen_info)
\r
192 uint8_t dir, num_sections;
\r
193 struct xran_sectioninfo_db *ptr;
\r
194 struct xran_section_info *list;
\r
197 dir = gen_info->dir;
\r
198 num_sections = gen_info->numSections;
\r
200 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
\r
201 if(unlikely(ptr == NULL)) {
\r
202 return (XRAN_STATUS_INVALID_PARAM);
\r
205 if(unlikely(ptr->cur_index+num_sections >= XRAN_MAX_NUM_SECTIONS)) {
\r
206 print_err("No more space to add section information!");
\r
207 return (XRAN_STATUS_RESOURCE);
\r
210 list = xran_get_section_info(ptr, ptr->cur_index);
\r
212 for(i=0; i<num_sections; i++) {
\r
213 rte_memcpy(&list[i], &gen_info->sections[i].info, sizeof(struct xran_section_info));
\r
217 return (XRAN_STATUS_SUCCESS);
\r
221 * @brief Find a section information of C-Plane from dabase
\r
222 * by given information
\r
224 * @ingroup xran_cp_pkt
\r
227 * handle for xRAN interface, currently not being used
\r
229 * The direction of the section to find
\r
231 * The CC ID of the section to find
\r
233 * RU port ID of the section to find
\r
235 * Context index for the section database
\r
236 * @param section_id
\r
237 * The ID of section to find
\r
239 * The pointer of section information if matched section is found
\r
240 * NULL if failed to find matched section
\r
242 struct xran_section_info *xran_cp_find_section_info(void *pHandle,
\r
243 uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
\r
244 uint8_t ctx_id, uint16_t section_id)
\r
246 int index, num_index;
\r
247 struct xran_sectioninfo_db *ptr;
\r
250 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
\r
251 if(unlikely(ptr == NULL))
\r
254 if(ptr->cur_index > XRAN_MAX_NUM_SECTIONS)
\r
255 num_index = XRAN_MAX_NUM_SECTIONS;
\r
257 num_index = ptr->cur_index;
\r
259 for(index=0; index < num_index; index++) {
\r
260 if(ptr->list[index].id == section_id) {
\r
261 return (xran_get_section_info(ptr, index));
\r
265 print_dbg("No section ID in the list - %d", section_id);
\r
270 * @brief Iterate each section information of C-Plane
\r
271 * from the database of eAxC by given information
\r
273 * @ingroup xran_cp_pkt
\r
276 * handle for xRAN interface, currently not being used
\r
278 * The direction of the section to find
\r
280 * The CC ID of the section to find
\r
282 * RU port ID of the section to find
\r
284 * Context index for the section database
\r
286 * The pointer to store the position of next entry
\r
288 * The pointer of section information in the list
\r
289 * NULL if reached at the end of the list
\r
291 struct xran_section_info *xran_cp_iterate_section_info(void *pHandle,
\r
292 uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
\r
293 uint8_t ctx_id, uint32_t *next)
\r
296 struct xran_sectioninfo_db *ptr;
\r
299 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
\r
300 if(unlikely(ptr == NULL))
\r
304 if(*next < ptr->cur_index) {
\r
306 return (xran_get_section_info(ptr, index));
\r
309 print_dbg("No more sections in the list");
\r
315 * @brief Get the size of stored entries
\r
316 * for the database of eAxC by given information
\r
318 * @ingroup xran_cp_pkt
\r
321 * handle for xRAN interface, currently not being used
\r
323 * The direction of the section to find
\r
325 * The CC ID of the section to find
\r
327 * RU port ID of the section to find
\r
329 * Context index for the section database
\r
331 * The size of stored entries
\r
332 * -1 if failed to find matched database
\r
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)
\r
337 struct xran_sectioninfo_db *ptr;
\r
340 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
\r
341 if(unlikely(ptr == NULL))
\r
344 return (ptr->cur_index);
\r
348 * @brief Reset a database of eAxC by given information
\r
350 * @ingroup xran_cp_pkt
\r
353 * handle for xRAN interface, currently not being used
\r
355 * The direction of the section to find
\r
357 * The CC ID of the section to find
\r
359 * RU port ID of the section to find
\r
361 * Context index for the section database
\r
363 * XRAN_STATUS_SUCCESS on success
\r
364 * XRAN_STATUS_INVALID_PARM if failed to find matched database
\r
366 int xran_cp_reset_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id)
\r
368 struct xran_sectioninfo_db *ptr;
\r
370 ptr = xran_get_section_db(pHandle, dir, cc_id, ruport_id, ctx_id);
\r
371 if(unlikely(ptr == NULL)) {
\r
372 return (XRAN_STATUS_INVALID_PARAM);
\r
375 ptr->cur_index = 0;
\r
377 return (XRAN_STATUS_SUCCESS);
\r
381 int xran_dump_sectiondb(void)
\r
387 int32_t xran_cp_populate_section_ext_1(int8_t *p_ext1_dst, /**< destination buffer */
\r
388 uint16_t ext1_dst_len, /**< dest buffer size */
\r
389 int16_t *p_bfw_iq_src, /**< source buffer of IQs */
\r
390 uint16_t rbNum, /* number RBs to ext1 chain */
\r
391 uint16_t bfwNumPerRb, /* number of bf weights per RB (i.e. antenna elements) */
\r
392 uint8_t bfwiqWidth, /* bit size of IQs */
\r
393 uint8_t bfwCompMeth) /* compression method */
\r
395 struct xran_cp_radioapp_section_ext1 *p_ext1;
\r
397 uint8_t *p_bfw_content = NULL;
\r
398 int32_t parm_size = 0;
\r
399 int32_t bfw_iq_bits = 0;
\r
400 int32_t total_len = 0;
\r
401 int32_t comp_len = 0;
\r
402 uint8_t ext_flag = XRAN_EF_F_ANOTHER_ONE;
\r
404 int16_t cur_ext_len = 0;
\r
405 int8_t *p_ext1_dst_cur = NULL;
\r
407 struct xranlib_compress_request bfp_com_req;
\r
408 struct xranlib_compress_response bfp_com_rsp;
\r
410 memset(&bfp_com_req, 0, sizeof(struct xranlib_compress_request));
\r
411 memset(&bfp_com_rsp, 0, sizeof(struct xranlib_compress_response));
\r
413 print_dbg("%s comp %d\n", __FUNCTION__, bfwCompMeth);
\r
414 print_dbg("bfwNumPerRb %d bfwiqWidth %d\n", bfwNumPerRb, bfwiqWidth);
\r
417 p_ext1_dst_cur = p_ext1_dst;
\r
419 return (XRAN_STATUS_INVALID_PARAM);
\r
421 /* create extType=1 section for each RB */
\r
422 for (idxRb = 0; idxRb < rbNum; idxRb++) {
\r
423 print_dbg("%s RB %d\n", __FUNCTION__, idxRb);
\r
425 if(total_len >= ext1_dst_len){
\r
426 print_err("p_ext1_dst overflow\n");
\r
430 cur_ext_len = 0; /** populate one extType=1 section with BFW for 1 RB */
\r
431 parm_size = sizeof(struct xran_cp_radioapp_section_ext1);
\r
432 p_ext1 = (struct xran_cp_radioapp_section_ext1 *)p_ext1_dst_cur;
\r
433 if(p_ext1 == NULL) {
\r
434 print_err("p_ext1 is null!\n");
\r
435 return (XRAN_STATUS_INVALID_PARAM);
\r
438 cur_ext_len += parm_size;
\r
440 if(idxRb+1 == rbNum)
\r
441 ext_flag = XRAN_EF_F_LAST;
\r
443 p_ext1->extType = XRAN_CP_SECTIONEXTCMD_1;
\r
444 p_ext1->ef = ext_flag;
\r
445 p_ext1->bfwCompMeth = bfwCompMeth;
\r
446 p_ext1->bfwIqWidth = XRAN_CONVERT_BFWIQWIDTH(bfwiqWidth);
\r
448 switch(bfwCompMeth) {
\r
449 case XRAN_BFWCOMPMETHOD_BLKFLOAT:
\r
450 p_bfw_content = (uint8_t *)(p_ext1+1);
\r
451 if(p_bfw_content == NULL) {
\r
452 print_err("Fail to allocate the space for section extension 1");
\r
453 return (XRAN_STATUS_RESOURCE);
\r
455 bfp_com_req.data_in = (int16_t*)p_bfw_iq_src;
\r
456 bfp_com_req.len = bfwNumPerRb*4;
\r
457 bfp_com_req.compMethod = p_ext1->bfwCompMeth;
\r
458 bfp_com_req.iqWidth = p_ext1->bfwIqWidth;
\r
460 print_dbg("req 0x%08p iqWidth %d\n",bfp_com_req.data_in, bfp_com_req.iqWidth);
\r
462 parm_size = 1; /* exponent as part of bfwCompParam 1 octet */
\r
464 case XRAN_BFWCOMPMETHOD_BLKSCALE:
\r
465 rte_panic("XRAN_BFWCOMPMETHOD_BLKSCALE");
\r
468 case XRAN_BFWCOMPMETHOD_ULAW:
\r
469 rte_panic("XRAN_BFWCOMPMETHOD_BLKSCALE");
\r
472 case XRAN_BFWCOMPMETHOD_BEAMSPACE:
\r
473 rte_panic("XRAN_BFWCOMPMETHOD_BLKSCALE");
\r
476 case XRAN_BFWCOMPMETHOD_NONE:
\r
478 p_bfw_content = (uint8_t *)(p_ext1+1);
\r
479 /* bfwCompParam is absent for no compression case */
\r
483 if(p_bfw_content == NULL) {
\r
484 print_err("Fail to allocate the space for section extension 1");
\r
485 return (XRAN_STATUS_RESOURCE);
\r
488 bfw_iq_bits = bfwNumPerRb* bfwiqWidth * 2;
\r
490 parm_size += bfw_iq_bits>>3;
\r
494 print_dbg("copy BF W %p -> %p size %d \n", p_bfw_iq_src, p_bfw_content, parm_size);
\r
495 if (p_ext1->bfwIqWidth == 0 || p_ext1->bfwIqWidth == 16){
\r
496 rte_memcpy(p_bfw_content, p_bfw_iq_src, parm_size);
\r
498 bfp_com_rsp.data_out = (int8_t*)p_bfw_content;
\r
499 if(xranlib_compress_avx512_bfw(&bfp_com_req, &bfp_com_rsp) == 0){
\r
500 comp_len = bfp_com_rsp.len;
\r
501 print_dbg("comp_len %d\n", comp_len);
\r
503 print_err("compression failed\n");
\r
504 return (XRAN_STATUS_FAIL);
\r
508 p_bfw_content = (uint8_t *)(p_bfw_content + parm_size);
\r
510 cur_ext_len += parm_size;
\r
511 parm_size = cur_ext_len % XRAN_SECTIONEXT_ALIGN;
\r
513 parm_size = XRAN_SECTIONEXT_ALIGN - parm_size;
\r
514 p_bfw_content = (uint8_t *)(p_bfw_content + parm_size);
\r
515 rte_memcpy(p_bfw_content, zeropad, parm_size);
\r
516 cur_ext_len += parm_size;
\r
517 print_dbg("zeropad %d cur_ext_len %d\n", parm_size, cur_ext_len);
\r
520 if(cur_ext_len % XRAN_SECTIONEXT_ALIGN)
\r
521 rte_panic("ext1 should be aligned on 4-bytes boundary");
\r
523 p_ext1->extLen = cur_ext_len / XRAN_SECTIONEXT_ALIGN;
\r
524 print_dbg("p_ext1->extLen %d\n", p_ext1->extLen);
\r
526 /* update for next RB */
\r
527 p_ext1_dst_cur += cur_ext_len;
\r
528 p_bfw_iq_src = p_bfw_iq_src + bfwNumPerRb*2;
\r
530 total_len += cur_ext_len;
\r
533 print_dbg("total_len %d\n", total_len);
\r
534 return (total_len);
\r
538 // Cyclic Prefix Length 5.4.4.14
\r
539 // CP_length = cpLength * Ts, Ts = 1/30.72MHz
\r
540 // i.e cpLength = CP_length / Ts ?
\r
541 #define CPLEN_TS (30720000)
\r
542 inline uint16_t xran_get_cplength(int CP_length)
\r
544 return (CP_length);
\r
547 // Frequency offset 5.4.5.11
\r
548 // frequency_offset = freqOffset * SCS * 0.5
\r
549 // i.e freqOffset = (frequency_offset *2 )/ SCS ?
\r
550 inline int32_t xran_get_freqoffset(int32_t freqOffset, int32_t scs)
\r
552 return (freqOffset);
\r
555 static int xran_copy_sectionext_1(struct rte_mbuf *mbuf,
\r
556 struct xran_sectionext1_info *params, int last_flag)
\r
559 int8_t *p_dst = (int8_t *)rte_pktmbuf_append(mbuf, params->bfwIQ_sz);
\r
560 if(p_dst == NULL) {
\r
561 print_err("Fail to allocate the space for section extension 1 [%d]", params->bfwIQ_sz);
\r
562 return (XRAN_STATUS_RESOURCE);
\r
564 if(params->p_bfwIQ){
\r
565 /* copy formated extType1 with all the headers */
\r
566 rte_memcpy(p_dst, params->p_bfwIQ, params->bfwIQ_sz);
\r
567 total_len = params->bfwIQ_sz;
\r
573 return (total_len);
\r
577 static int xran_prepare_sectionext_1(struct rte_mbuf *mbuf,
\r
578 struct xran_sectionext1_info *params, int last_flag)
\r
580 struct xran_cp_radioapp_section_ext1 *ext1;
\r
582 int parm_size, iq_size;
\r
587 print_dbg("%s %d\n", __FUNCTION__, last_flag);
\r
589 parm_size = sizeof(struct xran_cp_radioapp_section_ext1);
\r
590 ext1 = (struct xran_cp_radioapp_section_ext1 *)rte_pktmbuf_append(mbuf, parm_size);
\r
592 print_err("Fail to allocate the space for section extension 1 [%d]", parm_size);
\r
593 return (XRAN_STATUS_RESOURCE);
\r
596 total_len += parm_size;
\r
598 ext1->extType = XRAN_CP_SECTIONEXTCMD_1;
\r
599 ext1->ef = last_flag;
\r
600 ext1->bfwCompMeth = params->bfwCompMeth;
\r
601 ext1->bfwIqWidth = XRAN_CONVERT_BFWIQWIDTH(params->bfwiqWidth);
\r
603 switch(params->bfwCompMeth) {
\r
604 case XRAN_BFWCOMPMETHOD_BLKFLOAT:
\r
606 data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
\r
608 print_err("Fail to allocate the space for section extension 1 [%d]", parm_size);
\r
609 return (XRAN_STATUS_RESOURCE);
\r
611 total_len += parm_size;
\r
612 *data = (params->bfwCompParam.exponent & 0x0f);
\r
615 case XRAN_BFWCOMPMETHOD_BLKSCALE:
\r
617 data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
\r
619 print_err("Fail to allocate the space for section extension 1 [%d]", parm_size);
\r
620 return (XRAN_STATUS_RESOURCE);
\r
622 total_len += parm_size;
\r
623 *data = params->bfwCompParam.blockScaler;
\r
626 case XRAN_BFWCOMPMETHOD_ULAW:
\r
628 data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
\r
630 print_err("Fail to allocate the space for section extension 1 [%d]", parm_size);
\r
631 return (XRAN_STATUS_RESOURCE);
\r
633 total_len += parm_size;
\r
634 *data = params->bfwCompParam.compBitWidthShift;
\r
637 case XRAN_BFWCOMPMETHOD_BEAMSPACE:
\r
638 parm_size = params->bfwNumber>>3;
\r
639 if(params->bfwNumber%8) parm_size++;
\r
641 data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
\r
643 print_err("Fail to allocate the space for section extension 1 [%d]", parm_size);
\r
644 return (XRAN_STATUS_RESOURCE);
\r
646 rte_memcpy(data, params->bfwCompParam.activeBeamspaceCoeffMask, parm_size);
\r
647 total_len += parm_size;
\r
650 case XRAN_BFWCOMPMETHOD_NONE:
\r
655 print_dbg("params->bfwNumber %d params->bfwiqWidth %d\n", params->bfwNumber, params->bfwiqWidth);
\r
657 iq_size = params->bfwNumber * params->bfwiqWidth * 2;
\r
659 parm_size = iq_size>>3;
\r
663 data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
\r
665 print_err("Fail to allocate the space for section extension 1 BF W iq_size: [%d]", parm_size);
\r
666 return (XRAN_STATUS_RESOURCE);
\r
668 rte_memcpy(data, params->p_bfwIQ, parm_size);
\r
670 total_len += parm_size;
\r
671 parm_size = total_len % XRAN_SECTIONEXT_ALIGN;
\r
673 parm_size = XRAN_SECTIONEXT_ALIGN - parm_size;
\r
674 data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
\r
676 print_err("Fail to allocate the space for section extension 1 [%d]", parm_size);
\r
677 return (XRAN_STATUS_RESOURCE);
\r
679 rte_memcpy(data, zeropad, parm_size);
\r
680 total_len += parm_size;
\r
683 ext1->extLen = total_len / XRAN_SECTIONEXT_ALIGN;
\r
685 return (total_len);
\r
688 static int xran_prepare_sectionext_2(struct rte_mbuf *mbuf,
\r
689 struct xran_sectionext2_info *params, int last_flag)
\r
691 struct xran_cp_radioapp_section_ext2 *ext2;
\r
695 uint32_t val, shift_val;
\r
696 int val_size, pad_size;
\r
701 parm_size = sizeof(struct xran_cp_radioapp_section_ext2);
\r
702 ext2 = (struct xran_cp_radioapp_section_ext2 *)rte_pktmbuf_append(mbuf, parm_size);
\r
704 print_err("Fail to allocate the space for section extension 2");
\r
705 return (XRAN_STATUS_RESOURCE);
\r
707 total_len += parm_size;
\r
709 ext2->extType = XRAN_CP_SECTIONEXTCMD_2;
\r
710 ext2->ef = last_flag;
\r
711 ext2->bfZe3ddWidth = params->bfZe3ddWidth;
\r
712 ext2->bfAz3ddWidth = params->bfAz3ddWidth;
\r
713 ext2->bfZePtWidth = params->bfZePtWidth;
\r
714 ext2->bfAzPtWidth = params->bfAzPtWidth;
\r
715 ext2->bfaCompResv0 = 0;
\r
716 ext2->bfaCompResv1 = 0;
\r
720 if(params->bfAzPtWidth) {
\r
721 val += params->bfAzPt & bitmask[params->bfAzPtWidth];
\r
722 shift_val += 8 - (params->bfAzPtWidth+1);
\r
727 if(params->bfZePtWidth) {
\r
728 val = val << (params->bfZePtWidth+1);
\r
729 val += params->bfZePt & bitmask[params->bfZePtWidth];
\r
730 shift_val += 8 - (params->bfZePtWidth+1);
\r
735 if(params->bfAz3ddWidth) {
\r
736 val = val << (params->bfAz3ddWidth+1);
\r
737 val += params->bfAz3dd & bitmask[params->bfAz3ddWidth];
\r
738 shift_val += 8 - (params->bfAz3ddWidth+1);
\r
743 if(params->bfZe3ddWidth) {
\r
744 val = val << (params->bfZe3ddWidth+1);
\r
745 val += params->bfZe3dd & bitmask[params->bfZe3ddWidth];
\r
746 shift_val += 8 - (params->bfZe3ddWidth+1);
\r
752 val = val << shift_val;
\r
753 val = rte_cpu_to_be_32(val);
\r
756 val_size = 4 - (shift_val/8); /* ceil(total bit/8) */
\r
757 parm_size = val_size + 1; /* additional 1 byte for bfxxSI */
\r
760 total_len += parm_size;
\r
761 pad_size = total_len % XRAN_SECTIONEXT_ALIGN;
\r
763 pad_size = XRAN_SECTIONEXT_ALIGN - pad_size;
\r
764 parm_size += pad_size;
\r
765 total_len += pad_size;
\r
768 data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
\r
770 print_err("Fail to allocate the space for section extension 2");
\r
771 return (XRAN_STATUS_RESOURCE);
\r
774 rte_memcpy(data, &val, val_size);
\r
776 *data = ((params->bfAzSI) << 3) + (params->bfZeSI);
\r
778 rte_memcpy(data, zeropad, pad_size);
\r
780 ext2->extLen = total_len / XRAN_SECTIONEXT_ALIGN;
\r
781 *(uint32_t *)ext2 = rte_cpu_to_be_32(*(uint32_t *)ext2);
\r
783 return (total_len);
\r
786 static int xran_prepare_sectionext_4(struct rte_mbuf *mbuf,
\r
787 struct xran_sectionext4_info *params, int last_flag)
\r
789 struct xran_cp_radioapp_section_ext4 *ext4;
\r
797 parm_size = sizeof(struct xran_cp_radioapp_section_ext4);
\r
798 ext4 = (struct xran_cp_radioapp_section_ext4 *)rte_pktmbuf_append(mbuf, parm_size);
\r
800 print_err("Fail to allocate the space for section extension 4");
\r
801 return(XRAN_STATUS_RESOURCE);
\r
804 total_len += parm_size;
\r
806 ext4->extType = XRAN_CP_SECTIONEXTCMD_4;
\r
807 ext4->ef = last_flag;
\r
808 ext4->modCompScaler = params->modCompScaler;
\r
809 ext4->csf = params->csf?1:0;
\r
810 ext4->extLen = total_len / XRAN_SECTIONEXT_ALIGN;
\r
812 *(uint32_t *)ext4 = rte_cpu_to_be_32(*(uint32_t*)ext4);
\r
815 return (total_len);
\r
818 static int xran_prepare_sectionext_5(struct rte_mbuf *mbuf,
\r
819 struct xran_sectionext5_info *params, int last_flag)
\r
821 struct xran_cp_radioapp_section_ext_hdr *ext_hdr;
\r
822 struct xran_cp_radioapp_section_ext5 ext5;
\r
829 if(params->num_sets > XRAN_MAX_MODCOMP_ADDPARMS) {
\r
830 print_err("Exceeds maximum number of parameters(%d). Skipping.", params->num_sets);
\r
834 total_len = sizeof(struct xran_cp_radioapp_section_ext_hdr)
\r
835 + (sizeof(struct xran_cp_radioapp_section_ext5)*params->num_sets)/2
\r
836 - (params->num_sets>>1); // 8bits are added by every two sets, so needs to adjust
\r
838 /* for alignment */
\r
839 padding = total_len % XRAN_SECTIONEXT_ALIGN;
\r
841 padding = XRAN_SECTIONEXT_ALIGN - padding;
\r
842 total_len += padding;
\r
845 ext_hdr = (struct xran_cp_radioapp_section_ext_hdr *)rte_pktmbuf_append(mbuf, total_len);
\r
846 if(ext_hdr == NULL) {
\r
847 print_err("Fail to allocate the space for section extension 5");
\r
848 return (XRAN_STATUS_RESOURCE);
\r
851 ext_hdr->extType = XRAN_CP_SECTIONEXTCMD_5;
\r
852 ext_hdr->ef = last_flag;
\r
853 ext_hdr->extLen = total_len / XRAN_SECTIONEXT_ALIGN;
\r
855 *(uint16_t *)ext_hdr = rte_cpu_to_be_16(*((uint16_t *)ext_hdr));
\r
857 data = (uint8_t *)(ext_hdr + 1);
\r
859 while(i < params->num_sets) {
\r
860 if(i%2) { // odd index
\r
861 ext5.mcScaleOffset2 = params->mc[i].mcScaleOffset;
\r
862 ext5.csf2 = params->mc[i].csf;
\r
863 ext5.mcScaleReMask2 = params->mc[i].mcScaleReMask;
\r
864 ext5.reserved0 = 0;
\r
867 // adding two sets at once (due to the definition of structure)
\r
868 *((uint64_t *)&ext5) = rte_cpu_to_be_64(*((uint64_t *)&ext5));
\r
869 rte_memcpy(data, &ext5, sizeof(struct xran_cp_radioapp_section_ext5));
\r
870 data += sizeof(struct xran_cp_radioapp_section_ext5);
\r
872 else { // even index
\r
873 ext5.mcScaleOffset1 = params->mc[i].mcScaleOffset;
\r
874 ext5.csf1 = params->mc[i].csf;
\r
875 ext5.mcScaleReMask1 = params->mc[i].mcScaleReMask;
\r
876 ext5.mcScaleReMask2 = 0;
\r
879 if(i == params->num_sets) { // adding last even index
\r
880 *((uint64_t *)&ext5) = rte_cpu_to_be_64(*((uint64_t *)&ext5));
\r
881 rte_memcpy(data, &ext5, sizeof(struct xran_cp_radioapp_section_ext5)/2);
\r
882 data += sizeof(struct xran_cp_radioapp_section_ext5)/2;
\r
890 rte_memcpy(data, zeropad, padding);
\r
892 return (total_len);
\r
896 * @brief add section extension to C-Plane packet
\r
899 * A pointer to the packet buffer
\r
901 * A porinter to the information to generate a C-Plane packet
\r
903 * XRAN_STATUS_SUCCESS on success
\r
904 * XRAN_STATUS_INVALID_PARM
\r
905 * XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
\r
907 int xran_append_section_extensions(struct rte_mbuf *mbuf, struct xran_section_gen_info *params)
\r
914 if(unlikely(params->exDataSize > XRAN_MAX_NUM_EXTENSIONS)) {
\r
915 print_err("Invalid total number of extensions - %d", params->exDataSize);
\r
916 return (XRAN_STATUS_INVALID_PARAM);
\r
921 ret = XRAN_STATUS_SUCCESS;
\r
923 print_dbg("params->exDataSize %d\n", params->exDataSize);
\r
924 for(i=0; i < params->exDataSize; i++) {
\r
925 if(params->exData[i].data == NULL) {
\r
926 print_err("Invalid parameter - extension data %d is NULL", i);
\r
927 ret = XRAN_STATUS_INVALID_PARAM;
\r
931 last_flag = (params->exDataSize == (i+1))?0:1;
\r
933 switch(params->exData[i].type) {
\r
934 case XRAN_CP_SECTIONEXTCMD_1:
\r
935 ext_size = xran_copy_sectionext_1(mbuf, params->exData[i].data, last_flag);
\r
936 //xran_prepare_sectionext_1(mbuf, params->exData[i].data, last_flag);
\r
938 case XRAN_CP_SECTIONEXTCMD_2:
\r
939 ext_size = xran_prepare_sectionext_2(mbuf, params->exData[i].data, last_flag);
\r
941 case XRAN_CP_SECTIONEXTCMD_4:
\r
942 ext_size = xran_prepare_sectionext_4(mbuf, params->exData[i].data, last_flag);
\r
944 case XRAN_CP_SECTIONEXTCMD_5:
\r
945 ext_size = xran_prepare_sectionext_5(mbuf, params->exData[i].data, last_flag);
\r
947 case XRAN_CP_SECTIONEXTCMD_0:
\r
948 case XRAN_CP_SECTIONEXTCMD_3:
\r
950 print_err("Extension Type %d is not supported!", params->exData[i].type);
\r
951 ret = XRAN_STATUS_INVALID_PARAM;
\r
955 if(ext_size == XRAN_STATUS_RESOURCE) {
\r
959 totalen += ext_size;
\r
967 * @brief Fill the section body of type 0 in C-Plane packet
\r
970 * A pointer to the section in the packet buffer
\r
972 * A porinter to the information to generate a C-Plane packet
\r
974 * XRAN_STATUS_SUCCESS on success
\r
975 * XRAN_STATUS_INVALID_PARM if the number of symbol is invalid
\r
977 static int xran_prepare_section0(
\r
978 struct xran_cp_radioapp_section0 *section,
\r
979 struct xran_section_gen_info *params)
\r
981 #if (XRAN_STRICT_PARM_CHECK)
\r
982 if(unlikely(params->info.numSymbol > XRAN_SYMBOLNUMBER_MAX)) {
\r
983 print_err("Invalid number of Symbols - %d", params->info.numSymbol);
\r
984 return (XRAN_STATUS_INVALID_PARAM);
\r
988 section->hdr.sectionId = params->info.id;
\r
989 section->hdr.rb = params->info.rb;
\r
990 section->hdr.symInc = params->info.symInc;
\r
991 section->hdr.startPrbc = params->info.startPrbc;
\r
992 section->hdr.numPrbc = XRAN_CONVERT_NUMPRBC(params->info.numPrbc);
\r
994 section->hdr.u.s0.reMask = params->info.reMask;
\r
995 section->hdr.u.s0.numSymbol = params->info.numSymbol;
\r
996 section->hdr.u.s0.reserved = 0;
\r
998 // for network byte order
\r
999 *((uint64_t *)section) = rte_cpu_to_be_64(*((uint64_t *)section));
\r
1001 return (XRAN_STATUS_SUCCESS);
\r
1004 * @brief Fill the section header of type 0 in C-Plane packet
\r
1007 * A pointer to the section header in the packet buffer
\r
1009 * A porinter to the information to generate a C-Plane packet
\r
1011 * XRAN_STATUS_SUCCESS always
\r
1013 static int xran_prepare_section0_hdr(
\r
1014 struct xran_cp_radioapp_section0_header *s0hdr,
\r
1015 struct xran_cp_gen_params *params)
\r
1018 s0hdr->timeOffset = rte_cpu_to_be_16(params->hdr.timeOffset);
\r
1019 s0hdr->frameStructure.fftSize = params->hdr.fftSize;
\r
1020 s0hdr->frameStructure.uScs = params->hdr.scs;
\r
1021 s0hdr->cpLength = rte_cpu_to_be_16(params->hdr.cpLength);
\r
1022 s0hdr->reserved = 0;
\r
1024 return (XRAN_STATUS_SUCCESS);
\r
1028 * @brief Fill the section body of type 1 in C-Plane packet
\r
1029 * Extension is not supported.
\r
1032 * A pointer to the section header in the packet buffer
\r
1034 * A porinter to the information to generate a C-Plane packet
\r
1036 * XRAN_STATUS_SUCCESS on success
\r
1037 * XRAN_STATUS_INVALID_PARM if the number of symbol is invalid
\r
1039 static int xran_prepare_section1(
\r
1040 struct xran_cp_radioapp_section1 *section,
\r
1041 struct xran_section_gen_info *params)
\r
1043 #if (XRAN_STRICT_PARM_CHECK)
\r
1044 if(unlikely(params->info.numSymbol > XRAN_SYMBOLNUMBER_MAX)) {
\r
1045 print_err("Invalid number of Symbols - %d", params->info.numSymbol);
\r
1046 return (XRAN_STATUS_INVALID_PARAM);
\r
1050 section->hdr.sectionId = params->info.id;
\r
1051 section->hdr.rb = params->info.rb;
\r
1052 section->hdr.symInc = params->info.symInc;
\r
1053 section->hdr.startPrbc = params->info.startPrbc;
\r
1054 section->hdr.numPrbc = XRAN_CONVERT_NUMPRBC(params->info.numPrbc);
\r
1056 section->hdr.u.s1.reMask = params->info.reMask;
\r
1057 section->hdr.u.s1.numSymbol = params->info.numSymbol;
\r
1058 section->hdr.u.s1.beamId = params->info.beamId;
\r
1060 section->hdr.u.s1.ef = params->info.ef;
\r
1062 // for network byte order
\r
1063 *((uint64_t *)section) = rte_cpu_to_be_64(*((uint64_t *)section));
\r
1065 return (XRAN_STATUS_SUCCESS);
\r
1068 * @brief Fill the section header of type 1 in C-Plane packet
\r
1071 * A pointer to the section header in the packet buffer
\r
1073 * A porinter to the information to generate a C-Plane packet
\r
1075 * XRAN_STATUS_SUCCESS always
\r
1077 static int xran_prepare_section1_hdr(
\r
1078 struct xran_cp_radioapp_section1_header *s1hdr,
\r
1079 struct xran_cp_gen_params *params)
\r
1081 s1hdr->udComp.udIqWidth = params->hdr.iqWidth;
\r
1082 s1hdr->udComp.udCompMeth = params->hdr.compMeth;
\r
1083 s1hdr->reserved = 0;
\r
1085 return (XRAN_STATUS_SUCCESS);
\r
1089 * @brief Fill the section body of type 3 in C-Plane packet
\r
1090 * Extension is not supported.
\r
1093 * A pointer to the section header in the packet buffer
\r
1095 * A porinter to the information to generate a C-Plane packet
\r
1097 * XRAN_STATUS_SUCCESS on success
\r
1098 * XRAN_STATUS_INVALID_PARM if the number of symbol is invalid
\r
1100 static int xran_prepare_section3(
\r
1101 struct xran_cp_radioapp_section3 *section,
\r
1102 struct xran_section_gen_info *params)
\r
1104 #if (XRAN_STRICT_PARM_CHECK)
\r
1105 if(unlikely(params->info.numSymbol > XRAN_SYMBOLNUMBER_MAX)) {
\r
1106 print_err("Invalid number of Symbols - %d", params->info.numSymbol);
\r
1107 return (XRAN_STATUS_INVALID_PARAM);
\r
1111 section->hdr.sectionId = params->info.id;
\r
1112 section->hdr.rb = params->info.rb;
\r
1113 section->hdr.symInc = params->info.symInc;
\r
1114 section->hdr.startPrbc = params->info.startPrbc;
\r
1115 section->hdr.numPrbc = XRAN_CONVERT_NUMPRBC(params->info.numPrbc);
\r
1117 section->hdr.u.s3.reMask = params->info.reMask;
\r
1118 section->hdr.u.s3.numSymbol = params->info.numSymbol;
\r
1119 section->hdr.u.s3.beamId = params->info.beamId;
\r
1121 section->freqOffset = rte_cpu_to_be_32(params->info.freqOffset)>>8;
\r
1122 section->reserved = 0;
\r
1124 section->hdr.u.s3.ef = params->info.ef;
\r
1126 // for network byte order (header, 8 bytes)
\r
1127 *((uint64_t *)section) = rte_cpu_to_be_64(*((uint64_t *)section));
\r
1129 return (XRAN_STATUS_SUCCESS);
\r
1132 * @brief Fill the section header of type 3 in C-Plane packet
\r
1135 * A pointer to the section header in the packet buffer
\r
1137 * A porinter to the information to generate a C-Plane packet
\r
1139 * XRAN_STATUS_SUCCESS always
\r
1141 static int xran_prepare_section3_hdr(
\r
1142 struct xran_cp_radioapp_section3_header *s3hdr,
\r
1143 struct xran_cp_gen_params *params)
\r
1146 s3hdr->timeOffset = rte_cpu_to_be_16(params->hdr.timeOffset);
\r
1147 s3hdr->frameStructure.fftSize = params->hdr.fftSize;
\r
1148 s3hdr->frameStructure.uScs = params->hdr.scs;
\r
1149 s3hdr->cpLength = rte_cpu_to_be_16(params->hdr.cpLength);
\r
1150 s3hdr->udComp.udIqWidth = params->hdr.iqWidth;
\r
1151 s3hdr->udComp.udCompMeth = params->hdr.compMeth;
\r
1153 return (XRAN_STATUS_SUCCESS);
\r
1157 * @brief add sections to C-Plane packet
\r
1158 * Section type 1 and 3 are supported.
\r
1161 * A pointer to the packet buffer
\r
1163 * A porinter to the information to generate a C-Plane packet
\r
1165 * XRAN_STATUS_SUCCESS on success
\r
1166 * XRAN_STATUS_INVALID_PARM if section type is not 1 or 3, or handler is NULL
\r
1167 * XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
\r
1169 int xran_append_control_section(struct rte_mbuf *mbuf, struct xran_cp_gen_params *params)
\r
1171 int i, ret, ext_flag;
\r
1175 int (*xran_prepare_section_func)(void *section, void *params);
\r
1179 switch(params->sectionType) {
\r
1180 case XRAN_CP_SECTIONTYPE_0: /* Unused RB or Symbols in DL or UL, not supportted */
\r
1181 section_size = sizeof(struct xran_cp_radioapp_section0);
\r
1182 xran_prepare_section_func = (int (*)(void *, void *))xran_prepare_section0;
\r
1185 case XRAN_CP_SECTIONTYPE_1: /* Most DL/UL Radio Channels */
\r
1186 section_size = sizeof(struct xran_cp_radioapp_section1);
\r
1187 xran_prepare_section_func = (int (*)(void *, void *))xran_prepare_section1;
\r
1190 case XRAN_CP_SECTIONTYPE_3: /* PRACH and Mixed-numerology Channels */
\r
1191 section_size = sizeof(struct xran_cp_radioapp_section3);
\r
1192 xran_prepare_section_func = (int (*)(void *, void *))xran_prepare_section3;
\r
1195 case XRAN_CP_SECTIONTYPE_5: /* UE scheduling information, not supported */
\r
1196 case XRAN_CP_SECTIONTYPE_6: /* Channel Information, not supported */
\r
1197 case XRAN_CP_SECTIONTYPE_7: /* LAA, not supported */
\r
1200 xran_prepare_section_func = NULL;
\r
1201 print_err("Section Type %d is not supported!", params->sectionType);
\r
1202 return (XRAN_STATUS_INVALID_PARAM);
\r
1205 if(unlikely(xran_prepare_section_func == NULL)) {
\r
1206 print_err("Section Type %d is not supported!", params->sectionType);
\r
1207 return (XRAN_STATUS_INVALID_PARAM);
\r
1210 for(i=0; i < params->numSections; i++) {
\r
1211 section = rte_pktmbuf_append(mbuf, section_size);
\r
1212 if(section == NULL) {
\r
1213 print_err("Fail to allocate the space for section[%d]!", i);
\r
1214 return (XRAN_STATUS_RESOURCE);
\r
1216 print_dbg("%s %d ef %d\n", __FUNCTION__, i, params->sections[i].info.ef);
\r
1217 ret = xran_prepare_section_func((void *)section,
\r
1218 (void *)¶ms->sections[i]);
\r
1220 print_err("%s %d\n", __FUNCTION__, ret);
\r
1223 totalen += section_size;
\r
1225 if(params->sections[i].info.ef) {
\r
1226 print_dbg("sections[%d].info.ef %d exDataSize %d type %d\n", i, params->sections[i].info.ef,
\r
1227 params->sections[i].exDataSize, params->sections[i].exData[0].type);
\r
1228 ret = xran_append_section_extensions(mbuf, ¶ms->sections[i]);
\r
1239 * @brief fill the information of a radio application header in a C-Plane packet
\r
1242 * A pointer to the application header in the packet buffer
\r
1244 * A porinter to the information to generate a C-Plane packet
\r
1246 * XRAN_STATUS_SUCCESS on success
\r
1247 * XRAN_STATUS_INVALID_PARM if direction, slot index or symbold index is invalid
\r
1249 static inline int xran_prepare_radioapp_common_header(
\r
1250 struct xran_cp_radioapp_common_header *apphdr,
\r
1251 struct xran_cp_gen_params *params)
\r
1254 #if (XRAN_STRICT_PARM_CHECK)
\r
1255 if(unlikely(params->dir != XRAN_DIR_DL && params->dir != XRAN_DIR_UL)) {
\r
1256 print_err("Invalid direction!");
\r
1257 return (XRAN_STATUS_INVALID_PARAM);
\r
1259 if(unlikely(params->hdr.slotId > XRAN_SLOTID_MAX)) {
\r
1260 print_err("Invalid Slot ID!");
\r
1261 return (XRAN_STATUS_INVALID_PARAM);
\r
1263 if(unlikely(params->hdr.startSymId > XRAN_SYMBOLNUMBER_MAX)) {
\r
1264 print_err("Invalid Symbol ID!");
\r
1265 return (XRAN_STATUS_INVALID_PARAM);
\r
1269 apphdr->dataDirection = params->dir;
\r
1270 apphdr->payloadVer = XRAN_PAYLOAD_VER;
\r
1271 apphdr->filterIndex = params->hdr.filterIdx;
\r
1272 apphdr->frameId = params->hdr.frameId;
\r
1273 apphdr->subframeId = params->hdr.subframeId;
\r
1274 apphdr->slotId = params->hdr.slotId;
\r
1275 apphdr->startSymbolId = params->hdr.startSymId;
\r
1276 apphdr->numOfSections = params->numSections;
\r
1277 apphdr->sectionType = params->sectionType;
\r
1279 /* radio app header has common parts of 4bytes for all section types */
\r
1280 *((uint32_t *)apphdr) = rte_cpu_to_be_32(*((uint32_t *)apphdr));
\r
1282 return (XRAN_STATUS_SUCCESS);
\r
1286 * @brief add a radio application header in a C-Plane packet
\r
1289 * A pointer to the packet buffer
\r
1291 * A porinter to the information to generate a C-Plane packet
\r
1293 * The length of added section (>0) on success
\r
1294 * XRAN_STATUS_INVALID_PARM if section type is invalid, or handler is NULL
\r
1295 * XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
\r
1297 int xran_append_radioapp_header(struct rte_mbuf *mbuf, struct xran_cp_gen_params *params)
\r
1301 struct xran_cp_radioapp_common_header *apphdr;
\r
1302 int (*xran_prepare_radioapp_section_hdr_func)(void *hdr, void *params);
\r
1305 #if (XRAN_STRICT_PARM_CHECK)
\r
1306 if(unlikely(params->sectionType >= XRAN_CP_SECTIONTYPE_MAX)) {
\r
1307 print_err("Invalid Section Type - %d", params->sectionType);
\r
1308 return (XRAN_STATUS_INVALID_PARAM);
\r
1312 switch(params->sectionType) {
\r
1313 case XRAN_CP_SECTIONTYPE_0: /* Unused RB or Symbols in DL or UL, not supportted */
\r
1314 xran_prepare_radioapp_section_hdr_func = (int (*)(void *, void*))xran_prepare_section0_hdr;
\r
1315 totalen = sizeof(struct xran_cp_radioapp_section0_header);
\r
1318 case XRAN_CP_SECTIONTYPE_1: /* Most DL/UL Radio Channels */
\r
1319 xran_prepare_radioapp_section_hdr_func = (int (*)(void *, void*))xran_prepare_section1_hdr;
\r
1320 totalen = sizeof(struct xran_cp_radioapp_section1_header);
\r
1323 case XRAN_CP_SECTIONTYPE_3: /* PRACH and Mixed-numerology Channels */
\r
1324 xran_prepare_radioapp_section_hdr_func = (int (*)(void *, void*))xran_prepare_section3_hdr;
\r
1325 totalen = sizeof(struct xran_cp_radioapp_section3_header);
\r
1328 case XRAN_CP_SECTIONTYPE_5: /* UE scheduling information, not supported */
\r
1329 case XRAN_CP_SECTIONTYPE_6: /* Channel Information, not supported */
\r
1330 case XRAN_CP_SECTIONTYPE_7: /* LAA, not supported */
\r
1332 print_err("Section Type %d is not supported!", params->sectionType);
\r
1333 xran_prepare_radioapp_section_hdr_func = NULL;
\r
1335 return (XRAN_STATUS_INVALID_PARAM);
\r
1338 apphdr = (struct xran_cp_radioapp_common_header *)rte_pktmbuf_append(mbuf, totalen);
\r
1339 if(unlikely(apphdr == NULL)) {
\r
1340 print_err("Fail to reserve the space for radio application header!");
\r
1341 return (XRAN_STATUS_RESOURCE);
\r
1344 ret = xran_prepare_radioapp_common_header(apphdr, params);
\r
1345 if(unlikely(ret < 0)) {
\r
1349 if(likely(xran_prepare_radioapp_section_hdr_func)) {
\r
1350 totalen += xran_prepare_radioapp_section_hdr_func(apphdr, params);
\r
1353 print_err("xran_prepare_radioapp_section_hdr_func is NULL!");
\r
1354 return (XRAN_STATUS_INVALID_PARAM);
\r
1361 * @brief Create a C-Plane packet
\r
1362 * Transport layer fragmentation is not supported.
\r
1364 * @ingroup xran_cp_pkt
\r
1367 * A pointer to the packet buffer
\r
1369 * A porinter to the information to generate a C-Plane packet
\r
1371 * Component Carrier ID for this C-Plane message
\r
1373 * Antenna ID(RU Port ID) for this C-Plane message
\r
1375 * Sequence ID for this C-Plane message
\r
1377 * XRAN_STATUS_SUCCESS on success
\r
1378 * XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
\r
1379 * XRAN_STATUS_INVALID_PARM if section type is invalid
\r
1381 int xran_prepare_ctrl_pkt(struct rte_mbuf *mbuf,
\r
1382 struct xran_cp_gen_params *params,
\r
1383 uint8_t CC_ID, uint8_t Ant_ID,
\r
1387 uint32_t payloadlen;
\r
1388 struct xran_ecpri_hdr *ecpri_hdr;
\r
1391 payloadlen = xran_build_ecpri_hdr(mbuf, CC_ID, Ant_ID, seq_id, &ecpri_hdr);
\r
1393 ret = xran_append_radioapp_header(mbuf, params);
\r
1395 print_err("%s %d\n", __FUNCTION__, ret);
\r
1398 payloadlen += ret;
\r
1400 ret = xran_append_control_section(mbuf, params);
\r
1402 print_err("%s %d\n", __FUNCTION__, ret);
\r
1405 payloadlen += ret;
\r
1407 /* set payload length */
\r
1408 ecpri_hdr->cmnhdr.ecpri_payl_size = rte_cpu_to_be_16(payloadlen);
\r
1410 return (XRAN_STATUS_SUCCESS);
\r
1414 ///////////////////////////////////////
\r
1415 // for RU emulation
\r
1416 int xran_parse_section_ext1(void *ext,
\r
1417 struct xran_sectionext1_info *extinfo)
\r
1421 struct xran_cp_radioapp_section_ext1 *ext1;
\r
1423 int parm_size, iq_size;
\r
1428 N = xran_get_conf_num_bfweights(pHandle);
\r
1429 extinfo->bfwNumber = N;
\r
1431 ext1 = (struct xran_cp_radioapp_section_ext1 *)ext;
\r
1432 data = (uint8_t *)ext;
\r
1435 total_len = ext1->extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
\r
1437 extinfo->bfwCompMeth = ext1->bfwCompMeth;
\r
1438 extinfo->bfwiqWidth = (ext1->bfwIqWidth==0)?16:ext1->bfwIqWidth;
\r
1440 len += sizeof(struct xran_cp_radioapp_section_ext1);
\r
1441 data += sizeof(struct xran_cp_radioapp_section_ext1);
\r
1443 switch(ext1->bfwCompMeth) {
\r
1444 case XRAN_BFWCOMPMETHOD_NONE:
\r
1448 case XRAN_BFWCOMPMETHOD_BLKFLOAT:
\r
1450 extinfo->bfwCompParam.exponent = *data & 0x0f;
\r
1453 case XRAN_BFWCOMPMETHOD_BLKSCALE:
\r
1455 extinfo->bfwCompParam.blockScaler = *data;
\r
1458 case XRAN_BFWCOMPMETHOD_ULAW:
\r
1460 extinfo->bfwCompParam.compBitWidthShift = *data;
\r
1463 case XRAN_BFWCOMPMETHOD_BEAMSPACE:
\r
1464 parm_size = N>>3; if(N%8) parm_size++; parm_size *= 8;
\r
1465 rte_memcpy(data, extinfo->bfwCompParam.activeBeamspaceCoeffMask, parm_size);
\r
1469 print_err("Invalid BfComp method - %d", ext1->bfwCompMeth);
\r
1474 data += parm_size;
\r
1476 /* Get BF weights */
\r
1477 iq_size = N * extinfo->bfwiqWidth * 2; // total in bits
\r
1478 parm_size = iq_size>>3; // total in bytes (/8)
\r
1479 if(iq_size%8) parm_size++; // round up
\r
1481 //rte_memcpy(data, extinfo->p_bfwIQ, parm_size);
\r
1482 extinfo->p_bfwIQ = (int16_t*)data;
\r
1486 parm_size = len % XRAN_SECTIONEXT_ALIGN;
\r
1488 len += (XRAN_SECTIONEXT_ALIGN - parm_size);
\r
1490 if(len != total_len) {
\r
1491 // TODO: fix this print_err("The size of extension 1 is not correct! [%d:%d]", len, total_len);
\r
1494 return (total_len);
\r
1497 int xran_parse_section_ext2(void *ext,
\r
1498 struct xran_sectionext2_info *extinfo)
\r
1502 struct xran_cp_radioapp_section_ext2 *ext2;
\r
1509 ext2 = (struct xran_cp_radioapp_section_ext2 *)ext;
\r
1510 data = (uint8_t *)ext;
\r
1511 *(uint32_t *)ext2 = rte_cpu_to_be_32(*(uint32_t *)ext2);
\r
1514 total_len = ext2->extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
\r
1516 parm_size = sizeof(struct xran_cp_radioapp_section_ext2);
\r
1518 extinfo->bfAzPtWidth = ext2->bfAzPtWidth;
\r
1519 extinfo->bfZePtWidth = ext2->bfZePtWidth;
\r
1520 extinfo->bfAz3ddWidth = ext2->bfAz3ddWidth;
\r
1521 extinfo->bfZe3ddWidth = ext2->bfZe3ddWidth;
\r
1523 if(ext2->bfaCompResv0 || ext2->bfaCompResv1)
\r
1524 print_err("Incorrect reserved field - %d, %d", ext2->bfaCompResv0, ext2->bfaCompResv1);
\r
1526 data += parm_size;
\r
1529 val_size = (extinfo->bfAzPtWidth ? extinfo->bfAzPtWidth+1 : 0)
\r
1530 + (extinfo->bfZePtWidth ? extinfo->bfZePtWidth+1 : 0)
\r
1531 + (extinfo->bfAz3ddWidth ? extinfo->bfAz3ddWidth+1 : 0)
\r
1532 + (extinfo->bfZe3ddWidth ? extinfo->bfZe3ddWidth+ 1: 0);
\r
1534 val = rte_cpu_to_be_32(*(uint32_t *)data);
\r
1535 val >>= (32 - val_size);
\r
1537 if(extinfo->bfZe3ddWidth) {
\r
1538 extinfo->bfZe3dd = val & bitmask[extinfo->bfZe3ddWidth];
\r
1539 val >>= (extinfo->bfZe3ddWidth + 1);
\r
1541 if(extinfo->bfAz3ddWidth) {
\r
1542 extinfo->bfAz3dd = val & bitmask[extinfo->bfAz3ddWidth];
\r
1543 val >>= (extinfo->bfAz3ddWidth + 1);
\r
1545 if(extinfo->bfZePtWidth) {
\r
1546 extinfo->bfZePt = val & bitmask[extinfo->bfZePtWidth];
\r
1547 val >>= (extinfo->bfZePtWidth + 1);
\r
1549 if(extinfo->bfAzPtWidth) {
\r
1550 extinfo->bfAzPt = val & bitmask[extinfo->bfAzPtWidth];
\r
1551 val >>= (extinfo->bfAzPtWidth + 1);
\r
1555 parm_size = val_size/8;
\r
1556 if(val_size%8) parm_size += 1;
\r
1558 data += parm_size;
\r
1561 extinfo->bfAzSI = (*data >> 3) & 0x07;
\r
1562 extinfo->bfZeSI = *data & 0x07;
\r
1567 parm_size = len % XRAN_SECTIONEXT_ALIGN;
\r
1569 len += (XRAN_SECTIONEXT_ALIGN - parm_size);
\r
1571 if(len != total_len) {
\r
1572 print_err("The size of extension 2 is not correct! [%d:%d]", len, total_len);
\r
1575 return (total_len);
\r
1579 int xran_parse_section_ext4(void *ext,
\r
1580 struct xran_sectionext4_info *extinfo)
\r
1583 struct xran_cp_radioapp_section_ext4 *ext4;
\r
1587 ext4 = (struct xran_cp_radioapp_section_ext4 *)ext;
\r
1589 *(uint32_t *)ext4 = rte_cpu_to_be_32(*(uint32_t *)ext4);
\r
1592 total_len = ext4->extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
\r
1594 extinfo->modCompScaler = ext4->modCompScaler;
\r
1595 extinfo->csf = ext4->csf;
\r
1598 len += sizeof(struct xran_cp_radioapp_section_ext4);
\r
1599 if(len != total_len) {
\r
1600 print_err("The size of extension 4 is not correct! [%d:%d]", len, total_len);
\r
1603 return (total_len);
\r
1606 int xran_parse_section_ext5(void *ext,
\r
1607 struct xran_sectionext5_info *extinfo)
\r
1610 struct xran_cp_radioapp_section_ext_hdr *ext_hdr;
\r
1611 struct xran_cp_radioapp_section_ext5 ext5;
\r
1618 ext_hdr = (struct xran_cp_radioapp_section_ext_hdr *)ext;
\r
1619 *(uint16_t *)ext_hdr = rte_cpu_to_be_16(*(uint16_t *)ext_hdr);
\r
1621 total_len = ext_hdr->extLen * XRAN_SECTIONEXT_ALIGN; /* from word to byte */
\r
1623 // one set has 3.5 bytes, so enforcing double to do integer calculation
\r
1624 parm_size = ((total_len-sizeof(struct xran_cp_radioapp_section_ext_hdr))*2) / 7;
\r
1626 if(parm_size > XRAN_MAX_MODCOMP_ADDPARMS) {
\r
1627 print_err("Exceeds maximum number of parameters - %d", parm_size);
\r
1628 parm_size = XRAN_MAX_MODCOMP_ADDPARMS;
\r
1632 data = (uint8_t *)(ext_hdr + 1);
\r
1635 while(i < parm_size) {
\r
1636 // For odd number set, more data can be copied
\r
1637 *((uint64_t *)&ext5) = rte_cpu_to_be_64(*((uint64_t *)data));
\r
1639 extinfo->mc[i].mcScaleOffset = ext5.mcScaleOffset1;
\r
1640 extinfo->mc[i].csf = ext5.csf1;
\r
1641 extinfo->mc[i].mcScaleReMask = ext5.mcScaleReMask1;
\r
1644 extinfo->mc[i].mcScaleOffset = ext5.mcScaleOffset2;
\r
1645 extinfo->mc[i].csf = ext5.csf2;
\r
1646 extinfo->mc[i].mcScaleReMask = ext5.mcScaleReMask2;
\r
1649 data += sizeof(struct xran_cp_radioapp_section_ext5);
\r
1652 // check the values of last set
\r
1653 // due to alignment, it cannot be identified by the length that 3 or 4, 11 or 12 and etc
\r
1654 // don't check mcScaleOffset might not be zero (some part is out of zero-padding)
\r
1656 if(i < XRAN_MAX_MODCOMP_ADDPARMS) {
\r
1657 if(extinfo->mc[i].csf == 0 && extinfo->mc[i].mcScaleReMask == 0)
\r
1658 extinfo->num_sets = i;
\r
1660 extinfo->num_sets = i+1;
\r
1662 print_err("Maximum total number %d is not correct!", i);
\r
1665 return (total_len);
\r
1668 int xran_parse_section_extension(struct rte_mbuf *mbuf,
\r
1670 struct xran_section_gen_info *section)
\r
1672 int total_len, len, numext;
\r
1679 ptr = (uint8_t *)ext;
\r
1685 while(flag_last) {
\r
1687 flag_last = (*ptr & 0x80);
\r
1689 ext_type = *ptr & 0x7f;
\r
1690 section->exData[numext].type = ext_type;
\r
1691 switch(ext_type) {
\r
1692 case XRAN_CP_SECTIONEXTCMD_1:
\r
1693 section->exData[numext].data = §ion->m_ext1[numext];
\r
1694 len = xran_parse_section_ext1(ptr, section->exData[numext].data);
\r
1695 section->exData[numext].len = len;
\r
1697 case XRAN_CP_SECTIONEXTCMD_2:
\r
1698 section->exData[numext].data = §ion->m_ext2[numext];
\r
1699 len = xran_parse_section_ext2(ptr, section->exData[numext].data);
\r
1701 case XRAN_CP_SECTIONEXTCMD_4:
\r
1702 section->exData[numext].data = §ion->m_ext4[numext];
\r
1703 len = xran_parse_section_ext4(ptr, section->exData[numext].data);
\r
1705 case XRAN_CP_SECTIONEXTCMD_5:
\r
1706 section->exData[numext].data = §ion->m_ext5[numext];
\r
1707 len = xran_parse_section_ext5(ptr, section->exData[numext].data);
\r
1710 case XRAN_CP_SECTIONEXTCMD_0:
\r
1711 case XRAN_CP_SECTIONEXTCMD_3:
\r
1713 print_err("Extension %d is not supported!", ext_type);
\r
1717 section->exData[numext].len = len;
\r
1718 ptr += len; total_len += len;
\r
1721 if(++numext < XRAN_MAX_NUM_EXTENSIONS) continue;
\r
1723 /* exceeds maximum number of extensions */
\r
1727 section->exDataSize = numext;
\r
1729 return (total_len);
\r
1734 * @brief Parse a C-Plane packet (for RU emulation)
\r
1735 * Transport layer fragmentation is not supported.
\r
1737 * @ingroup xran_cp_pkt
\r
1740 * The pointer of the packet buffer to be parsed
\r
1742 * The pointer of structure to store the information of parsed packet
\r
1744 * The pointer of sturcture to store the decomposed information of ecpriRtcid/ecpriPcid
\r
1746 * XRAN_STATUS_SUCCESS on success
\r
1747 * XRAN_STATUS_INVALID_PACKET if failed to parse the packet
\r
1749 int xran_parse_cp_pkt(struct rte_mbuf *mbuf,
\r
1750 struct xran_cp_gen_params *result,
\r
1751 struct xran_recv_packet_info *pkt_info)
\r
1753 struct xran_ecpri_hdr *ecpri_hdr;
\r
1754 struct xran_cp_radioapp_common_header *apphdr;
\r
1759 ret = xran_parse_ecpri_hdr(mbuf, &ecpri_hdr, pkt_info);
\r
1760 if(ret < 0 && ecpri_hdr == NULL)
\r
1761 return (XRAN_STATUS_INVALID_PACKET);
\r
1763 /* Process radio header. */
\r
1764 apphdr = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_ecpri_hdr));
\r
1765 if(apphdr == NULL) {
\r
1766 print_err("Invalid packet - radio app hedaer!");
\r
1767 return (XRAN_STATUS_INVALID_PACKET);
\r
1770 *((uint32_t *)apphdr) = rte_cpu_to_be_32(*((uint32_t *)apphdr));
\r
1772 if(apphdr->payloadVer != XRAN_PAYLOAD_VER) {
\r
1773 print_err("Invalid Payload version - %d", apphdr->payloadVer);
\r
1774 ret = XRAN_STATUS_INVALID_PACKET;
\r
1777 result->dir = apphdr->dataDirection;
\r
1778 result->hdr.filterIdx = apphdr->filterIndex;
\r
1779 result->hdr.frameId = apphdr->frameId;
\r
1780 result->hdr.subframeId = apphdr->subframeId;
\r
1781 result->hdr.slotId = apphdr->slotId;
\r
1782 result->hdr.startSymId = apphdr->startSymbolId;
\r
1783 result->sectionType = apphdr->sectionType;
\r
1784 result->numSections = apphdr->numOfSections;
\r
1787 printf("[CP%5d] eAxC[%d:%d:%02d:%02d] %s seq[%03d-%03d-%d] sec[%d-%d] frame[%3d-%2d-%2d] sym%02d\n",
\r
1788 pkt_info->payload_len,
\r
1789 pkt_info->eaxc.cuPortId, pkt_info->eaxc.bandSectorId,
\r
1790 pkt_info->eaxc.ccId, pkt_info->eaxc.ruPortId,
\r
1791 result->dir?"DL":"UL",
\r
1792 pkt_info->seq_id, pkt_info->subseq_id, pkt_info->ebit,
\r
1793 result->sectionType, result->numSections,
\r
1794 result->hdr.frameId, result->hdr.subframeId, result->hdr.slotId,
\r
1795 result->hdr.startSymId
\r
1799 switch(apphdr->sectionType) {
\r
1800 case XRAN_CP_SECTIONTYPE_0: // Unused RB or Symbols in DL or UL, not supportted
\r
1802 struct xran_cp_radioapp_section0_header *hdr;
\r
1803 struct xran_cp_radioapp_section0 *section;
\r
1805 hdr = (struct xran_cp_radioapp_section0_header*)apphdr;
\r
1807 result->hdr.fftSize = rte_be_to_cpu_16(hdr->timeOffset);
\r
1808 result->hdr.scs = hdr->frameStructure.fftSize;
\r
1809 result->hdr.timeOffset = hdr->frameStructure.uScs;
\r
1810 result->hdr.cpLength = rte_be_to_cpu_16(hdr->cpLength);
\r
1811 //hdr->reserved; /* should be zero */
\r
1813 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section0_header));
\r
1814 if(section == NULL) {
\r
1815 print_err("Invalid packet 0 - radio app hedaer!");
\r
1816 return (XRAN_STATUS_INVALID_PACKET);
\r
1818 for(i=0; i<result->numSections; i++) {
\r
1819 *((uint64_t *)section) = rte_be_to_cpu_64(*((uint64_t *)section));
\r
1821 result->sections[i].info.type = apphdr->sectionType;
\r
1822 result->sections[i].info.id = section->hdr.sectionId;
\r
1823 result->sections[i].info.rb = section->hdr.rb;
\r
1824 result->sections[i].info.symInc = section->hdr.symInc;
\r
1825 result->sections[i].info.startPrbc = section->hdr.startPrbc;
\r
1826 result->sections[i].info.numPrbc = section->hdr.numPrbc,
\r
1827 result->sections[i].info.numSymbol = section->hdr.u.s0.numSymbol;
\r
1828 result->sections[i].info.reMask = section->hdr.u.s0.reMask;
\r
1829 //section->hdr.u.s0.reserved; /* should be zero */
\r
1831 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section0));
\r
1832 if(section == NULL) {
\r
1833 print_err("Invalid packet 0 - number of section [%d:%d]!",
\r
1834 result->numSections, i);
\r
1835 result->numSections = i;
\r
1836 ret = XRAN_STATUS_INVALID_PACKET;
\r
1843 case XRAN_CP_SECTIONTYPE_1: // Most DL/UL Radio Channels
\r
1845 struct xran_cp_radioapp_section1_header *hdr;
\r
1846 struct xran_cp_radioapp_section1 *section;
\r
1848 hdr = (struct xran_cp_radioapp_section1_header*)apphdr;
\r
1850 result->hdr.iqWidth = hdr->udComp.udIqWidth;
\r
1851 result->hdr.compMeth = hdr->udComp.udCompMeth;
\r
1853 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section1_header));
\r
1854 if(section == NULL) {
\r
1855 print_err("Invalid packet 1 - radio app hedaer!");
\r
1856 return (XRAN_STATUS_INVALID_PACKET);
\r
1859 for(i=0; i<result->numSections; i++) {
\r
1860 *((uint64_t *)section) = rte_be_to_cpu_64(*((uint64_t *)section));
\r
1862 result->sections[i].info.type = apphdr->sectionType;
\r
1863 result->sections[i].info.id = section->hdr.sectionId;
\r
1864 result->sections[i].info.rb = section->hdr.rb;
\r
1865 result->sections[i].info.symInc = section->hdr.symInc;
\r
1866 result->sections[i].info.startPrbc = section->hdr.startPrbc;
\r
1867 result->sections[i].info.numPrbc = section->hdr.numPrbc,
\r
1868 result->sections[i].info.numSymbol = section->hdr.u.s1.numSymbol;
\r
1869 result->sections[i].info.reMask = section->hdr.u.s1.reMask;
\r
1870 result->sections[i].info.beamId = section->hdr.u.s1.beamId;
\r
1871 result->sections[i].info.ef = section->hdr.u.s1.ef;
\r
1873 section = (void *)rte_pktmbuf_adj(mbuf,
\r
1874 sizeof(struct xran_cp_radioapp_section1));
\r
1875 if(section == NULL) {
\r
1876 print_err("Invalid packet 1 - number of section [%d:%d]!",
\r
1877 result->numSections, i);
\r
1878 result->numSections = i;
\r
1879 ret = XRAN_STATUS_INVALID_PACKET;
\r
1883 if(result->sections[i].info.ef) {
\r
1884 // parse section extension
\r
1885 extlen = xran_parse_section_extension(mbuf, (void *)section, &result->sections[i]);
\r
1887 section = (void *)rte_pktmbuf_adj(mbuf, extlen);
\r
1888 if(section == NULL) {
\r
1889 print_err("Invalid packet 1 - section extension [%d]!", i);
\r
1890 ret = XRAN_STATUS_INVALID_PACKET;
\r
1900 case XRAN_CP_SECTIONTYPE_3: // PRACH and Mixed-numerology Channels
\r
1902 struct xran_cp_radioapp_section3_header *hdr;
\r
1903 struct xran_cp_radioapp_section3 *section;
\r
1905 hdr = (struct xran_cp_radioapp_section3_header*)apphdr;
\r
1907 result->hdr.timeOffset = rte_be_to_cpu_16(hdr->timeOffset);
\r
1908 result->hdr.scs = hdr->frameStructure.uScs;
\r
1909 result->hdr.fftSize = hdr->frameStructure.fftSize;
\r
1910 result->hdr.cpLength = rte_be_to_cpu_16(hdr->cpLength);
\r
1911 result->hdr.iqWidth = hdr->udComp.udIqWidth;
\r
1912 result->hdr.compMeth = hdr->udComp.udCompMeth;
\r
1914 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section3_header));
\r
1915 if(section == NULL) {
\r
1916 print_err("Invalid packet 3 - radio app hedaer!");
\r
1917 return (XRAN_STATUS_INVALID_PACKET);
\r
1920 for(i=0; i<result->numSections; i++) {
\r
1921 *((uint64_t *)section) = rte_be_to_cpu_64(*((uint64_t *)section));
\r
1923 result->sections[i].info.type = apphdr->sectionType;
\r
1924 result->sections[i].info.id = section->hdr.sectionId;
\r
1925 result->sections[i].info.rb = section->hdr.rb;
\r
1926 result->sections[i].info.symInc = section->hdr.symInc;
\r
1927 result->sections[i].info.startPrbc = section->hdr.startPrbc;
\r
1928 result->sections[i].info.numPrbc = section->hdr.numPrbc,
\r
1929 result->sections[i].info.numSymbol = section->hdr.u.s3.numSymbol;
\r
1930 result->sections[i].info.reMask = section->hdr.u.s3.reMask;
\r
1931 result->sections[i].info.beamId = section->hdr.u.s3.beamId;
\r
1932 result->sections[i].info.ef = section->hdr.u.s3.ef;
\r
1933 result->sections[i].info.freqOffset = ((int32_t)rte_be_to_cpu_32(section->freqOffset))>>8;
\r
1935 if(section->reserved) {
\r
1936 print_err("Invalid packet 3 - section[%d:%d]", i, section->reserved);
\r
1937 ret = XRAN_STATUS_INVALID_PACKET;
\r
1940 section = (void *)rte_pktmbuf_adj(mbuf, sizeof(struct xran_cp_radioapp_section3));
\r
1941 if(section == NULL) {
\r
1942 print_err("Invalid packet 3 - number of section [%d:%d]!",
\r
1943 result->numSections, i);
\r
1944 result->numSections = i;
\r
1945 ret = XRAN_STATUS_INVALID_PACKET;
\r
1949 if(result->sections[i].info.ef) {
\r
1950 // parse section extension
\r
1951 extlen = xran_parse_section_extension(mbuf, (void *)section, &result->sections[i]);
\r
1953 section = (void *)rte_pktmbuf_adj(mbuf, extlen);
\r
1954 if(section == NULL) {
\r
1955 print_err("Invalid packet 3 - section extension [%d]!", i);
\r
1956 ret = XRAN_STATUS_INVALID_PACKET;
\r
1966 case XRAN_CP_SECTIONTYPE_5: // UE scheduling information, not supported
\r
1967 case XRAN_CP_SECTIONTYPE_6: // Channel Information, not supported
\r
1968 case XRAN_CP_SECTIONTYPE_7: // LAA, not supported
\r
1970 ret = XRAN_STATUS_INVALID_PARAM;
\r
1971 print_err("Non-supported Section Type - %d", apphdr->sectionType);
\r
1975 printf("[CP-%s] [%3d:%2d:%2d] section%d[%d] startSym=%d filterIdx=%X IQwidth=%d CompMeth=%d\n",
\r
1976 result->dir?"DL":"UL",
\r
1977 result->hdr.frameId, result->hdr.subframeId, result->hdr.slotId,
\r
1978 result->sectionType, result->numSections,
\r
1979 result->hdr.startSymId,
\r
1980 result->hdr.filterIdx,
\r
1981 result->hdr.iqWidth, result->hdr.compMeth);
\r
1983 for(i=0; i<result->numSections; i++) {
\r
1984 printf(" || %3d:%04X| rb=%d symInc=%d numSym=%d startPrbc=%02d numPrbc=%d reMask=%03X beamId=%04X freqOffset=%d ef=%d\n",
\r
1985 i, result->sections[i].info.id,
\r
1986 result->sections[i].info.rb,
\r
1987 result->sections[i].info.symInc, result->sections[i].info.numSymbol,
\r
1988 result->sections[i].info.startPrbc, result->sections[i].info.numPrbc,
\r
1989 result->sections[i].info.reMask,
\r
1990 result->sections[i].info.beamId,
\r
1991 result->sections[i].info.freqOffset,
\r
1992 result->sections[i].info.ef);
\r
1994 if(result->sections[i].info.ef) {
\r
1995 for(int j=0; j<result->sections[i].exDataSize; j++) {
\r
1996 printf(" || %2d : type=%d len=%d\n",
\r
1997 j, result->sections[i].exData[j].type, result->sections[i].exData[j].len);
\r
1998 switch(result->sections[i].exData[j].type) {
\r
1999 case XRAN_CP_SECTIONEXTCMD_1:
\r
2001 struct xran_sectionext1_info *ext1;
\r
2002 ext1 = result->sections[i].exData[j].data;
\r
2003 printf(" || bfwNumber=%d bfwiqWidth=%d bfwCompMeth=%d\n",
\r
2004 ext1->bfwNumber, ext1->bfwiqWidth, ext1->bfwCompMeth);
\r
2007 case XRAN_CP_SECTIONEXTCMD_2:
\r
2009 struct xran_sectionext2_info *ext2;
\r
2010 ext2 = result->sections[i].exData[j].data;
\r
2011 printf(" || AzPt=%02x(%d) ZePt=%02x(%d) Az3dd=%02x(%d) Ze3dd=%02x(%d) AzSI=%02x ZeSI=%02x\n",
\r
2012 ext2->bfAzPt, ext2->bfAzPtWidth,
\r
2013 ext2->bfZePt, ext2->bfZePtWidth,
\r
2014 ext2->bfAz3dd, ext2->bfAz3ddWidth,
\r
2015 ext2->bfZe3dd, ext2->bfZe3ddWidth,
\r
2016 ext2->bfAzSI, ext2->bfZeSI);
\r
2019 case XRAN_CP_SECTIONEXTCMD_4:
\r
2021 struct xran_sectionext4_info *ext4;
\r
2022 ext4 = result->sections[i].exData[j].data;
\r
2023 printf(" || csf=%d modCompScaler=%d\n",
\r
2024 ext4->csf, ext4->modCompScaler);
\r
2027 case XRAN_CP_SECTIONEXTCMD_5:
\r
2029 struct xran_sectionext5_info *ext5;
\r
2030 ext5 = result->sections[i].exData[j].data;
\r
2031 printf(" || num_sets=%d\n", ext5->num_sets);
\r
2032 for(int k=0; k<ext5->num_sets; k++) {
\r
2033 printf(" || %d - csf=%d mcScaleReMask=%04x mcScaleOffset=%04x\n",
\r
2034 k, ext5->mc[k].csf,
\r
2035 ext5->mc[k].mcScaleReMask, ext5->mc[k].mcScaleOffset);
\r
2040 case XRAN_CP_SECTIONEXTCMD_0:
\r
2041 case XRAN_CP_SECTIONEXTCMD_3:
\r
2043 printf("Invalid section extension type!\n");
\r