164c1f6178149e437c59a5a029cd7b0e4b2c1f77
[o-du/phy.git] / fhi_lib / lib / src / xran_common.c
1 /******************************************************************************\r
2 *\r
3 *   Copyright (c) 2019 Intel.\r
4 *\r
5 *   Licensed under the Apache License, Version 2.0 (the "License");\r
6 *   you may not use this file except in compliance with the License.\r
7 *   You may obtain a copy of the License at\r
8 *\r
9 *       http://www.apache.org/licenses/LICENSE-2.0\r
10 *\r
11 *   Unless required by applicable law or agreed to in writing, software\r
12 *   distributed under the License is distributed on an "AS IS" BASIS,\r
13 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
14 *   See the License for the specific language governing permissions and\r
15 *   limitations under the License.\r
16 *\r
17 *******************************************************************************/\r
18 \r
19 /**\r
20  * @brief XRAN layer common functionality for both O-DU and O-RU as well as C-plane and\r
21  *    U-plane\r
22  * @file xran_common.c\r
23  * @ingroup group_source_xran\r
24  * @author Intel Corporation\r
25  **/\r
26 \r
27 #include <assert.h>\r
28 #include <err.h>\r
29 #include <arpa/inet.h>\r
30 #include <sys/time.h>\r
31 #include <time.h>\r
32 \r
33 #include "xran_common.h"\r
34 #include "ethdi.h"\r
35 #include "xran_pkt.h"\r
36 #include "xran_pkt_up.h"\r
37 #include "xran_up_api.h"\r
38 #include "xran_lib_mlog_tasks_id.h"\r
39 \r
40 #include "../src/xran_printf.h"\r
41 #include <rte_mbuf.h>\r
42 #include "xran_mlog_lnx.h"\r
43 \r
44 #define MBUFS_CNT 16\r
45 \r
46 extern long interval_us;\r
47 \r
48 extern int xran_process_rx_sym(void *arg,\r
49                         struct rte_mbuf *mbuf,\r
50                         void *iq_data_start,\r
51                         uint16_t size,\r
52                         uint8_t CC_ID,\r
53                         uint8_t Ant_ID,\r
54                         uint8_t frame_id,\r
55                         uint8_t subframe_id,\r
56                         uint8_t slot_id,\r
57                         uint8_t symb_id,\r
58                         uint16_t num_prbu,\r
59                         uint16_t start_prbu,\r
60                         uint16_t sym_inc,\r
61                         uint16_t rb,\r
62                         uint16_t sect_id,\r
63                         uint32_t *mb_free);\r
64 \r
65 \r
66 extern int xran_process_prach_sym(void *arg,\r
67                         struct rte_mbuf *mbuf,\r
68                         void *iq_data_start,\r
69                         uint16_t size,\r
70                         uint8_t CC_ID,\r
71                         uint8_t Ant_ID,\r
72                         uint8_t frame_id,\r
73                         uint8_t subframe_id,\r
74                         uint8_t slot_id,\r
75                         uint8_t symb_id,\r
76                         uint16_t num_prbu,\r
77                         uint16_t start_prbu,\r
78                         uint16_t sym_inc,\r
79                         uint16_t rb,\r
80                         uint16_t sect_id,\r
81                         uint32_t *mb_free);\r
82 \r
83 extern int32_t xran_process_srs_sym(void *arg,\r
84                         struct rte_mbuf *mbuf,\r
85                         void *iq_data_start,\r
86                         uint16_t size,\r
87                         uint8_t CC_ID,\r
88                         uint8_t Ant_ID,\r
89                         uint8_t frame_id,\r
90                         uint8_t subframe_id,\r
91                         uint8_t slot_id,\r
92                         uint8_t symb_id,\r
93                         uint16_t num_prbu,\r
94                         uint16_t start_prbu,\r
95                         uint16_t sym_inc,\r
96                         uint16_t rb,\r
97                         uint16_t sect_id,\r
98                         uint32_t *mb_free);\r
99 \r
100 extern int32_t xran_pkt_validate(void *arg,\r
101                         struct rte_mbuf *mbuf,\r
102                         void *iq_data_start,\r
103                         uint16_t size,\r
104                         uint8_t CC_ID,\r
105                         uint8_t Ant_ID,\r
106                         uint8_t frame_id,\r
107                         uint8_t subframe_id,\r
108                         uint8_t slot_id,\r
109                         uint8_t symb_id,\r
110                         struct ecpri_seq_id *seq_id,\r
111                         uint16_t num_prbu,\r
112                         uint16_t start_prbu,\r
113                         uint16_t sym_inc,\r
114                         uint16_t rb,\r
115                         uint16_t sect_id);\r
116 \r
117 long rx_counter = 0;\r
118 long tx_counter = 0;\r
119 long tx_bytes_counter = 0;\r
120 long rx_bytes_counter = 0;\r
121 long tx_bytes_per_sec = 0;\r
122 long rx_bytes_per_sec = 0;\r
123 \r
124 \r
125 struct cb_elem_entry *xran_create_cb(XranSymCallbackFn cb_fn, void *cb_data)\r
126 {\r
127         struct cb_elem_entry * cb_elm = (struct cb_elem_entry *)malloc(sizeof(struct cb_elem_entry));\r
128         if(cb_elm){\r
129             cb_elm->pSymCallback    = cb_fn;\r
130             cb_elm->pSymCallbackTag = cb_data;\r
131         }\r
132 \r
133         return cb_elm;\r
134 }\r
135 \r
136 int xran_destroy_cb(struct cb_elem_entry * cb_elm)\r
137 {\r
138     if(cb_elm)\r
139         free(cb_elm);\r
140     return 0;\r
141 }\r
142 \r
143 int process_mbuf(struct rte_mbuf *pkt)\r
144 {\r
145     void *iq_samp_buf;\r
146     struct ecpri_seq_id seq;\r
147     static int symbol_total_bytes = 0;\r
148     int num_bytes = 0;\r
149     struct xran_device_ctx * p_x_ctx = xran_dev_get_ctx();\r
150 \r
151     uint8_t CC_ID = 0;\r
152     uint8_t Ant_ID = 0;\r
153     uint8_t frame_id = 0;\r
154     uint8_t subframe_id = 0;\r
155     uint8_t slot_id = 0;\r
156     uint8_t symb_id = 0;\r
157 \r
158     uint16_t num_prbu;\r
159     uint16_t start_prbu;\r
160     uint16_t sym_inc;\r
161     uint16_t rb;\r
162     uint16_t sect_id;\r
163 \r
164     uint8_t compMeth = 0;\r
165     uint8_t iqWidth = 0;\r
166 \r
167     void *pHandle = NULL;\r
168     uint8_t num_eAxc = xran_get_num_eAxc(pHandle);\r
169     int ret = MBUF_FREE;\r
170     uint32_t mb_free = 0;\r
171     int32_t valid_res = 0;\r
172     int expect_comp  = (p_x_ctx->fh_cfg.ru_conf.compMeth != XRAN_COMPMETHOD_NONE);\r
173 \r
174 \r
175     if(p_x_ctx->xran2phy_mem_ready == 0)\r
176         return MBUF_FREE;\r
177 \r
178     num_bytes = xran_extract_iq_samples(pkt,\r
179                                         &iq_samp_buf,\r
180                                         &CC_ID,\r
181                                         &Ant_ID,\r
182                                         &frame_id,\r
183                                         &subframe_id,\r
184                                         &slot_id,\r
185                                         &symb_id,\r
186                                         &seq,\r
187                                         &num_prbu,\r
188                                         &start_prbu,\r
189                                         &sym_inc,\r
190                                         &rb,\r
191                                         &sect_id,\r
192                                         expect_comp,\r
193                                         &compMeth,\r
194                                         &iqWidth);\r
195     if (num_bytes <= 0){\r
196         print_err("num_bytes is wrong [%d]\n", num_bytes);\r
197         return MBUF_FREE;\r
198     }\r
199 \r
200     valid_res = xran_pkt_validate(NULL,\r
201                                 pkt,\r
202                                 iq_samp_buf,\r
203                                 num_bytes,\r
204                                 CC_ID,\r
205                                 Ant_ID,\r
206                                 frame_id,\r
207                                 subframe_id,\r
208                                 slot_id,\r
209                                 symb_id,\r
210                                 &seq,\r
211                                 num_prbu,\r
212                                 start_prbu,\r
213                                 sym_inc,\r
214                                 rb,\r
215                                 sect_id);\r
216 \r
217     if(valid_res != 0) {\r
218         print_err("valid_res is wrong [%d] ant %u (%u : %u : %u : %u) seq %u num_bytes %d\n", valid_res, Ant_ID, frame_id, subframe_id, slot_id, symb_id, seq.seq_id, num_bytes);\r
219         return MBUF_FREE;\r
220     }\r
221 \r
222     if (Ant_ID >= p_x_ctx->srs_cfg.eAxC_offset && p_x_ctx->fh_init.srsEnable) {\r
223         /* SRS packet has ruportid = 2*num_eAxc + ant_id */\r
224         Ant_ID -= p_x_ctx->srs_cfg.eAxC_offset;\r
225         symbol_total_bytes += num_bytes;\r
226 \r
227         if (seq.e_bit == 1) {\r
228             print_dbg("Completed receiving symbol %d, size=%d bytes\n",\r
229                 symb_id, symbol_total_bytes);\r
230 \r
231             if (symbol_total_bytes) {\r
232                int16_t res = xran_process_srs_sym(NULL,\r
233                                 pkt,\r
234                                 iq_samp_buf,\r
235                                 num_bytes,\r
236                                 CC_ID,\r
237                                 Ant_ID,\r
238                                 frame_id,\r
239                                 subframe_id,\r
240                                 slot_id,\r
241                                 symb_id,\r
242                                 num_prbu,\r
243                                 start_prbu,\r
244                                 sym_inc,\r
245                                 rb,\r
246                                 sect_id,\r
247                                 &mb_free);\r
248 \r
249                 if(res == symbol_total_bytes) {\r
250                     ret = mb_free;\r
251                 } else {\r
252                     print_err("res != symbol_total_bytes\n");\r
253                 }\r
254             }\r
255             symbol_total_bytes = 0;\r
256         }\r
257         else {\r
258             print_dbg("Transport layer fragmentation (eCPRI) is not supported\n");\r
259         }\r
260 \r
261     } else if (Ant_ID >= p_x_ctx->PrachCPConfig.eAxC_offset && p_x_ctx->fh_init.prachEnable) {\r
262         /* PRACH packet has ruportid = num_eAxc + ant_id */\r
263         Ant_ID -= p_x_ctx->PrachCPConfig.eAxC_offset;\r
264         symbol_total_bytes += num_bytes;\r
265         if (seq.e_bit == 1) {\r
266             print_dbg("Completed receiving PRACH symbol %d, size=%d bytes\n",\r
267                 symb_id, num_bytes);\r
268 \r
269             if (symbol_total_bytes) {\r
270                 int16_t res =  xran_process_prach_sym(NULL,\r
271                                                       pkt,\r
272                                                       iq_samp_buf,\r
273                                                       num_bytes,\r
274                                                       CC_ID,\r
275                                                       Ant_ID,\r
276                                                       frame_id,\r
277                                                       subframe_id,\r
278                                                       slot_id,\r
279                                                       symb_id,\r
280                                                       num_prbu,\r
281                                                       start_prbu,\r
282                                                       sym_inc,\r
283                                                       rb,\r
284                                                       sect_id,\r
285                                                       &mb_free);\r
286                 if(res == symbol_total_bytes) {\r
287                     ret = mb_free;\r
288                 } else {\r
289                     print_err("res != symbol_total_bytes\n");\r
290                 }\r
291             }\r
292             symbol_total_bytes = 0;\r
293         } else {\r
294             print_dbg("Transport layer fragmentation (eCPRI) is not supported\n");\r
295         }\r
296 \r
297     } else { /* PUSCH */\r
298         symbol_total_bytes += num_bytes;\r
299 \r
300         if (seq.e_bit == 1) {\r
301             print_dbg("Completed receiving symbol %d, size=%d bytes\n",\r
302                 symb_id, symbol_total_bytes);\r
303 \r
304             if (symbol_total_bytes) {\r
305                 int res = xran_process_rx_sym(NULL,\r
306                                 pkt,\r
307                                 iq_samp_buf,\r
308                                 symbol_total_bytes,\r
309                                 CC_ID,\r
310                                 Ant_ID,\r
311                                 frame_id,\r
312                                 subframe_id,\r
313                                 slot_id,\r
314                                 symb_id,\r
315                                 num_prbu,\r
316                                 start_prbu,\r
317                                 sym_inc,\r
318                                 rb,\r
319                                 sect_id,\r
320                                 &mb_free);\r
321                 if(res == symbol_total_bytes) {\r
322                     ret = mb_free;\r
323                 } else {\r
324                     print_err("res != symbol_total_bytes\n");\r
325                 }\r
326             }\r
327             symbol_total_bytes = 0;\r
328         } else {\r
329             print_dbg("Transport layer fragmentation (eCPRI) is not supported\n");\r
330         }\r
331     }\r
332 \r
333     return ret;\r
334 }\r
335 \r
336 static int set_iq_bit_width(uint8_t iq_bit_width, struct data_section_compression_hdr *compr_hdr)\r
337 {\r
338     if (iq_bit_width == MAX_IQ_BIT_WIDTH)\r
339         compr_hdr->ud_comp_hdr.ud_iq_width = (uint8_t) 0;\r
340     else\r
341         compr_hdr->ud_comp_hdr.ud_iq_width = iq_bit_width;\r
342 \r
343     return  0;\r
344 \r
345 }\r
346 \r
347 /* Send a single 5G symbol over multiple packets */\r
348 int32_t prepare_symbol_ex(enum xran_pkt_dir direction,\r
349                 uint16_t section_id,\r
350                 struct rte_mbuf *mb,\r
351                 struct rb_map *data,\r
352                 uint8_t     compMeth,\r
353                 uint8_t     iqWidth,\r
354                 const enum xran_input_byte_order iq_buf_byte_order,\r
355                 uint8_t frame_id,\r
356                 uint8_t subframe_id,\r
357                 uint8_t slot_id,\r
358                 uint8_t symbol_no,\r
359                 int prb_start,\r
360                 int prb_num,\r
361                 uint8_t CC_ID,\r
362                 uint8_t RU_Port_ID,\r
363                 uint8_t seq_id,\r
364                 uint32_t do_copy)\r
365 {\r
366     int32_t n_bytes = ((prb_num == 0) ? MAX_N_FULLBAND_SC : prb_num) * N_SC_PER_PRB * sizeof(struct rb_map);\r
367 \r
368     n_bytes  =   ((iqWidth == 0) || (iqWidth == 16)) ? n_bytes : ((3 * iqWidth + 1 ) * prb_num);\r
369 \r
370     int32_t prep_bytes;\r
371 \r
372     int16_t nPktSize = sizeof(struct ether_hdr) + sizeof(struct xran_ecpri_hdr) +\r
373             sizeof(struct radio_app_common_hdr)+ sizeof(struct data_section_hdr) + n_bytes;\r
374     uint32_t off;\r
375     struct xran_up_pkt_gen_params xp = { 0 };\r
376 \r
377     if(compMeth != XRAN_COMPMETHOD_NONE)\r
378         nPktSize += sizeof(struct data_section_compression_hdr);\r
379 \r
380     n_bytes = RTE_MIN(n_bytes, XRAN_MAX_MBUF_LEN);\r
381 \r
382     /* radio app header */\r
383     xp.app_params.data_direction = direction;\r
384     xp.app_params.payl_ver       = 1;\r
385     xp.app_params.filter_id      = 0;\r
386     xp.app_params.frame_id       = frame_id;\r
387     xp.app_params.sf_slot_sym.subframe_id    = subframe_id;\r
388     xp.app_params.sf_slot_sym.slot_id        = slot_id;\r
389     xp.app_params.sf_slot_sym.symb_id        = symbol_no;\r
390 \r
391     /* convert to network byte order */\r
392     xp.app_params.sf_slot_sym.value = rte_cpu_to_be_16(xp.app_params.sf_slot_sym.value);\r
393 \r
394     xp.sec_hdr.fields.sect_id    = section_id;\r
395     xp.sec_hdr.fields.num_prbu   = (uint8_t)prb_num;\r
396     xp.sec_hdr.fields.start_prbu = (uint8_t)prb_start;\r
397     xp.sec_hdr.fields.sym_inc    = 0;\r
398     xp.sec_hdr.fields.rb         = 0;\r
399 \r
400     /* compression */\r
401     xp.compr_hdr_param.ud_comp_hdr.ud_comp_meth = compMeth;\r
402     xp.compr_hdr_param.ud_comp_hdr.ud_iq_width  = iqWidth;\r
403     xp.compr_hdr_param.rsrvd                    = 0;\r
404 \r
405     /* network byte order */\r
406     xp.sec_hdr.fields.all_bits  = rte_cpu_to_be_32(xp.sec_hdr.fields.all_bits);\r
407 \r
408     if (mb == NULL){\r
409         MLogPrint(NULL);\r
410         errx(1, "out of mbufs after %d packets", 1);\r
411     }\r
412 \r
413     prep_bytes = xran_prepare_iq_symbol_portion(mb,\r
414                                                   data,\r
415                                                   iq_buf_byte_order,\r
416                                                   n_bytes,\r
417                                                   &xp,\r
418                                                   CC_ID,\r
419                                                   RU_Port_ID,\r
420                                                   seq_id,\r
421                                                   do_copy);\r
422     if (prep_bytes <= 0)\r
423         errx(1, "failed preparing symbol");\r
424 \r
425     rte_pktmbuf_pkt_len(mb)  = nPktSize;\r
426     rte_pktmbuf_data_len(mb) = nPktSize;\r
427 \r
428 #ifdef DEBUG\r
429     printf("Symbol %2d prep_bytes (%d packets, %d bytes)\n", symbol_no, i, n_bytes);\r
430 #endif\r
431 \r
432     return prep_bytes;\r
433 }\r
434 \r
435 /* Send a single 5G symbol over multiple packets */\r
436 int send_symbol_ex(enum xran_pkt_dir direction,\r
437                 uint16_t section_id,\r
438                 struct rte_mbuf *mb,\r
439                 struct rb_map *data,\r
440                 const enum xran_input_byte_order iq_buf_byte_order,\r
441                 uint8_t frame_id,\r
442                 uint8_t subframe_id,\r
443                 uint8_t slot_id,\r
444                 uint8_t symbol_no,\r
445                 int prb_start,\r
446                 int prb_num,\r
447                 uint8_t CC_ID,\r
448                 uint8_t RU_Port_ID,\r
449                 uint8_t seq_id)\r
450 {\r
451     uint32_t do_copy = 0;\r
452     int32_t n_bytes = ((prb_num == 0) ? MAX_N_FULLBAND_SC : prb_num) * N_SC_PER_PRB * sizeof(struct rb_map);\r
453     struct xran_device_ctx *p_x_ctx = xran_dev_get_ctx();\r
454 \r
455     if (mb == NULL){\r
456         char * pChar = NULL;\r
457         mb = xran_ethdi_mbuf_alloc(); /* will be freede by ETH */\r
458         if(mb ==  NULL){\r
459             MLogPrint(NULL);\r
460             errx(1, "out of mbufs after %d packets", 1);\r
461         }\r
462         pChar = rte_pktmbuf_append(mb, sizeof(struct xran_ecpri_hdr)+ sizeof(struct radio_app_common_hdr)+ sizeof(struct data_section_hdr) + n_bytes);\r
463         if(pChar == NULL){\r
464                 MLogPrint(NULL);\r
465                 errx(1, "incorrect mbuf size %d packets", 1);\r
466         }\r
467         pChar = rte_pktmbuf_prepend(mb, sizeof(struct ether_hdr));\r
468         if(pChar == NULL){\r
469                 MLogPrint(NULL);\r
470                 errx(1, "incorrect mbuf size %d packets", 1);\r
471         }\r
472         do_copy = 1; /* new mbuf hence copy of IQs  */\r
473     }else {\r
474         rte_pktmbuf_refcnt_update(mb, 1); /* make sure eth won't free our mbuf */\r
475     }\r
476 \r
477     int32_t sent = prepare_symbol_ex(direction,\r
478                          section_id,\r
479                          mb,\r
480                          data,\r
481                          0,\r
482                          16,\r
483                          iq_buf_byte_order,\r
484                          frame_id,\r
485                          subframe_id,\r
486                          slot_id,\r
487                          symbol_no,\r
488                          prb_start,\r
489                          prb_num,\r
490                          CC_ID,\r
491                          RU_Port_ID,\r
492                          seq_id,\r
493                          do_copy);\r
494 \r
495     if(sent){\r
496         tx_counter++;\r
497         tx_bytes_counter += rte_pktmbuf_pkt_len(mb);\r
498         p_x_ctx->send_upmbuf2ring(mb, ETHER_TYPE_ECPRI);\r
499     } else {\r
500 \r
501     }\r
502 \r
503 #ifdef DEBUG\r
504     printf("Symbol %2d sent (%d packets, %d bytes)\n", symbol_no, i, n_bytes);\r
505 #endif\r
506 \r
507     return sent;\r
508 }\r
509 \r
510 int send_cpmsg(void *pHandle, struct rte_mbuf *mbuf,struct xran_cp_gen_params *params,\r
511                 struct xran_section_gen_info *sect_geninfo, uint8_t cc_id, uint8_t ru_port_id, uint8_t seq_id)\r
512 {\r
513     int ret = 0, nsection, i;\r
514     uint8_t frame_id = params->hdr.frameId;\r
515     uint8_t subframe_id = params->hdr.subframeId;\r
516     uint8_t slot_id = params->hdr.slotId;\r
517     uint8_t dir = params->dir;\r
518     struct xran_device_ctx *p_x_ctx = xran_dev_get_ctx();\r
519 \r
520     nsection = params->numSections;\r
521 \r
522     /* add in the ethernet header */\r
523     struct ether_hdr *const h = (void *)rte_pktmbuf_prepend(mbuf, sizeof(*h));\r
524     tx_counter++;\r
525     tx_bytes_counter += rte_pktmbuf_pkt_len(mbuf);\r
526     p_x_ctx->send_cpmbuf2ring(mbuf, ETHER_TYPE_ECPRI);\r
527     for(i=0; i<nsection; i++)\r
528         xran_cp_add_section_info(pHandle, dir, cc_id, ru_port_id,\r
529                 (slot_id + subframe_id*SLOTNUM_PER_SUBFRAME)%XRAN_MAX_SECTIONDB_CTX,\r
530                 &sect_geninfo[i].info);\r
531 \r
532     return (ret);\r
533 }\r
534 \r
535 int generate_cpmsg_dlul(void *pHandle, struct xran_cp_gen_params *params, struct xran_section_gen_info *sect_geninfo, struct rte_mbuf *mbuf,\r
536     enum xran_pkt_dir dir, uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id,\r
537     uint8_t startsym, uint8_t numsym, uint16_t prb_start, uint16_t prb_num,int16_t iq_buffer_offset, int16_t iq_buffer_len,\r
538     uint16_t beam_id, uint8_t cc_id, uint8_t ru_port_id, uint8_t comp_method, uint8_t iqWidth,  uint8_t seq_id, uint8_t symInc)\r
539 {\r
540     int ret = 0, nsection, i, loc_sym;\r
541 \r
542 \r
543     params->dir                  = dir;\r
544     params->sectionType          = XRAN_CP_SECTIONTYPE_1;        // Most DL/UL Radio Channels\r
545     params->hdr.filterIdx        = XRAN_FILTERINDEX_STANDARD;\r
546     params->hdr.frameId          = frame_id;\r
547     params->hdr.subframeId       = subframe_id;\r
548     params->hdr.slotId           = slot_id;\r
549     params->hdr.startSymId       = startsym;                     // start Symbol ID\r
550     params->hdr.iqWidth          = iqWidth;\r
551     params->hdr.compMeth         = comp_method;\r
552 \r
553     nsection = 0;\r
554     sect_geninfo[nsection].info.type        = params->sectionType;       // for database\r
555     sect_geninfo[nsection].info.startSymId  = params->hdr.startSymId;    // for database\r
556     sect_geninfo[nsection].info.iqWidth     = params->hdr.iqWidth;       // for database\r
557     sect_geninfo[nsection].info.compMeth    = params->hdr.compMeth;      // for database\r
558     sect_geninfo[nsection].info.id          = xran_alloc_sectionid(pHandle, dir, cc_id, ru_port_id, slot_id);\r
559     sect_geninfo[nsection].info.rb          = XRAN_RBIND_EVERY;\r
560     sect_geninfo[nsection].info.symInc      = symInc;\r
561     sect_geninfo[nsection].info.startPrbc   = prb_start;\r
562     sect_geninfo[nsection].info.numPrbc     = prb_num;\r
563     sect_geninfo[nsection].info.numSymbol   = numsym;\r
564     sect_geninfo[nsection].info.reMask      = 0xfff;\r
565     sect_geninfo[nsection].info.beamId      = beam_id;\r
566 \r
567     for (loc_sym = 0; loc_sym < XRAN_NUM_OF_SYMBOL_PER_SLOT; loc_sym++) {\r
568         sect_geninfo[0].info.sec_desc[loc_sym].iq_buffer_offset = iq_buffer_offset;\r
569         sect_geninfo[0].info.sec_desc[loc_sym].iq_buffer_len    = iq_buffer_len;\r
570     }\r
571 \r
572     sect_geninfo[nsection].info.ef          = 0;\r
573     sect_geninfo[nsection].exDataSize       = 0;\r
574 //    sect_geninfo[nsection].exData           = NULL;\r
575     nsection++;\r
576 \r
577     params->numSections          = nsection;\r
578     params->sections             = sect_geninfo;\r
579 \r
580     if(unlikely(mbuf == NULL)) {\r
581         print_err("Alloc fail!\n");\r
582         return (-1);\r
583     }\r
584 \r
585     ret = xran_prepare_ctrl_pkt(mbuf, params, cc_id, ru_port_id, seq_id);\r
586     if(ret < 0){\r
587         print_err("Fail to build control plane packet - [%d:%d:%d] dir=%d\n",\r
588                     frame_id, subframe_id, slot_id, dir);\r
589         rte_pktmbuf_free(mbuf);\r
590     }\r
591 \r
592     return (ret);\r
593 }\r
594 \r
595 int generate_cpmsg_prach(void *pHandle, struct xran_cp_gen_params *params, struct xran_section_gen_info *sect_geninfo, struct rte_mbuf *mbuf, struct xran_device_ctx *pxran_lib_ctx,\r
596                 uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id,\r
597                 uint16_t beam_id, uint8_t cc_id, uint8_t prach_port_id, uint8_t seq_id)\r
598 {\r
599     int i, nsection, ret;\r
600     struct xran_prach_cp_config  *pPrachCPConfig = &(pxran_lib_ctx->PrachCPConfig);\r
601     uint16_t timeOffset;\r
602     uint16_t nNumerology = pxran_lib_ctx->fh_cfg.frame_conf.nNumerology;\r
603 \r
604     if(unlikely(mbuf == NULL)) {\r
605         print_err("Alloc fail!\n");\r
606         return (-1);\r
607     }\r
608 #if 0\r
609     printf("%d:%d:%d:%d - filter=%d, startSym=%d[%d:%d], numSym=%d, occasions=%d, freqOff=%d\n",\r
610                 frame_id, subframe_id, slot_id, prach_port_id,\r
611                 pPrachCPConfig->filterIdx,\r
612                 pPrachCPConfig->startSymId,\r
613                 pPrachCPConfig->startPrbc,\r
614                 pPrachCPConfig->numPrbc,\r
615                 pPrachCPConfig->numSymbol,\r
616                 pPrachCPConfig->occassionsInPrachSlot,\r
617                 pPrachCPConfig->freqOffset);\r
618 #endif\r
619     timeOffset = pPrachCPConfig->timeOffset; //this is the CP value per 38.211 tab 6.3.3.1-1&2\r
620     timeOffset = timeOffset >> nNumerology; //original number is Tc, convert to Ts based on mu\r
621     if (pPrachCPConfig->startSymId > 0)\r
622     {\r
623         timeOffset += (pPrachCPConfig->startSymId * 2048) >> nNumerology;\r
624         if ((slot_id == 0) || (slot_id == (SLOTNUM_PER_SUBFRAME >> 1)))\r
625             timeOffset += 16;\r
626     }\r
627     params->dir                  = XRAN_DIR_UL;\r
628     params->sectionType          = XRAN_CP_SECTIONTYPE_3;\r
629     params->hdr.filterIdx        = pPrachCPConfig->filterIdx;\r
630     params->hdr.frameId          = frame_id;\r
631     params->hdr.subframeId       = subframe_id;\r
632     params->hdr.slotId           = slot_id;\r
633     params->hdr.startSymId       = pPrachCPConfig->startSymId;\r
634     params->hdr.iqWidth          = xran_get_conf_iqwidth(pHandle);\r
635     params->hdr.compMeth         = xran_get_conf_compmethod(pHandle);\r
636         /* use timeOffset field for the CP length value for prach sequence */\r
637     params->hdr.timeOffset       = timeOffset;\r
638     params->hdr.fftSize          = xran_get_conf_fftsize(pHandle);\r
639     params->hdr.scs              = xran_get_conf_prach_scs(pHandle);\r
640     params->hdr.cpLength         = 0;\r
641 \r
642     nsection = 0;\r
643     sect_geninfo[nsection].info.type        = params->sectionType;       // for database\r
644     sect_geninfo[nsection].info.startSymId  = params->hdr.startSymId;    // for database\r
645     sect_geninfo[nsection].info.iqWidth     = params->hdr.iqWidth;       // for database\r
646     sect_geninfo[nsection].info.compMeth    = params->hdr.compMeth;      // for database\r
647     sect_geninfo[nsection].info.id          = xran_alloc_sectionid(pHandle, XRAN_DIR_UL, cc_id, prach_port_id, slot_id);\r
648     sect_geninfo[nsection].info.rb          = XRAN_RBIND_EVERY;\r
649     sect_geninfo[nsection].info.symInc      = XRAN_SYMBOLNUMBER_NOTINC;\r
650     sect_geninfo[nsection].info.startPrbc   = pPrachCPConfig->startPrbc;\r
651     sect_geninfo[nsection].info.numPrbc     = pPrachCPConfig->numPrbc,\r
652     sect_geninfo[nsection].info.numSymbol   = pPrachCPConfig->numSymbol*pPrachCPConfig->occassionsInPrachSlot;\r
653     sect_geninfo[nsection].info.reMask      = 0xfff;\r
654     sect_geninfo[nsection].info.beamId      = beam_id;\r
655     sect_geninfo[nsection].info.freqOffset  = pPrachCPConfig->freqOffset;\r
656 \r
657     pxran_lib_ctx->prach_last_symbol[cc_id] = sect_geninfo[nsection].info.startSymId + sect_geninfo[nsection].info.numSymbol - 1;\r
658 \r
659     sect_geninfo[nsection].info.ef          = 0;\r
660     sect_geninfo[nsection].exDataSize       = 0;\r
661 //    sect_geninfo[nsection].exData           = NULL;\r
662     nsection++;\r
663 \r
664     params->numSections          = nsection;\r
665     params->sections             = sect_geninfo;\r
666 \r
667     ret = xran_prepare_ctrl_pkt(mbuf, params, cc_id, prach_port_id, seq_id);\r
668     if(ret < 0){\r
669         print_err("Fail to build prach control packet - [%d:%d:%d]\n", frame_id, subframe_id, slot_id);\r
670         rte_pktmbuf_free(mbuf);\r
671     }\r
672     return ret;\r
673 }\r
674 \r
675 \r
676 int process_ring(struct rte_ring *r)\r
677 {\r
678     assert(r);\r
679 \r
680     struct rte_mbuf *mbufs[MBUFS_CNT];\r
681     int i;\r
682     uint32_t remaining;\r
683     uint64_t t1;\r
684     const uint16_t dequeued = rte_ring_dequeue_burst(r, (void **)mbufs,\r
685         RTE_DIM(mbufs), &remaining);\r
686 \r
687     if (!dequeued)\r
688         return 0;\r
689 \r
690     t1 = MLogTick();\r
691     for (i = 0; i < dequeued; ++i) {\r
692         if (xran_ethdi_filter_packet(mbufs[i], 0) == MBUF_FREE)\r
693             rte_pktmbuf_free(mbufs[i]);\r
694     }\r
695     MLogTask(PID_PROCESS_UP_PKT, t1, MLogTick());\r
696 \r
697     return remaining;\r
698 }\r
699 \r
700 int32_t ring_processing_func(void)\r
701 {\r
702     struct xran_ethdi_ctx *const ctx = xran_ethdi_get_ctx();\r
703     struct xran_device_ctx *const pxran_lib_ctx = xran_dev_get_ctx();\r
704     int16_t retPoll = 0;\r
705     uint64_t t1, t2;\r
706 \r
707     rte_timer_manage();\r
708 \r
709     /* UP first */\r
710     if (process_ring(ctx->rx_ring[ETHDI_UP_VF]))\r
711         return 0;\r
712     /* CP next */\r
713     if (process_ring(ctx->rx_ring[ETHDI_CP_VF]))\r
714         return 0;\r
715 \r
716     if (pxran_lib_ctx->bbdev_dec) {\r
717         t1 = MLogTick();\r
718         retPoll = pxran_lib_ctx->bbdev_dec();\r
719         if (retPoll != -1)\r
720         {\r
721             t2 = MLogTick();\r
722             MLogTask(PID_XRAN_BBDEV_UL_POLL + retPoll, t1, t2);\r
723         }\r
724     }\r
725 \r
726     if (pxran_lib_ctx->bbdev_enc) {\r
727         t1 = MLogTick();\r
728         retPoll = pxran_lib_ctx->bbdev_enc();\r
729         if (retPoll != -1)\r
730         {\r
731             t2 = MLogTick();\r
732             MLogTask(PID_XRAN_BBDEV_DL_POLL + retPoll, t1, t2);\r
733         }\r
734     }\r
735 \r
736     if (XRAN_STOPPED == xran_if_current_state)\r
737         return -1;\r
738 \r
739     return 0;\r
740 }\r
741 \r
742 int ring_processing_thread(void *args)\r
743 {\r
744     struct sched_param sched_param;\r
745     int res = 0;\r
746 \r
747     printf("%s [CPU %2d] [PID: %6d]\n", __FUNCTION__,  rte_lcore_id(), getpid());\r
748     sched_param.sched_priority = XRAN_THREAD_DEFAULT_PRIO;\r
749     if ((res = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sched_param))){\r
750         printf("priority is not changed: coreId = %d, result1 = %d\n",rte_lcore_id(), res);\r
751     }\r
752 \r
753     for (;;)\r
754         if(ring_processing_func() != 0)\r
755             break;\r
756 \r
757     puts("Pkt processing thread finished.");\r
758     return 0;\r
759 }\r
760 \r