+ p_bfw_content = (uint8_t *)(p_bfw_content + parm_size);
+
+ cur_ext_len += parm_size;
+ parm_size = cur_ext_len % XRAN_SECTIONEXT_ALIGN;
+ if(parm_size) {
+ parm_size = XRAN_SECTIONEXT_ALIGN - parm_size;
+ p_bfw_content = (uint8_t *)(p_bfw_content + parm_size);
+ memcpy(p_bfw_content, zeropad, RTE_MIN(parm_size, sizeof(zeropad)));
+ cur_ext_len += parm_size;
+ print_dbg("zeropad %d cur_ext_len %d\n", parm_size, cur_ext_len);
+ }
+
+ if(cur_ext_len % XRAN_SECTIONEXT_ALIGN)
+ rte_panic("ext1 should be aligned on 4-bytes boundary");
+
+ p_ext1->extLen = cur_ext_len / XRAN_SECTIONEXT_ALIGN;
+ print_dbg("[%d] %p iq %p p_ext1->extLen %d\n",idxRb, p_ext1, p_ext1+1, p_ext1->extLen);
+
+ /* update for next RB */
+ p_ext1_dst_cur += cur_ext_len;
+ p_bfw_iq_src = p_bfw_iq_src + bfwNumPerRb*2;
+
+ total_len += cur_ext_len;
+ }
+
+ print_dbg("total_len %d\n", total_len);
+ return (total_len);
+}
+
+// TODO: Need to decide to add calculation or not
+// Frequency offset 5.4.5.11
+// frequency_offset = freqOffset * SCS * 0.5
+// i.e freqOffset = (frequency_offset *2 )/ SCS ?
+inline int32_t
+xran_get_freqoffset(int32_t freqOffset, int32_t scs)
+{
+ return (freqOffset);
+}
+
+static int32_t
+xran_append_sectionext_1(struct rte_mbuf *mbuf, struct xran_sectionext1_info *params, int32_t last_flag)
+{
+ int32_t total_len = 0;
+
+ if(params->bfwIQ_sz) {
+ int8_t *p_dst = (int8_t *)rte_pktmbuf_append(mbuf, params->bfwIQ_sz);
+
+ if(p_dst == NULL) {
+ print_err("Fail to allocate the space for section extension 1 [%d]", params->bfwIQ_sz);
+ return (XRAN_STATUS_RESOURCE);
+ }
+
+ /* extType1 with all the headers created by xran_cp_populate_section_ext_1() earlier */
+ total_len = params->bfwIQ_sz;
+ }
+
+ return (total_len);
+}
+
+static int32_t
+xran_prepare_sectionext_2(struct rte_mbuf *mbuf, struct xran_sectionext2_info *params, int32_t last_flag)
+{
+ struct xran_cp_radioapp_section_ext2 *ext2;
+ uint8_t *data;
+ int32_t total_len;
+ int32_t parm_size;
+ uint32_t val, shift_val;
+ int32_t val_size, pad_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 & bitmask[params->bfAzPtWidth];
+ shift_val += 8 - (params->bfAzPtWidth+1);
+ } else
+ shift_val += 8;
+
+ if(params->bfZePtWidth) {
+ val = val << (params->bfZePtWidth+1);
+ val += params->bfZePt & bitmask[params->bfZePtWidth];
+ shift_val += 8 - (params->bfZePtWidth+1);
+ } else
+ shift_val += 8;
+
+ if(params->bfAz3ddWidth) {
+ val = val << (params->bfAz3ddWidth+1);
+ val += params->bfAz3dd & bitmask[params->bfAz3ddWidth];
+ shift_val += 8 - (params->bfAz3ddWidth+1);
+ } else
+ shift_val += 8;
+
+ if(params->bfZe3ddWidth) {
+ val = val << (params->bfZe3ddWidth+1);
+ val += params->bfZe3dd & bitmask[params->bfZe3ddWidth];
+ 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 */
+
+ // alignment
+ total_len += parm_size;
+ pad_size = total_len % XRAN_SECTIONEXT_ALIGN;
+ if(pad_size) {
+ pad_size = XRAN_SECTIONEXT_ALIGN - pad_size;
+ parm_size += pad_size;
+ total_len += pad_size;
+ }
+
+ 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);
+ }
+
+ memcpy(data, &val, val_size);
+ data += val_size;
+ *data = ((params->bfAzSI) << 3) + (params->bfZeSI);
+ data++;
+ memcpy(data, zeropad, pad_size);
+
+ ext2->extLen = total_len / XRAN_SECTIONEXT_ALIGN;
+ *(uint32_t *)ext2 = rte_cpu_to_be_32(*(uint32_t *)ext2);
+
+ return (total_len);
+}
+
+static int32_t
+xran_prepare_sectionext_3(struct rte_mbuf *mbuf, struct xran_sectionext3_info *params, int32_t last_flag)
+{
+ int32_t total_len;
+ int32_t adj;
+ int32_t data_first_byte, data_second_byte;
+ int32_t data_third_byte, data_fourth_byte;
+ int32_t extLen;
+
+ if(params->layerId == XRAN_LAYERID_0
+ || params->layerId == XRAN_LAYERID_TXD) { /* first data layer */
+
+ union xran_cp_radioapp_section_ext3_first *ext3_f;
+ uint64_t *tmp;
+
+ total_len = sizeof(union xran_cp_radioapp_section_ext3_first);
+ ext3_f = (union xran_cp_radioapp_section_ext3_first *)rte_pktmbuf_append(mbuf, total_len);
+ if(ext3_f == NULL) {
+ print_err("Fail to allocate the space for section extension 3");
+ return (XRAN_STATUS_RESOURCE);
+ }
+
+ /*ext3_f->data_field.data_field1 = _mm_setzero_si128();
+
+ ext3_f->all_bits.layerId = params->layerId;
+ ext3_f->all_bits.ef = last_flag;
+ ext3_f->all_bits.extType = XRAN_CP_SECTIONEXTCMD_3;
+ ext3_f->all_bits.crsSymNum = params->crsSymNum;
+ ext3_f->all_bits.crsShift = params->crsShift;
+ ext3_f->all_bits.crsReMask = params->crsReMask;
+ ext3_f->all_bits.txScheme = params->txScheme;
+ ext3_f->all_bits.numLayers = params->numLayers;
+ ext3_f->all_bits.codebookIndex = params->codebookIdx;
+
+ if(params->numAntPort == 2) {
+ ext3_f->all_bits.beamIdAP3 = params->beamIdAP1;
+ ext3_f->all_bits.extLen = 3;
+ adj = 4;
+ total_len -= adj;
+ }
+ else {
+ ext3_f->all_bits.beamIdAP3 = params->beamIdAP1;
+ ext3_f->all_bits.beamIdAP2 = params->beamIdAP2;
+ ext3_f->all_bits.beamIdAP1 = params->beamIdAP3;
+ ext3_f->all_bits.extLen = 4;
+ adj = 0;
+ }*/
+
+ if(params->numAntPort == 2) {
+ data_third_byte = 0;
+ extLen = 3;
+ adj = 4;
+ total_len -= adj;
+ }else
+ {
+ data_third_byte = (params->beamIdAP2 << 16) | params->beamIdAP3;
+ extLen = 4;
+ adj = 0;
+ }
+
+ data_first_byte = (params->txScheme << xran_cp_radioapp_sec_ext3_TxScheme)
+ | (params->crsReMask << xran_cp_radioapp_sec_ext3_CrcReMask)
+ | (params->crsShift << xran_cp_radioapp_sec_ext3_CrcShift)
+ | (params->crsSymNum << xran_cp_radioapp_sec_ext3_CrcSymNum);
+ data_second_byte = (last_flag << xran_cp_radioapp_sec_ext3_EF)
+ | (XRAN_CP_SECTIONEXTCMD_3 << xran_cp_radioapp_sec_ext3_ExtType)
+ | (extLen << xran_cp_radioapp_sec_ext3_ExtLen)
+ | (params->codebookIdx << xran_cp_radioapp_sec_ext3_CodebookIdx)
+ | (params->layerId << xran_cp_radioapp_sec_ext3_LayerId)
+ | (params->numLayers << xran_cp_radioapp_sec_ext3_NumLayers);
+ data_fourth_byte = params->beamIdAP1;
+ ext3_f->data_field.data_field1 = _mm_set_epi32(data_fourth_byte, data_third_byte, data_second_byte, data_first_byte);
+
+ /* convert byte order */
+ tmp = (uint64_t *)ext3_f;
+ *tmp = rte_cpu_to_be_64(*tmp); tmp++;
+ *tmp = rte_cpu_to_be_64(*tmp);
+
+ if(adj)
+ rte_pktmbuf_trim(mbuf, adj);
+ }
+ else { /* non-first data layer */
+ union xran_cp_radioapp_section_ext3_non_first *ext3_nf;
+
+ total_len = sizeof(union xran_cp_radioapp_section_ext3_non_first);
+ ext3_nf = (union xran_cp_radioapp_section_ext3_non_first *)rte_pktmbuf_append(mbuf, total_len);
+ if(ext3_nf == NULL) {
+ print_err("Fail to allocate the space for section extension 3");
+ return (XRAN_STATUS_RESOURCE);
+ }
+
+ /*ext3_nf->all_bits.layerId = params->layerId;
+ ext3_nf->all_bits.ef = last_flag;
+ ext3_nf->all_bits.extType = XRAN_CP_SECTIONEXTCMD_3;
+ ext3_nf->all_bits.numLayers = params->numLayers;
+ ext3_nf->all_bits.codebookIndex = params->codebookIdx;
+
+ ext3_nf->all_bits.extLen = sizeof(union xran_cp_radioapp_section_ext3_non_first)/XRAN_SECTIONEXT_ALIGN;*/
+
+ ext3_nf->data_field = (last_flag << xran_cp_radioapp_sec_ext3_EF)
+ | (XRAN_CP_SECTIONEXTCMD_3 << xran_cp_radioapp_sec_ext3_ExtType)
+ | ((sizeof(union xran_cp_radioapp_section_ext3_non_first)/XRAN_SECTIONEXT_ALIGN) << xran_cp_radioapp_sec_ext3_ExtLen)
+ | (params->codebookIdx << xran_cp_radioapp_sec_ext3_CodebookIdx)
+ | (params->layerId << xran_cp_radioapp_sec_ext3_LayerId)
+ | (params->numLayers << xran_cp_radioapp_sec_ext3_NumLayers);
+
+ *(uint32_t *)ext3_nf = rte_cpu_to_be_32(*(uint32_t *)ext3_nf);
+ }
+
+ return (total_len);
+}
+
+static int32_t
+xran_prepare_sectionext_4(struct rte_mbuf *mbuf, struct xran_sectionext4_info *params, int32_t last_flag)
+{
+ struct xran_cp_radioapp_section_ext4 *ext4;
+ int32_t parm_size;
+
+ 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);
+ }
+
+ ext4->extType = XRAN_CP_SECTIONEXTCMD_4;
+ ext4->ef = last_flag;
+ ext4->modCompScaler = params->modCompScaler;
+ ext4->csf = params->csf?1:0;
+ ext4->extLen = parm_size / XRAN_SECTIONEXT_ALIGN;
+
+ *(uint32_t *)ext4 = rte_cpu_to_be_32(*(uint32_t*)ext4);
+
+ return (parm_size);
+}
+
+static int32_t
+xran_prepare_sectionext_5(struct rte_mbuf *mbuf, struct xran_sectionext5_info *params, int32_t last_flag)
+{
+ struct xran_cp_radioapp_section_ext_hdr *ext_hdr;
+ struct xran_cp_radioapp_section_ext5 ext5;
+ int32_t padding;
+ int32_t total_len;
+ uint8_t *data;
+ int32_t i;
+
+ if(params->num_sets > XRAN_MAX_MODCOMP_ADDPARMS) {
+ print_err("Exceeds maximum number of parameters(%d). Skipping.", params->num_sets);
+ return (0);
+ }
+
+ total_len = sizeof(struct xran_cp_radioapp_section_ext_hdr)
+ + (sizeof(struct xran_cp_radioapp_section_ext5)*params->num_sets)/2
+ - (params->num_sets>>1); // 8bits are added by every two sets, so needs to adjust
+
+ /* for alignment */
+ padding = total_len % XRAN_SECTIONEXT_ALIGN;
+ if(padding) {
+ padding = XRAN_SECTIONEXT_ALIGN - padding;
+ total_len += padding;
+ }
+
+ ext_hdr = (struct xran_cp_radioapp_section_ext_hdr *)rte_pktmbuf_append(mbuf, total_len);
+ if(ext_hdr == NULL) {
+ print_err("Fail to allocate the space for section extension 5");
+ return (XRAN_STATUS_RESOURCE);
+ }
+
+ ext_hdr->extType = XRAN_CP_SECTIONEXTCMD_5;
+ ext_hdr->ef = last_flag;
+ ext_hdr->extLen = total_len / XRAN_SECTIONEXT_ALIGN;
+
+ *(uint16_t *)ext_hdr = rte_cpu_to_be_16(*((uint16_t *)ext_hdr));
+
+ data = (uint8_t *)(ext_hdr + 1);
+ i = 0;
+ while(i < params->num_sets) {
+ if(i%2) { // odd index
+ ext5.mcScaleOffset2 = params->mc[i].mcScaleOffset;
+ ext5.csf2 = params->mc[i].csf;
+ ext5.mcScaleReMask2 = params->mc[i].mcScaleReMask;
+ ext5.reserved0 = 0;
+ i++;
+
+ // adding two sets at once (due to the definition of structure)
+ *((uint64_t *)&ext5) = rte_cpu_to_be_64(*((uint64_t *)&ext5));
+ memcpy(data, &ext5, sizeof(struct xran_cp_radioapp_section_ext5));
+ data += sizeof(struct xran_cp_radioapp_section_ext5);
+ }
+ else { // even index
+ ext5.mcScaleOffset1 = params->mc[i].mcScaleOffset;
+ ext5.csf1 = params->mc[i].csf;
+ ext5.mcScaleReMask1 = params->mc[i].mcScaleReMask;
+ ext5.mcScaleReMask2 = 0;
+ i++;
+
+ if(i == params->num_sets) { // adding last even index
+ *((uint64_t *)&ext5) = rte_cpu_to_be_64(*((uint64_t *)&ext5));
+ memcpy(data, &ext5, sizeof(struct xran_cp_radioapp_section_ext5)/2);
+ data += sizeof(struct xran_cp_radioapp_section_ext5)/2;
+ break;
+ }
+ }
+ }
+
+ /* zero padding */
+ if(padding)
+ memcpy(data, zeropad, padding);
+
+ return (total_len);
+}
+
+static int32_t
+xran_prepare_sectionext_6(struct rte_mbuf *mbuf,
+ struct xran_sectionext6_info *params, int32_t last_flag)
+{
+ union xran_cp_radioapp_section_ext6 *ext6;
+ int32_t parm_size;
+
+ parm_size = sizeof(union xran_cp_radioapp_section_ext6);
+ ext6 = (union xran_cp_radioapp_section_ext6 *)rte_pktmbuf_append(mbuf, parm_size);
+ if(ext6 == NULL) {
+ print_err("Fail to allocate the space for section extension 6");
+ return(XRAN_STATUS_RESOURCE);
+ }
+
+ ext6->data_field.data_field1 = 0x0LL;
+ ext6->all_bits.extType = XRAN_CP_SECTIONEXTCMD_6;
+ ext6->all_bits.ef = last_flag;
+ ext6->all_bits.rbgSize = params->rbgSize;
+ ext6->all_bits.rbgMask = params->rbgMask;
+ ext6->all_bits.symbolMask = params->symbolMask;
+ ext6->all_bits.extLen = parm_size / XRAN_SECTIONEXT_ALIGN;
+ //ext6->reserved0 = 0;
+ //ext6->reserved1 = 0;
+
+ *(uint64_t *)ext6 = rte_cpu_to_be_64(*(uint64_t*)ext6);
+
+ return (parm_size);
+}
+
+static int32_t
+xran_prepare_sectionext_10(struct rte_mbuf *mbuf,
+ struct xran_sectionext10_info *params, int32_t last_flag)
+{
+ union xran_cp_radioapp_section_ext10 *ext10;
+ int32_t parm_size;
+ int32_t total_len;
+ int32_t padding;
+ int32_t i;
+ uint16_t *id_ptr;
+
+
+#if (XRAN_STRICT_PARM_CHECK)
+ if(params->beamGrpType != XRAN_BEAMGT_COMMON
+ && params->beamGrpType != XRAN_BEAMGT_MATRIXIND
+ && params->beamGrpType != XRAN_BEAMGT_VECTORLIST) {
+ print_err("Invalid beam group Type - %d\n", params->beamGrpType);
+ return (XRAN_STATUS_INVALID_PARAM);
+ }