1 /******************************************************************************
3 * Copyright (c) 2020 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 #define XRAN_MAX_BUFLEN_EXT11 (MAX_RX_LEN - \
34 (RTE_PKTMBUF_HEADROOM \
35 + sizeof(struct xran_ecpri_hdr) \
36 + sizeof(struct xran_cp_radioapp_common_header) \
37 + sizeof(struct xran_cp_radioapp_section1) \
38 + sizeof(union xran_cp_radioapp_section_ext6) \
39 + sizeof(union xran_cp_radioapp_section_ext10) \
42 const std::string module_name = "C-Plane";
44 const uint8_t m_bitmask[] = { 0x00, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
49 /* wrapper function for performace tests to reset mbuf */
50 int xran_ut_prepare_cp(struct xran_cp_gen_params *params,
51 uint8_t cc_id, uint8_t ant_id, uint8_t seq_id)
54 register struct rte_mbuf *mbuf;
56 mbuf = xran_ethdi_mbuf_alloc();
58 printf("Failed to allocate buffer!\n");
62 ret = xran_prepare_ctrl_pkt(mbuf, params, cc_id, ant_id, seq_id);
63 rte_pktmbuf_free(mbuf);
68 void cput_fh_rx_callback(void *pCallbackTag, xran_status_t status)
73 void cput_fh_rx_prach_callback(void *pCallbackTag, xran_status_t status)
82 class C_plane: public KernelTests
85 struct xran_section_gen_info *m_pSectGenInfo = NULL;
86 struct xran_section_recv_info *m_pSectResult = NULL;
98 std::vector<uint8_t> exts;
105 struct xran_sectionext1_info ext1;
106 struct xran_sectionext2_info ext2;
107 struct xran_sectionext3_info ext3;
108 struct xran_sectionext4_info ext4;
109 struct xran_sectionext5_info ext5;
110 struct xran_sectionext6_info ext6;
111 struct xran_sectionext7_info ext7;
112 struct xran_sectionext8_info ext8;
113 struct xran_sectionext9_info ext9;
114 struct xran_sectionext10_info ext10;
115 struct xran_sectionext11_info ext11;
120 int m_maxSections = 8; /* not used */
123 struct rte_mbuf *m_pTestBuffer = nullptr;
125 struct xran_cp_gen_params m_params;
126 struct xran_recv_packet_info m_pktInfo;
127 struct xran_cp_recv_params m_result;
129 struct xran_sectionext1_info m_temp_ext1[XRAN_MAX_PRBS];
132 std::string m_dirStr;
133 uint8_t m_sectionType;
135 uint8_t m_ccId, m_antId;
137 uint8_t m_frameId, m_subframeId, m_slotId;
140 uint8_t m_iqWidth, m_compMethod;
141 uint8_t m_filterIndex;
142 uint16_t m_timeOffset;
147 struct sectinfo *m_sections;
148 struct extcfginfo *m_extcfgs;
151 uint16_t m_ext1_dst_len = 0;
152 int8_t *m_p_ext1_dst = nullptr;
153 int16_t *m_p_bfw_iq_src = nullptr;
155 struct xran_sectionext1_info m_ext1;
158 struct rte_mbuf_ext_shared_info m_extSharedInfo;
159 uint8_t *m_pBfwIQ_ext = nullptr;
160 int16_t *m_pBfw_src[XRAN_MAX_SET_BFWS];
161 int16_t m_pBfw_rx[XRAN_MAX_SET_BFWS][MAX_RX_LEN];
162 struct xran_ext11_bfw_info m_bfwInfo[XRAN_MAX_SET_BFWS];
164 void SetUp() override
169 std::string ext_name;
171 init_test("C_Plane");
173 m_dirStr = get_input_parameter<std::string>("direction");
175 if(!m_dirStr.compare("DL")) m_dir = XRAN_DIR_DL;
176 else if(!m_dirStr.compare("UL")) m_dir = XRAN_DIR_UL;
177 else FAIL() << "Invalid direction!";
179 m_sectionType = get_input_parameter<uint8_t>("section_type");
180 m_ccId = get_input_parameter<uint8_t>("cc_id");
181 m_antId = get_input_parameter<uint8_t>("ant_id");
182 m_seqId = get_input_parameter<uint16_t>("seq_id");
184 m_frameId = get_input_parameter<uint8_t>("frame_id");
185 m_subframeId = get_input_parameter<uint8_t>("subframe_id");
186 m_slotId = get_input_parameter<uint8_t>("slot_id");
187 m_symStart = get_input_parameter<uint8_t>("symbol_start");
188 m_compMethod = get_input_parameter<uint8_t>("comp_method");
189 m_iqWidth = get_input_parameter<uint8_t>("iq_width");
191 switch(m_sectionType) {
192 case XRAN_CP_SECTIONTYPE_1:
193 m_filterIndex = XRAN_FILTERINDEX_STANDARD;
196 case XRAN_CP_SECTIONTYPE_3:
197 m_filterIndex = get_input_parameter<uint8_t>("filter_index");
198 m_timeOffset = get_input_parameter<uint16_t>("time_offset");
199 m_fftSize = get_input_parameter<uint8_t>("fft_size");
200 m_scs = get_input_parameter<uint8_t>("scs");
201 m_cpLength = get_input_parameter<uint16_t>("cp_length");
205 FAIL() << "Invalid Section Type - " << m_sectionType << std::endl;
208 m_numSections = get_input_subsection_size("sections");
209 ASSERT_FALSE(m_numSections == 0);
211 m_sections = new struct sectinfo [m_numSections];
212 for(i=0; i<m_numSections; i++) {
213 m_sections[i].sectionId = get_input_parameter<uint16_t>("sections", i, "sectionId");
214 m_sections[i].rb = get_input_parameter<uint16_t>("sections", i, "rb");
215 m_sections[i].symInc = get_input_parameter<uint16_t>("sections", i, "symInc");
216 m_sections[i].startPrbc = get_input_parameter<uint16_t>("sections", i, "startPrbc");
217 m_sections[i].numPrbc = get_input_parameter<uint16_t>("sections", i, "numPrbc");
218 m_sections[i].reMask = get_input_parameter<uint16_t>("sections", i, "reMask");
219 m_sections[i].numSymbol = get_input_parameter<uint16_t>("sections", i, "numSymbol");
220 m_sections[i].beamId = get_input_parameter<uint16_t>("sections", i, "beamId");
222 switch(m_sectionType) {
223 case XRAN_CP_SECTIONTYPE_3:
224 m_sections[i].freqOffset = get_input_parameter<uint16_t>("sections", i, "freqOffset");
228 m_sections[i].exts = get_input_parameter<std::vector<uint8_t>>("sections", i, "exts");
231 /* allocate and prepare required data storage */
232 m_pSectGenInfo = new struct xran_section_gen_info [m_numSections];
233 ASSERT_NE(m_pSectGenInfo, nullptr);
234 m_params.sections = m_pSectGenInfo;
236 m_pSectResult = new struct xran_section_recv_info [m_numSections];
237 ASSERT_NE(m_pSectResult, nullptr);
238 m_result.sections = m_pSectResult;
240 /* reading configurations of section extension */
241 m_nextcfgs = get_input_subsection_size("extensions");
243 m_extcfgs = new struct extcfginfo [m_nextcfgs];
246 for(i=0; i < m_nextcfgs; i++) {
247 std::vector<uint16_t> beamIDs;
249 ext_type = get_input_parameter<int>("extensions", i, "type");
251 case XRAN_CP_SECTIONEXTCMD_1:
252 /* if section extension type 1 is present, then ignore other extensions */
253 if(i != 0 && m_nextcfgs != 1) {
254 std::cout << "### Extension 1 configuration, ignore other extensions !!\n" << std::endl;
259 m_extcfgs[i].u.ext1.bfwCompMeth = get_input_parameter<uint8_t> ("extensions", i, "bfwCompMeth");
260 m_extcfgs[i].u.ext1.bfwIqWidth = get_input_parameter<uint8_t> ("extensions", i, "bfwIqWidth");
261 m_antElmTRx = get_input_parameter<uint8_t> ("extensions", i, "antelm_trx");
264 case XRAN_CP_SECTIONEXTCMD_2:
265 m_extcfgs[i].u.ext2.bfAzPtWidth = get_input_parameter<uint8_t>("extensions", i, "bfAzPtWidth") & 0x7;
266 m_extcfgs[i].u.ext2.bfAzPt = get_input_parameter<uint8_t>("extensions", i, "bfAzPt") & 0xf;
267 m_extcfgs[i].u.ext2.bfZePtWidth = get_input_parameter<uint8_t>("extensions", i, "bfZePtWidth") & 0x7;
268 m_extcfgs[i].u.ext2.bfZePt = get_input_parameter<uint8_t>("extensions", i, "bfZePt") & 0xf;
269 m_extcfgs[i].u.ext2.bfAz3ddWidth = get_input_parameter<uint8_t>("extensions", i, "bfAz3ddWidth") & 0x7;
270 m_extcfgs[i].u.ext2.bfAz3dd = get_input_parameter<uint8_t>("extensions", i, "bfAz3dd") & 0xf;
271 m_extcfgs[i].u.ext2.bfZe3ddWidth = get_input_parameter<uint8_t>("extensions", i, "bfZe3ddWidth") & 0x7;
272 m_extcfgs[i].u.ext2.bfZe3dd = get_input_parameter<uint8_t>("extensions", i, "bfZe3dd") & 0xf;
273 m_extcfgs[i].u.ext2.bfAzSI = get_input_parameter<uint8_t>("extensions", i, "bfAzSI") & 0x7;
274 m_extcfgs[i].u.ext2.bfZeSI = get_input_parameter<uint8_t>("extensions", i, "bfZeSI") & 0x7;
277 case XRAN_CP_SECTIONEXTCMD_3:
278 m_extcfgs[i].u.ext3.codebookIdx = get_input_parameter<uint8_t> ("extensions", i, "codebookIdx");
279 m_extcfgs[i].u.ext3.layerId = get_input_parameter<uint8_t> ("extensions", i, "layerId") & 0xf;
280 m_extcfgs[i].u.ext3.numLayers = get_input_parameter<uint8_t> ("extensions", i, "numLayers") & 0xf;
281 m_extcfgs[i].u.ext3.txScheme = get_input_parameter<uint8_t> ("extensions", i, "txScheme") & 0xf;
282 m_extcfgs[i].u.ext3.crsReMask = get_input_parameter<uint16_t>("extensions", i, "crsReMask") & 0xfff;
283 m_extcfgs[i].u.ext3.crsShift = get_input_parameter<uint8_t> ("extensions", i, "crsShift") & 0x1;
284 m_extcfgs[i].u.ext3.crsSymNum = get_input_parameter<uint8_t> ("extensions", i, "crsSymNum") & 0xf;
285 m_extcfgs[i].u.ext3.numAntPort = get_input_parameter<uint16_t>("extensions", i, "numAntPort");
286 m_extcfgs[i].u.ext3.beamIdAP1 = get_input_parameter<uint16_t>("extensions", i, "beamIdAP1");
287 m_extcfgs[i].u.ext3.beamIdAP2 = get_input_parameter<uint16_t>("extensions", i, "beamIdAP2");
288 m_extcfgs[i].u.ext3.beamIdAP3 = get_input_parameter<uint16_t>("extensions", i, "beamIdAP3");
291 case XRAN_CP_SECTIONEXTCMD_4:
292 m_extcfgs[i].u.ext4.csf = get_input_parameter<uint8_t> ("extensions", i, "csf") & 0xf;
293 m_extcfgs[i].u.ext4.modCompScaler= get_input_parameter<uint16_t>("extensions", i, "modCompScaler") & 0x7fff;
296 case XRAN_CP_SECTIONEXTCMD_5:
298 std::vector<uint16_t> csf;
299 std::vector<uint16_t> mcScaleReMask;
300 std::vector<uint16_t> mcScaleOffset;
302 m_extcfgs[i].u.ext5.num_sets = get_input_parameter<uint8_t>("extensions", i, "num_sets");
303 if(m_extcfgs[i].u.ext5.num_sets > XRAN_MAX_MODCOMP_ADDPARMS)
304 FAIL() << "Invalid number of sets in extension 5!";
306 csf = get_input_parameter<std::vector<uint16_t>>("extensions", i, "csf");
307 mcScaleReMask = get_input_parameter<std::vector<uint16_t>>("extensions", i, "mcScaleReMask");
308 mcScaleOffset = get_input_parameter<std::vector<uint16_t>>("extensions", i, "mcScaleOffset");
310 if(csf.size() != m_extcfgs[i].u.ext5.num_sets
311 || mcScaleReMask.size() != m_extcfgs[i].u.ext5.num_sets
312 || mcScaleOffset.size() != m_extcfgs[i].u.ext5.num_sets)
313 FAIL() << "Invalid configuration in extension 5 - different size!";
315 for(j=0; j < m_extcfgs[i].u.ext5.num_sets; j++) {
316 m_extcfgs[i].u.ext5.mc[j].csf = csf[j];
317 m_extcfgs[i].u.ext5.mc[j].mcScaleReMask = mcScaleReMask[j];
318 m_extcfgs[i].u.ext5.mc[j].mcScaleOffset = mcScaleOffset[j];
323 case XRAN_CP_SECTIONEXTCMD_6:
324 m_extcfgs[i].u.ext6.rbgSize = get_input_parameter<uint8_t> ("extensions", i, "rbgSize");
325 m_extcfgs[i].u.ext6.rbgMask = get_input_parameter<uint32_t>("extensions", i, "rbgMask");
326 m_extcfgs[i].u.ext6.symbolMask = get_input_parameter<uint16_t>("extensions", i, "symbolMask");
329 case XRAN_CP_SECTIONEXTCMD_10:
330 m_extcfgs[i].u.ext10.numPortc = get_input_parameter<uint8_t> ("extensions", i, "numPortc");
331 m_extcfgs[i].u.ext10.beamGrpType= get_input_parameter<uint8_t> ("extensions", i, "beamGrpType");
332 switch(m_extcfgs[i].u.ext10.beamGrpType) {
333 case XRAN_BEAMGT_COMMON:
334 case XRAN_BEAMGT_MATRIXIND:
336 case XRAN_BEAMGT_VECTORLIST:
337 beamIDs = get_input_parameter<std::vector<uint16_t>>("extensions", i, "beamID");
338 for(j=0; j < m_extcfgs[i].u.ext10.numPortc; j++)
339 m_extcfgs[i].u.ext10.beamID[j] = beamIDs[j];
342 FAIL() << "Invalid Beam Group Type - " << m_extcfgs[i].u.ext10.beamGrpType << std::endl;
346 case XRAN_CP_SECTIONEXTCMD_11:
349 /* if section extension type 11 is present, then ignore other extensions */
350 if(i != 0 && m_nextcfgs != 1) {
351 std::cout << "### Extension 11 configuration, ignore other extensions !!\n" << std::endl;
357 m_extcfgs[i].u.ext11.RAD = get_input_parameter<uint8_t> ("extensions", i, "RAD");
358 m_extcfgs[i].u.ext11.disableBFWs = get_input_parameter<uint8_t> ("extensions", i, "disableBFWs");
359 m_extcfgs[i].u.ext11.numBundPrb = get_input_parameter<uint8_t> ("extensions", i, "numBundPrb");
360 m_extcfgs[i].u.ext11.bfwCompMeth = get_input_parameter<uint8_t> ("extensions", i, "bfwCompMeth");
361 m_extcfgs[i].u.ext11.bfwIqWidth = get_input_parameter<uint8_t> ("extensions", i, "bfwIqWidth");
362 m_extcfgs[i].u.ext11.numSetBFWs = get_input_parameter<uint8_t> ("extensions", i, "numSetBFWs");
363 m_antElmTRx = get_input_parameter<uint8_t> ("extensions", i, "antelm_trx");
364 beamIDs = get_input_parameter<std::vector<uint16_t>>("extensions", i, "beamID");
366 /* Allocate buffers */
367 m_extcfgs[i].u.ext11.maxExtBufSize = MAX_RX_LEN;
368 m_pBfwIQ_ext = (uint8_t *)xran_malloc(m_extcfgs[i].u.ext11.maxExtBufSize);
369 m_extcfgs[i].u.ext11.pExtBuf = m_pBfwIQ_ext;
371 for(j = 0; j < XRAN_MAX_SET_BFWS; j++) {
372 m_pBfw_src[j] = new int16_t [XRAN_MAX_BFW_N];
373 memset(m_pBfw_src[j], j+1, XRAN_MAX_BFW_N);
376 for(j=0; j < m_extcfgs[i].u.ext11.numSetBFWs; j++) {
377 m_bfwInfo[j].pBFWs = (uint8_t *)(m_pBfw_src[j]);
378 m_bfwInfo[j].beamId = beamIDs[j];
381 /* Initialize Shared information for external buffer */
382 m_extSharedInfo.free_cb = NULL;
383 m_extSharedInfo.fcb_opaque = NULL;
384 rte_mbuf_ext_refcnt_update(&m_extSharedInfo, 0);
385 m_extcfgs[i].u.ext11.pExtBufShinfo = &m_extSharedInfo;
387 /* Check all BFWs can be fit with given buffer */
388 temp = xran_cp_estimate_max_set_bfws(m_antElmTRx, m_extcfgs[i].u.ext11.bfwIqWidth,
389 m_extcfgs[i].u.ext11.bfwCompMeth, m_extcfgs[i].u.ext11.maxExtBufSize);
390 if(m_extcfgs[i].u.ext11.numSetBFWs > temp) {
391 FAIL() << "Too many sets of BFWs - " << m_extcfgs[i].u.ext11.numSetBFWs
392 << " (max " << temp << " for " << m_extcfgs[i].u.ext11.maxExtBufSize << std::endl;
395 temp = xran_cp_prepare_ext11_bfws(m_extcfgs[i].u.ext11.numSetBFWs, m_antElmTRx,
396 m_extcfgs[i].u.ext11.bfwIqWidth, m_extcfgs[i].u.ext11.bfwCompMeth,
397 m_pBfwIQ_ext, XRAN_MAX_BUFLEN_EXT11, m_bfwInfo);
399 FAIL() << "Fail to prepare BFWs!" << std::endl;
401 m_extcfgs[i].u.ext11.totalBfwIQLen = temp;
406 FAIL() << "Invalid Section Type Extension - " << ext_type << std::endl;
408 } /* switch(ext_type) */
410 m_extcfgs[i].type = ext_type;
411 m_extcfgs[i].name = get_input_parameter<std::string>("extensions", i, "name");
415 } /* for(i=0; i < m_nextcfgs; i++) */
421 m_ext1_dst_len = 9600;
422 m_p_ext1_dst = new int8_t [m_ext1_dst_len];
423 m_p_bfw_iq_src = new int16_t [9600/2];
426 void TearDown() override
428 if(m_pTestBuffer != nullptr) {
429 rte_pktmbuf_free(m_pTestBuffer);
430 m_pTestBuffer = nullptr;
434 xran_free(m_pBfwIQ_ext);
435 m_pBfwIQ_ext = nullptr;
437 for(int i = 0; i < XRAN_MAX_SET_BFWS; i++) {
438 DELETE_ARRAY(m_pBfw_src[i]);
441 DELETE_ARRAY(m_extcfgs);
442 DELETE_ARRAY(m_sections);
443 DELETE_ARRAY(m_p_bfw_iq_src);
444 DELETE_ARRAY(m_p_ext1_dst);
445 DELETE_ARRAY(m_pSectGenInfo);
446 DELETE_ARRAY(m_pSectResult);
449 int prepare_sections(void);
450 int prepare_extensions(void);
451 void verify_sections(void);
453 void test_ext1(void);
458 int C_plane::prepare_extensions()
460 int i, j, numext, sect_num;
463 for(sect_num=0; sect_num < m_numSections; sect_num++) {
466 for(i=0; i < m_sections[sect_num].exts.size(); i++) {
468 ext_id = m_sections[sect_num].exts[i];
469 if(ext_id >= m_nextcfgs) {
470 std::cout << "Invalid section extension configuration index - " << ext_id << " [max " << m_nextcfgs-1 << "]" << std::endl;
474 switch(m_extcfgs[ext_id].type) {
475 case XRAN_CP_SECTIONEXTCMD_1:
476 // std::cout << "Skip Extension 1 !!" << std::endl;
478 case XRAN_CP_SECTIONEXTCMD_2:
479 m_params.sections[sect_num].exData[numext].len = sizeof(m_extcfgs[ext_id].u.ext2);
480 m_params.sections[sect_num].exData[numext].data = &m_extcfgs[ext_id].u.ext2;
482 case XRAN_CP_SECTIONEXTCMD_3:
483 m_params.sections[sect_num].exData[numext].len = sizeof(m_extcfgs[ext_id].u.ext3);
484 m_params.sections[sect_num].exData[numext].data = &m_extcfgs[ext_id].u.ext3;
486 case XRAN_CP_SECTIONEXTCMD_4:
487 m_params.sections[sect_num].exData[numext].len = sizeof(m_extcfgs[ext_id].u.ext4);
488 m_params.sections[sect_num].exData[numext].data = &m_extcfgs[ext_id].u.ext4;
490 case XRAN_CP_SECTIONEXTCMD_5:
491 m_params.sections[sect_num].exData[numext].len = sizeof(m_extcfgs[ext_id].u.ext5);
492 m_params.sections[sect_num].exData[numext].data = &m_extcfgs[ext_id].u.ext5;
494 case XRAN_CP_SECTIONEXTCMD_6:
495 m_params.sections[sect_num].exData[numext].len = sizeof(m_extcfgs[ext_id].u.ext6);
496 m_params.sections[sect_num].exData[numext].data = &m_extcfgs[ext_id].u.ext6;
498 case XRAN_CP_SECTIONEXTCMD_10:
499 m_params.sections[sect_num].exData[numext].len = sizeof(m_extcfgs[ext_id].u.ext10);
500 m_params.sections[sect_num].exData[numext].data = &m_extcfgs[ext_id].u.ext10;
502 case XRAN_CP_SECTIONEXTCMD_11:
503 m_params.sections[sect_num].exData[numext].len = sizeof(m_extcfgs[ext_id].u.ext11);
504 m_params.sections[sect_num].exData[numext].data = &m_extcfgs[ext_id].u.ext11;
506 m_result.sections[sect_num].exts[numext].type = m_extcfgs[ext_id].type;
507 for(j=0 ; j < XRAN_MAX_SET_BFWS; j++)
508 m_result.sections[sect_num].exts[numext].u.ext11.bundInfo[j].pBFWs = (uint8_t *)m_pBfw_rx[j];
512 std::cout << "Invalid Section Extension Type - " << (int)m_extcfgs[ext_id].type << std::endl;
514 } /* switch(m_extcfgs[ext_id].type) */
516 m_params.sections[sect_num].exData[numext].type = m_extcfgs[ext_id].type;
518 } /* for(i=0; i < m_sections[sect_num].exts.size(); i++) */
521 m_params.sections[sect_num].exDataSize = numext;
522 m_params.sections[sect_num].info.ef = 1;
525 m_params.sections[sect_num].exDataSize = 0;
526 m_params.sections[sect_num].info.ef = 0;
528 } /* for(sect_num=0; sect_num < m_numSections; sect_num++) */
534 int C_plane::prepare_sections(void)
539 /* Preparing input data for packet generation */
540 m_params.dir = m_dir;
541 m_params.sectionType = m_sectionType;
543 m_params.hdr.filterIdx = m_filterIndex;
544 m_params.hdr.frameId = m_frameId;
545 m_params.hdr.subframeId = m_subframeId;
546 m_params.hdr.slotId = m_slotId;
547 m_params.hdr.startSymId = m_symStart;
548 m_params.hdr.iqWidth = XRAN_CONVERT_IQWIDTH(m_iqWidth);
549 m_params.hdr.compMeth = m_compMethod;
551 switch(m_sectionType) {
552 case XRAN_CP_SECTIONTYPE_1:
555 case XRAN_CP_SECTIONTYPE_3:
556 m_params.hdr.timeOffset = m_timeOffset;
557 m_params.hdr.fftSize = m_fftSize;
558 m_params.hdr.scs = m_scs;
559 m_params.hdr.cpLength = m_cpLength;
566 for(numsec=0; numsec < m_numSections; numsec++) {
567 m_params.sections[numsec].info.type = m_params.sectionType;
568 m_params.sections[numsec].info.startSymId = m_params.hdr.startSymId;
569 m_params.sections[numsec].info.iqWidth = m_params.hdr.iqWidth;
570 m_params.sections[numsec].info.compMeth = m_params.hdr.compMeth;
571 m_params.sections[numsec].info.id = m_sections[numsec].sectionId;
572 m_params.sections[numsec].info.rb = m_sections[numsec].rb;
573 m_params.sections[numsec].info.symInc = m_sections[numsec].symInc;
574 m_params.sections[numsec].info.startPrbc = m_sections[numsec].startPrbc;
575 m_params.sections[numsec].info.numPrbc = m_sections[numsec].numPrbc;
576 m_params.sections[numsec].info.reMask = m_sections[numsec].reMask;
577 m_params.sections[numsec].info.numSymbol = m_sections[numsec].numSymbol;
578 m_params.sections[numsec].info.beamId = m_sections[numsec].beamId;
580 switch(m_sectionType) {
581 case XRAN_CP_SECTIONTYPE_1:
584 case XRAN_CP_SECTIONTYPE_3:
585 m_params.sections[numsec].info.freqOffset = m_sections[numsec].freqOffset;
593 m_params.numSections = numsec;
599 void C_plane::verify_sections(void)
603 /* Verify the result */
604 EXPECT_TRUE(m_result.dir == m_params.dir);
605 EXPECT_TRUE(m_result.sectionType == m_params.sectionType);
607 EXPECT_TRUE(m_result.hdr.filterIdx == m_params.hdr.filterIdx);
608 EXPECT_TRUE(m_result.hdr.frameId == m_params.hdr.frameId);
609 EXPECT_TRUE(m_result.hdr.subframeId == m_params.hdr.subframeId);
610 EXPECT_TRUE(m_result.hdr.slotId == m_params.hdr.slotId);
611 EXPECT_TRUE(m_result.hdr.startSymId == m_params.hdr.startSymId);
612 EXPECT_TRUE(m_result.hdr.iqWidth == m_params.hdr.iqWidth);
613 EXPECT_TRUE(m_result.hdr.compMeth == m_params.hdr.compMeth);
615 switch(m_sectionType) {
616 case XRAN_CP_SECTIONTYPE_1:
619 case XRAN_CP_SECTIONTYPE_3:
620 EXPECT_TRUE(m_result.hdr.fftSize == m_params.hdr.fftSize);
621 EXPECT_TRUE(m_result.hdr.scs == m_params.hdr.scs);
622 EXPECT_TRUE(m_result.hdr.cpLength == m_params.hdr.cpLength);
626 FAIL() << "Invalid Section Type - " << m_sectionType << "\n";
629 ASSERT_TRUE(m_result.numSections == m_params.numSections);
630 for(i=0; i < m_result.numSections; i++) {
631 EXPECT_TRUE(m_result.sections[i].info.id == m_params.sections[i].info.id);
632 EXPECT_TRUE(m_result.sections[i].info.rb == m_params.sections[i].info.rb);
633 EXPECT_TRUE(m_result.sections[i].info.symInc == m_params.sections[i].info.symInc);
634 EXPECT_TRUE(m_result.sections[i].info.startPrbc == m_params.sections[i].info.startPrbc);
635 if(m_params.sections[i].info.numPrbc > 255)
636 EXPECT_TRUE(m_result.sections[i].info.numPrbc == 0);
638 EXPECT_TRUE(m_result.sections[i].info.numPrbc == m_params.sections[i].info.numPrbc);
639 EXPECT_TRUE(m_result.sections[i].info.numSymbol == m_params.sections[i].info.numSymbol);
640 EXPECT_TRUE(m_result.sections[i].info.reMask == m_params.sections[i].info.reMask);
641 EXPECT_TRUE(m_result.sections[i].info.beamId == m_params.sections[i].info.beamId);
642 EXPECT_TRUE(m_result.sections[i].info.ef == m_params.sections[i].info.ef);
644 switch(m_sectionType) {
645 case XRAN_CP_SECTIONTYPE_1:
648 case XRAN_CP_SECTIONTYPE_3:
649 EXPECT_TRUE(m_result.sections[i].info.freqOffset == m_params.sections[i].info.freqOffset);
653 FAIL() << "Invalid Section Type - " << m_sectionType << "\n";
656 if(m_params.sections[i].info.ef) {
657 //printf("[%d] %d == %d\n",i, m_result.sections[i].exDataSize, m_params.sections[i].exDataSize);
658 EXPECT_TRUE(m_result.sections[i].numExts == m_params.sections[i].exDataSize);
660 for(j=0; j < m_params.sections[i].exDataSize; j++) {
661 EXPECT_TRUE(m_result.sections[i].exts[j].type == m_params.sections[i].exData[j].type);
663 switch(m_params.sections[i].exData[j].type) {
664 case XRAN_CP_SECTIONEXTCMD_1:
666 struct xran_sectionext1_info *ext1_params, *ext1_result;
667 int iq_size, parm_size, N;
669 ext1_params = (struct xran_sectionext1_info *)m_params.sections[i].exData[j].data;
670 ext1_result = &m_result.sections[i].exts[j].u.ext1;
672 EXPECT_TRUE(ext1_result->bfwIqWidth == ext1_params->bfwIqWidth);
673 EXPECT_TRUE(ext1_result->bfwCompMeth == ext1_params->bfwCompMeth);
675 N = ext1_params->bfwNumber;
676 switch(ext1_params->bfwCompMeth) {
677 case XRAN_BFWCOMPMETHOD_BLKFLOAT:
678 //printf("[%d, %d] %d == %d\n",i, j, ext1_result->bfwCompParam.exponent, ext1_params->bfwCompParam.exponent);
679 EXPECT_TRUE(ext1_result->bfwCompParam.exponent == ext1_params->bfwCompParam.exponent);
682 case XRAN_BFWCOMPMETHOD_BLKSCALE:
683 EXPECT_TRUE(ext1_result->bfwCompParam.blockScaler == ext1_params->bfwCompParam.blockScaler);
686 case XRAN_BFWCOMPMETHOD_ULAW:
687 EXPECT_TRUE(ext1_result->bfwCompParam.compBitWidthShift == ext1_params->bfwCompParam.compBitWidthShift);
690 case XRAN_BFWCOMPMETHOD_BEAMSPACE:
691 parm_size = N>>3; if(N%8) parm_size++; parm_size *= 8;
692 EXPECT_TRUE(std::memcmp(ext1_result->bfwCompParam.activeBeamspaceCoeffMask, ext1_params->bfwCompParam.activeBeamspaceCoeffMask, parm_size));
696 /* Get the number of BF weights */
697 iq_size = N*ext1_params->bfwIqWidth*2; // total in bits
698 parm_size = iq_size>>3; // total in bytes (/8)
699 if(iq_size%8) parm_size++; // round up
700 EXPECT_FALSE(std::memcmp(ext1_result->p_bfwIQ, ext1_params->p_bfwIQ, parm_size));
704 case XRAN_CP_SECTIONEXTCMD_2:
706 struct xran_sectionext2_info *ext2_params, *ext2_result;
708 ext2_params = (struct xran_sectionext2_info *)m_params.sections[i].exData[j].data;
709 ext2_result = &m_result.sections[i].exts[j].u.ext2;
711 if(ext2_params->bfAzPtWidth) {
712 EXPECT_TRUE(ext2_result->bfAzPtWidth == ext2_params->bfAzPtWidth);
713 EXPECT_TRUE(ext2_result->bfAzPt == ext2_params->bfAzPt);
716 if(ext2_params->bfZePtWidth) {
717 EXPECT_TRUE(ext2_result->bfZePtWidth == ext2_params->bfZePtWidth);
718 EXPECT_TRUE(ext2_result->bfZePt == ext2_params->bfZePt);
720 if(ext2_params->bfAz3ddWidth) {
721 EXPECT_TRUE(ext2_result->bfAz3ddWidth == ext2_params->bfAz3ddWidth);
722 EXPECT_TRUE(ext2_result->bfAz3dd == ext2_params->bfAz3dd);
724 if(ext2_params->bfZe3ddWidth) {
725 EXPECT_TRUE(ext2_result->bfZe3ddWidth == ext2_params->bfZe3ddWidth);
726 EXPECT_TRUE(ext2_result->bfZe3dd == ext2_params->bfZe3dd);
729 EXPECT_TRUE(ext2_result->bfAzSI == ext2_params->bfAzSI);
730 EXPECT_TRUE(ext2_result->bfZeSI == ext2_params->bfZeSI);
734 case XRAN_CP_SECTIONEXTCMD_3:
736 struct xran_sectionext3_info *ext3_params, *ext3_result;
738 ext3_params = (struct xran_sectionext3_info *)m_params.sections[i].exData[j].data;
739 ext3_result = &m_result.sections[i].exts[j].u.ext3;
741 EXPECT_TRUE(ext3_result->layerId == ext3_params->layerId);
742 EXPECT_TRUE(ext3_result->codebookIdx== ext3_params->codebookIdx);
743 EXPECT_TRUE(ext3_result->numLayers == ext3_params->numLayers);
745 if(ext3_params->layerId == XRAN_LAYERID_0
746 || ext3_params->layerId == XRAN_LAYERID_TXD) { /* first data layer */
747 EXPECT_TRUE(ext3_result->txScheme == ext3_params->txScheme);
748 EXPECT_TRUE(ext3_result->crsReMask == ext3_params->crsReMask);
749 EXPECT_TRUE(ext3_result->crsShift == ext3_params->crsShift);
750 EXPECT_TRUE(ext3_result->crsSymNum == ext3_params->crsSymNum);
752 EXPECT_TRUE(ext3_result->numAntPort == ext3_params->numAntPort);
754 EXPECT_TRUE(ext3_result->beamIdAP1 == ext3_params->beamIdAP1);
756 if(ext3_params->numAntPort == 4) {
757 EXPECT_TRUE(ext3_result->beamIdAP2 == ext3_params->beamIdAP2);
758 EXPECT_TRUE(ext3_result->beamIdAP3 == ext3_params->beamIdAP3);
764 case XRAN_CP_SECTIONEXTCMD_4:
766 struct xran_sectionext4_info *ext4_params, *ext4_result;
768 ext4_params = (struct xran_sectionext4_info *)m_params.sections[i].exData[j].data;
769 ext4_result = &m_result.sections[i].exts[j].u.ext4;
771 EXPECT_TRUE(ext4_result->csf == ext4_params->csf);
772 EXPECT_TRUE(ext4_result->modCompScaler == ext4_params->modCompScaler);
776 case XRAN_CP_SECTIONEXTCMD_5:
778 struct xran_sectionext5_info *ext5_params, *ext5_result;
781 ext5_params = (struct xran_sectionext5_info *)m_params.sections[i].exData[j].data;
782 ext5_result = &m_result.sections[i].exts[j].u.ext5;
784 EXPECT_TRUE(ext5_result->num_sets == ext5_params->num_sets);
785 for(idx=0; idx < ext5_params->num_sets; idx++) {
786 EXPECT_TRUE(ext5_result->mc[idx].csf == ext5_params->mc[idx].csf);
787 EXPECT_TRUE(ext5_result->mc[idx].mcScaleReMask == ext5_params->mc[idx].mcScaleReMask);
788 EXPECT_TRUE(ext5_result->mc[idx].mcScaleOffset == ext5_params->mc[idx].mcScaleOffset);
792 case XRAN_CP_SECTIONEXTCMD_6:
794 struct xran_sectionext6_info *ext6_params, *ext6_result;
796 ext6_params = (struct xran_sectionext6_info *)m_params.sections[i].exData[j].data;
797 ext6_result = &m_result.sections[i].exts[j].u.ext6;
799 EXPECT_TRUE(ext6_result->rbgSize == ext6_params->rbgSize);
800 EXPECT_TRUE(ext6_result->rbgMask == ext6_params->rbgMask);
801 EXPECT_TRUE(ext6_result->symbolMask == ext6_params->symbolMask);
804 case XRAN_CP_SECTIONEXTCMD_10:
806 struct xran_sectionext10_info *ext10_params, *ext10_result;
809 ext10_params = (struct xran_sectionext10_info *)m_params.sections[i].exData[j].data;
810 ext10_result = &m_result.sections[i].exts[j].u.ext10;
812 EXPECT_TRUE(ext10_result->numPortc == ext10_params->numPortc);
813 EXPECT_TRUE(ext10_result->beamGrpType == ext10_params->beamGrpType);
814 if(ext10_result->beamGrpType == XRAN_BEAMGT_VECTORLIST) {
815 for(idx=0; idx < ext10_result->numPortc; idx++)
816 EXPECT_TRUE(ext10_result->beamID[idx] == ext10_params->beamID[idx]);
820 case XRAN_CP_SECTIONEXTCMD_11:
822 struct xran_sectionext11_info *ext11_params;
823 struct xran_sectionext11_recv_info *ext11_result;
825 ext11_params = (struct xran_sectionext11_info *)m_params.sections[i].exData[j].data;
826 ext11_result = &m_result.sections[i].exts[j].u.ext11;
828 EXPECT_TRUE(ext11_result->RAD == ext11_params->RAD);
829 EXPECT_TRUE(ext11_result->disableBFWs == ext11_params->disableBFWs);
830 EXPECT_TRUE(ext11_result->numBundPrb == ext11_params->numBundPrb);
831 EXPECT_TRUE(ext11_result->bfwCompMeth == ext11_params->bfwCompMeth);
832 EXPECT_TRUE(ext11_result->bfwIqWidth == ext11_params->bfwIqWidth);
835 EXPECT_TRUE(ext11_result->numSetBFWs == ext11_params->numSetBFWs);
836 for(k=0; k < ext11_result->numSetBFWs; k++) {
837 EXPECT_TRUE(ext11_result->bundInfo[k].beamId == m_bfwInfo[k].beamId);
839 EXPECT_TRUE(ext11_result->bundInfo[k].BFWSize == ext11_params->BFWSize);
841 if(ext11_result->bundInfo[k].pBFWs)
842 EXPECT_TRUE(memcmp(ext11_result->bundInfo[k].pBFWs,
843 ext11_params->bundInfo[k].pBFWs + ext11_params->bundInfo[k].offset + 4,
844 ext11_result->bundInfo[k].BFWSize) == 0);
845 switch(ext11_result->bfwCompMeth) {
846 case XRAN_BFWCOMPMETHOD_NONE:
849 case XRAN_BFWCOMPMETHOD_BLKFLOAT:
850 EXPECT_TRUE(ext11_result->bundInfo[k].bfwCompParam.exponent == ext11_params->bundInfo[k].bfwCompParam.exponent);
854 FAIL() << "Invalid BfComp method - %d" << ext11_result->bfwCompMeth << std::endl;
868 void C_plane::test_ext1(void)
873 int32_t nAntElm = 64;
875 int8_t compMethod = XRAN_COMPMETHOD_BLKFLOAT;
876 int8_t *p_ext1_dst = NULL;
877 int8_t *bfw_payload = NULL;
878 int32_t expected_len = ((nAntElm/16*4*iqWidth)+1)*nRbs + /* bfwCompParam + IQ = */
879 sizeof(struct xran_cp_radioapp_section_ext1)*nRbs; /* ext1 Headers */
881 int16_t ext_len = 9600;
882 int16_t ext_sec_total = 0;
883 int8_t * ext_buf = nullptr;
884 int8_t * ext_buf_init = nullptr;
886 struct xran_section_gen_info* loc_pSectGenInfo = m_params.sections;
887 struct xran_sectionext1_info m_prep_ext1;
888 struct xran_cp_radioapp_section_ext1 *p_ext1;
889 struct rte_mbuf_ext_shared_info share_data;
890 struct rte_mbuf *mbuf = NULL;
893 nAntElm = m_antElmTRx;
894 nRbs = m_params.sections[0].info.numPrbc;
895 iqWidth = m_extcfgs[0].u.ext1.bfwIqWidth;
896 compMethod = m_extcfgs[0].u.ext1.bfwCompMeth;
899 case XRAN_BFWCOMPMETHOD_NONE:
900 expected_len = (3+1)*nRbs + nAntElm*nRbs*4;
902 case XRAN_BFWCOMPMETHOD_BLKFLOAT:
903 expected_len = ((nAntElm/16*4*iqWidth)+1)*nRbs + /* bfwCompParam + IQ = */
904 sizeof(struct xran_cp_radioapp_section_ext1)*nRbs; /* ext1 Headers */
907 FAIL() << "Unsupported Compression Method - " << compMethod << std::endl;
910 if(loc_pSectGenInfo->info.type == XRAN_CP_SECTIONTYPE_1) {
911 /* extType 1 only with Section 1 for now */
913 ext_buf = ext_buf_init = (int8_t*) xran_malloc(ext_len);
915 ptr = m_p_bfw_iq_src;
917 for (idRb =0; idRb < nRbs*nAntElm*2; idRb++){
922 ext_buf += (RTE_PKTMBUF_HEADROOM +
923 sizeof (struct xran_ecpri_hdr) +
924 sizeof(struct xran_cp_radioapp_common_header) +
925 sizeof(struct xran_cp_radioapp_section1));
927 ext_len -= (RTE_PKTMBUF_HEADROOM +
928 sizeof(struct xran_ecpri_hdr) +
929 sizeof(struct xran_cp_radioapp_common_header) +
930 sizeof(struct xran_cp_radioapp_section1));
932 ext_sec_total = xran_cp_populate_section_ext_1((int8_t *)ext_buf,
940 ASSERT_TRUE(ext_sec_total == expected_len);
941 p_ext1_dst = ext_buf;
943 memset(&m_temp_ext1[0], 0, sizeof (struct xran_sectionext1_info)*XRAN_MAX_PRBS);
947 p_ext1 = (struct xran_cp_radioapp_section_ext1 *)p_ext1_dst;
948 bfw_payload = (int8_t*)(p_ext1+1);
949 p_ext1_dst += p_ext1->extLen*XRAN_SECTIONEXT_ALIGN;
951 m_temp_ext1[idRb].bfwNumber = nAntElm;
952 m_temp_ext1[idRb].bfwIqWidth = iqWidth;
953 m_temp_ext1[idRb].bfwCompMeth = compMethod;
955 if(compMethod == XRAN_BFWCOMPMETHOD_BLKFLOAT) {
956 m_temp_ext1[idRb].bfwCompParam.exponent = *bfw_payload++ & 0xF;
959 m_temp_ext1[idRb].p_bfwIQ = (int16_t*)bfw_payload;
960 m_temp_ext1[idRb].bfwIQ_sz = p_ext1->extLen*XRAN_SECTIONEXT_ALIGN;
962 loc_pSectGenInfo->exData[idRb].type = XRAN_CP_SECTIONEXTCMD_1;
963 loc_pSectGenInfo->exData[idRb].len = sizeof(m_temp_ext1[idRb]);
964 loc_pSectGenInfo->exData[idRb].data = &m_temp_ext1[idRb];
967 } while(p_ext1->ef != XRAN_EF_F_LAST);
969 ASSERT_TRUE(idRb == nRbs);
971 mbuf = xran_attach_cp_ext_buf(0, ext_buf_init, ext_buf, ext_sec_total, &share_data);
973 /* Update section information */
974 memset(&m_prep_ext1, 0, sizeof (struct xran_sectionext1_info));
975 m_prep_ext1.bfwNumber = nAntElm;
976 m_prep_ext1.bfwIqWidth = iqWidth;
977 m_prep_ext1.bfwCompMeth = compMethod;
978 m_prep_ext1.p_bfwIQ = (int16_t*)ext_buf;
979 m_prep_ext1.bfwIQ_sz = ext_sec_total;
982 loc_pSectGenInfo->exData[0].type = XRAN_CP_SECTIONEXTCMD_1;
983 loc_pSectGenInfo->exData[0].len = sizeof(m_prep_ext1);
984 loc_pSectGenInfo->exData[0].data = &m_prep_ext1;
986 loc_pSectGenInfo->info.ef = 1;
987 loc_pSectGenInfo->exDataSize = 1; /* append all extType1 as one shot
988 (as generated via xran_cp_populate_section_ext_1)*/
990 m_params.numSections = 1;
992 /* Generating C-Plane packet */
993 ASSERT_TRUE(xran_prepare_ctrl_pkt(/*m_pTestBuffer*/mbuf, &m_params, m_ccId, m_antId, m_seqId) == XRAN_STATUS_SUCCESS);
995 /** to match O-RU parsing */
996 loc_pSectGenInfo->exDataSize = nRbs;
997 loc_pSectGenInfo->exData[0].len = sizeof(m_temp_ext1[0]);
998 loc_pSectGenInfo->exData[0].data = &m_temp_ext1[0];
1000 /* Parsing generated packet */
1001 EXPECT_TRUE(xran_parse_cp_pkt(/*m_pTestBuffer*/mbuf, &m_result, &m_pktInfo) == XRAN_STATUS_SUCCESS);
1004 FAIL() << "xran_malloc failed\n";
1007 /* Verify the result */
1011 xran_free(ext_buf_init);
1015 /***************************************************************************
1016 * Functional Test cases
1017 ***************************************************************************/
1019 TEST_P(C_plane, CPacketGen)
1021 /* Configure section information */
1022 if(prepare_sections() < 0) {
1023 FAIL() << "Invalid Section configuration\n";
1025 if(prepare_extensions() < 0) {
1026 FAIL() << "Invalid Section extension configuration\n";
1029 if(m_extcfgs[0].type == XRAN_CP_SECTIONEXTCMD_1) {
1033 else if(m_extcfgs[0].type == XRAN_CP_SECTIONEXTCMD_11) {
1034 /* use large buffer to linearize external buffer for parsing */
1035 m_pTestBuffer = xran_ethdi_mbuf_alloc();
1036 ASSERT_FALSE(m_pTestBuffer == nullptr);
1038 if(xran_cp_attach_ext_buf(m_pTestBuffer,
1040 m_extcfgs[0].u.ext11.maxExtBufSize,
1041 &m_extSharedInfo) < 0) {
1042 rte_pktmbuf_free(m_pTestBuffer);
1043 m_pTestBuffer = nullptr;
1044 FAIL() << "Failed to attach external buffer !!\n";
1046 rte_mbuf_ext_refcnt_update(&m_extSharedInfo, 0);
1050 if(m_pTestBuffer == nullptr) {
1051 m_pTestBuffer = xran_ethdi_mbuf_alloc();
1052 ASSERT_FALSE(m_pTestBuffer == nullptr);
1055 /* Generating C-Plane packet */
1056 ASSERT_TRUE(xran_prepare_ctrl_pkt(m_pTestBuffer, &m_params, m_ccId, m_antId, m_seqId) == XRAN_STATUS_SUCCESS);
1058 /* Linearize data in the chain of mbufs to parse generated packet*/
1059 ASSERT_TRUE(rte_pktmbuf_linearize(m_pTestBuffer) == 0);
1061 /* Parsing generated packet */
1062 EXPECT_TRUE(xran_parse_cp_pkt(m_pTestBuffer, &m_result, &m_pktInfo) == XRAN_STATUS_SUCCESS);
1064 /* Verify the result */
1068 /***************************************************************************
1069 * Performance Test cases
1070 ***************************************************************************/
1072 TEST_P(C_plane, Perf)
1074 /* Configure section information */
1075 if(prepare_sections() < 0) {
1076 FAIL() << "Invalid Section configuration\n";
1078 if(prepare_extensions() < 0) {
1079 FAIL() << "Invalid Section extension configuration\n";
1082 /* using wrapper function to reset mbuf */
1083 performance("C", module_name,
1084 &xran_ut_prepare_cp, &m_params, m_ccId, m_antId, m_seqId);
1089 INSTANTIATE_TEST_CASE_P(UnitTest, C_plane,
1090 testing::ValuesIn(get_sequence(C_plane::get_number_of_cases("C_Plane"))));