diff --git a/radio/fhi_72/oaioran.c b/radio/fhi_72/oaioran.c index 8be878f8ca..ee213f4301 100644 --- a/radio/fhi_72/oaioran.c +++ b/radio/fhi_72/oaioran.c @@ -43,6 +43,8 @@ #include "common/utils/threadPool/notified_fifo.h" +#define N_SC_PER_PRB 12 + #if OAI_FHI72_USE_POLLING #define USE_POLLING #endif @@ -71,21 +73,19 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status) static int32_t last_slot = -1; static int32_t last_frame = -1; - /* xran context contains the same xran_fh_init struct info, - but xran_fh_config struct info is RU specific only */ - struct xran_device_ctx *xran_ctx = xran_dev_get_ctx(); - const struct xran_fh_init *fh_init = &xran_ctx->fh_init; + const struct xran_fh_init *fh_init = get_xran_fh_init(); int num_ports = fh_init->xran_ports; /* assuming all RUs have the same numerology */ - const int slots_per_subframe = 1 << xran_ctx->fh_cfg.frame_conf.nNumerology; + const struct xran_fh_config *fh_cfg = get_xran_fh_config(0); + const int slots_in_sf = 1 << fh_cfg->frame_conf.nNumerology; + const int sf_in_frame = 10; static int rx_RU[XRAN_PORTS_NUM][160] = {0}; uint32_t tti = callback_tag->slotiId; - uint32_t slotnum = SLOTNUM_PER_SUBFRAME(xran_ctx->interval_us_local); - uint32_t frame = XranGetFrameNum(tti, 0, SUBFRAMES_PER_SYSTEMFRAME, slotnum); - uint32_t subframe = XranGetSubFrameNum(tti, slotnum, SUBFRAMES_PER_SYSTEMFRAME); - uint32_t slot = XranGetSlotNum(tti, slotnum); + 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); uint32_t rx_sym = callback_tag->symbol & 0xFF; uint32_t ru_id = callback_tag->oXuId; @@ -95,8 +95,7 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status) if (rx_sym == 7) { // in F release this value is defined as XRAN_FULL_CB_SYM (full slot (offset + 7)) #ifdef F_RELEASE for (int ru_idx = 0; ru_idx < num_ports; ru_idx++) { - struct xran_device_ctx *xran_ctx_per_ru = xran_dev_get_ctx_by_id(ru_idx); - struct xran_fh_config *fh_config = &xran_ctx_per_ru->fh_cfg; + struct xran_fh_config *fh_config = get_xran_fh_config(ru_idx); oran_buf_list_t *bufs = get_xran_buffers(ru_idx); for (uint16_t cc_id = 0; cc_id < 1 /* fh_config->nCC */; cc_id++) { // OAI does not support multiple CC yet. for(uint32_t ant_id = 0; ant_id < fh_config->neAxc; ant_id++) { @@ -118,7 +117,7 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status) // would see periodic output with only "0" in stats counters if (!first_call_set) return; - uint32_t slot2 = slot + (subframe * slots_per_subframe); + uint32_t slot2 = slot + (subframe * slots_in_sf); rx_RU[ru_id][slot2] = 1; if (last_frame > 0 && frame > 0 && ((slot2 > 0 && last_frame != frame) || (slot2 == 0 && last_frame != ((1024 + frame - 1) & 1023)))) @@ -172,20 +171,21 @@ static int read_prach_data(ru_info_t *ru, int frame, int slot) /* calculate tti and subframe_id from frame, slot num */ int sym_idx = 0; - struct xran_device_ctx *xran_ctx = xran_dev_get_ctx(); - struct xran_prach_cp_config *pPrachCPConfig = &(xran_ctx->PrachCPConfig); - struct xran_ru_config *ru_conf = &(xran_ctx->fh_cfg.ru_conf); - int slots_per_frame = 10 << xran_ctx->fh_cfg.frame_conf.nNumerology; - int slots_per_subframe = 1 << xran_ctx->fh_cfg.frame_conf.nNumerology; + struct xran_fh_init *fh_init = get_xran_fh_init(); + struct xran_fh_config *fh_cfg = get_xran_fh_config(0); + int prach_sym = get_prach_conf_duration(0); + struct xran_ru_config *ru_conf = &fh_cfg->ru_conf; + int slots_per_frame = 10 << fh_cfg->frame_conf.nNumerology; + int slots_per_subframe = 1 << fh_cfg->frame_conf.nNumerology; int tti = slots_per_frame * (frame) + (slot); uint32_t subframe = slot / slots_per_subframe; uint32_t is_prach_slot = xran_is_prach_slot(0, subframe, (slot % slots_per_subframe)); - int nb_rx_per_ru = ru->nb_rx / xran_ctx->fh_init.xran_ports; + int nb_rx_per_ru = ru->nb_rx / fh_init->xran_ports; /* If it is PRACH slot, copy prach IQ from XRAN PRACH buffer to OAI PRACH buffer */ if (is_prach_slot) { - for (sym_idx = 0; sym_idx < pPrachCPConfig->numSymbol; sym_idx++) { + for (sym_idx = 0; sym_idx < prach_sym; sym_idx++) { for (int aa = 0; aa < ru->nb_rx; aa++) { int16_t *dst, *src; int idx = 0; @@ -316,16 +316,16 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot) #endif // return(0); - struct xran_device_ctx *xran_ctx = xran_dev_get_ctx(); - int slots_per_frame = 10 << xran_ctx->fh_cfg.frame_conf.nNumerology; + struct xran_fh_config *fh_cfg = get_xran_fh_config(0); + int slots_per_frame = 10 << fh_cfg->frame_conf.nNumerology; int tti = slots_per_frame * (*frame) + (*slot); read_prach_data(ru, *frame, *slot); - const struct xran_fh_init *fh_init = &xran_ctx->fh_init; - int nPRBs = xran_ctx->fh_cfg.nULRBs; - int fftsize = 1 << xran_ctx->fh_cfg.ru_conf.fftSize; + const struct xran_fh_init *fh_init = get_xran_fh_init(); + int nPRBs = fh_cfg->nULRBs; + int fftsize = 1 << fh_cfg->ru_conf.fftSize; int slot_offset_rxdata = 3 & (*slot); uint32_t slot_size = 4 * 14 * fftsize; @@ -336,8 +336,7 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot) for (uint8_t ant_id = 0; ant_id < ru->nb_rx; ant_id++) { rx_data = (uint8_t *)ru->rxdataF[ant_id]; start_ptr = rx_data + (slot_size * slot_offset_rxdata); - xran_ctx = xran_dev_get_ctx_by_id(ant_id / nb_rx_per_ru); - const struct xran_frame_config *frame_conf = &xran_ctx->fh_cfg.frame_conf; + const struct xran_frame_config *frame_conf = &get_xran_fh_config(ant_id / nb_rx_per_ru)->frame_conf; // skip processing this slot is TX (no RX in this slot) if (is_tdd_dl_guard_slot(frame_conf, *slot)) continue; @@ -481,10 +480,10 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp) int32_t *pos = NULL; int idx = 0; - struct xran_device_ctx *xran_ctx = xran_dev_get_ctx(); - const struct xran_fh_init *fh_init = &xran_ctx->fh_init; - int nPRBs = xran_ctx->fh_cfg.nDLRBs; - int fftsize = 1 << xran_ctx->fh_cfg.ru_conf.fftSize; + const struct xran_fh_init *fh_init = get_xran_fh_init(); + const struct xran_fh_config *fh_cfg = get_xran_fh_config(0); + int nPRBs = fh_cfg->nDLRBs; + int fftsize = 1 << fh_cfg->ru_conf.fftSize; int nb_tx_per_ru = ru->nb_tx / fh_init->xran_ports; for (uint16_t cc_id = 0; cc_id < 1 /*nSectorNum*/; cc_id++) { // OAI does not support multiple CC yet. diff --git a/radio/fhi_72/oran-init.c b/radio/fhi_72/oran-init.c index 410df0166a..07517dcf18 100644 --- a/radio/fhi_72/oran-init.c +++ b/radio/fhi_72/oran-init.c @@ -30,7 +30,9 @@ #include "common/utils/assertions.h" #include "common/utils/LOG/log.h" +#include "common/utils/nr/nr_common.h" #include "common_lib.h" +#include "openair2/LAYER2/NR_MAC_COMMON/nr_prach_config.h" /* PRACH data samples are 32 bits wide (16bits for I/Q). Each packet contains * 840 samples for long sequence or 144 for short sequence. The payload length @@ -46,6 +48,10 @@ static oran_port_instance_t gPortInst[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR]; void *gxran_handle; +static struct xran_fh_init g_fh_init = {0}; +static struct xran_fh_config g_fh_config[XRAN_PORTS_NUM] = {0}; +static uint32_t g_prach_conf_duration[XRAN_PORTS_NUM] = {0}; + static uint32_t get_nSW_ToFpga_FTH_TxBufferLen(int mu, int sections) { uint32_t xran_max_sections_per_slot = RTE_MAX(sections, XRAN_MIN_SECTIONS_PER_SLOT); @@ -460,12 +466,47 @@ int *oai_oran_initialize(struct xran_fh_init *xran_fh_init, struct xran_fh_confi printf("xran_reg_physide_cb failed %d\n", xret); exit(-1); } + + // retrieve and store prach duration + uint8_t idx = xran_fh_config[o_xu_id].prach_conf.nPrachConfIdx; + const struct xran_frame_config *fc = &xran_fh_config[o_xu_id].frame_conf; + g_prach_conf_duration[o_xu_id] = + get_nr_prach_occasion_info_from_index(idx, + fc->nNumerology > 2 ? FR2 : FR1, + fc->nFrameDuplexType == XRAN_FDD ? duplex_mode_FDD : duplex_mode_TDD) + .N_dur; } + // store config after xran initialization -- xran makes modifications to + // these structs during initialization + memcpy(&g_fh_init, xran_fh_init, sizeof(*xran_fh_init)); + memcpy(&g_fh_config, xran_fh_config, sizeof(*xran_fh_config) * xran_fh_init->xran_ports); + return (void *)gxran_handle; } oran_buf_list_t *get_xran_buffers(uint32_t port_id) { + struct xran_fh_init *fh_init = get_xran_fh_init(); + DevAssert(port_id < fh_init->xran_ports); return gPortInst[port_id][0].buf_list; } + +struct xran_fh_init *get_xran_fh_init(void) +{ + return &g_fh_init; +} + +struct xran_fh_config *get_xran_fh_config(uint32_t port_id) +{ + struct xran_fh_init *fh_init = get_xran_fh_init(); + DevAssert(port_id < fh_init->xran_ports); + return &g_fh_config[port_id]; +} + +uint32_t get_prach_conf_duration(uint32_t port_id) +{ + struct xran_fh_init *fh_init = get_xran_fh_init(); + DevAssert(port_id < fh_init->xran_ports); + return g_prach_conf_duration[port_id]; +} diff --git a/radio/fhi_72/oran-init.h b/radio/fhi_72/oran-init.h index e12fa90858..e56b683a9f 100644 --- a/radio/fhi_72/oran-init.h +++ b/radio/fhi_72/oran-init.h @@ -60,5 +60,8 @@ extern void *gxran_handle; int *oai_oran_initialize(struct xran_fh_init *fh_init, struct xran_fh_config *fh_config); oran_buf_list_t *get_xran_buffers(uint32_t port_id); +struct xran_fh_init *get_xran_fh_init(void); +struct xran_fh_config *get_xran_fh_config(uint32_t port_id); +uint32_t get_prach_conf_duration(uint32_t port_id); #endif /* ORAN_INIT_H */