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 *******************************************************************************/
21 #include "xran_lib_wrap.hpp"
22 #include "xran_common.h"
23 #include "xran_fh_o_du.h"
26 #include "xran_transport.h"
27 #include "xran_cp_api.h"
31 #define DELETE_ARRAY(x) { if(x) { delete[] x; x = nullptr; } }
33 const std::string module_name = "C-Plane";
35 const uint8_t m_bitmask[] = { 0x00, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
40 /* wrapper function for performace tests to reset mbuf */
41 int xran_ut_prepare_cp(struct rte_mbuf *mbuf, struct xran_cp_gen_params *params,
42 uint8_t cc_id, uint8_t ant_id, uint8_t seq_id)
44 rte_pktmbuf_reset(mbuf);
45 return(xran_prepare_ctrl_pkt(mbuf, params, cc_id, ant_id, seq_id));
49 void cput_fh_rx_callback(void *pCallbackTag, xran_status_t status)
54 void cput_fh_rx_prach_callback(void *pCallbackTag, xran_status_t status)
63 class C_plane: public KernelTests
66 struct xran_section_gen_info *m_pSectGenInfo = NULL;
67 struct xran_section_gen_info *m_pSectResult = NULL;
79 std::vector<uint8_t> exts;
86 struct xran_sectionext1_info ext1;
87 struct xran_sectionext2_info ext2;
88 struct xran_sectionext3_info ext3;
89 struct xran_sectionext4_info ext4;
90 struct xran_sectionext5_info ext5;
95 int m_maxSections = 8; /* not used */
98 struct rte_mbuf *m_pTestBuffer;
100 struct xran_cp_gen_params m_params;
101 struct xran_recv_packet_info m_pktInfo;
102 struct xran_cp_gen_params m_result;
104 struct xran_sectionext1_info m_temp_ext1[XRAN_MAX_PRBS];
107 std::string m_dirStr;
108 uint8_t m_sectionType;
110 uint8_t m_ccId, m_antId;
112 uint8_t m_frameId, m_subframeId, m_slotId;
115 uint8_t m_iqWidth, m_compMethod;
116 uint8_t m_filterIndex;
117 uint16_t m_timeOffset;
122 struct sectinfo *m_sections;
123 struct extcfginfo *m_extcfgs;
126 uint16_t m_ext1_dst_len = 0;
127 int8_t *m_p_ext1_dst = nullptr;
128 int16_t *m_p_bfw_iq_src = nullptr;
130 struct xran_sectionext1_info m_ext1;
132 int16_t m_bfwIQ[XRAN_MAX_BFW_N*2];
135 void SetUp() override
139 init_test("C_Plane");
141 m_dirStr = get_input_parameter<std::string>("direction");
143 if(!m_dirStr.compare("DL")) m_dir = XRAN_DIR_DL;
144 else if(!m_dirStr.compare("UL")) m_dir = XRAN_DIR_UL;
145 else FAIL() << "Invalid direction!";
147 m_sectionType = get_input_parameter<uint8_t>("section_type");
148 m_ccId = get_input_parameter<uint8_t>("cc_id");
149 m_antId = get_input_parameter<uint8_t>("ant_id");
150 m_seqId = get_input_parameter<uint16_t>("seq_id");
152 m_frameId = get_input_parameter<uint8_t>("frame_id");
153 m_subframeId = get_input_parameter<uint8_t>("subframe_id");
154 m_slotId = get_input_parameter<uint8_t>("slot_id");
155 m_symStart = get_input_parameter<uint8_t>("symbol_start");
156 m_compMethod = get_input_parameter<uint8_t>("comp_method");
157 m_iqWidth = get_input_parameter<uint8_t>("iq_width");
159 switch(m_sectionType) {
160 case XRAN_CP_SECTIONTYPE_1:
161 m_filterIndex = XRAN_FILTERINDEX_STANDARD;
164 case XRAN_CP_SECTIONTYPE_3:
165 m_filterIndex = get_input_parameter<uint8_t>("filter_index");
166 m_timeOffset = get_input_parameter<uint16_t>("time_offset");
167 m_fftSize = get_input_parameter<uint8_t>("fft_size");
168 m_scs = get_input_parameter<uint8_t>("scs");
169 m_cpLength = get_input_parameter<uint16_t>("cp_length");
173 FAIL() << "Invalid Section Type - " << m_sectionType << std::endl;
176 m_numSections = get_input_subsection_size("sections");
177 ASSERT_FALSE(m_numSections == 0);
179 m_sections = new struct sectinfo [m_numSections];
180 for(i=0; i<m_numSections; i++) {
181 m_sections[i].sectionId = get_input_parameter<uint16_t>("sections", i, "sectionId");
182 m_sections[i].rb = get_input_parameter<uint16_t>("sections", i, "rb");
183 m_sections[i].symInc = get_input_parameter<uint16_t>("sections", i, "symInc");
184 m_sections[i].startPrbc = get_input_parameter<uint16_t>("sections", i, "startPrbc");
185 m_sections[i].numPrbc = get_input_parameter<uint16_t>("sections", i, "numPrbc");
186 m_sections[i].reMask = get_input_parameter<uint16_t>("sections", i, "reMask");
187 m_sections[i].numSymbol = get_input_parameter<uint16_t>("sections", i, "numSymbol");
188 m_sections[i].beamId = get_input_parameter<uint16_t>("sections", i, "beamId");
190 switch(m_sectionType) {
191 case XRAN_CP_SECTIONTYPE_3:
192 m_sections[i].freqOffset = get_input_parameter<uint16_t>("sections", i, "freqOffset");
196 m_sections[i].exts = get_input_parameter<std::vector<uint8_t>>("sections", i, "exts");
199 /* reading configurations of section extension */
200 m_nextcfgs = get_input_subsection_size("extensions");
202 m_extcfgs = new struct extcfginfo [m_nextcfgs];
204 for(i=0; i < m_nextcfgs; i++) {
205 std::vector<uint16_t> csf;
206 std::vector<uint16_t> mcScaleReMask;
207 std::vector<uint16_t> mcScaleOffset;
209 m_extcfgs[i].type = get_input_parameter<int>("extensions", i, "type");
210 m_extcfgs[i].name = get_input_parameter<std::string>("extensions", i, "name");
212 switch(m_extcfgs[i].type) {
213 case XRAN_CP_SECTIONEXTCMD_1:
214 /* Skip section extension type 1 since it has separate function */
215 std::cout << "### Skip Extension 1 configuration !!\n" << std::endl;
218 case XRAN_CP_SECTIONEXTCMD_2:
219 m_extcfgs[i].u.ext2.bfAzPtWidth = get_input_parameter<uint8_t>("extensions", i, "bfAzPtWidth") & 0x7;
220 m_extcfgs[i].u.ext2.bfAzPt = get_input_parameter<uint8_t>("extensions", i, "bfAzPt") & 0xf;
221 m_extcfgs[i].u.ext2.bfZePtWidth = get_input_parameter<uint8_t>("extensions", i, "bfZePtWidth") & 0x7;
222 m_extcfgs[i].u.ext2.bfZePt = get_input_parameter<uint8_t>("extensions", i, "bfZePt") & 0xf;
223 m_extcfgs[i].u.ext2.bfAz3ddWidth = get_input_parameter<uint8_t>("extensions", i, "bfAz3ddWidth") & 0x7;
224 m_extcfgs[i].u.ext2.bfAz3dd = get_input_parameter<uint8_t>("extensions", i, "bfAz3dd") & 0xf;
225 m_extcfgs[i].u.ext2.bfZe3ddWidth = get_input_parameter<uint8_t>("extensions", i, "bfZe3ddWidth") & 0x7;
226 m_extcfgs[i].u.ext2.bfZe3dd = get_input_parameter<uint8_t>("extensions", i, "bfZe3dd") & 0xf;
227 m_extcfgs[i].u.ext2.bfAzSI = get_input_parameter<uint8_t>("extensions", i, "bfAzSI") & 0x7;
228 m_extcfgs[i].u.ext2.bfZeSI = get_input_parameter<uint8_t>("extensions", i, "bfZeSI") & 0x7;
231 case XRAN_CP_SECTIONEXTCMD_3:
232 m_extcfgs[i].u.ext3.codebookIdx = get_input_parameter<uint8_t> ("extensions", i, "codebookIdx");
233 m_extcfgs[i].u.ext3.layerId = get_input_parameter<uint8_t> ("extensions", i, "layerId") & 0xf;
234 m_extcfgs[i].u.ext3.numLayers = get_input_parameter<uint8_t> ("extensions", i, "numLayers") & 0xf;
235 m_extcfgs[i].u.ext3.txScheme = get_input_parameter<uint8_t> ("extensions", i, "txScheme") & 0xf;
236 m_extcfgs[i].u.ext3.crsReMask = get_input_parameter<uint16_t>("extensions", i, "crsReMask") & 0xfff;
237 m_extcfgs[i].u.ext3.crsShift = get_input_parameter<uint8_t> ("extensions", i, "crsShift") & 0x1;
238 m_extcfgs[i].u.ext3.crsSymNum = get_input_parameter<uint8_t> ("extensions", i, "crsSymNum") & 0xf;
239 m_extcfgs[i].u.ext3.numAntPort = get_input_parameter<uint16_t>("extensions", i, "numAntPort");
240 m_extcfgs[i].u.ext3.beamIdAP1 = get_input_parameter<uint16_t>("extensions", i, "beamIdAP1");
241 m_extcfgs[i].u.ext3.beamIdAP2 = get_input_parameter<uint16_t>("extensions", i, "beamIdAP2");
242 m_extcfgs[i].u.ext3.beamIdAP3 = get_input_parameter<uint16_t>("extensions", i, "beamIdAP3");
245 case XRAN_CP_SECTIONEXTCMD_4:
246 m_extcfgs[i].u.ext4.csf = get_input_parameter<uint8_t> ("extensions", i, "csf") & 0xf;
247 m_extcfgs[i].u.ext4.modCompScaler= get_input_parameter<uint16_t>("extensions", i, "modCompScaler") & 0x7fff;
250 case XRAN_CP_SECTIONEXTCMD_5:
251 m_extcfgs[i].u.ext5.num_sets = get_input_parameter<uint8_t>("extensions", i, "num_sets");
252 if(m_extcfgs[i].u.ext5.num_sets > XRAN_MAX_MODCOMP_ADDPARMS)
253 FAIL() << "Invalid number of sets in extension 5!";
255 csf = get_input_parameter<std::vector<uint16_t>>("extensions", i, "csf");
256 mcScaleReMask = get_input_parameter<std::vector<uint16_t>>("extensions", i, "mcScaleReMask");
257 mcScaleOffset = get_input_parameter<std::vector<uint16_t>>("extensions", i, "mcScaleOffset");
259 if(csf.size() != m_extcfgs[i].u.ext5.num_sets
260 || mcScaleReMask.size() != m_extcfgs[i].u.ext5.num_sets
261 || mcScaleOffset.size() != m_extcfgs[i].u.ext5.num_sets)
262 FAIL() << "Invalid configuration in extension 5 - different size!";
264 for(int ii=0; ii < m_extcfgs[i].u.ext5.num_sets; ii++) {
265 m_extcfgs[i].u.ext5.mc[ii].csf = csf[ii];
266 m_extcfgs[i].u.ext5.mc[ii].mcScaleReMask = mcScaleReMask[ii];
267 m_extcfgs[i].u.ext5.mc[ii].mcScaleOffset = mcScaleOffset[ii];
272 FAIL() << "Invalid Section Type Extension - " << m_extcfgs[i].type << std::endl;
274 } /* switch(m_extcfgs[i].type) */
275 } /* for(i=0; i < m_nextcfgs; i++) */
281 /* allocate and prepare required data storage */
282 m_pSectGenInfo = new struct xran_section_gen_info [m_numSections];
283 ASSERT_NE(m_pSectGenInfo, nullptr);
284 m_params.sections = m_pSectGenInfo;
286 m_pSectResult = new struct xran_section_gen_info [m_numSections];
287 ASSERT_NE(m_pSectResult, nullptr);
288 m_result.sections = m_pSectResult;
290 m_ext1_dst_len = 9600;
291 m_p_ext1_dst = new int8_t [m_ext1_dst_len];
292 m_p_bfw_iq_src = new int16_t [9600/2];
294 /* allocating an mbuf for packet generatrion */
295 m_pTestBuffer = xran_ethdi_mbuf_alloc();
296 ASSERT_FALSE(m_pTestBuffer == nullptr);
299 void TearDown() override
301 if(m_pTestBuffer != nullptr) {
302 rte_pktmbuf_free(m_pTestBuffer);
303 m_pTestBuffer = nullptr;
306 DELETE_ARRAY(m_extcfgs);
307 DELETE_ARRAY(m_sections);
308 DELETE_ARRAY(m_p_bfw_iq_src);
309 DELETE_ARRAY(m_p_ext1_dst);
310 DELETE_ARRAY(m_pSectGenInfo);
311 DELETE_ARRAY(m_pSectResult);
314 int prepare_sections(void);
315 int prepare_extensions(void);
316 void verify_sections(void);
322 int C_plane::prepare_extensions()
324 int i, numext, sect_num;
327 for(sect_num=0; sect_num < m_numSections; sect_num++) {
330 for(i=0; i < m_sections[sect_num].exts.size(); i++) {
332 ext_id = m_sections[sect_num].exts[i];
333 if(ext_id >= m_nextcfgs) {
334 std::cout << "Invalid section extension configuration index - " << ext_id << " [max " << m_nextcfgs-1 << "]" << std::endl;
338 switch(m_extcfgs[ext_id].type) {
339 case XRAN_CP_SECTIONEXTCMD_1:
340 std::cout << "Skip Extension 1 !!" << std::endl;
342 case XRAN_CP_SECTIONEXTCMD_2:
343 m_params.sections[sect_num].exData[numext].len = sizeof(m_extcfgs[ext_id].u.ext2);
344 m_params.sections[sect_num].exData[numext].data = &m_extcfgs[ext_id].u.ext2;
346 case XRAN_CP_SECTIONEXTCMD_3:
347 m_params.sections[sect_num].exData[numext].len = sizeof(m_extcfgs[ext_id].u.ext3);
348 m_params.sections[sect_num].exData[numext].data = &m_extcfgs[ext_id].u.ext3;
350 case XRAN_CP_SECTIONEXTCMD_4:
351 m_params.sections[sect_num].exData[numext].len = sizeof(m_extcfgs[ext_id].u.ext4);
352 m_params.sections[sect_num].exData[numext].data = &m_extcfgs[ext_id].u.ext4;
354 case XRAN_CP_SECTIONEXTCMD_5:
355 m_params.sections[sect_num].exData[numext].len = sizeof(m_extcfgs[ext_id].u.ext5);
356 m_params.sections[sect_num].exData[numext].data = &m_extcfgs[ext_id].u.ext5;
359 std::cout << "Invalid Section Extension Type - " << (int)m_extcfgs[ext_id].type << std::endl;
361 } /* switch(m_extcfgs[ext_id].type) */
363 m_params.sections[sect_num].exData[numext].type = m_extcfgs[ext_id].type;
365 } /* for(i=0; i < m_sections[sect_num].exts.size(); i++) */
368 m_params.sections[sect_num].exDataSize = numext;
369 m_params.sections[sect_num].info.ef = 1;
372 m_params.sections[sect_num].exDataSize = 0;
373 m_params.sections[sect_num].info.ef = 0;
375 } /* for(sect_num=0; sect_num < m_numSections; sect_num++) */
381 int C_plane::prepare_sections(void)
386 /* Preparing input data for packet generation */
387 m_params.dir = m_dir;
388 m_params.sectionType = m_sectionType;
390 m_params.hdr.filterIdx = m_filterIndex;
391 m_params.hdr.frameId = m_frameId;
392 m_params.hdr.subframeId = m_subframeId;
393 m_params.hdr.slotId = m_slotId;
394 m_params.hdr.startSymId = m_symStart;
395 m_params.hdr.iqWidth = XRAN_CONVERT_IQWIDTH(m_iqWidth);
396 m_params.hdr.compMeth = m_compMethod;
398 switch(m_sectionType) {
399 case XRAN_CP_SECTIONTYPE_1:
402 case XRAN_CP_SECTIONTYPE_3:
403 m_params.hdr.timeOffset = m_timeOffset;
404 m_params.hdr.fftSize = m_fftSize;
405 m_params.hdr.scs = m_scs;
406 m_params.hdr.cpLength = m_cpLength;
413 for(numsec=0; numsec < m_numSections; numsec++) {
414 m_params.sections[numsec].info.type = m_params.sectionType; // for database
415 m_params.sections[numsec].info.startSymId = m_params.hdr.startSymId; // for database
416 m_params.sections[numsec].info.iqWidth = m_params.hdr.iqWidth; // for database
417 m_params.sections[numsec].info.compMeth = m_params.hdr.compMeth; // for database
418 m_params.sections[numsec].info.id = m_sections[numsec].sectionId;
419 m_params.sections[numsec].info.rb = m_sections[numsec].rb;
420 m_params.sections[numsec].info.symInc = m_sections[numsec].symInc;
421 m_params.sections[numsec].info.startPrbc = m_sections[numsec].startPrbc;
422 m_params.sections[numsec].info.numPrbc = m_sections[numsec].numPrbc;
423 m_params.sections[numsec].info.reMask = m_sections[numsec].reMask;
424 m_params.sections[numsec].info.numSymbol = m_sections[numsec].numSymbol;
425 m_params.sections[numsec].info.beamId = m_sections[numsec].beamId;
427 switch(m_sectionType) {
428 case XRAN_CP_SECTIONTYPE_1:
431 case XRAN_CP_SECTIONTYPE_3:
432 m_params.sections[numsec].info.freqOffset = m_sections[numsec].freqOffset;
440 m_params.numSections = numsec;
446 void C_plane::verify_sections(void)
450 /* Verify the result */
451 EXPECT_TRUE(m_result.dir == m_params.dir);
452 EXPECT_TRUE(m_result.sectionType == m_params.sectionType);
454 EXPECT_TRUE(m_result.hdr.filterIdx == m_params.hdr.filterIdx);
455 EXPECT_TRUE(m_result.hdr.frameId == m_params.hdr.frameId);
456 EXPECT_TRUE(m_result.hdr.subframeId == m_params.hdr.subframeId);
457 EXPECT_TRUE(m_result.hdr.slotId == m_params.hdr.slotId);
458 EXPECT_TRUE(m_result.hdr.startSymId == m_params.hdr.startSymId);
459 EXPECT_TRUE(m_result.hdr.iqWidth == m_params.hdr.iqWidth);
460 EXPECT_TRUE(m_result.hdr.compMeth == m_params.hdr.compMeth);
462 switch(m_sectionType) {
463 case XRAN_CP_SECTIONTYPE_1:
466 case XRAN_CP_SECTIONTYPE_3:
467 EXPECT_TRUE(m_result.hdr.fftSize == m_params.hdr.fftSize);
468 EXPECT_TRUE(m_result.hdr.scs == m_params.hdr.scs);
469 EXPECT_TRUE(m_result.hdr.cpLength == m_params.hdr.cpLength);
473 FAIL() << "Invalid Section Type - " << m_sectionType << "\n";
476 ASSERT_TRUE(m_result.numSections == m_params.numSections);
477 for(i=0; i < m_result.numSections; i++) {
478 EXPECT_TRUE(m_result.sections[i].info.id == m_params.sections[i].info.id);
479 EXPECT_TRUE(m_result.sections[i].info.rb == m_params.sections[i].info.rb);
480 EXPECT_TRUE(m_result.sections[i].info.symInc == m_params.sections[i].info.symInc);
481 EXPECT_TRUE(m_result.sections[i].info.startPrbc == m_params.sections[i].info.startPrbc);
482 if(m_params.sections[i].info.numPrbc > 255)
483 EXPECT_TRUE(m_result.sections[i].info.numPrbc == 0);
485 EXPECT_TRUE(m_result.sections[i].info.numPrbc == m_params.sections[i].info.numPrbc);
486 EXPECT_TRUE(m_result.sections[i].info.numSymbol == m_params.sections[i].info.numSymbol);
487 EXPECT_TRUE(m_result.sections[i].info.reMask == m_params.sections[i].info.reMask);
488 EXPECT_TRUE(m_result.sections[i].info.beamId == m_params.sections[i].info.beamId);
489 EXPECT_TRUE(m_result.sections[i].info.ef == m_params.sections[i].info.ef);
491 switch(m_sectionType) {
492 case XRAN_CP_SECTIONTYPE_1:
495 case XRAN_CP_SECTIONTYPE_3:
496 EXPECT_TRUE(m_result.sections[i].info.freqOffset == m_params.sections[i].info.freqOffset);
500 FAIL() << "Invalid Section Type - " << m_sectionType << "\n";
503 if(m_params.sections[i].info.ef) {
504 //printf("[%d] %d == %d\n",i, m_result.sections[i].exDataSize, m_params.sections[i].exDataSize);
505 EXPECT_TRUE(m_result.sections[i].exDataSize == m_params.sections[i].exDataSize);
507 for(j=0; j < m_params.sections[i].exDataSize; j++) {
508 EXPECT_TRUE(m_result.sections[i].exData[j].type == m_params.sections[i].exData[j].type);
510 switch(m_params.sections[i].exData[j].type) {
511 case XRAN_CP_SECTIONEXTCMD_1:
513 struct xran_sectionext1_info *ext1_params, *ext1_result;
514 int iq_size, parm_size, N;
516 ext1_params = (struct xran_sectionext1_info *)m_params.sections[i].exData[j].data;
517 ext1_result = (struct xran_sectionext1_info *)m_result.sections[i].exData[j].data;
519 EXPECT_TRUE(ext1_result->bfwiqWidth == ext1_params->bfwiqWidth);
520 EXPECT_TRUE(ext1_result->bfwCompMeth == ext1_params->bfwCompMeth);
522 N = ext1_params->bfwNumber;
523 switch(ext1_params->bfwCompMeth) {
524 case XRAN_BFWCOMPMETHOD_BLKFLOAT:
525 //printf("[%d, %d] %d == %d\n",i, j, ext1_result->bfwCompParam.exponent, ext1_params->bfwCompParam.exponent);
526 EXPECT_TRUE(ext1_result->bfwCompParam.exponent == ext1_params->bfwCompParam.exponent);
529 case XRAN_BFWCOMPMETHOD_BLKSCALE:
530 EXPECT_TRUE(ext1_result->bfwCompParam.blockScaler == ext1_params->bfwCompParam.blockScaler);
533 case XRAN_BFWCOMPMETHOD_ULAW:
534 EXPECT_TRUE(ext1_result->bfwCompParam.compBitWidthShift == ext1_params->bfwCompParam.compBitWidthShift);
537 case XRAN_BFWCOMPMETHOD_BEAMSPACE:
538 parm_size = N>>3; if(N%8) parm_size++; parm_size *= 8;
539 EXPECT_TRUE(std::memcmp(ext1_result->bfwCompParam.activeBeamspaceCoeffMask, ext1_params->bfwCompParam.activeBeamspaceCoeffMask, parm_size));
543 /* Get the number of BF weights */
544 iq_size = N*ext1_params->bfwiqWidth*2; // total in bits
545 parm_size = iq_size>>3; // total in bytes (/8)
546 if(iq_size%8) parm_size++; // round up
547 EXPECT_FALSE(std::memcmp(ext1_result->p_bfwIQ, ext1_params->p_bfwIQ, parm_size));
551 case XRAN_CP_SECTIONEXTCMD_2:
553 struct xran_sectionext2_info *ext2_params, *ext2_result;
555 ext2_params = (struct xran_sectionext2_info *)m_params.sections[i].exData[j].data;
556 ext2_result = (struct xran_sectionext2_info *)m_result.sections[i].exData[j].data;
558 if(ext2_params->bfAzPtWidth) {
559 EXPECT_TRUE(ext2_result->bfAzPtWidth == ext2_params->bfAzPtWidth);
560 EXPECT_TRUE(ext2_result->bfAzPt == ext2_params->bfAzPt);
563 if(ext2_params->bfZePtWidth) {
564 EXPECT_TRUE(ext2_result->bfZePtWidth == ext2_params->bfZePtWidth);
565 EXPECT_TRUE(ext2_result->bfZePt == ext2_params->bfZePt);
567 if(ext2_params->bfAz3ddWidth) {
568 EXPECT_TRUE(ext2_result->bfAz3ddWidth == ext2_params->bfAz3ddWidth);
569 EXPECT_TRUE(ext2_result->bfAz3dd == ext2_params->bfAz3dd);
571 if(ext2_params->bfZe3ddWidth) {
572 EXPECT_TRUE(ext2_result->bfZe3ddWidth == ext2_params->bfZe3ddWidth);
573 EXPECT_TRUE(ext2_result->bfZe3dd == ext2_params->bfZe3dd);
576 EXPECT_TRUE(ext2_result->bfAzSI == ext2_params->bfAzSI);
577 EXPECT_TRUE(ext2_result->bfZeSI == ext2_params->bfZeSI);
581 case XRAN_CP_SECTIONEXTCMD_3:
583 struct xran_sectionext3_info *ext3_params, *ext3_result;
585 ext3_params = (struct xran_sectionext3_info *)m_params.sections[i].exData[j].data;
586 ext3_result = (struct xran_sectionext3_info *)m_result.sections[i].exData[j].data;
588 EXPECT_TRUE(ext3_result->layerId == ext3_params->layerId);
589 EXPECT_TRUE(ext3_result->codebookIdx== ext3_params->codebookIdx);
590 EXPECT_TRUE(ext3_result->numLayers == ext3_params->numLayers);
592 if(ext3_params->layerId == XRAN_LAYERID_0
593 || ext3_params->layerId == XRAN_LAYERID_TXD) { /* first data layer */
594 EXPECT_TRUE(ext3_result->txScheme == ext3_params->txScheme);
595 EXPECT_TRUE(ext3_result->crsReMask == ext3_params->crsReMask);
596 EXPECT_TRUE(ext3_result->crsShift == ext3_params->crsShift);
597 EXPECT_TRUE(ext3_result->crsSymNum == ext3_params->crsSymNum);
599 EXPECT_TRUE(ext3_result->numAntPort == ext3_params->numAntPort);
601 EXPECT_TRUE(ext3_result->beamIdAP1 == ext3_params->beamIdAP1);
603 if(ext3_params->numAntPort == 4) {
604 EXPECT_TRUE(ext3_result->beamIdAP2 == ext3_params->beamIdAP2);
605 EXPECT_TRUE(ext3_result->beamIdAP3 == ext3_params->beamIdAP3);
611 case XRAN_CP_SECTIONEXTCMD_4:
613 struct xran_sectionext4_info *ext4_params, *ext4_result;
615 ext4_params = (struct xran_sectionext4_info *)m_params.sections[i].exData[j].data;
616 ext4_result = (struct xran_sectionext4_info *)m_result.sections[i].exData[j].data;
618 EXPECT_TRUE(ext4_result->csf == ext4_params->csf);
619 EXPECT_TRUE(ext4_result->modCompScaler == ext4_params->modCompScaler);
623 case XRAN_CP_SECTIONEXTCMD_5:
625 struct xran_sectionext5_info *ext5_params, *ext5_result;
628 ext5_params = (struct xran_sectionext5_info *)m_params.sections[i].exData[j].data;
629 ext5_result = (struct xran_sectionext5_info *)m_result.sections[i].exData[j].data;
631 EXPECT_TRUE(ext5_result->num_sets == ext5_params->num_sets);
632 for(idx=0; idx < ext5_params->num_sets; idx++) {
633 EXPECT_TRUE(ext5_result->mc[idx].csf == ext5_params->mc[idx].csf);
634 EXPECT_TRUE(ext5_result->mc[idx].mcScaleReMask == ext5_params->mc[idx].mcScaleReMask);
635 EXPECT_TRUE(ext5_result->mc[idx].mcScaleOffset == ext5_params->mc[idx].mcScaleOffset);
648 /***************************************************************************
649 * Functional Test cases
650 ***************************************************************************/
652 TEST_P(C_plane, Section_Ext1)
657 int32_t nAntElm = 64;
659 int8_t compMethod = XRAN_COMPMETHOD_NONE;
660 int8_t *p_ext1_dst = NULL;
661 int8_t *bfw_payload = NULL;
662 int32_t expected_len = (3+1)*nRbs + nAntElm*nRbs*4;
664 int16_t ext_len = 9600;
665 int16_t ext_sec_total = 0;
666 int8_t * ext_buf = nullptr;
667 int8_t * ext_buf_init = nullptr;
669 struct xran_section_gen_info* loc_pSectGenInfo = m_params.sections;
670 struct xran_sectionext1_info m_prep_ext1;
671 struct xran_cp_radioapp_section_ext1 *p_ext1;
672 struct rte_mbuf_ext_shared_info share_data;
673 struct rte_mbuf *mbuf = NULL;
675 /* Configure section information */
676 if(prepare_sections() < 0) {
677 FAIL() << "Invalid Section configuration\n";
680 if(prepare_extensions() < 0) {
681 FAIL() << "Invalid Section extension configuration\n";
684 if(loc_pSectGenInfo->info.type == XRAN_CP_SECTIONTYPE_1) {
685 /* extType 1 only with Section 1 for now */
687 ext_buf = ext_buf_init = (int8_t*) xran_malloc(ext_len);
689 ptr = m_p_bfw_iq_src;
691 for (idRb =0; idRb < nRbs*nAntElm*2; idRb++){
696 ext_buf += (RTE_PKTMBUF_HEADROOM +
697 sizeof (struct xran_ecpri_hdr) +
698 sizeof(struct xran_cp_radioapp_common_header) +
699 sizeof(struct xran_cp_radioapp_section1));
701 ext_len -= (RTE_PKTMBUF_HEADROOM +
702 sizeof(struct xran_ecpri_hdr) +
703 sizeof(struct xran_cp_radioapp_common_header) +
704 sizeof(struct xran_cp_radioapp_section1));
706 ext_sec_total = xran_cp_populate_section_ext_1((int8_t *)ext_buf,
714 ASSERT_TRUE(ext_sec_total == expected_len);
715 p_ext1_dst = ext_buf;
717 memset(&m_temp_ext1[0], 0, sizeof (struct xran_sectionext1_info)*XRAN_MAX_PRBS);
721 p_ext1 = (struct xran_cp_radioapp_section_ext1 *)p_ext1_dst;
722 bfw_payload = (int8_t*)(p_ext1+1);
723 p_ext1_dst += p_ext1->extLen*XRAN_SECTIONEXT_ALIGN;
725 m_temp_ext1[idRb].bfwNumber = nAntElm;
726 m_temp_ext1[idRb].bfwiqWidth = iqWidth;
727 m_temp_ext1[idRb].bfwCompMeth = compMethod;
728 m_temp_ext1[idRb].p_bfwIQ = (int16_t*)bfw_payload;
729 m_temp_ext1[idRb].bfwIQ_sz = p_ext1->extLen*XRAN_SECTIONEXT_ALIGN;
731 loc_pSectGenInfo->exData[idRb].type = XRAN_CP_SECTIONEXTCMD_1;
732 loc_pSectGenInfo->exData[idRb].len = sizeof(m_temp_ext1[idRb]);
733 loc_pSectGenInfo->exData[idRb].data = &m_temp_ext1[idRb];
736 }while(p_ext1->ef != XRAN_EF_F_LAST);
737 ASSERT_TRUE(idRb == nRbs);
739 mbuf = xran_attach_cp_ext_buf(ext_buf_init, ext_buf, ext_sec_total, &share_data);
741 /* Update section information */
742 memset(&m_prep_ext1, 0, sizeof (struct xran_sectionext1_info));
743 m_prep_ext1.bfwNumber = nAntElm;
744 m_prep_ext1.bfwiqWidth = iqWidth;
745 m_prep_ext1.bfwCompMeth = compMethod;
746 m_prep_ext1.p_bfwIQ = (int16_t*)ext_buf;
747 m_prep_ext1.bfwIQ_sz = ext_sec_total;
750 loc_pSectGenInfo->exData[0].type = XRAN_CP_SECTIONEXTCMD_1;
751 loc_pSectGenInfo->exData[0].len = sizeof(m_prep_ext1);
752 loc_pSectGenInfo->exData[0].data = &m_prep_ext1;
754 loc_pSectGenInfo->info.ef = 1;
755 loc_pSectGenInfo->exDataSize = 1; /* append all extType1 as one shot
756 (as generated via xran_cp_populate_section_ext_1)*/
758 m_params.numSections = 1;
760 /* Generating C-Plane packet */
761 ASSERT_TRUE(xran_prepare_ctrl_pkt(/*m_pTestBuffer*/mbuf, &m_params, m_ccId, m_antId, m_seqId) == XRAN_STATUS_SUCCESS);
763 /** to match O-RU parsing */
764 loc_pSectGenInfo->exDataSize = nRbs;
765 loc_pSectGenInfo->exData[0].len = sizeof(m_temp_ext1[0]);
766 loc_pSectGenInfo->exData[0].data = &m_temp_ext1[0];
768 /* Parsing generated packet */
769 EXPECT_TRUE(xran_parse_cp_pkt(/*m_pTestBuffer*/mbuf, &m_result, &m_pktInfo) == XRAN_STATUS_SUCCESS);
771 FAIL() << "xran_malloc failed\n";
774 /* Verify the result */
778 xran_free(ext_buf_init);
782 TEST_P(C_plane, Section_Ext1_9bit)
787 int32_t nAntElm = 64;
789 int8_t compMethod = XRAN_COMPMETHOD_BLKFLOAT;
790 int8_t *p_ext1_dst = NULL;
791 int8_t *bfw_payload = NULL;
792 int32_t expected_len = ((nAntElm/16*4*iqWidth)+1)*nRbs + /* bfwCompParam + IQ = */
793 sizeof(struct xran_cp_radioapp_section_ext1)*nRbs; /* ext1 Headers */
795 int16_t ext_len = 9600;
796 int16_t ext_sec_total = 0;
797 int8_t * ext_buf = nullptr;
798 int8_t * ext_buf_init = nullptr;
800 struct xran_section_gen_info* loc_pSectGenInfo = m_params.sections;
801 struct xran_sectionext1_info m_prep_ext1;
802 struct xran_cp_radioapp_section_ext1 *p_ext1;
803 struct rte_mbuf_ext_shared_info share_data;
804 struct rte_mbuf *mbuf = NULL;
806 /* Configure section information */
807 if(prepare_sections() < 0) {
808 FAIL() << "Invalid Section configuration\n";
811 if(prepare_extensions() < 0) {
812 FAIL() << "Invalid Section extension configuration\n";
815 if(loc_pSectGenInfo->info.type == XRAN_CP_SECTIONTYPE_1) {
816 /* extType 1 only with Section 1 for now */
818 ext_buf = ext_buf_init = (int8_t*) xran_malloc(ext_len);
820 ptr = m_p_bfw_iq_src;
822 for (idRb =0; idRb < nRbs*nAntElm*2; idRb++){
827 ext_buf += (RTE_PKTMBUF_HEADROOM +
828 sizeof (struct xran_ecpri_hdr) +
829 sizeof(struct xran_cp_radioapp_common_header) +
830 sizeof(struct xran_cp_radioapp_section1));
832 ext_len -= (RTE_PKTMBUF_HEADROOM +
833 sizeof(struct xran_ecpri_hdr) +
834 sizeof(struct xran_cp_radioapp_common_header) +
835 sizeof(struct xran_cp_radioapp_section1));
837 ext_sec_total = xran_cp_populate_section_ext_1((int8_t *)ext_buf,
845 ASSERT_TRUE(ext_sec_total == expected_len);
846 p_ext1_dst = ext_buf;
848 memset(&m_temp_ext1[0], 0, sizeof (struct xran_sectionext1_info)*XRAN_MAX_PRBS);
852 p_ext1 = (struct xran_cp_radioapp_section_ext1 *)p_ext1_dst;
853 bfw_payload = (int8_t*)(p_ext1+1);
854 p_ext1_dst += p_ext1->extLen*XRAN_SECTIONEXT_ALIGN;
856 m_temp_ext1[idRb].bfwNumber = nAntElm;
857 m_temp_ext1[idRb].bfwiqWidth = iqWidth;
858 m_temp_ext1[idRb].bfwCompMeth = compMethod;
860 m_temp_ext1[idRb].bfwCompParam.exponent = *bfw_payload++ & 0xF;
862 m_temp_ext1[idRb].p_bfwIQ = (int16_t*)bfw_payload;
863 m_temp_ext1[idRb].bfwIQ_sz = p_ext1->extLen*XRAN_SECTIONEXT_ALIGN;
865 loc_pSectGenInfo->exData[idRb].type = XRAN_CP_SECTIONEXTCMD_1;
866 loc_pSectGenInfo->exData[idRb].len = sizeof(m_temp_ext1[idRb]);
867 loc_pSectGenInfo->exData[idRb].data = &m_temp_ext1[idRb];
870 }while(p_ext1->ef != XRAN_EF_F_LAST);
871 ASSERT_TRUE(idRb == nRbs);
873 mbuf = xran_attach_cp_ext_buf(ext_buf_init, ext_buf, ext_sec_total, &share_data);
875 /* Update section information */
876 memset(&m_prep_ext1, 0, sizeof (struct xran_sectionext1_info));
877 m_prep_ext1.bfwNumber = nAntElm;
878 m_prep_ext1.bfwiqWidth = iqWidth;
879 m_prep_ext1.bfwCompMeth = compMethod;
880 m_prep_ext1.p_bfwIQ = (int16_t*)ext_buf;
881 m_prep_ext1.bfwIQ_sz = ext_sec_total;
884 loc_pSectGenInfo->exData[0].type = XRAN_CP_SECTIONEXTCMD_1;
885 loc_pSectGenInfo->exData[0].len = sizeof(m_prep_ext1);
886 loc_pSectGenInfo->exData[0].data = &m_prep_ext1;
888 loc_pSectGenInfo->info.ef = 1;
889 loc_pSectGenInfo->exDataSize = 1; /* append all extType1 as one shot
890 (as generated via xran_cp_populate_section_ext_1)*/
892 m_params.numSections = 1;
894 /* Generating C-Plane packet */
895 ASSERT_TRUE(xran_prepare_ctrl_pkt(/*m_pTestBuffer*/mbuf, &m_params, m_ccId, m_antId, m_seqId) == XRAN_STATUS_SUCCESS);
897 /** to match O-RU parsing */
898 loc_pSectGenInfo->exDataSize = nRbs;
899 loc_pSectGenInfo->exData[0].len = sizeof(m_temp_ext1[0]);
900 loc_pSectGenInfo->exData[0].data = &m_temp_ext1[0];
902 /* Parsing generated packet */
903 EXPECT_TRUE(xran_parse_cp_pkt(/*m_pTestBuffer*/mbuf, &m_result, &m_pktInfo) == XRAN_STATUS_SUCCESS);
905 FAIL() << "xran_malloc failed\n";
908 /* Verify the result */
912 xran_free(ext_buf_init);
917 TEST_P(C_plane, PacketGen)
919 /* Configure section information */
920 if(prepare_sections() < 0) {
921 FAIL() << "Invalid Section configuration\n";
923 if(prepare_extensions() < 0) {
924 FAIL() << "Invalid Section extension configuration\n";
927 /* Generating C-Plane packet */
928 ASSERT_TRUE(xran_prepare_ctrl_pkt(m_pTestBuffer, &m_params, m_ccId, m_antId, m_seqId) == XRAN_STATUS_SUCCESS);
930 /* Parsing generated packet */
931 EXPECT_TRUE(xran_parse_cp_pkt(m_pTestBuffer, &m_result, &m_pktInfo) == XRAN_STATUS_SUCCESS);
933 /* Verify the result */
938 TEST_P(C_plane, PacketGen_Ext)
940 /* Configure section information */
941 if(prepare_sections() < 0) {
942 FAIL() << "Invalid Section configuration\n";
945 /* Generating C-Plane packet */
946 ASSERT_TRUE(xran_prepare_ctrl_pkt(m_pTestBuffer, &m_params, m_ccId, m_antId, m_seqId) == XRAN_STATUS_SUCCESS);
948 /* Parsing generated packet */
949 EXPECT_TRUE(xran_parse_cp_pkt(m_pTestBuffer, &m_result, &m_pktInfo) == XRAN_STATUS_SUCCESS);
951 /* Verify the result */
956 /***************************************************************************
957 * Performance Test cases
958 ***************************************************************************/
960 TEST_P(C_plane, Perf)
962 /* Configure section information */
963 if(prepare_sections() < 0) {
964 FAIL() << "Invalid Section configuration\n";
966 if(prepare_extensions() < 0) {
967 FAIL() << "Invalid Section extension configuration\n";
970 /* using wrapper function to reset mbuf */
971 performance("C", module_name,
972 &xran_ut_prepare_cp, m_pTestBuffer, &m_params, m_ccId, m_antId, m_seqId);
976 TEST_P(C_plane, Perf_Ext)
978 /* Configure section information */
979 if(prepare_sections() < 0) {
980 FAIL() << "Invalid Section configuration\n";
983 /* using wrapper function to reset mbuf */
984 performance("C", module_name,
985 &xran_ut_prepare_cp, m_pTestBuffer, &m_params, m_ccId, m_antId, m_seqId);
988 INSTANTIATE_TEST_CASE_P(UnitTest, C_plane,
989 testing::ValuesIn(get_sequence(C_plane::get_number_of_cases("C_Plane"))));