feat(fronthaul): Add xran packet manipulation code

Add sources from xran library containing Split 7.2 packet manipulation
tools.

Signed-off-by: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org>
This commit is contained in:
Bartosz Podrygajlo
2026-05-13 16:50:49 +02:00
parent fc78a643f1
commit 83c9116145
7 changed files with 5489 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,564 @@
/******************************************************************************
*
* 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 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 4
#define XRAN_MAX_NUM_EXTENSIONS 10//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_LTE4 = 5, /**< UL filter for PRACH preamble format LTE-4 */
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_6 = 6, /**< Non-contiguous PRB allocation */
XRAN_CP_SECTIONEXTCMD_7 = 7, /**< Multiple-eAxC designation */
XRAN_CP_SECTIONEXTCMD_8 = 8, /**< MMSE parameters */
XRAN_CP_SECTIONEXTCMD_9 = 9, /**< Dynamic Spectrum Sharing parameters */
XRAN_CP_SECTIONEXTCMD_10 = 10, /**< Multiple ports grouping */
XRAN_CP_SECTIONEXTCMD_11 = 11, /**< Flexible BF weights */
XRAN_CP_SECTIONEXTCMD_MAX /* 12~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 */
/** Resource Block Group Size 5.4.7.6.1 */
enum xran_cp_rbgsize {
XRAN_RBGSIZE_1RB = 1, /**< 1 RB */
XRAN_RBGSIZE_2RB = 2, /**< 2 RBs */
XRAN_RBGSIZE_3RB = 3, /**< 3 RBs */
XRAN_RBGSIZE_4RB = 4, /**< 4 RBs */
XRAN_RBGSIZE_6RB = 5, /**< 6 RBs */
XRAN_RBGSIZE_8RB = 6, /**< 8 RBs */
XRAN_RBGSIZE_16RB = 7, /**< 16 RBs */
};
/** Technology for Dynamic Spectrum Sharing operation 5,4,7.9.1 */
#define XRAN_DSSTECH_LTE 0 /**< LTE support */
#define XRAN_DSSTECH_NR 1 /**< NR support */
/** The type of beam grouping 5.4.7.10.1 */
#define XRAN_BEAMGT_COMMON 0 /** common beam */
#define XRAN_BEAMGT_MATRIXIND 1 /** beam matrix indication */
#define XRAN_BEAMGT_VECTORLIST 2 /** beam vector listing */
#define XRAN_MAX_NUMPORTC_EXT10 64 /* defined in 5.4.7.10.2 */
/**
* This structure contains the information to generate the section body of C-Plane message */
struct xran_section_info {
/** for U-plane */
struct xran_section_desc sec_desc[XRAN_NUM_OF_SYMBOL_PER_SLOT];
int32_t freqOffset; /* X 24bits */
uint32_t startPrbc:9; /* X X X X X 9bits */
uint32_t numPrbc:9; /* X X X X X 8bits */ /* will be converted to zero if >255 */
uint32_t type:4; /* type of this section */
/* section type bit- */
/* 0 1 3 5 6 7 length */
uint32_t startSymId:4; /* X X X X X X 4bits */
uint32_t numSymbol:4; /* X X X X 4bits */
uint32_t res:2;
uint16_t beamId; /* X X 15bits */
uint16_t ueId; /* X X 15bits */
uint16_t regFactor; /* X 16bits */
uint16_t id; /* X X X X X 12bits */
uint16_t reMask; /* X X X X 12bits */
uint8_t symInc:1; /* X X X X X 1bit */
uint8_t rb:1; /* X X X X X 1bit */
uint8_t ef:1; /* X X X X 1bit */
uint8_t prbElemBegin:1; /* Flag to indicate beginning of a PRB element */
uint8_t prbElemEnd:1; /* Flag to indicate end of a PRB element */
uint8_t reserved:3;
uint8_t compMeth:4; /* X X X 4bits */
uint8_t iqWidth:4; /* X X X 4bits */
};
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;
int8_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_sectionext6_info {
uint8_t rbgSize;
uint8_t pad;
uint16_t symbolMask;
uint32_t rbgMask;
};
struct xran_sectionext7_info {
uint16_t eAxCmask;
};
struct xran_sectionext8_info {
uint16_t regularizationFactor;
};
struct xran_sectionext9_info {
uint8_t technology;
uint8_t reserved;
};
struct xran_sectionext10_info {
uint8_t numPortc;
uint8_t beamGrpType;
uint16_t beamID[XRAN_MAX_NUMPORTC_EXT10];
};
struct xran_sectionext11_info {
uint8_t RAD;
uint8_t disableBFWs;
uint8_t numBundPrb;
uint8_t numSetBFWs; /* Total number of beam forming weights set (L) */
uint8_t bfwCompMeth;
uint8_t bfwIqWidth;
int32_t totalBfwIQLen;
int32_t maxExtBufSize; /* Maximum space of external buffer */
uint8_t *pExtBuf; /* pointer to start of external buffer */
void *pExtBufShinfo; /* Pointer to rte_mbuf_ext_shared_info */
};
union xran_ext_bfwcompparam_info {
uint8_t exponent;
// uint8_t blockScaler; /* Not supported */
// uint8_t compBitWidthShift; /* Not supported */
// uint8_t *pActBeamspaceCoeffMask; /* Not supported */
};
struct xran_ext11_prbbundle_info {
union xran_ext_bfwcompparam_info bfwCompParam;
uint16_t beamId; /* 15bits, needs to strip MSB */
uint16_t BFWSize; /* actual size of bfws in bytes */
uint8_t *pBFWs; /* external buffer pointer */
};
struct xran_sectionext11_recv_info {
uint8_t RAD;
uint8_t disableBFWs;
uint8_t numBundPrb;
uint8_t numSetBFWs; /* Total number of beam forming weights set (L) */
uint8_t bfwCompMeth;
uint8_t bfwIqWidth;
int32_t totalBfwIQLen;
int32_t maxExtBufSize; /* Maximum space of external buffer */
uint8_t *pExtBuf; /* pointer to start of external buffer */
void *pExtBufShinfo; /* Pointer to rte_mbuf_ext_shared_info */
/* For parsing */
struct xran_ext11_prbbundle_info bundInfo[XRAN_MAX_SET_BFWS];
};
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 */
/** the array to store section extension */
struct xran_section_ext_gen_info exData[XRAN_MAX_NUM_EXTENSIONS];
uint32_t exDataSize; /**< The number of Extensions or type 6/7 data */
};
/**
* 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 */
};
/** The structure to store received section extension */
struct xran_section_ext_recv_info {
uint16_t type; /**< the type of section extension */
uint16_t size;
union {
struct xran_sectionext1_info ext1;
struct xran_sectionext2_info ext2;
struct xran_sectionext3_info ext3;
struct xran_sectionext4_info ext4;
struct xran_sectionext5_info ext5;
struct xran_sectionext6_info ext6;
struct xran_sectionext9_info ext9;
struct xran_sectionext10_info ext10;
struct xran_sectionext11_recv_info ext11;
} u;
};
/**
* This structure to hold the information of received sections of C-Plane message */
struct xran_section_recv_info {
struct xran_section_info info; /**< The information for received section */
uint32_t numExts;
/** the array to store section extension */
struct xran_section_ext_recv_info exts[XRAN_MAX_NUM_EXTENSIONS];
};
/**
* This structure to store received C-Plane message */
struct xran_cp_recv_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 received */
uint8_t numSetBFW; /**<Set of BFWs */
uint8_t ext1count; /**<Count set of extension type-1 BFWs*/
uint32_t tti; /**<micro-second*/
uint8_t dssPeriod; /**< DSS pattern period for LTE/NR */
uint8_t technology_arr[XRAN_MAX_DSS_PERIODICITY]; /**< technology array represents slot is LTE(0)/NR(1) */
struct xran_cp_header_params hdr;
/**< The information for C-Plane message header */
struct xran_section_recv_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;
};
typedef struct tagSECTION_DB_TYPE {
struct xran_sectioninfo_db* p_sectiondb_elm[XRAN_MAX_SECTIONDB_CTX][XRAN_DIR_MAX][XRAN_COMPONENT_CARRIERS_MAX][XRAN_MAX_ANTENNA_NR * 2 + XRAN_MAX_ANT_ARRAY_ELM_NR];
} SECTION_DB_TYPE, * PSECTION_DB_TYPE;
uint16_t xran_get_cplength(int32_t cpLength);
int32_t xran_get_freqoffset(int32_t freqOffset, int32_t 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,
uint16_t start_sect_id);
int32_t xran_parse_cp_pkt(struct rte_mbuf *mbuf,
struct xran_cp_recv_params *result,
struct xran_recv_packet_info *pkt_info, void* handle, uint32_t *mb_free);
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);
struct xran_section_info *
xran_cp_get_section_info_ptr(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id);
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);
int32_t xran_cp_getsize_section_info(void *pHandle, uint8_t dir, uint8_t cc_id, uint8_t ruport_id, uint8_t ctx_id);
int32_t 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 */
struct xran_prb_elm *p_pRbMapElm);
struct rte_mbuf *xran_attach_cp_ext_buf(uint16_t vf_id, 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);
int32_t xran_cp_attach_ext_buf(struct rte_mbuf *mbuf, uint8_t *extbuf_start, uint16_t extbuf_len,
struct rte_mbuf_ext_shared_info *shinfo);
int32_t xran_cp_prepare_ext11_bfws(uint8_t numSetBFW, uint8_t numBFW,
uint8_t iqWidth, uint8_t compMeth,
uint8_t *dst, int16_t dst_maxlen,
struct xran_ext11_bfw_info bfwInfo[]);
int32_t xran_cp_estimate_max_set_bfws(uint8_t numBFWs, uint8_t iqWidth,
uint8_t compMeth, uint16_t mtu);
#ifdef __cplusplus
}
#endif
#endif /* _XRAN_CP_API_H_ */

