mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
[FHI72] Implement SRS eAxC IDs
Signed-off-by: Teodora Vladić <teodora.vladic@openairinterface.org>
This commit is contained in:
@@ -1582,6 +1582,9 @@ Edit the sample OAI gNB configuration file and check following parameters:
|
||||
* `prach_config`: PRACH-specific configuration
|
||||
* `eAxC_offset`: PRACH antenna offset; if not set, default value of `N = max(Nrx,Ntx)` is used
|
||||
* `kbar`: the PRACH guard interval, provided in RU
|
||||
* `srs_config`: SRS-specific configuration
|
||||
* `num_ant_elem`: number of Tx/Rx antenna elements; default is 0
|
||||
* `srs_eAxC_offset`: SRS antenna offset; if not set, default value of `N = max(Nrx,Ntx) + Nrx` is used
|
||||
* `app_id`: `DU` or `RU`. Sets the application `id` value in xRAN. Use the default value: `DU`.
|
||||
|
||||
Layer mapping (eAxC offsets) happens as follows:
|
||||
|
||||
@@ -28,6 +28,8 @@ It calls various helper function in the same file to set up DPDK memory buffer
|
||||
- `oai_xran_fh_rx_prach_callback()` through `xran_5g_prach_req()`: callback for
|
||||
PRACH data. For each TTI, OAI checks if PRACH is scheduled through `prach_ru_queue`.
|
||||
If yes, then reads and stores IQ samples into the `prach_buf`.
|
||||
- `oai_xran_fh_rx_srs_callback()` through `xran_5g_srs_req()`: callback for
|
||||
SRS data if SRS configured on eAxC IDs other than for PUSCH. TODO later text
|
||||
- `oai_physide_dl_tti_call_back()` through `xran_reg_physide_cb()`: only used
|
||||
to unblock timing in `oai_xran_fh_rx_callback()` and `oai_xran_fh_rx_prach_callback()`
|
||||
upon first xran call.
|
||||
|
||||
@@ -168,6 +168,44 @@ int oai_physide_dl_tti_call_back(void *param, uint8_t mu)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @details Read SRS data from xran buffers for each RU (for each `port_id`).
|
||||
* If I/Q compression (bitwidth < 16 bits) is configured, decompresses the data
|
||||
* before writing. */
|
||||
void oai_xran_fh_rx_srs_callback(void *pCallbackTag, xran_status_t status, uint8_t mu)
|
||||
{
|
||||
if (!first_call_set)
|
||||
return;
|
||||
struct xran_cb_tag *callback_tag = (struct xran_cb_tag *)pCallbackTag;
|
||||
|
||||
uint32_t port_id = callback_tag->oXuId;
|
||||
struct xran_fh_config *fh_cfg = get_xran_fh_config(port_id);
|
||||
uint32_t num_ant_elem = fh_cfg->nAntElmTRx;
|
||||
|
||||
const int slots_in_sf = 1 << mu;
|
||||
const int sf_in_frame = 10;
|
||||
|
||||
uint32_t tti = callback_tag->slotiId;
|
||||
uint32_t frame = XranGetFrameNum(tti, 0, sf_in_frame, slots_in_sf);
|
||||
//uint32_t subframe = XranGetSubFrameNum(tti, slots_in_sf, sf_in_frame);
|
||||
uint32_t slot = XranGetSlotNum(tti, slots_in_sf * sf_in_frame); // slot within a frame, not a subframe
|
||||
uint32_t rx_sym = callback_tag->symbol & 0xFF; // rx_sym = 7 => cb full slot
|
||||
|
||||
LOG_D(HW, "[%d.%d] %s, tti %d rx_sym %d ru_id %d\n", frame, slot, __FUNCTION__, tti, rx_sym, port_id);
|
||||
|
||||
// TODO: reset the number of received packets for non SRS slots
|
||||
for (uint16_t cc_id = 0; cc_id < 1 /*nSectorNum*/; cc_id++) {
|
||||
oran_buf_list_t *bufs = get_xran_buffers(port_id);
|
||||
for (int ant_id = 0; ant_id < num_ant_elem; ant_id++) {
|
||||
for (int sym_idx = 0; sym_idx < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_idx++) {
|
||||
struct xran_prb_map *pPrbMap = (struct xran_prb_map *)bufs->srsdstdecomp[ant_id][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData;
|
||||
pPrbMap->sFrontHaulRxPacketCtrl[sym_idx].nRxPkt = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: map SRS IQ data into OAI (new buffer or reuse rxdataF ?)
|
||||
}
|
||||
|
||||
/** @details Read PRACH data from xran buffers for each RU (for each `port_id`).
|
||||
* If I/Q compression (bitwidth < 16 bits) is configured, decompresses the data
|
||||
* before writing. */
|
||||
|
||||
@@ -21,6 +21,8 @@ typedef struct {
|
||||
void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status, uint8_t mu);
|
||||
/** @brief xran callback for fronthaul PRACH RX, see xran_5g_prach_req(). */
|
||||
void oai_xran_fh_rx_prach_callback(void *pCallbackTag, xran_status_t status, uint8_t mu);
|
||||
/** @brief xran callback for fronthaul SRS RX, see xran_5g_srs_req(). */
|
||||
void oai_xran_fh_rx_srs_callback(void *pCallbackTag, xran_status_t status, uint8_t mu);
|
||||
/** @brief xran callback for time alignment, see xran_reg_physide_cb(). */
|
||||
int oai_physide_dl_tti_call_back(void *param, uint8_t mu);
|
||||
|
||||
|
||||
@@ -834,6 +834,36 @@ static bool set_fh_prach_config(void *mplane_api,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool set_fh_srs_config(void *mplane_api,
|
||||
const openair0_config_t *oai0,
|
||||
const uint32_t max_num_ant,
|
||||
const paramdef_t *srsp,
|
||||
int nsrs,
|
||||
struct xran_srs_config *srs_config)
|
||||
{
|
||||
//const split7_config_t *s7cfg = &oai0->split7;
|
||||
|
||||
/* deprecated */
|
||||
srs_config->symbMask = 0;
|
||||
/**< SRS slot within TDD period (special slot), for O-RU emulation */
|
||||
srs_config->slot = 0;
|
||||
/**< tti offset to delay the transmission of NDM SRS UP, for O-RU emulation */
|
||||
srs_config->ndm_offset = 0;
|
||||
/**< symbol duration for NDM SRS UP transmisson, for O-RU emulation */
|
||||
srs_config->ndm_txduration = 0;
|
||||
|
||||
/**< starting value of eAxC for SRS packets for this numerology (Absolute value). Should be unique across all numerologies for the RU */
|
||||
#ifdef OAI_MPLANE
|
||||
xran_mplane_t *xran_mplane = (xran_mplane_t *)mplane_api;
|
||||
// TODO
|
||||
#else
|
||||
const paramdef_t *pd = gpd(srsp, nsrs, ORAN_SRS_CONFIG_EAXC_OFFSET);
|
||||
srs_config->srsEaxcOffset = pd->paramflags & PARAMFLAG_PARAMSET ? *pd->u8ptr : max_num_ant;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool set_fh_frame_config(const openair0_config_t *oai0, struct xran_frame_config *frame_config)
|
||||
{
|
||||
const split7_config_t *s7cfg = &oai0->split7;
|
||||
@@ -1006,6 +1036,15 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c
|
||||
return false;
|
||||
}
|
||||
|
||||
paramdef_t srsp[] = ORAN_SRS_DESC;
|
||||
int nsrs = sizeofArray(srsp);
|
||||
sprintf(aprefix, "%s.%s.[%d].%s", CONFIG_STRING_ORAN, CONFIG_STRING_ORAN_FH, ru_idx, CONFIG_STRING_ORAN_SRS);
|
||||
ret = config_get(config_get_if(), srsp, nsrs, aprefix);
|
||||
if (ret < 0) {
|
||||
printf("No configuration section \"%s\": cannot initialize fhi_lib!\n", aprefix);
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(fh_config, 0, sizeof(*fh_config));
|
||||
|
||||
fh_config->dpdk_port = ru_idx; // DPDK port number used for FH
|
||||
@@ -1013,7 +1052,7 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c
|
||||
fh_config->nCC = 1; // number of Component carriers supported on FH; M-plane info
|
||||
fh_config->neAxc = RTE_MAX(oai0->tx_num_channels / num_rus, oai0->rx_num_channels / num_rus); // number of eAxc supported on one CC = max(PDSCH, PUSCH)
|
||||
fh_config->neAxcUl = oai0->rx_num_channels / num_rus; // number of eAxc supported on one CC for UL direction = PUSCH
|
||||
fh_config->nAntElmTRx = 0; // number of antenna elements for TX and RX = SRS; used only if XRAN_CATEGORY_B
|
||||
fh_config->nAntElmTRx = *gpd(srsp, nsrs, ORAN_SRS_CONFIG_NUM_ANT_ELEM)->uptr; // number of antenna elements for TX and RX = SRS; one tx/rx-array can have one or more antenna elements; XRAN_MAX_ANT_ARRAY_ELM_NR
|
||||
fh_config->nDLAbsFrePointA = 0; // Abs Freq Point A of the Carrier Center Frequency for in KHz Value; not used in xran
|
||||
fh_config->nULAbsFrePointA = 0; // Abs Freq Point A of the Carrier Center Frequency for in KHz Value; not used in xran
|
||||
fh_config->nDLCenterFreqARFCN = 0; // center frequency for DL in NR-ARFCN; not used in xran
|
||||
@@ -1026,7 +1065,9 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c
|
||||
return false;
|
||||
|
||||
fh_config->enableCP = 1; // enable C-plane
|
||||
fh_config->srsEnable = 0; // enable SRS; used only if XRAN_CATEGORY_B
|
||||
fh_config->srsEnable = srsp->paramflags & PARAMFLAG_PARAMSET ? 1 : 0; // enable SRS; can be used for XRAN_CATEGORY_A and XRAN_CATEGORY_B
|
||||
fh_config->srsEnableCp = srsp->paramflags & PARAMFLAG_PARAMSET ? 1 : 0; // enable SRS C-plane
|
||||
fh_config->SrsDelaySym = 0; // enable static SRS configuration (when srsEnableCp = 0)
|
||||
fh_config->puschMaskEnable = 0; // enable PUSCH mask; only used if id = O_RU
|
||||
fh_config->puschMaskSlot = 0; // specific which slot PUSCH channel masked; only used if id = O_RU
|
||||
fh_config->csirsEnable = 0; // enable CSI-RS (Cat B specific)
|
||||
@@ -1039,9 +1080,10 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c
|
||||
fh_config->mu_number[0] = mu_number; /* 0 -> 15kHz, 1 -> 30kHz, 2 -> 60kHz, 3 -> 120kHz, 4 -> 240kHz */
|
||||
fh_config->nNumerology[0] = mu_number; /* 0 -> 15kHz, 1 -> 30kHz, 2 -> 60kHz, 3 -> 120kHz, 4 -> 240kHz */
|
||||
|
||||
/* SRS only used if XRAN_CATEGORY_B
|
||||
/* SRS configuration
|
||||
Note: srs_config->eAxC_offset >= prach_config->eAxC_offset + PRACH */
|
||||
// fh_config->srs_conf = {0};
|
||||
if (!set_fh_srs_config(mplane_api, oai0, RTE_MAX(oai0->tx_num_channels / num_rus, oai0->rx_num_channels / num_rus) + oai0->rx_num_channels / num_rus, srsp, nsrs, &fh_config->srs_conf))
|
||||
return false;
|
||||
if (!set_fh_frame_config(oai0, &fh_config->frame_conf))
|
||||
return false;
|
||||
if (!set_fh_ru_config(mplane_api, rup, oai0->split7.prach_fftSize, nru, xran_cat, mu_number, &fh_config->ru_conf))
|
||||
|
||||
@@ -264,6 +264,7 @@ static void oran_allocate_buffers(void *handle,
|
||||
oran_port_instance_t *pi = &portInstances[0];
|
||||
AssertFatal(handle != NULL, "no handle provided\n");
|
||||
uint32_t xran_max_antenna_nr = RTE_MAX(fh_config->neAxc, fh_config->neAxcUl);
|
||||
uint32_t xran_max_ant_array_elm_nr = RTE_MAX(fh_config->nAntElmTRx, xran_max_antenna_nr);
|
||||
uint32_t xran_max_sections_per_slot = RTE_MAX(fh_config->max_sections_per_slot, XRAN_MIN_SECTIONS_PER_SLOT);
|
||||
|
||||
#if defined(__arm__) || defined(__aarch64__)
|
||||
@@ -363,12 +364,32 @@ static void oran_allocate_buffers(void *handle,
|
||||
size_of_prb_map_prach,
|
||||
&prachConf);
|
||||
|
||||
// SRS
|
||||
oran_cplane_prb_config srsConf = {
|
||||
.nTddPeriod = fh_config->frame_conf.nTddPeriod,
|
||||
.mixed_slot_index = idx,
|
||||
.slotMap = ulPm,
|
||||
.mixedSlotMap = ulPmMixed,
|
||||
};
|
||||
oran_allocate_uplane_buffers(pi->instanceHandle, bl->srsdst, bl->bufs.srs, xran_max_ant_array_elm_nr, rxBufSize);
|
||||
oran_allocate_cplane_buffers(pi->instanceHandle,
|
||||
bl->srsdstdecomp,
|
||||
bl->bufs.srsdecomp,
|
||||
xran_max_ant_array_elm_nr,
|
||||
xran_max_sections_per_slot,
|
||||
mtu,
|
||||
fh_config,
|
||||
size_of_prb_map,
|
||||
&srsConf);
|
||||
|
||||
struct xran_buffer_list *src[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
|
||||
struct xran_buffer_list *srccp[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
|
||||
struct xran_buffer_list *dst[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
|
||||
struct xran_buffer_list *dstcp[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
|
||||
struct xran_buffer_list *prachdst[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
|
||||
struct xran_buffer_list *prachdstdecomp[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
|
||||
struct xran_buffer_list *srsdst[XRAN_MAX_ANT_ARRAY_ELM_NR][XRAN_N_FE_BUF_LEN];
|
||||
struct xran_buffer_list *srsdstdecomp[XRAN_MAX_ANT_ARRAY_ELM_NR][XRAN_N_FE_BUF_LEN];
|
||||
for (uint32_t a = 0; a < XRAN_MAX_ANTENNA_NR; ++a) {
|
||||
for (uint32_t j = 0; j < XRAN_N_FE_BUF_LEN; ++j) {
|
||||
src[a][j] = &bl->src[a][j];
|
||||
@@ -380,8 +401,15 @@ static void oran_allocate_buffers(void *handle,
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t a = 0; a < XRAN_MAX_ANT_ARRAY_ELM_NR && xran_max_ant_array_elm_nr; ++a) {
|
||||
for (uint32_t j = 0; j < XRAN_N_FE_BUF_LEN; ++j) {
|
||||
srsdst[a][j] = &bl->srsdst[a][j];
|
||||
srsdstdecomp[a][j] = &bl->srsdstdecomp[a][j];
|
||||
}
|
||||
}
|
||||
xran_5g_fronthault_config(pi->instanceHandle, src, srccp, dst, dstcp, oai_xran_fh_rx_callback, &portInstances->pusch_tag, fh_config->nNumerology[0]);
|
||||
xran_5g_prach_req(pi->instanceHandle, prachdst, prachdstdecomp, oai_xran_fh_rx_prach_callback, &portInstances->prach_tag, fh_config->nNumerology[0]);
|
||||
xran_5g_srs_req(pi->instanceHandle, srsdst, srsdstdecomp, oai_xran_fh_rx_srs_callback, &portInstances->prach_tag, fh_config->nNumerology[0]);
|
||||
}
|
||||
|
||||
void *oai_oran_initialize(struct xran_fh_init *xran_fh_init, struct xran_fh_config *xran_fh_config)
|
||||
@@ -421,6 +449,7 @@ void *oai_oran_initialize(struct xran_fh_init *xran_fh_init, struct xran_fh_conf
|
||||
struct xran_cb_tag tag = {.cellId = sector, .oXuId = o_xu_id};
|
||||
pi->prach_tag = tag;
|
||||
pi->pusch_tag = tag;
|
||||
pi->srs_tag = tag;
|
||||
|
||||
oran_allocate_buffers(gxran_handle[0], o_xu_id, 1, pi, xran_fh_init->mtu, &xran_fh_config[o_xu_id]);
|
||||
if ((xret = xran_timingsource_reg_tticb(NULL, oai_physide_dl_tti_call_back, NULL, 10, XRAN_CB_TTI)) != XRAN_STATUS_SUCCESS) {
|
||||
|
||||
@@ -16,6 +16,9 @@ typedef struct oran_bufs {
|
||||
|
||||
struct xran_flat_buffer prach[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN][XRAN_NUM_OF_SYMBOL_PER_SLOT];
|
||||
struct xran_flat_buffer prachdecomp[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
|
||||
|
||||
struct xran_flat_buffer srs[XRAN_MAX_ANT_ARRAY_ELM_NR][XRAN_N_FE_BUF_LEN][XRAN_NUM_OF_SYMBOL_PER_SLOT];
|
||||
struct xran_flat_buffer srsdecomp[XRAN_MAX_ANT_ARRAY_ELM_NR][XRAN_N_FE_BUF_LEN];
|
||||
} oran_bufs_t;
|
||||
|
||||
typedef struct oran_buf_list {
|
||||
@@ -28,6 +31,9 @@ typedef struct oran_buf_list {
|
||||
struct xran_buffer_list prachdst[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
|
||||
struct xran_buffer_list prachdstdecomp[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
|
||||
|
||||
struct xran_buffer_list srsdst[XRAN_MAX_ANT_ARRAY_ELM_NR][XRAN_N_FE_BUF_LEN];
|
||||
struct xran_buffer_list srsdstdecomp[XRAN_MAX_ANT_ARRAY_ELM_NR][XRAN_N_FE_BUF_LEN];
|
||||
|
||||
oran_bufs_t bufs;
|
||||
} oran_buf_list_t;
|
||||
|
||||
@@ -38,6 +44,7 @@ typedef struct oran_port_instance_t {
|
||||
|
||||
struct xran_cb_tag prach_tag;
|
||||
struct xran_cb_tag pusch_tag;
|
||||
struct xran_cb_tag srs_tag;
|
||||
} oran_port_instance_t;
|
||||
|
||||
extern struct xran_fh_config gxran_fh_config[XRAN_PORTS_NUM];
|
||||
|
||||
@@ -140,4 +140,16 @@
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
#define CONFIG_STRING_ORAN_SRS "srs_config"
|
||||
|
||||
#define ORAN_SRS_CONFIG_NUM_ANT_ELEM "num_ant_elem"
|
||||
#define ORAN_SRS_CONFIG_EAXC_OFFSET "srs_eAxC_offset"
|
||||
|
||||
// clang-format off
|
||||
#define ORAN_SRS_DESC {\
|
||||
{ORAN_SRS_CONFIG_NUM_ANT_ELEM, "Number of antenna elements\n", 0, .uptr=NULL, .defuintval=0, TYPE_UINT32, 0}, \
|
||||
{ORAN_SRS_CONFIG_EAXC_OFFSET, "RU's eAxC offset for SRS\n", 0, .u8ptr=NULL, .defuintval=0, TYPE_UINT8, 0}, \
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
#endif /* ORAN_PARAMS_H */
|
||||
|
||||
Reference in New Issue
Block a user