Commit 5b6e16c8 authored by Jaroslava Fiedlerova's avatar Jaroslava Fiedlerova

Merge remote-tracking branch 'origin/ue-monitoring-stats' into integration_2024_w47 (!2996)

Ue monitoring stats

- one commit to add UE mac stats similar to gNB one and remove a partial
implementation at phy level of some counters
- second commit only rename the two UE persisted HARQ tyepdef names for DL
and for UL (one was saying "UE" but not the direction and the second the
direction but not "UE")
parents e5310431 65e3c89b
......@@ -43,6 +43,7 @@
#define MAX_BWP_SIZE 275
#define NR_MAX_NUM_BWP 4
#define NR_MAX_HARQ_PROCESSES 32
#define NR_MAX_HARQ_ROUNDS_FOR_STATS 16
#define NR_NB_REG_PER_CCE 6
#define NR_NB_SC_PER_RB 12
#define NR_MAX_NUM_LCID 32
......
......@@ -594,7 +594,11 @@ void processSlotTX(void *arg)
RU_write(rxtxD, sl_tx_action);
}
static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE, const UE_nr_rxtx_proc_t *proc, int *tx_wait_for_dlsch, nr_phy_data_t *phy_data)
static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE,
const UE_nr_rxtx_proc_t *proc,
int *tx_wait_for_dlsch,
nr_phy_data_t *phy_data,
bool *stats_printed)
{
int sampleShift = INT_MAX;
NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
......@@ -602,7 +606,6 @@ static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE, const UE_nr_rxtx_proc_t *proc
fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params;
if (IS_SOFTMODEM_NOS1 || IS_SA_MODE(get_softmodem_params())) {
// Start synchronization with a target gNB
if (UE->synch_request.received_synch_request == 1) {
fapi_nr_synch_request_t *synch_req = &UE->synch_request.synch_req;
......@@ -655,6 +658,16 @@ static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE, const UE_nr_rxtx_proc_t *proc
const int ack_nack_slot = (proc->nr_slot_rx + phy_data->dlsch[0].dlsch_config.k1_feedback) % UE->frame_parms.slots_per_frame;
tx_wait_for_dlsch[ack_nack_slot]++;
}
} else {
// good time to print statistics, we don't have to spend time to decode DCI
if (proc->frame_rx % 128 == 0) {
if (*stats_printed == false) {
print_ue_mac_stats(UE->Mod_id, proc->frame_rx, proc->nr_slot_rx);
*stats_printed = true;
}
} else {
*stats_printed = false;
}
}
if (UE->sl_mode == 2) {
......@@ -833,6 +846,7 @@ void *UE_thread(void *arg)
int shiftForNextFrame = 0;
int intialSyncOffset = 0;
openair0_timestamp sync_timestamp;
bool stats_printed = false;
if (get_softmodem_params()->sync_ref && UE->sl_mode == 2) {
UE->is_synchronized = 1;
......@@ -1029,7 +1043,7 @@ void *UE_thread(void *arg)
notifiedFIFO_elt_t *newRx = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), curMsg.proc.nr_slot_rx, NULL, UE_dl_processing);
nr_rxtx_thread_data_t *curMsgRx = (nr_rxtx_thread_data_t *)NotifiedFifoData(newRx);
*curMsgRx = (nr_rxtx_thread_data_t){.proc = curMsg.proc, .UE = UE};
int ret = UE_dl_preprocessing(UE, &curMsgRx->proc, tx_wait_for_dlsch, &curMsgRx->phy_data);
int ret = UE_dl_preprocessing(UE, &curMsgRx->proc, tx_wait_for_dlsch, &curMsgRx->phy_data, &stats_printed);
if (ret != INT_MAX)
shiftForNextFrame = ret;
pushTpool(&(get_nrUE_params()->Tpool), newRx);
......
......@@ -467,10 +467,10 @@ void nr_init_ul_harq_processes(NR_UL_UE_HARQ_t harq_list[NR_MAX_ULSCH_HARQ_PROCE
void init_nr_ue_transport(PHY_VARS_NR_UE *ue) {
nr_init_dl_harq_processes(ue->dl_harq_processes, NR_MAX_DLSCH_HARQ_PROCESSES, ue->frame_parms.N_RB_DL);
nr_init_ul_harq_processes(ue->ul_harq_processes, NR_MAX_ULSCH_HARQ_PROCESSES, ue->frame_parms.N_RB_UL, ue->frame_parms.nb_antennas_tx);
for(int i=0; i<5; i++)
ue->dl_stats[i] = 0;
nr_init_ul_harq_processes(ue->ul_harq_processes,
NR_MAX_ULSCH_HARQ_PROCESSES,
ue->frame_parms.N_RB_UL,
ue->frame_parms.nb_antennas_tx);
}
void clean_UE_harq(PHY_VARS_NR_UE *UE)
......
......@@ -285,7 +285,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
}
// HARQ stats
phy_vars_ue->dl_stats[harq_process->DLround]++;
LOG_D(PHY, "Round %d RV idx %d\n", harq_process->DLround, dlsch->dlsch_config.rv);
uint16_t nb_rb;// = 30;
uint8_t dmrs_Type = dlsch->dlsch_config.dmrsConfigType;
......
......@@ -200,13 +200,6 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
#define modOrder(I_MCS,I_TBS) ((I_MCS-I_TBS)*2+2) // Find modulation order from I_TBS and I_MCS
#endif
int dump_ue_stats(PHY_VARS_NR_UE *phy_vars_ue,
const UE_nr_rxtx_proc_t *proc,
char *buffer,
int length,
runmode_t mode,
int input_level_dBm);
/*!
\brief This function performs the initial cell search procedure - PSS detection, SSS detection and PBCH detection. At the
end, the basic frame parameters are known (Frame configuration - TDD/FDD and cyclic prefix length,
......
......@@ -520,8 +520,6 @@ typedef struct PHY_VARS_NR_UE_s {
SLIST_HEAD(ral_thresholds_gen_poll_s, ral_threshold_phy_t) ral_thresholds_gen_polled[RAL_LINK_PARAM_GEN_MAX];
SLIST_HEAD(ral_thresholds_lte_poll_s, ral_threshold_phy_t) ral_thresholds_lte_polled[RAL_LINK_PARAM_LTE_MAX];
#endif
int dl_errors;
_Atomic(int) dl_stats[16];
void* scopeData;
// Pointers to hold PDSCH data only for phy simulators
void *phy_sim_rxdataF;
......
......@@ -1010,22 +1010,6 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_
} // for rsc_id
} // for gNB_id
if ((frame_rx%64 == 0) && (nr_slot_rx==0)) {
LOG_I(NR_PHY,"============================================\n");
// fixed text + 8 HARQs rounds à 10 ("999999999/") + NULL
// if we use 999999999 HARQs, that should be sufficient for at least 138 hours
const size_t harq_output_len = 31 + 10 * 8 + 1;
char output[harq_output_len];
char *p = output;
const char *end = output + harq_output_len;
p += snprintf(p, end - p, "[UE %d] Harq round stats for Downlink: %d", ue->Mod_id, ue->dl_stats[0]);
for (int round = 1; round < 16 && (round < 3 || ue->dl_stats[round] != 0); ++round)
p += snprintf(p, end - p,"/%d", ue->dl_stats[round]);
LOG_I(NR_PHY,"%s\n", output);
LOG_I(NR_PHY,"============================================\n");
}
LOG_D(PHY," ------ --> PDCCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_IN);
......
......@@ -180,7 +180,7 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr
}
/* set a tx slot with no ack */
NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack;
NR_UE_DL_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack;
harq_status->slot_for_feedback_ack = proc->nr_slot_tx;
......@@ -267,7 +267,7 @@ int test_pucch_common_config_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_
common_pucch_configuration(ue, gNB_id, TST_PUCCH_COMMON_CONFIG_INDEX_OK);
/* set a tx slot with no ack */
NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack;
NR_UE_DL_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack;
harq_status->ack = DL_ACK;
......@@ -557,7 +557,7 @@ int test_pucch_dedicated_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_id,
int reset_harq = false;
int dl_harq_pid[TST_NB_STEP_SINGLE_TRANSPORT_BLOCK] = {TST_DL_HARQ_PID_FIRST, TST_DL_HARQ_PID_SECOND, TST_DL_HARQ_PID_THIRD, TST_DL_HARQ_PID_FOURTH };
int pucch_resource_indicator[TST_NB_STEP_SINGLE_TRANSPORT_BLOCK][2] = { { 0, 4 }, { 1, 0 } , { 1, 3 } , { 5, 7 } };
NR_UE_HARQ_STATUS_t *harq_status;
NR_UE_DL_HARQ_STATUS_t *harq_status;
ue->PDSCH_Config.maxNrofCodeWordsScheduledByDCI = nb_code_n1;
......@@ -584,7 +584,7 @@ int test_pucch_dedicated_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_id,
/* set a tx slot with no ack */
ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid = dl_harq_pid[i];
NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack;
NR_UE_DL_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack;
harq_status->slot_for_feedback_ack = proc->nr_slot_tx;
harq_status->send_harq_status = 1;
......@@ -618,7 +618,7 @@ int test_pucch_dedicated_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_id,
/* set a tx slot with no ack */
ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid = dl_harq_pid[i];
NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack;
NR_UE_DL_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack;
harq_status->slot_for_feedback_ack = proc->nr_slot_tx;
harq_status->send_harq_status = 1;
......@@ -662,7 +662,7 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE
int reset_harq = false;
int dl_harq_pid[TST_NB_STEP_TWO_TRANSPORT_BLOCKS] = {TST_DL_HARQ_PID_FIRST, TST_DL_HARQ_PID_SECOND, TST_DL_HARQ_PID_THIRD, TST_DL_HARQ_PID_FOURTH };
int pucch_resource_indicator[TST_NB_STEP_TWO_TRANSPORT_BLOCKS][2] = { { 0, 1 }, { 3, 7 } , { 2 , 4 } , { 4 , 6 } };
NR_UE_HARQ_STATUS_t *harq_status;
NR_UE_DL_HARQ_STATUS_t *harq_status;
int TB_identifier = 1;
int thread_number = TST_THREAD_ID;
......@@ -682,7 +682,7 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE
/* set a tx slot with no ack */
ue->dlsch[proc->thread_id][gNB_id][code_word]->current_harq_pid = dl_harq_pid[i];
NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][code_word]->harq_processes[dl_harq_pid[i]].harq_ack;
NR_UE_DL_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][code_word]->harq_processes[dl_harq_pid[i]].harq_ack;
harq_status->slot_for_feedback_ack = proc->nr_slot_tx;
harq_status->send_harq_status = 1;
......@@ -725,7 +725,7 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE
/* set a tx slot with no ack */
ue->dlsch[proc->thread_id][gNB_id][code_word]->current_harq_pid = dl_harq_pid[i];
NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][code_word]->harq_processes[dl_harq_pid[i]].harq_ack;
NR_UE_DL_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][code_word]->harq_processes[dl_harq_pid[i]].harq_ack;
harq_status->slot_for_feedback_ack = proc->nr_slot_tx;
harq_status->send_harq_status = 1;
......@@ -759,7 +759,7 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE
/* set a tx slot with no ack */
ue->dlsch[proc->thread_id][gNB_id][code_word]->current_harq_pid = dl_harq_pid[i];
NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][code_word]->harq_processes[dl_harq_pid[i]].harq_ack;
NR_UE_DL_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][code_word]->harq_processes[dl_harq_pid[i]].harq_ack;
harq_status->slot_for_feedback_ack = proc->nr_slot_tx;
harq_status->send_harq_status = 1;
......@@ -973,7 +973,7 @@ int test_sr_ack_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pro
/* set a first harq ack context */
NR_UE_HARQ_STATUS_t *harq_status;
NR_UE_DL_HARQ_STATUS_t *harq_status;
ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_FIRST;
......@@ -1085,7 +1085,7 @@ int test_csi_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc)
/* set a first harq ack context */
NR_UE_HARQ_STATUS_t *harq_status;
NR_UE_DL_HARQ_STATUS_t *harq_status;
ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_FIRST;
......
......@@ -2232,8 +2232,7 @@ static const uint16_t Table_51311[32][2] = {{2, 1200}, {2, 1570}, {2, 1930}, {2,
{4, 6580}, {6, 4380}, {6, 4660}, {6, 5170}, {6, 5670}, {6, 6160}, {6, 6660}, {6, 7190},
{6, 7720}, {6, 8220}, {6, 8730}, {6, 9100}, {6, 9480}, {2, 0}, {4, 0}, {6, 0}};
//Table 5.1.3.1-2 of 38.214
// Imcs values 20 and 26 have been multiplied by 2 to avoid the floating point
// Table 5.1.3.1-2 of 38.214
static const uint16_t Table_51312[32][2] = {{2, 1200}, {2, 1930}, {2, 3080}, {2, 4490}, {2, 6020}, {4, 3780}, {4, 4340},
{4, 4900}, {4, 5530}, {4, 6160}, {4, 6580}, {6, 4660}, {6, 5170}, {6, 5670},
{6, 6160}, {6, 6660}, {6, 7190}, {6, 7720}, {6, 8220}, {6, 8730}, {8, 6825},
......
......@@ -385,13 +385,15 @@ typedef struct {
uint32_t R;
uint32_t TBS;
int last_ndi;
} NR_UE_HARQ_STATUS_t;
int round;
} NR_UE_DL_HARQ_STATUS_t;
typedef struct {
uint32_t R;
uint32_t TBS;
int last_ndi;
} NR_UL_HARQ_INFO_t;
int round;
} NR_UE_UL_HARQ_INFO_t;
typedef struct {
uint8_t freq_hopping;
......@@ -510,6 +512,31 @@ typedef enum {
ON_PUSCH
} CSI_mapping_t;
typedef struct {
uint64_t rounds[NR_MAX_HARQ_ROUNDS_FOR_STATS];
uint64_t total_bits;
uint64_t total_symbols;
uint64_t target_code_rate;
uint64_t qam_mod_order;
uint64_t rb_size;
uint64_t nr_of_symbols;
} ue_mac_dir_stats_t;
typedef struct {
ue_mac_dir_stats_t dl;
ue_mac_dir_stats_t ul;
uint32_t bad_dci;
uint32_t ulsch_DTX;
uint64_t ulsch_total_bytes_scheduled;
uint32_t pucch0_DTX;
int cumul_rsrp;
uint8_t num_rsrp_meas;
char srs_stats[50]; // Statistics may differ depending on SRS usage
int pusch_snrx10;
int deltaMCS;
int NPRB;
} ue_mac_stats_t;
/*!\brief Top level UE MAC structure */
typedef struct NR_UE_MAC_INST_s {
module_id_t ue_id;
......@@ -594,8 +621,8 @@ typedef struct NR_UE_MAC_INST_s {
// Defined for abstracted mode
nr_downlink_indication_t dl_info;
NR_UE_HARQ_STATUS_t dl_harq_info[NR_MAX_HARQ_PROCESSES];
NR_UL_HARQ_INFO_t ul_harq_info[NR_MAX_HARQ_PROCESSES];
NR_UE_DL_HARQ_STATUS_t dl_harq_info[NR_MAX_HARQ_PROCESSES];
NR_UE_UL_HARQ_INFO_t ul_harq_info[NR_MAX_HARQ_PROCESSES];
NR_TAG_Id_t tag_Id;
A_SEQUENCE_OF(NR_TAG_t) TAG_list;
......@@ -615,6 +642,7 @@ typedef struct NR_UE_MAC_INST_s {
bool pusch_power_control_initialized;
int delta_msg2;
pthread_mutex_t if_mutex;
ue_mac_stats_t stats;
} NR_UE_MAC_INST_t;
/*@}*/
......
......@@ -240,8 +240,7 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac)
nr_mac->scheduling_info.phr_info.was_mac_reset = true;
// flush the soft buffers for all DL HARQ processes
for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++)
memset(&nr_mac->dl_harq_info[k], 0, sizeof(NR_UE_HARQ_STATUS_t));
memset(nr_mac->dl_harq_info, 0, sizeof(nr_mac->dl_harq_info));
// for each DL HARQ process, consider the next received transmission for a TB as the very first transmission
for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++)
......
......@@ -1053,7 +1053,7 @@ void trigger_MAC_UE_RA(NR_UE_MAC_INST_t *mac)
void prepare_msg4_msgb_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack)
{
NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[pid];
NR_UE_DL_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[pid];
int sched_slot = current_harq->ul_slot;
int sched_frame = current_harq->ul_frame;
mac->nr_ue_emul_l1.num_harqs = 1;
......
......@@ -806,7 +806,7 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac,
/* MCS */
dlsch_pdu->mcs = dci->mcs;
NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[dci->harq_pid.val];
NR_UE_DL_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[dci->harq_pid.val];
/* NDI (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI)*/
if (dl_conf_req->pdu_type == FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH ||
dl_conf_req->pdu_type == FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH ||
......@@ -815,9 +815,9 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac,
dlsch_pdu->new_data_indicator = true;
current_harq->R = 0;
current_harq->TBS = 0;
}
else
} else {
dlsch_pdu->new_data_indicator = false;
}
if (dl_conf_req->pdu_type != FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH &&
dl_conf_req->pdu_type != FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH) {
......@@ -935,6 +935,12 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac,
dci_ind->N_CCE,
frame,
slot);
if (dlsch_pdu->new_data_indicator)
current_harq->round = 0;
else
current_harq->round++;
if (current_harq->round < sizeofArray(mac->stats.dl.rounds))
mac->stats.dl.rounds[current_harq->round]++;
}
LOG_D(MAC,
......@@ -1126,7 +1132,7 @@ static int nr_ue_process_dci_dl_11(NR_UE_MAC_INST_t *mac,
/* MCS (for transport block 1)*/
dlsch_pdu->mcs = dci->mcs;
/* NDI (for transport block 1)*/
NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[dci->harq_pid.val];
NR_UE_DL_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[dci->harq_pid.val];
if (dci->ndi != current_harq->last_ndi) {
// new data
dlsch_pdu->new_data_indicator = true;
......@@ -1275,6 +1281,12 @@ static int nr_ue_process_dci_dl_11(NR_UE_MAC_INST_t *mac,
dci_ind->N_CCE,
frame,
slot);
if (dlsch_pdu->new_data_indicator)
current_harq->round = 0;
else
current_harq->round++;
if (current_harq->round < sizeofArray(mac->stats.dl.rounds))
mac->stats.dl.rounds[current_harq->round]++;
// send the ack/nack slot number to phy to indicate tx thread to wait for DLSCH decoding
dlsch_pdu->k1_feedback = feedback_ti;
......@@ -1432,10 +1444,11 @@ nr_dci_format_t nr_ue_process_dci_indication_pdu(NR_UE_MAC_INST_t *mac, frame_t
nr_extract_dci_info(mac, dci->dci_format, dci->payloadSize, dci->rnti, dci->ss_type, dci->payloadBits, slot);
if (format == NR_DCI_NONE)
return NR_DCI_NONE;
dci_pdu_rel15_t *def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[slot][format];
int ret = nr_ue_process_dci(mac, frame, slot, def_dci_pdu_rel15, dci, format);
if (ret < 0)
int ret = nr_ue_process_dci(mac, frame, slot, mac->def_dci_pdu_rel15[slot] + format, dci, format);
if (ret < 0) {
mac->stats.bad_dci++;
return NR_DCI_NONE;
}
return format;
}
......@@ -1459,7 +1472,7 @@ void set_harq_status(NR_UE_MAC_INST_t *mac,
frame_t frame,
int slot)
{
NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[harq_id];
NR_UE_DL_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[harq_id];
current_harq->active = true;
current_harq->ack_received = false;
current_harq->pucch_resource_indicator = pucch_id;
......@@ -1486,7 +1499,7 @@ void set_harq_status(NR_UE_MAC_INST_t *mac,
// looking for other active HARQ processes with feedback in the same frame/slot
if (i == harq_id)
continue;
NR_UE_HARQ_STATUS_t *harq = &mac->dl_harq_info[i];
NR_UE_DL_HARQ_STATUS_t *harq = &mac->dl_harq_info[i];
if (harq->active &&
harq->ul_frame == current_harq->ul_frame &&
harq->ul_slot == current_harq->ul_slot) {
......@@ -2331,7 +2344,7 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche
for (int dl_harq_pid = 0; dl_harq_pid < num_dl_harq; dl_harq_pid++) {
NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[dl_harq_pid];
NR_UE_DL_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[dl_harq_pid];
if (current_harq->active) {
LOG_D(PHY, "HARQ pid %d is active for %d.%d\n",
......
......@@ -166,8 +166,8 @@ void handle_time_alignment_timer_expired(NR_UE_MAC_INST_t *mac)
{
// flush all HARQ buffers for all Serving Cells
for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++) {
memset(&mac->dl_harq_info[k], 0, sizeof(NR_UE_HARQ_STATUS_t));
memset(&mac->ul_harq_info[k], 0, sizeof(NR_UL_HARQ_INFO_t));
memset(&mac->dl_harq_info[k], 0, sizeof(*mac->dl_harq_info));
memset(&mac->ul_harq_info[k], 0, sizeof(*mac->ul_harq_info));
mac->dl_harq_info[k].last_ndi = -1; // initialize to invalid value
mac->ul_harq_info[k].last_ndi = -1; // initialize to invalid value
}
......@@ -704,6 +704,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
0,
f_alloc) < 0) {
LOG_E(NR_MAC, "can't nr_ue_process_dci_freq_dom_resource_assignment()\n");
mac->stats.bad_dci++;
return -1;
}
......@@ -713,7 +714,6 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
// Time domain allocation
pusch_config_pdu->start_symbol_index = tda_info->startSymbolIndex;
pusch_config_pdu->nr_of_symbols = tda_info->nrOfSymbols;
l_prime_mask = get_l_prime(tda_info->nrOfSymbols,
tda_info->mapping_type,
add_pos,
......@@ -817,11 +817,13 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
ul_ports_config(mac, &dmrslength, pusch_config_pdu, dci, dci_format);
} else {
LOG_E(NR_MAC, "UL grant from DCI format %d is not handled...\n", dci_format);
mac->stats.bad_dci++;
return -1;
}
if (pusch_config_pdu->nrOfLayers < 1) {
LOG_E(NR_MAC, "Invalid UL number of layers %d from DCI\n", pusch_config_pdu->nrOfLayers);
mac->stats.bad_dci++;
return -1;
}
......@@ -892,6 +894,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
0,
dci->frequency_domain_assignment) < 0) {
LOG_E(NR_MAC, "can't nr_ue_process_dci_freq_dom_resource_assignment()\n");
mac->stats.bad_dci++;
return -1;
}
......@@ -910,18 +913,20 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
pusch_config_pdu->mcs_table = get_pusch_mcs_table(mcs_table_config, tp_enabled, dci_format, rnti_type, ss_type, false);
/* NDI */
NR_UL_HARQ_INFO_t *harq = &mac->ul_harq_info[dci->harq_pid.val];
const int pid = dci->harq_pid.val;
NR_UE_UL_HARQ_INFO_t *harq = &mac->ul_harq_info[pid];
pusch_config_pdu->pusch_data.new_data_indicator = false;
if (dci->ndi != harq->last_ndi) {
pusch_config_pdu->pusch_data.new_data_indicator = true;
// if new data reset harq structure
memset(harq, 0, sizeof(*harq));
}
} else
harq->round++;
harq->last_ndi = dci->ndi;
/* RV */
pusch_config_pdu->pusch_data.rv_index = dci->rv;
/* HARQ_PROCESS_NUMBER */
pusch_config_pdu->pusch_data.harq_process_id = dci->harq_pid.val;
pusch_config_pdu->pusch_data.harq_process_id = pid;
if (NR_DMRS_ulconfig != NULL)
add_pos = (NR_DMRS_ulconfig->dmrs_AdditionalPosition == NULL) ? 2 : *NR_DMRS_ulconfig->dmrs_AdditionalPosition;
......@@ -994,6 +999,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
pusch_config_pdu->qam_mod_order = nr_get_Qm_ul(pusch_config_pdu->mcs_index, pusch_config_pdu->mcs_table);
if (pusch_config_pdu->qam_mod_order == 0) {
LOG_W(NR_MAC, "Invalid Mod order, likely due to unexpected UL DCI. Ignoring DCI! \n");
mac->stats.bad_dci++;
return -1;
}
......@@ -1001,15 +1007,16 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
int number_of_symbols = pusch_config_pdu->nr_of_symbols;
int number_dmrs_symbols = 0;
for (int i = start_symbol; i < start_symbol + number_of_symbols; i++) {
if((pusch_config_pdu->ul_dmrs_symb_pos >> i) & 0x01)
if ((pusch_config_pdu->ul_dmrs_symb_pos >> i) & 0x01)
number_dmrs_symbols += 1;
}
int nb_dmrs_re_per_rb = ((pusch_config_pdu->dmrs_config_type == pusch_dmrs_type1) ? 6 : 4) * pusch_config_pdu->num_dmrs_cdm_grps_no_data;
int nb_dmrs_re_per_rb =
((pusch_config_pdu->dmrs_config_type == pusch_dmrs_type1) ? 6 : 4) * pusch_config_pdu->num_dmrs_cdm_grps_no_data;
// Compute TBS
uint16_t R = nr_get_code_rate_ul(pusch_config_pdu->mcs_index, pusch_config_pdu->mcs_table);
int pid = pusch_config_pdu->pusch_data.harq_process_id;
const int pid = pusch_config_pdu->pusch_data.harq_process_id;
if (R > 0) {
pusch_config_pdu->target_code_rate = R;
pusch_config_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_config_pdu->qam_mod_order,
......@@ -1022,8 +1029,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
pusch_config_pdu->nrOfLayers) >> 3;
mac->ul_harq_info[pid].TBS = pusch_config_pdu->pusch_data.tb_size;
mac->ul_harq_info[pid].R = R;
}
else {
} else {
pusch_config_pdu->target_code_rate = mac->ul_harq_info[pid].R;
pusch_config_pdu->pusch_data.tb_size = mac->ul_harq_info[pid].TBS;
}
......@@ -1052,7 +1058,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
pusch_config_pdu->rb_start,
pusch_config_pdu->nr_of_symbols,
nb_dmrs_re_per_rb * number_dmrs_symbols,
0, //TODO: count PTRS per RB
0, // TODO: count PTRS per RB
pusch_config_pdu->qam_mod_order,
pusch_config_pdu->target_code_rate,
pusch_config_pdu->pusch_uci.beta_offset_csi1,
......@@ -1063,12 +1069,13 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
pusch_config_pdu->ldpcBaseGraph = get_BG(pusch_config_pdu->pusch_data.tb_size << 3, pusch_config_pdu->target_code_rate);
//The MAC entity shall restart retxBSR-Timer upon reception of a grant for transmission of new data on any UL-SCH
// The MAC entity shall restart retxBSR-Timer upon reception of a grant for transmission of new data on any UL-SCH
if (pusch_config_pdu->pusch_data.new_data_indicator && dci && dci->ulsch_indicator)
nr_timer_start(&mac->scheduling_info.retxBSR_Timer);
if (pusch_config_pdu->pusch_data.tb_size == 0) {
LOG_E(MAC, "Invalid TBS = 0. Probably caused by missed detection of DCI\n");
mac->stats.bad_dci++;
return -1;
}
......@@ -1081,6 +1088,14 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
nr_timer_start(&mac->scheduling_info.phr_info.periodicPHR_Timer);
}
}
if (mac->ul_harq_info[pid].round < sizeofArray(mac->stats.ul.rounds))
mac->stats.ul.rounds[mac->ul_harq_info[pid].round]++;
int bits = pusch_config_pdu->pusch_data.tb_size;
mac->stats.ul.total_bits += bits;
mac->stats.ul.target_code_rate += pusch_config_pdu->target_code_rate * bits;
mac->stats.ul.total_symbols += bits / pusch_config_pdu->qam_mod_order;
mac->stats.ul.rb_size += pusch_config_pdu->rb_size;
mac->stats.ul.nr_of_symbols += pusch_config_pdu->nr_of_symbols;
return 0;
}
......@@ -2124,9 +2139,9 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac)
tx_ssb->nb_mapped_ro);
// If all the required SSBs are mapped to this RO, exit the loop of SSBs
if (ro_p->nb_mapped_ssb == ssb_rach_ratio) {
idx++;
break;
}
idx++;
break;
}
}
done = MAX_NB_SSB == idx;
}
......
......@@ -67,6 +67,57 @@ queue_t nr_ul_dci_req_queue;
queue_t nr_ul_tti_req_queue;
static void save_pdsch_pdu_for_crnti(nfapi_nr_dl_tti_request_t *dl_tti_request);
void print_ue_mac_stats(const module_id_t mod, const int frame_rx, const int slot_rx)
{
NR_UE_MAC_INST_t *mac = get_mac_inst(mod);
int ret = pthread_mutex_lock(&mac->if_mutex);
AssertFatal(!ret, "mutex failed %d\n", ret);
char txt[1024];
char *end = txt + sizeof(txt);
char *cur = txt;
float nbul = 0;
for (uint64_t *p = mac->stats.ul.rounds; p < mac->stats.ul.rounds + NR_MAX_HARQ_ROUNDS_FOR_STATS; p++)
nbul += *p;
if (nbul < 1)
nbul = 1;
float nbdl = 0;
for (uint64_t *p = mac->stats.dl.rounds; p < mac->stats.dl.rounds + NR_MAX_HARQ_ROUNDS_FOR_STATS; p++)
nbdl += *p;
if (nbdl < 1)
nbdl = 1;
cur += snprintf(cur, end - cur, "UE %d stats sfn: %d.%d, cumulated bad DCI %d\n", mod, frame_rx, slot_rx, mac->stats.bad_dci);
cur += snprintf(cur, end - cur, " DL harq: %lu", mac->stats.dl.rounds[0]);
int nb;
for (nb = NR_MAX_HARQ_ROUNDS_FOR_STATS - 1; nb > 1; nb--)
if (mac->stats.ul.rounds[nb])
break;
for (int i = 1; i < nb + 1; i++)
cur += snprintf(cur, end - cur, "/%lu", mac->stats.dl.rounds[i]);
cur += snprintf(cur, end - cur, "\n Ul harq: %lu", mac->stats.ul.rounds[0]);
for (nb = NR_MAX_HARQ_ROUNDS_FOR_STATS - 1; nb > 1; nb--)
if (mac->stats.ul.rounds[nb])
break;
for (int i = 1; i < nb + 1; i++)
cur += snprintf(cur, end - cur, "/%lu", mac->stats.ul.rounds[i]);
snprintf(cur,
end - cur,
" avg code rate %.01f, avg bit/symbol %.01f, avg per TB: "
"(nb RBs %.01f, nb symbols %.01f)\n",
(double)mac->stats.ul.target_code_rate / (mac->stats.ul.total_bits * 1024 * 10), // See const Table_51311 definition
(double)mac->stats.ul.total_bits / mac->stats.ul.total_symbols,
mac->stats.ul.rb_size / nbul,
mac->stats.ul.nr_of_symbols / nbul);
LOG_I(NR_MAC, "%s", txt);
ret = pthread_mutex_unlock(&mac->if_mutex);
AssertFatal(!ret, "mutex failed %d\n", ret);
}
void nrue_init_standalone_socket(int tx_port, int rx_port)
{
{
......@@ -1120,7 +1171,7 @@ static int8_t handle_csirs_measurements(NR_UE_MAC_INST_t *mac,
void update_harq_status(NR_UE_MAC_INST_t *mac, uint8_t harq_pid, uint8_t ack_nack)
{
NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[harq_pid];
NR_UE_DL_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[harq_pid];
if (current_harq->active) {
LOG_D(PHY,"Updating harq_status for harq_id %d, ack/nak %d\n", harq_pid, current_harq->ack);
......
......@@ -322,5 +322,7 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info);
void nr_ue_sl_indication(nr_sidelink_indication_t *sl_indication);
void print_ue_mac_stats(const module_id_t mod, const int frame_rx, const int slot_rx);
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment