From 6b665a851e32af8ca35ac88ff194f230bbf1a351 Mon Sep 17 00:00:00 2001 From: Romain Beurdouche Date: Tue, 14 Apr 2026 15:17:34 +0200 Subject: [PATCH] Process PUSCH packets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit xran K release introduces a new parameter nRxPkt describing the fragmentation of Rx symbols. Co-authored-by: Teodora Vladić Signed-off-by: Teodora Vladić --- radio/fhi_72/oaioran.c | 74 ++++++++++++++++++++++++++++++---------- radio/fhi_72/oaioran.h | 6 ++-- radio/fhi_72/oran-init.c | 3 ++ 3 files changed, 63 insertions(+), 20 deletions(-) diff --git a/radio/fhi_72/oaioran.c b/radio/fhi_72/oaioran.c index b075397c1e..4284912c3d 100644 --- a/radio/fhi_72/oaioran.c +++ b/radio/fhi_72/oaioran.c @@ -44,6 +44,7 @@ int xran_is_prach_slot(uint8_t PortId, uint32_t subframe_id, uint32_t slot_id #ifndef USE_POLLING extern notifiedFIFO_t oran_sync_fifo; +#define MAX_QUEUE_LENGTH_NO_JUMP 3 atomic_int xran_queue_length = 0; #else volatile oran_sync_info_t oran_sync_info = {0}; @@ -135,6 +136,21 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status info->f = frame; #if defined K_RELEASE info->mu = mu; + + for (int ru_idx = 0; ru_idx < num_ports; ru_idx++) { + oran_buf_list_t *bufs = get_xran_buffers(ru_idx); + struct xran_fh_config *fh_config = get_xran_fh_config(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++) { + struct xran_prb_map *pRbMap = (struct xran_prb_map *)bufs->dstcp[ant_id][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData; + AssertFatal(pRbMap != NULL, "(%d:%d:%d)pRbMap == NULL. Aborting.\n", cc_id, tti % XRAN_N_FE_BUF_LEN, ant_id); + for (uint32_t sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) { + info->nRxPkt[cc_id][ant_id][sym_id] = pRbMap->sFrontHaulRxPacketCtrl[sym_id].nRxPkt; + pRbMap->sFrontHaulRxPacketCtrl[sym_id].nRxPkt = 0; + } + } + } + } #endif LOG_D(HW, "Push %d.%d.%d (slot %d, subframe %d,last_slot %d)\n", frame, info->sl, slot, ru_id, subframe, last_slot); atomic_fetch_add(&xran_queue_length, 1); @@ -146,6 +162,19 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status oran_sync_info.f = frame; #if defined K_RELEASE oran_sync_info.mu = mu; + + oran_buf_list_t *bufs = get_xran_buffers(ru_id); + struct xran_fh_config *fh_config = get_xran_fh_config(ru_id); + 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++) { + struct xran_prb_map *pRbMap = (struct xran_prb_map *)bufs->dstcp[ant_id][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData; + AssertFatal(pRbMap != NULL, "(%d:%d:%d)pRbMap == NULL. Aborting.\n", cc_id, tti % XRAN_N_FE_BUF_LEN, ant_id); + for (uint32_t sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) { + oran_sync_info.nRxPkt[cc_id][ant_id][sym_id] = pRbMap->sFrontHaulRxPacketCtrl[sym_id].nRxPkt; + pRbMap->sFrontHaulRxPacketCtrl[sym_id].nRxPkt = 0; + } + } + } #endif #endif } else @@ -178,7 +207,7 @@ static int read_prach_data(ru_info_t *ru, int frame, int slot #if defined K_RELEASE , uint8_t mu #endif - ) + ) { /* calculate tti and subframe_id from frame, slot num */ int sym_idx = 0; @@ -341,7 +370,6 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot) atomic_fetch_sub(&xran_queue_length, 1); oran_sync_info_t *info = NotifiedFifoData(res); -#define MAX_QUEUE_LENGTH_NO_JUMP 3 if (xran_queue_length > 0 && xran_queue_length < MAX_QUEUE_LENGTH_NO_JUMP) { LOG_D(HW, "%4d.%2d TTI processing delay detected\n", info->f, info->sl); } else if (xran_queue_length >= MAX_QUEUE_LENGTH_NO_JUMP) { @@ -440,28 +468,38 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot) int start_totalRB = pRbMap->prbMap[0].nRBStart; int32_t local_dst[num_totalRB * N_SC_PER_PRB] __attribute__((aligned(64))); +#if defined K_RELEASE + struct xran_prb_elm *pRbElm = &pRbMap->prbMap[0]; + struct xran_rx_packet_ctl *p_rx_packet_ctl = &pRbMap->sFrontHaulRxPacketCtrl[sym_idx]; + uint32_t one_rb_size = + (((pRbElm->iqWidth == 0) || (pRbElm->iqWidth == 16)) ? (N_SC_PER_PRB * 2 * 2) : (3 * pRbElm->iqWidth + 1)); +#ifndef USE_POLLING + int32_t nRxPkt = info->nRxPkt[cc_id][ant_id][sym_idx]; +#else + int32_t nRxPkt = oran_sync_info.nRxPkt[cc_id][ant_id][sym_idx]; +#endif + LOG_D(HW, "nRxPkt %d\n", nRxPkt); + for (int pkt_idx = 0; pkt_idx < nRxPkt; pkt_idx++) { + uint8_t *pData; + if (fh_init->mtu < p_rx_packet_ctl->nRBSize[pkt_idx] * one_rb_size) + pData = bufs->dst[ant_id % nb_rx_per_ru][tti % XRAN_N_FE_BUF_LEN] + .pBuffers[sym_idx % XRAN_NUM_OF_SYMBOL_PER_SLOT] + .pData; + else + pData = p_rx_packet_ctl->pData[pkt_idx]; + int numRB = p_rx_packet_ctl->nRBSize[pkt_idx]; + int startRB = p_rx_packet_ctl->nRBStart[pkt_idx]; + // num_prbu & start_prbu are for UL U-plane only + LOG_D(HW, "p_rx_packet_ctl[%d] startRB[%d]:numRB[%d]\n", pkt_idx, startRB, numRB); + { + { +#elif defined F_RELEASE LOG_D(HW, "[%d.%d] pRbMap->nPrbElm %d\n", *frame, *slot, pRbMap->nPrbElm); for (uint32_t idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++) { int numRB, startRB; uint8_t *pData; struct xran_section_desc *p_sec_desc = NULL; struct xran_prb_elm *pRbElm = &pRbMap->prbMap[idxElm]; -#if defined K_RELEASE - uint32_t one_rb_size = - (((pRbElm->iqWidth == 0) || (pRbElm->iqWidth == 16)) ? (N_SC_PER_PRB * 2 * 2) : (3 * pRbElm->iqWidth + 1)); - if (fh_init->mtu < num_totalRB * one_rb_size) - pData = bufs->dst[ant_id % nb_rx_per_ru][tti % XRAN_N_FE_BUF_LEN] - .pBuffers[sym_idx % XRAN_NUM_OF_SYMBOL_PER_SLOT] - .pData; - else { - p_sec_desc = &pRbElm->sec_desc[sym_idx]; - pData = p_sec_desc->pData; - } - numRB = num_totalRB; - startRB = start_totalRB; - { - { -#elif defined F_RELEASE // UP_nRBSize & UP_nRBStart are for DL U-plane only LOG_D(HW, "[%d.%d] idxElm[%d] startSym[%d]:numSym[%d] UP_startRB[%d]:UP_numRB[%d] sym_idx[%d] ant_id[%d] pRbElm->nRBStart[%d]:pRbElm->nRBSize[%d]\n", *frame, *slot, idxElm, pRbElm->nStartSymb, pRbElm->numSymb, pRbElm->UP_nRBStart, pRbElm->UP_nRBSize, sym_idx, ant_id, pRbElm->nRBStart, pRbElm->nRBSize); for (int idxDesc = 0; idxDesc < XRAN_MAX_FRAGMENT; idxDesc++) { diff --git a/radio/fhi_72/oaioran.h b/radio/fhi_72/oaioran.h index cf9dfb70cb..0a70e74eee 100644 --- a/radio/fhi_72/oaioran.h +++ b/radio/fhi_72/oaioran.h @@ -14,15 +14,17 @@ typedef struct { uint32_t f; #if defined K_RELEASE uint8_t mu; + // the first column can expand to XRAN_MAX_SECTOR_NR for the support of multiple CCs + int32_t nRxPkt[1][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT]; #endif } oran_sync_info_t; /** @brief xran callback for fronthaul RX, see xran_5g_fronthault_config(). */ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status #if defined K_RELEASE - , uint8_t mu + , uint8_t mu #endif - ); + ); /** @brief xran callback for time alignment, see xran_reg_physide_cb(). */ int oai_physide_dl_tti_call_back(void *param #if defined K_RELEASE diff --git a/radio/fhi_72/oran-init.c b/radio/fhi_72/oran-init.c index 315347e7d1..0880cac1b3 100644 --- a/radio/fhi_72/oran-init.c +++ b/radio/fhi_72/oran-init.c @@ -94,6 +94,9 @@ static struct xran_prb_map get_xran_prb_map(const struct xran_fh_config *f, cons e->nBeamIndex = 0; e->compMethod = f->ru_conf.compMeth; e->iqWidth = f->ru_conf.iqWidth; +#if defined K_RELEASE + memset(&prbmap.sFrontHaulRxPacketCtrl, 0, XRAN_NUM_OF_SYMBOL_PER_SLOT * sizeof(struct xran_rx_packet_ctl)); +#endif return prbmap; }