Commit e13e01c0 authored by Ting-An-Lin's avatar Ting-An-Lin Committed by rajeshwari.p

add targets/ARCH/ORAN_FHI/lib in OAI

parent c3d01306
/******************************************************************************
*
* Copyright (c) 2020 Intel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
/**
* @brief
* @file
* @ingroup
* @author Intel Corporation
**/
#ifndef _SAMPLEAPP__CONFIG_H_
#define _SAMPLEAPP__CONFIG_H_
#include <stdint.h>
#include <rte_ether.h>
#include "xran_fh_o_du.h"
/** Run time configuration of application */
typedef struct _RuntimeConfig
{
uint8_t appMode; /**< Application mode: lls-CU or RU */
uint8_t xranTech; /**< Radio Access Technology (NR or LTE) */
uint8_t xranCat; /**< xran mode: NR Categoty A, NR Category B, LTE Cat A, LTE Cat B */
uint8_t numCC; /**< Number of CC per ports supported by RU */
uint8_t numAxc; /**< Number of Antenna Carriers per CC */
uint8_t numUlAxc; /**< Number of Antenna Carriers per CC for UL (Cat B) */
uint32_t antElmTRx; /**< Number of antenna elements for TX and RX */
uint32_t muMimoUEs; /**< Number of UEs (with 1 RX ant)/beams */
uint32_t DlLayersPerUe; /**< Number of DL layer per UE */
uint32_t UlLayersPerUe; /**< Number of UL layer per UE */
uint32_t ttiPeriod; /**< TTI period */
uint32_t testVect; /**< Test Signal to send */
struct rte_ether_addr o_du_addr[XRAN_VF_MAX]; /**< O-DU Ethernet Mac Address */
struct rte_ether_addr o_ru_addr[XRAN_VF_MAX]; /**< O-RU Ethernet Mac Address */
struct rte_ether_addr tmp_addr; /**< Temp Ethernet Mac Address */
uint32_t instance_id; /**< Instance ID of application */
uint32_t io_core; /**< Core used for IO */
uint64_t io_worker; /**< Mask for worker cores */
int32_t io_sleep; /**< enable sleep on PMD cores */
uint32_t system_core; /* house keeping core */
int iova_mode; /**< DPDK IOVA Mode */
uint32_t mtu; /**< maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single
xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame) */
int numSlots; /**< number of slots in IQ vector */
char ant_file[XRAN_MAX_SECTOR_NR*XRAN_MAX_ANTENNA_NR][512]; /**< file to use for test vector */
char prach_file[XRAN_MAX_SECTOR_NR*XRAN_MAX_ANTENNA_NR][512]; /**< file to use for test vector */
char dl_bfw_file [XRAN_MAX_SECTOR_NR*XRAN_MAX_ANTENNA_NR][512]; /**< file with beamforming weights for DL streams */
char ul_bfw_file [XRAN_MAX_SECTOR_NR*XRAN_MAX_ANTENNA_NR][512]; /**< file with beamforming weights for UL streams */
char ul_srs_file [XRAN_MAX_SECTOR_NR*XRAN_MAX_ANT_ARRAY_ELM_NR][512]; /**< file with SRS content for UL antenna elements */
/* prach config */
uint8_t enablePrach; /**< enable PRACH */
uint8_t prachOffset; /**< Sets the PRACH position in frequency / subcarrier position, n_PRBoffset^RA and is expressed as a physical resource block number.
Set by SIB2, prach-FreqOffset in E-UTRA. */
uint8_t prachConfigIndex;/**< TS36.211 - Table 5.7.1-2 : PRACH Configuration Index */
uint8_t iqswap; /**< do swap of IQ before send to ETH */
uint8_t nebyteorderswap; /**< do swap of byte order from host byte order to network byte order. ETH */
uint8_t compression; /**< enable use case with compression */
uint8_t CompHdrType; /**< dynamic or static compression header */
uint16_t totalBfWeights; /**< The total number of beamforming weights on RU */
uint8_t enableSrs; /**< enable SRS (valid for Cat B only) */
uint16_t srsSymMask; /**< SRS symbol mask [014] within S/U slot [0-13] def is 13 */
uint16_t maxFrameId; /**< max value of frame id */
uint16_t Tadv_cp_dl;
uint16_t T2a_min_cp_dl;
uint16_t T2a_max_cp_dl;
uint16_t T2a_min_cp_ul;
uint16_t T2a_max_cp_ul;
uint16_t T2a_min_up;
uint16_t T2a_max_up;
uint16_t Ta3_min;
uint16_t Ta3_max;
uint16_t T1a_min_cp_dl;
uint16_t T1a_max_cp_dl;
uint16_t T1a_min_cp_ul;
uint16_t T1a_max_cp_ul;
uint16_t T1a_min_up;
uint16_t T1a_max_up;
uint16_t Ta4_min;
uint16_t Ta4_max;
uint8_t enableCP; /**< enable C-plane */
uint8_t cp_vlan_tag; /**< C-plane vlan tag */
uint8_t up_vlan_tag; /**< U-plane vlan tag */
int32_t debugStop;
int32_t debugStopCount;
int32_t bbdevMode;
int32_t DynamicSectionEna;
int32_t GPS_Alpha;
int32_t GPS_Beta;
uint8_t mu_number; /**< Mu numner as per 3GPP */
uint32_t nDLAbsFrePointA; /**< Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000 */
uint32_t nULAbsFrePointA; /**< Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000 */
uint32_t nDLBandwidth; /**< Carrier bandwidth for in MHz. Value: 5->400 */
uint32_t nULBandwidth; /**< Carrier bandwidth for in MHz. Value: 5->400 */
uint32_t nDLFftSize; /**< DL FFT size */
uint32_t nULFftSize; /**< UL FFT size */
uint8_t nFrameDuplexType;
uint8_t nTddPeriod;
struct xran_slot_config sSlotConfig[XRAN_MAX_TDD_PERIODICITY];
struct xran_prb_map PrbMapDl;
struct xran_prb_map PrbMapUl;
int32_t DU_Port_ID_bitwidth;
int32_t BandSector_ID_bitwidth;
int32_t CC_ID_bitwidth;
int32_t RU_Port_ID_bitwidth;
} RuntimeConfig;
/**
* Parse application configuration file.
*
* @param filename The name of the configuration file to be parsed.
* @param config The configuration structure to be filled with parsed data. */
int parseConfigFile(char *filename, RuntimeConfig *config);
#endif /* _SAMPLEAPP__CONFIG_H_ */
/******************************************************************************
*
* Copyright (c) 2020 Intel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
/**
* @brief
* @file
* @ingroup
* @author Intel Corporation
**/
#ifndef _SAMPLEAPP__DEBUG_H_
#define _SAMPLEAPP__DEBUG_H_
#include <stdio.h>
#include "config.h"
#define MAX_FILE_NAME_LEN (512)
#define MAX_PATH_NAME_LEN (1024)
#ifdef _DEBUG
#define log_dbg(fmt, ...) \
fprintf(stderr, \
"DEBUG: %s(%d): " fmt "\n", \
__FILE__, \
__LINE__, ##__VA_ARGS__)
#else
#define log_dbg(fmt, ...)
#endif
#if defined(_DEBUG) || defined(_VERBOSE)
#define log_wrn(fmt, ...) \
fprintf( \
stderr, \
"WARNING: %s(%d): " fmt "\n", \
__FILE__, \
__LINE__, ##__VA_ARGS__)
#else
#define log_dbg(fmt, ...)
#define log_wrn(fmt, ...)
#endif
#define log_err(fmt, ...) \
fprintf(stderr, \
"ERROR: %s(%d): " fmt "\n", \
__FILE__, \
__LINE__, ##__VA_ARGS__)
inline void ShowData(void* ptr, unsigned int size)
{
uint8_t *d = (uint8_t *)ptr;
unsigned int i;
for(i = 0; i < size; i++)
{
if ( !(i & 0xf) )
printf("\n");
printf("%02x ", d[i]);
}
printf("\n");
}
#endif /* _SAMPLEAPP__DEBUG_H_ */
/******************************************************************************
*
* Copyright (c) 2019 Intel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
/**
* @brief This file has all definitions for the Ethernet Data Interface Layer
* @file ethdi.h
* @ingroup group_lte_source_auxlib
* @author Intel Corporation
**/
#ifndef _ETHDI_H_
#define _ETHDI_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <rte_config.h>
#include <rte_mbuf.h>
#include <rte_timer.h>
/* comment this to enable PDUMP
* DPDK has to be compiled with
* CONFIG_RTE_LIBRTE_PMD_PCAP=y
* CONFIG_RTE_LIBRTE_PDUMP=y
*/
#undef RTE_LIBRTE_PDUMP
#ifdef RTE_LIBRTE_PDUMP
#include <rte_pdump.h>
#endif
#include "ethernet.h"
#include "xran_fh_o_du.h"
#define XRAN_THREAD_DEFAULT_PRIO (98)
/* If we're not receiving packets for more then this threshold... */
//#define SLEEP_THRESHOLD (rte_get_tsc_hz() / 30) /* = 33.3(3)ms */
/* we go to sleep for this long (usleep). Undef SLEEP_TRESHOLD to disable. */
#define SLEEP_TIME 200 /* (us) */
#define BCAST {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
#define TX_TIMER_INTERVAL ((rte_get_timer_hz() / 1000000000L)*interval_us*1000) /* nanosec */
#define TX_RX_LOOP_TIME rte_get_timer_hz() / 1
/* CAUTION: Keep in sync with the string table below. */
enum xran_entities_id
{
ID_O_DU,
ID_O_RU,
ID_BROADCAST,
ID_MAX
};
static char *const entity_names[] = {
"ORAN O-DU sim app",
"ORAN O-RU sim app",
};
typedef int (*PROCESS_CB)(void * arg);
/**
* Structure storing internal configuration of workers
*/
struct xran_worker_config {
lcore_function_t *f;
void *arg;
int32_t state;
};
struct xran_ethdi_ctx
{
struct xran_io_cfg io_cfg;
struct rte_ether_addr entities[XRAN_VF_MAX][ID_BROADCAST + 1];
struct rte_ring *tx_ring[XRAN_VF_MAX];
struct rte_ring *rx_ring[XRAN_VF_MAX];
struct rte_ring *pkt_dump_ring[XRAN_VF_MAX];
struct rte_timer timer_autodetect;
struct rte_timer timer_ping;
struct rte_timer timer_sync;
struct rte_timer timer_tx;
struct xran_worker_config pkt_wrk_cfg[RTE_MAX_LCORE];
unsigned pkt_stats[PKT_LAST + 1];
};
enum {
MBUF_KEEP,
MBUF_FREE
};
extern enum xran_if_state xran_if_current_state;
static inline struct xran_ethdi_ctx *xran_ethdi_get_ctx(void)
{
extern struct xran_ethdi_ctx g_ethdi_ctx;
return &g_ethdi_ctx;
}
typedef int (*xran_ethdi_handler)(struct rte_mbuf *, int sender, uint64_t rx_time);
typedef int (*ethertype_handler)(struct rte_mbuf *, uint64_t rx_time);
typedef int (*xran_ethdi_handler)(struct rte_mbuf *, int sender, uint64_t rx_time);
int xran_register_ethertype_handler(uint16_t ethertype, ethertype_handler callback);
int32_t xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg,
int *lcore_id, struct rte_ether_addr *p_o_du_addr,
struct rte_ether_addr *p_ru_addr);
struct rte_mbuf *xran_ethdi_mbuf_alloc(void);
int32_t xran_ethdi_mbuf_send(struct rte_mbuf *mb, uint16_t ethertype, uint16_t vf_id);
int32_t xran_ethdi_mbuf_send_cp(struct rte_mbuf *mb, uint16_t ethertype, uint16_t vf_id);
int32_t xran_ethdi_filter_packet(struct rte_mbuf *pkt, uint64_t rx_time);
int32_t process_dpdk_io(void);
#ifdef __cplusplus
}
#endif
#endif /* #ifndef _ETHDI_H_ */
/******************************************************************************
*
* Copyright (c) 2019 Intel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
/**
* @brief This file has all definitions for the Ethernet Data Interface Layer
* @file ethernet.h
* @ingroup group_lte_source_auxlib
* @author Intel Corporation
**/
#ifndef AUXLIB_ETHERNET_H
#define AUXLIB_ETHERNET_H
#ifdef __cplusplus
extern "C" {
#endif
#include <rte_config.h>
#include <rte_ether.h>
#include <rte_mbuf.h>
#define BURST_SIZE 4096
#define ETHER_TYPE_ETHDI RTE_ETHER_TYPE_IPV4 /* hack needed for jumbo frames */
#define ETHER_TYPE_ECPRI 0xAEFE
#define ETHER_TYPE_SYNC 0xBEFE
#define ETHER_TYPE_START_TX 0xCEFE
#define NUM_MBUFS 65535/*16383*/ /*65535*/ /** optimal is n = (2^q - 1) */
#define NUM_MBUFS_RING NUM_MBUFS+1 /** The size of the ring (must be a power of 2) */
#define MBUF_CACHE 256
#define MBUF_POOL_ELM_SMALL (1500 + RTE_PKTMBUF_HEADROOM )/* regular ethernet MTU, most compatible */
#define MBUF_POOL_ELEMENT (MAX_RX_LEN + RTE_PKTMBUF_HEADROOM)
#define MAX_RX_LEN 9600
#define MAX_TX_LEN (MAX_RX_LEN - 14) /* headroom for rx driver */
#define MAX_DATA_SIZE (MAX_TX_LEN - sizeof(struct ether_hdr) - \
sizeof(struct ethdi_hdr) - sizeof(struct burst_hdr))
/* Looks like mbuf size is limited to 16 bits - see the buf_len field. */
#define MBUF_POOL_ELM_BIG USHRT_MAX
#define NUM_MBUFS_BIG 64
#define DEFAULT_DUMP_LENGTH 96
extern struct rte_mempool *_eth_mbuf_pool;
extern struct rte_mempool *_eth_mbuf_pool_small;
extern struct rte_mempool *_eth_mbuf_pool_big;
extern struct rte_mempool *socket_direct_pool;
extern struct rte_mempool *socket_indirect_pool;
/* Do NOT change the order of this enum and below
* - need to be in sync with the table of handlers in testue.c */
enum pkt_type
{
PKT_ZERO,
PKT_EMPTY,
PKT_DISCOVER_REQUEST,
PKT_PING,
PKT_PONG,
PKT_DISCOVER_REPLY,
PKT_LTE_DATA,
PKT_LTE_CONTROL,
PKT_BURST,
PKT_DATATEST,
PKT_ADD_ETHDEV,
PKT_SYNC_START,
PKT_LAST,
};
/* Do NOT change the order. */
static char * const xran_pkt_descriptions[PKT_LAST + 1] = {
"ZERO",
"empty packet",
"discovery request packet",
"ping packet",
"pong packet",
"discovery reply packet",
"LTE data packet",
"LTE control packet",
"BURST packet",
"DATATEST packet",
"Add ethernet port command packet",
"SYNC-START packet",
"LAST packet",
};
struct burst_hdr {
int8_t pkt_idx;
int8_t total_pkts;
int8_t original_type;
int8_t data[];
};
struct ethdi_hdr {
uint8_t pkt_type;
uint8_t source_id;
uint8_t dest_id;
int8_t data[]; /* original raw data starts here! */
};
void xran_init_mbuf_pool(void);
void xran_init_port(int port);
void xran_add_eth_hdr_vlan(struct rte_ether_addr *dst, uint16_t ethertype, struct rte_mbuf *mb);
#if 0
void xran_memdump(void *addr, int len);
void xran_add_eth_hdr(struct ether_addr *dst, uint16_t ethertype, struct rte_mbuf *);
int xran_send_mbuf(struct ether_addr *dst, struct rte_mbuf *mb);
int xran_send_message_burst(int dst_id, int pkt_type, void *body, int len);
int xran_show_delayed_message(void);
#endif
/*
* Print a message after all critical processing done.
* Mt-safe. 4 variants - normal, warning, error and debug log.
*/
int __xran_delayed_msg(const char *fmt, ...);
#define nlog(m, ...) __xran_delayed_msg("%s(): " m "\n", __FUNCTION__, ##__VA_ARGS__)
#define delayed_message nlog /* this is the old alias for this function */
#define wlog(m, ...) nlog("WARNING: " m, ##__VA_ARGS__)
#define elog(m, ...) nlog("ERROR: " m, ##__VA_ARGS__)
#ifdef DEBUG
# define dlog(m, ...) nlog("DEBUG: " m, ##__VA_ARGS__)
#else
# define dlog(m, ...)
#endif
#define PANIC_ON(x, m, ...) do { if (unlikely(x)) \
rte_panic("%s: " m "\n", #x, ##__VA_ARGS__); } while (0)
/* Add mbuf to the TX ring. */
static inline int xran_enqueue_mbuf(struct rte_mbuf *mb, struct rte_ring *r)
{
if (rte_ring_enqueue(r, mb) == 0) {
return 1; /* success */
}
rte_pktmbuf_free(mb);
wlog("failed to enqueue packet on port %d (ring full)", mb->port);
return 0; /* fail */
}
#ifdef __cplusplus
}
#endif
#endif /* AUXLIB_ETHERNET_H */
/******************************************************************************
*
* Copyright (c) 2019 Intel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
/**
* @brief Header file for functions to perform application level fragmentation
*
* @file xran_app_frag.h
* @ingroup group_source_xran
* @author Intel Corporation
**/
#ifndef _XRAN_APP_FRAG_
#define _XRAN_APP_FRAG_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdio.h>
#include <rte_config.h>
#include <rte_malloc.h>
#include <rte_memory.h>
#include <rte_mempool.h>
#include <rte_byteorder.h>
#include "xran_fh_o_du.h"
#include "xran_cp_api.h"
int32_t xran_app_fragment_packet(struct rte_mbuf *pkt_in, /* eth hdr is prepended */
struct rte_mbuf **pkts_out,
uint16_t nb_pkts_out,
uint16_t mtu_size,
struct rte_mempool *pool_direct,
struct rte_mempool *pool_indirect,
struct xran_section_info *sectinfo,
uint8_t *seqid);
#ifdef __cplusplus
}
#endif
#endif /* _XRAN_APP_FRAG_ */
/******************************************************************************
*
* Copyright (c) 2019 Intel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
/**
* @brief xRAN BFP compression/decompression utilities functions
*
* @file xran_bfp_utils.hpp
* @ingroup group_source_xran
* @author Intel Corporation
**/
#pragma once
#include <immintrin.h>
namespace BlockFloatCompander
{
/// Define function signatures for byte packing functions
typedef __m512i(*PackFunction)(const __m512i);
typedef __m512i(*UnpackFunction)(const uint8_t*);
typedef __m256i(*UnpackFunction256)(const uint8_t*);
/// Calculate exponent based on 16 max abs values using leading zero count.
inline __m512i
maskUpperWord(const __m512i inData)
{
const auto k_upperWordMask = _mm512_set_epi64(0x0000FFFF0000FFFF, 0x0000FFFF0000FFFF,
0x0000FFFF0000FFFF, 0x0000FFFF0000FFFF,
0x0000FFFF0000FFFF, 0x0000FFFF0000FFFF,
0x0000FFFF0000FFFF, 0x0000FFFF0000FFFF);
return _mm512_and_epi64(inData, k_upperWordMask);
}
/// Calculate exponent based on 16 max abs values using leading zero count.
inline __m512i
expLzCnt(const __m512i maxAbs, const __m512i totShiftBits)
{
/// Compute exponent
const auto lzCount = _mm512_lzcnt_epi32(maxAbs);
return _mm512_subs_epu16(totShiftBits, lzCount);
}
inline int
horizontalMax1x32(const __m512i maxAbsReg)
{
/// Swap each IQ pair in each lane (via 32b rotation) and compute max of
/// each pair.
const auto maxRot16 = _mm512_rol_epi32(maxAbsReg, BlockFloatCompander::k_numBitsIQ);
const auto maxAbsIQ = _mm512_max_epi16(maxAbsReg, maxRot16);
/// Convert to 32b by removing repeated values in maxAbs
const auto maxAbs32 = maskUpperWord(maxAbsIQ);
/// Return reduced max
return _mm512_reduce_max_epi32(maxAbs32);
}
/// Pack compressed 9 bit data in network byte order
/// See https://soco.intel.com/docs/DOC-2665619
inline __m512i
networkBytePack9b(const __m512i compData)
{
/// Logical shift left to align network order byte parts
const __m512i k_shiftLeft = _mm512_set_epi64(0x0000000100020003, 0x0004000500060007,
0x0000000100020003, 0x0004000500060007,
0x0000000100020003, 0x0004000500060007,
0x0000000100020003, 0x0004000500060007);
const auto compDataPacked = _mm512_sllv_epi16(compData, k_shiftLeft);
/// First epi8 shuffle of even indexed samples
const __m512i k_byteShuffleMask1 = _mm512_set_epi64(0x0000000000000000, 0x0C0D080904050001,
0x0000000000000000, 0x0C0D080904050001,
0x0000000000000000, 0x0C0D080904050001,
0x0000000000000000, 0x0C0D080904050001);
constexpr uint64_t k_byteMask1 = 0x00FF00FF00FF00FF;
const auto compDataShuff1 = _mm512_maskz_shuffle_epi8(k_byteMask1, compDataPacked, k_byteShuffleMask1);
/// Second epi8 shuffle of odd indexed samples
const __m512i k_byteShuffleMask2 = _mm512_set_epi64(0x000000000000000E, 0x0F0A0B0607020300,
0x000000000000000E, 0x0F0A0B0607020300,
0x000000000000000E, 0x0F0A0B0607020300,
0x000000000000000E, 0x0F0A0B0607020300);
constexpr uint64_t k_byteMask2 = 0x01FE01FE01FE01FE;
const auto compDataShuff2 = _mm512_maskz_shuffle_epi8(k_byteMask2, compDataPacked, k_byteShuffleMask2);
/// Ternary blend of the two shuffled results
const __m512i k_ternLogSelect = _mm512_set_epi64(0x00000000000000FF, 0x01FC07F01FC07F00,
0x00000000000000FF, 0x01FC07F01FC07F00,
0x00000000000000FF, 0x01FC07F01FC07F00,
0x00000000000000FF, 0x01FC07F01FC07F00);
return _mm512_ternarylogic_epi64(compDataShuff1, compDataShuff2, k_ternLogSelect, 0xd8);
}
/// Pack compressed 10 bit data in network byte order
/// See https://soco.intel.com/docs/DOC-2665619
inline __m512i
networkBytePack10b(const __m512i compData)
{
/// Logical shift left to align network order byte parts
const __m512i k_shiftLeft = _mm512_set_epi64(0x0000000200040006, 0x0000000200040006,
0x0000000200040006, 0x0000000200040006,
0x0000000200040006, 0x0000000200040006,
0x0000000200040006, 0x0000000200040006);
const auto compDataPacked = _mm512_sllv_epi16(compData, k_shiftLeft);
/// First epi8 shuffle of even indexed samples
const __m512i k_byteShuffleMask1 = _mm512_set_epi64(0x000000000000000C, 0x0D08090004050001,
0x000000000000000C, 0x0D08090004050001,
0x000000000000000C, 0x0D08090004050001,
0x000000000000000C, 0x0D08090004050001);
constexpr uint64_t k_byteMask1 = 0x01EF01EF01EF01EF;
const auto compDataShuff1 = _mm512_maskz_shuffle_epi8(k_byteMask1, compDataPacked, k_byteShuffleMask1);
/// Second epi8 shuffle of odd indexed samples
const __m512i k_byteShuffleMask2 = _mm512_set_epi64(0x0000000000000E0F, 0x0A0B000607020300,
0x0000000000000E0F, 0x0A0B000607020300,
0x0000000000000E0F, 0x0A0B000607020300,
0x0000000000000E0F, 0x0A0B000607020300);
constexpr uint64_t k_byteMask2 = 0x03DE03DE03DE03DE;
const auto compDataShuff2 = _mm512_maskz_shuffle_epi8(k_byteMask2, compDataPacked, k_byteShuffleMask2);
/// Ternary blend of the two shuffled results
const __m512i k_ternLogSelect = _mm512_set_epi64(0x000000000000FF03, 0xF03F00FF03F03F00,
0x000000000000FF03, 0xF03F00FF03F03F00,
0x000000000000FF03, 0xF03F00FF03F03F00,
0x000000000000FF03, 0xF03F00FF03F03F00);
return _mm512_ternarylogic_epi64(compDataShuff1, compDataShuff2, k_ternLogSelect, 0xd8);
}
/// Pack compressed 12 bit data in network byte order
/// See https://soco.intel.com/docs/DOC-2665619
inline __m512i
networkBytePack12b(const __m512i compData)
{
/// Logical shift left to align network order byte parts
const __m512i k_shiftLeft = _mm512_set_epi64(0x0000000400000004, 0x0000000400000004,
0x0000000400000004, 0x0000000400000004,
0x0000000400000004, 0x0000000400000004,
0x0000000400000004, 0x0000000400000004);
const auto compDataPacked = _mm512_sllv_epi16(compData, k_shiftLeft);
/// First epi8 shuffle of even indexed samples
const __m512i k_byteShuffleMask1 = _mm512_set_epi64(0x00000000000C0D00, 0x0809000405000001,
0x00000000000C0D00, 0x0809000405000001,
0x00000000000C0D00, 0x0809000405000001,
0x00000000000C0D00, 0x0809000405000001);
constexpr uint64_t k_byteMask1 = 0x06DB06DB06DB06DB;
const auto compDataShuff1 = _mm512_maskz_shuffle_epi8(k_byteMask1, compDataPacked, k_byteShuffleMask1);
/// Second epi8 shuffle of odd indexed samples
const __m512i k_byteShuffleMask2 = _mm512_set_epi64(0x000000000E0F000A, 0x0B00060700020300,
0x000000000E0F000A, 0x0B00060700020300,
0x000000000E0F000A, 0x0B00060700020300,
0x000000000E0F000A, 0x0B00060700020300);
constexpr uint64_t k_byteMask2 = 0x0DB60DB60DB60DB6;
const auto compDataShuff2 = _mm512_maskz_shuffle_epi8(k_byteMask2, compDataPacked, k_byteShuffleMask2);
/// Ternary blend of the two shuffled results
const __m512i k_ternLogSelect = _mm512_set_epi64(0x00000000FF0F00FF, 0x0F00FF0F00FF0F00,
0x00000000FF0F00FF, 0x0F00FF0F00FF0F00,
0x00000000FF0F00FF, 0x0F00FF0F00FF0F00,
0x00000000FF0F00FF, 0x0F00FF0F00FF0F00);
return _mm512_ternarylogic_epi64(compDataShuff1, compDataShuff2, k_ternLogSelect, 0xd8);
}
/// Unpack compressed 9 bit data in network byte order
/// See https://soco.intel.com/docs/DOC-2665619
inline __m512i
networkByteUnpack9b(const uint8_t* inData)
{
/// Align chunks of compressed bytes into lanes to allow for expansion
const __m512i* rawDataIn = reinterpret_cast<const __m512i*>(inData);
const auto k_expPerm = _mm512_set_epi32(9, 8, 7, 6, 7, 6, 5, 4,
5, 4, 3, 2, 3, 2, 1, 0);
const auto inLaneAlign = _mm512_permutexvar_epi32(k_expPerm, *rawDataIn);
/// Byte shuffle to get all bits for each sample into 16b chunks
/// Due to previous permute to get chunks of bytes into each lane, there is
/// a different shuffle offset in each lane
const __m512i k_byteShuffleMask = _mm512_set_epi64(0x0A0B090A08090708, 0x0607050604050304,
0x090A080907080607, 0x0506040503040203,
0x0809070806070506, 0x0405030402030102,
0x0708060705060405, 0x0304020301020001);
const auto inDatContig = _mm512_shuffle_epi8(inLaneAlign, k_byteShuffleMask);
/// Logical shift left to set sign bit
const __m512i k_slBits = _mm512_set_epi64(0x0007000600050004, 0x0003000200010000,
0x0007000600050004, 0x0003000200010000,
0x0007000600050004, 0x0003000200010000,
0x0007000600050004, 0x0003000200010000);
const auto inSetSign = _mm512_sllv_epi16(inDatContig, k_slBits);
/// Mask to zero unwanted bits
const __m512i k_expMask = _mm512_set1_epi16(0xFF80);
return _mm512_and_epi64(inSetSign, k_expMask);
}
/// Unpack compressed 10 bit data in network byte order
/// See https://soco.intel.com/docs/DOC-2665619
inline __m512i
networkByteUnpack10b(const uint8_t* inData)
{
/// Align chunks of compressed bytes into lanes to allow for expansion
const __m512i* rawDataIn = reinterpret_cast<const __m512i*>(inData);
const auto k_expPerm = _mm512_set_epi32(10, 9, 8, 7, 8, 7, 6, 5,
5, 4, 3, 2, 3, 2, 1, 0);
const auto inLaneAlign = _mm512_permutexvar_epi32(k_expPerm, *rawDataIn);
/// Byte shuffle to get all bits for each sample into 16b chunks
/// Due to previous permute to get chunks of bytes into each lane, lanes
/// 0 and 2 happen to be aligned, but lane 1 is offset by 2 bytes
const __m512i k_byteShuffleMask = _mm512_set_epi64(0x0A0B090A08090708, 0x0506040503040203,
0x0809070806070506, 0x0304020301020001,
0x0A0B090A08090708, 0x0506040503040203,
0x0809070806070506, 0x0304020301020001);
const auto inDatContig = _mm512_shuffle_epi8(inLaneAlign, k_byteShuffleMask);
/// Logical shift left to set sign bit
const __m512i k_slBits = _mm512_set_epi64(0x0006000400020000, 0x0006000400020000,
0x0006000400020000, 0x0006000400020000,
0x0006000400020000, 0x0006000400020000,
0x0006000400020000, 0x0006000400020000);
const auto inSetSign = _mm512_sllv_epi16(inDatContig, k_slBits);
/// Mask to zero unwanted bits
const __m512i k_expMask = _mm512_set1_epi16(0xFFC0);
return _mm512_and_epi64(inSetSign, k_expMask);
}
/// Unpack compressed 12 bit data in network byte order
/// See https://soco.intel.com/docs/DOC-2665619
inline __m512i
networkByteUnpack12b(const uint8_t* inData)
{
/// Align chunks of compressed bytes into lanes to allow for expansion
const __m512i* rawDataIn = reinterpret_cast<const __m512i*>(inData);
const auto k_expPerm = _mm512_set_epi32(12, 11, 10, 9, 9, 8, 7, 6,
6, 5, 4, 3, 3, 2, 1, 0);
const auto inLaneAlign = _mm512_permutexvar_epi32(k_expPerm, *rawDataIn);
/// Byte shuffle to get all bits for each sample into 16b chunks
/// For 12b mantissa all lanes post-permute are aligned and require same shuffle offset
const __m512i k_byteShuffleMask = _mm512_set_epi64(0x0A0B090A07080607, 0x0405030401020001,
0x0A0B090A07080607, 0x0405030401020001,
0x0A0B090A07080607, 0x0405030401020001,
0x0A0B090A07080607, 0x0405030401020001);
const auto inDatContig = _mm512_shuffle_epi8(inLaneAlign, k_byteShuffleMask);
/// Logical shift left to set sign bit
const __m512i k_slBits = _mm512_set_epi64(0x0004000000040000, 0x0004000000040000,
0x0004000000040000, 0x0004000000040000,
0x0004000000040000, 0x0004000000040000,
0x0004000000040000, 0x0004000000040000);
const auto inSetSign = _mm512_sllv_epi16(inDatContig, k_slBits);
/// Mask to zero unwanted bits
const __m512i k_expMask = _mm512_set1_epi16(0xFFF0);
return _mm512_and_epi64(inSetSign, k_expMask);
}
/// Unpack compressed 9 bit data in network byte order
/// See https://soco.intel.com/docs/DOC-2665619
/// This unpacking function is for 256b registers
inline __m256i
networkByteUnpack9b256(const uint8_t* inData)
{
/// Align chunks of compressed bytes into lanes to allow for expansion
const __m256i* rawDataIn = reinterpret_cast<const __m256i*>(inData);
const auto k_expPerm = _mm256_set_epi32(5, 4, 3, 2, 3, 2, 1, 0);
const auto inLaneAlign = _mm256_permutexvar_epi32(k_expPerm, *rawDataIn);
/// Byte shuffle to get all bits for each sample into 16b chunks
/// Due to previous permute to get chunks of bytes into each lane, there is
/// a different shuffle offset in each lane
const __m256i k_byteShuffleMask = _mm256_set_epi64x(0x0809070806070506, 0x0405030402030102,
0x0708060705060405, 0x0304020301020001);
const auto inDatContig = _mm256_shuffle_epi8(inLaneAlign, k_byteShuffleMask);
/// Logical shift left to set sign bit
const __m256i k_slBits = _mm256_set_epi64x(0x0007000600050004, 0x0003000200010000,
0x0007000600050004, 0x0003000200010000);
const auto inSetSign = _mm256_sllv_epi16(inDatContig, k_slBits);
/// Mask to zero unwanted bits
const __m256i k_expMask = _mm256_set1_epi16(0xFF80);
return _mm256_and_si256(inSetSign, k_expMask);
}
/// Unpack compressed 10 bit data in network byte order
/// See https://soco.intel.com/docs/DOC-2665619
/// This unpacking function is for 256b registers
inline __m256i
networkByteUnpack10b256(const uint8_t* inData)
{
/// Align chunks of compressed bytes into lanes to allow for expansion
const __m256i* rawDataIn = reinterpret_cast<const __m256i*>(inData);
const auto k_expPerm = _mm256_set_epi32(5, 4, 3, 2, 3, 2, 1, 0);
const auto inLaneAlign = _mm256_permutexvar_epi32(k_expPerm, *rawDataIn);
/// Byte shuffle to get all bits for each sample into 16b chunks
/// Due to previous permute to get chunks of bytes into each lane, lanes
/// 0 and 2 happen to be aligned, but lane 1 is offset by 2 bytes
const __m256i k_byteShuffleMask = _mm256_set_epi64x(0x0A0B090A08090708, 0x0506040503040203,
0x0809070806070506, 0x0304020301020001);
const auto inDatContig = _mm256_shuffle_epi8(inLaneAlign, k_byteShuffleMask);
/// Logical shift left to set sign bit
const __m256i k_slBits = _mm256_set_epi64x(0x0006000400020000, 0x0006000400020000,
0x0006000400020000, 0x0006000400020000);
const auto inSetSign = _mm256_sllv_epi16(inDatContig, k_slBits);
/// Mask to zero unwanted bits
const __m256i k_expMask = _mm256_set1_epi16(0xFFC0);
return _mm256_and_si256(inSetSign, k_expMask);
}
/// Unpack compressed 12 bit data in network byte order
/// See https://soco.intel.com/docs/DOC-2665619
/// This unpacking function is for 256b registers
inline __m256i
networkByteUnpack12b256(const uint8_t* inData)
{
/// Align chunks of compressed bytes into lanes to allow for expansion
const __m256i* rawDataIn = reinterpret_cast<const __m256i*>(inData);
const auto k_expPerm = _mm256_set_epi32(6, 5, 4, 3, 3, 2, 1, 0);
const auto inLaneAlign = _mm256_permutexvar_epi32(k_expPerm, *rawDataIn);
/// Byte shuffle to get all bits for each sample into 16b chunks
/// For 12b mantissa all lanes post-permute are aligned and require same shuffle offset
const __m256i k_byteShuffleMask = _mm256_set_epi64x(0x0A0B090A07080607, 0x0405030401020001,
0x0A0B090A07080607, 0x0405030401020001);
const auto inDatContig = _mm256_shuffle_epi8(inLaneAlign, k_byteShuffleMask);
/// Logical shift left to set sign bit
const __m256i k_slBits = _mm256_set_epi64x(0x0004000000040000, 0x0004000000040000,
0x0004000000040000, 0x0004000000040000);
const auto inSetSign = _mm256_sllv_epi16(inDatContig, k_slBits);
/// Mask to zero unwanted bits
const __m256i k_expMask = _mm256_set1_epi16(0xFFF0);
return _mm256_and_si256(inSetSign, k_expMask);
}
}
/******************************************************************************
*
* Copyright (c) 2019 Intel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
/**
* @brief XRAN layer common functionality for both lls-CU and RU as well as C-plane and
* U-plane
* @file xran_common.h
* @ingroup group_source_xran
* @author Intel Corporation
**/
#ifndef _XRAN_COMMON_H_
#define _XRAN_COMMON_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/queue.h>
#include <rte_common.h>
#include <rte_mbuf.h>
#include <rte_timer.h>
#include "xran_fh_o_du.h"
#include "xran_pkt_up.h"
#include "xran_cp_api.h"
#define O_DU 0
#define O_RU 1
#define N_SC_PER_PRB 12
#define MAX_N_FULLBAND_SC 273
#define N_SYM_PER_SLOT 14
#define SUBFRAME_DURATION_US 1000
#define SLOTNUM_PER_SUBFRAME (SUBFRAME_DURATION_US/interval_us)
#define SUBFRAMES_PER_SYSTEMFRAME 10
#define SLOTS_PER_SYSTEMFRAME (SLOTNUM_PER_SUBFRAME*SUBFRAMES_PER_SYSTEMFRAME)
/* PRACH data samples are 32 bits wide, 16bits for I and 16bits for Q. Each packet contains 839 samples for long sequence or 144*14 (max) for short sequence. The payload length is 3356 octets.*/
#define PRACH_PLAYBACK_BUFFER_BYTES (144*14*4L)
#define PRACH_SRS_BUFFER_BYTES (144*14*4L)
/**< this is the configuration of M-plane */
#define XRAN_MAX_NUM_SECTIONS (N_SYM_PER_SLOT* (XRAN_MAX_ANTENNA_NR*2) + XRAN_MAX_ANT_ARRAY_ELM_NR)
#define XRAN_MAX_MBUF_LEN 9600 /**< jumbo frame */
#define NSEC_PER_SEC 1000000000L
#define TIMER_RESOLUTION_CYCLES 1596*1 /* 1us */
#define XRAN_RING_SIZE 512 /*4*14*8 pow of 2 */
#define XRAN_NAME_MAX_LEN (64)
#define XRAN_RING_NUM (3)
#define XranDiffSymIdx(prevSymIdx, currSymIdx, numTotalSymIdx) ((prevSymIdx > currSymIdx) ? ((currSymIdx + numTotalSymIdx) - prevSymIdx) : (currSymIdx - prevSymIdx))
#define XRAN_MLOG_VAR 0 /**< enable debug variables to mlog */
/* PRACH configuration table defines */
#define XRAN_PRACH_CANDIDATE_PREAMBLE (2)
#define XRAN_PRACH_CANDIDATE_Y (2)
#define XRAN_PRACH_CANDIDATE_SLOT (40)
#define XRAN_PRACH_CONFIG_TABLE_SIZE (256)
#define XRAN_PRACH_PREAMBLE_FORMAT_OF_ABC (9)
typedef enum
{
FORMAT_0 = 0,
FORMAT_1,
FORMAT_2,
FORMAT_3,
FORMAT_A1,
FORMAT_A2,
FORMAT_A3,
FORMAT_B1,
FORMAT_B2,
FORMAT_B3,
FORMAT_B4,
FORMAT_C0,
FORMAT_C2,
FORMAT_LAST
}PreambleFormatEnum;
/* add PRACH used config table, same structure as used in refPHY */
typedef struct
{
uint8_t prachConfigIdx;
uint8_t preambleFmrt[XRAN_PRACH_CANDIDATE_PREAMBLE];
uint8_t x;
uint8_t y[XRAN_PRACH_CANDIDATE_Y];
uint8_t slotNr[XRAN_PRACH_CANDIDATE_SLOT];
uint8_t slotNrNum;
uint8_t startingSym;
uint8_t nrofPrachInSlot;
uint8_t occassionsInPrachSlot;
uint8_t duration;
} xRANPrachConfigTableStruct;
typedef struct
{
uint8_t preambleFmrt;
uint16_t lRALen;
uint8_t fRA;
uint32_t nu;
uint16_t nRaCp;
}xRANPrachPreambleLRAStruct;
struct xran_prach_cp_config
{
uint8_t filterIdx;
uint8_t startSymId;
uint16_t startPrbc;
uint8_t numPrbc;
uint8_t numSymbol;
uint16_t timeOffset;
int32_t freqOffset;
uint8_t nrofPrachInSlot;
uint8_t occassionsInPrachSlot;
uint8_t x;
uint8_t y[XRAN_PRACH_CANDIDATE_Y];
uint8_t isPRACHslot[XRAN_PRACH_CANDIDATE_SLOT];
uint8_t eAxC_offset; /**< starting eAxC for PRACH stream */
};
#define XRAN_MAX_POOLS_PER_SECTOR_NR 8 /**< 2x(TX_OUT, RX_IN, PRACH_IN, SRS_IN) with C-plane */
typedef struct sectorHandleInfo
{
/**< Structure that contains the information to describe the
* instance i.e service type, virtual function, package Id etc..*/
uint16_t nIndex;
uint16_t nXranPort;
/* Unique ID of an handle shared between phy layer and library */
/**< number of antennas supported per link*/
uint32_t nBufferPoolIndex;
/**< Buffer poolIndex*/
struct rte_mempool * p_bufferPool[XRAN_MAX_POOLS_PER_SECTOR_NR];
uint32_t bufferPoolElmSz[XRAN_MAX_POOLS_PER_SECTOR_NR];
uint32_t bufferPoolNumElm[XRAN_MAX_POOLS_PER_SECTOR_NR];
}XranSectorHandleInfo, *PXranSectorHandleInfo;
typedef void (*XranSymCallbackFn)(struct rte_timer *tim, void* arg);
struct cb_elem_entry{
XranSymCallbackFn pSymCallback;
void *pSymCallbackTag;
LIST_ENTRY(cb_elem_entry) pointers;
};
/* Callback function to send mbuf to the ring */
typedef int (*xran_ethdi_mbuf_send_fn)(struct rte_mbuf *mb, uint16_t ethertype, uint16_t vf_id);
/*
* manage one cell's all Ethernet frames for one DL or UL LTE subframe
*/
typedef struct {
/* -1-this subframe is not used in current frame format
0-this subframe can be transmitted, i.e., data is ready
1-this subframe is waiting transmission, i.e., data is not ready
10 - DL transmission missing deadline. When FE needs this subframe data but bValid is still 1,
set bValid to 10.
*/
int32_t bValid ; // when UL rx, it is subframe index.
int32_t nSegToBeGen;
int32_t nSegGenerated; // how many date segment are generated by DL LTE processing or received from FE
// -1 means that DL packet to be transmitted is not ready in BS
int32_t nSegTransferred; // number of data segments has been transmitted or received
struct rte_mbuf *pData[XRAN_N_MAX_BUFFER_SEGMENT]; // point to DPDK allocated memory pool
struct xran_buffer_list sBufferList;
} BbuIoBufCtrlStruct;
#define XranIncrementJob(i) ((i >= (XRAN_SYM_JOB_SIZE-1)) ? 0 : (i+1))
#define XRAN_MAX_PKT_BURST_PER_SYM 32
#define XRAN_MAX_PACKET_FRAG 9
#define MBUF_TABLE_SIZE (2 * MAX(XRAN_MAX_PKT_BURST_PER_SYM, XRAN_MAX_PACKET_FRAG))
struct mbuf_table {
uint16_t len;
struct rte_mbuf *m_table[MBUF_TABLE_SIZE];
};
struct xran_device_ctx
{
uint8_t sector_id;
uint8_t xran_port_id;
struct xran_eaxcid_config eAxc_id_cfg;
struct xran_fh_init fh_init;
struct xran_fh_config fh_cfg;
struct xran_prach_cp_config PrachCPConfig;
uint32_t enablePrach;
uint32_t enableCP;
int32_t DynamicSectionEna;
int64_t offset_sec;
int64_t offset_nsec; //offset to GPS time calcuated based on alpha and beta
uint32_t enableSrs;
struct xran_srs_config srs_cfg; /** configuration of SRS */
BbuIoBufCtrlStruct sFrontHaulTxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
BbuIoBufCtrlStruct sFrontHaulTxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
BbuIoBufCtrlStruct sFrontHaulRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
BbuIoBufCtrlStruct sFrontHaulRxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
BbuIoBufCtrlStruct sFHPrachRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
BbuIoBufCtrlStruct sFHSrsRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANT_ARRAY_ELM_NR];
/* buffers lists */
struct xran_flat_buffer sFrontHaulTxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
struct xran_flat_buffer sFrontHaulTxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
struct xran_flat_buffer sFrontHaulRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
struct xran_flat_buffer sFrontHaulRxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
struct xran_flat_buffer sFHPrachRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
struct xran_flat_buffer sFHSrsRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANT_ARRAY_ELM_NR][XRAN_MAX_NUM_OF_SRS_SYMBOL_PER_SLOT];
xran_transport_callback_fn pCallback[XRAN_MAX_SECTOR_NR];
void *pCallbackTag[XRAN_MAX_SECTOR_NR];
xran_transport_callback_fn pPrachCallback[XRAN_MAX_SECTOR_NR];
void *pPrachCallbackTag[XRAN_MAX_SECTOR_NR];
xran_transport_callback_fn pSrsCallback[XRAN_MAX_SECTOR_NR];
void *pSrsCallbackTag[XRAN_MAX_SECTOR_NR];
LIST_HEAD(sym_cb_elem_list, cb_elem_entry) sym_cb_list_head[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
int32_t sym_up; /**< when we start sym 0 of up with respect to OTA time as measured in symbols */
int32_t sym_up_ul;
xran_fh_tti_callback_fn ttiCb[XRAN_CB_MAX];
void *TtiCbParam[XRAN_CB_MAX];
uint32_t SkipTti[XRAN_CB_MAX];
int xran2phy_mem_ready;
int rx_packet_symb_tracker[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
int rx_packet_prach_tracker[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
int rx_packet_callback_tracker[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR];
int rx_packet_prach_callback_tracker[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR];
int prach_start_symbol[XRAN_MAX_SECTOR_NR];
int prach_last_symbol[XRAN_MAX_SECTOR_NR];
int phy_tti_cb_done;
struct rte_mempool *direct_pool;
struct rte_mempool *indirect_pool;
struct mbuf_table tx_mbufs[RTE_MAX_ETHPORTS];
struct xran_common_counters fh_counters;
phy_encoder_poll_fn bbdev_enc; /**< call back to poll BBDev encoder */
phy_decoder_poll_fn bbdev_dec; /**< call back to poll BBDev decoder */
xran_ethdi_mbuf_send_fn send_cpmbuf2ring; /**< callback to send mbufs of C-Plane packets to the ring */
xran_ethdi_mbuf_send_fn send_upmbuf2ring; /**< callback to send mbufs of U-Plane packets to the ring */
uint32_t pkt_proc_core_id; /**< core used for processing DPDK timer cb */
};
extern const xRANPrachConfigTableStruct gxranPrachDataTable_sub6_fdd[XRAN_PRACH_CONFIG_TABLE_SIZE];
extern const xRANPrachConfigTableStruct gxranPrachDataTable_sub6_tdd[XRAN_PRACH_CONFIG_TABLE_SIZE];
extern const xRANPrachConfigTableStruct gxranPrachDataTable_mmw[XRAN_PRACH_CONFIG_TABLE_SIZE];
extern const xRANPrachPreambleLRAStruct gxranPreambleforLRA[13];
int process_mbuf(struct rte_mbuf *pkt);
int process_ring(struct rte_ring *r);
int ring_processing_thread(void *args);
int packets_dump_thread(void *args);
int send_symbol_ex(enum xran_pkt_dir direction,
uint16_t section_id,
struct rte_mbuf *mb,
struct rb_map *data,
const enum xran_input_byte_order iq_buf_byte_order,
uint8_t frame_id,
uint8_t subframe_id,
uint8_t slot_id,
uint8_t symbol_no,
int prb_start,
int prb_num,
uint8_t CC_ID,
uint8_t RU_Port_ID,
uint8_t seq_id);
int32_t prepare_symbol_ex(enum xran_pkt_dir direction,
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,
uint8_t slot_id,
uint8_t symbol_no,
int prb_start,
int prb_num,
uint8_t CC_ID,
uint8_t RU_Port_ID,
uint8_t seq_id,
uint32_t do_copy);
int send_cpmsg(void *pHandle, struct rte_mbuf *mbuf,struct xran_cp_gen_params *params,
struct xran_section_gen_info *sect_geninfo, uint8_t cc_id, uint8_t ru_port_id, uint8_t seq_id);
int32_t 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,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 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,
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);
struct xran_eaxcid_config *xran_get_conf_eAxC(void *pHandle);
uint8_t xran_get_conf_prach_scs(void *pHandle);
uint8_t xran_get_conf_fftsize(void *pHandle);
uint8_t xran_get_conf_numerology(void *pHandle);
uint8_t xran_get_conf_iqwidth(void *pHandle);
uint8_t xran_get_conf_compmethod(void *pHandle);
uint8_t xran_get_conf_num_bfweights(void *pHandle);
uint8_t xran_get_num_cc(void *pHandle);
uint8_t xran_get_num_eAxc(void *pHandle);
uint8_t xran_get_num_eAxcUl(void *pHandle);
uint8_t xran_get_num_ant_elm(void *pHandle);
enum xran_category xran_get_ru_category(void *pHandle);
struct xran_device_ctx *xran_dev_get_ctx(void);
int xran_register_cb_mbuf2ring(xran_ethdi_mbuf_send_fn mbuf_send_cp, xran_ethdi_mbuf_send_fn mbuf_send_up);
uint16_t xran_alloc_sectionid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id);
uint8_t xran_get_seqid(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ant_id, uint8_t slot_id);
int32_t ring_processing_func(void);
int xran_init_prach(struct xran_fh_config* pConf, struct xran_device_ctx * p_xran_dev_ctx);
void xran_updateSfnSecStart(void);
uint32_t xran_slotid_convert(uint16_t slot_id, uint16_t dir);
struct cb_elem_entry *xran_create_cb(XranSymCallbackFn cb_fn, void *cb_data);
int xran_destroy_cb(struct cb_elem_entry * cb_elm);
uint16_t xran_map_ecpriRtcid_to_vf(int32_t dir, int32_t cc_id, int32_t ru_port_id);
uint16_t xran_map_ecpriPcid_to_vf(int32_t dir, int32_t cc_id, int32_t ru_port_id);
#ifdef __cplusplus
}
#endif
#endif
/******************************************************************************
*
* Copyright (c) 2019 Intel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
/*!
\file xran_compression.h
\brief External API for compading with the use BFP algorithm.
*/
#ifndef _XRAN_COMPRESSION_H_
#define _XRAN_COMPRESSION_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/*!
\struct xranlib_compress_request
\brief Request structure containing pointer to data and its length.
*/
struct xranlib_compress_request {
int16_t *data_in; /*!< Pointer to data to compress. */
int16_t numRBs; /*!< numRBs */
int16_t numDataElements; /*!< number of elements in block process [UP: 24 i.e 12RE*2; CP: 16,32,64,128. i.e AntElm*2] */
int16_t compMethod; /*!< Compression method */
int16_t iqWidth; /*!< Bit size */
int32_t len; /*!< Length of input buffer in bytes */
};
/*!
\struct xranlib_compress_response
\brief Response structure containing pointer to data and its length.
*/
struct xranlib_compress_response {
int8_t *data_out; /*!< Pointer to data after compression. */
int32_t len; /*!< Length of output data. */
};
/*!
\struct xranlib_decompress_request
\brief Request structure containing pointer to data and its length.
*/
struct xranlib_decompress_request {
int8_t *data_in; /*!< Pointer to data to decompress. */
int16_t numRBs; /*!< numRBs */
int16_t numDataElements; /*!< number of elements in block process [UP: 24 i.e 12RE*2; CP: 16,32,64,128. i.e AntElm*2] */
int16_t compMethod; /*!< Compression method */
int16_t iqWidth; /*!< Bit size */
int32_t len; /*!< Length of input data. */
};
/*!
\struct xranlib_decompress_response
\brief Response structure containing pointer to data and its length.
*/
struct xranlib_decompress_response {
int16_t *data_out; /*!< Pointer to data after decompression. */
int32_t len; /*!< Length of output data. */
};
/*!
\brief Report the version number for the xranlib_companding library.
\param [in] version Pointer to a char buffer where the version string should be copied.
\param [in] buffer_size The length of the string buffer, must be at least
xranlib_SDK_VERSION_STRING_MAX_LEN characters.
\return 0 if the version string was populated, otherwise -1.
*/
int16_t
xranlib_companding_version(char *version, int buffer_size);
//! @{
/*!
\brief Compress functions - it converts a 16-bit linear PCM value to 8-bt A-law.
\param [in] request Structure containing the input data and data length.
\param [out] response Structure containing the output data and data length.
\return 0 for success, -1 for error
*/
int32_t
xranlib_compress(const struct xranlib_compress_request *request,
struct xranlib_compress_response *response);
int32_t
xranlib_compress_sse(const struct xranlib_compress_request *request,
struct xranlib_compress_response *response);
int32_t
xranlib_compress_avx2(const struct xranlib_compress_request *request,
struct xranlib_compress_response *response);
int32_t
xranlib_compress_avx512(const struct xranlib_compress_request *request,
struct xranlib_compress_response *response);
int32_t
xranlib_compress_avx512_bfw(const struct xranlib_compress_request *request,
struct xranlib_compress_response *response);
//! @}
//! @{
/*!
\brief Decompress function - it converts an A-law value to 16-bit linear PCM.
\param [in] request Structure containing the input data and data length.
\param [out] response Structure containing the output data and data length.
\return 0 for success, -1 for error.
**/
int32_t
xranlib_decompress(const struct xranlib_decompress_request *request,
struct xranlib_decompress_response *response);
int32_t
xranlib_decompress_sse(const struct xranlib_decompress_request *request,
struct xranlib_decompress_response *response);
int32_t
xranlib_decompress_avx2(const struct xranlib_decompress_request *request,
struct xranlib_decompress_response *response);
int32_t
xranlib_decompress_avx512(const struct xranlib_decompress_request *request,
struct xranlib_decompress_response *response);
int32_t
xranlib_decompress_avx512_bfw(const struct xranlib_decompress_request *request,
struct xranlib_decompress_response *response);
//! @}
#ifdef __cplusplus
}
#endif
#endif /* _XRAN_COMPRESSION_H_ */
/******************************************************************************
*
* Copyright (c) 2019 Intel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
#pragma once
#include <stdint.h>
#include <immintrin.h>
// This configuration file sets global constants and macros which are
// of general use throughout the project.
// All current IA processors of interest align their cache lines on
// this boundary. If the cache alignment for future processors changes
// then the most restrictive alignment should be set.
constexpr unsigned k_cacheByteAlignment = 64;
// Force the data to which this macro is applied to be aligned on a cache line.
// For example:
//
// CACHE_ALIGNED float data[64];
#define CACHE_ALIGNED alignas(k_cacheByteAlignment)
// Hint to the compiler that the data to which this macro is applied
// can be assumed to be aligned to a cache line. This allows the
// compiler to generate improved code by using aligned reads and
// writes.
#define ASSUME_CACHE_ALIGNED(data)
// __assume_aligned(data, k_cacheByteAlignment);
/// Intel compiler frequently complains about templates not being declared in an external
/// header. Templates are used throughout this project's source files to define local type-specific
/// versions of functions. Defining every one of these in a header is unnecessary, so the warnings
/// about this are turned off globally.
#pragma warning(disable:1418)
#pragma warning(disable:1419)
namespace BlockFloatCompander
{
/// Compute 32 RB at a time
static constexpr int k_numBitsIQ = 16;
static constexpr int k_numBitsIQPair = 2 * k_numBitsIQ;
static constexpr int k_maxNumBlocks = 16;
static constexpr int k_maxNumElements = 128;
static constexpr int k_numSampsExpanded = k_maxNumBlocks * k_maxNumElements;
static constexpr int k_numSampsCompressed = (k_numSampsExpanded * 2) + k_maxNumBlocks;
struct CompressedData
{
/// Compressed data
CACHE_ALIGNED uint8_t dataCompressedDataOut[k_numSampsCompressed];
CACHE_ALIGNED uint8_t *dataCompressed;
/// Size of mantissa including sign bit
int iqWidth;
/// Number of BFP blocks in message
int numBlocks;
/// Number of data elements per compression block (only required for reference function)
int numDataElements;
};
struct ExpandedData
{
/// Expanded data or input data to compressor
CACHE_ALIGNED int16_t dataExpandedIn[k_numSampsExpanded];
CACHE_ALIGNED int16_t *dataExpanded;
/// Size of mantissa including sign bit
int iqWidth;
/// Number of BFP blocks in message
int numBlocks;
/// Number of data elements per compression block (only required for reference function)
int numDataElements;
};
/// Reference compression and expansion functions
void BFPCompressRef(const ExpandedData& dataIn, CompressedData* dataOut);
void BFPExpandRef(const CompressedData& dataIn, ExpandedData* dataOut);
/// User-Plane specific compression and expansion functions
void BFPCompressUserPlaneAvx512(const ExpandedData& dataIn, CompressedData* dataOut);
void BFPExpandUserPlaneAvx512(const CompressedData& dataIn, ExpandedData* dataOut);
/// Control-Plane specific compression and expansion functions for 8 antennas
void BFPCompressCtrlPlane8Avx512(const ExpandedData& dataIn, CompressedData* dataOut);
void BFPExpandCtrlPlane8Avx512(const CompressedData& dataIn, ExpandedData* dataOut);
/// Control-Plane specific compression and expansion functions for 16 antennas
void BFPCompressCtrlPlane16Avx512(const ExpandedData& dataIn, CompressedData* dataOut);
void BFPExpandCtrlPlane16Avx512(const CompressedData& dataIn, ExpandedData* dataOut);
/// Control-Plane specific compression and expansion functions for 32 antennas
void BFPCompressCtrlPlane32Avx512(const ExpandedData& dataIn, CompressedData* dataOut);
void BFPExpandCtrlPlane32Avx512(const CompressedData& dataIn, ExpandedData* dataOut);
/// Control-Plane specific compression and expansion functions for 64 antennas
void BFPCompressCtrlPlane64Avx512(const ExpandedData& dataIn, CompressedData* dataOut);
void BFPExpandCtrlPlane64Avx512(const CompressedData& dataIn, ExpandedData* dataOut);
}
/******************************************************************************
*
* Copyright (c) 2019 Intel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
/**
* @brief This file provides the definitions for Control Plane Messages APIs.
*
* @file xran_cp_api.h
* @ingroup group_lte_source_xran
* @author Intel Corporation
*
**/
#ifndef _XRAN_CP_API_H_
#define _XRAN_CP_API_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "xran_fh_o_du.h"
#include "xran_pkt_cp.h"
#include "xran_transport.h"
#define XRAN_MAX_SECTIONDB_CTX 2
#define XRAN_MAX_NUM_EXTENSIONS XRAN_MAX_PRBS /* Maximum number of extensions in a section [up to 1 ext section per RB]*/
#define XRAN_MAX_NUM_UE 16 /* Maximum number of UEs/Lyaers */
#define XRAN_MAX_NUM_ANT_BF 64 /* Maximum number of beamforming antenna,
* could be defined as XRAN_MAX_ANTENNA_NR */
/* Maximum total number of beamforming weights (5.4.7.1.2) */
#define XRAN_MAX_BFW_N (XRAN_MAX_NUM_ANT_BF*XRAN_MAX_NUM_UE)
#define XRAN_MAX_MODCOMP_ADDPARMS 6 /* max should be even number */
#define XRAN_SECTIONEXT_ALIGN 4 /* alignment size in byte for section extension */
/** Control Plane section types, defined in 5.4 Table 5.1 */
enum xran_cp_sectiontype {
XRAN_CP_SECTIONTYPE_0 = 0, /**< Unused RB or Symbols in DL or UL, not supported */
XRAN_CP_SECTIONTYPE_1 = 1, /**< Most DL/UL Radio Channels */
XRAN_CP_SECTIONTYPE_3 = 3, /**< PRACH and Mixed-numerology Channels */
XRAN_CP_SECTIONTYPE_5 = 5, /**< UE scheduling information, not supported */
XRAN_CP_SECTIONTYPE_6 = 6, /**< Channel Information, not supported */
XRAN_CP_SECTIONTYPE_7 = 7, /**< LAA, not supported */
XRAN_CP_SECTIONTYPE_MAX
};
/** Filter index, defined in 5.4.4.3 */
enum xran_cp_filterindex {
XRAN_FILTERINDEX_STANDARD = 0, /**< UL filter for standard channel */
XRAN_FILTERINDEX_PRACH_012 = 1, /**< UL filter for PRACH preamble format 0, 1, 2 */
XRAN_FILTERINDEX_PRACH_3 = 2, /**< UL filter for PRACH preamble format 3 */
XRAN_FILTERINDEX_PRACH_ABC = 3, /**< UL filter for PRACH preamble format A1~3, B1~4, C0, C2 */
XRAN_FILTERINDEX_NPRACH = 4, /**< UL filter for NPRACH */
XRAN_FILTERINDEX_MAX
};
/** Maximum Slot Index, defined in 5.4.4.6 */
#define XRAN_SLOTID_MAX 16
/** FFT size in frame structure, defined in 5.4.4.13 Table 5.9 */
enum xran_cp_fftsize {
XRAN_FFTSIZE_128 = 7, /* 128 */
XRAN_FFTSIZE_256 = 8, /* 256 */
XRAN_FFTSIZE_512 = 9, /* 512 */
XRAN_FFTSIZE_1024 = 10, /* 1024 */
XRAN_FFTSIZE_2048 = 11, /* 2048 */
XRAN_FFTSIZE_4096 = 12, /* 4096 */
XRAN_FFTSIZE_1536 = 13, /* 1536 */
XRAN_FFTSIZE_MAX
};
/** Sub-carrier spacing, defined in 5.4.4.13 Table 5.10 */
enum xran_cp_subcarrierspacing { /*3GPP u, SCS, Nslot, Slot len */
XRAN_SCS_15KHZ = 0, /* 0, 15kHz, 1, 1ms */
XRAN_SCS_30KHZ = 1, /* 1, 30kHz, 2, 500us */
XRAN_SCS_60KHZ = 2, /* 2, 60kHz, 4, 250us */
XRAN_SCS_120KHZ = 3, /* 3, 120kHz, 8, 125us */
XRAN_SCS_240KHZ = 4, /* 4, 240kHz, 16, 62.5us */
XRAN_SCS_1P25KHZ = 12, /* NA, 1.25kHz, 1, 1ms */
XRAN_SCS_3P75KHZ = 13, /* NA, 3.75kHz, 1, 1ms */
XRAN_SCS_5KHZ = 14, /* NA, 5kHz, 1, 1ms */
XRAN_SCS_7P5KHZ = 15, /* NA, 7.5kHz, 1, 1ms */
XRAN_SCS_MAX
};
/** Resource block indicator, defined in 5.4.5.2 */
enum xran_cp_rbindicator {
XRAN_RBIND_EVERY = 0, /**< every RB used */
XRAN_RBIND_EVERYOTHER = 1, /**< every other RB used */
XRAN_RBIND_MAX
};
/** Symbol number increment command, defined in 5.4.5.3 */
enum xran_cp_symbolnuminc {
XRAN_SYMBOLNUMBER_NOTINC = 0, /**< do not increment the current symbol number */
XRAN_SYMBOLNUMBER_INC = 1, /**< increment the current symbol number and use that */
XRAN_SYMBOLNUMBER_INC_MAX
};
/** Macro to convert the number of PRBs as defined in 5.4.5.6 */
#define XRAN_CONVERT_NUMPRBC(x) ((x) > 255 ? 0 : (x))
#define XRAN_CONVERT_IQWIDTH(x) ((x) > 15 ? 0 : (x))
/** Minimum number of symbols, defined in 5.4.5.7 */
#define XRAN_SYMBOLNUMBER_MIN 1
/** Maximum number of symbols, defined in 5.4.5.7 */
#define XRAN_SYMBOLNUMBER_MAX 14
/* LAA message type 5.4.5.14 Table 5.11, not supported */
#define XRAN_LAAMSGTYPE_LBT_PDSCH_REQ 0
#define XRAN_LAAMSGTYPE_LBT_DRS_REQ 1
#define XRAN_LAAMSGTYPE_LBT_PDSCH_RSP 2
#define XRAN_LAAMSGTYPE_LBT_DRS_RSP 3
#define XRAN_LAAMSGTYPE_LBT_BUFFER_ERROR 4
#define XRAN_LAAMSGTYPE_LBT_CWCONFIG_REQ 5
#define XRAN_LAAMSGTYPE_LBT_CWCONFIG_RSP 6
#define XRAN_LBTMODE_FULL 0
#define XRAN_LBTMODE_PARTIAL25 1
#define XRAN_LBTMODE_PARTIAL34 2
#define XRAN_LBTMODE_FULLSTOP 3
#define XRAN_EF_F_LAST 0
#define XRAN_EF_F_ANOTHER_ONE 1
/** Control Plane section extension commands, defined in 5.4.6 Table 5.13 */
enum xran_cp_sectionextcmd {
XRAN_CP_SECTIONEXTCMD_0 = 0, /**< Reserved, for future use */
XRAN_CP_SECTIONEXTCMD_1 = 1, /**< Beamforming weights */
XRAN_CP_SECTIONEXTCMD_2 = 2, /**< Beamforming attributes */
XRAN_CP_SECTIONEXTCMD_3 = 3, /**< DL Precoding configuration parameters and indications, not supported */
XRAN_CP_SECTIONEXTCMD_4 = 4, /**< Modulation compression parameter */
XRAN_CP_SECTIONEXTCMD_5 = 5, /**< Modulation compression additional scaling parameters */
XRAN_CP_SECTIONEXTCMD_MAX /* 6~127 reserved for future use */
};
/** Macro to convert bfwIqWidth defined in 5.4.7.1.1, Table 5-15 */
#define XRAN_CONVERT_BFWIQWIDTH(x) ((x) > 15 ? 0 : (x))
/** Beamforming Weights Compression Method 5.4.7.1.1, Table 5-16 */
enum xran_cp_bfw_compression_method {
XRAN_BFWCOMPMETHOD_NONE = 0, /**< Uncopressed I/Q value */
XRAN_BFWCOMPMETHOD_BLKFLOAT = 1, /**< I/Q mantissa value */
XRAN_BFWCOMPMETHOD_BLKSCALE = 2, /**< I/Q scaled value */
XRAN_BFWCOMPMETHOD_ULAW = 3, /**< compressed I/Q value */
XRAN_BFWCOMPMETHOD_BEAMSPACE = 4, /**< beamspace I/Q coefficient */
XRAN_BFWCOMPMETHOD_MAX /* reserved for future methods */
};
/** Beamforming Attributes Bitwidth 5.4.7.2.1 */
enum xran_cp_bfa_bitwidth {
XRAN_BFABITWIDTH_NO = 0, /**< the filed is no applicable or the default value shall be used */
XRAN_BFABITWIDTH_2BIT = 1, /**< the filed is 2-bit bitwidth */
XRAN_BFABITWIDTH_3BIT = 2, /**< the filed is 3-bit bitwidth */
XRAN_BFABITWIDTH_4BIT = 3, /**< the filed is 4-bit bitwidth */
XRAN_BFABITWIDTH_5BIT = 4, /**< the filed is 5-bit bitwidth */
XRAN_BFABITWIDTH_6BIT = 5, /**< the filed is 6-bit bitwidth */
XRAN_BFABITWIDTH_7BIT = 6, /**< the filed is 7-bit bitwidth */
XRAN_BFABITWIDTH_8BIT = 7, /**< the filed is 8-bit bitwidth */
};
/** Layer ID for DL transmission in TM1-TM4 5.4.7.3.2 */
#define XRAN_LAYERID_0 0 /**< Layer 0 */
#define XRAN_LAYERID_1 1 /**< Layer 1 */
#define XRAN_LAYERID_2 2 /**< Layer 2 */
#define XRAN_LAYERID_3 3 /**< Layer 3 */
#define XRAN_LAYERID_TXD 0xf /**< TxD */
/** LTE Transmission Scheme for section extension type 3 5.4.7.3.3 */
#define XRAN_TXS_SMUXCDD 0 /**< Spatial Multiplexing (CDD) */
#define XRAN_TXS_SMUXNOCDD 1 /**< Spatial Multiplexing (no CDD) */
#define XRAN_TXS_TXDIV 2 /**< Transmit diversity */
/**
* This structure contains the information to generate the section body of C-Plane message */
struct xran_section_info {
uint8_t type; /* type of this section */
/* section type bit- */
/* 0 1 3 5 6 7 length */
uint8_t startSymId; /* X X X X X X 4bits */
uint8_t numSymbol; /* X X X X 4bits */
uint8_t symInc; /* X X X X X 1bit */
uint16_t id; /* X X X X X 12bits */
uint16_t reMask; /* X X X X 12bits */
uint16_t startPrbc; /* X X X X X 10bits */
uint16_t numPrbc; /* X X X X X 8bits */ /* will be converted to zero if >255 */
uint8_t rb; /* X X X X X 1bit */
uint8_t compMeth; /* X X X 4bits */
uint8_t iqWidth; /* X X X 4bits */
uint8_t ef; /* X X X X 1bit */
int32_t freqOffset; /* X 24bits */
uint16_t beamId; /* X X 15bits */
uint16_t ueId; /* X X 15bits */
uint16_t regFactor; /* X 16bits */
uint16_t pad0;
/** for U-plane */
struct xran_section_desc sec_desc[XRAN_NUM_OF_SYMBOL_PER_SLOT];
};
struct xran_sectionext1_info {
uint16_t rbNumber; /**< number RBs to ext1 chain */
uint16_t bfwNumber; /**< number of bf weights in this section */
uint8_t bfwiqWidth;
uint8_t bfwCompMeth;
int16_t *p_bfwIQ; /**< pointer to formed section extention */
int16_t bfwIQ_sz; /**< size of buffer with section extention information */
union {
uint8_t exponent;
uint8_t blockScaler;
uint8_t compBitWidthShift;
uint8_t activeBeamspaceCoeffMask[XRAN_MAX_BFW_N]; /* ceil(N/8)*8, should be multiple of 8 */
} bfwCompParam;
};
struct xran_sectionext2_info {
uint8_t bfAzPtWidth; /* beamforming zenith beamwidth parameter */
uint8_t bfAzPt;
uint8_t bfZePtWidth; /* beamforming azimuth beamwidth parameter */
uint8_t bfZePt;
uint8_t bfAz3ddWidth; /* beamforming zenith pointing parameter */
uint8_t bfAz3dd;
uint8_t bfZe3ddWidth; /* beamforming azimuth pointing parameter */
uint8_t bfZe3dd;
uint8_t bfAzSI;
uint8_t bfZeSI;
};
struct xran_sectionext3_info {
uint8_t codebookIdx;
uint8_t layerId;
uint8_t numLayers;
uint8_t txScheme;
uint16_t crsReMask;
uint8_t crsShift;
uint8_t crsSymNum;
uint16_t numAntPort; /* number of antenna port - 2 or 4 */
uint16_t beamIdAP1;
uint16_t beamIdAP2;
uint16_t beamIdAP3;
};
struct xran_sectionext4_info {
uint8_t csf;
uint8_t pad0;
uint16_t modCompScaler;
};
struct xran_sectionext5_info {
uint8_t num_sets;
struct {
uint16_t csf;
uint16_t mcScaleReMask;
uint16_t mcScaleOffset;
} mc[XRAN_MAX_MODCOMP_ADDPARMS];
};
struct xran_sectionext_info {
uint16_t type;
uint16_t len;
void *data;
};
/**
* This structure contains the information to generate the section header of C-Plane message */
struct xran_cp_header_params {
// common parameters
uint8_t filterIdx;
uint8_t frameId;
uint8_t subframeId;
uint8_t slotId;
uint8_t startSymId;
/* section type bit- */
/* 0 1 3 5 6 7 length */
uint8_t fftSize; /* X X 4bits */
uint8_t scs; /* X X 4bits */
uint8_t iqWidth; /* X X X 4bits */
uint8_t compMeth; /* X X X 4bits */
uint8_t numUEs; /* X 8bits */
uint16_t timeOffset; /* X X 16bits */
uint16_t cpLength; /* X X 16bits */
};
/** The structure for the generation of section extension */
struct xran_section_ext_gen_info {
uint16_t type; /**< the type of section extension */
uint16_t len; /**< length of extension data */
void *data; /**< pointer to extension data */
};
/**
* This structure to hold the information to generate the sections of C-Plane message */
struct xran_section_gen_info {
struct xran_section_info info; /**< The information for section */
uint32_t exDataSize; /**< The number of Extensions or type 6/7 data */
/** the array to store section extension */
struct xran_section_ext_gen_info exData[XRAN_MAX_NUM_EXTENSIONS];
struct xran_sectionext1_info m_ext1[XRAN_MAX_NUM_EXTENSIONS];
struct xran_sectionext2_info m_ext2[XRAN_MAX_NUM_EXTENSIONS];
struct xran_sectionext3_info m_ext3[XRAN_MAX_NUM_EXTENSIONS];
struct xran_sectionext4_info m_ext4[XRAN_MAX_NUM_EXTENSIONS];
struct xran_sectionext5_info m_ext5[XRAN_MAX_NUM_EXTENSIONS];
};
/**
* This structure to hold the information to generate a C-Plane message */
struct xran_cp_gen_params {
uint8_t dir; /**< UL or DL */
uint8_t sectionType; /**< each section must have same type with this */
uint16_t numSections; /**< the number of sections to generate */
struct xran_cp_header_params hdr;
/**< The information for C-Plane message header */
struct xran_section_gen_info *sections;
/**< Array of the section information */
};
/**
* This structure to hold the information of RB allocation from PHY
* to send data for allocated RBs only. */
struct xran_cp_rbmap_list {
uint16_t grp_id; /**< group id for this entry, reserved for future use */
uint8_t sym_start; /**< Start symbol ID */
uint8_t sym_num; /**< Number of symbols */
uint16_t rb_start; /**< Start RB position */
uint16_t rb_num; /**< Number of RBs */
int16_t iq_buff_offset; /**< Offset within Sym for start of IQs */
int16_t iq_buff_len; /**< length IQs */
uint16_t beam_id; /**< Bean Index */
uint8_t iqWidth; /**< I and Q width in bits */
uint8_t comp_meth; /**< Compression method */
uint8_t pad0;
};
uint16_t xran_get_cplength(int cpLength);
int32_t xran_get_freqoffset(int freqOffset, int scs);
int32_t xran_prepare_ctrl_pkt(struct rte_mbuf *mbuf,
struct xran_cp_gen_params *params,
uint8_t CC_ID, uint8_t Ant_ID,
uint8_t seq_id);
int32_t xran_parse_cp_pkt(struct rte_mbuf *mbuf,
struct xran_cp_gen_params *result,
struct xran_recv_packet_info *pkt_info);
int32_t xran_cp_init_sectiondb(void *pHandle);
int32_t xran_cp_free_sectiondb(void *pHandle);
int32_t xran_cp_add_section_info(void *pHandle,
uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
uint8_t ctx_id, struct xran_section_info *info);
int32_t xran_cp_add_multisection_info(void *pHandle,
uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id,
struct xran_cp_gen_params *gen_info);
struct xran_section_info *xran_cp_find_section_info(void *pHandle,
uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
uint8_t ctx_id, uint16_t section_id);
struct xran_section_info *xran_cp_iterate_section_info(void *pHandle,
uint8_t dir, uint8_t cc_id, uint8_t ruport_id,
uint8_t ctx_id, uint32_t *next);
int xran_cp_getsize_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id);
int xran_cp_reset_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id);
int32_t xran_cp_populate_section_ext_1(int8_t *p_ext1_dst, /**< destination buffer */
uint16_t ext1_dst_len, /**< dest buffer size */
int16_t *p_bfw_iq_src, /**< source buffer of IQs */
uint16_t rbNumber, /**< number RBs to ext1 chain */
uint16_t bfwNumber, /**< number of bf weights in this set of sections */
uint8_t bfwiqWidth, /**< bit size of IQs */
uint8_t bfwCompMeth); /**< compression method */
struct rte_mbuf *xran_attach_cp_ext_buf(int8_t* p_ext_buff_start, int8_t* p_ext_buff, uint16_t ext_buff_len,
struct rte_mbuf_ext_shared_info * p_share_data);
#ifdef __cplusplus
}
#endif
#endif /* _XRAN_CP_API_H_ */
/******************************************************************************
*
* Copyright (c) 2019 Intel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
/**
* @brief This file provides public interface to xRAN Front Haul layer implementation as defined in the
* ORAN-WG4.CUS.0-v01.00 spec. Implementation specific to
* Lower Layer Split Central Unit (O-DU): a logical node that includes the eNB/gNB functions as
* listed in section 2.1 split option 7-2x, excepting those functions allocated exclusively to the O-RU.
* The O-DU controls the operation of O-RUs for 5G NR Radio Access technology
*
* @file xran_fh_o_du.h
* @ingroup group_lte_source_xran
* @author Intel Corporation
*
**/
#ifndef _XRAN_FH_O_DU_H_
#define _XRAN_FH_O_DU_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/queue.h>
#include <netinet/in.h>
#include <setjmp.h>
#include <stdarg.h>
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <unistd.h>
#define XRAN_STATUS_SUCCESS (0)
/**<
* @ingroup xran
* Success status value. */
#define XRAN_STATUS_FAIL (-1)
/**<
* @ingroup xran
* Fail status value. */
#define XRAN_STATUS_RETRY (-2)
/**<
* @ingroup xran
* Retry status value. */
#define XRAN_STATUS_RESOURCE (-3)
/**<
* @ingroup xran
* The resource that has been requested is unavailable. Refer
* to relevant sections of the API for specifics on what the suggested
* course of action is. */
#define XRAN_STATUS_INVALID_PARAM (-4)
/**<
* @ingroup xran
* Invalid parameter has been passed in. */
#define XRAN_STATUS_FATAL (-5)
/**<
* @ingroup xran
* A serious error has occurred. Recommended course of action
* is to shutdown and restart the component. */
#define XRAN_STATUS_UNSUPPORTED (-6)
/**<
* @ingroup xran
* The function is not supported, at least not with the specific
* parameters supplied. This may be because a particular
* capability is not supported by the current implementation. */
#define XRAN_STATUS_INVALID_PACKET (-7)
/**<
* @ingroup xran
* Recevied packet does not have correct format. */
/** Macro to calculate TTI number from symbol index used by timing thread */
#define XranGetTtiNum(symIdx, numSymPerTti) (((uint32_t)symIdx / (uint32_t)numSymPerTti))
/** Macro to calculate Symbol number for given slot from symbol index */
#define XranGetSymNum(symIdx, numSymPerTti) (((uint32_t)symIdx % (uint32_t)numSymPerTti))
/** Macro to calculate Frame number for given tti */
#define XranGetFrameNum(tti,SFNatSecStart,numSubFramePerSystemFrame, numSlotPerSubFrame) ((((uint32_t)tti / ((uint32_t)numSubFramePerSystemFrame * (uint32_t)numSlotPerSubFrame)) + SFNatSecStart) & 0x3FF)
/** Macro to calculate Subframe number for given tti */
#define XranGetSubFrameNum(tti, numSlotPerSubFrame, numSubFramePerSystemFrame) (((uint32_t)tti/(uint32_t)numSlotPerSubFrame) % (uint32_t)numSubFramePerSystemFrame)
/** Macro to calculate Slot number */
#define XranGetSlotNum(tti, numSlotPerSfn) ((uint32_t)tti % ((uint32_t)numSlotPerSfn))
#define XRAN_PORTS_NUM (1) /**< number of XRAN ports (aka O-RU devices) supported */
#define XRAN_N_FE_BUF_LEN (40) /**< Number of TTIs (slots) */
#define XRAN_MAX_SECTOR_NR (12) /**< Max sectors per XRAN port */
#define XRAN_MAX_ANTENNA_NR (16) /**< Max number of extended Antenna-Carriers:
a data flow for a single antenna (or spatial stream) for a single carrier in a single sector */
/* see 10.2 Hierarchy of Radiation Structure in O-RU (assume TX and RX pannel are the same dimensions)*/
#define XRAN_MAX_PANEL_NR (1) /**< Max number of Panels supported per O-RU */
#define XRAN_MAX_TRX_ANTENNA_ARRAY (1) /**< Max number of TX and RX arrays per panel in O-RU */
#define XRAN_MAX_ANT_ARRAY_ELM_NR (64) /**< Maximum number of Antenna Array Elemets in Antenna Array in the O-RU */
#define XRAN_NUM_OF_SYMBOL_PER_SLOT (14) /**< Number of symbols per slot */
#define XRAN_MAX_NUM_OF_SRS_SYMBOL_PER_SLOT XRAN_NUM_OF_SYMBOL_PER_SLOT /**< Max Number of SRS symbols per slot */
#define XRAN_MAX_TDD_PERIODICITY (80) /**< Max TDD pattern period */
#define XRAN_MAX_CELLS_PER_PORT (XRAN_MAX_SECTOR_NR) /**< Max cells mapped to XRAN port */
#define XRAN_COMPONENT_CARRIERS_MAX (XRAN_MAX_SECTOR_NR) /**< number of CCs */
#define XRAN_NUM_OF_ANT_RADIO (XRAN_MAX_SECTOR_NR*XRAN_MAX_ANTENNA_NR) /**< Max Number of Antennas supported for all CC on single XRAN port */
#define XRAN_MAX_PRBS (275) /**< Max of PRBs per CC per antanna for 5G NR */
#define XRAN_MAX_SECTIONS_PER_SYM (16) /**< Max number of different sections in single symbol (section is equal to RB allocation for UE) */
#define XRAN_MAX_PKT_BURST (448+4) /**< 4x14x8 symbols per ms */
#define XRAN_N_MAX_BUFFER_SEGMENT XRAN_MAX_PKT_BURST /**< Max number of segments per ms */
#define XRAN_STRICT_PARM_CHECK (1) /**< enable parameter check for C-plane */
/* Slot type definition */
#define XRAN_SLOT_TYPE_INVALID (0) /**< invalid slot type */
#define XRAN_SLOT_TYPE_DL (1) /**< DL slot */
#define XRAN_SLOT_TYPE_UL (2) /**< UL slot */
#define XRAN_SLOT_TYPE_SP (3) /**< Special slot */
#define XRAN_SLOT_TYPE_FDD (4) /**< FDD slot */
#define XRAN_SLOT_TYPE_LAST (5) /**< MAX slot */
/* symbol type definition */
#define XRAN_SYMBOL_TYPE_DL (0) /**< DL symbol */
#define XRAN_SYMBOL_TYPE_UL (1) /**< UL symbol */
#define XRAN_SYMBOL_TYPE_GUARD (2) /**< GUARD symbol */
#define XRAN_SYMBOL_TYPE_FDD (3) /**< FDD symbol */
#define XRAN_NUM_OF_SLOT_IN_TDD_LOOP (80)/**< MAX number of slot for TDD repetition */
//#define _XRAN_DEBUG /**< Enable debug log */
//#define _XRAN_VERBOSE /**< Enable verbose log */
#ifdef _XRAN_DEBUG
#define xran_log_dbg(fmt, ...) \
fprintf(stderr, \
"DEBUG: %s(%d): " fmt "\n", \
__FILE__, \
__LINE__, ##__VA_ARGS__)
#else
#define xran_log_dbg(fmt, ...)
#endif
#if defined(_XRAN_DEBUG) || defined(_XRAN_VERBOSE)
#define xran_log_wrn(fmt, ...) \
fprintf( \
stderr, \
"WARNING: %s(%d): " fmt "\n", \
__FILE__, \
__LINE__, ##__VA_ARGS__)
#else
#define xran_log_dbg(fmt, ...)
#define xran_log_wrn(fmt, ...)
#endif
#define xran_log_err(fmt, ...) \
fprintf(stderr, \
"ERROR: %s(%d): " fmt "\n", \
__FILE__, \
__LINE__, ##__VA_ARGS__)
enum XranFrameDuplexType
{
XRAN_FDD = 0, XRAN_TDD
};
enum xran_if_state
{
XRAN_INIT = 0,
XRAN_RUNNING,
XRAN_STOPPED
};
/**
******************************************************************************
* @ingroup xran
*
* @description
* Compression Method 6.3.3.13, Table 6-43
*****************************************************************************/
enum xran_compression_method {
XRAN_COMPMETHOD_NONE = 0,
XRAN_COMPMETHOD_BLKFLOAT = 1,
XRAN_COMPMETHOD_BLKSCALE = 2,
XRAN_COMPMETHOD_ULAW = 3,
XRAN_COMPMETHOD_MODULATION = 4,
XRAN_COMPMETHOD_MAX
};
/**
******************************************************************************
* @ingroup xran
*
* @description
* Callback function type for symbol packet enum
*****************************************************************************/
enum callback_to_phy_id
{
XRAN_CB_TTI = 0, /**< callback on TTI boundary */
XRAN_CB_HALF_SLOT_RX =1, /**< callback on half slot (sym 7) packet arrival*/
XRAN_CB_FULL_SLOT_RX =2, /**< callback on full slot (sym 14) packet arrival */
XRAN_CB_MAX /**< max number of callbacks */
};
/** Beamforming type, enumerated as "frequency", "time" or "hybrid"
section 10.4.2 Weight-based dynamic beamforming */
enum xran_weight_based_beamforming_type {
XRAN_BF_T_FREQUENCY = 0,
XRAN_BF_T_TIME = 1,
XRAN_BF_T_HYBRID = 2,
XRAN_BF_T_MAX
};
typedef int32_t xran_status_t; /**< Xran status return value */
/** callback function type for Symbol packet */
typedef void (*xran_callback_sym_fn)(void*);
/** Callback function type for TTI event */
typedef int (*xran_fh_tti_callback_fn)(void*);
/** Callback function type packet arrival from transport layer (ETH or IP) */
typedef void (*xran_transport_callback_fn)(void*, xran_status_t);
/** Callback functions to poll BBdev encoder */
typedef int16_t (*phy_encoder_poll_fn)(void);
/** Callback functions to poll BBdev decoder */
typedef int16_t (*phy_decoder_poll_fn)(void);
/** XRAN port enum */
enum xran_vf_ports
{
XRAN_UP_VF = 0, /**< port type for U-plane */
XRAN_CP_VF, /**< port type for C-plane */
XRAN_UP_VF1, /**< port type for U-plane */
XRAN_CP_VF1, /**< port type for C-plane */
XRAN_UP_VF2, /**< port type for U-plane */
XRAN_CP_VF2, /**< port type for C-plane */
XRAN_UP_VF3, /**< port type for U-plane */
XRAN_CP_VF3, /**< port type for C-plane */
XRAN_UP_VF4, /**< port type for U-plane */
XRAN_CP_VF4, /**< port type for C-plane */
XRAN_UP_VF5, /**< port type for U-plane */
XRAN_CP_VF5, /**< port type for C-plane */
XRAN_UP_VF6, /**< port type for U-plane */
XRAN_CP_VF6, /**< port type for C-plane */
XRAN_UP_VF7, /**< port type for U-plane */
XRAN_CP_VF7, /**< port type for C-plane */
XRAN_VF_MAX
};
/** XRAN Radio Access technology enum */
enum xran_ran_tech
{
XRAN_RAN_5GNR = 0, /**< 5G NR */
XRAN_RAN_LTE = 1, /**< LTE */
XRAN_RAN_MAX
};
/** XRAN user data compression header handling types */
enum xran_comp_hdr_type
{
XRAN_COMP_HDR_TYPE_DYNAMIC = 0, /**< dynamic data format where U-plane udCompHdr controls compression parameters */
XRAN_COMP_HDR_TYPE_STATIC = 1, /**< static data format where M-plane defines compression parameters */
XRAN_COMP_HDR_TYPE_MAX
};
/** XRAN category enum */
enum xran_category
{
XRAN_CATEGORY_A = 0, /**< 5G NR Category A */
XRAN_CATEGORY_B = 1, /**< 5G NR Category B */
XRAN_CATEGORY_MAX
};
/** type of beamforming */
enum xran_beamforming_type
{
XRAN_BEAM_ID_BASED = 0, /**< beam index based */
XRAN_BEAM_WEIGHT, /**< beam forming weights */
XRAN_BEAM_ATTRIBUTE, /**< beam index based */
};
/** state of bbdev with xran */
enum xran_bbdev_init
{
XRAN_BBDEV_NOT_USED = -1, /**< BBDEV is disabled */
XRAN_BBDEV_MODE_HW_OFF = 0, /**< BBDEV is enabled for SW sim mode */
XRAN_BBDEV_MODE_HW_ON = 1, /**< BBDEV is enable for HW */
XRAN_BBDEV_MODE_MAX
};
/** callback return information */
struct xran_cb_tag {
uint16_t cellId;
uint32_t symbol;
uint32_t slotiId;
};
/** DPDK IO configuration for XRAN layer */
struct xran_io_cfg {
uint8_t id; /**< should be (0) for O-DU or (1) O-RU (debug) */
uint8_t num_vfs; /**< number of VFs for C-plane and U-plane (should be even) */
char *dpdk_dev[XRAN_VF_MAX]; /**< VFs devices */
char *bbdev_dev[1]; /**< BBDev dev name */
int32_t bbdev_mode; /**< DPDK for BBDev */
uint32_t dpdkIoVaMode; /**< IOVA Mode */
uint32_t dpdkMemorySize; /**< DPDK max memory allocation */
int32_t core; /**< reservd */
int32_t system_core; /**< reservd */
uint64_t pkt_proc_core; /**< worker mask */
int32_t pkt_aux_core; /**< reservd */
int32_t timing_core; /**< core used by xRAN */
int32_t port[XRAN_VF_MAX]; /**< VFs ports */
int32_t io_sleep; /**< enable sleep on PMD cores */
};
/** XRAN spec section 3.1.3.1.6 ecpriRtcid / ecpriPcid define */
struct xran_eaxcid_config {
uint16_t mask_cuPortId; /**< Mask CU PortId */
uint16_t mask_bandSectorId; /**< Mask Band */
uint16_t mask_ccId; /**< Mask CC */
uint16_t mask_ruPortId; /**< Mask RU Port ID */
uint8_t bit_cuPortId; /**< bandsectorId + ccId + ruportId */
uint8_t bit_bandSectorId; /**< ccId + ruPortId */
uint8_t bit_ccId; /**< ruportId */
uint8_t bit_ruPortId; /**< 0 */
};
/**
* XRAN Front haul interface initialization settings
*/
struct xran_fh_init {
struct xran_io_cfg io_cfg;/**< DPDK IO for XRAN */
struct xran_eaxcid_config eAxCId_conf; /**< config of ecpriRtcid/ecpriPcid */
uint32_t dpdkBasebandFecMode; /**< DPDK Baseband FEC device mode (0-SW, 1-HW) */
char *dpdkBasebandDevice; /**< DPDK Baseband device address */
char *filePrefix; /**< DPDK prefix */
uint32_t mtu; /**< maximum transmission unit (MTU) is the size of the largest protocol data unit (PDU) that can be communicated in a single
xRAN network layer transaction. supported 1500 bytes and 9600 bytes (Jumbo Frame) */
int8_t *p_o_du_addr; /**< O-DU Ethernet Mac Address */
int8_t *p_o_ru_addr; /**< O-RU Ethernet Mac Address */
uint16_t totalBfWeights;/**< The total number of beamforming weights on RU for extensions */
uint16_t Tadv_cp_dl; /**< Table 2 7 : xRAN Delay Management Model Parameters */
uint16_t T2a_min_cp_dl; /**< Table 2 7 : xRAN Delay Management Model Parameters */
uint16_t T2a_max_cp_dl; /**< Table 2 7 : xRAN Delay Management Model Parameters */
uint16_t T2a_min_cp_ul; /**< Table 2 7 : xRAN Delay Management Model Parameters */
uint16_t T2a_max_cp_ul; /**< Table 2 7 : xRAN Delay Management Model Parameters */
uint16_t T2a_min_up; /**< Table 2 7 : xRAN Delay Management Model Parameters */
uint16_t T2a_max_up; /**< Table 2 7 : xRAN Delay Management Model Parameters */
uint16_t Ta3_min; /**< Table 2 7 : xRAN Delay Management Model Parameters */
uint16_t Ta3_max; /**< Table 2 7 : xRAN Delay Management Model Parameters */
uint16_t T1a_min_cp_dl; /**< Table 2 7 : xRAN Delay Management Model Parameters */
uint16_t T1a_max_cp_dl; /**< Table 2 7 : xRAN Delay Management Model Parameters */
uint16_t T1a_min_cp_ul; /**< Table 2 7 : xRAN Delay Management Model Parameters */
uint16_t T1a_max_cp_ul; /**< Table 2 7 : xRAN Delay Management Model Parameters */
uint16_t T1a_min_up; /**< Table 2 7 : xRAN Delay Management Model Parameters */
uint16_t T1a_max_up; /**< Table 2 7 : xRAN Delay Management Model Parameters */
uint16_t Ta4_min; /**< Table 2 7 : xRAN Delay Management Model Parameters */
uint16_t Ta4_max; /**< Table 2 7 : xRAN Delay Management Model Parameters */
uint8_t enableCP; /**< enable C-plane */
uint8_t prachEnable; /**< enable PRACH */
uint8_t srsEnable; /**< enable SRS (Cat B specific) */
uint8_t cp_vlan_tag; /**< C-plane vlan tag */
uint8_t up_vlan_tag; /**< U-plane vlan tag */
int32_t debugStop; /**< enable auto stop */
int32_t debugStopCount; /**< enable auto stop after number of Tx packets */
int32_t DynamicSectionEna; /**< enable dynamic C-Plane section allocation */
int32_t GPS_Alpha; // refer to alpha as defined in section 9.7.2 of ORAN spec. this value should be alpha*(1/1.2288ns), range 0 - 1e7 (ns)
int32_t GPS_Beta; //beta value as defined in section 9.7.2 of ORAN spec. range -32767 ~ +32767
};
/** Beamforming waights for single stream for each PRBs given number of Antenna elements */
struct xran_cp_bf_weight{
int16_t nAntElmTRx; /**< num TRX for this allocation */
int8_t* p_ext_start; /**< pointer to start of buffer for full C-plane packet */
int8_t* p_ext_section; /**< pointer to form extType */
int16_t ext_section_sz; /**< extType section size */
};
struct xran_cp_bf_attribute{
int16_t weight[4];
};
struct xran_cp_bf_precoding{
int16_t weight[4];
};
/** section descriptor for given number of PRBs used on U-plane packet creation */
struct xran_section_desc {
uint16_t section_id; /**< section id used for this element */
int16_t iq_buffer_offset; /**< Offset in bytes for the content of IQs with in main symb buffer */
int16_t iq_buffer_len; /**< Length in bytes for the content of IQs with in main symb buffer */
uint8_t *pData; /**< optional pointer to data buffer */
void *pCtrl; /**< optional poitner to mbuf */
};
/** PRB element structure */
struct xran_prb_elm {
int16_t nRBStart; /**< start RB of RB allocation */
int16_t nRBSize; /**< number of RBs used */
int16_t nStartSymb; /**< start symbol ID */
int16_t numSymb; /**< number of symbols */
int16_t nBeamIndex; /**< beam index for given PRB */
int16_t bf_weight_update; /** need to update beam weights or not */
int16_t compMethod; /**< compression index for given PRB */
int16_t iqWidth; /**< compression bit width for given PRB */
int16_t BeamFormingType; /**< index based, weights based or attribute based beam forming*/
struct xran_section_desc * p_sec_desc[XRAN_NUM_OF_SYMBOL_PER_SLOT]; /**< section desctiptors to U-plane data given RBs */
struct xran_cp_bf_weight bf_weight; /**< beam forming information relevant for given RBs */
union {
struct xran_cp_bf_attribute bf_attribute;
struct xran_cp_bf_precoding bf_precoding;
};
};
/** PRB map structure */
struct xran_prb_map {
uint8_t dir; /**< DL or UL direction */
uint8_t xran_port; /**< xran id of given RU [0-(XRAN_PORTS_NUM-1)] */
uint16_t band_id; /**< xran band id */
uint16_t cc_id; /**< componnent carrier id [0 - (XRAN_MAX_SECTOR_NR-1)] */
uint16_t ru_port_id; /**< RU device antenna port id [0 - (XRAN_MAX_ANTENNA_NR-1) */
uint16_t tti_id; /**< xRAN slot id [0 - (max tti-1)] */
uint8_t start_sym_id; /**< start symbol Id [0-13] */
uint32_t nPrbElm; /**< total number of PRB elements for given map [0- (XRAN_MAX_PRBS-1)] */
struct xran_prb_elm prbMap[XRAN_MAX_PRBS];
};
/* PRACH config required for XRAN based FH */
struct xran_prach_config
{
/* PRACH config*/
uint8_t nPrachConfIdx; /**< PRACH Configuration Index*/
uint8_t nPrachSubcSpacing;
/**< PRACH Sub-carrier spacing
Value:0->1
For below 6GHz the values indicate 15kHz or 30kHz
For above 6GHz the values indicate 60kHz or 120kHz*/
uint8_t nPrachZeroCorrConf; /**< PRACH zeroCorrelationZoneConfig */
uint8_t nPrachRestrictSet; /**< PRACH restrictedSetConfig */
uint16_t nPrachRootSeqIdx; /**< PRACH Root Sequence Index */
uint16_t nPrachFreqStart; /**< PRACH prach-frequency-start */
int32_t nPrachFreqOffset; /**< PRACH prach-frequency-offset */
uint8_t nPrachFilterIdx; /**< PRACH Filter index */
};
/**< SRS configuration required for XRAN based FH */
struct xran_srs_config {
uint16_t symbMask; /**< symbols used for SRS with in U/S slot [bits 0-13] */
uint8_t eAxC_offset; /**< starting value of eAxC for SRS packets */
};
/** XRAN slot configuration */
struct xran_slot_config {
uint8_t nSymbolType[XRAN_NUM_OF_SYMBOL_PER_SLOT]; /**< Defines the Symbol type for all 14 symbols in a slot. 0: DL, 1: UL, 2: Guard */
uint8_t reserved[2];
};
/** XRAN front haul frame config */
struct xran_frame_config {
uint8_t nFrameDuplexType; /**< Frame Duplex type: 0 -> FDD, 1 -> TDD */
uint8_t nNumerology; /**< Numerology, determine sub carrier spacing, Value: 0->4
0: 15khz, 1: 30khz, 2: 60khz
3: 120khz, 4: 240khz */
uint8_t nTddPeriod; /**< TDD period */
struct xran_slot_config sSlotConfig[XRAN_MAX_TDD_PERIODICITY];
/**< TDD Slot configuration - If nFrameDuplexType = TDD(1), then this config defines the slot config type for each slot.*/
/* The number of slots need to be equal to nTddPeriod */
};
/** XRAN-PHY interface byte order */
enum xran_input_byte_order {
XRAN_NE_BE_BYTE_ORDER = 0, /**< Network byte order (Big endian), xRAN lib doesn't do swap */
XRAN_CPU_LE_BYTE_ORDER /**< CPU byte order (Little endian), xRAN lib does do swap */
};
/** XRAN-PHY interface I and Q order */
enum xran_input_i_q_order {
XRAN_I_Q_ORDER = 0, /**< I , Q */
XRAN_Q_I_ORDER /**< Q , I */
};
/** XRAN front haul O-RU settings */
struct xran_ru_config {
enum xran_ran_tech xranTech; /**< 5GNR or LTE */
enum xran_category xranCat; /**< mode: Catergory A or Category B */
enum xran_comp_hdr_type xranCompHdrType; /**< dynamic or static udCompHdr handling*/
uint8_t iqWidth; /**< IQ bit width */
uint8_t compMeth; /**< Compression method */
uint8_t fftSize; /**< FFT Size */
enum xran_input_byte_order byteOrder; /**< Order of bytes in int16_t in buffer. Big or little endian */
enum xran_input_i_q_order iqOrder; /**< order of IQs in the buffer */
uint16_t xran_max_frame; /**< max frame number supported */
};
/**
* @ingroup xran
* XRAN front haul general configuration */
struct xran_fh_config {
uint32_t dpdk_port; /**< DPDK port number used for FH */
uint32_t sector_id; /**< Band sector ID for FH */
uint32_t nCC; /**< number of Component carriers supported on FH */
uint32_t neAxc; /**< number of eAxc supported on one CC*/
uint32_t neAxcUl; /**< number of eAxc supported on one CC for UL direction */
uint32_t nAntElmTRx; /**< Number of antenna elements for TX and RX */
uint16_t nDLFftSize; /**< DL FFT size */
uint16_t nULFftSize; /**< UL FFT size */
uint16_t nDLRBs; /**< DL PRB */
uint16_t nULRBs; /**< UL PRB */
uint32_t nDLAbsFrePointA; /**< Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000 */
uint32_t nULAbsFrePointA; /**< Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000 */
uint32_t nDLCenterFreqARFCN; /**< center frerquency for DL in MHz */
uint32_t nULCenterFreqARFCN; /**< center frerquency for UL in MHz */
xran_fh_tti_callback_fn ttiCb; /**< call back for TTI event */
void *ttiCbParam; /**< parameters of call back function */
struct xran_prach_config prach_conf; /**< PRACH specific configurations for FH */
struct xran_srs_config srs_conf; /**< SRS specific configurations for FH */
struct xran_frame_config frame_conf; /**< frame config */
struct xran_ru_config ru_conf; /**< config of RU as per XRAN spec */
phy_encoder_poll_fn bbdev_enc; /**< call back to poll BBDev encoder */
phy_decoder_poll_fn bbdev_dec; /**< call back to poll BBDev decoder */
uint16_t tx_cp_eAxC2Vf[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR*2 + XRAN_MAX_ANT_ARRAY_ELM_NR]; /**< mapping of C-Plane (ecpriRtcid) or U-Plane (ecpriPcid) to VF */
uint16_t tx_up_eAxC2Vf[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR*2 + XRAN_MAX_ANT_ARRAY_ELM_NR]; /**< mapping of C-Plane (ecpriRtcid) or U-Plane (ecpriPcid) to VF */
uint16_t rx_cp_eAxC2Vf[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR*2 + XRAN_MAX_ANT_ARRAY_ELM_NR]; /**< mapping of C-Plane (ecpriRtcid) or U-Plane (ecpriPcid) to VF */
uint16_t rx_up_eAxC2Vf[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR*2 + XRAN_MAX_ANT_ARRAY_ELM_NR]; /**< mapping of C-Plane (ecpriRtcid) or U-Plane (ecpriPcid) to VF */
uint32_t log_level; /**< configuration of log level */
};
/**
* @ingroup xran
* XRAN front haul statistic counters according to Table 7 1 : Common Counters for both DL and UL */
struct xran_common_counters{
uint64_t Rx_on_time; /**< Data was received on time (applies to user data reception window) */
uint64_t Rx_early; /**< Data was received too early (applies to user data reception window) */
uint64_t Rx_late; /**< Data was received too late (applies to user data reception window) */
uint64_t Rx_corrupt; /**< Corrupt/Incorrect header packet */
uint64_t Rx_pkt_dupl; /**< Duplicated packet */
uint64_t Total_msgs_rcvd; /**< Total messages received (on all links) */
/* debug statistis */
uint64_t rx_counter;
uint64_t tx_counter;
uint64_t tx_bytes_counter;
uint64_t rx_bytes_counter;
uint64_t tx_bytes_per_sec;
uint64_t rx_bytes_per_sec;
uint64_t rx_pusch_packets[XRAN_MAX_ANTENNA_NR];
uint64_t rx_prach_packets[XRAN_MAX_ANTENNA_NR];
uint64_t rx_srs_packets;
};
/**
* @ingroup xran
* CC instance handle pointer type */
typedef void * xran_cc_handle_t;
/**
*****************************************************************************
* @ingroup xran
*
* @description
* A flat buffer structure. The data pointer, pData, is a virtual address.
* The API requires the memory to by physically contiguous. Each flat
* buffer segment may contain several equally sized elements.
*
*****************************************************************************/
struct xran_flat_buffer
{
uint32_t nElementLenInBytes;
/**< The Element length specified in bytes.
* This parameter specifies the size of a single element in the buffer.
* The total size of the buffer is described as
* bufferSize = nElementLenInBytes * nNumberOfElements */
uint32_t nNumberOfElements;
/**< The number of elements in the physical contiguous memory segment */
uint32_t nOffsetInBytes;
/**< Offset in bytes to the start of the data in the physical contiguous
* memory segment */
uint32_t nIsPhyAddr;
uint8_t *pData;
/**< The data pointer is a virtual address, however the actual data pointed
* to is required to be in contiguous physical memory unless the field
requiresPhysicallyContiguousMemory in CpaInstanceInfo is false. */
void *pCtrl;
/**< pointer to control section coresponding to data buffer */
};
/**
*****************************************************************************
* @ingroup xran
* Scatter/Gather buffer list containing an array of Simple buffers.
*
* @description
* A Scatter/Gather buffer list structure. It is expected that this buffer
* structure will be used where more than one flat buffer can be provided
* on a particular API.
*
* IMPORTANT - The memory for the pPrivateMetaData member must be allocated
* by the client as contiguous memory. When allocating memory for
* pPrivateMetaData a call to cpaCyBufferListGetMetaSize MUST be made to
* determine the size of the Meta Data Buffer. The returned size
* (in bytes) may then be passed in a memory allocation routine to allocate
* the pPrivateMetaData memory.
*
*****************************************************************************/
struct xran_buffer_list
{
uint32_t nNumBuffers;
/**< Number of pointers */
struct xran_flat_buffer *pBuffers;
/**< Pointer to an unbounded array containing the number of CpaFlatBuffers
* defined by nNumBuffers */
void *pUserData;
/**< This is an opaque field that is not read or modified internally. */
void *pPrivateMetaData;
/**< Private Meta representation of this buffer List - the memory for this
* buffer needs to be allocated by the client as contiguous data.
* The amount of memory required is returned with a call to
* cpaCyBufferListGetMetaSize. If cpaCyBufferListGetMetaSize returns a size
* of zero no memory needs to be allocated, and this parameter can be NULL.
*/
};
/**
* @ingroup xran
* Initialize the XRAN Layer via DPDK.
*
* @param argc
* A non-negative value. If it is greater than 0, the array members
* for argv[0] through argv[argc] (non-inclusive) shall contain pointers
* to strings.
* @param argv
* An array of strings. The contents of the array, as well as the strings
* which are pointed to by the array, may be modified by this function.
*
* @return
* 0 - on success
* Error codes returned via rte_errno
*/
int32_t xran_init(int argc, char *argv[], struct xran_fh_init *p_xran_fh_init, char *appName, void ** pHandle);
/**
* @ingroup xran
*
* Function returns handles for number of sectors supported by XRAN layer. Currently function
* supports one handle XRAN layer where it supports only one CC
*
* @param pHandle
* Pointer to XRAN layer handle
* @param nNumInstances
* total number of instances of CC
* @param pSectorInstanceHandles
* Pointer to xran_cc_handle_t where to store Handle pointer
*
* @return
* 0 - on success
*/
int32_t xran_sector_get_instances (void * pHandle, uint16_t nNumInstances,
xran_cc_handle_t * pSectorInstanceHandles);
/**
* @ingroup xran
*
* Function initialize Memory Management subsystem (mm) in order to handle memory buffers between XRAN layer
* and PHY.
*
* @param pHandle
* Pointer to XRAN layer handle for given CC
* @param nMemorySize
* memory size of all segments
* @param nMemorySegmentSize
* size of memory per segment
*
* @return
* 0 - on success
*/
int32_t xran_mm_init (void * pHandle, uint64_t nMemorySize, uint32_t nMemorySegmentSize);
/**
* @ingroup xran
*
* Function allocates buffer memory (bm) used between XRAN layer and PHY. In general case it's DPDK mbuf.
* it uses Memory Management system to get memory chunk and define memory pool on top of it.
*
* @param pHandle
* Pointer to XRAN layer handle for given CC
* @param nPoolIndex
* pointer to buffer pool identification to be returned
* @param nNumberOfBuffers
* number of buffer to allocate in the pool
* @param nBufferSize
* buffer size to allocate
*
* @return
* 0 - on success
*/
int32_t xran_bm_init (void * pHandle, uint32_t * pPoolIndex, uint32_t nNumberOfBuffers, uint32_t nBufferSize);
/**
* @ingroup xran
*
* Function allocates buffer used between XRAN layer and PHY. In general case it's DPDK mbuf.
*
* @param pHandle
* Pointer to XRAN layer handle for given CC
* @param nPoolIndex
* buffer pool identification
* @param ppData
* Pointer to pointer where to store address of new buffer
* @param ppCtrl
* Pointer to pointer where to store address of internal private control information
*
*
* @return
* 0 - on success
*/
int32_t xran_bm_allocate_buffer(void * pHandle, uint32_t nPoolIndex, void **ppData, void **ppCtrl);
/**
* @ingroup xran
*
* Function frees buffer used between XRAN layer and PHY. In general case it's DPDK mbuf
*
* @param pHandle
* Pointer to XRAN layer handle for given CC
* @param pData
* Pointer to buffer
* @param pData
* Pointer to internal private control information
*
* @return
* 0 - on success
*/
int32_t xran_bm_free_buffer(void * pHandle, void *pData, void *pCtrl);
/**
* @ingroup xran
*
* Function destroys Memory Management (MM) layer of XRAN library
*
* @param pHandle
* Pointer to XRAN layer handle for given CC
*
* @return
* 0 - on success
*/
int32_t xran_mm_destroy (void * pHandle);
/**
* @ingroup xran
*
* Function configures TX(DL) and RX(UL) output buffers and callback (UL only) for XRAN layer with
* given handle
*
* @param pHandle
* Pointer to XRAN layer handle for given CC
* @param pSrcBuffer
* list of memory buffers to use to fetch IQs from PHY to XRAN layer (DL)
* @param pSrcCpBuffer
* list of memory buffers to use to configure C-plane (DL)
* @param pDstBuffer
* list of memory buffers to use to deliver IQs from XRAN layer to PHY (UL)
* @param pDstCpBuffer
* list of memory buffers to use to configure C-plane (UL)
* @param xran_transport_callback_fn pCallback
* Callback function to call with arrival of all packets for given CC for given symbol
* @param pCallbackTag
* Parameters of Callback function
*
* @return
* 0 - on success
* -1 - on error
*/
int32_t xran_5g_fronthault_config (void * pHandle,
struct xran_buffer_list *pSrcBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
struct xran_buffer_list *pSrcCpBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
struct xran_buffer_list *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
struct xran_buffer_list *pDstCpBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
xran_transport_callback_fn pCallback,
void *pCallbackTag);
/**
* @ingroup xran
*
* Function configures PRACH output buffers and callback for XRAN layer with given handle
*
* @param pHandle
* Pointer to XRAN layer handle for given CC
* @param pDstBuffer
* list of memory buffers to use to deliver PRACH IQs from xran layer to PHY
* @param xran_transport_callback_fn pCallback
* Callback function to call with arrival of PRACH packets for given CC
* @param pCallbackTag
* Parameters of Callback function
*
* @return
* 0 - on success
* -1 - on error
*/
int32_t xran_5g_prach_req (void * pHandle,
struct xran_buffer_list *pDstBuffer[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
xran_transport_callback_fn pCallback,
void *pCallbackTag);
/**
* @ingroup xran
*
* Function configures SRS output buffers and callback for XRAN layer with given handle
*
* @param pHandle
* Pointer to XRAN layer handle for given CC
* @param pDstBuffer
* list of memory buffers to use to deliver SRS IQs from xran layer to PHY
* @param xran_transport_callback_fn pCallback
* Callback function to call with arrival of SRS packets for given CC
* @param pCallbackTag
* Parameters of Callback function
*
* @return
* 0 - on success
* -1 - on error
*/
int32_t xran_5g_srs_req (void * pHandle,
struct xran_buffer_list *pDstBuffer[XRAN_MAX_ANT_ARRAY_ELM_NR][XRAN_N_FE_BUF_LEN],
xran_transport_callback_fn pCallback,
void *pCallbackTag);
/**
* @ingroup xran
*
* Function returns XRAN core utilization stats
*
* @param total_time (out)
* Pointer to variable to store Total time thread has been running
* @param used_time (out)
* Pointer to variable to store Total time essential tasks have been running on the thread
* @param core_used (out)
* Pointer to variable to store Core on which the XRAN thread is running
* @param clear (in)
* If set to 1, then internal variables total_time and used_time are cleared
*
* @return
* 0 - on success
*/
uint32_t xran_get_time_stats(uint64_t *total_time, uint64_t *used_time, uint32_t *core_used, uint32_t clear);
/**
* @ingroup xran
*
* Function opens XRAN layer with given handle
*
* @param pHandle
* Pointer to XRAN layer handle for given CC
* @param pointer to struct xran_fh_config pConf
* Pointer to XRAN configuration structure with specific settings to use
*
* @return
* 0 - on success
*/
int32_t xran_open(void *pHandle, struct xran_fh_config* pConf);
/**
* @ingroup xran
*
* Function starts XRAN layer with given handle
*
* @param pHandle
* Pointer to XRAN layer handle for given CC
*
* @return
* 0 - on success
*/
int32_t xran_start(void *pHandle);
/**
* @ingroup xran
*
* Function stops XRAN layer with given handle
*
* @param pHandle
* Pointer to XRAN layer handle for given CC
*
* @return
* 0 - on success
*/
int32_t xran_stop(void *pHandle);
/**
* @ingroup xran
*
* Function closes XRAN layer with given handle
*
* @param pHandle
* Pointer to XRAN layer handle for given CC
*
* @return
* 0 - on success
*/
int32_t xran_close(void *pHandle);
/**
* @ingroup xran
*
* Function registers callback to XRAN layer. Function support callbacks aligned on packet arrival.
*
* @param pHandle
* Pointer to XRAN layer handle for given CC
* @param symCb
* pointer to callback function
* @param symCb
* pointer to Callback Function parameters
* @param symb
* symbol to be register for
* @param ant
* Antenna number to trigger callback for packet arrival
*
* @return
* 0 - in case of success
* -1 - in case of failure
*/
int32_t xran_reg_sym_cb(void *pHandle, xran_callback_sym_fn symCb, void * symCbParam, uint8_t symb, uint8_t ant);
/**
* @ingroup xran
*
* Function registers callback to XRAN layer. Function support callbacks align to OTA time. TTI even, half of slot,
* full slot with respect to PTP time.
*
* @param pHandle
* Pointer to XRAN layer handle for given CC
* @param Cb
* pointer to callback function
* @param cbParam
* pointer to Callback Function parameters
* @param skipTtiNum
* number of calls to be skipped before first call
* @param callback_to_phy_id
* call back time identification (see enum callback_to_phy_id)
*
* @return
* 0 - in case of success
* -1 - in case of failure
*/
int32_t xran_reg_physide_cb(void *pHandle, xran_fh_tti_callback_fn Cb, void *cbParam, int skipTtiNum, enum callback_to_phy_id);
/**
* @ingroup xran
*
* Function returns current TTI, Frame, Subframe, Slot Number as seen "Over air" base on PTP time
*
* @param nFrameIdx
* Pointer to Frame number [0-99]
*
* @param nSubframeIdx
* Pointer to Subframe number [0-10]
*
* @param nSlotIdx
* Pointer to Slot number [0-7]
*
* @param nSecond
* Pointer to current UTC second
*
* @return
* current TTI number [0-7999]
*/
int32_t xran_get_slot_idx (uint32_t *nFrameIdx, uint32_t *nSubframeIdx, uint32_t *nSlotIdx, uint64_t *nSecond);
/**
* @ingroup xran
*
* Function retrun XRAN layer common counters for given handle
*
* @param pHandle
* Pointer to XRAN layer handle for given CC
*
* @param pStats
* Pointer to pointer of common counter structure
*
* @return
* 0 - on success
*/
int32_t xran_get_common_counters(void *pXranLayerHandle, struct xran_common_counters *pStats);
/**
* @ingroup xran
*
* Function returns status of operation of FH layer
*
* @return
* XRAN_INIT - init state
* XRAN_RUNNING - running
* XRAN_STOPPED - stopped
*/
enum xran_if_state xran_get_if_state(void);
/**
* @ingroup xran
*
* Function allocates memory of given size from heap
*
* @param buf_len
* buffer size
*
* @return
* buf_len - size of memory allocation
*/
void* xran_malloc(size_t buf_len);
/**
* @ingroup xran
*
* Function frees memory of given size from heap
*
* @param buf_len
* addr - pointer to buffer
*
* @return
* void
*/
void xran_free(void *addr);
/**
* @ingroup xran
*
* Function calculates offset for ptr according to ORAN headers requared
*
* @param dst
* pointer to be addjusted
* @compMethod
* compression method according to enum xran_compression_method
*
* @return
* ptr - pointer to payload given header requared
*/
uint8_t* xran_add_hdr_offset(uint8_t *dst, int16_t compMethod);
/**
* @ingroup xran
*
* Function calculates offset for ptr according to ORAN C-plane headers requared
*
* @param dst
* pointer to be addjusted
*
* @return
* ptr - pointer to payload given header requared
*/
uint8_t *xran_add_cp_hdr_offset(uint8_t *dst);
#ifdef __cplusplus
}
#endif
#endif /* _XRAN_FH_O_DU_H_*/
/******************************************************************************
*
* Copyright (c) 2019 Intel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
/**
* @brief Header file for function to work with 5G NR frame structure and related
* routines
* @file xran_frame_struct.h
* @ingroup group_source_xran
* @author Intel Corporation
**/
#ifndef _XRAN_FRAME_STRUCT_
#define _XRAN_FRAME_STRUCT_
#ifdef __cplusplus
extern "C" {
#endif
#include "xran_fh_o_du.h"
uint32_t xran_fs_get_tti_interval(uint8_t nMu);
uint32_t xran_fs_get_scs(uint8_t nMu);
//-------------------------------------------------------------------------------------------
/** @ingroup group_nr5g_source_phy_common
*
* @param[in] nNumerology - Numerology determine sub carrier spacing, Value: 0->4 0: 15khz, 1: 30khz, 2: 60khz 3: 120khz, 4: 240khz
* @param[in] nBandwidth - Carrier bandwidth for in MHz. Value: 5->400
* @param[in] nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
*
* @return Number of RBs in cell
*
* @description
* Returns number of RBs based on 38.101-1 and 38.101-2 for the cell
*
**/
//-------------------------------------------------------------------------------------------
uint16_t xran_fs_get_num_rbs(uint32_t nNumerology, uint32_t nBandwidth, uint32_t nAbsFrePointA);
//-------------------------------------------------------------------------------------------
/** @ingroup phy_cal_nrarfcn
*
* @param[in] center frequency
*
* @return NR-ARFCN
*
* @description
* This calculates NR-ARFCN value according to center frequency
*
**/
//-------------------------------------------------------------------------------------------
uint32_t xran_fs_cal_nrarfcn(uint32_t nCenterFreq);
int32_t xran_fs_slot_limit(int32_t nSlotIdx);
void xran_fs_clear_slot_type(uint32_t nCcId);
int32_t xran_fs_set_slot_type(uint32_t nCcId, uint32_t nFrameDuplexType, uint32_t nTddPeriod, struct xran_slot_config* psSlotConfig);
int32_t xran_fs_get_slot_type(int32_t nCcId, int32_t nSlotIdx, int32_t nType);
uint32_t xran_fs_slot_limit_init(int32_t tti_interval_us);
uint32_t xran_fs_get_max_slot(void);
uint32_t xran_fs_get_max_slot_SFN(void);
int32_t xran_fs_get_symbol_type(int32_t nCellIdx, int32_t nSlotdx, int32_t nSymbIdx);
#ifdef __cplusplus
}
#endif
#endif /* _XRAN_FRAME_STRUCT_ */
/******************************************************************************
*
* Copyright (c) 2019 Intel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
/**
* @brief This file has the System Debug Trace Logger (Mlog) Task IDs used by XRAN library
* @file mlog_task_id.h
* @ingroup group_lte_source_common
* @author Intel Corporation
**/
#ifndef _XRAN_TASK_ID_H_
#define _XRAN_TASK_ID_H_
#ifdef __cplusplus
extern "C" {
#endif
#define RESOURCE_CORE_0 0
#define RESOURCE_CORE_1 1
#define RESOURCE_CORE_2 2
#define RESOURCE_CORE_3 3
#define RESOURCE_CORE_4 4
#define RESOURCE_CORE_5 5
#define RESOURCE_CORE_6 6
#define RESOURCE_CORE_7 7
#define RESOURCE_CORE_8 8
#define RESOURCE_CORE_9 9
#define RESOURCE_CORE_10 10
#define RESOURCE_CORE_11 11
#define RESOURCE_CORE_12 12
#define RESOURCE_CORE_13 13
#define RESOURCE_CORE_14 14
#define RESOURCE_CORE_15 15
#define RESOURCE_CORE_16 16
#define RESOURCE_IA_CORE 100
//--------------------------------------------------------------------
// XRAN
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// POLLING
//--------------------------------------------------------------------
#define PID_XRAN_BBDEV_DL_POLL 51
#define PID_XRAN_BBDEV_DL_POLL_DISPATCH 52
#define PID_XRAN_BBDEV_UL_POLL 53
#define PID_XRAN_BBDEV_UL_POLL_DISPATCH 54
#define PID_TTI_TIMER 2100
#define PID_TTI_CB 2101
#define PID_SYM_TIMER 2102
#define PID_GNB_PROC_TIMING_TIMEOUT 2103
#define PID_TIME_SYSTIME_POLL 2104
#define PID_TIME_SYSTIME_STOP 2105
#define PID_TIME_ARM_TIMER 2106
#define PID_TIME_ARM_TIMER_DEADLINE 2107
#define PID_RADIO_FREQ_RX_PKT 2400
#define PID_RADIO_RX_STOP 2401
#define PID_RADIO_RX_UL_IQ 2402
#define PID_RADIO_PRACH_PKT 2403
#define PID_RADIO_FE_COMPRESS 2404
#define PID_RADIO_FE_DECOMPRESS 2405
#define PID_RADIO_TX_BYPASS_PROC 2406
#define PID_RADIO_ETH_TX_BURST 2407
#define PID_RADIO_TX_DL_IQ 2408
#define PID_RADIO_RX_VALIDATE 2409
#define PID_RADIO_RX_IRQ_ON 2410
#define PID_RADIO_RX_IRQ_OFF 2411
#define PID_RADIO_RX_EPOLL_WAIT 2412
#define PID_RADIO_TX_LTEMODE_PROC 2413
#define PID_RADIO_RX_LTEMODE_PROC 2414
#define PID_RADIO_TX_PLAY_BACK_IQ 2415
#define PID_PROCESS_TX_SYM 2416
#define PID_CP_DL_CB 2500
#define PID_CP_UL_CB 2501
#define PID_UP_DL_CB 2502
#define PID_SYM_OTA_CB 2503
#define PID_TTI_CB_TO_PHY 2504
#define PID_HALF_SLOT_CB_TO_PHY 2505
#define PID_FULL_SLOT_CB_TO_PHY 2506
#define PID_UP_UL_HALF_DEAD_LINE_CB 2507
#define PID_UP_UL_FULL_DEAD_LINE_CB 2508
#define PID_PROCESS_UP_PKT 2600
#define PID_PROCESS_CP_PKT 2700
#ifdef __cplusplus
}
#endif
#endif /* _XRAN_TASK_ID_H_ */
/*******************************************************************************
*
* <COPYRIGHT_TAG>
*
*******************************************************************************/
#ifndef XRAN_LIB_WRAP_HPP
#define XRAN_LIB_WRAP_HPP
#include <exception>
#include <random>
#include <string>
#include <utility>
#include <vector>
#include <malloc.h>
#include <stdint.h>
#include "common.hpp"
#include "xran_fh_o_du.h"
#include "xran_common.h"
#include "xran_frame_struct.h"
#define XRAN_UT_CFG_FILENAME "conf.json"
#define XRAN_UT_KEY_GLOBALCFG "GLOBAL"
#define XRAN_UT_KEY_GLOBALCFG_IO "io_cfg"
#define XRAN_UT_KEY_GLOBALCFG_EAXCID "eAxCId_cfg"
#define XRAN_UT_KEY_GLOBALCFG_PRACH "prach_cfg"
#define XRAN_UT_KEY_GLOBALCFG_RU "ru_cfg"
#define XRAN_UT_KEY_GLOBALCFG_SLOT "slotcfg_"
#define MAX_NUM_OF_XRAN_CTX (2)
#define SW_FPGA_TOTAL_BUFFER_LEN (4*1024*1024*1024)
#define SW_FPGA_SEGMENT_BUFFER_LEN (1*1024*1024*1024)
#define SW_FPGA_FH_TOTAL_BUFFER_LEN (1*1024*1024*1024)
#define FPGA_TO_SW_PRACH_RX_BUFFER_LEN (8192)
#define MAX_ANT_CARRIER_SUPPORTED (XRAN_MAX_SECTOR_NR*XRAN_MAX_ANTENNA_NR)
extern "C"
{
extern uint32_t xran_lib_ota_tti;
extern uint32_t xran_lib_ota_sym;
extern uint32_t xran_lib_ota_sym_idx;
void sym_ota_cb(struct rte_timer *tim, void *arg);
void tti_ota_cb(struct rte_timer *tim, void *arg);
}
class xranLibWraper
{
public:
typedef enum
{
XRANFTHTX_OUT = 0,
XRANFTHTX_PRB_MAP_OUT,
XRANFTHTX_SEC_DESC_OUT,
XRANFTHRX_IN,
XRANFTHRX_PRB_MAP_IN,
XRANFTHTX_SEC_DESC_IN,
XRANFTHRACH_IN,
MAX_SW_XRAN_INTERFACE_NUM
} SWXRANInterfaceTypeEnum;
enum nChBw
{
PHY_BW_5MHZ = 5, PHY_BW_10MHZ = 10, PHY_BW_15MHZ = 15,
PHY_BW_20MHZ = 20, PHY_BW_25MHZ = 25, PHY_BW_30MHZ = 30,
PHY_BW_40MHZ = 40, PHY_BW_50MHZ = 50, PHY_BW_60MHZ = 60,
PHY_BW_70MHZ = 70, PHY_BW_80MHZ = 80, PHY_BW_90MHZ = 90,
PHY_BW_100MHZ = 100, PHY_BW_200MHZ = 200, PHY_BW_400MHZ = 400
};
// F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
const uint16_t nNumRbsPerSymF1[3][13] =
{
// 5MHz 10MHz 15MHz 20MHz 25MHz 30MHz 40MHz 50MHz 60MHz 70MHz 80MHz 90MHz 100MHz
{ 25, 52, 79, 106, 133, 160, 216, 270, 0, 0, 0, 0, 0 }, // Numerology 0 (15KHz)
{ 11, 24, 38, 51, 65, 78, 106, 133, 162, 0, 217, 245, 273 }, // Numerology 1 (30KHz)
{ 0, 11, 18, 24, 31, 38, 51, 65, 79, 0, 107, 121, 135 } // Numerology 2 (60KHz)
};
// F2 Tables 38.101-2 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
const uint16_t nNumRbsPerSymF2[2][4] =
{
// 50MHz 100MHz 200MHz 400MHz
{ 66, 132, 264, 0 }, // Numerology 2 (60KHz)
{ 32, 66, 132, 264 } // Numerology 3 (120KHz)
};
protected:
char argv[25] = "unittest";
std::string m_dpdk_dev_up, m_dpdk_dev_cp, m_dpdk_bbdev;
void *m_xranhandle;
uint8_t m_du_mac[6] = { 0x00,0x11, 0x22, 0x33, 0x44, 0x66 };
uint8_t m_ru_mac[6] = { 0x00,0x11, 0x22, 0x33, 0x44, 0x55 };
bool m_bSub6;
uint32_t m_nSlots = 10;
struct xran_fh_config m_xranConf;
struct xran_fh_init m_xranInit;
struct xran_timer_ctx {
uint32_t tti_to_process;
} m_timer_ctx[MAX_NUM_OF_XRAN_CTX];
/* io struct */
BbuIoBufCtrlStruct m_sFrontHaulTxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
BbuIoBufCtrlStruct m_sFrontHaulTxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
BbuIoBufCtrlStruct m_sFrontHaulRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
BbuIoBufCtrlStruct m_sFrontHaulRxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
BbuIoBufCtrlStruct m_sFHPrachRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
/* Cat B */
BbuIoBufCtrlStruct m_sFHSrsRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANT_ARRAY_ELM_NR];
/* buffers lists */
struct xran_flat_buffer m_sFrontHaulTxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
struct xran_flat_buffer m_sFrontHaulTxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
struct xran_flat_buffer m_sFrontHaulRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
struct xran_flat_buffer m_sFrontHaulRxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
struct xran_flat_buffer m_sFHPrachRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
/* Cat B SRS buffers */
struct xran_flat_buffer m_sFHSrsRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANT_ARRAY_ELM_NR][XRAN_MAX_NUM_OF_SRS_SYMBOL_PER_SLOT];
void *m_nInstanceHandle[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR]; // instance per sector
uint32_t m_nBufPoolIndex[XRAN_MAX_SECTOR_NR][MAX_SW_XRAN_INTERFACE_NUM]; // every api owns unique buffer pool
uint32_t m_nSW_ToFpga_FTH_TxBufferLen;
uint32_t m_nFpgaToSW_FTH_RxBufferLen;
int32_t m_nSectorIndex[XRAN_MAX_SECTOR_NR];
int iq_bfw_buffer_size_dl = 0;
int iq_bfw_buffer_size_ul = 0;
/* beamforming weights for UL (O-DU) */
int16_t *p_tx_dl_bfw_buffer[MAX_ANT_CARRIER_SUPPORTED];
int32_t tx_dl_bfw_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
int32_t tx_dl_bfw_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
/* beamforming weights for UL (O-DU) */
int16_t *p_tx_ul_bfw_buffer[MAX_ANT_CARRIER_SUPPORTED];
int32_t tx_ul_bfw_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
int32_t tx_ul_bfw_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
private:
json m_global_cfg;
template<typename T>
T get_globalcfg(const std::string &type, const std::string &parameter_name)
{
return m_global_cfg[XRAN_UT_KEY_GLOBALCFG][type][parameter_name];
}
template<typename T>
std::vector<T> get_globalcfg_array(const std::string &type, const std::string &parameter_name)
{
auto array_size = m_global_cfg[XRAN_UT_KEY_GLOBALCFG][type][parameter_name].size();
std::vector<T> result(array_size);
for(unsigned number = 0; number < array_size; number++)
result.at(number) = m_global_cfg[XRAN_UT_KEY_GLOBALCFG][type][parameter_name][number];
return result;
}
uint16_t get_eaxcid_mask(int numbit, int shift)
{
uint16_t result = 0;
for(int i=0; i < numbit; i++) {
result = result << 1; result +=1;
}
return (result << shift);
}
int init_memory()
{
xran_status_t status;
int32_t i, j, k, z;
SWXRANInterfaceTypeEnum eInterfaceType;
void *ptr;
void *mb;
uint32_t *u32dptr;
uint16_t *u16dptr;
uint8_t *u8dptr;
uint32_t xran_max_antenna_nr = RTE_MAX(get_num_eaxc(), get_num_eaxc_ul());
uint32_t xran_max_ant_array_elm_nr = RTE_MAX(get_num_antelmtrx(), xran_max_antenna_nr);
std::cout << "XRAN front haul xran_mm_init" << std::endl;
status = xran_mm_init(m_xranhandle, (uint64_t) SW_FPGA_FH_TOTAL_BUFFER_LEN, SW_FPGA_SEGMENT_BUFFER_LEN);
if(status != XRAN_STATUS_SUCCESS) {
std::cout << "Failed at XRAN front haul xran_mm_init" << std::endl;
return (-1);
}
/* initialize maximum instances to have flexibility for the tests */
int nInstanceNum = XRAN_MAX_SECTOR_NR;
/* initialize maximum supported CC to have flexibility on the test */
int32_t nSectorNum = 6;//XRAN_MAX_SECTOR_NR;
for(k = 0; k < XRAN_PORTS_NUM; k++) {
status = xran_sector_get_instances(m_xranhandle, nInstanceNum, &m_nInstanceHandle[k][0]);
if(status != XRAN_STATUS_SUCCESS) {
std::cout << "get sector instance failed " << k << " for XRAN nInstanceNum " << nInstanceNum << std::endl;
return (-1);
}
for (i = 0; i < nInstanceNum; i++)
std::cout << __func__ << " [" << k << "]: CC " << i << " handle " << m_nInstanceHandle[0][i] << std::endl;
}
std::cout << "Sucess xran_mm_init" << std::endl;
/* Init Memory */
for(i = 0; i<nSectorNum; i++) {
eInterfaceType = XRANFTHTX_OUT;
status = xran_bm_init(m_nInstanceHandle[0][i],
&m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType],
XRAN_N_FE_BUF_LEN * xran_max_antenna_nr * XRAN_NUM_OF_SYMBOL_PER_SLOT,
m_nSW_ToFpga_FTH_TxBufferLen);
if(status != XRAN_STATUS_SUCCESS) {
std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
return (-1);
}
for(j = 0; j < XRAN_N_FE_BUF_LEN; j++) {
for(z = 0; z < xran_max_antenna_nr; z++){
m_sFrontHaulTxBbuIoBufCtrl[j][i][z].bValid = 0;
m_sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
m_sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
m_sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
m_sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
m_sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &m_sFrontHaulTxBuffers[j][i][z][0];
for(k = 0; k < XRAN_NUM_OF_SYMBOL_PER_SLOT; k++) {
m_sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = m_nSW_ToFpga_FTH_TxBufferLen; // 14 symbols 3200bytes/symbol
m_sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
m_sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
status = xran_bm_allocate_buffer(m_nInstanceHandle[0][i], m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType], &ptr, &mb);
if(status != XRAN_STATUS_SUCCESS) {
std::cout << __LINE__ << " Failed at xran_bm_allocate_buffer, status " << status << std::endl;
return (-1);
}
m_sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
m_sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *)mb;
if(ptr) {
u32dptr = (uint32_t*)(ptr);
uint8_t *ptr_temp = (uint8_t *)ptr;
memset(u32dptr, 0x0, m_nSW_ToFpga_FTH_TxBufferLen);
}
}
}
}
/* C-plane DL */
eInterfaceType = XRANFTHTX_SEC_DESC_OUT;
status = xran_bm_init(m_nInstanceHandle[0][i],
&m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType],
XRAN_N_FE_BUF_LEN * xran_max_antenna_nr * XRAN_NUM_OF_SYMBOL_PER_SLOT*XRAN_MAX_SECTIONS_PER_SYM, sizeof(struct xran_section_desc));
if(XRAN_STATUS_SUCCESS != status) {
std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
return (-1);
}
eInterfaceType = XRANFTHTX_PRB_MAP_OUT;
status = xran_bm_init(m_nInstanceHandle[0][i],
&m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType],
XRAN_N_FE_BUF_LEN * xran_max_antenna_nr * XRAN_NUM_OF_SYMBOL_PER_SLOT,
sizeof(struct xran_prb_map));
if(status != XRAN_STATUS_SUCCESS) {
std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
return (-1);
}
for(j = 0; j < XRAN_N_FE_BUF_LEN; j++) {
for(z = 0; z < xran_max_antenna_nr; z++) {
m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0;
m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &m_sFrontHaulTxPrbMapBuffers[j][i][z];
m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nElementLenInBytes = sizeof(struct xran_prb_map);
m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nNumberOfElements = 1;
m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nOffsetInBytes = 0;
status = xran_bm_allocate_buffer(m_nInstanceHandle[0][i], m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType], &ptr, &mb);
if(status != XRAN_STATUS_SUCCESS) {
std::cout << __LINE__ << " Failed at xran_bm_allocate_buffer, status " << status << std::endl;
return (-1);
}
m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pData = (uint8_t *)ptr;
m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pCtrl = (void *)mb;
void *sd_ptr;
void *sd_mb;
int elm_id;
struct xran_prb_map * p_rb_map = (struct xran_prb_map *)ptr;
//memcpy(ptr, &startupConfiguration.PrbMap, sizeof(struct xran_prb_map));
for (elm_id = 0; elm_id < XRAN_MAX_SECTIONS_PER_SYM; elm_id++){
struct xran_prb_elm *pPrbElem = &p_rb_map->prbMap[elm_id];
for(k = 0; k < XRAN_NUM_OF_SYMBOL_PER_SLOT; k++){
status = xran_bm_allocate_buffer(m_nInstanceHandle[0][i], m_nBufPoolIndex[m_nSectorIndex[i]][XRANFTHTX_SEC_DESC_OUT], &sd_ptr, &sd_mb);
if(XRAN_STATUS_SUCCESS != status){
std::cout << __LINE__ << "SD Failed at xran_bm_allocate_buffer , status %d\n" << status << std::endl;
return (-1);
}
pPrbElem->p_sec_desc[k] = (struct xran_section_desc *)sd_ptr;
}
}
}
}
}
for(i = 0; i<nSectorNum; i++) {
eInterfaceType = XRANFTHRX_IN;
status = xran_bm_init(m_nInstanceHandle[0][i],
&m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType],
XRAN_N_FE_BUF_LEN * xran_max_antenna_nr * XRAN_NUM_OF_SYMBOL_PER_SLOT,
m_nSW_ToFpga_FTH_TxBufferLen); /* ????, actual alloc size is m_nFpgaToSW_FTH_RxBUfferLen */
if(status != XRAN_STATUS_SUCCESS) {
std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
return (-1);
}
for(j = 0;j < XRAN_N_FE_BUF_LEN; j++) {
for(z = 0; z < xran_max_antenna_nr; z++) {
m_sFrontHaulRxBbuIoBufCtrl[j][i][z].bValid = 0;
m_sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
m_sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
m_sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
m_sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
m_sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &m_sFrontHaulRxBuffers[j][i][z][0];
for(k = 0; k< XRAN_NUM_OF_SYMBOL_PER_SLOT; k++) {
m_sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = m_nFpgaToSW_FTH_RxBufferLen;
m_sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
m_sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
status = xran_bm_allocate_buffer(m_nInstanceHandle[0][i], m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType],&ptr, &mb);
if(status != XRAN_STATUS_SUCCESS) {
std::cout << __LINE__ << " Failed at xran_bm_allocate_buffer, status " << status << std::endl;
return (-1);
}
m_sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
m_sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *) mb;
if(ptr) {
u32dptr = (uint32_t*)(ptr);
uint8_t *ptr_temp = (uint8_t *)ptr;
memset(u32dptr, 0x0, m_nFpgaToSW_FTH_RxBufferLen);
}
}
}
}
eInterfaceType = XRANFTHTX_SEC_DESC_IN;
status = xran_bm_init(m_nInstanceHandle[0][i],
&m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType],
XRAN_N_FE_BUF_LEN * xran_max_antenna_nr * XRAN_NUM_OF_SYMBOL_PER_SLOT*XRAN_MAX_SECTIONS_PER_SYM, sizeof(struct xran_section_desc));
if(XRAN_STATUS_SUCCESS != status) {
std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
return (-1);
}
eInterfaceType = XRANFTHRX_PRB_MAP_IN;
status = xran_bm_init(m_nInstanceHandle[0][i],
&m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType],
XRAN_N_FE_BUF_LEN * xran_max_antenna_nr * XRAN_NUM_OF_SYMBOL_PER_SLOT,
sizeof(struct xran_prb_map));
if(status != XRAN_STATUS_SUCCESS) {
std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
return (-1);
}
for(j = 0;j < XRAN_N_FE_BUF_LEN; j++) {
for(z = 0; z < xran_max_antenna_nr; z++) {
m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0;
m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &m_sFrontHaulRxPrbMapBuffers[j][i][z];
m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nElementLenInBytes = sizeof(struct xran_prb_map);
m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nNumberOfElements = 1;
m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nOffsetInBytes = 0;
status = xran_bm_allocate_buffer(m_nInstanceHandle[0][i],m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType], &ptr, &mb);
if(status != XRAN_STATUS_SUCCESS) {
std::cout << __LINE__ << " Failed at xran_bm_allocate_buffer , status " << status << std::endl;
return (-1);
}
m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pData = (uint8_t *)ptr;
m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pCtrl = (void *)mb;
void *sd_ptr;
void *sd_mb;
int elm_id;
struct xran_prb_map * p_rb_map = (struct xran_prb_map *)ptr;
//memcpy(ptr, &startupConfiguration.PrbMap, sizeof(struct xran_prb_map));
for (elm_id = 0; elm_id < XRAN_MAX_SECTIONS_PER_SYM; elm_id++){
struct xran_prb_elm *pPrbElem = &p_rb_map->prbMap[elm_id];
for(k = 0; k < XRAN_NUM_OF_SYMBOL_PER_SLOT; k++){
status = xran_bm_allocate_buffer(m_nInstanceHandle[0][i], m_nBufPoolIndex[m_nSectorIndex[i]][XRANFTHTX_SEC_DESC_IN], &sd_ptr, &sd_mb);
if(XRAN_STATUS_SUCCESS != status){
std::cout << __LINE__ << "SD Failed at xran_bm_allocate_buffer , status %d\n" << status << std::endl;
return (-1);
}
pPrbElem->p_sec_desc[k] = (struct xran_section_desc *)sd_ptr;
}
}
}
}
}
for(i = 0; i<nSectorNum; i++) {
eInterfaceType = XRANFTHRACH_IN;
status = xran_bm_init(m_nInstanceHandle[0][i],
&m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType],
XRAN_N_FE_BUF_LEN * xran_max_antenna_nr * XRAN_NUM_OF_SYMBOL_PER_SLOT,
FPGA_TO_SW_PRACH_RX_BUFFER_LEN);
if(status != XRAN_STATUS_SUCCESS) {
std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
return (-1);
}
for(j = 0; j < XRAN_N_FE_BUF_LEN; j++) {
for(z = 0; z < xran_max_antenna_nr; z++) {
m_sFHPrachRxBbuIoBufCtrl[j][i][z].bValid = 0;
m_sFHPrachRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
m_sFHPrachRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
m_sFHPrachRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
m_sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = xran_max_antenna_nr;
m_sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &m_sFHPrachRxBuffers[j][i][z][0];
for(k = 0; k< XRAN_NUM_OF_SYMBOL_PER_SLOT; k++) {
m_sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = FPGA_TO_SW_PRACH_RX_BUFFER_LEN;
m_sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
m_sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
status = xran_bm_allocate_buffer(m_nInstanceHandle[0][i], m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType], &ptr, &mb);
if(status != XRAN_STATUS_SUCCESS) {
std::cout << __LINE__ << " Failed at xran_bm_allocate_buffer, status " << status << std::endl;
return (-1);
}
m_sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
m_sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *)mb;
if(ptr) {
u32dptr = (uint32_t*)(ptr);
memset(u32dptr, 0x0, FPGA_TO_SW_PRACH_RX_BUFFER_LEN);
}
}
}
}
}
return (0);
}
public:
xranLibWraper()
{
int i, temp;
std::string tmpstr;
unsigned int tmp_mac[6];
m_global_cfg = read_json_from_file(XRAN_UT_CFG_FILENAME);
memset(&m_xranInit, 0, sizeof(xran_fh_init));
m_xranInit.io_cfg.id = 0;
/* DPDK configuration */
m_dpdk_dev_up = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_IO, "dpdk_dev_up");
m_dpdk_dev_cp = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_IO, "dpdk_dev_cp");
m_xranInit.io_cfg.num_vfs = 2;
m_xranInit.io_cfg.dpdk_dev[XRAN_UP_VF] = (m_dpdk_dev_up == "") ? NULL : (char *)&m_dpdk_dev_up;
m_xranInit.io_cfg.dpdk_dev[XRAN_CP_VF] = (m_dpdk_dev_cp == "") ? NULL : (char *)&m_dpdk_dev_cp;
m_xranInit.io_cfg.core = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "core");
m_xranInit.io_cfg.system_core = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "system_core");
m_xranInit.io_cfg.pkt_proc_core = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "pkt_proc_core");
m_xranInit.io_cfg.pkt_aux_core = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "pkt_aux_core");
m_xranInit.io_cfg.timing_core = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "timing_core");
std::string bbdev_mode = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_IO, "bbdev_mode");
if(bbdev_mode == "sw")
m_xranInit.io_cfg.bbdev_mode = XRAN_BBDEV_MODE_HW_OFF;
else if(bbdev_mode == "hw")
m_xranInit.io_cfg.bbdev_mode = XRAN_BBDEV_MODE_HW_ON;
else if(bbdev_mode == "none")
m_xranInit.io_cfg.bbdev_mode = XRAN_BBDEV_NOT_USED;
else {
std::cout << "Invalid BBDev mode [" << bbdev_mode << "], bbdev won't be used." << std::endl;
m_xranInit.io_cfg.bbdev_mode = XRAN_BBDEV_NOT_USED;
}
m_xranInit.dpdkBasebandFecMode = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "dpdkBasebandFecMode");
m_dpdk_bbdev = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_IO, "dpdkBasebandDevice");
m_xranInit.dpdkBasebandDevice = (m_dpdk_bbdev == "") ? NULL : (char *)&m_dpdk_bbdev;
/* Network configurations */
m_xranInit.mtu = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "mtu");
std::string du_mac_str = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_IO, "o_du_macaddr");
std::string ru_mac_str = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_IO, "o_ru_macaddr");
/* using temp variables to resolve KW issue */
std::sscanf(du_mac_str.c_str(), "%02x:%02x:%02x:%02x:%02x:%02x",
&tmp_mac[0], &tmp_mac[1], &tmp_mac[2],
&tmp_mac[3], &tmp_mac[4], &tmp_mac[5]);
for(i=0; i<6; i++)
m_du_mac[i] = (uint8_t)tmp_mac[i];
std::sscanf(du_mac_str.c_str(), "%02x:%02x:%02x:%02x:%02x:%02x",
&tmp_mac[0], &tmp_mac[1], &tmp_mac[2],
&tmp_mac[3], &tmp_mac[4], &tmp_mac[5]);
for(i=0; i<6; i++)
m_ru_mac[i] = (uint8_t)tmp_mac[i];
m_xranInit.p_o_du_addr = (int8_t *)m_du_mac;
m_xranInit.p_o_ru_addr = (int8_t *)m_ru_mac;
m_xranInit.cp_vlan_tag = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "cp_vlan_tag");
m_xranInit.up_vlan_tag = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "up_vlan_tag");
/* eAxCID configurations */
int bitnum_cuport = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_EAXCID, "bit_cuPortId");
int bitnum_bandsec = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_EAXCID, "bit_bandSectorId");
int bitnum_ccid = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_EAXCID, "bit_ccId");
int bitnum_ruport = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_EAXCID, "bit_ruPortId");
m_xranInit.eAxCId_conf.bit_cuPortId = bitnum_bandsec + bitnum_ccid + bitnum_ruport;
m_xranInit.eAxCId_conf.bit_bandSectorId = bitnum_ccid + bitnum_ruport;
m_xranInit.eAxCId_conf.bit_ccId = bitnum_ruport;
m_xranInit.eAxCId_conf.bit_ruPortId = 0;
m_xranInit.eAxCId_conf.mask_cuPortId = get_eaxcid_mask(bitnum_cuport, m_xranInit.eAxCId_conf.bit_cuPortId);
m_xranInit.eAxCId_conf.mask_bandSectorId = get_eaxcid_mask(bitnum_bandsec, m_xranInit.eAxCId_conf.bit_bandSectorId);
m_xranInit.eAxCId_conf.mask_ccId = get_eaxcid_mask(bitnum_ccid, m_xranInit.eAxCId_conf.bit_ccId);
m_xranInit.eAxCId_conf.mask_ruPortId = get_eaxcid_mask(bitnum_ruport, m_xranInit.eAxCId_conf.bit_ruPortId);
m_xranInit.totalBfWeights = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "totalBfWeights");
m_xranInit.Tadv_cp_dl = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "Tadv_cp_dl");
m_xranInit.T2a_min_cp_dl = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T2a_min_cp_dl");
m_xranInit.T2a_max_cp_dl = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T2a_max_cp_dl");
m_xranInit.T2a_min_cp_ul = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T2a_min_cp_ul");
m_xranInit.T2a_max_cp_ul = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T2a_max_cp_ul");
m_xranInit.T2a_min_up = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T2a_min_up");
m_xranInit.T2a_max_up = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T2a_max_up");
m_xranInit.Ta3_min = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "Ta3_min");
m_xranInit.Ta3_max = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "Ta3_max");
m_xranInit.T1a_min_cp_dl = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T1a_min_cp_dl");
m_xranInit.T1a_max_cp_dl = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T1a_max_cp_dl");
m_xranInit.T1a_min_cp_ul = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T1a_min_cp_ul");
m_xranInit.T1a_max_cp_ul = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T1a_max_cp_ul");
m_xranInit.T1a_min_up = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T1a_min_up");
m_xranInit.T1a_max_up = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T1a_max_up");
m_xranInit.Ta4_min = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "Ta4_min");
m_xranInit.Ta4_max = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "Ta4_max");
m_xranInit.enableCP = 1;
m_xranInit.prachEnable = 1;
m_xranInit.debugStop = 0;
m_xranInit.debugStopCount = 0;
m_xranInit.DynamicSectionEna= 0;
m_xranInit.filePrefix = "wls";
m_bSub6 = get_globalcfg<bool>(XRAN_UT_KEY_GLOBALCFG_RU, "sub6");
memset(&m_xranConf, 0, sizeof(struct xran_fh_config));
tmpstr = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_RU, "duplex");
if(tmpstr == "FDD") {
m_xranConf.frame_conf.nFrameDuplexType = 0;
}
else if(tmpstr == "TDD") {
m_xranConf.frame_conf.nFrameDuplexType = 1;
std::string slotcfg_key = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_RU, "slot_config");
int numcfg = get_globalcfg<int>(slotcfg_key, "period");
m_xranConf.frame_conf.nTddPeriod = numcfg;
for(int i=0; i< numcfg; i++) {
std::stringstream slotcfgname;
slotcfgname << "slot" << i;
std::vector<int> slotcfg = get_globalcfg_array<int>(slotcfg_key, slotcfgname.str());
for(int j=0; j < slotcfg.size(); j++) {
m_xranConf.frame_conf.sSlotConfig[i].nSymbolType[j] = slotcfg[j];
}
m_xranConf.frame_conf.sSlotConfig[i].reserved[0] = 0;
m_xranConf.frame_conf.sSlotConfig[i].reserved[1] = 0;
}
}
else {
std::cout << "*** Invalid Duplex type [" << tmpstr << "] !!!" << std::endl;
std::cout << "****** Set it to FDD... " << std::endl;
m_xranConf.frame_conf.nFrameDuplexType = 0;
}
m_xranConf.frame_conf.nNumerology = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "mu");
if(m_xranConf.frame_conf.nNumerology > 3) {
std::cout << "*** Invalid Numerology [" << m_xranConf.frame_conf.nNumerology << "] !!!" << std::endl;
m_xranConf.frame_conf.nNumerology = 0;
std::cout << "****** Set it to " << m_xranConf.frame_conf.nNumerology << "..." << std::endl;
}
m_xranConf.nCC = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "num_cc");
if(m_xranConf.nCC > XRAN_MAX_SECTOR_NR) {
std::cout << "*** Exceeds maximum number of carriers supported [" << m_xranConf.nCC << "] !!!" << std::endl;
m_xranConf.nCC = XRAN_MAX_SECTOR_NR;
std::cout << "****** Adjusted to " << m_xranConf.nCC << "..." << std::endl;
}
m_xranConf.neAxc = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "num_eaxc");
if(m_xranConf.neAxc > XRAN_MAX_ANTENNA_NR) {
std::cout << "*** Exceeds maximum number of antenna supported [" << m_xranConf.neAxc << "] !!!" << std::endl;
m_xranConf.neAxc = XRAN_MAX_ANTENNA_NR;
std::cout << "****** Adjusted to " << m_xranConf.neAxc << "..." << std::endl;
}
m_bSub6 = get_globalcfg<bool>(XRAN_UT_KEY_GLOBALCFG_RU, "sub6");
temp = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "chbw_dl");
m_xranConf.nDLRBs = get_num_rbs(get_numerology(), temp, m_bSub6);
temp = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "chbw_ul");
m_xranConf.nULRBs = get_num_rbs(get_numerology(), temp, m_bSub6);
m_xranConf.nAntElmTRx = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "ant_elm_trx");
m_xranConf.nDLFftSize = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "fft_size");
m_xranConf.nULFftSize = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "fft_size");
m_xranConf.prach_conf.nPrachConfIdx = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_PRACH, "config_id");
m_xranConf.prach_conf.nPrachSubcSpacing = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_PRACH, "scs");
m_xranConf.prach_conf.nPrachFreqStart = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_PRACH, "freq_start");
m_xranConf.prach_conf.nPrachFreqOffset = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_PRACH, "freq_offset");
m_xranConf.prach_conf.nPrachFilterIdx = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_PRACH, "filter_id");
m_xranConf.prach_conf.nPrachZeroCorrConf= 0;
m_xranConf.prach_conf.nPrachRestrictSet = 0;
m_xranConf.prach_conf.nPrachRootSeqIdx = 0;
tmpstr = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_RU, "category");
if(tmpstr == "A")
m_xranConf.ru_conf.xranCat = XRAN_CATEGORY_A;
else if(tmpstr == "B")
m_xranConf.ru_conf.xranCat = XRAN_CATEGORY_B;
else {
std::cout << "*** Invalid RU Category [" << tmpstr << "] !!!" << std::endl;
std::cout << "****** Set it to Category A... " << std::endl;
m_xranConf.ru_conf.xranCat = XRAN_CATEGORY_A;
}
m_xranConf.ru_conf.iqWidth = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "iq_width");
m_xranConf.ru_conf.compMeth = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "comp_meth");
temp = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "fft_size");
m_xranConf.ru_conf.fftSize = 0;
while (temp >>= 1)
++m_xranConf.ru_conf.fftSize;
m_xranConf.ru_conf.byteOrder = XRAN_NE_BE_BYTE_ORDER;
m_xranConf.ru_conf.iqOrder = XRAN_I_Q_ORDER;
m_xranConf.log_level = 0;
/*
m_xranConf.bbdev_enc = nullptr;
m_xranConf.bbdev_dec = nullptr;
m_xranConf.ttiCb = nullptr;
m_xranConf.ttiCbParam = nullptr;
*/
}
~xranLibWraper()
{
}
int SetUp()
{
int i;
printf("O-DU MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n",
m_xranInit.p_o_du_addr[0],
m_xranInit.p_o_du_addr[1],
m_xranInit.p_o_du_addr[2],
m_xranInit.p_o_du_addr[3],
m_xranInit.p_o_du_addr[4],
m_xranInit.p_o_du_addr[5]);
printf("O-RU MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n",
m_xranInit.p_o_ru_addr[0],
m_xranInit.p_o_ru_addr[1],
m_xranInit.p_o_ru_addr[2],
m_xranInit.p_o_ru_addr[3],
m_xranInit.p_o_ru_addr[4],
m_xranInit.p_o_ru_addr[5]);
printf("eAxCID - %d:%d:%d:%d (%04x, %04x, %04x, %04x)\n",
m_xranInit.eAxCId_conf.bit_cuPortId,
m_xranInit.eAxCId_conf.bit_bandSectorId,
m_xranInit.eAxCId_conf.bit_ccId,
m_xranInit.eAxCId_conf.bit_ruPortId,
m_xranInit.eAxCId_conf.mask_cuPortId,
m_xranInit.eAxCId_conf.mask_bandSectorId,
m_xranInit.eAxCId_conf.mask_ccId,
m_xranInit.eAxCId_conf.mask_ruPortId);
printf("Total BF Weights : %d\n", m_xranInit.totalBfWeights);
xran_init(0, NULL, &m_xranInit, &argv[0], &m_xranhandle);
for(i = 0; i < XRAN_MAX_SECTOR_NR; i++)
m_nSectorIndex[i] = i;
/* set to maximum length to support multiple cases */
m_nFpgaToSW_FTH_RxBufferLen = 13168; /* 273*12*4 + 64*/
m_nSW_ToFpga_FTH_TxBufferLen = 13168; /* 273*12*4 + 64*/
if(init_memory() < 0) {
std::cout << "Fatal Error on Initialization !!!" << std::endl;
std::cout << "INIT FAILED" << std::endl;
return (-1);
}
std::cout << "INIT DONE" << std::endl;
return (0);
}
void TearDown()
{
if(m_xranhandle) {
xran_close(m_xranhandle);
m_xranhandle = nullptr;
std::cout << "CLOSE DONE" << std::endl;
}
else
std::cout << "ALREADY CLOSED" << std::endl;
}
int Init(struct xran_fh_config *pCfg = nullptr)
{
xran_status_t status;
int32_t nSectorNum;
int32_t i, j, k, z;
void *ptr;
void *mb;
uint32_t *u32dptr;
uint16_t *u16dptr;
uint8_t *u8dptr;
SWXRANInterfaceTypeEnum eInterfaceType;
int32_t cc_id, ant_id, sym_id, tti;
int32_t flowId;
char *pos = NULL;
struct xran_prb_map *pRbMap = NULL;
uint32_t xran_max_antenna_nr = RTE_MAX(get_num_eaxc(), get_num_eaxc_ul());
uint32_t xran_max_ant_array_elm_nr = RTE_MAX(get_num_antelmtrx(), xran_max_antenna_nr);
/* Update member variables */
if(pCfg)
memcpy(&m_xranConf, pCfg, sizeof(struct xran_fh_config));
/* Init timer context */
xran_lib_ota_tti = 0;
xran_lib_ota_sym = 0;
xran_lib_ota_sym_idx = 0;
for(i=0; i < MAX_NUM_OF_XRAN_CTX; i++)
m_timer_ctx[i].tti_to_process = i;
nSectorNum = get_num_cc();
/* Cat B RU support */
if(get_rucategory() == XRAN_CATEGORY_B) {
/* 10 * [14*32*273*2*2] = 4892160 bytes */
iq_bfw_buffer_size_dl = (m_nSlots * N_SYM_PER_SLOT * get_num_antelmtrx() * get_num_dlrbs() * 4L);
iq_bfw_buffer_size_ul = (m_nSlots * N_SYM_PER_SLOT * get_num_antelmtrx() * get_num_ulrbs() * 4L);
for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(get_num_cc() * get_num_eaxc()); i++) {
p_tx_dl_bfw_buffer[i] = (int16_t*)malloc(iq_bfw_buffer_size_dl);
tx_dl_bfw_buffer_size[i] = (int32_t)iq_bfw_buffer_size_dl;
if(p_tx_dl_bfw_buffer[i] == NULL)
return(-1);
memset(p_tx_dl_bfw_buffer[i], 'D', iq_bfw_buffer_size_dl);
tx_dl_bfw_buffer_position[i] = 0;
p_tx_ul_bfw_buffer[i] = (int16_t*)malloc(iq_bfw_buffer_size_ul);
tx_ul_bfw_buffer_size[i] = (int32_t)iq_bfw_buffer_size_ul;
if(p_tx_ul_bfw_buffer[i] == NULL)
return (-1);
memset(p_tx_ul_bfw_buffer[i], 'U', iq_bfw_buffer_size_ul);
tx_ul_bfw_buffer_position[i] = 0;
}
}
/* Init RB map */
for(cc_id = 0; cc_id <nSectorNum; cc_id++) {
for(tti = 0; tti < XRAN_N_FE_BUF_LEN; tti ++) {
for(ant_id = 0; ant_id < xran_max_antenna_nr; ant_id++) {
flowId = xran_max_antenna_nr*cc_id + ant_id;
/* C-plane DL */
pRbMap = (struct xran_prb_map *)m_sFrontHaulTxPrbMapBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers->pData;
if(pRbMap) {
pRbMap->dir = XRAN_DIR_DL;
pRbMap->xran_port = 0;
pRbMap->band_id = 0;
pRbMap->cc_id = cc_id;
pRbMap->ru_port_id = ant_id;
pRbMap->tti_id = tti;
pRbMap->start_sym_id = 0;
pRbMap->nPrbElm = 1;
pRbMap->prbMap[0].nRBStart = 0;
pRbMap->prbMap[0].nRBSize = get_num_dlrbs();
pRbMap->prbMap[0].nStartSymb = 0;
pRbMap->prbMap[0].numSymb = 14;
pRbMap->prbMap[0].nBeamIndex = 0;
pRbMap->prbMap[0].compMethod = XRAN_COMPMETHOD_NONE;
if(get_rucategory() == XRAN_CATEGORY_A) {
pRbMap->prbMap[0].BeamFormingType = XRAN_BEAM_ID_BASED;
pRbMap->prbMap[0].bf_weight_update = 0;
//pRbMap->prbMap[0].bf_attribute.weight[];
//pRbMap->prbMap[0].bf_precoding.weight[];
}
else if(get_rucategory() == XRAN_CATEGORY_B) {
int idxElm;
int iPrb;
char *dl_bfw_pos = ((char*)p_tx_dl_bfw_buffer[flowId]) + tx_dl_bfw_buffer_position[flowId];
struct xran_prb_elm* p_prbMap = NULL;
int num_antelm;
pRbMap->prbMap[0].BeamFormingType = XRAN_BEAM_WEIGHT;
pRbMap->prbMap[0].bf_weight_update = 1;
num_antelm = get_num_antelmtrx();
#if 0
/* populate beam weights to C-plane for each elm */
pRbMap->bf_weight.nAntElmTRx = num_antelm;
for(idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++){
p_prbMap = &pRbMap->prbMap[idxElm];
for (iPrb = p_prbMap->nRBStart; iPrb < (p_prbMap->nRBStart + p_prbMap->nRBSize); iPrb++) {
/* copy BF W IQs for 1 PRB of */
rte_memcpy(&pRbMap->bf_weight.weight[iPrb][0], (dl_bfw_pos + (iPrb * num_antelm)*4), num_antelm*4);
}
}
#endif
} /* else if(get_rucategory() == XRAN_CATEGORY_B) */
} /* if(pRbMap) */
else {
std::cout << "DL pRbMap ==NULL" << std::endl;
}
/* C-plane UL */
pRbMap = (struct xran_prb_map *)m_sFrontHaulRxPrbMapBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers->pData;
if(pRbMap) {
pRbMap->dir = XRAN_DIR_UL;
pRbMap->xran_port = 0;
pRbMap->band_id = 0;
pRbMap->cc_id = cc_id;
pRbMap->ru_port_id = ant_id;
pRbMap->tti_id = tti;
pRbMap->start_sym_id = 0;
pRbMap->nPrbElm = 1;
pRbMap->prbMap[0].nRBStart = 0;
pRbMap->prbMap[0].nRBSize = get_num_ulrbs();
pRbMap->prbMap[0].nStartSymb = 0;
pRbMap->prbMap[0].numSymb = 14;
pRbMap->prbMap[0].nBeamIndex = 0;
pRbMap->prbMap[0].compMethod = XRAN_COMPMETHOD_NONE;
if(get_rucategory() == XRAN_CATEGORY_A) {
pRbMap->prbMap[0].BeamFormingType = XRAN_BEAM_ID_BASED;
pRbMap->prbMap[0].bf_weight_update = 0;
//pRbMap->prbMap[0].bf_attribute.weight[];
//pRbMap->prbMap[0].bf_precoding.weight[];
}
else if(get_rucategory() == XRAN_CATEGORY_B) {
int idxElm;
int iPrb;
char *ul_bfw_pos = ((char*)p_tx_ul_bfw_buffer[flowId]) + tx_ul_bfw_buffer_position[flowId];
struct xran_prb_elm* p_prbMap = NULL;
int num_antelm;
pRbMap->prbMap[0].BeamFormingType = XRAN_BEAM_WEIGHT;
pRbMap->prbMap[0].bf_weight_update = 1;
num_antelm = get_num_antelmtrx();
#if 0
/* populate beam weights to C-plane for each elm */
pRbMap->bf_weight.nAntElmTRx = num_antelm;
for (idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++){
p_prbMap = &pRbMap->prbMap[idxElm];
for (iPrb = p_prbMap->nRBStart; iPrb < (p_prbMap->nRBStart + p_prbMap->nRBSize); iPrb++){
/* copy BF W IQs for 1 PRB of */
rte_memcpy(&pRbMap->bf_weight.weight[iPrb][0], (ul_bfw_pos + (iPrb*num_antelm)*4), num_antelm*4);
}
}
#endif
} /* else if(get_rucategory() == XRAN_CATEGORY_B) */
} /* if(pRbMap) */
else {
std::cout << "UL: pRbMap ==NULL" << std::endl;
}
}
}
}
return (0);
}
void Cleanup()
{
int i;
if(get_rucategory() == XRAN_CATEGORY_B) {
for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(get_num_cc() * get_num_eaxc()); i++) {
if(p_tx_dl_bfw_buffer[i]) {
free(p_tx_dl_bfw_buffer[i]);
p_tx_dl_bfw_buffer[i] == NULL;
}
if(p_tx_ul_bfw_buffer[i]) {
free(p_tx_ul_bfw_buffer[i]);
p_tx_ul_bfw_buffer[i] == NULL;
}
}
}
return;
}
void Open(xran_ethdi_mbuf_send_fn send_cp, xran_ethdi_mbuf_send_fn send_up,
void *fh_rx_callback, void *fh_rx_prach_callback, void *fh_srs_callback)
{
struct xran_fh_config *pXranConf;
int32_t nSectorNum;
int i, j, k, z;
uint32_t xran_max_antenna_nr = RTE_MAX(get_num_eaxc(), get_num_eaxc_ul());
uint32_t xran_max_ant_array_elm_nr = RTE_MAX(get_num_antelmtrx(), xran_max_antenna_nr);
struct xran_buffer_list *pFthTxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
struct xran_buffer_list *pFthTxPrbMapBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
struct xran_buffer_list *pFthRxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
struct xran_buffer_list *pFthRxPrbMapBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
struct xran_buffer_list *pFthRxRachBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
struct xran_buffer_list *pFthRxSrsBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANT_ARRAY_ELM_NR][XRAN_N_FE_BUF_LEN];
#if 0
xran_reg_physide_cb(xranHandle, physide_dl_tti_call_back, NULL, 10, XRAN_CB_TTI);
xran_reg_physide_cb(xranHandle, physide_ul_half_slot_call_back, NULL, 10, XRAN_CB_HALF_SLOT_RX);
xran_reg_physide_cb(xranHandle, physide_ul_full_slot_call_back, NULL, 10, XRAN_CB_FULL_SLOT_RX);
#endif
nSectorNum = get_num_cc();
for(i=0; i<nSectorNum; i++)
{
for(j=0; j<XRAN_N_FE_BUF_LEN; j++)
{
for(z = 0; z < xran_max_antenna_nr; z++){
pFthTxBuffer[i][z][j] = NULL;
pFthTxPrbMapBuffer[i][z][j] = NULL;
pFthRxBuffer[i][z][j] = NULL;
pFthRxPrbMapBuffer[i][z][j] = NULL;
pFthRxRachBuffer[i][z][j] = NULL;
}
for(z = 0; z < xran_max_ant_array_elm_nr; z++){
pFthRxSrsBuffer[i][z][j] = NULL;
}
}
}
for(i=0; i<nSectorNum; i++) {
for(j=0; j<XRAN_N_FE_BUF_LEN; j++) {
for(z = 0; z < xran_max_antenna_nr; z++) {
pFthTxBuffer[i][z][j] = &(m_sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList);
pFthTxPrbMapBuffer[i][z][j] = &(m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList);
pFthRxBuffer[i][z][j] = &(m_sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList);
pFthRxPrbMapBuffer[i][z][j] = &(m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList);
pFthRxRachBuffer[i][z][j] = &(m_sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList);
}
for(z = 0; z < xran_max_ant_array_elm_nr && xran_max_ant_array_elm_nr; z++){
pFthRxSrsBuffer[i][z][j] = &(m_sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList);
}
}
}
if(m_nInstanceHandle[0] != NULL) {
for(i = 0; i<nSectorNum; i++) {
xran_5g_fronthault_config(m_nInstanceHandle[0][i],
pFthTxBuffer[i], pFthTxPrbMapBuffer[i],
pFthRxBuffer[i], pFthRxPrbMapBuffer[i],
(void (*)(void *, xran_status_t))fh_rx_callback, &pFthRxBuffer[i][0]);
xran_5g_prach_req(m_nInstanceHandle[0][i], pFthRxRachBuffer[i],
(void (*)(void *, xran_status_t))fh_rx_prach_callback, &pFthRxRachBuffer[i][0]);
}
/* add SRS callback here */
for (i = 0; i<nSectorNum && xran_max_ant_array_elm_nr; i++) {
xran_5g_srs_req(m_nInstanceHandle[0][i], pFthRxSrsBuffer[i],
(void (*)(void *, xran_status_t))fh_srs_callback,&pFthRxSrsBuffer[i][0]);
}
}
xran_register_cb_mbuf2ring(send_cp, send_up);
xran_open(m_xranhandle, &m_xranConf);
}
void Close()
{
if(m_xranhandle)
xran_close(m_xranhandle);
}
int Start()
{
if(m_xranhandle)
return(xran_start(m_xranhandle));
else
return (-1);
}
int Stop()
{
if(m_xranhandle)
return(xran_stop(m_xranhandle));
else
return (-1);
}
/* emulation of timer */
void update_tti()
{
tti_ota_cb(nullptr, get_timer_ctx());
}
void update_symbol_index()
{
xran_lib_ota_sym_idx++;
if((xran_lib_ota_sym_idx % N_SYM_PER_SLOT) == 0) {
update_tti();
}
xran_lib_ota_sym++;
if(xran_lib_ota_sym >= N_SYM_PER_SLOT)
xran_lib_ota_sym = 0;
}
int apply_cpenable(bool flag)
{
struct xran_device_ctx *pCtx = xran_dev_get_ctx();
if(is_running())
return (-1);
if(pCtx == nullptr)
return (-1);
if(flag == true) {
m_xranInit.enableCP = 1;
pCtx->enableCP = 1;
}
else {
m_xranInit.enableCP = 0;
pCtx->enableCP = 0;
}
return (0);
}
int get_slot_config(const std::string &cfgname, struct xran_frame_config *pCfg)
{
int numcfg, i, j;
std::vector<int> slotcfg;
numcfg = get_globalcfg<int>(cfgname, "period");
pCfg->nTddPeriod = numcfg;
for(i=0; i < numcfg; i++) {
std::stringstream slotcfgname;
slotcfgname << "slot" << i;
std::vector<int> slotcfg = get_globalcfg_array<int>(cfgname, slotcfgname.str());
for(j=0; j < slotcfg.size(); j++)
pCfg->sSlotConfig[i].nSymbolType[j] = slotcfg[j];
pCfg->sSlotConfig[i].reserved[0] = 0; pCfg->sSlotConfig[i].reserved[1] = 0;
}
return (numcfg);
}
int get_num_rbs(uint32_t nNumerology, uint32_t nBandwidth, bool nSub6)
{
if(nNumerology > 3)
return (-1);
if(nSub6) {
if (nNumerology < 3) {
/* F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB */
switch(nBandwidth) {
case PHY_BW_5MHZ: return(nNumRbsPerSymF1[nNumerology][0]);
case PHY_BW_10MHZ: return(nNumRbsPerSymF1[nNumerology][1]);
case PHY_BW_15MHZ: return(nNumRbsPerSymF1[nNumerology][2]);
case PHY_BW_20MHZ: return(nNumRbsPerSymF1[nNumerology][3]);
case PHY_BW_25MHZ: return(nNumRbsPerSymF1[nNumerology][4]);
case PHY_BW_30MHZ: return(nNumRbsPerSymF1[nNumerology][5]);
case PHY_BW_40MHZ: return(nNumRbsPerSymF1[nNumerology][6]);
case PHY_BW_50MHZ: return(nNumRbsPerSymF1[nNumerology][7]);
case PHY_BW_60MHZ: return(nNumRbsPerSymF1[nNumerology][8]);
case PHY_BW_70MHZ: return(nNumRbsPerSymF1[nNumerology][9]);
case PHY_BW_80MHZ: return(nNumRbsPerSymF1[nNumerology][10]);
case PHY_BW_90MHZ: return(nNumRbsPerSymF1[nNumerology][11]);
case PHY_BW_100MHZ: return(nNumRbsPerSymF1[nNumerology][12]);
}
}
}
else { /* if(nSub6) */
if((nNumerology >= 2) && (nNumerology <= 3)) {
nNumerology -= 2;
/* F2 Tables 38.101-2 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB */
switch(nBandwidth) {
case PHY_BW_50MHZ: return(nNumRbsPerSymF2[nNumerology][0]); break;
case PHY_BW_100MHZ: return(nNumRbsPerSymF2[nNumerology][1]); break;
case PHY_BW_200MHZ: return(nNumRbsPerSymF2[nNumerology][2]); break;
case PHY_BW_400MHZ: return(nNumRbsPerSymF2[nNumerology][3]); break;
}
}
}
return(-1);
}
void *get_xranhandle() { return(m_xranhandle); }
void *get_timer_ctx() { return((void *)&m_timer_ctx[0]); }
int get_symbol_index() { return (xran_lib_ota_sym); }
bool is_running() { return((xran_get_if_state() == XRAN_RUNNING)?true:false); }
enum xran_category get_rucategory() { return(m_xranConf.ru_conf.xranCat); }
int get_numerology() { return(m_xranConf.frame_conf.nNumerology); }
int get_duplextype() { return(m_xranConf.frame_conf.nFrameDuplexType); }
int get_num_cc() { return(m_xranConf.nCC); }
int get_num_eaxc() { return(m_xranConf.neAxc); }
int get_num_eaxc_ul() { return(m_xranConf.neAxcUl); }
int get_num_dlrbs() { return(m_xranConf.nDLRBs); }
int get_num_ulrbs() { return(m_xranConf.nULRBs); }
int get_num_antelmtrx() { return(m_xranConf.nAntElmTRx); }
bool is_cpenable() { return(m_xranInit.enableCP); };
bool is_prachenable() { return(m_xranInit.prachEnable); };
bool is_dynamicsection() { return(m_xranInit.DynamicSectionEna?true:false); }
void get_cfg_prach(struct xran_prach_config *pCfg)
{
if(pCfg)
memcpy(pCfg, &m_xranConf.prach_conf, sizeof(struct xran_prach_config));
}
void get_cfg_frame(struct xran_frame_config *pCfg)
{
if(pCfg)
memcpy(pCfg, &m_xranConf.frame_conf, sizeof(struct xran_frame_config));
}
void get_cfg_ru(struct xran_ru_config *pCfg)
{
if(pCfg)
memcpy(pCfg, &m_xranConf.ru_conf, sizeof(struct xran_ru_config));
}
void get_cfg_fh(struct xran_fh_config *pCfg)
{
if(pCfg)
memcpy(pCfg, &m_xranConf, sizeof(struct xran_fh_config));
}
};
/* external declaration for the instance */
extern xranLibWraper *xranlib;
#endif //XRAN_LIB_WRAP_HPP
/******************************************************************************
*
* Copyright (c) 2019 Intel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
#ifndef _XRAN_MLOG_LNX_H_
#define _XRAN_MLOG_LNX_H_
#ifdef __cplusplus
extern "C"
{
#endif
#ifdef MLOG_ENABLED
#include <mlog_lnx.h>
#else
/* stubs for MLOG functions */
#define MLOG_FALSE ( 0 )
#define MLogOpen(a, b, c, d, e) MLOG_FALSE
#define MLogRestart(a) MLOG_FALSE
#define MLogPrint(a) MLOG_FALSE
#define MLogGetFileLocation() NULL
#define MLogGetFileSize() 0
#define MLogSetMask(a) MLOG_FALSE
#define MLogGetMask()
#define MLogRegisterTick()
#define MLogTick() 0
#define MLogIncrementCounter() 0
#define MLogTask(w,x,y) 0
#define MLogTaskCore(w,x,y,z) 0
#define MLogMark(x,y)
#define MLogDevInfo(x)
#define MLogRegisterFrameSubframe(x,y)
#define MLogAddVariables(x,y,z)
#define MLogGetStats(a, b, c, d, e) MLOG_FALSE
#define MLogGetAvgStats(a, b, c, d) MLOG_FALSE
#define MLogAddTestCase(a, b) MLOG_FALSE
#define MLogAddPowerStats(a, b, c, d, e) MLOG_FALSE
#endif /* MLOG_ENABLED */
#ifdef __cplusplus
}
#endif /* #ifdef __cplusplus */
#endif /* #ifndef _XRAN_MLOG_LNX_H_ */
/******************************************************************************
*
* Copyright (c) 2020 Intel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
/**
* @brief This file has the System Debug Trace Logger (Mlog) Task IDs used by PHY
* @file mlog_task_id.h
* @ingroup group_source_xran
* @author Intel Corporation
**/
#ifndef _XRAN_TASK_ID_H_
#define _XRAN_TASK_ID_H_
#ifdef __cplusplus
extern "C" {
#endif
#define RESOURCE_CORE_0 0
#define RESOURCE_CORE_1 1
#define RESOURCE_CORE_2 2
#define RESOURCE_CORE_3 3
#define RESOURCE_CORE_4 4
#define RESOURCE_CORE_5 5
#define RESOURCE_CORE_6 6
#define RESOURCE_CORE_7 7
#define RESOURCE_CORE_8 8
#define RESOURCE_CORE_9 9
#define RESOURCE_CORE_10 10
#define RESOURCE_CORE_11 11
#define RESOURCE_CORE_12 12
#define RESOURCE_CORE_13 13
#define RESOURCE_CORE_14 14
#define RESOURCE_CORE_15 15
#define RESOURCE_CORE_16 16
#define RESOURCE_IA_CORE 100
//--------------------------------------------------------------------
// XRAN APP
//--------------------------------------------------------------------
#define PID_GNB_PROC_TIMING 70
#define PID_GNB_PROC_TIMING_TIMEOUT 71
#define PID_GNB_SYM_CB 72
#define PID_GNB_PRACH_CB 73
#define PID_GNB_SRS_CB 74
#ifdef __cplusplus
}
#endif
#endif /* _XRAN_TASK_ID_H_ */
/******************************************************************************
*
* Copyright (c) 2019 Intel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
/**
* @brief Definitions and support functions to process XRAN packet
* @file xran_pkt.h
* @ingroup group_source_xran
* @author Intel Corporation
**/
/* ORAN-WG4.CUS.0-v01.00 O-RAN Fronthaul Working Group
Control, User and Synchronization Plane Specification
*/
/*
* Layer common to data and control packets
*/
#ifndef _XRAN_PKT_H_
#define _XRAN_PKT_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <rte_common.h>
#include <rte_ether.h>
#include <rte_byteorder.h>
/**
*****************************************************************************
* @file xran_pkt.h
*
* @defgroup xran_common_pkt XRAN Packet definitions and functions
* @ingroup xran
*
* @description
* Definitions and support functions to process XRAN packet
*****************************************************************************/
#define ECPRI_MAX_PAYLOAD_SIZE 65535 /**< Max packet size taken in this implementation */
/* XRAN spec: For this encapsulation, either the eCPRI Ethertype or the IEEE 1914.3 Ethertype shall be use */
#define XRAN_ETHER_TYPE 0xAEFE /**< defined by eCPRI Specification V1.1 */
#define XRAN_ECPRI_VER 0x0001 /**< eCPRI protocol revision 3.1.3.1.1 */
#define XRAN_PAYLOAD_VER 0x0001 /**< Payload version 5.4.4.2 */
#define VLAN_ID 0 /**< Default Tag protocol identifier (TPID)*/
#define VLAN_PCP 7 /**< U-Plane and C-Plane only see Table 3 5 : Quality of service classes */
/**
******************************************************************************
* @ingroup xran_common_pkt
*
* @description
* eCPRI message types
* as per eCPRI spec 3.2.4. Message Types
*****************************************************************************/
enum ecpri_msg_type
{
ECPRI_IQ_DATA = 0x00, /**< U-plane: IQ data */
ECPRI_BIT_SEQUENCE = 0x01, /* msg type is not supported */
ECPRI_RT_CONTROL_DATA = 0x02, /**< C-plane: Control */
/* Below msg types are not supported */
ECPRI_GEN_DATA_TRANSFER = 0x03,
ECPRI_REMOTE_MEM_ACCESS = 0x04,
ECPRI_DELAY_MEASUREMENT = 0x05,
ECPRI_REMOTE_RESET = 0x06,
ECPRI_EVENT_INDICATION = 0x07,
ECPRI_MSG_TYPE_MAX
};
/**
******************************************************************************
* @ingroup xran_common_pkt
*
* @description
* see 3.1.3.1.7 ecpriSeqid (message identifier)
*****************************************************************************/
struct ecpri_seq_id
{
uint8_t seq_id:8; /**< Sequence ID */
uint8_t sub_seq_id:7; /**< Subsequence ID */
uint8_t e_bit:1; /**< E bit */
} __rte_packed;
/**
******************************************************************************
* @ingroup xran_common_pkt
*
* @description
* Structure holds common eCPRI header as per
* Table 3 1 : eCPRI Transport Header Field Definitions
*****************************************************************************/
struct xran_ecpri_cmn_hdr
{
uint8_t ecpri_concat:1; /**< 3.1.3.1.3 eCPRI concatenation indicator */
uint8_t ecpri_resv:3; /**< 3.1.3.1.2 eCPRI reserved */
uint8_t ecpri_ver:4; /**< 3.1.3.1.1 eCPRI protocol revision, defined in XRAN_ECPRI_VER */
uint8_t ecpri_mesg_type; /**< 3.1.3.1.4 eCPRI message type, defined in ecpri_msg_type */
uint16_t ecpri_payl_size; /**< 3.1.3.1.5 eCPRI payload size, without common header and any padding bytes */
} __rte_packed;
/**
******************************************************************************
* @ingroup xran_common_pkt
*
* @description
* Structure holds eCPRI transport header as per
* Table 3 1 : eCPRI Transport Header Field Definitions
*****************************************************************************/
struct xran_ecpri_hdr
{
struct xran_ecpri_cmn_hdr cmnhdr;
rte_be16_t ecpri_xtc_id; /**< 3.1.3.1.6 real time control data / IQ data transfer message series identifier */
struct ecpri_seq_id ecpri_seq_id; /**< 3.1.3.1.7 message identifier */
} __rte_packed;
/**
******************************************************************************
* @ingroup xran_common_pkt
*
* @description
* Enum used to set xRAN packet data direction (gNB Tx/Rx 5.4.4.1)
* uplink or downlink
*****************************************************************************/
enum xran_pkt_dir
{
XRAN_DIR_UL = 0, /**< UL direction */
XRAN_DIR_DL = 1, /**< DL direction */
XRAN_DIR_MAX
};
/**
******************************************************************************
* @ingroup xran_common_pkt
*
* @description
* Structure holds components of radio application header
* 5.4.4 Coding of Information Elements - Application Layer, Common
* for U-plane as per 6.3.2 DL/UL Data
*****************************************************************************/
struct radio_app_common_hdr
{
/* Octet 9 */
uint8_t filter_id:4; /**< This parameter defines an index to the channel filter to be
used between IQ data and air interface, both in DL and UL.
For most physical channels filterIndex =0000b is used which
indexes the standard channel filter, e.g. 100MHz channel filter
for 100MHz nominal carrier bandwidth. (see 5.4.4.3 for more) */
uint8_t payl_ver:3; /**< This parameter defines the payload protocol version valid
for the following IEs in the application layer. In this version of
the specification payloadVersion=001b shall be used. */
uint8_t data_direction:1; /**< This parameter indicates the gNB data direction. */
/* Octet 10 */
uint8_t frame_id:8; /**< This parameter is a counter for 10 ms frames (wrapping period 2.56 seconds) */
/* Octet 11 */
/* Octet 12 */
union {
uint16_t value;
struct {
uint16_t symb_id:6; /**< This parameter identifies the first symbol number within slot,
to which the information of this message is applies. */
uint16_t slot_id:6; /**< This parameter is the slot number within a 1ms sub-frame. All slots in
one sub-frame are counted by this parameter, slotId running from 0 to Nslot-1.
In this version of the specification the maximum Nslot=16, All
other values of the 6 bits are reserved for future use. */
uint16_t subframe_id:4; /**< This parameter is a counter for 1 ms sub-frames within 10ms frame. */
};
}sf_slot_sym;
} __rte_packed;
/**
******************************************************************************
* @ingroup xran_common_pkt
*
* @description
* This parameter defines the compression method and IQ bit width for the
* user data in the data section. This field is absent from U-Plane messages
* when the static IQ format and compression method is configured via the M-Plane.
* In this way a single compression method and IQ bit width is provided
* (per UL and DL, per LTE and NR) without adding more overhead to U-Plane messages.
*****************************************************************************/
struct compression_hdr
{
uint8_t ud_comp_meth:4;
/**< udCompMeth| compression method |udIqWidth meaning
---------------+-----------------------------+--------------------------------------------
0000b | no compression |bitwidth of each uncompressed I and Q value
0001b | block floating point |bitwidth of each I and Q mantissa value
0010b | block scaling |bitwidth of each I and Q scaled value
0011b | mu-law |bitwidth of each compressed I and Q value
0100b | modulation compression |bitwidth of each compressed I and Q value
0100b - 1111b | reserved for future methods |depends on the specific compression method
*/
uint8_t ud_iq_width:4; /**< Bit width of each I and each Q
16 for udIqWidth=0, otherwise equals udIqWidth e.g. udIqWidth = 0000b means I and Q are each 16 bits wide;
e.g. udIQWidth = 0001b means I and Q are each 1 bit wide;
e.g. udIqWidth = 1111b means I and Q are each 15 bits wide
*/
} __rte_packed;
/**
******************************************************************************
* @ingroup xran_common_pkt
*
* @description
* Structure holds common xran packet header
* 3.1.1 Ethernet Encapsulation
*****************************************************************************/
struct xran_pkt_comm_hdr
{
struct rte_ether_hdr eth_hdr; /**< Ethernet Header */
struct xran_ecpri_hdr ecpri_hdr; /**< eCPRI Transport Header */
} __rte_packed;
#ifdef __cplusplus
}
#endif
#endif
/******************************************************************************
*
* Copyright (c) 2019 Intel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
/**
* @brief This file provides the definition of Control Plane Messages
* for XRAN Front Haul layer as defined in XRAN-FH.CUS.0-v02.01.
*
* @file xran_pkt_cp.h
* @ingroup group_lte_source_xran
* @author Intel Corporation
*
**/
#ifndef _XRAN_PKT_CP_H_
#define _XRAN_PKT_CP_H_
#ifdef __cplusplus
extern "C" {
#endif
/**********************************************************************
* Common structures for C/U-plane
**********************************************************************/
/**
* @ingroup xran_cp_pkt
*
* @description
* user data compression header defined in 5.4.4.10 / 6.3.3.13
*/
struct xran_radioapp_udComp_header {
uint8_t udCompMeth:4; /**< Compression method, XRAN_COMPMETHOD_xxxx */
uint8_t udIqWidth:4; /**< IQ bit width, 1 ~ 16 */
} __attribute__((__packed__));
/**********************************************************************
* Definition of C-Plane Protocol 5.4
**********************************************************************/
/**
* @ingroup xran_cp_pkt
*
* @description
* Common Radio Application Header for C-Plane
*/
struct xran_cp_radioapp_common_header { /* 6bytes, first 4bytes need the conversion for byte order */
uint32_t startSymbolId:6; /**< 5.4.4.7 start symbol identifier */
uint32_t slotId:6; /**< 5.4.4.6 slot identifier */
uint32_t subframeId:4; /**< 5.4.4.5 subframe identifier */
uint32_t frameId:8; /**< 5.4.4.4 frame identifier */
uint32_t filterIndex:4; /**< 5.4.4.3 filter index, XRAN_FILTERINDEX_xxxx */
uint32_t payloadVer:3; /**< 5.4.4.2 payload version, should be 1 */
uint32_t dataDirection:1; /**< 5.4.4.1 data direction (gNB Tx/Rx) */
uint8_t numOfSections; /**< 5.4.4.8 number of sections */
uint8_t sectionType; /**< 5.4.4.9 section type */
} __attribute__((__packed__));
/**
* @ingroup xran_cp_pkt
*
* @description
* frame structure defined in 5.4.4.13
*/
struct xran_cp_radioapp_frameStructure {
uint8_t uScs:4; /**< sub-carrier spacing, XRAN_SCS_xxx */
uint8_t fftSize:4; /**< FFT size, XRAN_FFTSIZE_xxx */
} __attribute__((__packed__));
/**
* @ingroup xran_cp_pkt
*
* @description
* Section headers definition for C-Plane.
* Section type 6 and 7 are not present since those have different fields.
*/
struct xran_cp_radioapp_section_header { /* 8bytes, need the conversion for byte order */
union {
struct {
uint32_t reserved:16;
uint32_t numSymbol:4; /**< 5.4.5.7 number of symbols */
uint32_t reMask:12; /**< 5.4.5.5 resource element mask */
} s0;
struct {
uint32_t beamId:15; /**< 5.4.5.9 beam identifier */
uint32_t ef:1; /**< 5.4.5.8 extension flag */
uint32_t numSymbol:4; /**< 5.4.5.7 number of symbols */
uint32_t reMask:12; /**< 5.4.5.5 resource element mask */
} s1;
struct {
uint32_t beamId:15; /**< 5.4.5.9 beam identifier */
uint32_t ef:1; /**< 5.4.5.8 extension flag */
uint32_t numSymbol:4; /**< 5.4.5.7 number of symbols */
uint32_t reMask:12; /**< 5.4.5.5 resource element mask */
} s3;
struct {
uint32_t ueId:15; /**< 5.4.5.10 UE identifier */
uint32_t ef:1; /**< 5.4.5.8 extension flag */
uint32_t numSymbol:4; /**< 5.4.5.7 number of symbols */
uint32_t reMask:12; /**< 5.4.5.5 resource element mask */
} s5;
} u;
uint32_t numPrbc:8; /**< 5.4.5.6 number of contiguous PRBs per control section 0000 0000b = all PRBs */
uint32_t startPrbc:10; /**< 5.4.5.4 starting PRB of control section */
uint32_t symInc:1; /**< 5.4.5.3 symbol number increment command XRAN_SYMBOLNUMBER_xxxx */
uint32_t rb:1; /**< 5.4.5.2 resource block indicator, XRAN_RBIND_xxx */
uint32_t sectionId:12; /**< 5.4.5.1 section identifier */
} __attribute__((__packed__));
struct xran_cp_radioapp_section_ext_hdr {
/* 12 bytes, need to convert byte order for two parts respectively
* - 2 and 8 bytes, reserved1 would be OK if it is zero
*/
uint16_t extLen:8; /**< 5.4.6.3 extension length, in 32bits words */
uint16_t extType:7; /**< 5.4.6.1 extension type */
uint16_t ef:1; /**< 5.4.6.2 extension flag */
} __attribute__((__packed__));
/**
* @ingroup xran_cp_pkt
*
* @description
* Beamforming Weights Extension Type(ExtType 1) defined in 5.4.7.1
* The structure is reordered for byte order conversion.
*/
struct xran_cp_radioapp_section_ext1 {
/* variable length, need to be careful to convert byte order
* - does not need to convert first 3 bytes */
uint8_t extType:7; /**< 5.4.6.1 extension type */
uint8_t ef:1; /**< 5.4.6.2 extension flag */
uint8_t extLen; /**< 5.4.6.3 extension length, in 32bits words */
/* bfwCompHdr */
uint8_t bfwCompMeth:4; /**< 5.4.7.1.1 Beamforming weight Compression method */
uint8_t bfwIqWidth:4; /**< 5.4.7.1.1 Beamforming weight IQ bit width */
/*
*
*
* bfwCompParam
* (bfwI, bfwQ)+
* ......
* zero padding for 4-byte alignment
*/
} __attribute__((__packed__));
/**
* @ingroup xran_cp_pkt
*
* @description
* Beamforming Attributes Extension Type(ExtType 2) defined in 5.4.7.2
* The structure is reordered for byte order conversion.
*/
struct xran_cp_radioapp_section_ext2 {
/* variable length, need to be careful to convert byte order
* - first 4 bytes can be converted at once
*/
uint32_t bfZe3ddWidth:3; /**< 5.4.7.2.1 beamforming zenith beamwidth parameter bitwidth, Table 5-21 */
uint32_t bfAz3ddWidth:3; /**< 5.4.7.2.1 beamforming azimuth beamwidth parameter bitwidth, Table 5-20 */
uint32_t bfaCompResv1:2;
uint32_t bfZePtWidth:3; /**< 5.4.7.2.1 beamforming zenith pointing parameter bitwidth, Table 5-19 */
uint32_t bfAzPtWidth:3; /**< 5.4.7.2.1 beamforming azimuth pointing parameter bitwidth, Table 5-18 */
uint32_t bfaCompResv0:2;
uint32_t extLen:8; /**< 5.4.6.3 extension length, in 32bits words */
uint32_t extType:7; /**< 5.4.6.1 extension type */
uint32_t ef:1; /**< 5.4.6.2 extension flag */
/*
* would be better to use bit manipulation directly to add these parameters
*
* bfAzPt: var by bfAzPtWidth
* bfZePt: var by bfZePtWidth
* bfAz3dd: var by bfAz3ddWidth
* bfZe3dd: var by bfZe3ddWidth
* bfAzSI:5 (including zero-padding for unused bits)
* bfZeSI:3
* padding for 4-byte alignment
*
*/
} __attribute__((__packed__));
/**
* @ingroup xran_cp_pkt
*
* @description
* DL Precoding Extension Type(ExtType 3) for first data layer.
* Defined in 5.4.7.3 Table 5-22.
* Only be used for LTE TM2-4 and not for other LTE TMs nor NR.
* The structure is reordered for byte order conversion.
*/
struct xran_cp_radioapp_section_ext3_first {
/* 16 bytes, need to convert byte order for two parts - 8/8 bytes */
uint64_t reserved1:8;
uint64_t crsSymNum:4; /**< 5.4.7.3.6 CRS symbol number indication */
uint64_t reserved0:3;
uint64_t crsShift:1; /**< 5.4.7.3.7 CRS shift used for DL transmission */
uint64_t crsReMask:12; /**< 5.4.7.3.5 CRS resource element mask */
uint64_t txScheme:4; /**< 5.4.7.3.3 transmission scheme */
uint64_t numLayers:4; /**< 5.4.7.3.4 number of layers used for DL transmission */
uint64_t layerId:4; /**< 5.4.7.3.2 Layer ID for DL transmission */
uint64_t codebookIndex:8; /**< 5.4.7.3.1 precoder codebook used for transmission */
uint64_t extLen:8; /**< 5.4.6.3 extension length, in 32bits words */
uint64_t extType:7; /**< 5.4.6.1 extension type */
uint64_t ef:1; /**< 5.4.6.2 extension flag */
uint64_t beamIdAP1:16; /**< 5.4.7.3.8 beam id to be used for antenna port 1 */
uint64_t beamIdAP2:16; /**< 5.4.7.3.9 beam id to be used for antenna port 2 */
uint64_t beamIdAP3:16; /**< 5.4.7.3.10 beam id to be used for antenna port 3 */
uint64_t reserved2:16;
} __attribute__((__packed__));
/**
* @ingroup xran_cp_pkt
*
* @description
* DL Precoding Extension Type(ExtType 3) for non-first data layer.
* Defined in 5.4.7.3 Table 5-23.
* Only be used for LTE TM2-4 and not for other LTE TMs nor NR.
* The structure is reordered for byte order conversion.
*/
struct xran_cp_radioapp_section_ext3_non_first {
/* 4 bytes, need to convert byte order at once */
uint32_t numLayers:4; /**< 5.4.7.3.4 number of layers used for DL transmission */
uint32_t layerId:4; /**< 5.4.7.3.2 Layer ID for DL transmission */
uint32_t codebookIndex:8; /**< 5.4.7.3.1 precoder codebook used for transmission */
uint32_t extLen:8; /**< 5.4.6.3 extension length, in 32bits words */
uint32_t extType:7; /**< 5.4.6.1 extension type */
uint32_t ef:1; /**< 5.4.6.2 extension flag */
} __attribute__((__packed__));
/**
* @ingroup xran_cp_pkt
*
* @description
* Modulation Compression Parameter Extension Type(ExtType 4), 5.4.7.4
* Only applies to section type 1 and 3.
* The structure is reordered for byte order conversion.
*/
struct xran_cp_radioapp_section_ext4 {
/* 4 bytes, need to convert byte order at once */
uint32_t modCompScaler:15; /**< 5.4.7.4.2 modulation compression scaler value */
uint32_t csf:1; /**< 5.4.7.4.1 constellation shift flag */
uint32_t extLen:8; /**< 5.4.6.3 extension length, in 32bits words */
uint32_t extType:7; /**< 5.4.6.1 extension type */
uint32_t ef:1; /**< 5.4.6.2 extension flag */
} __attribute__((__packed__));
/**
* @ingroup xran_cp_pkt
*
* @description
* Modulation Compression Additional Parameter Extension Type(ExtType 5) for one scaler value.
* Defined in 5.4.7.5 Table 5-26 and Table 5-27.
* Only applies to section type 1 3, and 5.
* The structure is reordered for byte order conversion.
*/
struct xran_cp_radioapp_section_ext5 {
uint32_t reserved0:8;
uint32_t mcScaleOffset2:15; /**< 5.4.7.5.3 scaling value for modulation compression */
uint32_t csf2:1; /**< 5.4.7.5.2 constellation shift flag */
uint32_t mcScaleReMask2:12; /**< 5.4.7.5.1 modulation compression power scale RE mask */
uint32_t mcScaleOffset1:15; /**< 5.4.7.5.3 scaling value for modulation compression */
uint32_t csf1:1; /**< 5.4.7.5.2 constellation shift flag */
uint32_t mcScaleReMask1:12; /**< 5.4.7.5.1 modulation compression power scale RE mask */
} __attribute__((__packed__));
/**********************************************************
* Scheduling and Beam-forming Commands 5.4.2
**********************************************************/
/**
* @ingroup xran_cp_pkt
*
* @description
* Section header definition for type 0
*/
struct xran_cp_radioapp_section0_header { // 12bytes (6+2+1+2+1)
struct xran_cp_radioapp_common_header cmnhdr;
uint16_t timeOffset; /**< 5.4.4.12 time offset */
struct xran_cp_radioapp_frameStructure frameStructure;
uint16_t cpLength; /**< 5.4.4.14 cyclic prefix length */
uint8_t reserved;
} __attribute__((__packed__));
/**
* @ingroup xran_cp_pkt
*
* @description
* Section definition for type 0: Unused RB or Symbols in DL or UL (Table 5-2)
* Not supported in this release
*/
struct xran_cp_radioapp_section0 { // 8bytes (4+4)
struct xran_cp_radioapp_section_header hdr;
} __attribute__((__packed__));
/**
* @ingroup xran_cp_pkt
*
* @description
* Section header definition for type 1
*/
struct xran_cp_radioapp_section1_header { // 8bytes (6+1+1)
struct xran_cp_radioapp_common_header cmnhdr;
struct xran_radioapp_udComp_header udComp;
uint8_t reserved;
} __attribute__((__packed__));
/**
* @ingroup xran_cp_pkt
*
* @description
* Section definition for type 1: Most DL/UL Radio Channels (Table 5-3)
*/
struct xran_cp_radioapp_section1 { // 8bytes (4+4)
struct xran_cp_radioapp_section_header hdr;
// section extensions // 5.4.6 & 5.4.7
// .........
} __attribute__((__packed__));
/**
* @ingroup xran_cp_pkt
*
* @description
* Section header definition for type 3
*/
struct xran_cp_radioapp_section3_header { // 12bytes (6+2+1+2+1)
struct xran_cp_radioapp_common_header cmnhdr;
uint16_t timeOffset; /**< 5.4.4.12 time offset */
struct xran_cp_radioapp_frameStructure frameStructure;
uint16_t cpLength; /**< 5.4.4.14 cyclic prefix length */
struct xran_radioapp_udComp_header udComp;
} __attribute__((__packed__));
/**
* @ingroup xran_cp_pkt
*
* @description
* Section definition for type 3: PRACH and Mixed-numerology Channels (Table 5-4)
*/
struct xran_cp_radioapp_section3 { // 12bytes (4+4+4)
struct xran_cp_radioapp_section_header hdr;
uint32_t freqOffset:24; /**< 5.4.5.11 frequency offset */
uint32_t reserved:8;
// section extensions // 5.4.6 & 5.4.7
// .........
} __attribute__((__packed__));
/**
* @ingroup xran_cp_pkt
*
* @description
* Section header definition for type 5
*/
struct xran_cp_radioapp_section5_header { // 8bytes (6+1+1)
struct xran_cp_radioapp_common_header cmnhdr;
struct xran_radioapp_udComp_header udComp;
uint8_t reserved;
} __attribute__((__packed__));
/**
* @ingroup xran_cp_pkt
*
* @description
* Section definition for type 5: UE scheduling information (Table 5-5)
* Not supported in this release
*/
struct xran_cp_radioapp_section5 {
struct xran_cp_radioapp_section_header hdr;
// section extensions // 5.4.6 & 5.4.7
// .........
} __attribute__((__packed__));
/**
* @ingroup xran_cp_pkt
*
* @description
* Section header definition for type 6
*/
struct xran_cp_radioapp_section6_header { // 8bytes (6+1+1)
struct xran_cp_radioapp_common_header cmnhdr;
uint8_t numberOfUEs; /**< 5.4.4.11 number of UEs */
uint8_t reserved;
} __attribute__((__packed__));
/**
* @ingroup xran_cp_pkt
*
* @description
* Section definition for type 6: Channel Information (Table 5-6)
* Not supported in this release
*/
struct xran_cp_radioapp_section6 {
uint32_t regularizationFactor:16;/**< 5.4.5.12 regularization Factor */
uint32_t ueId:15; /**< 5.4.5.10 UE identifier */
uint32_t ef:1; /**< 5.4.5.8 extension flag */
uint8_t startPrbch:2; /**< 5.4.5.4 starting PRB of control section */
uint8_t symInc:1; /**< 5.4.5.3 symbol number increment command XRAN_SYMBOLNUMBER_xxxx */
uint8_t rb:1; /**< 5.4.5.2 resource block indicator, XRAN_RBIND_xxx */
uint8_t reserved:4;
uint8_t startPrbcl:8; /**< 5.4.5.4 starting PRB of control section */
uint8_t numPrbc:8; /**< 5.4.5.6 number of contiguous PRBs per control section */
// ciIQsamples start from here // 5.4.5.13 channel information I and Q values
// .........
//
// section extensions // 5.4.6 & 5.4.7
// .........
} __attribute__((__packed__));
/**
* @ingroup xran_cp_pkt
*
* @description
* Section header definition for type 7: LAA
* Not supported in this release
*/
struct xran_cp_radioapp_section7_header {
struct xran_cp_radioapp_common_header cmnhdr;
uint16_t reserved;
uint8_t laaMsgLen:4; /**< 5.4.5.15 LAA message length */
uint8_t laaMsgType:4; /**< 5.4.5.14 LAA message type */
// Payload start from here // 5.4.5.16 ~ 5.4.5.32
} __attribute__((__packed__));
#ifdef __cplusplus
}
#endif
#endif /* _XRAN_PKT_CP_H_ */
/******************************************************************************
*
* Copyright (c) 2019 Intel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
/**
* @brief Definitions and support functions to process XRAN packet
* @file xran_pkt_up.h
* @ingroup group_source_xran
* @author Intel Corporation
**/
/**
*****************************************************************************
* @file xran_pkt_up.h
*
* @defgroup xran_up_pkt U-Plane XRAN Packet definitions and functions
* @ingroup xran
*
* @description
* Structures relevant to U-plane packets only (data now only)
*****************************************************************************/
#ifndef _XRAN_PKT_UP_H_
#define _XRAN_PKT_UP_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "xran_pkt.h"
#define IQ_PAIR_NUM_IN_RB 12
#define MAX_DATA_SECTIONS_NUM 273
#define MAX_IQ_BIT_WIDTH 16
/* currently library supports I and Q sizes of 8 and 16 bits each */
#define IQ_BITS MAX_IQ_BIT_WIDTH
/*
* Structure holding data section header fields
* It is repeated for every section ID in xRAN packet
*/
/**
******************************************************************************
* @ingroup xran_up_pkt
*
* @description
* Structure holding data section header fields
* It is repeated for every section ID in xRAN packet
* 5.4.5 Coding of Information Elements - Application Layer, Sections
* for U-plane as per 6.3.2 DL/UL Data
*****************************************************************************/
struct data_section_hdr {
union {
uint32_t all_bits;
struct {
uint32_t num_prbu:8; /**< 5.4.5.6 number of contiguous PRBs per control section */
uint32_t start_prbu:10; /**< 5.4.5.4 starting PRB of control section */
uint32_t sym_inc:1; /**< 5.4.5.3 symbol number increment command XRAN_SYMBOLNUMBER_xxxx */
uint32_t rb:1; /**< 5.4.5.2 resource block indicator, XRAN_RBIND_xxx */
uint32_t sect_id:12; /**< 5.4.5.1 section identifier */
};
}fields;
#ifdef FCN_ADAPT
uint8_t udCompHdr;
uint8_t reserved;
#endif
} __rte_packed;
/*
******************************************************************************
* @ingroup xran_up_pkt
*
* @description
* Structure holds compression header structure and field reserved for future use.
* reserved goes always with udCompHdr in u-plane pkt
* U-plane as per 6.3.2 DL/UL Data
*****************************************************************************/
struct data_section_compression_hdr
{
struct compression_hdr ud_comp_hdr;
uint8_t rsrvd; /**< This parameter provides 1 byte for future definition,
should be set to all zeros by the sender and ignored by the receiver.
This field is only present when udCompHdr is present, and is absent when
the static IQ format and compression method is configured via the M-Plane */
/* TODO: support for Block Floating Point compression */
/* udCompMeth 0000b = no compression absent*/
};
/*
******************************************************************************
* @ingroup xran_up_pkt
*
* @description
* Structure holds the compression parameters by the compression header.
* may not be present by udCompMeth in 6.3.3.13
*****************************************************************************/
union compression_params {
struct block_fl_point {
uint8_t exponent:4;
uint8_t reserved:4;
} blockFlPoint;
struct block_scaling {
uint8_t sblockScaler;
} blockScaling;
struct u_law {
uint8_t compShift:4;
uint8_t compBitWidth:4;
} uLaw;
} __rte_packed;
/*
******************************************************************************
* @ingroup xran_up_pkt
*
* @description
* Structure holds an IQ sample pair
* U-plane as per 6.3.2 DL/UL Data
* Each bit field size is defined with IQ_BITS macro
* Currently supported I and Q sizes are 8 and 16 bits
*****************************************************************************/
struct rb_map
{
int16_t i_sample:IQ_BITS; /**< This parameter is the In-phase sample value */
int16_t q_sample:IQ_BITS; /**< This parameter is the Quadrature sample value */
} __rte_packed;
/**
******************************************************************************
* @ingroup xran_common_pkt
*
* @description
* Structure holds complete xran u-plane packet header
* 3.1.1 Ethernet Encapsulation
*****************************************************************************/
struct xran_up_pkt_hdr
{
struct xran_ecpri_hdr ecpri_hdr; /**< eCPRI Transport Header */
struct radio_app_common_hdr app_hdr; /**< eCPRI Transport Header */
struct data_section_hdr data_sec_hdr;
} __rte_packed;
/**
******************************************************************************
* @ingroup xran_common_pkt
*
* @description
* Structure holds complete ethernet and xran u-plane packet header
* 3.1.1 Ethernet Encapsulation
*****************************************************************************/
struct eth_xran_up_pkt_hdr
{
struct rte_ether_hdr eth_hdr;
struct xran_up_pkt_hdr xran_hdr;
}__rte_packed;
#ifdef __cplusplus
}
#endif
#endif
/******************************************************************************
*
* Copyright (c) 2019 Intel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
/**
* @brief Modules provide debug prints and utility functions
* @file xran_printf.h
* @ingroup group_source_xran
* @author Intel Corporation
**/
#ifndef XRAN_PRINTF_H
#define XRAN_PRINTF_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <stdlib.h>
#define PRINTF_LOG_OK
#define PRINTF_INF_OK
#define PRINTF_ERR_OK
//#define PRINTF_DBG_OK
#ifndef WIN32
#ifdef PRINTF_LOG_OK
#define print_log(fmt, args...) printf("%s:" fmt "\n", __FUNCTION__, ## args)
#else /* PRINTF_LOG_OK */
#define print_log(fmt, args...)
#endif /* PRINTF_LOG_OK */
#else
#define print_log(fmt, ...) printf("%s:" fmt "\n", __FUNCTION__, __VA_ARGS__)
#endif
#ifndef WIN32
#ifdef PRINTF_DBG_OK
#define print_dbg(fmt, args...) printf("%s:[dbg] " fmt "\n", __FUNCTION__, ## args)
#else /* PRINTF_LOG_OK */
#define print_dbg(fmt, args...)
#endif /* PRINTF_LOG_OK */
#else
#define print_dbg(fmt, ...) printf("%s:[dbg] " fmt "\n", __FUNCTION__, __VA_ARGS__)
#endif
#ifndef WIN32
#ifdef PRINTF_ERR_OK
#define print_err(fmt, args...) printf("%s:[err] " fmt "\n", __FUNCTION__, ## args)
#else /* PRINTF_LOG_OK */
#define print_err(fmt, args...)
#endif /* PRINTF_LOG_OK */
#else
#define print_err(fmt, ...) printf("%s:[err] " fmt "\n", __FUNCTION__, __VA_ARGS__)
#endif
#ifndef WIN32
#ifdef PRINTF_INF_OK
#define print_inf printf
#else /* PRINTF_LOG_OK */
#define print_inf
#endif /* PRINTF_LOG_OK */
#else
#define print_inf printf
#endif
#ifdef __cplusplus
}
#endif
#ifndef _IASSERT_
#define _IASSERT_
#ifdef _DEBUG
#define iAssert(p) if(!(p)){fprintf(stderr,\
"Assertion failed: %s, file %s, line %d, val %d\n",\
#p, __FILE__, __LINE__, p);exit(-1);}
#else /* _DEBUG */
#define iAssert(p)
#endif /* _DEBUG */
#ifndef PHY_APP
#ifndef _assert
#define _assert(x)
#endif
#endif
#endif /* _IASSERT_*/
#ifdef CHECK_PARAMS
#define CHECK_NOT_NULL(param, returnValue) \
if (param == NULL) \
{ \
print_err("%s is NULL!\n", #param); \
return returnValue; \
}
#else
#define CHECK_NOT_NULL(param, returnValue)
#endif
#ifdef __cplusplus
}
#endif
#endif // PHY_PRINTF_H
/******************************************************************************
*
* Copyright (c) 2019 Intel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
/**
* @brief This file provides interface to synchronization related APIs (PTP/1588)
* for XRAN.
*
* @file xran_sync_api.h
* @ingroup group_lte_source_xran
* @author Intel Corporation
*
**/
#ifndef _XRAN_SYNC_API_H_
#define _XRAN_SYNC_API_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Function checks if machine is synchronized using PTP for Linux
* software.
*
* @return int Returns 0 if synchronized, otherwise positive.
*/
int xran_is_synchronized(void);
#ifdef __cplusplus
}
#endif
#endif /* _XRAN_SYNC_API_H_ */
/******************************************************************************
*
* Copyright (c) 2019 Intel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
/**
* @brief This file provides interface to Timing for XRAN.
*
* @file xran_timer.h
* @ingroup group_lte_source_xran
* @author Intel Corporation
*
**/
#ifndef _XRAN_TIMER_H
#define _XRAN_TIMER_H
#ifdef __cplusplus
extern "C" {
#endif
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define MSEC_PER_SEC 1000L
#define XranIncrementSymIdx(sym_idx, numSymPerMs) (((uint32_t)sym_idx >= (((uint32_t)numSymPerMs * MSEC_PER_SEC) - 1)) ? 0 : (uint32_t)sym_idx+1)
#define XranDecrementSymIdx(sym_idx, numSymPerMs) (((uint32_t)sym_idx == 0) ? (((uint32_t)numSymPerMs * MSEC_PER_SEC)) - 1) : (uint32_t)sym_idx-1)
uint64_t xran_tick(void);
unsigned long get_ticks_diff(unsigned long curr_tick, unsigned long last_tick);
long poll_next_tick(long interval_ns, unsigned long *used_tick);
long sleep_next_tick(long interval);
int timing_set_debug_stop(int value, int count);
int timing_get_debug_stop(void);
inline uint64_t timing_get_current_second(void);
int timing_set_numerology(uint8_t value);
#ifdef __cplusplus
}
#endif
#endif
/******************************************************************************
*
* Copyright (c) 2019 Intel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
/**
* @brief This file provides the definitions for Transport layer (eCPRI) API.
*
* @file xran_transport.h
* @ingroup group_lte_source_xran
* @author Intel Corporation
*
**/
#ifndef _XRAN_TRANSPORT_H_
#define _XRAN_TRANSPORT_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <rte_common.h>
#include <rte_mbuf.h>
#include "xran_pkt.h"
struct xran_eaxc_info {
uint8_t cuPortId;
uint8_t bandSectorId;
uint8_t ccId;
uint8_t ruPortId;
};
struct xran_recv_packet_info {
int ecpri_version;
enum ecpri_msg_type msg_type;
int payload_len;
struct xran_eaxc_info eaxc;
int seq_id;
int subseq_id;
int ebit;
};
int xran_get_ecpri_hdr_size(void);
void xran_update_ecpri_payload_size(struct rte_mbuf *mbuf, int size);
uint16_t xran_compose_cid(uint8_t CU_Port_ID, uint8_t BandSector_ID, uint8_t CC_ID, uint8_t Ant_ID);
void xran_decompose_cid(uint16_t cid, struct xran_eaxc_info *result);
int xran_build_ecpri_hdr(struct rte_mbuf *mbuf,
uint8_t CC_ID, uint8_t Ant_ID,
uint8_t seq_id,
struct xran_ecpri_hdr **ecpri_hdr);
int xran_parse_ecpri_hdr(struct rte_mbuf *mbuf,
struct xran_ecpri_hdr **ecpri_hdr,
struct xran_recv_packet_info *pkt_info);
#ifdef __cplusplus
}
#endif
#endif
/******************************************************************************
*
* Copyright (c) 2019 Intel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
/**
* @brief This file provides the definitions for User Plane Messages APIs.
*
* @file xran_up_api.h
* @ingroup group_lte_source_xran
* @author Intel Corporation
*
**/
#ifndef _XRAN_UP_API_H_
#define _XRAN_UP_API_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <rte_common.h>
#include <rte_mbuf.h>
#include "xran_pkt.h"
#include "xran_pkt_up.h"
/*
* structure used for storing packet parameters needed for generating
* a data packet
*/
struct xran_up_pkt_gen_params
{
struct radio_app_common_hdr app_params;
struct data_section_hdr sec_hdr;
struct data_section_compression_hdr compr_hdr_param;
union compression_params compr_param;
};
/*
* structure used for storing packet parameters needed for generating
* a data packet without compression
* Next fields are omitted:
* udCompHdr (not always present)
* reserved (not always present)
* udCompParam (not always present)
*/
struct xran_up_pkt_gen_no_compression_params
{
struct radio_app_common_hdr app_params;
struct data_section_hdr sec_hdr;
};
/**
* @brief Function extracts IQ samples from received mbuf packet.
*
* @param mbuf Packet with received data.
* @param iq_data_start Address of the first IQ sample in mbuf will be returned
* here
* @return int Bytes of IQ samples that have been extracted from mbuf.
*/
int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf,
void **iq_data_start,
uint8_t *CC_ID,
uint8_t *Ant_ID,
uint8_t *frame_id,
uint8_t *subframe_id,
uint8_t *slot_id,
uint8_t *symb_id,
struct ecpri_seq_id *seq_id,
uint16_t *num_prbu,
uint16_t *start_prbu,
uint16_t *sym_inc,
uint16_t *rb,
uint16_t *sect_id,
int8_t expect_comp,
uint8_t *compMeth,
uint8_t *iqWidth);
int xran_prepare_iq_symbol_portion(
struct rte_mbuf *mbuf,
const void *iq_data_start,
const enum xran_input_byte_order iq_buf_byte_order,
const uint32_t iq_data_num_bytes,
struct xran_up_pkt_gen_params *params,
uint8_t CC_ID,
uint8_t Ant_ID,
uint8_t seq_id,
uint32_t do_copy);
#ifdef __cplusplus
}
#endif
#endif /* _XRAN_UP_API_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment