Commit 6c34d3e6 authored by Laurent THOMAS's avatar Laurent THOMAS

Simplify interface by removing dcireq_t struct that was only calling one function

Simplify the intermediate struct nr_uplink_indication_t by passing only tx frame+slot
Simplify nr_scheduled_response_t by removing module id, CCid, ... that are there only to rediscover the mac storage structure head, pass directly the mac head pointer instead
fix bugs in ul_info.frame_rx + 1 that was missing %1024
add mutex mac_IF_mutex modifications verification of returned value to log errors if a error occurs
remove fill_scheduled_response() that was doing nothing useful
split nr_ue_dl_indication() implementation in two very differnt functions depending on the call purpose (ue scheduler or actual dl data processing), the API is kept as one nr_ue_dl_indication() unchanged, nevertheless this design is obscur
rework completly the access to mac->ul_config_request[slot]
    - make proper encapsulation of the data access, mutex, ... and proper API to create elements, iterators
    - kept general usage of this mutex protected storage as it is, even in useless cases (like inside processing of this given tx slot, so the consumer speaks to itself)
nr_ue_get_rach(): remove a hidden result data global variable to return explcitly computed value (in one place, it reveals we don't use the computed value, kept as it is)
nr_get_msg3_payload(): add a polling waiting state to wait the RRC thread sent the pdu to RLC (should be fixed better later)
simplify a bit ue->tx_resume_ind_fifo, add logs in error cases, coherency checks with the associated counter tx_wait_for_dlsch
this counter tx_wait_for_dlsch reduce it's visibility to be now local in main UE loop (UE_thread)
nevertheless, it should be simplified more (the pair tx_resume_ind_fifo/tx_wait_for_dlsch is a complex wiat to make a semaphore, and maybe we can entirely simplify the multi-threading by running in place when it is appropriate time instead of calling send_slot_ind() that is furthermore a wrong function naming
split nr_ue_scheduled_response() in nr_ue_scheduled_response_dl() and nr_ue_scheduled_response_ul(), the function is kept to minimize the code change
improve this function C code, by shortening long C lines

minor cleaning: move to static functions related to this MR when they can be static
parent 64eaf48a
......@@ -310,16 +310,13 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
int CC_id = 0;
uint8_t gNB_id = 0;
nr_uplink_indication_t ul_info;
int slots_per_frame = 20; //30 kHZ subcarrier spacing
int slot_ahead = 2; // TODO: Make this dynamic
ul_info.cc_id = CC_id;
ul_info.gNB_index = gNB_id;
ul_info.module_id = mod_id;
ul_info.frame_rx = frame;
ul_info.slot_rx = slot;
ul_info.slot_tx = (slot + slot_ahead) % slots_per_frame;
ul_info.frame_tx = (ul_info.slot_rx + slot_ahead >= slots_per_frame) ? ul_info.frame_rx + 1 : ul_info.frame_rx;
nr_uplink_indication_t ul_info = {.cc_id = CC_id,
.gNB_index = gNB_id,
.module_id = mod_id,
.slot = (slot + slot_ahead) % slots_per_frame,
.frame = (slot + slot_ahead >= slots_per_frame) ? (frame + 1) % 1024 : frame};
if (pthread_mutex_lock(&mac->mutex_dl_info)) abort();
......@@ -330,8 +327,7 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
free_and_zero(ch_info);
}
if (is_nr_DL_slot(mac->tdd_UL_DL_ConfigurationCommon,
ul_info.slot_rx)) {
if (is_nr_DL_slot(mac->tdd_UL_DL_ConfigurationCommon, slot)) {
memset(&mac->dl_info, 0, sizeof(mac->dl_info));
mac->dl_info.cc_id = CC_id;
mac->dl_info.gNB_index = gNB_id;
......@@ -345,9 +341,8 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
if (pthread_mutex_unlock(&mac->mutex_dl_info)) abort();
if (is_nr_UL_slot(mac->tdd_UL_DL_ConfigurationCommon,
ul_info.slot_tx, mac->frame_type)) {
LOG_D(NR_MAC, "Slot %d. calling nr_ue_ul_ind()\n", ul_info.slot_tx);
if (is_nr_UL_slot(mac->tdd_UL_DL_ConfigurationCommon, ul_info.slot, mac->frame_type)) {
LOG_D(NR_MAC, "Slot %d. calling nr_ue_ul_ind()\n", ul_info.slot);
nr_ue_ul_scheduler(&ul_info);
}
process_queued_nr_nfapi_msgs(mac, sfn_slot);
......@@ -545,7 +540,12 @@ void processSlotTX(void *arg) {
PHY_VARS_NR_UE *UE = rxtxD->UE;
nr_phy_data_tx_t phy_data = {0};
LOG_D(PHY,"%d.%d => slot type %d\n", proc->frame_tx, proc->nr_slot_tx, proc->tx_slot_type);
LOG_D(PHY,
"SlotTx %d.%d => slot type %d, wait: %d \n",
proc->frame_tx,
proc->nr_slot_tx,
proc->tx_slot_type,
rxtxD->tx_wait_for_dlsch);
if (proc->tx_slot_type == NR_UPLINK_SLOT || proc->tx_slot_type == NR_MIXED_SLOT){
// wait for rx slots to send indication (if any) that DLSCH decoding is finished
......@@ -558,17 +558,12 @@ void processSlotTX(void *arg) {
// [TODO] mapping right after NR initial sync
if(UE->if_inst != NULL && UE->if_inst->ul_indication != NULL) {
start_meas(&UE->ue_ul_indication_stats);
nr_uplink_indication_t ul_indication;
memset((void*)&ul_indication, 0, sizeof(ul_indication));
ul_indication.module_id = UE->Mod_id;
ul_indication.gNB_index = proc->gNB_id;
ul_indication.cc_id = UE->CC_id;
ul_indication.frame_rx = proc->frame_rx;
ul_indication.slot_rx = proc->nr_slot_rx;
ul_indication.frame_tx = proc->frame_tx;
ul_indication.slot_tx = proc->nr_slot_tx;
ul_indication.phy_data = &phy_data;
nr_uplink_indication_t ul_indication = {.module_id = UE->Mod_id,
.gNB_index = proc->gNB_id,
.cc_id = UE->CC_id,
.frame = proc->frame_tx,
.slot = proc->nr_slot_tx,
.phy_data = &phy_data};
UE->if_inst->ul_indication(&ul_indication);
stop_meas(&UE->ue_ul_indication_stats);
......@@ -580,9 +575,10 @@ void processSlotTX(void *arg) {
RU_write(rxtxD);
}
nr_phy_data_t UE_dl_preprocessing(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc)
static nr_phy_data_t UE_dl_preprocessing(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, int *tx_wait_for_dlsch)
{
nr_phy_data_t phy_data = {0};
LOG_D(PHY, "preprocessing %d.%d => slot type %d \n", proc->frame_rx, proc->nr_slot_rx, proc->rx_slot_type);
if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa) {
......@@ -613,10 +609,11 @@ nr_phy_data_t UE_dl_preprocessing(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc)
uint64_t a=rdtsc_oai();
pbch_pdcch_processing(UE, proc, &phy_data);
if (phy_data.dlsch[0].active) {
if (phy_data.dlsch[0].active && phy_data.dlsch[0].rnti != SI_RNTI) {
// indicate to tx thread to wait for DLSCH decoding
const int ack_nack_slot = (proc->nr_slot_rx + phy_data.dlsch[0].dlsch_config.k1_feedback) % UE->frame_parms.slots_per_frame;
UE->tx_wait_for_dlsch[ack_nack_slot]++;
tx_wait_for_dlsch[ack_nack_slot]++;
LOG_D(NR_PHY, "Adding wait even for slot %d, total %d\n", ack_nack_slot, tx_wait_for_dlsch[ack_nack_slot]);
}
LOG_D(PHY, "In %s: slot %d, time %llu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc_oai()-a)/3500);
......@@ -764,10 +761,10 @@ void *UE_thread(void *arg)
const int nb_slot_frame = UE->frame_parms.slots_per_frame;
int absolute_slot=0, decoded_frame_rx=INT_MAX, trashed_frames=0;
initNotifiedFIFO(&UE->phy_config_ind);
int tx_wait_for_dlsch[NR_MAX_SLOTS_PER_FRAME];
int num_ind_fifo = nb_slot_frame;
for(int i=0; i < num_ind_fifo; i++) {
UE->tx_wait_for_dlsch[num_ind_fifo] = 0;
UE->tx_resume_ind_fifo[i] = malloc(sizeof(*UE->tx_resume_ind_fifo[i]));
initNotifiedFIFO(UE->tx_resume_ind_fifo[i]);
}
......@@ -824,6 +821,7 @@ void *UE_thread(void *arg)
syncInFrame(UE, &timestamp);
UE->rx_offset=0;
UE->time_sync_cell=0;
memset(tx_wait_for_dlsch, 0, sizeof(tx_wait_for_dlsch));
// read in first symbol
AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
......@@ -913,24 +911,26 @@ void *UE_thread(void *arg)
if (curMsg.proc.nr_slot_tx == 0)
nr_ue_rrc_timer_trigger(UE->Mod_id, curMsg.proc.frame_tx, curMsg.proc.gNB_id);
// RX slot processing. We launch and forget.
notifiedFIFO_elt_t *newEltRx =
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(newEltRx);
curMsgRx->proc = curMsg.proc;
curMsgRx->UE = UE;
curMsgRx->phy_data = UE_dl_preprocessing(UE, &curMsg.proc, UE->tx_wait_for_dlsch);
pushTpool(&(get_nrUE_params()->Tpool), newEltRx);
// Start TX slot processing here. It runs in parallel with RX slot processing
notifiedFIFO_elt_t *newElt = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), curMsg.proc.nr_slot_tx, &txFifo, processSlotTX);
nr_rxtx_thread_data_t *curMsgTx = (nr_rxtx_thread_data_t *) NotifiedFifoData(newElt);
notifiedFIFO_elt_t *newEltTx =
newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), curMsg.proc.nr_slot_tx, &txFifo, processSlotTX);
nr_rxtx_thread_data_t *curMsgTx = (nr_rxtx_thread_data_t *)NotifiedFifoData(newEltTx);
curMsgTx->proc = curMsg.proc;
curMsgTx->writeBlockSize = writeBlockSize;
curMsgTx->proc.timestamp_tx = writeTimestamp;
curMsgTx->UE = UE;
curMsgTx->tx_wait_for_dlsch = UE->tx_wait_for_dlsch[curMsgTx->proc.nr_slot_tx];
UE->tx_wait_for_dlsch[curMsgTx->proc.nr_slot_tx] = 0;
pushTpool(&(get_nrUE_params()->Tpool), newElt);
// RX slot processing. We launch and forget.
newElt = 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(newElt);
curMsgRx->proc = curMsg.proc;
curMsgRx->UE = UE;
curMsgRx->phy_data = UE_dl_preprocessing(UE, &curMsg.proc);
pushTpool(&(get_nrUE_params()->Tpool), newElt);
pushTpool(&(get_nrUE_params()->Tpool), newEltTx);
// Wait for TX slot processing to finish
notifiedFIFO_elt_t *res;
......
......@@ -69,4 +69,5 @@
#define FAPI_NR_UL_CONFIG_TYPE_SRS 0x04
#define FAPI_NR_UL_CONFIG_TYPES 0x04
#define FAPI_NR_END 0xff
#endif
......@@ -168,7 +168,7 @@ typedef struct {
typedef struct {
uint16_t pdu_length;
uint16_t pdu_index;
void* pdu_index;
uint8_t* pdu;
} fapi_nr_tx_request_body_t;
......@@ -390,24 +390,25 @@ typedef struct {
} fapi_nr_ul_config_srs_pdu;
typedef struct {
uint8_t pdu_type;
int pdu_type;
union {
fapi_nr_ul_config_prach_pdu prach_config_pdu;
fapi_nr_ul_config_pucch_pdu pucch_config_pdu;
nfapi_nr_ue_pusch_pdu_t pusch_config_pdu;
fapi_nr_ul_config_srs_pdu srs_config_pdu;
};
pthread_mutex_t* lock;
int* NBpdus;
} fapi_nr_ul_config_request_pdu_t;
typedef struct {
uint16_t sfn;
uint16_t slot;
uint8_t number_pdus;
fapi_nr_ul_config_request_pdu_t ul_config_list[FAPI_NR_UL_CONFIG_LIST_NUM];
int frame;
int slot;
int nb_ULpdus;
fapi_nr_ul_config_request_pdu_t ul_config_list[FAPI_NR_UL_CONFIG_LIST_NUM + 1];
pthread_mutex_t mutex_ul_config;
} fapi_nr_ul_config_request_t;
typedef struct {
uint16_t rnti;
uint16_t BWPSize;
......
......@@ -300,8 +300,6 @@ typedef enum { /* see 38.321 Table 7.1-2 RNTI usage *
#endif
typedef struct {
int nb_search_space;
uint16_t sfn;
uint16_t slot;
fapi_nr_dl_config_dci_dl_pdu_rel15_t pdcch_config[FAPI_NR_MAX_SS];
} NR_UE_PDCCH_CONFIG;
......@@ -362,7 +360,7 @@ typedef struct UE_NR_SCAN_INFO_s {
} UE_NR_SCAN_INFO_t;
/// Top-level PHY Data Structure for UE
typedef struct {
typedef struct PHY_VARS_NR_UE_s {
/// \brief Module ID indicator for this instance
uint8_t Mod_id;
/// \brief Component carrier ID for this PHY instance
......
......@@ -157,17 +157,6 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
void *typeSpecific,
uint8_t *b);
bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
NR_UE_DLSCH_t dlsch[2],
int16_t* llr[2]);
int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
NR_UE_DLSCH_t dlsch[2],
int16_t *llr[2],
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
int32_t pdcch_est_size,
......
This diff is collapsed.
......@@ -51,6 +51,6 @@ int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config);
\param synch_request including target_Nid_cell*/
void nr_ue_synch_request(nr_synch_request_t *synch_request);
void update_harq_status(module_id_t module_id, uint8_t harq_pid, uint8_t ack_nack);
void update_harq_status(NR_UE_MAC_INST_t *mac, uint8_t harq_pid, uint8_t ack_nack);
#endif
......@@ -488,7 +488,7 @@ int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue,
return(dci_cnt);
}
int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
NR_UE_DLSCH_t dlsch[2],
int16_t *llr[2],
......@@ -646,11 +646,8 @@ void send_slot_ind(notifiedFIFO_t *nf, int slot) {
}
}
bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
NR_UE_DLSCH_t dlsch[2],
int16_t* llr[2]) {
static bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, NR_UE_DLSCH_t dlsch[2], int16_t *llr[2])
{
if (dlsch[0].active == false) {
LOG_E(PHY, "DLSCH should be active when calling this function\n");
return 1;
......@@ -1029,7 +1026,6 @@ void pdsch_processing(PHY_VARS_NR_UE *ue,
time_stats_t meas = {0};
start_meas(&meas);
// do procedures for C-RNTI
int ret_pdsch = 0;
const uint32_t rxdataF_sz = ue->frame_parms.samples_per_slot_wCP;
__attribute__ ((aligned(32))) c16_t rxdataF[ue->frame_parms.nb_antennas_rx][rxdataF_sz];
......@@ -1085,11 +1081,8 @@ void pdsch_processing(PHY_VARS_NR_UE *ue,
llr[i] = (int16_t *)malloc16_clear(rx_llr_buf_sz * sizeof(int16_t));
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_C, VCD_FUNCTION_IN);
ret_pdsch = nr_ue_pdsch_procedures(ue,
proc,
dlsch,
llr,
rxdataF);
// it returns -1 in case of internal failure, or 0 in case of normal result
int ret_pdsch = nr_ue_pdsch_procedures(ue, proc, dlsch, llr, rxdataF);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_C, VCD_FUNCTION_OUT);
......@@ -1102,9 +1095,12 @@ void pdsch_processing(PHY_VARS_NR_UE *ue,
if (ret_pdsch >= 0)
nr_ue_dlsch_procedures(ue, proc, dlsch, llr);
else
else {
// don't wait anymore
send_slot_ind(ue->tx_resume_ind_fifo[(proc->nr_slot_rx + dlsch_config->k1_feedback) % ue->frame_parms.slots_per_frame], proc->nr_slot_rx);
send_slot_ind(ue->tx_resume_ind_fifo[(proc->nr_slot_rx + dlsch_config->k1_feedback) % ue->frame_parms.slots_per_frame],
proc->nr_slot_rx);
LOG_W(NR_PHY, "nr_ue_pdsch_procedures failed in slot %d\n", proc->nr_slot_rx);
}
stop_meas(&ue->dlsch_procedures_stat);
if (cpumeas(CPUMEAS_GETSTATE)) {
......
......@@ -881,24 +881,9 @@ int main(int argc, char **argv)
UE_mac->state = UE_CONNECTED;
UE_mac->ra.ra_state = RA_SUCCEEDED;
nr_dcireq_t dcireq;
nr_scheduled_response_t scheduled_response;
nr_phy_data_t phy_data = {0};
memset((void*)&dcireq,0,sizeof(dcireq));
memset((void*)&scheduled_response,0,sizeof(scheduled_response));
dcireq.module_id = 0;
dcireq.gNB_index = 0;
dcireq.cc_id = 0;
scheduled_response.dl_config = &dcireq.dl_config_req;
scheduled_response.ul_config = &dcireq.ul_config_req;
scheduled_response.tx_request = NULL;
scheduled_response.module_id = 0;
scheduled_response.CC_id = 0;
scheduled_response.frame = frame;
scheduled_response.slot = slot;
scheduled_response.phy_data = &phy_data;
fapi_nr_dl_config_request_t dl_config = {.sfn = frame, .slot = slot};
nr_scheduled_response_t scheduled_response = {.dl_config = &dl_config, .phy_data = &phy_data, .mac = UE_mac};
nr_ue_phy_config_request(&UE_mac->phy_config);
//NR_COMMON_channels_t *cc = RC.nrmac[0]->common_channels;
......@@ -984,9 +969,6 @@ int main(int argc, char **argv)
UE_proc.nr_slot_rx = slot;
UE_proc.gNB_id = 0;
dcireq.frame = frame;
dcireq.slot = slot;
NR_UE_DLSCH_t *dlsch0 = &phy_data.dlsch[0];
int harq_pid = slot;
......@@ -1121,8 +1103,9 @@ int main(int argc, char **argv)
// Apply MIMO Channel
multipath_channel(gNB2UE, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials == 1) ? 1 : 0);
add_noise(UE->common_vars.rxdata, (const double **) r_re, (const double **) r_im, sigma2, slot_length, slot_offset, ts, delay, pdu_bit_map, 0x1, frame_parms->nb_antennas_rx);
nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
dl_config.sfn = frame;
dl_config.slot = slot;
ue_dci_configuration(UE_mac, &dl_config, frame, slot);
nr_ue_scheduled_response(&scheduled_response);
pbch_pdcch_processing(UE,
......
......@@ -719,7 +719,6 @@ int main(int argc, char *argv[])
uint32_t errors_decoding = 0;
nr_scheduled_response_t scheduled_response={0};
fapi_nr_ul_config_request_t ul_config={0};
fapi_nr_tx_request_t tx_req={0};
......@@ -1074,15 +1073,9 @@ int main(int argc, char *argv[])
nr_schedule_response(Sched_INFO);
// --------- setting parameters for UE --------
scheduled_response.module_id = 0;
scheduled_response.CC_id = 0;
scheduled_response.frame = frame;
scheduled_response.slot = slot;
scheduled_response.dl_config = NULL;
scheduled_response.ul_config = &ul_config;
scheduled_response.tx_request = &tx_req;
scheduled_response.phy_data = (void *)&phy_data;
nr_scheduled_response_t scheduled_response = {.ul_config = &ul_config,
.tx_request = &tx_req,
.phy_data = (void *)&phy_data};
// Config UL TX PDU
tx_req.slot = slot;
......@@ -1094,7 +1087,7 @@ int main(int argc, char *argv[])
tx_req.tx_request_body[0].pdu = &ulsch_input_buffer[0];
ul_config.slot = slot;
ul_config.number_pdus = do_SRS == 1 ? 2 : 1;
ul_config.nb_ULpdus = do_SRS == 1 ? 2 : 1;
fapi_nr_ul_config_request_pdu_t *ul_config0 = &ul_config.ul_config_list[0];
ul_config0->pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
......
......@@ -451,7 +451,7 @@ typedef struct {
} NR_BWP_PDCCH_t;
/*!\brief Top level UE MAC structure */
typedef struct {
typedef struct NR_UE_MAC_INST_s {
NR_UE_L2_STATE_t state;
int servCellIndex;
long physCellId;
......
......@@ -215,26 +215,6 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac);
void nr_ue_ul_scheduler(nr_uplink_indication_t *ul_info);
void nr_ue_dl_scheduler(nr_downlink_indication_t *dl_info);
/**\brief fill nr_scheduled_response struct instance
@param nr_scheduled_response_t * pointer to scheduled_response instance to fill
@param fapi_nr_dl_config_request_t* pointer to dl_config,
@param fapi_nr_ul_config_request_t* pointer to ul_config,
@param fapi_nr_tx_request_t* pointer to tx_request;
@param module_id_t mod_id module ID
@param int cc_id CC ID
@param frame_t frame frame number
@param int slot reference number
@param void *phy_pata pointer to a PHY specific structure to be filled in the scheduler response (can be null) */
void fill_scheduled_response(nr_scheduled_response_t *scheduled_response,
fapi_nr_dl_config_request_t *dl_config,
fapi_nr_ul_config_request_t *ul_config,
fapi_nr_tx_request_t *tx_request,
module_id_t mod_id,
int cc_id,
frame_t frame,
int slot,
void *phy_data);
/*! \fn int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slotP);
\brief Called by PHY to get sdu for PUSCH transmission. It performs the following operations: Checks BSR for DCCH, DCCH1 and
DTCH corresponding to previous values computed either in SR or BSR procedures. It gets rlc status indications on DCCH,DCCH1 and
......@@ -435,20 +415,6 @@ void nr_ue_msg3_scheduler(NR_UE_MAC_INST_t *mac,
sub_frame_t current_slot,
uint8_t Msg3_tda_id);
/* \brief Function called by PHY to process the received RAR and check that the preamble matches what was sent by the gNB. It provides the timing advance and t-CRNTI.
@param Mod_id Index of UE instance
@param CC_id Index to a component carrier
@param frame Frame index
@param ra_rnti RA_RNTI value
@param dlsch_buffer Pointer to dlsch_buffer containing RAR PDU
@param t_crnti Pointer to PHY variable containing the T_CRNTI
@param preamble_index Preamble Index used by PHY to transmit the PRACH. This should match the received RAR to trigger the rest of
random-access procedure
@param selected_rar_buffer the output buffer for storing the selected RAR header and RAR payload
@returns timing advance or 0xffff if preamble doesn't match
*/
int nr_ue_process_rar(nr_downlink_indication_t *dl_info, int pdu_id);
void nr_ue_contention_resolution(module_id_t module_id, int cc_id, frame_t frame, int slot, NR_PRACH_RESOURCES_t *prach_resources);
void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_resources, frame_t frame, int slot);
......@@ -468,11 +434,7 @@ andom-access to transmit a BSR along with the C-RNTI control element (see 5.1.4
@param gNB_id gNB index
@param nr_slot_tx slot for PRACH transmission
@returns indication to generate PRACH to phy */
uint8_t nr_ue_get_rach(module_id_t mod_id,
int CC_id,
frame_t frame,
uint8_t gNB_id,
int nr_slot_tx);
uint8_t nr_ue_get_rach(module_id_t mod_id, int CC_id, frame_t frame, uint8_t gNB_id, int nr_slot_tx, uint8_t payload[16]);
/* \brief Function implementing the routine for the selection of Random Access resources (5.1.2 TS 38.321).
@param module_idP Index of UE instance
......@@ -502,7 +464,7 @@ void set_ra_rnti(NR_UE_MAC_INST_t *mac, fapi_nr_ul_config_prach_pdu *prach_pdu);
void nr_Msg1_transmitted(module_id_t mod_id);
void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, slot_t slotP, uint8_t gNB_id);
void nr_get_msg3_payload(module_id_t mod_id);
void nr_get_msg3_payload(module_id_t mod_id, uint8_t *pdu);
void send_msg3_rrc_request(module_id_t mod_id, int rnti);
void nr_ue_msg2_scheduler(module_id_t mod_id, uint16_t rach_frame, uint16_t rach_slot, uint16_t *msg2_frame, uint16_t *msg2_slot);
......@@ -517,10 +479,12 @@ void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac);
void ue_init_config_request(NR_UE_MAC_INST_t *mac, int scs);
fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot, int fb_time);
fapi_nr_dl_config_request_t *get_dl_config_request(NR_UE_MAC_INST_t *mac, int slot);
void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type);
fapi_nr_ul_config_request_pdu_t *lockGet_ul_config(NR_UE_MAC_INST_t *mac, frame_t frame_tx, int slot_tx, uint8_t pdu_type);
fapi_nr_ul_config_request_pdu_t *fapiLockIterator(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx);
void release_ul_config(fapi_nr_ul_config_request_pdu_t *pdu, bool clearIt);
int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm);
......@@ -530,7 +494,13 @@ int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm);
// - in which ULSCH should be scheduled. K2 is configured in RRC configuration.
// PUSCH Msg3 scheduler:
// - scheduled by RAR UL grant according to 8.3 of TS 38.213
int nr_ue_pusch_scheduler(NR_UE_MAC_INST_t *mac, uint8_t is_Msg3, frame_t current_frame, int current_slot, frame_t *frame_tx, int *slot_tx, long k2);
int nr_ue_pusch_scheduler(const NR_UE_MAC_INST_t *mac,
const uint8_t is_Msg3,
const frame_t current_frame,
const int current_slot,
frame_t *frame_tx,
int *slot_tx,
const long k2);
int get_rnti_type(NR_UE_MAC_INST_t *mac, uint16_t rnti);
......
......@@ -608,15 +608,24 @@ void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, slot
ra->ra_state = WAIT_CONTENTION_RESOLUTION;
}
void nr_get_msg3_payload(module_id_t mod_id)
void nr_get_msg3_payload(module_id_t mod_id, uint8_t *pdu)
{
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
RA_config_t *ra = &mac->ra;
uint8_t *pdu = mac->CCCH_pdu.payload;
const uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_FIXED);
NR_MAC_SUBHEADER_FIXED *header = (NR_MAC_SUBHEADER_FIXED *) pdu;
pdu += sh_size;
int lcid = 0; // SRB0 for messages sent in MSG3
// dirty fix for a race condition
// RRC thread populates this rlc buffer
// no mechanism ensure synchronization
// so we wait here RRC thread before reading the SDU
mac_rlc_status_resp_t tmp;
do {
tmp = mac_rlc_status_ind(mod_id, ra->t_crnti, 0, 0, 0, ENB_FLAG_NO, MBMS_FLAG_NO, lcid, 0, 0);
if (!tmp.bytes_in_buffer)
usleep(100);
} while (!tmp.bytes_in_buffer);
tbs_size_t len = mac_rlc_data_req(mod_id,
ra->t_crnti,
0,
......@@ -667,11 +676,7 @@ void nr_get_msg3_payload(module_id_t mod_id)
* @gNB_id gNB ID
* @nr_slot_tx current UL TX slot
*/
uint8_t nr_ue_get_rach(module_id_t mod_id,
int CC_id,
frame_t frame,
uint8_t gNB_id,
int nr_slot_tx)
uint8_t nr_ue_get_rach(module_id_t mod_id, int CC_id, frame_t frame, uint8_t gNB_id, int nr_slot_tx, uint8_t payload[16])
{
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
RA_config_t *ra = &mac->ra;
......@@ -708,9 +713,7 @@ uint8_t nr_ue_get_rach(module_id_t mod_id,
const uint8_t TBS_max = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); // Note: unclear the reason behind the selection of such TBS_max
int size_sdu = 0;
uint8_t mac_ce[16] = {0};
uint8_t *pdu = get_softmodem_params()->sa ? mac->CCCH_pdu.payload : mac_ce;
uint8_t *payload = pdu;
uint8_t *pdu = payload;
// Concerning the C-RNTI MAC CE, it has to be included if the UL transmission (Msg3) is not being made for the CCCH logical channel.
// Therefore it has been assumed that this event only occurs only when RA is done and it is not SA mode.
......@@ -957,19 +960,12 @@ void prepare_msg4_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack)
NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[pid];
int sched_slot = current_harq->ul_slot;
int sched_frame = current_harq->ul_frame;
fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, sched_slot, 0);
pthread_mutex_lock(&ul_config->mutex_ul_config);
mac->nr_ue_emul_l1.num_harqs = 1;
AssertFatal(ul_config->number_pdus < FAPI_NR_UL_CONFIG_LIST_NUM,
"ul_config->number_pdus %d out of bounds\n",
ul_config->number_pdus);
fapi_nr_ul_config_pucch_pdu *pucch_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu;
PUCCH_sched_t pucch = {0};
pucch.n_CCE = current_harq->n_CCE;
pucch.N_CCE = current_harq->N_CCE;
pucch.delta_pucch = current_harq->delta_pucch;
pucch.ack_payload = ack_nack;
pucch.n_harq = 1;
PUCCH_sched_t pucch = {.n_CCE = current_harq->n_CCE,
.N_CCE = current_harq->N_CCE,
.delta_pucch = current_harq->delta_pucch,
.ack_payload = ack_nack,
.n_harq = 1};
current_harq->active = false;
current_harq->ack_received = false;
if (get_softmodem_params()->emulate_l1) {
......@@ -977,11 +973,9 @@ void prepare_msg4_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack)
mac->nr_ue_emul_l1.harq[pid].active_dl_harq_sfn = sched_frame;
mac->nr_ue_emul_l1.harq[pid].active_dl_harq_slot = sched_slot;
}
nr_ue_configure_pucch(mac,
sched_slot,
mac->ra.t_crnti,
&pucch,
pucch_pdu);
fill_ul_config(ul_config, sched_frame, sched_slot, FAPI_NR_UL_CONFIG_TYPE_PUCCH);
pthread_mutex_unlock(&ul_config->mutex_ul_config);
fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, sched_frame, sched_slot, FAPI_NR_UL_CONFIG_TYPE_PUCCH);
if (!pdu)
return;
nr_ue_configure_pucch(mac, sched_slot, mac->ra.t_crnti, &pucch, &pdu->pucch_config_pdu);
release_ul_config(pdu, false);
}
......@@ -89,6 +89,21 @@ static const int sequence_cyclic_shift_2_harq_ack_bits[4]
/* HARQ-ACK Value (0,0) (0,1) (1,0) (1,1) */
/* Sequence cyclic shift */ = { 0, 3, 9, 6 };
/* \brief Function called by PHY to process the received RAR and check that the preamble matches what was sent by the gNB. It
provides the timing advance and t-CRNTI.
@param Mod_id Index of UE instance
@param CC_id Index to a component carrier
@param frame Frame index
@param ra_rnti RA_RNTI value
@param dlsch_buffer Pointer to dlsch_buffer containing RAR PDU
@param t_crnti Pointer to PHY variable containing the T_CRNTI
@param preamble_index Preamble Index used by PHY to transmit the PRACH. This should match the received RAR to trigger the rest of
random-access procedure
@param selected_rar_buffer the output buffer for storing the selected RAR header and RAR payload
@returns timing advance or 0xffff if preamble doesn't match
*/
static int nr_ue_process_rar(nr_downlink_indication_t *dl_info, int pdu_id);
int get_pucch0_mcs(const int O_ACK, const int O_SR, const int ack_payload, const int sr_payload)
{
int mcs = 0;
......@@ -393,25 +408,13 @@ static int nr_ue_process_dci_ul_00(module_id_t module_id,
return -1;
}
// Get UL config request corresponding slot_tx
fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx, tda_info.k2);
if (!ul_config) {
LOG_W(MAC, "ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n", frame, slot);
return -1;
}
pthread_mutex_lock(&ul_config->mutex_ul_config);
AssertFatal(ul_config->number_pdus < FAPI_NR_UL_CONFIG_LIST_NUM,
"ul_config->number_pdus %d out of bounds\n",
ul_config->number_pdus);
nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu;
fill_ul_config(ul_config, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH);
pthread_mutex_unlock(&ul_config->mutex_ul_config);
fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH);
if (!pdu)
return 0;
// Config PUSCH PDU
return nr_config_pusch_pdu(mac, &tda_info, pusch_config_pdu, dci, NULL, dci_ind->rnti, NR_UL_DCI_FORMAT_0_0);
int ret = nr_config_pusch_pdu(mac, &tda_info, &pdu->pusch_config_pdu, dci, NULL, dci_ind->rnti, NR_UL_DCI_FORMAT_0_0);
release_ul_config(pdu, false);
return ret;
}
static int nr_ue_process_dci_ul_01(module_id_t module_id,
......@@ -478,26 +481,12 @@ static int nr_ue_process_dci_ul_01(module_id_t module_id,
return -1;
}
// Get UL config request corresponding slot_tx
fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx, tda_info.k2);
if (!ul_config) {
LOG_W(MAC, "ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n", frame, slot);
return -1;
}
ul_config->number_pdus = 0;
pthread_mutex_lock(&ul_config->mutex_ul_config);
AssertFatal(ul_config->number_pdus < FAPI_NR_UL_CONFIG_LIST_NUM,
"ul_config->number_pdus %d out of bounds\n",
ul_config->number_pdus);
nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu;
fill_ul_config(ul_config, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH);
pthread_mutex_unlock(&ul_config->mutex_ul_config);
// Config PUSCH PDU
return nr_config_pusch_pdu(mac, &tda_info, pusch_config_pdu, dci, NULL, dci_ind->rnti, NR_UL_DCI_FORMAT_0_1);
fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH);
if (!pdu)
return 0;
int ret = nr_config_pusch_pdu(mac, &tda_info, &pdu->pusch_config_pdu, dci, NULL, dci_ind->rnti, NR_UL_DCI_FORMAT_0_1);
release_ul_config(pdu, false);
return ret;
}
static int nr_ue_process_dci_dl_10(module_id_t module_id,
......@@ -3950,7 +3939,7 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce,
// - b buffer
// - ulsch power offset
// - optimize: mu_pusch, j and table_6_1_2_1_1_2_time_dom_res_alloc_A are already defined in nr_ue_procedures
int nr_ue_process_rar(nr_downlink_indication_t *dl_info, int pdu_id)
static int nr_ue_process_rar(nr_downlink_indication_t *dl_info, int pdu_id)
{
module_id_t mod_id = dl_info->module_id;
frame_t frame = dl_info->frame;
......@@ -4027,7 +4016,6 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, int pdu_id)
#endif
if (ra->RA_RAPID_found) {
RAR_grant_t rar_grant;
unsigned char tpc_command;
......@@ -4131,33 +4119,19 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, int pdu_id)
ret = nr_ue_pusch_scheduler(mac, is_Msg3, frame, slot, &frame_tx, &slot_tx, tda_info.k2);
if (ret != -1) {
fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx, tda_info.k2);
uint16_t rnti = mac->crnti;
if (!ul_config) {
LOG_W(MAC, "In %s: ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n", __FUNCTION__, frame, slot);
return -1;
}
AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]),
"Number of PDUS in ul_config = %d > ul_config_list num elements", ul_config->number_pdus);
// Upon successful reception, set the T-CRNTI to the RAR value if the RA preamble is selected among the contention-based RA Preambles
if (!ra->cfra) {
ra->t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8);
rnti = ra->t_crnti;
send_msg3_rrc_request(mod_id, rnti);
}
pthread_mutex_lock(&ul_config->mutex_ul_config);
AssertFatal(ul_config->number_pdus<FAPI_NR_UL_CONFIG_LIST_NUM, "ul_config->number_pdus %d out of bounds\n",ul_config->number_pdus);
nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu;
fill_ul_config(ul_config, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH);
pthread_mutex_unlock(&ul_config->mutex_ul_config);
fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH);
if (!pdu)
return -1;
// Config Msg3 PDU
nr_config_pusch_pdu(mac, &tda_info, pusch_config_pdu, NULL, &rar_grant, rnti, NR_DCI_NONE);
nr_config_pusch_pdu(mac, &tda_info, &pdu->pusch_config_pdu, NULL, &rar_grant, rnti, NR_DCI_NONE);
release_ul_config(pdu, false);
}
} else {
......
This diff is collapsed.
This diff is collapsed.
......@@ -46,22 +46,6 @@ extern slot_rnti_mcs_s slot_rnti_mcs[NUM_NFAPI_SLOT];
typedef struct NR_UL_TIME_ALIGNMENT NR_UL_TIME_ALIGNMENT_t;
typedef struct {
/// module id
module_id_t module_id;
/// gNB index
uint32_t gNB_index;
/// component carrier id
int cc_id;
/// frame
frame_t frame;
/// slot
int slot;
fapi_nr_dl_config_request_t dl_config_req;
fapi_nr_ul_config_request_t ul_config_req;
} nr_dcireq_t;
typedef struct {
/// module id
module_id_t module_id;
......@@ -95,14 +79,10 @@ typedef struct {
uint32_t gNB_index;
/// component carrier id
int cc_id;
/// frame
frame_t frame_rx;
/// slot rx
uint32_t slot_rx;
/// frame tx
frame_t frame_tx;
frame_t frame;
/// slot tx
uint32_t slot_tx;
uint32_t slot;
/// dci reception indication structure
fapi_nr_dci_indication_t *dci_ind;
......@@ -142,17 +122,9 @@ typedef struct {
// Downlink subframe P7
struct PHY_VARS_NR_UE_s;
struct NR_UE_MAC_INST_s;
typedef struct {
/// module id
module_id_t module_id;
/// component carrier id
int CC_id;
/// frame
frame_t frame;
/// slot
int slot;
/// NR UE FAPI-like P7 message, direction: L2 to L1
/// downlink transmission configuration request structure
fapi_nr_dl_config_request_t *dl_config;
......@@ -169,9 +141,12 @@ typedef struct {
/// data transmission request structure
fapi_nr_tx_request_t *tx_request;
module_id_t module;
int carrier;
/// PHY data structure initially passed on to L2 via the nr_downlink_indication_t and
/// returned to L1 via nr_scheduled_response_t
void *phy_data;
struct NR_UE_MAC_INST_s *mac;
} nr_scheduled_response_t;
typedef struct {
......@@ -322,46 +297,11 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request,
bool sfn_slot_matcher(void *wanted, void *candidate);
/**\brief done free of memory allocation by module_id and release to pointer pool.
\param module_id module id*/
int nr_ue_if_module_kill(uint32_t module_id);
/**\brief interface between L1/L2, indicating the downlink related information, like dci_ind and rx_req
\param dl_info including dci_ind and rx_request messages*/
int nr_ue_dl_indication(nr_downlink_indication_t *dl_info);
int nr_ue_ul_indication(nr_uplink_indication_t *ul_info);
int nr_ue_dcireq(nr_dcireq_t *dcireq);
// TODO check
/**\brief handle BCCH-BCH message from dl_indication
\param phy_data PHY structure to be filled in by the callee in the FAPI call (L1 caller -> indication to L2 -> FAPI call to L1 callee)
\param pduP pointer to bch pdu
\param additional_bits corresponding to 38.212 ch.7
\param ssb_index SSB index within 0 - (L_ssb-1) corresponding to 38.331 ch.13 parameter i
\param ssb_length corresponding to L1 parameter L_ssb
\param cell_id cell id */
int handle_bcch_bch(module_id_t module_id,
int cc_id,
unsigned int gNB_index,
void *phy_data,
uint8_t *pduP,
unsigned int additional_bits,
uint32_t ssb_index,
uint32_t ssb_length,
uint16_t ssb_start_subcarrier,
uint16_t cell_id);
// TODO check
/**\brief handle BCCH-DL-SCH message from dl_indication
\param pdu_len length(bytes) of pdu
\param pduP pointer to pdu*/
int handle_bcch_dlsch(module_id_t module_id, int cc_id, unsigned int gNB_index, uint8_t ack_nack, uint8_t *pduP, uint32_t pdu_len);
int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci);
#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