diff --git a/radio/fhi_72/oaioran.c b/radio/fhi_72/oaioran.c index f340b08dd1..74c56ae36e 100644 --- a/radio/fhi_72/oaioran.c +++ b/radio/fhi_72/oaioran.c @@ -25,6 +25,7 @@ #include "oran-config.h" // for g_kbar #include "common/utils/threadPool/notified_fifo.h" +#include "common/utils/fsn.h" #define N_SC_PER_PRB 12 @@ -314,7 +315,7 @@ int oai_physide_dl_tti_call_back(void *param * Function is blocking and waits for next frame/slot combination. It is unblocked * by oai_xran_fh_rx_prach_callback(). If K_RELEASE, it writes the current slot into parameters * frame/slot. If F_RELEASE, it takes the frame/slot. */ -int xran_fh_rx_prach_read_slot(prach_list_t *prach_list, ru_info_t *ru, int *frame, int *slot) +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 @@ -340,8 +341,8 @@ int xran_fh_rx_prach_read_slot(prach_list_t *prach_list, ru_info_t *ru, int *fra DevAssert(xran_queue_prach_length == 0); } - int slot = info->sl; - int frame = info->f; + *slot = info->sl; + *frame = info->f; uint8_t mu = info->mu; delNotifiedFIFO_elt(res); #else @@ -351,8 +352,8 @@ int xran_fh_rx_prach_read_slot(prach_list_t *prach_list, ru_info_t *ru, int *fra } else { prach_rx_awaiting = false; } - int slot = oran_sync_info_prach.sl; - int frame = oran_sync_info_prach.f; + *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; @@ -368,6 +369,35 @@ int xran_fh_rx_prach_read_slot(prach_list_t *prach_list, ru_info_t *ru, int *fra last_slot = *slot; #endif #endif + + prach_item_t p; + fsn_t now = {.f = *frame, .s = *slot, .mu = gNB->frame_parms.numerology_index}; + if (get_next_nr_prach(&gNB->prach_ru_queue, &now, &p)) { + struct xran_fh_config *fh_cfg = get_xran_fh_config(0); +#if defined F_RELEASE + uint8_t mu = fh_cfg->frame_conf.nNumerology; +#elif defined K_RELEASE + uint8_t mu = fh_cfg->nNumerology[0]; +#endif + int slots_per_subframe = 1 << mu; + uint32_t subframe = *slot / slots_per_subframe; // `slot` = slot in which PRACH is received + // PRACH occasion in a frame if and only if SFN % x == y, TS 38.211 Table 6.3.3.2-2/3/4 + nr_prach_info_t prach_info = get_prach_info(0); + bool is_prach_frame = (*frame % prach_info.x == prach_info.y); + bool is_prach_slot = is_prach_frame && xran_is_prach_slot(0, subframe, (p.slot % slots_per_subframe) +#if defined K_RELEASE + , mu +#endif + ); // `p.slot` = slot in which PRACH is scheduled + if (is_prach_slot) { + ru->prach_buf = p.prach_buf; + } else { + LOG_W(HW, "[%d.%d] Expected PRACH reception of scheduled slot %d\n", *frame, *slot, p.slot); + } + } else { + return (0); + } + /* calculate tti and subframe_id from frame, slot num */ int sym_idx = 0; @@ -395,12 +425,10 @@ int xran_fh_rx_prach_read_slot(prach_list_t *prach_list, ru_info_t *ru, int *fra int slots_per_frame = 10 << fh_cfg->frame_conf.nNumerology; #endif - int tti = slots_per_frame * (frame) + (slot); + int tti = slots_per_frame * (*frame) + (*slot); 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 (ru->prach_buf) { for (uint16_t cc_id = 0; cc_id < 1 /*nSectorNum*/; cc_id++) { // OAI does not support multiple CC yet. for (int aa = 0; aa < ru->nb_rx; aa++) { for (sym_idx = prach_start_sym; sym_idx < prach_end_sym; sym_idx++) { @@ -481,7 +509,13 @@ int xran_fh_rx_prach_read_slot(prach_list_t *prach_list, ru_info_t *ru, int *fra } // sym_idx } // aa } // cc_id - } // ru->prach_buf + + // after reading PRACH, write back to queue + bool success = spsc_q_put(&gNB->prach_l1rx_queue, &p, sizeof(p)); + // assume prach_l1rx_queue never full: prach_ru_queue filled at + // constant pace, but prach_l1rx_queue emptied as fast as possible, + // see rx_func() + DevAssert(success); return (0); } @@ -614,12 +648,6 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot) int tti = slots_per_frame * (*frame) + (*slot); - read_prach_data(ru -#if defined F_RELEASE - , *frame, *slot -#endif - ); - const struct xran_fh_init *fh_init = get_xran_fh_init(); #if defined K_RELEASE int fftsize = 1 << fh_cfg->perMu[mu].nULFftSize; diff --git a/radio/fhi_72/oran_isolate.c b/radio/fhi_72/oran_isolate.c index b2eb9f576d..29da80a979 100644 --- a/radio/fhi_72/oran_isolate.c +++ b/radio/fhi_72/oran_isolate.c @@ -12,9 +12,7 @@ #include "xran_sync_api.h" #include "common/utils/LOG/log.h" -#include "common/utils/fsn.h" #include "openair1/PHY/defs_gNB.h" -#include "openair1/PHY/NR_TRANSPORT/nr_transport_proto.h" #include "oaioran.h" #include "oran-config.h" @@ -268,6 +266,8 @@ int trx_oran_ctlrecv(openair0_device_t *device, void *msg, ssize_t msg_len) void oran_fh_if4p5_south_in(RU_t *ru, int *frame, int *slot) { + int ret = 0; // return code for PUSCH/PRACH processing + ru_info_t ru_info = { .nb_rx = ru->nb_rx * ru->num_beams_period, .nb_tx = ru->nb_tx * ru->num_beams_period, @@ -277,54 +277,30 @@ void oran_fh_if4p5_south_in(RU_t *ru, int *frame, int *slot) .prach_buf = NULL, }; - prach_item_t p; - PHY_VARS_gNB *gNB = ru->gNB_list[0]; - fsn_t now = {.f = *frame, .s = *slot, .mu = gNB->frame_parms.numerology_index}; - if (get_next_nr_prach(&gNB->prach_ru_queue, &now, &p)) { - struct xran_fh_config *fh_cfg = get_xran_fh_config(0); + /* Firstly, process PRACH packets */ + int f_prach, sl_prach; #if defined F_RELEASE - uint8_t mu = fh_cfg->frame_conf.nNumerology; -#elif defined K_RELEASE - uint8_t mu = fh_cfg->nNumerology[0]; + // no PRACH callback (no queue) in F release so use the expected combination + f_prach = *frame; + sl_prach = *slot; #endif - int slots_per_subframe = 1 << mu; - uint32_t subframe = *slot / slots_per_subframe; // `slot` = slot in which PRACH is received - // PRACH occasion in a frame if and only if SFN % x == y, TS 38.211 Table 6.3.3.2-2/3/4 - nr_prach_info_t prach_info = get_prach_info(0); - bool is_prach_frame = (*frame % prach_info.x == prach_info.y); - bool is_prach_slot = is_prach_frame && xran_is_prach_slot(0, subframe, (p.slot % slots_per_subframe) -#if defined K_RELEASE - , mu -#endif - ); // `p.slot` = slot in which PRACH is scheduled - bool is_prach_slot = is_prach_frame && check_xran_prach_slot; - if (is_prach_slot) { - ru_info.prach_buf = p.prach_buf; - } else { - LOG_W(HW, "[%d.%d] Expected PRACH reception of scheduled slot %d\n", *frame, *slot, p.slot); - } + ret = xran_fh_rx_prach_read_slot(ru->gNB_list[0], &ru_info, &f_prach, &sl_prach); + if (ret != 0) { + printf("ORAN: %d.%d ORAN_fh_if4p5_south_in ERROR in RX PRACH function \n", f_prach, sl_prach); } - RU_proc_t *proc = &ru->proc; + /* Secondly, process PUSCH packets */ + RU_proc_t *proc = &ru->proc; // to check if (frame,slot) combination corresponds to the expected PUSCH one int f, sl; LOG_D(HW, "Read rxdataF %p,%p\n", ru_info.rxdataF[0], ru_info.rxdataF[1]); start_meas(&ru->rx_fhaul); - int ret = xran_fh_rx_read_slot(&ru_info, &f, &sl); + ret = xran_fh_rx_read_slot(&ru_info, &f, &sl); stop_meas(&ru->rx_fhaul); LOG_D(HW, "Read %d.%d rxdataF %p,%p\n", f, sl, ru_info.rxdataF[0], ru_info.rxdataF[1]); if (ret != 0) { printf("ORAN: %d.%d ORAN_fh_if4p5_south_in ERROR in RX function \n", f, sl); } - if (ru_info.prach_buf) { - // xran_fh_rx_read_slot() should have read PRACH, write back to queue - bool success = spsc_q_put(&gNB->prach_l1rx_queue, &p, sizeof(p)); - // assume prach_l1rx_queue never full: prach_ru_queue filled at - // constant pace, but prach_l1rx_queue emptied as fast as possible, - // see rx_func() - DevAssert(success); - } - int slots_per_frame = 10 << (ru->openair0_cfg.nr_scs_for_raster); proc->tti_rx = sl; proc->frame_rx = f; diff --git a/radio/fhi_72/oran_isolate.h b/radio/fhi_72/oran_isolate.h index afdf443596..450115fcff 100644 --- a/radio/fhi_72/oran_isolate.h +++ b/radio/fhi_72/oran_isolate.h @@ -14,6 +14,8 @@ #include "openair1/PHY/impl_defs_nr.h" #include "openair1/PHY/TOOLS/tools_defs.h" #include "openair1/PHY/defs_nr_common.h" +#include "openair1/PHY/NR_TRANSPORT/nr_transport_proto.h" + /* * Structure added to bear the information needed from OAI RU */ @@ -38,12 +40,18 @@ typedef struct ru_info_s { c16_t (*prach_buf)[NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX][NR_PRACH_SEQ_LEN_L]; } ru_info_t; -/** @brief Reads RX data (PRACH/PUSCH) of next slot. +/** @brief Reads RX data PUSCH of next slot. * * @param ru pointer to structure keeping pointers to OAI data. * @param frame output of the frame which has been read. * @param slot output of the slot which has been read. */ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot); +/** @brief Reads RX data PRACH of next slot. + * + * @param ru pointer to structure keeping pointers to OAI data. + * @param frame input for F_RELEASE, output for K_RELEASE. + * @param slot input for F_RELEASE, output for K_RELEASE. */ +int xran_fh_rx_prach_read_slot(PHY_VARS_gNB *gNB, ru_info_t *ru, int *frame, int *slot); /** @brief Writes TX data (PDSCH) of given slot. */ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp);