clearing old structures and functions for rach occasions
This commit is contained in:
@@ -48,7 +48,6 @@
|
||||
static void build_ssb_list(NR_UE_MAC_INST_t *mac)
|
||||
{
|
||||
// Create the list of transmitted SSBs
|
||||
free(mac->ssb_list.tx_ssb);
|
||||
memset(&mac->ssb_list, 0, sizeof(ssb_list_info_t));
|
||||
ssb_list_info_t *ssb_list = &mac->ssb_list;
|
||||
fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
|
||||
@@ -63,7 +62,6 @@ static void build_ssb_list(NR_UE_MAC_INST_t *mac)
|
||||
} else
|
||||
ssb_list->nb_ssb_per_index[ssb_index] = -1;
|
||||
}
|
||||
ssb_list->tx_ssb = calloc(ssb_list->nb_tx_ssb, sizeof(*ssb_list->tx_ssb));
|
||||
}
|
||||
|
||||
static void set_tdd_config_nr_ue(fapi_nr_tdd_table_t *tdd_table, const frame_structure_t *fs)
|
||||
@@ -1789,9 +1787,6 @@ void nr_rrc_mac_config_req_sib1(module_id_t module_id, int cc_idP, NR_SIB1_t *si
|
||||
if (mac->state == UE_RECEIVING_SIB && can_start_ra)
|
||||
mac->state = UE_PERFORMING_RA;
|
||||
|
||||
// Setup the SSB to Rach Occasions mapping according to the config
|
||||
build_ssb_to_ro_map(mac);
|
||||
|
||||
if (!get_softmodem_params()->emulate_l1)
|
||||
mac->if_module->phy_config_request(&mac->phy_config);
|
||||
ret = pthread_mutex_unlock(&mac->if_mutex);
|
||||
@@ -2651,11 +2646,6 @@ void nr_rrc_mac_config_req_cg(module_id_t module_id,
|
||||
if (ue_Capability)
|
||||
handle_mac_uecap_info(mac, ue_Capability);
|
||||
|
||||
// Setup the SSB to Rach Occasions mapping according to the config
|
||||
// Only if RACH is configured for current BWP
|
||||
if (mac->current_UL_BWP->rach_ConfigCommon)
|
||||
build_ssb_to_ro_map(mac);
|
||||
|
||||
if (!mac->dl_config_request || !mac->ul_config_request)
|
||||
ue_init_config_request(mac, mac->frame_structure.numb_slots_frame);
|
||||
ret = pthread_mutex_unlock(&mac->if_mutex);
|
||||
|
||||
@@ -79,23 +79,7 @@
|
||||
/*!\brief value for indicating BSR Timer is not running */
|
||||
#define NR_MAC_UE_BSR_TIMER_NOT_RUNNING (0xFFFF)
|
||||
|
||||
// ================================================
|
||||
// SSB to RO mapping private defines and structures
|
||||
// ================================================
|
||||
|
||||
#define MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PERIOD (16) // Maximum association period is 16
|
||||
#define MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD (16) // Max association pattern period is 160ms and minimum PRACH configuration period is 10ms
|
||||
#define MAX_NB_ASSOCIATION_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD (16) // Max nb of association periods in an association pattern period of 160ms
|
||||
#define MAX_NB_FRAME_IN_PRACH_CONF_PERIOD (16) // Max PRACH configuration period is 160ms and frame is 10ms
|
||||
#define MAX_NB_SLOT_IN_FRAME (160) // Max number of slots in a frame (@ SCS 240kHz = 160)
|
||||
#define MAX_NB_FRAME_IN_ASSOCIATION_PATTERN_PERIOD (16) // Maximum number of frames in the maximum association pattern period
|
||||
#define MAX_NB_SSB (64) // Maximum number of possible SSB indexes
|
||||
#define MAX_RO_PER_SSB (8) // Maximum number of consecutive ROs that can be mapped to an SSB according to the ssb_per_RACH config
|
||||
|
||||
// Maximum number of ROs that can be mapped to an SSB in an association pattern
|
||||
// This is to reserve enough elements in the SSBs list for each mapped ROs for a single SSB
|
||||
// An arbitrary maximum number is chosen to be safe: maximum number of slots in an association pattern * maximum number of ROs in a slot
|
||||
#define MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN (MAX_TDM*MAX_FDM*MAX_NB_SLOT_IN_FRAME*MAX_NB_FRAME_IN_ASSOCIATION_PATTERN_PERIOD)
|
||||
|
||||
// ===============
|
||||
// DCI fields defs
|
||||
@@ -181,22 +165,11 @@ typedef struct prach_occasion_info {
|
||||
int start_symbol; // 0 - 13 (14 symbols in a slot)
|
||||
int fdm; // 0-7 (possible values of msg1-FDM: 1, 2, 4 or 8)
|
||||
int slot;
|
||||
int frame; // 0 - 15 (maximum number of frames in a 160ms association pattern)
|
||||
uint8_t mapped_ssb_idx[MAX_SSB_PER_RO]; // List of mapped SSBs
|
||||
uint8_t nb_mapped_ssb;
|
||||
int format; // RO preamble format
|
||||
int frame_info[2];
|
||||
int association_period_idx;
|
||||
} prach_occasion_info_t;
|
||||
|
||||
// PRACH occasion slot details
|
||||
// A PRACH occasion slot is a series of PRACH occasions in time (symbols) and frequency
|
||||
typedef struct prach_occasion_slot {
|
||||
prach_occasion_info_t *prach_occasion; // Starting symbol of each PRACH occasions in a slot
|
||||
uint8_t nb_of_prach_occasion_in_time;
|
||||
uint8_t nb_of_prach_occasion_in_freq;
|
||||
} prach_occasion_slot_t;
|
||||
|
||||
typedef enum {
|
||||
phr_cause_prohibit_timer = 0,
|
||||
phr_cause_periodic_timer,
|
||||
@@ -471,39 +444,8 @@ typedef struct NR_UL_TIME_ALIGNMENT {
|
||||
int slot;
|
||||
} NR_UL_TIME_ALIGNMENT_t;
|
||||
|
||||
// The PRACH Config period is a series of selected slots in one or multiple frames
|
||||
typedef struct prach_conf_period {
|
||||
prach_occasion_slot_t prach_occasion_slot_map[MAX_NB_FRAME_IN_PRACH_CONF_PERIOD][MAX_NB_SLOT_IN_FRAME];
|
||||
uint16_t nb_of_prach_occasion; // Total number of PRACH occasions in the PRACH Config period
|
||||
uint8_t nb_of_frame; // Size of the PRACH Config period in number of 10ms frames
|
||||
uint8_t nb_of_slot; // Nb of slots in each frame
|
||||
} prach_conf_period_t;
|
||||
|
||||
// The association period is a series of PRACH Config periods
|
||||
typedef struct prach_association_period {
|
||||
prach_conf_period_t *prach_conf_period_list[MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PERIOD];
|
||||
uint8_t nb_of_prach_conf_period; // Nb of PRACH configuration periods within the association period
|
||||
uint8_t nb_of_frame; // Total number of frames included in the association period
|
||||
} prach_association_period_t;
|
||||
|
||||
// The association pattern is a series of Association periods
|
||||
typedef struct prach_association_pattern {
|
||||
prach_association_period_t prach_association_period_list[MAX_NB_ASSOCIATION_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD];
|
||||
prach_conf_period_t prach_conf_period_list[MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD];
|
||||
uint8_t nb_of_assoc_period; // Nb of association periods within the association pattern
|
||||
uint8_t nb_of_prach_conf_period_in_max_period; // Nb of PRACH configuration periods within the maximum association pattern period (according to the size of the configured PRACH
|
||||
uint8_t nb_of_frame; // Total number of frames included in the association pattern period (after mapping the SSBs and determining the real association pattern length)
|
||||
} prach_association_pattern_t;
|
||||
|
||||
// SSB details
|
||||
typedef struct ssb_info {
|
||||
prach_occasion_info_t *mapped_ro[MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN]; // List of mapped RACH Occasions to this SSB index
|
||||
uint32_t nb_mapped_ro; // Total number of mapped ROs to this SSB index
|
||||
} ssb_info_t;
|
||||
|
||||
// List of all the possible SSBs and their details
|
||||
typedef struct ssb_list_info {
|
||||
ssb_info_t *tx_ssb;
|
||||
int nb_tx_ssb;
|
||||
int nb_ssb_per_index[MAX_NB_SSB];
|
||||
} ssb_list_info_t;
|
||||
@@ -614,7 +556,6 @@ typedef struct NR_UE_MAC_INST_s {
|
||||
|
||||
si_schedInfo_t si_SchedInfo;
|
||||
ssb_list_info_t ssb_list;
|
||||
prach_association_pattern_t prach_assoc_pattern[MAX_NUM_BWP_UE];
|
||||
|
||||
NR_UE_ServingCell_Info_t sc_info;
|
||||
A_SEQUENCE_OF(NR_UE_DL_BWP_t) dl_BWPs;
|
||||
|
||||
@@ -335,7 +335,6 @@ void nr_ue_send_synch_request(NR_UE_MAC_INST_t *mac, module_id_t module_id, int
|
||||
NR_UE_L2_STATE_t nr_ue_get_sync_state(module_id_t mod_id);
|
||||
|
||||
int16_t get_prach_tx_power(NR_UE_MAC_INST_t *mac);
|
||||
void free_rach_structures(NR_UE_MAC_INST_t *nr_mac, int bwp_id);
|
||||
void schedule_RA_after_SR_failure(NR_UE_MAC_INST_t *mac);
|
||||
void nr_Msg1_transmitted(NR_UE_MAC_INST_t *mac);
|
||||
void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac, uint8_t CC_id, frame_t frameP, slot_t slotP, uint8_t gNB_id);
|
||||
@@ -350,9 +349,7 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *p
|
||||
int start_DLBWP,
|
||||
dci_field_t frequency_domain_assignment);
|
||||
|
||||
void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac);
|
||||
|
||||
void ue_init_config_request(NR_UE_MAC_INST_t *mac, int slots_per_frame);
|
||||
void ue_init_config_request(NR_UE_MAC_INST_t *mac, int scs);
|
||||
|
||||
fapi_nr_dl_config_request_t *get_dl_config_request(NR_UE_MAC_INST_t *mac, int slot);
|
||||
|
||||
|
||||
@@ -78,7 +78,6 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac)
|
||||
memset(&mac->ssb_measurements, 0, sizeof(mac->ssb_measurements));
|
||||
memset(&mac->ul_time_alignment, 0, sizeof(mac->ul_time_alignment));
|
||||
memset(&mac->ssb_list, 0, sizeof(mac->ssb_list));
|
||||
memset(mac->prach_assoc_pattern, 0, sizeof(mac->prach_assoc_pattern));
|
||||
|
||||
for (int i = 0; i < NR_MAX_SR_ID; i++)
|
||||
memset(&mac->scheduling_info.sr_info[i], 0, sizeof(mac->scheduling_info.sr_info[i]));
|
||||
|
||||
@@ -1333,14 +1333,6 @@ void prepare_msg4_msgb_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack)
|
||||
release_ul_config(pdu, false);
|
||||
}
|
||||
|
||||
void free_rach_structures(NR_UE_MAC_INST_t *nr_mac, int bwp_id)
|
||||
{
|
||||
for (int j = 0; j < MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD; j++)
|
||||
for (int k = 0; k < MAX_NB_FRAME_IN_PRACH_CONF_PERIOD; k++)
|
||||
for (int l = 0; l < MAX_NB_SLOT_IN_FRAME; l++)
|
||||
free(nr_mac->prach_assoc_pattern[bwp_id].prach_conf_period_list[j].prach_occasion_slot_map[k][l].prach_occasion);
|
||||
}
|
||||
|
||||
void reset_ra(NR_UE_MAC_INST_t *nr_mac, bool free_prach)
|
||||
{
|
||||
RA_config_t *ra = &nr_mac->ra;
|
||||
@@ -1350,7 +1342,4 @@ void reset_ra(NR_UE_MAC_INST_t *nr_mac, bool free_prach)
|
||||
|
||||
if (!free_prach)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < MAX_NUM_BWP_UE; i++)
|
||||
free_rach_structures(nr_mac, i);
|
||||
}
|
||||
|
||||
@@ -1561,403 +1561,6 @@ int nr_ue_pusch_scheduler(const NR_UE_MAC_INST_t *mac,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Build the list of all the valid RACH occasions in the maximum association pattern period according to the PRACH config
|
||||
static void build_ro_list(NR_UE_MAC_INST_t *mac)
|
||||
{
|
||||
int y2; // PRACH Configuration Index table additional variable used to compute the valid frame numbers
|
||||
uint8_t slot_shift_for_map;
|
||||
uint8_t map_shift;
|
||||
bool even_slot_invalid;
|
||||
int nb_fdm;
|
||||
|
||||
uint8_t config_index;
|
||||
int msg1_FDM;
|
||||
|
||||
uint8_t nb_of_frames_per_prach_conf_period;
|
||||
|
||||
NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon;
|
||||
NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
|
||||
|
||||
config_index = rach_ConfigGeneric->prach_ConfigurationIndex;
|
||||
msg1_FDM = rach_ConfigGeneric->msg1_FDM;
|
||||
|
||||
switch (msg1_FDM){
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
nb_fdm = 1 << msg1_FDM;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1 == 0, "Unknown msg1_FDM from rach_ConfigGeneric %d\n", msg1_FDM);
|
||||
}
|
||||
|
||||
// Create the PRACH occasions map
|
||||
// WIP: For now assume no rejected PRACH occasions because of conflict with SSB or TDD_UL_DL_ConfigurationCommon schedule
|
||||
|
||||
int unpaired = mac->phy_config.config_req.cell_config.frame_duplex_type;
|
||||
|
||||
const int ul_mu = mac->current_UL_BWP->scs;
|
||||
const int mu = nr_get_prach_or_ul_mu(mac->current_UL_BWP->msgA_ConfigCommon_r16, setup, ul_mu);
|
||||
nr_prach_info_t prach_config = get_nr_prach_occasion_info_from_index(config_index, mac->frequency_range, unpaired);
|
||||
|
||||
// Identify the proper PRACH Configuration Index table according to the operating frequency
|
||||
LOG_D(NR_MAC,"mu = %u, PRACH config index = %u, unpaired = %u\n", mu, config_index, unpaired);
|
||||
|
||||
if (mac->frequency_range == FR2) { //FR2
|
||||
y2 = prach_config.y2;
|
||||
slot_shift_for_map = mu-2;
|
||||
if ((mu == 3) && (prach_config.N_RA_slot == 1))
|
||||
even_slot_invalid = true;
|
||||
else
|
||||
even_slot_invalid = false;
|
||||
}
|
||||
else { // FR1
|
||||
y2 = prach_config.y;
|
||||
slot_shift_for_map = mu;
|
||||
if ((mu == 1) && (prach_config.N_RA_slot == 1) && ((prach_config.format & 0xff) > 3))
|
||||
// no prach in even slots @ 30kHz for 1 prach per subframe
|
||||
even_slot_invalid = true;
|
||||
else
|
||||
even_slot_invalid = false;
|
||||
} // FR1
|
||||
|
||||
const int bwp_id = mac->current_UL_BWP->bwp_id;
|
||||
prach_association_pattern_t *prach_assoc_pattern = &mac->prach_assoc_pattern[bwp_id];
|
||||
prach_assoc_pattern->nb_of_prach_conf_period_in_max_period = MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD / prach_config.x;
|
||||
nb_of_frames_per_prach_conf_period = prach_config.x;
|
||||
int slots_per_frame = mac->frame_structure.numb_slots_frame;
|
||||
LOG_D(NR_MAC,"nb_of_prach_conf_period_in_max_period %d\n", prach_assoc_pattern->nb_of_prach_conf_period_in_max_period);
|
||||
|
||||
// Fill in the PRACH occasions table for every slot in every frame in every PRACH configuration periods in the maximum association pattern period
|
||||
// ----------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// For every PRACH configuration periods
|
||||
// -------------------------------------
|
||||
for (int period_idx = 0; period_idx < prach_assoc_pattern->nb_of_prach_conf_period_in_max_period; period_idx++) {
|
||||
prach_conf_period_t *prach_conf_period_list = &prach_assoc_pattern->prach_conf_period_list[period_idx];
|
||||
prach_conf_period_list->nb_of_prach_occasion = 0;
|
||||
prach_conf_period_list->nb_of_frame = nb_of_frames_per_prach_conf_period;
|
||||
prach_conf_period_list->nb_of_slot = slots_per_frame;
|
||||
|
||||
LOG_D(NR_MAC,"PRACH Conf Period Idx %d\n", period_idx);
|
||||
|
||||
// For every frames in a PRACH configuration period
|
||||
// ------------------------------------------------
|
||||
for (int frame_idx = 0; frame_idx < nb_of_frames_per_prach_conf_period; frame_idx++) {
|
||||
int frame_rach = (period_idx * nb_of_frames_per_prach_conf_period) + frame_idx;
|
||||
|
||||
LOG_D(NR_MAC,"PRACH Conf Period Frame Idx %d - Frame %d\n", frame_idx, frame_rach);
|
||||
// Is it a valid frame for this PRACH configuration index? (n_sfn mod x = y)
|
||||
if ((frame_rach % prach_config.x) == prach_config.y || (frame_rach % prach_config.x) == y2) {
|
||||
|
||||
// For every slot in a frame
|
||||
// -------------------------
|
||||
for (int slot = 0; slot < slots_per_frame; slot++) {
|
||||
// Is it a valid slot?
|
||||
map_shift = slot >> slot_shift_for_map; // in PRACH configuration index table slots are numbered wrt 60kHz
|
||||
if ((prach_config.s_map >> map_shift) & 0x01) {
|
||||
// Valid slot
|
||||
|
||||
// Additionally, for 30kHz/120kHz, we must check for the n_RA_Slot param also
|
||||
if (even_slot_invalid && (slot%2 == 0))
|
||||
continue; // no prach in even slots @ 30kHz/120kHz for 1 prach per 60khz slot/subframe
|
||||
|
||||
// We're good: valid frame and valid slot
|
||||
// Compute all the PRACH occasions in the slot
|
||||
|
||||
prach_occasion_slot_t *slot_map = &prach_conf_period_list->prach_occasion_slot_map[frame_idx][slot];
|
||||
slot_map->nb_of_prach_occasion_in_time = prach_config.N_t_slot;
|
||||
slot_map->nb_of_prach_occasion_in_freq = nb_fdm;
|
||||
slot_map->prach_occasion = malloc(prach_config.N_t_slot * nb_fdm * sizeof(*slot_map->prach_occasion));
|
||||
AssertFatal(slot_map->prach_occasion, "no memory available\n");
|
||||
for (int n_prach_occ_in_time = 0; n_prach_occ_in_time < prach_config.N_t_slot; n_prach_occ_in_time++) {
|
||||
uint8_t start_symbol = prach_config.start_symbol + n_prach_occ_in_time * prach_config.N_dur;
|
||||
LOG_D(NR_MAC,"PRACH Occ in time %d\n", n_prach_occ_in_time);
|
||||
|
||||
for (int n_prach_occ_in_freq = 0; n_prach_occ_in_freq < nb_fdm; n_prach_occ_in_freq++) {
|
||||
slot_map->prach_occasion[n_prach_occ_in_time * nb_fdm + n_prach_occ_in_freq] =
|
||||
(prach_occasion_info_t){.start_symbol = start_symbol,
|
||||
.fdm = n_prach_occ_in_freq,
|
||||
.frame = frame_idx,
|
||||
.slot = slot,
|
||||
.format = prach_config.format};
|
||||
prach_assoc_pattern->prach_conf_period_list[period_idx].nb_of_prach_occasion++;
|
||||
|
||||
LOG_D(NR_MAC,
|
||||
"Adding a PRACH occasion: frame %u, slot-symbol %d-%d, occ_in_time-occ_in-freq %d-%d, nb ROs in conf period %d, for this slot: RO# in time %d, RO# in freq %d\n",
|
||||
frame_rach,
|
||||
slot,
|
||||
start_symbol,
|
||||
n_prach_occ_in_time,
|
||||
n_prach_occ_in_freq,
|
||||
prach_conf_period_list->nb_of_prach_occasion,
|
||||
slot_map->nb_of_prach_occasion_in_time,
|
||||
slot_map->nb_of_prach_occasion_in_freq);
|
||||
} // For every freq in the slot
|
||||
} // For every time occasions in the slot
|
||||
} // Valid slot?
|
||||
} // For every slots in a frame
|
||||
} // Valid frame?
|
||||
} // For every frames in a prach configuration period
|
||||
} // For every prach configuration periods in the maximum association pattern period (160ms)
|
||||
}
|
||||
|
||||
static int get_ssb_idx_from_list(ssb_list_info_t *ssb_list, int idx)
|
||||
{
|
||||
for (int ssb_index = 0; ssb_index < MAX_NB_SSB; ssb_index++) {
|
||||
if (ssb_list->nb_ssb_per_index[ssb_index] == idx)
|
||||
return ssb_index;
|
||||
}
|
||||
AssertFatal(false, "Couldn't find SSB index in SSB list\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Map the transmitted SSBs to the ROs and create the association pattern according to the config
|
||||
static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac)
|
||||
{
|
||||
// Map SSBs to PRACH occasions
|
||||
// WIP: Assumption: No PRACH occasion is rejected because of a conflict with SSBs or TDD_UL_DL_ConfigurationCommon schedule
|
||||
NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon;
|
||||
NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR ssb_perRACH_config = setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present;
|
||||
|
||||
const struct {
|
||||
// true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB
|
||||
bool multiple_ssb_per_ro;
|
||||
// Nb of SSBs per RACH or RACHs per SSB
|
||||
int ssb_rach_ratio;
|
||||
} config[] = {{false, 0}, {false, 8}, {false, 4}, {false, 2}, {true, 1}, {true, 2}, {true, 4}, {true, 8}, {true, 16}};
|
||||
AssertFatal(ssb_perRACH_config <= NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_sixteen,
|
||||
"Unsupported ssb_perRACH_config %d\n",
|
||||
ssb_perRACH_config);
|
||||
const bool multiple_ssb_per_ro = config[ssb_perRACH_config].multiple_ssb_per_ro;
|
||||
const int ssb_rach_ratio = config[ssb_perRACH_config].ssb_rach_ratio;
|
||||
|
||||
LOG_D(NR_MAC,"SSB rach ratio %d, Multiple SSB per RO %d\n", ssb_rach_ratio, multiple_ssb_per_ro);
|
||||
|
||||
const int bwp_id = mac->current_UL_BWP->bwp_id;
|
||||
ssb_list_info_t *ssb_list = &mac->ssb_list;
|
||||
|
||||
// Evaluate the number of PRACH configuration periods required to map all the SSBs and set the association period
|
||||
// WIP: Assumption for now is that all the PRACH configuration periods within a maximum association pattern period have the same
|
||||
// number of PRACH occasions
|
||||
// (No PRACH occasions are conflicting with SSBs nor TDD_UL_DL_ConfigurationCommon schedule)
|
||||
// There is only one possible association period which can contain up to 16 PRACH configuration periods
|
||||
LOG_D(NR_MAC,"Evaluate the number of PRACH configuration periods required to map all the SSBs and set the association period\n");
|
||||
const int required_nb_of_prach_occasion =
|
||||
multiple_ssb_per_ro ? ((ssb_list->nb_tx_ssb - 1) + ssb_rach_ratio) / ssb_rach_ratio : ssb_list->nb_tx_ssb * ssb_rach_ratio;
|
||||
|
||||
prach_association_pattern_t *prach_assoc_pattern = &mac->prach_assoc_pattern[bwp_id];
|
||||
const prach_conf_period_t *prach_conf_period = &prach_assoc_pattern->prach_conf_period_list[0];
|
||||
AssertFatal(prach_conf_period->nb_of_prach_occasion > 0,
|
||||
"prach_conf_period->nb_of_prach_occasion shouldn't be 0 (nb_tx_ssb %d, ssb_rach_ratio %d)\n",
|
||||
ssb_list->nb_tx_ssb,
|
||||
ssb_rach_ratio);
|
||||
prach_association_period_t *prach_association_period = &prach_assoc_pattern->prach_association_period_list[0];
|
||||
const int required_nb_of_prach_conf_period =
|
||||
((required_nb_of_prach_occasion - 1) + prach_conf_period->nb_of_prach_occasion) / prach_conf_period->nb_of_prach_occasion;
|
||||
|
||||
if (required_nb_of_prach_conf_period == 1) {
|
||||
prach_association_period->nb_of_prach_conf_period = 1;
|
||||
}
|
||||
else if (required_nb_of_prach_conf_period == 2) {
|
||||
prach_association_period->nb_of_prach_conf_period = 2;
|
||||
}
|
||||
else if (required_nb_of_prach_conf_period <= 4) {
|
||||
prach_association_period->nb_of_prach_conf_period = 4;
|
||||
}
|
||||
else if (required_nb_of_prach_conf_period <= 8) {
|
||||
prach_association_period->nb_of_prach_conf_period = 8;
|
||||
}
|
||||
else if (required_nb_of_prach_conf_period <= 16) {
|
||||
prach_association_period->nb_of_prach_conf_period = 16;
|
||||
}
|
||||
else {
|
||||
AssertFatal(1 == 0, "Invalid number of PRACH config periods within an association period %d\n", required_nb_of_prach_conf_period);
|
||||
}
|
||||
|
||||
prach_assoc_pattern->nb_of_assoc_period = 1; // WIP: only one possible association period
|
||||
prach_association_period->nb_of_frame = prach_association_period->nb_of_prach_conf_period * prach_conf_period->nb_of_frame;
|
||||
prach_assoc_pattern->nb_of_frame = prach_association_period->nb_of_frame;
|
||||
|
||||
LOG_D(NR_MAC,
|
||||
"Assoc period %d, Nb of frames in assoc period %d\n",
|
||||
prach_association_period->nb_of_prach_conf_period,
|
||||
prach_association_period->nb_of_frame);
|
||||
|
||||
// Set the starting PRACH Configuration period index in the association_pattern map for this particular association period
|
||||
int prach_configuration_period_idx =
|
||||
0; // WIP: only one possible association period so the starting PRACH configuration period is automatically 0
|
||||
|
||||
// Map all the association periods within the association pattern period
|
||||
LOG_D(NR_MAC,"Proceed to the SSB to RO mapping\n");
|
||||
// Check if we need to map multiple SSBs per RO or multiple ROs per SSB
|
||||
|
||||
if (multiple_ssb_per_ro) {
|
||||
const prach_association_period_t *end =
|
||||
prach_assoc_pattern->prach_association_period_list + prach_assoc_pattern->nb_of_assoc_period;
|
||||
for (prach_association_period_t *prach_period = prach_assoc_pattern->prach_association_period_list; prach_period < end;
|
||||
prach_period++) {
|
||||
// Set the starting PRACH Configuration period index in the association_pattern map for this particular association period
|
||||
// WIP: only one possible association period so the starting PRACH configuration period is automatically 0
|
||||
// WIP: For the moment, only map each SSB idx once per association period if configuration is multiple SSBs per RO
|
||||
// this is true if no PRACH occasions are conflicting with SSBs nor TDD_UL_DL_ConfigurationCommon schedule
|
||||
int idx = 0;
|
||||
bool done = false;
|
||||
for (int i = 0; i < prach_period->nb_of_prach_conf_period && !done; i++, prach_configuration_period_idx++) {
|
||||
prach_period->prach_conf_period_list[i] = &prach_assoc_pattern->prach_conf_period_list[prach_configuration_period_idx];
|
||||
prach_conf_period_t *prach_conf = prach_period->prach_conf_period_list[i];
|
||||
// Build the association period with its association PRACH Configuration indexes
|
||||
// Go through all the ROs within the PRACH config period
|
||||
for (int frame = 0; frame < prach_conf->nb_of_frame && !done; frame++) {
|
||||
for (int slot = 0; slot < prach_conf->nb_of_slot && !done; slot++) {
|
||||
prach_occasion_slot_t *slot_map = &prach_conf->prach_occasion_slot_map[frame][slot];
|
||||
for (int ro_in_time = 0; ro_in_time < slot_map->nb_of_prach_occasion_in_time && !done; ro_in_time++) {
|
||||
for (int ro_in_freq = 0; ro_in_freq < slot_map->nb_of_prach_occasion_in_freq && !done; ro_in_freq++) {
|
||||
prach_occasion_info_t *ro_p =
|
||||
slot_map->prach_occasion + ro_in_time * slot_map->nb_of_prach_occasion_in_freq + ro_in_freq;
|
||||
// Go through the list of transmitted SSBs and map the required amount of SSBs to this RO
|
||||
// WIP: For the moment, only map each SSB idx once per association period if configuration is multiple SSBs per RO
|
||||
// this is true if no PRACH occasions are conflicting with SSBs nor TDD_UL_DL_ConfigurationCommon schedule
|
||||
for (; idx < ssb_list->nb_tx_ssb; idx++) {
|
||||
ssb_info_t *tx_ssb = ssb_list->tx_ssb + idx;
|
||||
// Map only the transmitted ssb_idx
|
||||
int ssb_idx = get_ssb_idx_from_list(ssb_list, idx);
|
||||
ro_p->mapped_ssb_idx[ro_p->nb_mapped_ssb] = ssb_idx;
|
||||
ro_p->nb_mapped_ssb++;
|
||||
AssertFatal(MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN > tx_ssb->nb_mapped_ro + 1,
|
||||
"Too many mapped ROs (%d) to a single SSB\n",
|
||||
tx_ssb->nb_mapped_ro);
|
||||
tx_ssb->mapped_ro[tx_ssb->nb_mapped_ro] = ro_p;
|
||||
tx_ssb->nb_mapped_ro++;
|
||||
LOG_D(NR_MAC,
|
||||
"Mapped ssb_idx %u to RO slot-symbol %u-%u, %u-%u-%u/%u\n"
|
||||
"Nb mapped ROs for this ssb idx: in the association period only %u\n",
|
||||
ssb_idx,
|
||||
ro_p->slot,
|
||||
ro_p->start_symbol,
|
||||
slot,
|
||||
ro_in_time,
|
||||
ro_in_freq,
|
||||
slot_map->nb_of_prach_occasion_in_freq,
|
||||
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;
|
||||
}
|
||||
}
|
||||
done = MAX_NB_SSB == idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int frame = 0;
|
||||
int slot = 0;
|
||||
int ro_in_time = 0;
|
||||
int ro_in_freq = 0;
|
||||
prach_association_period_t *end = prach_assoc_pattern->prach_association_period_list + prach_assoc_pattern->nb_of_assoc_period;
|
||||
for (prach_association_period_t *prach_period = prach_assoc_pattern->prach_association_period_list; prach_period < end;
|
||||
prach_period++) {
|
||||
// Go through the list of transmitted SSBs
|
||||
for (int idx = 0; idx < ssb_list->nb_tx_ssb; idx++) {
|
||||
ssb_info_t *tx_ssb = ssb_list->tx_ssb + idx;
|
||||
uint8_t nb_mapped_ro_in_association_period = 0; // Reset the nb of mapped ROs for the new SSB index
|
||||
bool done = false;
|
||||
// Map all the required ROs to this SSB
|
||||
// Go through the list of PRACH config periods within this association period
|
||||
for (int i = 0; i < prach_period->nb_of_prach_conf_period && !done; i++, prach_configuration_period_idx++) {
|
||||
// Build the association period with its association PRACH Configuration indexes
|
||||
prach_period->prach_conf_period_list[i] = &prach_assoc_pattern->prach_conf_period_list[prach_configuration_period_idx];
|
||||
prach_conf_period_t *prach_conf = prach_period->prach_conf_period_list[i];
|
||||
for (; frame < prach_conf->nb_of_frame; frame++) {
|
||||
for (; slot < prach_conf->nb_of_slot; slot++) {
|
||||
prach_occasion_slot_t *slot_map = &prach_conf->prach_occasion_slot_map[frame][slot];
|
||||
for (; ro_in_time < slot_map->nb_of_prach_occasion_in_time; ro_in_time++) {
|
||||
for (; ro_in_freq < slot_map->nb_of_prach_occasion_in_freq; ro_in_freq++) {
|
||||
prach_occasion_info_t *ro_p =
|
||||
slot_map->prach_occasion + ro_in_time * slot_map->nb_of_prach_occasion_in_freq + ro_in_freq;
|
||||
int ssb_idx = get_ssb_idx_from_list(ssb_list, idx);
|
||||
ro_p->mapped_ssb_idx[0] = ssb_idx;
|
||||
ro_p->nb_mapped_ssb = 1;
|
||||
AssertFatal(MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN > tx_ssb->nb_mapped_ro + 1,
|
||||
"Too many mapped ROs (%d) to a single SSB\n",
|
||||
tx_ssb->nb_mapped_ro);
|
||||
tx_ssb->mapped_ro[tx_ssb->nb_mapped_ro] = ro_p;
|
||||
tx_ssb->nb_mapped_ro++;
|
||||
nb_mapped_ro_in_association_period++;
|
||||
|
||||
LOG_D(NR_MAC,
|
||||
"Mapped ssb_idx %u to RO slot-symbol %u-%u-%u, %u-%u-%u-%u/%u\n"
|
||||
"Nb mapped ROs for this ssb idx: in the association period only %u / total %u\n",
|
||||
ssb_idx,
|
||||
ro_p->frame,
|
||||
ro_p->slot,
|
||||
ro_p->start_symbol,
|
||||
frame,
|
||||
slot,
|
||||
ro_in_time,
|
||||
ro_in_freq,
|
||||
slot_map->nb_of_prach_occasion_in_freq,
|
||||
tx_ssb->nb_mapped_ro,
|
||||
nb_mapped_ro_in_association_period);
|
||||
|
||||
// Exit the loop if this SSB has been mapped to all the required ROs
|
||||
// WIP: Assuming that ssb_rach_ratio equals the maximum nb of times a given ssb_idx is mapped within an
|
||||
// association period:
|
||||
// this is true if no PRACH occasions are conflicting with SSBs nor TDD_UL_DL_ConfigurationCommon schedule
|
||||
if (nb_mapped_ro_in_association_period == ssb_rach_ratio) {
|
||||
ro_in_freq++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nb_mapped_ro_in_association_period == ssb_rach_ratio)
|
||||
break;
|
||||
else
|
||||
ro_in_freq = 0;
|
||||
}
|
||||
if (nb_mapped_ro_in_association_period == ssb_rach_ratio)
|
||||
break;
|
||||
else
|
||||
ro_in_time = 0;
|
||||
}
|
||||
if (nb_mapped_ro_in_association_period == ssb_rach_ratio)
|
||||
break;
|
||||
else
|
||||
slot = 0;
|
||||
}
|
||||
if (nb_mapped_ro_in_association_period == ssb_rach_ratio)
|
||||
break;
|
||||
else
|
||||
frame = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build the SSB to RO mapping upon RRC configuration update
|
||||
void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac)
|
||||
{
|
||||
// Clear all the lists and maps
|
||||
const int bwp_id = mac->current_UL_BWP->bwp_id;
|
||||
free_rach_structures(mac, bwp_id);
|
||||
|
||||
memset(&mac->prach_assoc_pattern[bwp_id], 0, sizeof(prach_association_pattern_t));
|
||||
|
||||
// Build the list of all the valid RACH occasions in the maximum association pattern period according to the PRACH config
|
||||
LOG_D(NR_MAC,"Build RO list\n");
|
||||
build_ro_list(mac);
|
||||
|
||||
// Map the transmitted SSBs to the ROs and create the association pattern according to the config
|
||||
LOG_D(NR_MAC,"Map SSB to RO\n");
|
||||
map_ssb_to_ro(mac);
|
||||
LOG_D(NR_MAC,"Map SSB to RO done\n");
|
||||
}
|
||||
|
||||
static bool schedule_uci_on_pusch(NR_UE_MAC_INST_t *mac,
|
||||
frame_t frame_tx,
|
||||
int slot_tx,
|
||||
|
||||
Reference in New Issue
Block a user