Separate PRACH and PUSCH packet processing
* rename read_prach_data() to xran_rx_prach_read_slot() * in F release, there is no PRACH queue so `frame` and `slot` are passed as input; in K release, `frame` and `slot` are taken from the PRACH queue Note: since the PUSCH callback is the called before PRACH callback, this commit is correct but the timing for PRACH processing is just a little bit late. In previous state, PRACH processing was done inside the function of PUSCH processing. => next commit will just reverse the order. Signed-off-by: Teodora Vladić <teodora.vladic@openairinterface.org>
This commit is contained in:
committed by
Romain Beurdouche
parent
1bc8e64641
commit
d06bd3d49f
+43
-15
@@ -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;
|
||||
|
||||
+13
-37
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user