Merge remote-tracking branch 'origin/fhi72-fdd-mode' into integration_2025_w04 (!3210)
FHI72: FDD support - harmonize DL/UL PRB mapping in one get_xran_prb_map() function with support of mixed slot and duplex mode - do not assume TDD by default
This commit is contained in:
+20
-7
@@ -263,6 +263,22 @@ int read_prach_data(ru_info_t *ru, int frame, int slot)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_tdd_ul_symbol(const struct xran_frame_config *frame_conf, int slot, int sym_idx)
|
||||||
|
{
|
||||||
|
/* in FDD, every symbol is also UL */
|
||||||
|
if (frame_conf->nFrameDuplexType == XRAN_FDD)
|
||||||
|
return true;
|
||||||
|
int tdd_period = frame_conf->nTddPeriod;
|
||||||
|
int slot_in_period = slot % tdd_period;
|
||||||
|
/* check if symbol is UL */
|
||||||
|
return frame_conf->sSlotConfig[slot_in_period].nSymbolType[sym_idx] == 1 /* UL */;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_tdd_dl_guard_slot(const struct xran_frame_config *frame_conf, int slot)
|
||||||
|
{
|
||||||
|
return !is_tdd_ul_symbol(frame_conf, slot, XRAN_NUM_OF_SYMBOL_PER_SLOT - 1);
|
||||||
|
}
|
||||||
|
|
||||||
int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
|
int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
|
||||||
{
|
{
|
||||||
void *ptr = NULL;
|
void *ptr = NULL;
|
||||||
@@ -328,18 +344,15 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
|
|||||||
rx_data = (uint8_t *)ru->rxdataF[ant_id];
|
rx_data = (uint8_t *)ru->rxdataF[ant_id];
|
||||||
start_ptr = rx_data + (slot_size * slot_offset_rxdata);
|
start_ptr = rx_data + (slot_size * slot_offset_rxdata);
|
||||||
xran_ctx = xran_dev_get_ctx_by_id(ant_id / nb_rx_per_ru);
|
xran_ctx = xran_dev_get_ctx_by_id(ant_id / nb_rx_per_ru);
|
||||||
const struct xran_fh_config *fh_config = &xran_ctx->fh_cfg;
|
const struct xran_frame_config *frame_conf = &xran_ctx->fh_cfg.frame_conf;
|
||||||
int tdd_period = fh_config->frame_conf.nTddPeriod;
|
// skip processing this slot is TX (no RX in this slot)
|
||||||
int slot_in_period = *slot % tdd_period;
|
if (is_tdd_dl_guard_slot(frame_conf, *slot))
|
||||||
if (fh_config->frame_conf.sSlotConfig[slot_in_period].nSymbolType[XRAN_NUM_OF_SYMBOL_PER_SLOT - 1] == 0)
|
|
||||||
continue;
|
continue;
|
||||||
// skip processing this slot if the last symbol in the slot is TX
|
|
||||||
// (no RX in this slot)
|
|
||||||
// This loop would better be more inner to avoid confusion and maybe also errors.
|
// This loop would better be more inner to avoid confusion and maybe also errors.
|
||||||
for (int32_t sym_idx = 0; sym_idx < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_idx++) {
|
for (int32_t sym_idx = 0; sym_idx < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_idx++) {
|
||||||
/* the callback is for mixed and UL slots. In mixed, we have to
|
/* the callback is for mixed and UL slots. In mixed, we have to
|
||||||
* skip DL and guard symbols. */
|
* skip DL and guard symbols. */
|
||||||
if (fh_config->frame_conf.sSlotConfig[slot_in_period].nSymbolType[sym_idx] != 1 /* UL */)
|
if (!is_tdd_ul_symbol(frame_conf, *slot, sym_idx))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
uint8_t *pData;
|
uint8_t *pData;
|
||||||
|
|||||||
@@ -770,7 +770,6 @@ static bool set_fh_config(int ru_idx, int num_rus, enum xran_category xran_cat,
|
|||||||
for (int i = 1; i < oai0->rx_num_channels; ++i)
|
for (int i = 1; i < oai0->rx_num_channels; ++i)
|
||||||
DevAssert(oai0->rx_freq[0] == oai0->rx_freq[i]);
|
DevAssert(oai0->rx_freq[0] == oai0->rx_freq[i]);
|
||||||
DevAssert(oai0->nr_band > 0);
|
DevAssert(oai0->nr_band > 0);
|
||||||
DevAssert(oai0->nr_scs_for_raster > 0);
|
|
||||||
AssertFatal(oai0->threequarter_fs == 0, "cannot use three-quarter sampling with O-RAN 7.2 split\n");
|
AssertFatal(oai0->threequarter_fs == 0, "cannot use three-quarter sampling with O-RAN 7.2 split\n");
|
||||||
|
|
||||||
paramdef_t FHconfigs[] = ORAN_FH_DESC;
|
paramdef_t FHconfigs[] = ORAN_FH_DESC;
|
||||||
|
|||||||
+32
-49
@@ -79,10 +79,10 @@ static uint32_t get_nFpgaToSW_FTH_RxBufferLen(int mu)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct xran_prb_map get_xran_prb_map_dl(const struct xran_fh_config *f)
|
static struct xran_prb_map get_xran_prb_map(const struct xran_fh_config *f, const uint8_t dir, const int16_t start_sym, const int16_t num_sym)
|
||||||
{
|
{
|
||||||
struct xran_prb_map prbmap = {
|
struct xran_prb_map prbmap = {
|
||||||
.dir = XRAN_DIR_DL,
|
.dir = dir,
|
||||||
.xran_port = 0,
|
.xran_port = 0,
|
||||||
.band_id = 0,
|
.band_id = 0,
|
||||||
.cc_id = 0,
|
.cc_id = 0,
|
||||||
@@ -91,33 +91,10 @@ static struct xran_prb_map get_xran_prb_map_dl(const struct xran_fh_config *f)
|
|||||||
.nPrbElm = 1,
|
.nPrbElm = 1,
|
||||||
};
|
};
|
||||||
struct xran_prb_elm *e = &prbmap.prbMap[0];
|
struct xran_prb_elm *e = &prbmap.prbMap[0];
|
||||||
e->nStartSymb = 0;
|
e->nStartSymb = start_sym;
|
||||||
e->numSymb = 14;
|
e->numSymb = num_sym;
|
||||||
e->nRBStart = 0;
|
e->nRBStart = 0;
|
||||||
e->nRBSize = f->nDLRBs;
|
e->nRBSize = (dir == XRAN_DIR_DL) ? f->nDLRBs : f->nULRBs;
|
||||||
e->nBeamIndex = 0;
|
|
||||||
e->compMethod = f->ru_conf.compMeth;
|
|
||||||
e->iqWidth = f->ru_conf.iqWidth;
|
|
||||||
return prbmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct xran_prb_map get_xran_prb_map_ul(const struct xran_fh_config *f)
|
|
||||||
{
|
|
||||||
struct xran_prb_map prbmap = {
|
|
||||||
.dir = XRAN_DIR_UL,
|
|
||||||
.xran_port = 0,
|
|
||||||
.band_id = 0,
|
|
||||||
.cc_id = 0,
|
|
||||||
.ru_port_id = 0,
|
|
||||||
.tti_id = 0,
|
|
||||||
.start_sym_id = 0,
|
|
||||||
.nPrbElm = 1,
|
|
||||||
};
|
|
||||||
struct xran_prb_elm *e = &prbmap.prbMap[0];
|
|
||||||
e->nStartSymb = 0;
|
|
||||||
e->numSymb = 14;
|
|
||||||
e->nRBStart = 0;
|
|
||||||
e->nRBSize = f->nULRBs;
|
|
||||||
e->nBeamIndex = 0;
|
e->nBeamIndex = 0;
|
||||||
e->compMethod = f->ru_conf.compMeth;
|
e->compMethod = f->ru_conf.compMeth;
|
||||||
e->iqWidth = f->ru_conf.iqWidth;
|
e->iqWidth = f->ru_conf.iqWidth;
|
||||||
@@ -263,7 +240,8 @@ static void oran_allocate_cplane_buffers(void *instHandle,
|
|||||||
fb->pCtrl = mb;
|
fb->pCtrl = mb;
|
||||||
|
|
||||||
struct xran_prb_map *src = &prb_conf->slotMap;
|
struct xran_prb_map *src = &prb_conf->slotMap;
|
||||||
if ((j % prb_conf->nTddPeriod) == prb_conf->mixed_slot_index)
|
// get mixed slot map if in TDD and in mixed slot
|
||||||
|
if (prb_conf->nTddPeriod != 0 && (j % prb_conf->nTddPeriod) == prb_conf->mixed_slot_index)
|
||||||
src = &prb_conf->mixedSlotMap;
|
src = &prb_conf->mixedSlotMap;
|
||||||
#ifdef E_RELEASE
|
#ifdef E_RELEASE
|
||||||
/* as per E release sample app, the memory is copied up to size_of_prb_map
|
/* as per E release sample app, the memory is copied up to size_of_prb_map
|
||||||
@@ -338,28 +316,43 @@ static void oran_allocate_buffers(void *handle,
|
|||||||
printf("-> hInstance %p\n", pi->instanceHandle);
|
printf("-> hInstance %p\n", pi->instanceHandle);
|
||||||
AssertFatal(status == XRAN_STATUS_SUCCESS, "get sector instance failed for XRAN nInstanceNum %d\n", xran_inst);
|
AssertFatal(status == XRAN_STATUS_SUCCESS, "get sector instance failed for XRAN nInstanceNum %d\n", xran_inst);
|
||||||
|
|
||||||
const uint32_t txBufSize = get_nSW_ToFpga_FTH_TxBufferLen(fh_config->frame_conf.nNumerology, fh_config->max_sections_per_slot);
|
// DL/UL PRB mapping depending on the duplex mode
|
||||||
oran_allocate_uplane_buffers(pi->instanceHandle, bl->src, bl->bufs.tx, xran_max_antenna_nr, txBufSize);
|
struct xran_prb_map dlPm = get_xran_prb_map(fh_config, XRAN_DIR_DL, 0, 14);
|
||||||
|
struct xran_prb_map ulPm = get_xran_prb_map(fh_config, XRAN_DIR_UL, 0, 14);
|
||||||
|
struct xran_prb_map dlPmMixed = {0};
|
||||||
|
struct xran_prb_map ulPmMixed = {0};
|
||||||
|
uint32_t idx = 0;
|
||||||
|
if (fh_config->frame_conf.nFrameDuplexType == XRAN_TDD) {
|
||||||
|
oran_mixed_slot_t info = get_mixed_slot_info(&fh_config->frame_conf);
|
||||||
|
dlPmMixed = get_xran_prb_map(fh_config, XRAN_DIR_DL, 0, info.num_dlsym);
|
||||||
|
ulPmMixed = get_xran_prb_map(fh_config, XRAN_DIR_UL, info.start_ulsym, info.num_ulsym);
|
||||||
|
idx = info.idx;
|
||||||
|
}
|
||||||
|
|
||||||
oran_mixed_slot_t info = get_mixed_slot_info(&fh_config->frame_conf);
|
|
||||||
struct xran_prb_map dlPm = get_xran_prb_map_dl(fh_config);
|
|
||||||
struct xran_prb_map dlPmMixed = dlPm;
|
|
||||||
dlPmMixed.prbMap[0].nStartSymb = 0;
|
|
||||||
dlPmMixed.prbMap[0].numSymb = info.num_dlsym;
|
|
||||||
oran_cplane_prb_config dlConf = {
|
oran_cplane_prb_config dlConf = {
|
||||||
.nTddPeriod = fh_config->frame_conf.nTddPeriod,
|
.nTddPeriod = fh_config->frame_conf.nTddPeriod,
|
||||||
.mixed_slot_index = info.idx,
|
.mixed_slot_index = idx,
|
||||||
.slotMap = dlPm,
|
.slotMap = dlPm,
|
||||||
.mixedSlotMap = dlPmMixed,
|
.mixedSlotMap = dlPmMixed,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
oran_cplane_prb_config ulConf = {
|
||||||
|
.nTddPeriod = fh_config->frame_conf.nTddPeriod,
|
||||||
|
.mixed_slot_index = idx,
|
||||||
|
.slotMap = ulPm,
|
||||||
|
.mixedSlotMap = ulPmMixed,
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef E_RELEASE
|
#ifdef E_RELEASE
|
||||||
uint32_t size_of_prb_map = sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm) * (xran_max_sections_per_slot - 1);
|
uint32_t size_of_prb_map = sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm) * (xran_max_sections_per_slot - 1);
|
||||||
#elif defined F_RELEASE
|
#elif defined F_RELEASE
|
||||||
uint32_t numPrbElm = xran_get_num_prb_elm(&dlPmMixed, mtu);
|
uint32_t numPrbElm = xran_get_num_prb_elm(&dlPm, mtu);
|
||||||
uint32_t size_of_prb_map = sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm) * (numPrbElm);
|
uint32_t size_of_prb_map = sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm) * (numPrbElm);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// PDSCH
|
||||||
|
const uint32_t txBufSize = get_nSW_ToFpga_FTH_TxBufferLen(fh_config->frame_conf.nNumerology, fh_config->max_sections_per_slot);
|
||||||
|
oran_allocate_uplane_buffers(pi->instanceHandle, bl->src, bl->bufs.tx, xran_max_antenna_nr, txBufSize);
|
||||||
oran_allocate_cplane_buffers(pi->instanceHandle,
|
oran_allocate_cplane_buffers(pi->instanceHandle,
|
||||||
bl->srccp,
|
bl->srccp,
|
||||||
bl->bufs.tx_prbmap,
|
bl->bufs.tx_prbmap,
|
||||||
@@ -372,19 +365,9 @@ static void oran_allocate_buffers(void *handle,
|
|||||||
size_of_prb_map,
|
size_of_prb_map,
|
||||||
&dlConf);
|
&dlConf);
|
||||||
|
|
||||||
|
// PUSCH
|
||||||
const uint32_t rxBufSize = get_nFpgaToSW_FTH_RxBufferLen(fh_config->frame_conf.nNumerology);
|
const uint32_t rxBufSize = get_nFpgaToSW_FTH_RxBufferLen(fh_config->frame_conf.nNumerology);
|
||||||
oran_allocate_uplane_buffers(pi->instanceHandle, bl->dst, bl->bufs.rx, xran_max_antenna_nr, rxBufSize);
|
oran_allocate_uplane_buffers(pi->instanceHandle, bl->dst, bl->bufs.rx, xran_max_antenna_nr, rxBufSize);
|
||||||
|
|
||||||
struct xran_prb_map ulPm = get_xran_prb_map_ul(fh_config);
|
|
||||||
struct xran_prb_map ulPmMixed = ulPm;
|
|
||||||
ulPmMixed.prbMap[0].nStartSymb = info.start_ulsym;
|
|
||||||
ulPmMixed.prbMap[0].numSymb = info.num_ulsym;
|
|
||||||
oran_cplane_prb_config ulConf = {
|
|
||||||
.nTddPeriod = fh_config->frame_conf.nTddPeriod,
|
|
||||||
.mixed_slot_index = info.idx,
|
|
||||||
.slotMap = ulPm,
|
|
||||||
.mixedSlotMap = ulPmMixed,
|
|
||||||
};
|
|
||||||
oran_allocate_cplane_buffers(pi->instanceHandle,
|
oran_allocate_cplane_buffers(pi->instanceHandle,
|
||||||
bl->dstcp,
|
bl->dstcp,
|
||||||
bl->bufs.rx_prbmap,
|
bl->bufs.rx_prbmap,
|
||||||
|
|||||||
Reference in New Issue
Block a user