View File

@@ -0,0 +1,351 @@
/******************************************************************************
*
* 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 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 */
#define XRAN_MTU_DEFAULT RTE_ETHER_MTU
#define XRAN_APP_LAYER_MAX_SIZE_L2_DEFAUT (XRAN_MTU_DEFAULT - 8) /**< In case of L2 only solution, application layer maximum transmission unit size
is standard IEEE 802.3 Ethernet frame payload
size (1500 bytes) ? transport overhead (8 bytes) = 1492 bytes (or larger for Jumbo frames) */
#ifndef OK
#define OK 0 /* Function executed correctly */
#endif
#ifndef FAIL
#define FAIL 1 /* Function failed to execute */
#endif
#define NS_PER_SEC 1000000000LL
/**
******************************************************************************
* @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
* eCPRI Timestamp for one-way delay measurements format per IEEE-1588
* clause 5.3.3.
*****************************************************************************/
typedef struct {
uint16_t secs_msb; // 6 bytes for seconds
uint32_t secs_lsb;
uint32_t ns; // 4 bytes for nanoseconds
} TimeStamp;
/**
******************************************************************************
* @ingroup xran_common_pkt
*
* @description
* eCPRI action types
* as per eCPRI spec Table 8 action Types
*****************************************************************************/
enum ecpri_action_type
{
ECPRI_REQUEST = 0x00, /* Uses Time Stamp T1 and Comp Delay 1 */
ECPRI_REQUEST_W_FUP = 0x01, /* Uses 0 for Time Stamp and Comp Delay 1 */
ECPRI_RESPONSE = 0x02, /* Uses Time Stamp T2 and Comp Delay 2 */
ECPRI_REMOTE_REQ = 0x03, /* Uses 0 for Time Stamp and Comp Delay */
ECPRI_REMOTE_REQ_W_FUP = 0x04, /* Uses 0 for Time Stamp and Comp Delay */
ECPRI_FOLLOW_UP = 0x05, /* Uses Time Info and Comp Delay Info */
ECPRI_ACTION_TYPE_MAX
};
/**
******************************************************************************
* @ingroup xran_common_pkt
*
* @description
* see 3.1.3.1.7 ecpriSeqid (message identifier)
*****************************************************************************/
union ecpri_seq_id
{
struct
{
uint8_t seq_id:8; /**< Sequence ID */
uint8_t sub_seq_id:7; /**< Subsequence ID */
uint8_t e_bit:1; /**< E bit */
} bits;
struct
{
uint16_t data_num_1;
} data;
} __rte_packed;
#define ecpri_seq_id_bitfield_seq_id 0
#define ecpri_seq_id_bitfield_sub_seq_id 8
#define ecpri_seq_id_bitfield_e_bit 15
/**
******************************************************************************
* @ingroup xran_common_pkt
*
* @description
* Structure holds common eCPRI header as per
* Table 3 1 : eCPRI Transport Header Field Definitions
*****************************************************************************/
union xran_ecpri_cmn_hdr
{
struct
{
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 */
} bits;
struct
{
uint32_t data_num_1;
} data;
} __rte_packed;
#define xran_ecpri_cmn_hdr_bitfield_EcpriVer 4
#define xran_ecpri_cmn_hdr_bitfield_EcpriMsgType 8
/**
******************************************************************************
* @ingroup xran_common_pkt
*
* @description
* Structure holds common eCPRI delay measuurement header as per
* Table 2.17 : eCPRI One-Way delay measurement message
*****************************************************************************/
struct xran_ecpri_delay_meas_pl
{
uint8_t MeasurementID; /**< Table 2-17 Octet 5 */
uint8_t ActionType; /**< Table 2-17 Octet 6 */
TimeStamp ts; /**< Table 2-17 Octet 7-16 */
int64_t CompensationValue; /**< Table 2-17 Octet 17 */
uint8_t DummyBytes[1400]; /**< Table 2-17 Octet 25 */
} /*__rte_packed*/;
/**
******************************************************************************
* @ingroup xran_common_pkt
*
* @description
* Structure holds common eCPRI cmn header per eCPRI figure 8 and the measurement delay header and pl per
* eCPRI Figure 23 : eCPRI One-Way delay measurement message
*****************************************************************************/
struct xran_ecpri_del_meas_pkt
{
union xran_ecpri_cmn_hdr cmnhdr;
struct xran_ecpri_delay_meas_pl deMeasPl;
}/*__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
{
union 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 */
union 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 */
union {
uint8_t value;
struct {
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. */
};
}data_feature;
/* 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;
enum xran_mbuf_mem_op_id {
MBUF_KEEP,
MBUF_FREE
};
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,662 @@
/******************************************************************************
*
* 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 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
#include <stdint.h>
#if defined(__arm__) || defined(__aarch64__)
#include <arm_neon.h>
typedef int32x4_t simd_data_t;
#else
#include <xmmintrin.h>
typedef __m128i simd_data_t;
#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 */
union {
uint32_t all_bits;
struct {
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) */
};
} field;
uint8_t numOfSections; /**< 5.4.4.8 number of sections */
uint8_t sectionType; /**< 5.4.4.9 section type */
} __attribute__((__packed__));
#define xran_cp_radioapp_cmn_hdr_bitwidth_StartSymId 0
#define xran_cp_radioapp_cmn_hdr_bitwidth_SlotId 6
#define xran_cp_radioapp_cmn_hdr_bitwidth_SubFrameId 12
#define xran_cp_radioapp_cmn_hdr_bitwidth_FrameId 16
#define xran_cp_radioapp_cmn_hdr_bitwidth_FilterIdex 24
#define xran_cp_radioapp_cmn_hdr_bitwidth_PayLoadVer 28
#define xran_cp_radioapp_cmn_hdr_bitwidth_DataDir 31
/**
* @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 {
uint32_t first_4byte;
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;
union {
uint32_t second_4byte;
struct {
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 */
} common;
} u1;
} __attribute__((__packed__));
#define xran_cp_radioapp_sec_hdr_sc_BeamID 0
#define xran_cp_radioapp_sec_hdr_sc_Ef 15
#define xran_cp_radioapp_sec_hdr_sc_NumSym 16
#define xran_cp_radioapp_sec_hdr_sc_ReMask 20
#define xran_cp_radioapp_sec_hdr_c_NumPrbc 0
#define xran_cp_radioapp_sec_hdr_c_StartPrbc 8
#define xran_cp_radioapp_sec_hdr_c_SymInc 18
#define xran_cp_radioapp_sec_hdr_c_RB 19
#define xran_cp_radioapp_sec_hdr_c_SecId 20
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.
*/
union xran_cp_radioapp_section_ext3_first {
/* 16 bytes, need to convert byte order for two parts - 8/8 bytes */
struct{
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;
}all_bits;
struct{
simd_data_t data_field1;
}data_field;
} __attribute__((__packed__));
#define xran_cp_radioapp_sec_ext3_Res1 0
#define xran_cp_radioapp_sec_ext3_CrcSymNum 8
#define xran_cp_radioapp_sec_ext3_Res0 12
#define xran_cp_radioapp_sec_ext3_CrcShift 15
#define xran_cp_radioapp_sec_ext3_CrcReMask 16
#define xran_cp_radioapp_sec_ext3_TxScheme 28
#define xran_cp_radioapp_sec_ext3_NumLayers 0
#define xran_cp_radioapp_sec_ext3_LayerId 4
#define xran_cp_radioapp_sec_ext3_CodebookIdx 8
#define xran_cp_radioapp_sec_ext3_ExtLen 16
#define xran_cp_radioapp_sec_ext3_ExtType 24
#define xran_cp_radioapp_sec_ext3_EF 31
/**
* @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.
*/
union xran_cp_radioapp_section_ext3_non_first {
uint32_t data_field;
struct {
/* 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 */
}all_bits;
} __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__));
/**
* @ingroup xran_cp_pkt
*
* @description
* Non-contiguous PRB allocation in time and frequency domain.
* ExtType 6, Defined in 5.4.7.6 Table 5-28
* Only applies to section type 1 3, and 5.
* The structure is reordered for byte order conversion.
*/
union xran_cp_radioapp_section_ext6 {
struct {
uint64_t symbolMask:14; /**< 5.4.7.6.3 symbol bit mask */
uint64_t reserved1:2;
uint64_t rbgMask:28; /**< 5.4.7.6.2 resource block group bit mask */
uint64_t rbgSize:3; /**< 5.4.7.6.1 resource block group size */
uint64_t reserved0:1;
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 */
}all_bits;
struct{
uint64_t data_field1;
}data_field;
} __attribute__((__packed__));
/**
* @ingroup xran_cp_pkt
*
* @description
* eAxC Mask Selection Extension (ExtType 7)
* Defined in 5.4.7.7 Table 5-29
* applies to section type 0
* The structure is reordered for byte order conversion.
*/
struct xran_cp_radioapp_section_ext7 {
uint32_t eAxCmask:16; /**< 5.4.7.7.1 eAxC Mask */
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
* Regularization factor (ExtType 8), defined in 5.4.7.8 Table 5-30
* applies to section type 5 instead of sending section type 6
* The structure is reordered for byte order conversion.
*/
struct xran_cp_radioapp_section_ext8 {
uint32_t regularizationFactor:16; /**< 5.4.7.8.1 eAxC Mask */
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
* Dynamic Spectrum Sharing parameters (ExtType 9)
* Defined in 5.4.7.9 Table 5-31
* The structure does not need the conversion of byte order.
*/
struct xran_cp_radioapp_section_ext9 {
uint8_t reserved;
uint8_t technology; /**< 5.4.7.9.1 technology (interface name) */
uint8_t extLen; /**< 5.4.6.3 extension length, in 32bits words */
uint8_t extType:7; /**< 5.4.6.1 extension type */
uint8_t ef:1; /**< 5.4.6.2 extension flag */
} __attribute__((__packed__));
/**
* @ingroup xran_cp_pkt
*
* @description
* Section description for group configuration of multiple ports
* ExtType 10, Defined in 5.4.7.10 Table 5-32 and Table 5-33
* Applies to section type 1 3, and 5.
* The structure does not need the conversion of byte order.
*/
union xran_cp_radioapp_section_ext10 {
uint32_t data_field;
struct{
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 */
uint8_t numPortc:6; /**< 5.4.7.10.2 the number of eAxC ports */
uint8_t beamGroupType:2; /**< 5.4.7.10.1 the type of beam grouping */
uint8_t reserved; /**< beam IDs start from here for group type 2 */
}all_bits;
} __attribute__((__packed__));
#define xran_cp_radioapp_sec_ext10_ExtType 0
#define xran_cp_radioapp_sec_ext10_EF 7
#define xran_cp_radioapp_sec_ext10_ExtLen 8
#define xran_cp_radioapp_sec_ext10_NumPortc 16
#define xran_cp_radioapp_sec_ext10_BeamGroupType 22
#define xran_cp_radioapp_sec_ext10_Res0 24
/**
* @ingroup xran_cp_pkt
*
* @description
* Flexible Beamforming Weights Extension Type (ExtType 11)
* Defined in 5.4.7.11 Table 5-35
* The structure is reordered for network byte order.
*/
union xran_cp_radioapp_section_ext11 {
struct {
uint32_t reserved:6;
uint32_t RAD:1; /**< 5.4.7.11.8 Reset After PRB Discontinuity */
uint32_t disableBFWs:1; /**< 5.4.7.11.6 disable beamforming weights */
uint32_t extLen:16; /**< extension length in 32bits words - 2bytes */
uint32_t extType:7; /**< 5.4.6.1 extension type */
uint32_t ef:1; /**< 5.4.6.2 extension flag */
uint8_t numBundPrb; /**< 5.4.7.11.3 Number of bundled PRBs per beamforming weights */
uint8_t bfwCompMeth:4; /**< 5.4.7.11.1 Beamforming weight Compression method (5.4.7.1.1) */
uint8_t bfwIqWidth:4; /**< 5.4.7.11.1 Beamforming weight IQ bit width (5.4.7.1.1) */
} __attribute__((__packed__)) all_bits;
struct{
uint32_t data_field1;
uint16_t data_field2;
} __attribute__((__packed__)) data_field;
/*
* bfwCompParam 5.4.7.11.2 beamforming weight compression parameter for PRB bundle
* beamId beam ID for PRB bundle (15bits)
* bfwI / bfwQ ....... beamforming weights for PRB bundle
* .....
* repeat until PRB bundle L
*
* zero pad (4-byte boundary)
*/
} __attribute__((__packed__));
#define xran_cp_radioapp_sec_ext11_bitfield_REV 0
#define xran_cp_radioapp_sec_ext11_bitfield_RAD 6
#define xran_cp_radioapp_sec_ext11_bitfield_DisBFWs 7
#define xran_cp_radioapp_sec_ext11_bitfield_ExtLen 8
#define xran_cp_radioapp_sec_ext11_bitfield_ExtType 24
#define xran_cp_radioapp_sec_ext11_bitfield_Ef 31
#define xran_cp_radioapp_sec_ext11_bitfield_NumPrb 0
#define xran_cp_radioapp_sec_ext11_bitfield_BFWCompMeth 8
#define xran_cp_radioapp_sec_ext11_bitfield_BFWIQWidth 12
/**********************************************************
* 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_ */

View File

@@ -0,0 +1,197 @@
/******************************************************************************
*
* 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 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;
} __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 xran u-plane packet header with compression
* 3.1.1 Ethernet Encapsulation
*****************************************************************************/
struct xran_up_pkt_hdr_comp
{
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; /**< data section Header */
struct data_section_compression_hdr data_comp_hdr; /** Compression Header */
} __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;
struct eth_xran_up_pkt_hdr_comp
{
struct rte_ether_hdr eth_hdr;
struct xran_up_pkt_hdr_comp xran_hdr;
}__rte_packed;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,561 @@
/******************************************************************************
*
* 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 provides the implementation of User Plane Messages APIs.
*
* @file xran_up_api.c
* @ingroup group_lte_source_xran
* @author Intel Corporation
*
**/
#include <inttypes.h>
#if defined(__arm__) || defined(__aarch64__)
#else
#include <immintrin.h>
#endif
#include <rte_mbuf.h>
#include <rte_mbuf.h>
#include "xran_fh_o_du.h"
#include "xran_transport.h"
#include "xran_up_api.h"
#include "xran_printf.h"
#include "xran_mlog_lnx.h"
#include "xran_common.h"
#if 0
/**
* @brief Builds eCPRI header in xRAN packet
*
* @param mbuf Initialized rte_mbuf packet
* @param iq_data_num_bytes Number of bytes in IQ data buffer
* @param iq_data_offset Number of elements already sent
* @return int int 0 on success, non zero on failure
*/
static int build_ecpri_hdr(struct rte_mbuf *mbuf,
const uint32_t iq_data_num_bytes,
const uint32_t iq_data_offset,
uint8_t alignment)
{
struct xran_ecpri_hdr *ecpri_hdr = (struct xran_ecpri_hdr *)
rte_pktmbuf_append(mbuf, sizeof(struct xran_ecpri_hdr));
uint16_t iq_samples_bytes_in_mbuf = rte_pktmbuf_tailroom(mbuf) -
sizeof(struct radio_app_common_hdr) - sizeof(struct data_section_hdr);
iq_samples_bytes_in_mbuf -= (iq_samples_bytes_in_mbuf % alignment);
if (NULL == ecpri_hdr)
return 1;
ecpri_hdr->cmnhdr.data.data_num_1 = 0x0;
ecpri_hdr->cmnhdr.bits.ecpri_ver = XRAN_ECPRI_VER;
//ecpri_hdr->cmnhdr.bits.ecpri_resv = 0;
//ecpri_hdr->cmnhdr.bits.ecpri_concat = 0;
ecpri_hdr->cmnhdr.bits.ecpri_mesg_type = ECPRI_IQ_DATA;
if (iq_data_offset + iq_samples_bytes_in_mbuf > iq_data_num_bytes) {
ecpri_hdr->cmnhdr.bits.ecpri_payl_size =
rte_cpu_to_be_16(sizeof(struct radio_app_common_hdr) +
sizeof(struct data_section_hdr) +
(iq_data_num_bytes - iq_data_offset) +
XRAN_ECPRI_HDR_SZ); //xran_get_ecpri_hdr_size());
ecpri_hdr->ecpri_seq_id.bits.e_bit = 1; /* last segment */
} else {
ecpri_hdr->cmnhdr.bits.ecpri_payl_size =
rte_cpu_to_be_16(sizeof(struct radio_app_common_hdr) +
sizeof(struct data_section_hdr) +
iq_samples_bytes_in_mbuf +
XRAN_ECPRI_HDR_SZ); //xran_get_ecpri_hdr_size());
ecpri_hdr->ecpri_seq_id.bits.e_bit = 0;
}
ecpri_hdr->ecpri_xtc_id = 0; /* currently not used */
ecpri_hdr->ecpri_seq_id.bits.sub_seq_id = iq_data_offset /
iq_samples_bytes_in_mbuf;
return 0;
}
#endif
/**
* @brief Builds eCPRI header in xRAN packet
*
* @param mbuf Initialized rte_mbuf packet
* @param ecpri_mesg_type eCPRI message type
* @param payl_size the size in bytes of the payload part of eCPRI message
* @param CC_ID Component Carrier ID for ecpriRtcid/ecpriPcid
* @param Ant_ID Antenna ID for ecpriRtcid/ecpriPcid
* @param seq_id Message identifier for eCPRI message
* @param comp_meth Compression method
* @return int int 0 on success, non zero on failure
*/
static inline int xran_build_ecpri_hdr_ex(struct rte_mbuf *mbuf,
uint8_t ecpri_mesg_type,
int payl_size,
uint8_t CC_ID,
uint8_t Ant_ID,
uint8_t seq_id,
uint8_t comp_meth,
enum xran_comp_hdr_type staticEn)
{
char *pChar = rte_pktmbuf_mtod(mbuf, char*);
struct xran_ecpri_hdr *ecpri_hdr = (struct xran_ecpri_hdr *)(pChar + sizeof(struct rte_ether_hdr));
uint16_t ecpri_payl_size = payl_size
+ sizeof(struct radio_app_common_hdr)
+ XRAN_ECPRI_HDR_SZ; //xran_get_ecpri_hdr_size();
if (NULL == ecpri_hdr)
return 1;
ecpri_hdr->cmnhdr.data.data_num_1 = 0x0;
ecpri_hdr->cmnhdr.bits.ecpri_ver = XRAN_ECPRI_VER;
//ecpri_hdr->cmnhdr.bits.ecpri_resv = 0; // should be zero
//ecpri_hdr->cmnhdr.bits.ecpri_concat = 0;
ecpri_hdr->cmnhdr.bits.ecpri_mesg_type = ecpri_mesg_type;
ecpri_hdr->cmnhdr.bits.ecpri_payl_size = rte_cpu_to_be_16(ecpri_payl_size);
/* one to one lls-CU to RU only and band sector is the same */
ecpri_hdr->ecpri_xtc_id = xran_compose_cid(0, 0, CC_ID, Ant_ID);
/* no transport layer fragmentation supported */
ecpri_hdr->ecpri_seq_id.data.data_num_1 = 0x8000;
ecpri_hdr->ecpri_seq_id.bits.seq_id = seq_id;
/* no transport layer fragmentation supported */
//ecpri_hdr->ecpri_seq_id.sub_seq_id = 0;
//ecpri_hdr->ecpri_seq_id.e_bit = 1;
return 0;
}
/**
* @brief Builds application layer of xRAN packet
*
* @param mbuf Initialized rte_mbuf packet
* @param app_hdr_input Radio App common header structure to be set in mbuf
* packet.
* @return int 0 on success, non zero on failure
*/
static inline int build_application_layer(
struct rte_mbuf *mbuf,
const struct radio_app_common_hdr *app_hdr_input)
{
char *pChar = rte_pktmbuf_mtod(mbuf, char*);
struct radio_app_common_hdr *app_hdr = (struct radio_app_common_hdr *)(pChar + sizeof(struct rte_ether_hdr)
+ sizeof (struct xran_ecpri_hdr));
if (NULL == app_hdr)
return 1;
memcpy(app_hdr, app_hdr_input, sizeof(struct radio_app_common_hdr));
return 0;
}
/**
* @brief Builds section header in xRAN packet
*
* @param mbuf Initialized rte_mbuf packet
* @param sec_hdr Section header structure to be set in mbuf packet
* @param offset Offset to create the section header
* @return int 0 on success, non zero on failure
*/
static inline int build_section_hdr(
struct rte_mbuf *mbuf,
const struct data_section_hdr *sec_hdr,
uint32_t offset)
{
char *pChar = rte_pktmbuf_mtod(mbuf, char*);
struct data_section_hdr *section_hdr = (struct data_section_hdr *)(pChar + offset);
if (NULL == section_hdr)
return 1;
memcpy(section_hdr, &sec_hdr->fields.all_bits, sizeof(struct data_section_hdr));
return 0;
}
#if 0
/**
* @brief Function for appending IQ samples data to the mbuf.
*
* @param mbuf Initialized rte_mbuf packet.
* @param iq_data_start Address of the first element in IQ data array.
* @param iq_data_num_bytes Size of the IQ data array.
* @param iq_data_offset IQ data btyes already sent.
* @return uint16_t Bytes that have been appended to the packet.
*/
static inline uint16_t append_iq_samples_ex(
struct rte_mbuf *mbuf,
int iq_sam_offset,
const void *iq_data_start,
const uint32_t iq_data_num_bytes,
enum xran_input_byte_order iq_buf_byte_order,
uint32_t do_copy)
{
char *pChar = rte_pktmbuf_mtod(mbuf, char*);
void *iq_sam_buf;
iq_sam_buf = (pChar + iq_sam_offset);
if (iq_sam_buf == NULL){
print_err("iq_sam_buf == NULL\n");
return 0;
}
if(iq_buf_byte_order == XRAN_CPU_LE_BYTE_ORDER){
int idx = 0;
uint16_t *psrc = (uint16_t *)iq_data_start;
uint16_t *pdst = (uint16_t *)iq_sam_buf;
/* CPU byte order (le) of IQ to network byte order (be) */
for (idx = 0; idx < iq_data_num_bytes/sizeof(int16_t); idx++){
pdst[idx] = (psrc[idx]>>8) | (psrc[idx]<<8); //rte_cpu_to_be_16(psrc[idx]);
}
}
else if(iq_buf_byte_order == XRAN_NE_BE_BYTE_ORDER){
if(do_copy) {
memcpy(iq_sam_buf, (uint8_t *)iq_data_start, iq_data_num_bytes);
}
}
return iq_data_num_bytes;
}
/**
* @brief Function for appending IQ samples data to the mbuf.
*
* @param mbuf Initialized rte_mbuf packet.
* @param iq_data_start Address of the first element in IQ data array.
* @param iq_data_num_bytes Size of the IQ data array.
* @param iq_data_offset IQ data btyes already sent.
* @return uint16_t Bytes that have been appended to the packet.
*/
static uint16_t append_iq_samples(
struct rte_mbuf *mbuf,
const void *iq_data_start,
const uint32_t iq_data_num_bytes,
const uint32_t iq_data_offset,
const uint8_t alignment)
{
uint16_t iq_bytes_to_send = 0;
uint16_t free_space_in_pkt = rte_pktmbuf_tailroom(mbuf);
if (free_space_in_pkt > iq_data_num_bytes - iq_data_offset)
iq_bytes_to_send = iq_data_num_bytes - iq_data_offset;
else
iq_bytes_to_send = free_space_in_pkt;
/* don't cut off an iq in half */
iq_bytes_to_send -= iq_bytes_to_send % alignment;
void *iq_sam_buf = (void *)rte_pktmbuf_append(mbuf, iq_bytes_to_send);
memcpy(iq_sam_buf, (uint8_t *)iq_data_start + iq_data_offset,
iq_bytes_to_send);
return iq_bytes_to_send;
}
#endif
/**
* @brief Builds compression header in xRAN packet
*
* @param mbuf Initialized rte_mbuf packet
* @param compression_hdr Section compression header structure
* to be set in mbuf packet
* @param offset mbuf data offset to create compression header
* @return int 0 on success, non zero on failure
*/
static inline int build_compression_hdr(
struct rte_mbuf *mbuf,
const struct data_section_compression_hdr *compr_hdr,
uint32_t offset)
{
char *pChar = rte_pktmbuf_mtod(mbuf, char*);
struct data_section_compression_hdr *compression_hdr =
(struct data_section_compression_hdr *)(pChar + offset);
if (NULL == compression_hdr)
return 1;
memcpy(compression_hdr, compr_hdr, sizeof(*compression_hdr));
return 0;
}
#if 0
/**
* @brief Appends compression parameter in xRAN packet
*
* @param mbuf Initialized rte_mbuf packet
* @param ud_comp_paramr Compression param to be set in mbuf packet
* @return int 0 on success, non zero on failure
*/
static int append_comp_param(struct rte_mbuf *mbuf, union compression_params *ud_comp_param)
{
union compression_params *compr_param =
(union compression_params *)rte_pktmbuf_append(mbuf, sizeof(union compression_params));
if (NULL == compr_param)
return 1;
memcpy(compr_param, ud_comp_param, sizeof(union compression_params));
return 0;
}
#endif
/**
* @brief Function for extracting all IQ samples from xRAN packet
* holding a single data section
* @param iq_data_start Address of the first element in IQ data array.
* @param symb_id Symbol ID to be extracted from ecpri header
* @param seq_id Sequence ID to be extracted from radio header
* @return int Size of remaining mbuf filled with IQ samples
zero on failure
*/
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,
uint8_t *filter_id,
union 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,
enum xran_comp_hdr_type staticComp,
uint8_t *compMeth,
uint8_t *iqWidth,
uint8_t *is_prach)
{
#if XRAN_MLOG_VAR
uint32_t mlogVar[10];
uint32_t mlogVarCnt = 0;
#endif
struct xran_eaxc_info result;
if (NULL == mbuf)
return 0;
if (NULL == iq_data_start)
return 0;
/* Process eCPRI header. */
const struct xran_ecpri_hdr *ecpri_hdr = rte_pktmbuf_mtod(mbuf, void *);
if (ecpri_hdr == NULL)
return 0;
if (seq_id)
*seq_id = ecpri_hdr->ecpri_seq_id;
if(*CC_ID == 0xFF && *Ant_ID == 0xFF) {
/* if not classified vi HW Queue parse packet */
xran_decompose_cid((uint16_t)ecpri_hdr->ecpri_xtc_id, &result);
*CC_ID = result.ccId;
*Ant_ID = result.ruPortId;
}
/* Process radio header. */
struct radio_app_common_hdr *radio_hdr =
(void *)rte_pktmbuf_adj(mbuf, sizeof(*ecpri_hdr));
if (radio_hdr == NULL)
return 0; /* packet too short */
radio_hdr->sf_slot_sym.value = rte_be_to_cpu_16(radio_hdr->sf_slot_sym.value);
*is_prach = (radio_hdr->data_feature.filter_id > 0);
if (frame_id)
*frame_id = radio_hdr->frame_id;
if (subframe_id)
*subframe_id = radio_hdr->sf_slot_sym.subframe_id;
if (slot_id)
*slot_id = xran_slotid_convert(radio_hdr->sf_slot_sym.slot_id, 1);
if (symb_id)
*symb_id = radio_hdr->sf_slot_sym.symb_id;
if (filter_id)
*filter_id = radio_hdr->data_feature.filter_id;
/* Process data section hdr */
struct data_section_hdr *data_hdr =
(void *)rte_pktmbuf_adj(mbuf, sizeof(*radio_hdr));
if (data_hdr == NULL)
return 0; /* packet too short */
/* cpu byte order */
data_hdr->fields.all_bits = rte_be_to_cpu_32(data_hdr->fields.all_bits);
*num_prbu = data_hdr->fields.num_prbu;
*start_prbu = data_hdr->fields.start_prbu;
*sym_inc = data_hdr->fields.sym_inc;
*rb = data_hdr->fields.rb;
*sect_id = data_hdr->fields.sect_id;
if(expect_comp) {
const struct data_section_compression_hdr *data_compr_hdr;
if (staticComp != XRAN_COMP_HDR_TYPE_STATIC)
{
data_compr_hdr =
(void *) rte_pktmbuf_adj(mbuf, sizeof(*data_hdr));
if (data_compr_hdr == NULL)
return 0;
*compMeth = data_compr_hdr->ud_comp_hdr.ud_comp_meth;
*iqWidth = data_compr_hdr->ud_comp_hdr.ud_iq_width;
const uint8_t *compr_param =
(void *)rte_pktmbuf_adj(mbuf, sizeof(*data_compr_hdr));
*iq_data_start = (void *)compr_param; /*rte_pktmbuf_adj(mbuf, sizeof(*compr_param))*/;
}
else
{
*iq_data_start = rte_pktmbuf_adj(mbuf, sizeof(*data_hdr));
}
} else {
*iq_data_start = rte_pktmbuf_adj(mbuf, sizeof(*data_hdr));
}
if (*iq_data_start == NULL)
return 0;
#if XRAN_MLOG_VAR
mlogVar[mlogVarCnt++] = 0xBBBBBBBB;
mlogVar[mlogVarCnt++] = radio_hdr->frame_id;
mlogVar[mlogVarCnt++] = radio_hdr->sf_slot_sym.subframe_id;
mlogVar[mlogVarCnt++] = radio_hdr->sf_slot_sym.slot_id;
mlogVar[mlogVarCnt++] = radio_hdr->sf_slot_sym.symb_id;
mlogVar[mlogVarCnt++] = data_hdr->fields.sect_id;
mlogVar[mlogVarCnt++] = data_hdr->fields.start_prbu;
mlogVar[mlogVarCnt++] = data_hdr->fields.num_prbu;
mlogVar[mlogVarCnt++] = rte_pktmbuf_pkt_len(mbuf);
MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
#endif
return rte_pktmbuf_pkt_len(mbuf);
}
/**
* @brief Function for starting preparion of IQ samples portions
* to be sent in xRAN packet
*
* @param mbuf Initialized rte_mbuf packet.
* @param iq_data_start Address of the first element in IQ data array.
* @param iq_data_num_bytes Size of the IQ data array.
* @param iq_data_offset IQ data bytes already sent.
* @param alignment Size of IQ data alignment.
* @param pkt_gen_params Struct with parameters used for building packet
* @param num_sections Number of data sections to be created
* @return int Number of bytes that have been appended
to the packet within all appended sections.
*/
int32_t 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,
enum xran_comp_hdr_type staticEn,
uint32_t do_copy,
uint16_t num_sections,
uint16_t section_id_start,
uint16_t iq_offset)
{
uint32_t offset=0 , ret_val=0;
uint16_t idx , iq_len=0;
const void *iq_data;
uint16_t iq_n_section_size; //All data_section + compression hdrs + iq
iq_n_section_size = iq_data_num_bytes + num_sections*sizeof(struct data_section_hdr);
if ((params[0].compr_hdr_param.ud_comp_hdr.ud_comp_meth != XRAN_COMPMETHOD_NONE)&&(staticEn == XRAN_COMP_HDR_TYPE_DYNAMIC))
{
iq_n_section_size += num_sections*sizeof(struct data_section_compression_hdr);
}
if(xran_build_ecpri_hdr_ex(mbuf,
ECPRI_IQ_DATA,
(int)iq_n_section_size,
CC_ID,
Ant_ID,
seq_id,
params[0].compr_hdr_param.ud_comp_hdr.ud_comp_meth,
staticEn)){
print_err("xran_build_ecpri_hdr_ex return 0\n");
return 0;
}
if (build_application_layer(mbuf, &(params[0].app_params)) != 0){
print_err("build_application_layer return != 0\n");
return 0;
}
offset = sizeof(struct rte_ether_hdr)
+ sizeof(struct xran_ecpri_hdr)
+ sizeof(struct radio_app_common_hdr);
for(idx=0 ; idx < num_sections ; idx++)
{
if (build_section_hdr(mbuf, &(params[idx].sec_hdr),offset) != 0){
print_err("build_section_hdr return != 0\n");
return 0;
}
offset += sizeof(struct data_section_hdr);
if ((params[idx].compr_hdr_param.ud_comp_hdr.ud_comp_meth != XRAN_COMPMETHOD_NONE)&&(staticEn == XRAN_COMP_HDR_TYPE_DYNAMIC)) {
if (build_compression_hdr(mbuf, &(params[idx].compr_hdr_param),offset) !=0)
return 0;
offset += sizeof(struct data_section_compression_hdr);
}
/** IQ buffer contains space for data section/compression hdr in case of multiple sections.*/
iq_data = (const void *)((uint8_t *)iq_data_start
+ idx*(sizeof(struct data_section_hdr) + iq_data_num_bytes/num_sections));
if ((params[idx].compr_hdr_param.ud_comp_hdr.ud_comp_meth != XRAN_COMPMETHOD_NONE)&&(staticEn == XRAN_COMP_HDR_TYPE_DYNAMIC))
iq_data = (const void *)((uint8_t *)iq_data + idx*sizeof(struct data_section_compression_hdr));
//ret_val = (do_copy ? append_iq_samples_ex(mbuf, offset, iq_data_start, iq_data_num_bytes/num_sections, iq_buf_byte_order, do_copy) : iq_data_num_bytes/num_sections);
ret_val = iq_data_num_bytes/num_sections;
if(!ret_val)
return ret_val;
iq_len += ret_val;
offset += ret_val;
}
return iq_len;
}

View File

@@ -0,0 +1,115 @@
/******************************************************************************
*
* 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 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,
uint8_t *filter_id,
union 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,
enum xran_comp_hdr_type staticComp,
uint8_t *compMeth,
uint8_t *iqWidth,
uint8_t *is_prach);
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,
enum xran_comp_hdr_type staticEn,
uint32_t do_copy,
uint16_t num_sections,
uint16_t section_id_start,
uint16_t iq_offset);
#ifdef __cplusplus
}
#endif
#endif /* _XRAN_UP_API_H_ */