*******************************************************************************/
/**
- * @brief XRAN layer common functionality for both lls-CU and RU as well as C-plane and
+ * @brief XRAN layer common functionality for both O-DU and O-RU as well as C-plane and
* U-plane
* @file xran_common.c
* @ingroup group_source_xran
#include <rte_mbuf.h>
#include "xran_mlog_lnx.h"
+static struct timespec sleeptime = {.tv_nsec = 1E3 }; /* 1 us */
+
#define MBUFS_CNT 16
extern long interval_us;
uint16_t start_prbu,
uint16_t sym_inc,
uint16_t rb,
- uint16_t sect_id);
+ uint16_t sect_id,
+ uint32_t *mb_free);
+
+extern int32_t xran_process_srs_sym(void *arg,
+ struct rte_mbuf *mbuf,
+ void *iq_data_start,
+ uint16_t size,
+ uint8_t CC_ID,
+ uint8_t Ant_ID,
+ uint8_t frame_id,
+ uint8_t subframe_id,
+ uint8_t slot_id,
+ uint8_t symb_id,
+ uint16_t num_prbu,
+ uint16_t start_prbu,
+ uint16_t sym_inc,
+ uint16_t rb,
+ uint16_t sect_id,
+ uint32_t *mb_free);
extern int32_t xran_pkt_validate(void *arg,
struct rte_mbuf *mbuf,
uint16_t rb,
uint16_t sect_id);
-long rx_counter = 0;
-long tx_counter = 0;
+
+struct cb_elem_entry *xran_create_cb(XranSymCallbackFn cb_fn, void *cb_data)
+{
+ struct cb_elem_entry * cb_elm = (struct cb_elem_entry *)malloc(sizeof(struct cb_elem_entry));
+ if(cb_elm){
+ cb_elm->pSymCallback = cb_fn;
+ cb_elm->pSymCallbackTag = cb_data;
+ }
+
+ return cb_elm;
+}
+
+int xran_destroy_cb(struct cb_elem_entry * cb_elm)
+{
+ if(cb_elm)
+ free(cb_elm);
+ return 0;
+}
int process_mbuf(struct rte_mbuf *pkt)
{
static int symbol_total_bytes = 0;
int num_bytes = 0;
struct xran_device_ctx * p_x_ctx = xran_dev_get_ctx();
+ struct xran_common_counters *pCnt = &p_x_ctx->fh_counters;
uint8_t CC_ID = 0;
uint8_t Ant_ID = 0;
uint16_t sym_inc;
uint16_t rb;
uint16_t sect_id;
+
+ uint8_t compMeth = 0;
+ uint8_t iqWidth = 0;
+
void *pHandle = NULL;
- uint8_t num_eAxc = xran_get_num_eAxc(pHandle);
int ret = MBUF_FREE;
uint32_t mb_free = 0;
int32_t valid_res = 0;
+ int expect_comp = (p_x_ctx->fh_cfg.ru_conf.compMeth != XRAN_COMPMETHOD_NONE);
if(p_x_ctx->xran2phy_mem_ready == 0)
&start_prbu,
&sym_inc,
&rb,
- §_id);
-
+ §_id,
+ expect_comp,
+ &compMeth,
+ &iqWidth);
if (num_bytes <= 0){
print_err("num_bytes is wrong [%d]\n", num_bytes);
return MBUF_FREE;
sect_id);
if(valid_res != 0) {
- 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);
+ print_dbg("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);
return MBUF_FREE;
}
- if (Ant_ID >= num_eAxc && p_x_ctx->fh_init.prachEnable) // PRACH packet has ruportid = num_eAxc + ant_id
- {
- Ant_ID -= num_eAxc;
- if (seq.e_bit == 1) {
+ if (Ant_ID >= p_x_ctx->srs_cfg.eAxC_offset && p_x_ctx->fh_init.srsEnable) {
+ /* SRS packet has ruportid = 2*num_eAxc + ant_id */
+ Ant_ID -= p_x_ctx->srs_cfg.eAxC_offset;
+ symbol_total_bytes += num_bytes;
- print_dbg("Completed receiving PRACH symbol %d, size=%d bytes\n",
- symb_id, num_bytes);
+ if (seq.e_bit == 1) {
+ print_dbg("SRS receiving symbol %d, size=%d bytes\n",
+ symb_id, symbol_total_bytes);
- xran_process_prach_sym(NULL,
+ if (symbol_total_bytes) {
+ int16_t res = xran_process_srs_sym(NULL,
pkt,
iq_samp_buf,
num_bytes,
start_prbu,
sym_inc,
rb,
- sect_id);
+ sect_id,
+ &mb_free);
+
+ if(res == symbol_total_bytes) {
+ ret = mb_free;
+ } else {
+ print_err("res != symbol_total_bytes\n");
+ }
+ pCnt->rx_srs_packets++;
+ }
+ symbol_total_bytes = 0;
}
else {
print_dbg("Transport layer fragmentation (eCPRI) is not supported\n");
}
- } else {
+
+ } else if (Ant_ID >= p_x_ctx->PrachCPConfig.eAxC_offset && p_x_ctx->fh_init.prachEnable) {
+ /* PRACH packet has ruportid = num_eAxc + ant_id */
+ Ant_ID -= p_x_ctx->PrachCPConfig.eAxC_offset;
+ symbol_total_bytes += num_bytes;
+ if (seq.e_bit == 1) {
+ print_dbg("Completed receiving PRACH symbol %d, size=%d bytes\n",
+ symb_id, num_bytes);
+
+ if (symbol_total_bytes) {
+ int16_t res = xran_process_prach_sym(NULL,
+ pkt,
+ iq_samp_buf,
+ num_bytes,
+ CC_ID,
+ Ant_ID,
+ frame_id,
+ subframe_id,
+ slot_id,
+ symb_id,
+ num_prbu,
+ start_prbu,
+ sym_inc,
+ rb,
+ sect_id,
+ &mb_free);
+ if(res == symbol_total_bytes) {
+ ret = mb_free;
+ } else {
+ print_err("res != symbol_total_bytes\n");
+ }
+ pCnt->rx_prach_packets[Ant_ID]++;
+ }
+ symbol_total_bytes = 0;
+ } else {
+ print_dbg("Transport layer fragmentation (eCPRI) is not supported\n");
+ }
+
+ } else { /* PUSCH */
symbol_total_bytes += num_bytes;
if (seq.e_bit == 1) {
print_dbg("Completed receiving symbol %d, size=%d bytes\n",
symb_id, symbol_total_bytes);
- if (symbol_total_bytes){
+ if (symbol_total_bytes) {
int res = xran_process_rx_sym(NULL,
pkt,
iq_samp_buf,
rb,
sect_id,
&mb_free);
- if(res == symbol_total_bytes)
- ret = mb_free;
- else
+ if(res == symbol_total_bytes) {
+ ret = mb_free;
+ } else {
print_err("res != symbol_total_bytes\n");
+ }
+ pCnt->rx_pusch_packets[Ant_ID]++;
}
symbol_total_bytes = 0;
- }
- else {
+ } else {
print_dbg("Transport layer fragmentation (eCPRI) is not supported\n");
}
}
uint16_t section_id,
struct rte_mbuf *mb,
struct rb_map *data,
+ uint8_t compMeth,
+ uint8_t iqWidth,
const enum xran_input_byte_order iq_buf_byte_order,
uint8_t frame_id,
uint8_t subframe_id,
{
int32_t n_bytes = ((prb_num == 0) ? MAX_N_FULLBAND_SC : prb_num) * N_SC_PER_PRB * sizeof(struct rb_map);
+ n_bytes = ((iqWidth == 0) || (iqWidth == 16)) ? n_bytes : ((3 * iqWidth + 1 ) * prb_num);
+
int32_t prep_bytes;
- int16_t nPktSize = sizeof(struct ether_hdr) + sizeof(struct xran_ecpri_hdr) +
+ int16_t nPktSize = sizeof(struct rte_ether_hdr) + sizeof(struct xran_ecpri_hdr) +
sizeof(struct radio_app_common_hdr)+ sizeof(struct data_section_hdr) + n_bytes;
uint32_t off;
- struct xran_up_pkt_gen_no_compression_params xp = { 0 };
+ struct xran_up_pkt_gen_params xp = { 0 };
+
+ if(compMeth != XRAN_COMPMETHOD_NONE)
+ nPktSize += sizeof(struct data_section_compression_hdr);
n_bytes = RTE_MIN(n_bytes, XRAN_MAX_MBUF_LEN);
xp.app_params.filter_id = 0;
xp.app_params.frame_id = frame_id;
xp.app_params.sf_slot_sym.subframe_id = subframe_id;
- xp.app_params.sf_slot_sym.slot_id = slot_id;
+ xp.app_params.sf_slot_sym.slot_id = xran_slotid_convert(slot_id, 0);
xp.app_params.sf_slot_sym.symb_id = symbol_no;
/* convert to network byte order */
xp.sec_hdr.fields.start_prbu = (uint8_t)prb_start;
xp.sec_hdr.fields.sym_inc = 0;
xp.sec_hdr.fields.rb = 0;
+#ifdef FCN_ADAPT
+ xp.sec_hdr.udCompHdr = 0;
+ xp.sec_hdr.reserved = 0;
+#endif
+
+ /* compression */
+ xp.compr_hdr_param.ud_comp_hdr.ud_comp_meth = compMeth;
+ xp.compr_hdr_param.ud_comp_hdr.ud_iq_width = iqWidth;
+ xp.compr_hdr_param.rsrvd = 0;
/* network byte order */
xp.sec_hdr.fields.all_bits = rte_cpu_to_be_32(xp.sec_hdr.fields.all_bits);
errx(1, "out of mbufs after %d packets", 1);
}
- prep_bytes = xran_prepare_iq_symbol_portion_no_comp(mb,
+ prep_bytes = xran_prepare_iq_symbol_portion(mb,
data,
iq_buf_byte_order,
n_bytes,
{
uint32_t do_copy = 0;
int32_t n_bytes = ((prb_num == 0) ? MAX_N_FULLBAND_SC : prb_num) * N_SC_PER_PRB * sizeof(struct rb_map);
+ struct xran_device_ctx *p_x_ctx = xran_dev_get_ctx();
+ struct xran_common_counters *pCnt = &p_x_ctx->fh_counters;
+
if (mb == NULL){
char * pChar = NULL;
MLogPrint(NULL);
errx(1, "incorrect mbuf size %d packets", 1);
}
- pChar = rte_pktmbuf_prepend(mb, sizeof(struct ether_hdr));
+ pChar = rte_pktmbuf_prepend(mb, sizeof(struct rte_ether_hdr));
if(pChar == NULL){
MLogPrint(NULL);
errx(1, "incorrect mbuf size %d packets", 1);
section_id,
mb,
data,
+ 0,
+ 16,
iq_buf_byte_order,
frame_id,
subframe_id,
do_copy);
if(sent){
- tx_counter++;
- xran_ethdi_mbuf_send(mb, ETHER_TYPE_ECPRI);
+ pCnt->tx_counter++;
+ pCnt->tx_bytes_counter += rte_pktmbuf_pkt_len(mb);
+ p_x_ctx->send_upmbuf2ring(mb, ETHER_TYPE_ECPRI, xran_map_ecpriPcid_to_vf(direction, CC_ID, RU_Port_ID));
} else {
}
-
-
#ifdef DEBUG
printf("Symbol %2d sent (%d packets, %d bytes)\n", symbol_no, i, n_bytes);
#endif
struct xran_section_gen_info *sect_geninfo, uint8_t cc_id, uint8_t ru_port_id, uint8_t seq_id)
{
int ret = 0, nsection, i;
- uint8_t frame_id = params->hdr.frameId;
uint8_t subframe_id = params->hdr.subframeId;
uint8_t slot_id = params->hdr.slotId;
uint8_t dir = params->dir;
+ struct xran_device_ctx *p_x_ctx = xran_dev_get_ctx();
+ struct xran_common_counters *pCnt = &p_x_ctx->fh_counters;
nsection = params->numSections;
/* add in the ethernet header */
- struct ether_hdr *const h = (void *)rte_pktmbuf_prepend(mbuf, sizeof(*h));
- xran_ethdi_mbuf_send_cp(mbuf, ETHER_TYPE_ECPRI);
- tx_counter++;
+ struct rte_ether_hdr *const h = (void *)rte_pktmbuf_prepend(mbuf, sizeof(*h));
+
+ pCnt->tx_counter++;
+ pCnt->tx_bytes_counter += rte_pktmbuf_pkt_len(mbuf);
+ p_x_ctx->send_cpmbuf2ring(mbuf, ETHER_TYPE_ECPRI, xran_map_ecpriRtcid_to_vf(dir, cc_id, ru_port_id));
for(i=0; i<nsection; i++)
xran_cp_add_section_info(pHandle, dir, cc_id, ru_port_id,
(slot_id + subframe_id*SLOTNUM_PER_SUBFRAME)%XRAN_MAX_SECTIONDB_CTX,
int generate_cpmsg_dlul(void *pHandle, struct xran_cp_gen_params *params, struct xran_section_gen_info *sect_geninfo, struct rte_mbuf *mbuf,
enum xran_pkt_dir dir, uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id,
- uint8_t startsym, uint8_t numsym, uint16_t prb_start, uint16_t prb_num,
- uint16_t beam_id, uint8_t cc_id, uint8_t ru_port_id, uint8_t comp_method, uint8_t seq_id, uint8_t symInc)
+ uint8_t startsym, uint8_t numsym, uint16_t prb_start, uint16_t prb_num,int16_t iq_buffer_offset, int16_t iq_buffer_len,
+ 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)
{
- int ret = 0, nsection, i;
+ int ret = 0, nsection, loc_sym;
params->dir = dir;
params->hdr.subframeId = subframe_id;
params->hdr.slotId = slot_id;
params->hdr.startSymId = startsym; // start Symbol ID
- params->hdr.iqWidth = xran_get_conf_iqwidth(pHandle);
+ params->hdr.iqWidth = iqWidth;
params->hdr.compMeth = comp_method;
nsection = 0;
sect_geninfo[nsection].info.reMask = 0xfff;
sect_geninfo[nsection].info.beamId = beam_id;
+ for (loc_sym = 0; loc_sym < XRAN_NUM_OF_SYMBOL_PER_SLOT; loc_sym++) {
+ sect_geninfo[0].info.sec_desc[loc_sym].iq_buffer_offset = iq_buffer_offset;
+ sect_geninfo[0].info.sec_desc[loc_sym].iq_buffer_len = iq_buffer_len;
+ }
+
sect_geninfo[nsection].info.ef = 0;
sect_geninfo[nsection].exDataSize = 0;
// sect_geninfo[nsection].exData = NULL;
uint8_t frame_id, uint8_t subframe_id, uint8_t slot_id,
uint16_t beam_id, uint8_t cc_id, uint8_t prach_port_id, uint8_t seq_id)
{
- int i, nsection, ret;
- xRANPrachCPConfigStruct *pPrachCPConfig = &(pxran_lib_ctx->PrachCPConfig);
+ int nsection, ret;
+ struct xran_prach_cp_config *pPrachCPConfig = &(pxran_lib_ctx->PrachCPConfig);
uint16_t timeOffset;
uint16_t nNumerology = pxran_lib_ctx->fh_cfg.frame_conf.nNumerology;
{
struct xran_ethdi_ctx *const ctx = xran_ethdi_get_ctx();
struct xran_device_ctx *const pxran_lib_ctx = xran_dev_get_ctx();
+ int16_t retPoll = 0;
+ int32_t i;
+ uint64_t t1, t2;
rte_timer_manage();
+ if (pxran_lib_ctx->bbdev_dec) {
+ t1 = MLogTick();
+ retPoll = pxran_lib_ctx->bbdev_dec();
+ if (retPoll != -1)
+ {
+ t2 = MLogTick();
+ MLogTask(PID_XRAN_BBDEV_UL_POLL + retPoll, t1, t2);
+ }
+ }
+
+ if (pxran_lib_ctx->bbdev_enc) {
+ t1 = MLogTick();
+ retPoll = pxran_lib_ctx->bbdev_enc();
+ if (retPoll != -1)
+ {
+ t2 = MLogTick();
+ MLogTask(PID_XRAN_BBDEV_DL_POLL + retPoll, t1, t2);
+ }
+ }
+
/* UP first */
- if (process_ring(ctx->rx_ring[ETHDI_UP_VF]))
- return 0;
- /* CP next */
- if (process_ring(ctx->rx_ring[ETHDI_CP_VF]))
- return 0;
- if (pxran_lib_ctx->bbdev_dec)
- pxran_lib_ctx->bbdev_dec();
+ for (i = 0; i < ctx->io_cfg.num_vfs && i < (XRAN_VF_MAX - 1); i = i+2){
+ if (process_ring(ctx->rx_ring[i]))
+ return 0;
- if (pxran_lib_ctx->bbdev_enc)
- pxran_lib_ctx->bbdev_enc();
+ /* CP next */
+ if(ctx->io_cfg.id == O_RU) /* process CP only on O-RU */
+ if (process_ring(ctx->rx_ring[i+1]))
+ return 0;
+ }
if (XRAN_STOPPED == xran_if_current_state)
return -1;
int ring_processing_thread(void *args)
{
struct sched_param sched_param;
+ struct xran_device_ctx *const p_xran_dev_ctx = xran_dev_get_ctx();
int res = 0;
+ memset(&sched_param, 0, sizeof(struct sched_param));
+
printf("%s [CPU %2d] [PID: %6d]\n", __FUNCTION__, rte_lcore_id(), getpid());
sched_param.sched_priority = XRAN_THREAD_DEFAULT_PRIO;
if ((res = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sched_param))){
printf("priority is not changed: coreId = %d, result1 = %d\n",rte_lcore_id(), res);
}
- for (;;)
+ for (;;){
if(ring_processing_func() != 0)
break;
+ /* work around for some kernel */
+ if(p_xran_dev_ctx->fh_init.io_cfg.io_sleep)
+ nanosleep(&sleeptime,NULL);
+ }
+
puts("Pkt processing thread finished.");
return 0;
}