Use locally available data instead of peaking into xran internals
Look up xran_fh_init/xran_fh_config through driver instead of peaking into xran internals. Note that xran writes values back into these structs during initialization, and hence it is important to store them _after initialization_. Some remarks regarding less obvious changes: - slotnum is replaced by slots_in_sf: SLOTNUM_PER_SUBFRAME uses the time duration of a slot (=interval_us_local) to calculate the numbers of slots in a subframe, which can be done with a simple shift instead - The prach duration should be queried from the PRACH configuration table. The function to query the occasion info is part of the MAC layer code while this information can be used outside of this layer. Use header `nr_prach_config.h` to not duplicate functionality. Co-authored-by: Romain Beurdouche <romain.beurdouche@eurecom.fr>
This commit is contained in:
co-authored by
Romain Beurdouche
parent
42b5df351d
commit
cc076eb547
+29
-30
@@ -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.
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user