diff --git a/doc/ORAN_FHI7.2_Tutorial.md b/doc/ORAN_FHI7.2_Tutorial.md index e766aacbe8..2633396e0b 100644 --- a/doc/ORAN_FHI7.2_Tutorial.md +++ b/doc/ORAN_FHI7.2_Tutorial.md @@ -501,19 +501,6 @@ cmake .. -GNinja -DOAI_FHI72=ON -Dxran_DOWNLOAD=ON ninja nr-softmodem oran_fhlib_5g params_libconfig ``` -Note that in tags 2025.w06 and prior, the FHI72 driver used polling to wait for -the next slot. This is inefficient as it burns CPU time, and has been replaced -with a more efficient mechanism. Nevertheless, if you experience problems that -did not occur previously, it is possible to re-enable polling, either with -`build_oai` like this - - ./build_oai --gNB --ninja -t oran_fhlib_5g --cmake-opt -Dxran_LOCATION=$HOME/phy/fhi_lib/lib --cmake-opt -DOAI_FHI72_USE_POLLING=ON - -or with `cmake` like so - - cmake .. -GNinja -DOAI_FHI72=ON -Dxran_LOCATION=$HOME/phy/fhi_lib/lib -DOAI_FHI72_USE_POLLING=ON - ninja oran_fhlib_5g - ## Configuration RU and DU configurations have a circular dependency: you have to configure DU MAC address in the RU configuration and the RU MAC address, VLAN and Timing advance parameters in the DU configuration. diff --git a/radio/fhi_72/CMakeLists.txt b/radio/fhi_72/CMakeLists.txt index 9f09ba8168..549fe0b2ed 100644 --- a/radio/fhi_72/CMakeLists.txt +++ b/radio/fhi_72/CMakeLists.txt @@ -85,8 +85,6 @@ if (CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") target_link_libraries(oran_fhlib_5g PRIVATE armral) endif() -add_boolean_option(OAI_FHI72_USE_POLLING OFF "Enable polling in FHI72 driver" ON) - message(STATUS "Building FHI72 CUS library") set_target_properties(oran_fhlib_5g PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/radio/fhi_72/README.md b/radio/fhi_72/README.md index e161ceaf40..a631e72641 100644 --- a/radio/fhi_72/README.md +++ b/radio/fhi_72/README.md @@ -43,8 +43,8 @@ optionally compresses IQ data, then writes it into IQ buffers of xran. For PUSCH/PRACH, `oran_fh_if4p5_south_in()` calls `xran_fh_rx_read_slot()`/ `xran_fh_rx_prach_read_slot()` that blocks and waits for the next slot. -This is done through either a message queue, or through polling, which in both -cases depends on xran calling the callbacks `oai_xran_fh_rx_callback()`/ -`oai_xran_fh_rx_prach_callback()` as installed during xran initialization. +This is done through a message queue which depends on xran calling the callbacks +`oai_xran_fh_rx_callback()`/`oai_xran_fh_rx_prach_callback()` as installed during +xran initialization. Once unblocked, it reads first PUSCH data, then PRACH data, before returning to OAI. diff --git a/radio/fhi_72/oaioran.c b/radio/fhi_72/oaioran.c index d005a8a518..6aaaa0d8fb 100644 --- a/radio/fhi_72/oaioran.c +++ b/radio/fhi_72/oaioran.c @@ -29,10 +29,6 @@ #define N_SC_PER_PRB 12 -#if OAI_FHI72_USE_POLLING -#define USE_POLLING -#endif - // Declare variable useful for the send buffer function volatile bool first_call_set = false; @@ -43,7 +39,6 @@ int xran_is_prach_slot(uint8_t PortId, uint32_t subframe_id, uint32_t slot_id ); #include "common/utils/LOG/log.h" -#ifndef USE_POLLING extern notifiedFIFO_t oran_sync_fifo; #define MAX_QUEUE_LENGTH_NO_JUMP 3 atomic_int xran_queue_length = 0; @@ -51,13 +46,6 @@ atomic_int xran_queue_prach_length = 0; #if defined K_RELEASE extern notifiedFIFO_t oran_sync_fifo_prach; #endif -#else -volatile oran_sync_info_t oran_sync_info = {0}; -#if defined K_RELEASE -volatile oran_sync_info_t oran_sync_info_prach = {0}; -volatile bool prach_rx_awaiting = false; -#endif -#endif /* Prints TX_TOTAL, RX_TOTAL, RX_ON_TIME, RX_ERR_DROP counters every 128 frames. */ void print_fhi_counters(ru_info_t *ru, const int frame, const int slot) @@ -116,8 +104,7 @@ void print_fhi_counters(ru_info_t *ru, const int frame, const int slot) /** @details xran-specific callback, called when all packets for given CC and * 1/4, 1/2, 3/4, all symbols of a slot arrived. Currently, only used to get * timing information and unblock another thread in xran_fh_rx_read_slot() - * through either a message queue, or writing in global memory with polling, on - * a full slot boundary. */ + * through a message queue on a full slot boundary. */ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status #if defined K_RELEASE , uint8_t mu @@ -191,7 +178,6 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status rx_RU[i][slot2] = 0; if (last_slot == -1 || slot2 != last_slot) { -#ifndef USE_POLLING notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(oran_sync_info_t), 0, &oran_sync_fifo, NULL); oran_sync_info_t *info = NotifiedFifoData(req); info->tti = tti; @@ -218,28 +204,6 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status 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); pushNotifiedFIFO(&oran_sync_fifo, req); -#else - LOG_D(HW, "Writing %d.%d.%d (slot %d, subframe %d,last_slot %d)\n", frame, slot2, ru_id, slot, subframe, last_slot); - oran_sync_info.tti = tti; - oran_sync_info.sl = slot2; - 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 LOG_E(HW, "Cannot Push %d.%d.%d (slot %d, subframe %d,last_slot %d)\n", frame, slot2, ru_id, slot, subframe, last_slot); last_slot = slot2; @@ -295,20 +259,12 @@ void oai_xran_fh_rx_prach_callback(void *pCallbackTag, xran_status_t status rx_RU[i][slot2] = 0; if (last_slot == -1 || slot2 != last_slot) { -#ifndef USE_POLLING notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(oran_sync_info_t), 0, &oran_sync_fifo_prach, NULL); oran_sync_info_t *info = NotifiedFifoData(req); info->tti = tti; info->sl = slot2; info->f = frame; info->mu = mu; -#else - LOG_D(HW, "Writing PRACH slot %d.%d.%d (slot %d, subframe %d,last_slot %d)\n", frame, slot2, ru_id, slot, subframe, last_slot); - oran_sync_info_prach.tti = tti; - oran_sync_info_prach.sl = slot2; - oran_sync_info_prach.f = frame; - oran_sync_info_prach.mu = mu; -#endif struct xran_cb_tag *callback_tag = (struct xran_cb_tag *)pCallbackTag; uint32_t tti = callback_tag->slotiId; uint32_t ru_id = callback_tag->oXuId; @@ -321,23 +277,15 @@ void oai_xran_fh_rx_prach_callback(void *pCallbackTag, xran_status_t status AssertFatal(pRbMap != NULL, "(%d:%d:%d)pRbMapPrach == 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++) { AssertFatal(pRbMap->sFrontHaulRxPacketCtrl[sym_id].nRxPkt <= 1, "PRACH segmentation is not supported\n"); -#ifndef USE_POLLING info->nRxPkt[cc_id][ant_id][sym_id] = pRbMap->sFrontHaulRxPacketCtrl[sym_id].nRxPkt; -#else - oran_sync_info_prach.nRxPkt[cc_id][ant_id][sym_id] = pRbMap->sFrontHaulRxPacketCtrl[sym_id].nRxPkt; -#endif pRbMap->sFrontHaulRxPacketCtrl[sym_id].nRxPkt = 0; } } } } -#ifndef USE_POLLING LOG_D(HW, "Push PRACH slot %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_prach_length, 1); pushNotifiedFIFO(&oran_sync_fifo_prach, req); -#else - prach_rx_awaiting = true; -#endif } else LOG_E(HW, "Cannot Push PRACH slot %d.%d.%d (slot %d, subframe %d,last_slot %d)\n", frame, slot2, ru_id, slot, subframe, last_slot); last_slot = slot2; @@ -372,7 +320,6 @@ int oai_physide_dl_tti_call_back(void *param int xran_fh_rx_prach_read_slot(PHY_VARS_gNB *gNB, ru_info_t *ru, int *frame, int *slot) { #if defined K_RELEASE -#ifndef USE_POLLING // pull next even from oran_sync_fifo_prach if any notifiedFIFO_elt_t *res = pullNotifiedFIFO(&oran_sync_fifo_prach); atomic_fetch_sub(&xran_queue_prach_length, 1); @@ -399,29 +346,6 @@ int xran_fh_rx_prach_read_slot(PHY_VARS_gNB *gNB, ru_info_t *ru, int *frame, int *frame = info->f; uint8_t mu = info->mu; delNotifiedFIFO_elt(res); -#else -#error "POLLING is not supported for K release unless you know how to fix the race condition on prach_rx_awaiting" - if (!prach_rx_awaiting) { - return (0); - } else { - prach_rx_awaiting = false; - } - *slot = oran_sync_info_prach.sl; - *frame = oran_sync_info_prach.f; - uint8_t mu = oran_sync_info_prach.mu; - uint32_t tti_in = oran_sync_info_prach.tti; - - static int last_slot = -1; - LOG_D(HW, "oran slot %d, last_slot %d\n", *slot, last_slot); - int cnt = 0; - // while (*slot == last_slot) { - while (tti_in == oran_sync_info_prach.tti) { - //*slot = oran_sync_info.sl; - cnt++; - } - LOG_D(HW, "cnt %d, Reading %d.%d\n", cnt, *frame, *slot); - last_slot = *slot; -#endif #endif prach_item_t p; @@ -494,11 +418,7 @@ int xran_fh_rx_prach_read_slot(PHY_VARS_gNB *gNB, ru_info_t *ru, int *frame, int #if defined K_RELEASE struct xran_prb_map * pPrbMap = (struct xran_prb_map *)bufs->prachdstdecomp[aa % nb_rx_per_ru][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData; struct xran_rx_packet_ctl *p_rx_packet_ctl = &pPrbMap->sFrontHaulRxPacketCtrl[sym_idx]; -#ifndef USE_POLLING int32_t nRxPkt = info->nRxPkt[cc_id][aa][sym_idx]; -#else - int32_t nRxPkt = oran_sync_info.nRxPkt[cc_id][aa][sym_idx]; -#endif if (nRxPkt == 0) { LOG_D(HW, "read_prach %d.%d.%d saa = %d: nRxPkt = 0!\n", *frame, *slot, sym_idx, aa); memset(&dst[sym_idx], 0, N_ZC * 2 * sizeof(*dst)); @@ -640,7 +560,6 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot) int idx = 0; static int outcnt = 0; -#ifndef USE_POLLING // pull next event from oran_sync_fifo notifiedFIFO_elt_t *res = pullNotifiedFIFO(&oran_sync_fifo); atomic_fetch_sub(&xran_queue_length, 1); @@ -669,25 +588,6 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot) uint8_t mu = info->mu; #endif delNotifiedFIFO_elt(res); -#else - *slot = oran_sync_info.sl; - *frame = oran_sync_info.f; -#if defined K_RELEASE - uint8_t mu = oran_sync_info.mu; -#endif - uint32_t tti_in = oran_sync_info.tti; - - static int last_slot = -1; - LOG_D(HW, "oran slot %d, last_slot %d\n", *slot, last_slot); - int cnt = 0; - // while (*slot == last_slot) { - while (tti_in == oran_sync_info.tti) { - //*slot = oran_sync_info.sl; - cnt++; - } - LOG_D(HW, "cnt %d, Reading %d.%d\n", cnt, *frame, *slot); - last_slot = *slot; -#endif // return(0); struct xran_fh_config *fh_cfg = get_xran_fh_config(0); @@ -743,11 +643,7 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot) 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 + int32_t nRxPkt = info->nRxPkt[cc_id][ant_id][sym_idx]; LOG_D(HW, "nRxPkt %d\n", nRxPkt); for (int pkt_idx = 0; pkt_idx < nRxPkt; pkt_idx++) { uint8_t *pData;