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 *******************************************************************************/
23 * @brief XRAN layer common functionality for both lls-CU and RU as well as C-plane and
26 * @ingroup group_source_xran
27 * @author Intel Corporation
32 #include <arpa/inet.h>
36 #include "xran_common.h"
39 #include "xran_pkt_up.h"
40 #include "xran_cp_api.h"
41 #include "xran_up_api.h"
42 #include "../src/xran_printf.h"
45 #include "mlog_lnx_xRAN.h"
52 extern int xran_process_rx_sym(void *arg,
63 int process_mbuf(struct rte_mbuf *pkt)
66 struct ecpri_seq_id seq;
67 static int symbol_total_bytes = 0;
69 struct xran_ethdi_ctx *const ctx = xran_ethdi_get_ctx();
73 uint8_t subframe_id = 0;
77 num_bytes = xran_extract_iq_samples(pkt,
89 symbol_total_bytes += num_bytes;
92 print_dbg("Completed receiving symbol %d, size=%d bytes\n",
93 symb_id, symbol_total_bytes);
95 if (symbol_total_bytes)
96 xran_process_rx_sym(NULL,
105 symbol_total_bytes = 0;
111 static int set_iq_bit_width(uint8_t iq_bit_width, struct data_section_compression_hdr *compr_hdr)
113 if (iq_bit_width == MAX_IQ_BIT_WIDTH)
114 compr_hdr->ud_comp_hdr.ud_iq_width = (uint8_t) 0;
116 compr_hdr->ud_comp_hdr.ud_iq_width = iq_bit_width;
122 /* Send a single 5G symbol over multiple packets */
123 int send_symbol_ex(enum xran_pkt_dir direction,
136 const int n_bytes = prb_num * N_SC_PER_PRB * sizeof(struct rb_map);
139 struct xran_up_pkt_gen_no_compression_params xp = { 0 };
141 /* radio app header */
142 xp.app_params.data_direction = direction;
143 xp.app_params.payl_ver = 1;
144 xp.app_params.filter_id = 0;
145 xp.app_params.frame_id = frame_id;
146 xp.app_params.sf_slot_sym.subframe_id = subframe_id;
147 xp.app_params.sf_slot_sym.slot_id = slot_id;
148 xp.app_params.sf_slot_sym.symb_id = symbol_no;
150 /* convert to network byte order */
151 xp.app_params.sf_slot_sym.value = rte_cpu_to_be_16(xp.app_params.sf_slot_sym.value);
153 xp.sec_hdr.fields.sect_id = section_id;
154 xp.sec_hdr.fields.num_prbu = (uint8_t)prb_num;
155 xp.sec_hdr.fields.start_prbu = (uint8_t)prb_start;
156 xp.sec_hdr.fields.sym_inc = 0;
157 xp.sec_hdr.fields.rb = 0;
159 /* network byte order */
160 xp.sec_hdr.fields.all_bits = rte_cpu_to_be_32(xp.sec_hdr.fields.all_bits);
162 struct rte_mbuf *mb = xran_ethdi_mbuf_alloc();
166 errx(1, "out of mbufs after %d packets", 1);
169 sent = xran_prepare_iq_symbol_portion_no_comp(mb,
177 errx(1, "failed preparing symbol");
179 xran_ethdi_mbuf_send(mb, ETHER_TYPE_ECPRI);
182 printf("Symbol %2d sent (%d packets, %d bytes)\n", symbol_no, i, n_bytes);
188 int send_cpmsg_dlul(void *pHandle, enum xran_pkt_dir dir,
189 uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id,
190 uint8_t startsym, uint8_t numsym, int prb_num,
192 uint8_t cc_id, uint8_t ru_port_id,
195 struct xran_cp_gen_params params;
196 struct xran_section_gen_info sect_geninfo[XRAN_MAX_NUM_SECTIONS];
197 struct rte_mbuf *mbuf;
198 int ret, nsection, i;
202 params.sectionType = XRAN_CP_SECTIONTYPE_1; // Most DL/UL Radio Channels
203 params.hdr.filterIdx = XRAN_FILTERINDEX_STANDARD;
204 params.hdr.frameId = frame_id;
205 params.hdr.subframeId = subframe_id;
206 params.hdr.slotId = slot_id;
207 params.hdr.startSymId = startsym; // start Symbol ID
208 params.hdr.iqWidth = xran_get_conf_iqwidth(pHandle);
209 params.hdr.compMeth = xran_get_conf_compmethod(pHandle);
212 sect_geninfo[nsection].info.type = params.sectionType;
213 sect_geninfo[nsection].info.id = xran_alloc_sectionid(pHandle, dir, cc_id, ru_port_id, slot_id);
214 sect_geninfo[nsection].info.rb = XRAN_RBIND_EVERY;
215 sect_geninfo[nsection].info.symInc = XRAN_SYMBOLNUMBER_NOTINC;
216 sect_geninfo[nsection].info.startPrbc = 0;
217 sect_geninfo[nsection].info.numPrbc = NUM_OF_PRB_IN_FULL_BAND,
218 sect_geninfo[nsection].info.numSymbol = numsym;
219 sect_geninfo[nsection].info.reMask = 0xfff;
220 sect_geninfo[nsection].info.beamId = beam_id;
222 sect_geninfo[nsection].info.ef = 0; // no extension
223 sect_geninfo[nsection].exDataSize = 0;
224 sect_geninfo[nsection].exData = NULL;
227 params.numSections = nsection;
228 params.sections = sect_geninfo;
230 mbuf = xran_ethdi_mbuf_alloc();
231 if(unlikely(mbuf == NULL)) {
232 print_err("Alloc fail!\n");
236 ret = xran_prepare_ctrl_pkt(mbuf, ¶ms, cc_id, ru_port_id, seq_id);
238 print_err("Fail to build control plane packet - [%d:%d:%d] dir=%d\n",
239 frame_id, subframe_id, slot_id, dir);
242 xran_ethdi_mbuf_send_cp(mbuf, ETHER_TYPE_ECPRI);
243 for(i=0; i<nsection; i++)
244 xran_cp_add_section_info(pHandle,
245 dir, cc_id, ru_port_id, subframe_id, slot_id,
246 §_geninfo[i].info);
252 int send_cpmsg_prach(void *pHandle,
253 uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id,
254 uint16_t beam_id, uint8_t cc_id, uint8_t prach_port_id,
257 struct xran_cp_gen_params params;
258 struct xran_section_gen_info sect_geninfo[8];
259 struct rte_mbuf *mbuf;
260 int i, nsection, ret;
261 struct xran_lib_ctx *pxran_lib_ctx = xran_lib_get_ctx();
262 xRANPrachCPConfigStruct *pPrachCPConfig = &(pxran_lib_ctx->PrachCPConfig);
265 printf("%d:%d:%d:%d - filter=%d, startSym=%d[%d:%d], numSym=%d, occasions=%d, freqOff=%d\n",
266 frame_id, subframe_id, slot_id, prach_port_id,
267 pPrachCPConfig->filterIdx,
268 pPrachCPConfig->startSymId,
269 pPrachCPConfig->startPrbc,
270 pPrachCPConfig->numPrbc,
271 pPrachCPConfig->numSymbol,
272 pPrachCPConfig->occassionsInPrachSlot,
273 pPrachCPConfig->freqOffset);
276 params.dir = XRAN_DIR_UL;
277 params.sectionType = XRAN_CP_SECTIONTYPE_3;
278 params.hdr.filterIdx = pPrachCPConfig->filterIdx;
279 params.hdr.frameId = frame_id;
280 params.hdr.subframeId = subframe_id;
281 params.hdr.slotId = slot_id;
282 params.hdr.startSymId = pPrachCPConfig->startSymId;
283 params.hdr.iqWidth = xran_get_conf_iqwidth(pHandle);
284 params.hdr.compMeth = xran_get_conf_compmethod(pHandle);
285 /* use timeOffset field for the CP length value for prach sequence */
286 params.hdr.timeOffset = pPrachCPConfig->timeOffset;
287 params.hdr.fftSize = xran_get_conf_fftsize(pHandle);
288 params.hdr.scs = xran_get_conf_prach_scs(pHandle);
289 params.hdr.cpLength = 0;
292 sect_geninfo[nsection].info.type = params.sectionType;
293 sect_geninfo[nsection].info.id = xran_alloc_sectionid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id, slot_id);
294 sect_geninfo[nsection].info.rb = XRAN_RBIND_EVERY;
295 sect_geninfo[nsection].info.symInc = XRAN_SYMBOLNUMBER_NOTINC;
296 sect_geninfo[nsection].info.startPrbc = pPrachCPConfig->startPrbc;
297 sect_geninfo[nsection].info.numPrbc = pPrachCPConfig->numPrbc,
298 sect_geninfo[nsection].info.numSymbol = pPrachCPConfig->numSymbol*pPrachCPConfig->occassionsInPrachSlot;
299 sect_geninfo[nsection].info.reMask = 0xfff;
300 sect_geninfo[nsection].info.beamId = beam_id;
301 sect_geninfo[nsection].info.freqOffset= pPrachCPConfig->freqOffset;
303 sect_geninfo[nsection].info.ef = 0; // no extension
304 sect_geninfo[nsection].exDataSize = 0;
305 sect_geninfo[nsection].exData = NULL;
308 params.numSections = nsection;
309 params.sections = sect_geninfo;
311 mbuf = xran_ethdi_mbuf_alloc();
312 if(unlikely(mbuf == NULL)) {
313 print_err("Alloc fail!\n");
317 ret = xran_prepare_ctrl_pkt(mbuf, ¶ms, cc_id, prach_port_id, seq_id);
319 print_err("Fail to build prach control packet - [%d:%d:%d]\n", frame_id, subframe_id, slot_id);
323 xran_ethdi_mbuf_send_cp(mbuf, ETHER_TYPE_ECPRI);
324 for(i=0; i < nsection; i++)
325 xran_cp_add_section_info(pHandle,
326 XRAN_DIR_UL, cc_id, prach_port_id, subframe_id, slot_id,
327 §_geninfo[i].info);
334 int process_ring(struct rte_ring *r)
338 struct rte_mbuf *mbufs[MBUFS_CNT];
341 const uint16_t dequeued = rte_ring_dequeue_burst(r, (void **)mbufs,
342 RTE_DIM(mbufs), &remaining);
346 for (i = 0; i < dequeued; ++i) {
347 if (xran_ethdi_filter_packet(mbufs[i], 0) == MBUF_FREE)
348 rte_pktmbuf_free(mbufs[i]);
354 int ring_processing_thread(void *args)
356 struct timespec tv = {0};
357 int64_t prev_nsec = 0;
358 uint8_t is_timer_set = 0;
359 struct xran_ethdi_ctx *const ctx = xran_ethdi_get_ctx();
360 struct sched_param sched_param;
363 printf("%s [CPU %2d] [PID: %6d]\n", __FUNCTION__, rte_lcore_id(), getpid());
364 sched_param.sched_priority = XRAN_THREAD_DEFAULT_PRIO;
365 if ((res = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sched_param)))
367 printf("priority is not changed: coreId = %d, result1 = %d\n",rte_lcore_id(), res);
371 if (clock_gettime(CLOCK_REALTIME, &tv) != 0)
372 err(1, "gettimeofday() failed");
373 if (tv.tv_nsec % 125000 < prev_nsec % 125000) { /* crossed an 125ms boundary */
374 rte_timer_manage(); /* timers only run on IO core */
377 prev_nsec = tv.tv_nsec;
383 if (process_ring(ctx->rx_ring[ETHDI_UP_VF]))
386 if (process_ring(ctx->rx_ring[ETHDI_CP_VF]))
389 if (XRAN_STOPPED == xran_if_current_state)
393 puts("Pkt processing thread finished.");
397 #endif /* _XRAN_COMMON_ */