diff --git a/radio/fhi_72/oaioran.c b/radio/fhi_72/oaioran.c index 02487e9300..35c0356005 100644 --- a/radio/fhi_72/oaioran.c +++ b/radio/fhi_72/oaioran.c @@ -263,6 +263,22 @@ int read_prach_data(ru_info_t *ru, int frame, int slot) 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) { 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]; 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_fh_config *fh_config = &xran_ctx->fh_cfg; - int tdd_period = fh_config->frame_conf.nTddPeriod; - int slot_in_period = *slot % tdd_period; - if (fh_config->frame_conf.sSlotConfig[slot_in_period].nSymbolType[XRAN_NUM_OF_SYMBOL_PER_SLOT - 1] == 0) + const struct xran_frame_config *frame_conf = &xran_ctx->fh_cfg.frame_conf; + // skip processing this slot is TX (no RX in this slot) + if (is_tdd_dl_guard_slot(frame_conf, *slot)) 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. 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 * 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; uint8_t *pData; diff --git a/radio/fhi_72/oran-config.c b/radio/fhi_72/oran-config.c index 34da6f5890..2f2032c30a 100644 --- a/radio/fhi_72/oran-config.c +++ b/radio/fhi_72/oran-config.c @@ -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) DevAssert(oai0->rx_freq[0] == oai0->rx_freq[i]); 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"); paramdef_t FHconfigs[] = ORAN_FH_DESC; diff --git a/radio/fhi_72/oran-init.c b/radio/fhi_72/oran-init.c index 8072c5852e..a5c620e995 100644 --- a/radio/fhi_72/oran-init.c +++ b/radio/fhi_72/oran-init.c @@ -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 = { - .dir = XRAN_DIR_DL, + .dir = dir, .xran_port = 0, .band_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, }; struct xran_prb_elm *e = &prbmap.prbMap[0]; - e->nStartSymb = 0; - e->numSymb = 14; + e->nStartSymb = start_sym; + e->numSymb = num_sym; e->nRBStart = 0; - e->nRBSize = f->nDLRBs; - 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->nRBSize = (dir == XRAN_DIR_DL) ? f->nDLRBs : f->nULRBs; e->nBeamIndex = 0; e->compMethod = f->ru_conf.compMeth; e->iqWidth = f->ru_conf.iqWidth; @@ -263,7 +240,8 @@ static void oran_allocate_cplane_buffers(void *instHandle, fb->pCtrl = mb; 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; #ifdef E_RELEASE /* 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); 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); - oran_allocate_uplane_buffers(pi->instanceHandle, bl->src, bl->bufs.tx, xran_max_antenna_nr, txBufSize); + // DL/UL PRB mapping depending on the duplex mode + 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 = { .nTddPeriod = fh_config->frame_conf.nTddPeriod, - .mixed_slot_index = info.idx, + .mixed_slot_index = idx, .slotMap = dlPm, .mixedSlotMap = dlPmMixed, }; + oran_cplane_prb_config ulConf = { + .nTddPeriod = fh_config->frame_conf.nTddPeriod, + .mixed_slot_index = idx, + .slotMap = ulPm, + .mixedSlotMap = ulPmMixed, + }; + #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); #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); #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, bl->srccp, bl->bufs.tx_prbmap, @@ -372,19 +365,9 @@ static void oran_allocate_buffers(void *handle, size_of_prb_map, &dlConf); + // PUSCH 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); - - 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, bl->dstcp, bl->bufs.rx_prbmap,