+ return (freqOffset);
+}
+
+
+static int xran_prepare_sectionext_1(struct rte_mbuf *mbuf,
+ struct xran_sectionext1_info *params, int last_flag)
+{
+ struct xran_cp_radioapp_section_ext1 *ext1;
+ uint8_t *data;
+ int parm_size, iq_size;
+ int total_len;
+ static const uint8_t zeropad[XRAN_SECTIONEXT_ALIGN] = { 0, 0, 0, 0 };
+
+
+ total_len = 0;
+
+ parm_size = sizeof(struct xran_cp_radioapp_section_ext1);
+ ext1 = (struct xran_cp_radioapp_section_ext1 *)rte_pktmbuf_append(mbuf, parm_size);
+ if(ext1 == NULL) {
+ print_err("Fail to allocate the space for section extension 1");
+ return (XRAN_STATUS_RESOURCE);
+ }
+
+ total_len += parm_size;
+
+ ext1->extType = XRAN_CP_SECTIONEXTCMD_1;
+ ext1->ef = last_flag;
+ ext1->bfwCompMeth = params->bfwCompMeth;
+ ext1->bfwIqWidth = XRAN_CONVERT_BFWIQWIDTH(params->bfwiqWidth);
+
+ switch(params->bfwCompMeth) {
+ case XRAN_BFWCOMPMETHOD_BLKFLOAT:
+ parm_size = 1;
+ data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
+ if(data == NULL) {
+ print_err("Fail to allocate the space for section extension 1");
+ return (XRAN_STATUS_RESOURCE);
+ }
+ total_len += parm_size;
+ *data = (params->bfwCompParam.exponent & 0x0f);
+ break;
+
+ case XRAN_BFWCOMPMETHOD_BLKSCALE:
+ parm_size = 1;
+ data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
+ if(data == NULL) {
+ print_err("Fail to allocate the space for section extension 1");
+ return (XRAN_STATUS_RESOURCE);
+ }
+ total_len += parm_size;
+ *data = params->bfwCompParam.blockScaler;
+ break;
+
+ case XRAN_BFWCOMPMETHOD_ULAW:
+ parm_size = 1;
+ data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
+ if(data == NULL) {
+ print_err("Fail to allocate the space for section extension 1");
+ return (XRAN_STATUS_RESOURCE);
+ }
+ total_len += parm_size;
+ *data = params->bfwCompParam.compBitWidthShift;
+ break;
+
+ case XRAN_BFWCOMPMETHOD_BEAMSPACE:
+#if 0
+ parm_size = ceil(params->bfwNumber/8)*8;
+#else
+ parm_size = params->bfwNumber>>3;
+ if(params->bfwNumber%8) parm_size++;
+ parm_size *= 8;
+#endif
+ data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
+ if(data == NULL) {
+ print_err("Fail to allocate the space for section extension 1");
+ return (XRAN_STATUS_RESOURCE);
+ }
+ rte_memcpy(data, params->bfwCompParam.activeBeamspaceCoeffMask, parm_size);
+ total_len += parm_size;
+ break;
+
+ case XRAN_BFWCOMPMETHOD_NONE:
+ default:
+ parm_size = 0;
+ }
+
+ iq_size = params->bfwNumber * params->bfwiqWidth * 2;
+#if 0
+ parm_size = ceil(iq_size/8);
+#else
+ parm_size = iq_size>>3;
+ if(iq_size%8) parm_size++;
+#endif
+
+ data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
+ if(data == NULL) {
+ print_err("Fail to allocate the space for section extension 1");
+ return (XRAN_STATUS_RESOURCE);
+ }
+ rte_memcpy(data, params->bfwIQ, parm_size);
+
+ total_len += parm_size;
+ parm_size = total_len % XRAN_SECTIONEXT_ALIGN;
+ if(parm_size) {
+ parm_size = XRAN_SECTIONEXT_ALIGN - parm_size;
+ data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
+ if(data == NULL) {
+ print_err("Fail to allocate the space for section extension 1");
+ return (XRAN_STATUS_RESOURCE);
+ }
+ rte_memcpy(data, zeropad, parm_size);
+ total_len += parm_size;
+ }
+
+ ext1->extLen = total_len / XRAN_SECTIONEXT_ALIGN;
+
+ return (total_len);
+}
+
+static int xran_prepare_sectionext_2(struct rte_mbuf *mbuf,
+ struct xran_sectionext2_info *params, int last_flag)
+{
+ struct xran_cp_radioapp_section_ext2 *ext2;
+ uint8_t *data;
+ int total_len;
+ int parm_size;
+ uint32_t val, shift_val;
+ int val_size;
+
+
+ total_len = 0;
+
+ parm_size = sizeof(struct xran_cp_radioapp_section_ext2);
+ ext2 = (struct xran_cp_radioapp_section_ext2 *)rte_pktmbuf_append(mbuf, parm_size);
+ if(ext2 == NULL) {
+ print_err("Fail to allocate the space for section extension 2");
+ return (XRAN_STATUS_RESOURCE);
+ }
+ total_len += parm_size;
+
+ ext2->extType = XRAN_CP_SECTIONEXTCMD_2;
+ ext2->ef = last_flag;
+ ext2->bfZe3ddWidth = params->bfZe3ddWidth;
+ ext2->bfAz3ddWidth = params->bfAz3ddWidth;
+ ext2->bfZePtWidth = params->bfZePtWidth;
+ ext2->bfAzPtWidth = params->bfAzPtWidth;
+ ext2->bfaCompResv0 = 0;
+ ext2->bfaCompResv1 = 0;
+
+ val = 0;
+ shift_val = 0;
+ if(params->bfAzPtWidth) {
+ val += params->bfAzPt;
+ shift_val += 8 - (params->bfAzPtWidth+1);
+ }
+ else
+ shift_val += 8;
+
+ if(params->bfZePtWidth) {
+ val = val << (params->bfZePtWidth+1);
+ val += params->bfZePt;
+ shift_val += 8 - (params->bfZePtWidth+1);
+ }
+ else
+ shift_val += 8;
+
+ if(params->bfAz3ddWidth) {
+ val = val << (params->bfAz3ddWidth+1);
+ val += params->bfAz3dd;
+ shift_val += 8 - (params->bfAz3ddWidth+1);
+ }
+ else
+ shift_val += 8;
+
+ if(params->bfZe3ddWidth) {
+ val = val << (params->bfZe3ddWidth+1);
+ val += params->bfZe3dd;
+ shift_val += 8 - (params->bfZe3ddWidth+1);
+ }
+ else
+ shift_val += 8;
+
+ if(val) {
+ val = val << shift_val;
+ val = rte_cpu_to_be_32(val);
+ }
+
+ val_size = 4 - (shift_val/8); /* ceil(total bit/8) */
+ parm_size = val_size + 1; /* additional 1 byte for bfxxSI */
+
+ data = (uint8_t *)rte_pktmbuf_append(mbuf, parm_size);
+ if(data == NULL) {
+ print_err("Fail to allocate the space for section extension 2");
+ return (XRAN_STATUS_RESOURCE);
+ }
+ total_len += parm_size;
+
+ rte_memcpy(data, &val, val_size);
+ data += val_size;
+ *data = ((params->bfAzSI) << 3) + (params->bfZeSI);
+
+ ext2->extLen = total_len / XRAN_SECTIONEXT_ALIGN;
+ *(uint32_t *)ext2 = rte_cpu_to_be_32(*(uint32_t *)ext2);
+
+ return (total_len);
+}
+
+static int xran_prepare_sectionext_4(struct rte_mbuf *mbuf,
+ struct xran_sectionext4_info *params, int last_flag)
+{
+ struct xran_cp_radioapp_section_ext4 *ext4;
+ int parm_size;
+ int total_len;
+ int ret;
+
+
+ total_len = 0;
+
+ parm_size = sizeof(struct xran_cp_radioapp_section_ext4);
+ ext4 = (struct xran_cp_radioapp_section_ext4 *)rte_pktmbuf_append(mbuf, parm_size);
+ if(ext4 == NULL) {
+ print_err("Fail to allocate the space for section extension 4");
+ return(XRAN_STATUS_RESOURCE);
+ }
+ else {
+ total_len += parm_size;
+
+ ext4->extType = XRAN_CP_SECTIONEXTCMD_4;
+ ext4->ef = last_flag;
+ ext4->modCompScaler = params->modCompScaler;
+ ext4->csf = params->csf?1:0;
+ ext4->extLen = 1;
+
+ *(uint32_t *)ext4 = rte_cpu_to_be_32(*(uint32_t*)ext4);
+ }
+
+ return (total_len);
+}
+
+static int xran_prepare_sectionext_5(struct rte_mbuf *mbuf,
+ struct xran_sectionext5_info *params, int last_flag)
+{
+ struct xran_cp_radioapp_section_ext5_1 *ext5_1;
+ struct xran_cp_radioapp_section_ext5_2 *ext5_2;
+ int parm_size;
+ int total_len;
+ uint32_t *data;
+
+
+ total_len = 0;
+
+ if(params->num_sets == 1) {
+ parm_size = sizeof(struct xran_cp_radioapp_section_ext5_1);
+ ext5_1 = (struct xran_cp_radioapp_section_ext5_1 *)rte_pktmbuf_append(mbuf, parm_size);
+ if(ext5_1 == NULL) {
+ print_err("Fail to allocate the space for section extension 5-1");
+ return (XRAN_STATUS_RESOURCE);
+ }
+ else {
+ total_len += parm_size;
+
+ ext5_1->extType = XRAN_CP_SECTIONEXTCMD_5;
+ ext5_1->ef = last_flag;
+
+ ext5_1->mcScaleOffset = params->mc[0].mcScaleOffset;
+ ext5_1->csf = params->mc[0].csf;
+ ext5_1->mcScaleReMask = params->mc[0].mcScaleReMask;
+ ext5_1->reserved = 0;
+
+ ext5_1->extLen = 2;
+
+ *(uint64_t *)ext5_1 = rte_cpu_to_be_64(*(uint64_t *)ext5_1);
+ }
+ }
+ else if(params->num_sets == 2) {
+ parm_size = sizeof(struct xran_cp_radioapp_section_ext5_2);
+ ext5_2 = (struct xran_cp_radioapp_section_ext5_2 *)rte_pktmbuf_append(mbuf, parm_size);
+ if(ext5_2 == NULL) {
+ print_err("Fail to allocate the space for section extension 5-2");
+ return (XRAN_STATUS_RESOURCE);
+ }
+ else {
+ total_len += parm_size;
+
+ ext5_2->extType = XRAN_CP_SECTIONEXTCMD_5;
+ ext5_2->ef = last_flag;
+
+ ext5_2->mcScaleOffset1 = params->mc[0].mcScaleOffset;
+ ext5_2->csf1 = params->mc[0].csf;
+ ext5_2->mcScaleReMask1 = params->mc[0].mcScaleReMask;
+ ext5_2->mcScaleOffset2 = params->mc[1].mcScaleOffset;
+ ext5_2->csf2 = params->mc[1].csf;
+ ext5_2->mcScaleReMask2 = params->mc[1].mcScaleReMask;
+
+ ext5_2->reserved0 = 0;
+ ext5_2->reserved1 = 0;
+
+ ext5_2->extLen = 3;
+
+ *(uint64_t *)ext5_2 = rte_cpu_to_be_64(*(uint64_t *)ext5_2);
+ data = (uint32_t *)((uint8_t *)ext5_2 + 8);
+ *data = rte_cpu_to_be_32(*data);
+ }
+ }
+ else {
+ print_err("Invalid number of scalar values - %d", params->num_sets);
+ return (XRAN_STATUS_INVALID_PARAM);
+ }
+
+ return (total_len);
+}
+
+/**
+ * @brief add section extension to C-Plane packet
+ *
+ * @param mbuf
+ * A pointer to the packet buffer
+ * @param params
+ * A porinter to the information to generate a C-Plane packet
+ * @return
+ * XRAN_STATUS_SUCCESS on success
+ * XRAN_STATUS_INVALID_PARM
+ * XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
+ */
+int xran_append_section_extensions(struct rte_mbuf *mbuf, struct xran_section_gen_info *params)
+{
+ int i, ret;
+ uint32_t totalen;
+ int last_flag;
+ int ext_size;
+
+
+ if(unlikely(params->exDataSize >= XRAN_MAX_NUM_EXTENSIONS)) {
+ print_err("Invalid total number of extensions - %d", params->exDataSize);
+ return (XRAN_STATUS_INVALID_PARAM);
+ }
+
+ totalen = 0;
+
+
+ ret = XRAN_STATUS_SUCCESS;
+
+ for(i=0; i < params->exDataSize; i++) {
+ if(params->exData[i].data == NULL) {
+ print_err("Invalid parameter - extension data %d is NULL", i);
+ ret = XRAN_STATUS_INVALID_PARAM;
+ continue;
+ }
+
+// params->exData[].len
+ last_flag = ((params->exDataSize - i)==1)?0:1;
+ switch(params->exData[i].type) {
+ case XRAN_CP_SECTIONEXTCMD_1:
+ ext_size = xran_prepare_sectionext_1(mbuf, params->exData[i].data, last_flag);
+ break;
+ case XRAN_CP_SECTIONEXTCMD_2:
+ ext_size = xran_prepare_sectionext_2(mbuf, params->exData[i].data, last_flag);
+ break;
+ case XRAN_CP_SECTIONEXTCMD_4:
+ ext_size = xran_prepare_sectionext_4(mbuf, params->exData[i].data, last_flag);
+ break;
+ case XRAN_CP_SECTIONEXTCMD_5:
+ ext_size = xran_prepare_sectionext_5(mbuf, params->exData[i].data, last_flag);
+ break;
+
+ case XRAN_CP_SECTIONEXTCMD_0:
+ case XRAN_CP_SECTIONEXTCMD_3:
+ default:
+ print_err("Extension Type %d is not supported!", params->exData[i].type);
+ ret = XRAN_STATUS_INVALID_PARAM;
+ ext_size = 0;
+ }
+
+ if(ext_size == XRAN_STATUS_RESOURCE) {
+ break;
+ }
+
+ totalen += ext_size;
+ }
+
+ return (totalen);