Merge remote-tracking branch 'origin/improv_TDD' into integration_2025_w07 (!3249)

Improvements in TDD configuration

Including using the frame structure introduced in !2799 also at the UE
This commit is contained in:
Robert Schmidt
2025-02-14 15:10:22 +01:00
38 changed files with 584 additions and 712 deletions
+2
View File
@@ -1366,6 +1366,7 @@ target_link_libraries(NR_L2_UE PRIVATE nr_nas)
add_library(MAC_NR_COMMON
${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c
${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common_tdd.c
${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c
)
target_link_libraries(MAC_NR_COMMON PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
@@ -1891,6 +1892,7 @@ add_executable(nr-uesoftmodem
${OPENAIR_DIR}/radio/COMMON/common_lib.c
${OPENAIR_DIR}/radio/COMMON/record_player.c
${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c
${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common_tdd.c
${OPENAIR1_DIR}/PHY/TOOLS/phy_scope_interface.c
)
+1 -1
View File
@@ -142,7 +142,7 @@ typedef struct frame_structure_s {
int8_t numb_slots_frame;
int8_t numb_slots_period;
int8_t numb_period_frame;
bool is_tdd;
frame_type_t frame_type;
} frame_structure_t;
typedef struct {
+2 -2
View File
@@ -328,7 +328,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, slot)) {
if (is_dl_slot(slot, &mac->frame_structure)) {
memset(&mac->dl_info, 0, sizeof(mac->dl_info));
mac->dl_info.cc_id = CC_id;
mac->dl_info.gNB_index = gNB_id;
@@ -342,7 +342,7 @@ 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, mac->frame_type)) {
if (is_ul_slot(ul_info.slot, &mac->frame_structure)) {
LOG_D(NR_MAC, "Slot %d. calling nr_ue_ul_ind()\n", ul_info.slot);
nr_ue_ul_scheduler(mac, &ul_info);
}
@@ -655,21 +655,18 @@ typedef struct
typedef struct
{
uint8_t slot_config;//For each symbol in each slot a uint8_t value is provided indicating: 0: DL slot 1: UL slot 2: Guard slot
uint8_t slot_config; //For each symbol in each slot a uint8_t value is provided indicating: 0: DL slot 1: UL slot 2: Guard slot
} fapi_nr_max_num_of_symbol_per_slot_t;
typedef struct
{
fapi_nr_max_num_of_symbol_per_slot_t *max_num_of_symbol_per_slot_list;
} fapi_nr_max_tdd_periodicity_t;
typedef struct
{
uint8_t tdd_period_in_slots;
fapi_nr_max_tdd_periodicity_t* max_tdd_periodicity_list;
} fapi_nr_tdd_table_t;
typedef struct
@@ -709,8 +706,7 @@ typedef struct {
fapi_nr_cell_config_t cell_config;
fapi_nr_ssb_config_t ssb_config;
fapi_nr_ssb_table_t ssb_table;
fapi_nr_tdd_table_t tdd_table_1;
fapi_nr_tdd_table_t *tdd_table_2;
fapi_nr_tdd_table_t tdd_table;
fapi_nr_prach_config_t prach_config;
} fapi_nr_config_request_t;
+1 -1
View File
@@ -395,7 +395,7 @@ void free_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms) {
void do_tdd_config_sim(PHY_VARS_gNB *gNB, int mu)
{
frame_structure_t fs = {.is_tdd = true};
frame_structure_t fs = {.frame_type = TDD};
fs.numb_slots_frame = (1 << mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
fs.numb_period_frame = get_nb_periods_per_frame(gNB->gNB_config.tdd_table.tdd_period.value);
fs.numb_slots_period = fs.numb_slots_frame / fs.numb_period_frame;
@@ -44,14 +44,8 @@ int nr_ue_slot_select(const fapi_nr_config_request_t *cfg, int nr_slot)
if (cfg->cell_config.frame_duplex_type == FDD)
return NR_UPLINK_SLOT | NR_DOWNLINK_SLOT;
int period = cfg->tdd_table_1.tdd_period_in_slots +
(cfg->tdd_table_2 ? cfg->tdd_table_2->tdd_period_in_slots : 0);
int rel_slot = nr_slot % period;
const fapi_nr_tdd_table_t *tdd_table = &cfg->tdd_table_1;
if (cfg->tdd_table_2 && rel_slot >= tdd_table->tdd_period_in_slots) {
rel_slot -= tdd_table->tdd_period_in_slots;
tdd_table = cfg->tdd_table_2;
}
const fapi_nr_tdd_table_t *tdd_table = &cfg->tdd_table;
int rel_slot = nr_slot % tdd_table->tdd_period_in_slots;
if (tdd_table->max_tdd_periodicity_list == NULL) // this happens before receiving TDD configuration
return NR_DOWNLINK_SLOT;
+6 -2
View File
@@ -647,7 +647,11 @@ printf("%d\n", slot);
frame_structure_t frame_structure = {0};
frame_type_t frame_type = TDD;
config_frame_structure(mu, scc, get_tdd_period_idx(scc->tdd_UL_DL_ConfigurationCommon), frame_type, &frame_structure);
config_frame_structure(mu,
scc->tdd_UL_DL_ConfigurationCommon,
get_tdd_period_idx(scc->tdd_UL_DL_ConfigurationCommon),
frame_type,
&frame_structure);
AssertFatal(is_dl_slot(slot, &frame_structure), "The slot selected is not DL. Can't run DLSIM\n");
// TODO do a UECAP for phy-sim
@@ -859,7 +863,7 @@ printf("%d\n", slot);
nr_l2_init_ue(1);
UE_mac = get_mac_inst(0);
ue_init_config_request(UE_mac, mu);
ue_init_config_request(UE_mac, get_slots_per_frame_from_scs(mu));
UE->if_inst = nr_ue_if_module_init(0);
UE->if_inst->scheduled_response = nr_ue_scheduled_response;
+6 -2
View File
@@ -628,7 +628,11 @@ int main(int argc, char *argv[])
frame_structure_t frame_structure = {0};
frame_type_t frame_type = TDD;
config_frame_structure(mu, scc, get_tdd_period_idx(scc->tdd_UL_DL_ConfigurationCommon), frame_type, &frame_structure);
config_frame_structure(mu,
scc->tdd_UL_DL_ConfigurationCommon,
get_tdd_period_idx(scc->tdd_UL_DL_ConfigurationCommon),
frame_type,
&frame_structure);
AssertFatal(is_ul_slot(slot, &frame_structure), "The slot selected is not UL. Can't run ULSIM\n");
// TODO do a UECAP for phy-sim
@@ -737,7 +741,7 @@ int main(int argc, char *argv[])
nr_l2_init_ue(1);
NR_UE_MAC_INST_t* UE_mac = get_mac_inst(0);
ue_init_config_request(UE_mac, mu);
ue_init_config_request(UE_mac, get_slots_per_frame_from_scs(mu));
UE->if_inst = nr_ue_if_module_init(0);
UE->if_inst->scheduled_response = nr_ue_scheduled_response;
+6 -76
View File
@@ -76,8 +76,6 @@ static const uint16_t symbol_ssb_E[64] = {8, 12, 16, 20, 32, 36, 40, 44,
288, 292, 296, 300, 312, 316, 320, 324, 344, 348, 352, 356, 368, 372, 376, 380,
400, 404, 408, 412, 424, 428, 432, 436, 456, 460, 464, 468, 480, 484, 488, 492};
const uint8_t nr_slots_per_frame[5] = {10, 20, 40, 80, 160};
// Table 6.3.3.1-5 (38.211) NCS for preamble formats with delta_f_RA = 1.25 KHz
static const uint16_t NCS_unrestricted_delta_f_RA_125[16] = {0, 13, 15, 18, 22, 26, 32, 38, 46, 59, 76, 93, 119, 167, 279, 419};
static const uint16_t NCS_restricted_TypeA_delta_f_RA_125[15] =
@@ -3555,73 +3553,6 @@ int ul_ant_bits(NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig, long transformPrec
}
}
static const int tdd_period_to_num[8] = {500, 625, 1000, 1250, 2000, 2500, 5000, 10000};
bool is_nr_DL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon, slot_t slot)
{
if (tdd_UL_DL_ConfigurationCommon == NULL)
return true;
int period1, period2 = 0;
if (tdd_UL_DL_ConfigurationCommon->pattern1.ext1 &&
tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530)
period1 = 3000+*tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530;
else
period1 = tdd_period_to_num[tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity];
if (tdd_UL_DL_ConfigurationCommon->pattern2) {
if (tdd_UL_DL_ConfigurationCommon->pattern2->ext1 &&
tdd_UL_DL_ConfigurationCommon->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530)
period2 = 3000 + *tdd_UL_DL_ConfigurationCommon->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530;
else
period2 = tdd_period_to_num[tdd_UL_DL_ConfigurationCommon->pattern2->dl_UL_TransmissionPeriodicity];
}
int period = period1+period2;
int scs = tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing;
int slots = period * (1 << scs) / 1000;
int slots1 = period1 * (1 << scs) / 1000;
int slot_in_period = slot % slots;
if (slot_in_period < slots1)
return slot_in_period <= tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots;
else
return slot_in_period <= slots1 + tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots;
}
bool is_nr_UL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon, slot_t slot, frame_type_t frame_type)
{
// Note: condition on frame_type
// goal: the UL scheduler assumes mode is TDD therefore this hack is needed to make FDD work
if (frame_type == FDD)
return true;
if (tdd_UL_DL_ConfigurationCommon == NULL)
// before receiving TDD information all slots should be considered to be DL
return false;
int period1, period2 = 0;
if (tdd_UL_DL_ConfigurationCommon->pattern1.ext1 &&
tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530)
period1 = 3000 + *tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530;
else
period1 = tdd_period_to_num[tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity];
if (tdd_UL_DL_ConfigurationCommon->pattern2) {
if (tdd_UL_DL_ConfigurationCommon->pattern2->ext1 &&
tdd_UL_DL_ConfigurationCommon->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530)
period2 = 3000 + *tdd_UL_DL_ConfigurationCommon->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530;
else
period2 = tdd_period_to_num[tdd_UL_DL_ConfigurationCommon->pattern2->dl_UL_TransmissionPeriodicity];
}
int period = period1+period2;
int scs = tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing;
int slots = period * (1 << scs) / 1000;
int slots1 = period1 * (1 << scs) / 1000;
int slot_in_period = slot % slots;
if (slot_in_period < slots1)
return slot_in_period >= tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots;
else
return slot_in_period >= slots1+tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots;
}
int16_t fill_dmrs_mask(const NR_PDSCH_Config_t *pdsch_Config,
int dci_format,
int dmrs_TypeA_Position,
@@ -4198,6 +4129,7 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
// 38.213 table 10.1-1
/// MUX PATTERN 1
int slots_per_frame = get_slots_per_frame_from_scs(scs_ssb);
if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 1 && frequency_range == FR1){
big_o = table_38213_13_11_c1[index_4lsb];
big_m = table_38213_13_11_c3[index_4lsb];
@@ -4214,7 +4146,7 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
// 38.213 chapter 13: over two consecutive slots
type0_PDCCH_CSS_config->search_space_duration = 2;
// two frames
type0_PDCCH_CSS_config->search_space_frame_period = nr_slots_per_frame[scs_ssb]<<1;
type0_PDCCH_CSS_config->search_space_frame_period = slots_per_frame << 1;
}
if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 1 && frequency_range == FR2){
@@ -4235,7 +4167,7 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
// 38.213 chapter 13: over two consecutive slots
type0_PDCCH_CSS_config->search_space_duration = 2;
// two frames
type0_PDCCH_CSS_config->search_space_frame_period = nr_slots_per_frame[scs_ssb]<<1;
type0_PDCCH_CSS_config->search_space_frame_period = slots_per_frame << 1;
}
/// MUX PATTERN 2
@@ -4302,7 +4234,7 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
// 38.213 chapter 13: over one slot
type0_PDCCH_CSS_config->search_space_duration = 1;
// SSB periodicity in slots
type0_PDCCH_CSS_config->search_space_frame_period = ssb_period*nr_slots_per_frame[scs_ssb];
type0_PDCCH_CSS_config->search_space_frame_period = ssb_period * slots_per_frame;
}
/// MUX PATTERN 3
@@ -4332,7 +4264,7 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD
// 38.213 chapter 13: over one slot
type0_PDCCH_CSS_config->search_space_duration = 1;
// SSB periodicity in slots
type0_PDCCH_CSS_config->search_space_frame_period = ssb_period*nr_slots_per_frame[scs_ssb];
type0_PDCCH_CSS_config->search_space_frame_period = ssb_period * slots_per_frame;
}
AssertFatal(type0_PDCCH_CSS_config->sfn_c >= 0, "");
@@ -4392,9 +4324,7 @@ void fill_coresetZero(NR_ControlResourceSet_t *coreset0, NR_Type0_PDCCH_CSS_conf
coreset0->pdcch_DMRS_ScramblingID = NULL;
}
void fill_searchSpaceZero(NR_SearchSpace_t *ss0,
int slots_per_frame,
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config)
void fill_searchSpaceZero(NR_SearchSpace_t *ss0, int slots_per_frame, NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config)
{
AssertFatal(ss0, "SearchSpace0 should have been allocated outside of this function\n");
if(ss0->controlResourceSetId == NULL)
+10 -4
View File
@@ -63,10 +63,16 @@ int16_t fill_dmrs_mask(const NR_PDSCH_Config_t *pdsch_Config,
int startSymbol,
mappingType_t mappingtype,
int length);
bool is_nr_DL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon, slot_t slotP);
bool is_nr_UL_slot(NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon, slot_t slotP, frame_type_t frame_type);
int get_slots_per_frame_from_scs(int scs);
bool is_ul_slot(const slot_t slot, const frame_structure_t *fs);
bool is_dl_slot(const slot_t slot, const frame_structure_t *fs);
bool is_mixed_slot(const slot_t slot, const frame_structure_t *fs);
int get_tdd_period_idx(NR_TDD_UL_DL_ConfigCommon_t *tdd);
void config_frame_structure(int mu,
NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon,
uint8_t tdd_period,
uint8_t frame_type,
frame_structure_t *fs);
uint8_t compute_srs_resource_indicator(long *maxMIMO_Layers,
NR_PUSCH_Config_t *pusch_Config,
@@ -0,0 +1,252 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "nr_mac_common.h"
#include "common/utils/nr/nr_common.h"
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h"
int get_slots_per_frame_from_scs(int scs)
{
const int nr_slots_per_frame[5] = {10, 20, 40, 80, 160};
return nr_slots_per_frame[scs];
}
const float tdd_ms_period_pattern[] = {0.5, 0.625, 1.0, 1.25, 2.0, 2.5, 5.0, 10.0};
const float tdd_ms_period_ext[] = {3.0, 4.0};
/**
* @brief Retrieves the periodicity in milliseconds for the given TDD pattern
* depending on the presence of the extension
* @param pattern Pointer to the NR_TDD_UL_DL_Pattern_t pattern structure
* @return Periodicity value in milliseconds.
*/
static float get_tdd_periodicity(NR_TDD_UL_DL_Pattern_t *pattern)
{
if (!pattern->ext1) {
LOG_D(NR_MAC, "Setting TDD configuration period to dl_UL_TransmissionPeriodicity %ld\n", pattern->dl_UL_TransmissionPeriodicity);
return tdd_ms_period_pattern[pattern->dl_UL_TransmissionPeriodicity];
} else {
DevAssert(pattern->ext1->dl_UL_TransmissionPeriodicity_v1530 != NULL);
LOG_D(NR_MAC,
"Setting TDD configuration period to dl_UL_TransmissionPeriodicity_v1530 %ld\n",
*pattern->ext1->dl_UL_TransmissionPeriodicity_v1530);
return tdd_ms_period_ext[*pattern->ext1->dl_UL_TransmissionPeriodicity_v1530];
}
}
/**
* @brief Determines the TDD period index based on pattern periodicities
* @note Not applicabile to pattern extension
* @param tdd Pointer to the NR_TDD_UL_DL_ConfigCommon_t containing patterns
* @return Index of the TDD period in tdd_ms_period_pattern
*/
int get_tdd_period_idx(NR_TDD_UL_DL_ConfigCommon_t *tdd)
{
int tdd_period_idx = 0;
float pattern1_ms = get_tdd_periodicity(&tdd->pattern1);
float pattern2_ms = tdd->pattern2 ? get_tdd_periodicity(tdd->pattern2) : 0.0;
bool found_match = false;
// Find matching TDD period in the predefined list of periodicities
for (int i = 0; i < NFAPI_MAX_NUM_PERIODS; i++) {
if ((pattern1_ms + pattern2_ms) == tdd_ms_period_pattern[i]) {
tdd_period_idx = i;
LOG_I(NR_MAC,
"TDD period index = %d, based on the sum of dl_UL_TransmissionPeriodicity "
"from Pattern1 (%f ms) and Pattern2 (%f ms): Total = %f ms\n",
tdd_period_idx,
pattern1_ms,
pattern2_ms,
pattern1_ms + pattern2_ms);
found_match = true;
break;
}
}
// Assert if no match was found
AssertFatal(found_match, "The sum of pattern1_ms and pattern2_ms does not match any value in tdd_ms_period_pattern");
return tdd_period_idx;
}
/**
* @brief Configures the TDD period, including bitmap, in the frame structure
*
* This function sets the TDD period configuration for DL, UL, and mixed slots in
* the specified frame structure instance, according to the given pattern, and
* updates the bitmap.
*
* @param pattern NR_TDD_UL_DL_Pattern_t configuration containing TDD slots and symbols configuration
* @param fs frame_structure_t pointer
* @param curr_total_slot current position in the slot bitmap to start from
*
* @return Number of slots in the configured TDD period
*/
static uint8_t set_tdd_bmap_period(NR_TDD_UL_DL_Pattern_t *pattern, tdd_period_config_t *pc, int8_t curr_total_slot)
{
int8_t n_dl_slot = pattern->nrofDownlinkSlots;
int8_t n_ul_slot = pattern->nrofUplinkSlots;
int8_t n_dl_symbols = pattern->nrofDownlinkSymbols;
int8_t n_ul_symbols = pattern->nrofUplinkSymbols;
// Total slots in the period: if DL/UL symbols are present, is mixed slot
const bool has_mixed_slot = (n_ul_symbols + n_dl_symbols) > 0;
int8_t total_slot = has_mixed_slot ? n_dl_slot + n_ul_slot + 1 : n_dl_slot + n_ul_slot;
/** Update TDD period configuration:
* mixed slots with DL symbols are counted as DL slots
* mixed slots with UL symbols are counted as UL slots */
pc->num_dl_slots += (n_dl_slot + (n_dl_symbols > 0));
pc->num_ul_slots += (n_ul_slot + (n_ul_symbols > 0));
// Populate the slot bitmap for each slot in the TDD period
for (int i = 0; i < total_slot; i++) {
tdd_bitmap_t *bitmap = &pc->tdd_slot_bitmap[i + curr_total_slot];
if (i < n_dl_slot)
bitmap->slot_type = TDD_NR_DOWNLINK_SLOT;
else if ((i == n_dl_slot) && has_mixed_slot) {
bitmap->slot_type = TDD_NR_MIXED_SLOT;
bitmap->num_dl_symbols = n_dl_symbols;
bitmap->num_ul_symbols = n_ul_symbols;
} else if (n_ul_slot)
bitmap->slot_type = TDD_NR_UPLINK_SLOT;
}
LOG_I(NR_MAC,
"Set TDD configuration period to: %d DL slots, %d UL slots, %d slots per period (NR_TDD_UL_DL_Pattern is %d DL slots, %d "
"UL slots, %d DL symbols, %d UL symbols)\n",
pc->num_dl_slots,
pc->num_ul_slots,
total_slot,
n_dl_slot,
n_ul_slot,
n_dl_symbols,
n_ul_symbols);
return total_slot;
}
/**
* @brief Configures TDD patterns (1 or 2) in the frame structure
*
* This function sets up the TDD configuration in the frame structure by applying
* DL and UL patterns as defined in NR_TDD_UL_DL_ConfigCommon.
* It handles both TDD pattern1 and pattern2.
*
* @param tdd NR_TDD_UL_DL_ConfigCommon_t pointer containing pattern1 and pattern2
* @param fs Pointer to the frame structure to update with the configured TDD patterns.
*
* @return void
*/
static void config_tdd_patterns(NR_TDD_UL_DL_ConfigCommon_t *tdd, frame_structure_t *fs)
{
int num_of_patterns = 1;
uint8_t nb_slots_p2 = 0;
// Reset num dl/ul slots
tdd_period_config_t *pc = &fs->period_cfg;
pc->num_dl_slots = 0;
pc->num_ul_slots = 0;
// Pattern1
uint8_t nb_slots_p1 = set_tdd_bmap_period(&tdd->pattern1, pc, 0);
// Pattern2
if (tdd->pattern2) {
num_of_patterns++;
nb_slots_p2 = set_tdd_bmap_period(tdd->pattern2, pc, nb_slots_p1);
}
LOG_I(NR_MAC,
"Configured %d TDD patterns (total slots: pattern1 = %d, pattern2 = %d)\n",
num_of_patterns,
nb_slots_p1,
nb_slots_p2);
}
/**
* @brief Configures the frame structure and the NFAPI config request
* depending on the duplex mode. If TDD, does the TDD patterns
* and TDD periods configuration.
*
* @param mu numerology
* @param scc pointer to scc
* @param tdd_period TDD period
* @param frame_type type of frame structure (FDD or TDD)
* @param fs pointer to the frame structure to update
*/
void config_frame_structure(int mu,
NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon,
uint8_t tdd_period,
uint8_t frame_type,
frame_structure_t *fs)
{
fs->numb_slots_frame = get_slots_per_frame_from_scs(mu);
fs->frame_type = frame_type;
if (frame_type == TDD) {
fs->numb_period_frame = get_nb_periods_per_frame(tdd_period);
fs->numb_slots_period = fs->numb_slots_frame / fs->numb_period_frame;
config_tdd_patterns(tdd_UL_DL_ConfigurationCommon, fs);
} else { // FDD
fs->numb_period_frame = 1;
fs->numb_slots_period = fs->numb_slots_frame;
}
AssertFatal(fs->numb_period_frame > 0, "Frame configuration cannot be configured!\n");
}
/**
* @brief Returns true for:
* (1) FDD
* (2) Mixed slot with UL symbols
* (3) Full UL slot
*/
bool is_ul_slot(const slot_t slot, const frame_structure_t *fs)
{
if (fs->frame_type == FDD)
return true;
const tdd_period_config_t *pc = &fs->period_cfg;
slot_t s = get_slot_idx_in_period(slot, fs);
return ((is_mixed_slot(s, fs) && pc->tdd_slot_bitmap[s].num_ul_symbols)
|| (pc->tdd_slot_bitmap[s].slot_type == TDD_NR_UPLINK_SLOT));
}
/**
* @brief Returns true for:
* (1) FDD
* (2) Mixed slot with DL symbols
* (3) Full DL slot
*/
bool is_dl_slot(const slot_t slot, const frame_structure_t *fs)
{
if (fs->frame_type == FDD)
return true;
const tdd_period_config_t *pc = &fs->period_cfg;
slot_t s = get_slot_idx_in_period(slot, fs);
return ((is_mixed_slot(s, fs) && pc->tdd_slot_bitmap[s].num_dl_symbols)
|| (pc->tdd_slot_bitmap[s].slot_type == TDD_NR_DOWNLINK_SLOT));
}
/**
* @brief Returns true for:
* (1) Mixed slot with DL and/or UL symbols
*/
bool is_mixed_slot(const slot_t slot, const frame_structure_t *fs)
{
if (fs->frame_type == FDD)
return false;
slot_t s = get_slot_idx_in_period(slot, fs);
const tdd_period_config_t *pc = &fs->period_cfg;
return pc->tdd_slot_bitmap[s].slot_type == TDD_NR_MIXED_SLOT;
}
@@ -37,8 +37,6 @@
/*#include "PHY/defs_common.h"*/
extern const uint8_t nr_slots_per_frame[5];
/* Scheduler */
extern RAN_CONTEXT_t RC;
extern uint8_t nfapi_mode;
+64 -92
View File
@@ -44,71 +44,44 @@
#include "oai_asn1.h"
#include "executables/position_interface.h"
void set_tdd_config_nr_ue(fapi_nr_tdd_table_t *tdd_table,
int mu,
NR_TDD_UL_DL_Pattern_t *pattern)
static void set_tdd_config_nr_ue(fapi_nr_tdd_table_t *tdd_table, const frame_structure_t *fs)
{
const int nrofDownlinkSlots = pattern->nrofDownlinkSlots;
const int nrofDownlinkSymbols = pattern->nrofDownlinkSymbols;
const int nrofUplinkSlots = pattern->nrofUplinkSlots;
const int nrofUplinkSymbols = pattern->nrofUplinkSymbols;
const int nb_periods_per_frame = get_nb_periods_per_frame(pattern->dl_UL_TransmissionPeriodicity);
const int nb_slots_per_period = ((1 << mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME) / nb_periods_per_frame;
tdd_table->tdd_period_in_slots = nb_slots_per_period;
tdd_table->tdd_period_in_slots = fs->numb_slots_period;
tdd_table->max_tdd_periodicity_list = malloc(fs->numb_slots_period * sizeof(*tdd_table->max_tdd_periodicity_list));
if ((nrofDownlinkSymbols + nrofUplinkSymbols) == 0)
AssertFatal(nb_slots_per_period == (nrofDownlinkSlots + nrofUplinkSlots),
"set_tdd_configuration_nr: given period is inconsistent with current tdd configuration, nrofDownlinkSlots %d, nrofUplinkSlots %d, nb_slots_per_period %d \n",
nrofDownlinkSlots,nrofUplinkSlots,nb_slots_per_period);
else {
AssertFatal(nrofDownlinkSymbols + nrofUplinkSymbols < 14,"illegal symbol configuration DL %d, UL %d\n",nrofDownlinkSymbols,nrofUplinkSymbols);
AssertFatal(nb_slots_per_period == (nrofDownlinkSlots + nrofUplinkSlots + 1),
"set_tdd_configuration_nr: given period is inconsistent with current tdd configuration, nrofDownlinkSlots %d, nrofUplinkSlots %d, nrofMixed slots 1, nb_slots_per_period %d \n",
nrofDownlinkSlots,nrofUplinkSlots,nb_slots_per_period);
}
tdd_table->max_tdd_periodicity_list = (fapi_nr_max_tdd_periodicity_t *) malloc(nb_slots_per_period * sizeof(fapi_nr_max_tdd_periodicity_t));
for(int memory_alloc = 0 ; memory_alloc < nb_slots_per_period; memory_alloc++)
tdd_table->max_tdd_periodicity_list[memory_alloc].max_num_of_symbol_per_slot_list =
(fapi_nr_max_num_of_symbol_per_slot_t *) malloc(NR_NUMBER_OF_SYMBOLS_PER_SLOT*sizeof(fapi_nr_max_num_of_symbol_per_slot_t));
int slot_number = 0;
while(slot_number != nb_slots_per_period) {
if(nrofDownlinkSlots != 0) {
for (int number_of_symbol = 0; number_of_symbol < nrofDownlinkSlots * NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) {
tdd_table->max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol % NR_NUMBER_OF_SYMBOLS_PER_SLOT].slot_config = 0;
if((number_of_symbol + 1) % NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0)
slot_number++;
const tdd_period_config_t *pc = &fs->period_cfg;
for (int i = 0; i < fs->numb_slots_period; i++) {
fapi_nr_max_tdd_periodicity_t *period_list = &tdd_table->max_tdd_periodicity_list[i];
period_list->max_num_of_symbol_per_slot_list =
malloc(NR_NUMBER_OF_SYMBOLS_PER_SLOT * sizeof(*period_list->max_num_of_symbol_per_slot_list));
if (pc->tdd_slot_bitmap[i].slot_type == TDD_NR_DOWNLINK_SLOT) {
for (int s = 0; s < NR_NUMBER_OF_SYMBOLS_PER_SLOT; s++) {
period_list->max_num_of_symbol_per_slot_list[s].slot_config = 0;
}
}
if (nrofDownlinkSymbols != 0 || nrofUplinkSymbols != 0) {
for(int number_of_symbol = 0; number_of_symbol < nrofDownlinkSymbols; number_of_symbol++) {
tdd_table->max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config = 0;
if (pc->tdd_slot_bitmap[i].slot_type == TDD_NR_UPLINK_SLOT) {
for (int s = 0; s < NR_NUMBER_OF_SYMBOLS_PER_SLOT; s++) {
period_list->max_num_of_symbol_per_slot_list[s].slot_config = 1;
}
for(int number_of_symbol = nrofDownlinkSymbols; number_of_symbol < NR_NUMBER_OF_SYMBOLS_PER_SLOT - nrofUplinkSymbols; number_of_symbol++) {
tdd_table->max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config = 2;
}
for(int number_of_symbol = NR_NUMBER_OF_SYMBOLS_PER_SLOT - nrofUplinkSymbols; number_of_symbol < NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) {
tdd_table->max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config = 1;
}
slot_number++;
}
if(nrofUplinkSlots != 0) {
for (int number_of_symbol = 0; number_of_symbol < nrofUplinkSlots * NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) {
tdd_table->max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol%NR_NUMBER_OF_SYMBOLS_PER_SLOT].slot_config = 1;
if((number_of_symbol + 1) % NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0)
slot_number++;
if (pc->tdd_slot_bitmap[i].slot_type == TDD_NR_MIXED_SLOT) {
int dl_symb = pc->tdd_slot_bitmap[i].num_dl_symbols;
int ul_symb = pc->tdd_slot_bitmap[i].num_ul_symbols;
int g_symb = NR_NUMBER_OF_SYMBOLS_PER_SLOT - dl_symb - ul_symb;
for (int s = 0; s < dl_symb; s++) {
period_list->max_num_of_symbol_per_slot_list[s].slot_config = 0;
}
for (int s = dl_symb; s < dl_symb + g_symb; s++) {
period_list->max_num_of_symbol_per_slot_list[s].slot_config = 2;
}
for (int s = dl_symb + g_symb; s < NR_NUMBER_OF_SYMBOLS_PER_SLOT; s++) {
period_list->max_num_of_symbol_per_slot_list[s].slot_config = 1;
}
}
}
}
static void config_common_ue_sa(NR_UE_MAC_INST_t *mac,
NR_ServingCellConfigCommonSIB_t *scc,
int cc_idP)
static void config_common_ue_sa(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommonSIB_t *scc, int cc_idP)
{
fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
mac->phy_config.Mod_id = mac->ue_id;
@@ -166,10 +139,10 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac,
}
}
mac->frame_type = get_frame_type(mac->nr_band, get_softmodem_params()->numerology);
frame_type_t frame_type = get_frame_type(mac->nr_band, get_softmodem_params()->numerology);
// cell config
cfg->cell_config.phy_cell_id = mac->physCellId;
cfg->cell_config.frame_duplex_type = mac->frame_type;
cfg->cell_config.frame_duplex_type = frame_type;
// SSB config
cfg->ssb_config.ss_pbch_power = scc->ss_PBCH_BlockPower;
@@ -191,17 +164,18 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac,
}
}
int period_idx = mac->tdd_UL_DL_ConfigurationCommon ? get_tdd_period_idx(mac->tdd_UL_DL_ConfigurationCommon) : 0;
config_frame_structure(get_softmodem_params()->numerology,
mac->tdd_UL_DL_ConfigurationCommon,
period_idx,
frame_type,
&mac->frame_structure);
// TDD Table Configuration
if (cfg->cell_config.frame_duplex_type == TDD){
set_tdd_config_nr_ue(&cfg->tdd_table_1, cfg->ssb_config.scs_common, &mac->tdd_UL_DL_ConfigurationCommon->pattern1);
if (mac->tdd_UL_DL_ConfigurationCommon->pattern2) {
cfg->tdd_table_2 = (fapi_nr_tdd_table_t *) malloc(sizeof(fapi_nr_tdd_table_t));
set_tdd_config_nr_ue(cfg->tdd_table_2, cfg->ssb_config.scs_common, mac->tdd_UL_DL_ConfigurationCommon->pattern2);
}
}
if (cfg->cell_config.frame_duplex_type == TDD)
set_tdd_config_nr_ue(&cfg->tdd_table, &mac->frame_structure);
// PRACH configuration
uint8_t nb_preambles = 64;
NR_RACH_ConfigCommon_t *rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup;
if(rach_ConfigCommon->totalNumberOfRA_Preambles != NULL)
@@ -214,7 +188,7 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac,
else {
// If absent, the UE applies the SCS as derived from the prach-ConfigurationIndex (for 839)
int config_index = rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex;
const int64_t *prach_config_info_p = get_prach_config_info(mac->frequency_range, config_index, mac->frame_type);
const int64_t *prach_config_info_p = get_prach_config_info(mac->frequency_range, config_index, frame_type);
int format = prach_config_info_p[0];
cfg->prach_config.prach_sub_c_spacing = format == 3 ? 5 : 4;
}
@@ -239,7 +213,9 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac,
(get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing, frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i);
prach_fd_occasion->prach_zero_corr_conf = rach_ConfigCommon->rach_ConfigGeneric.zeroCorrelationZoneConfig;
prach_fd_occasion->num_root_sequences = compute_nr_root_seq(rach_ConfigCommon,
nb_preambles, mac->frame_type, mac->frequency_range);
nb_preambles,
frame_type,
mac->frequency_range);
//prach_fd_occasion->num_unused_root_sequences = ???
}
cfg->prach_config.ssb_per_rach = rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present-1;
@@ -296,24 +272,22 @@ void configure_ntn_ta(module_id_t module_id, ntn_timing_advance_componets_t *ntn
ntn_ta->ntn_params_changed = true;
}
static void config_common_ue(NR_UE_MAC_INST_t *mac,
NR_ServingCellConfigCommon_t *scc,
int cc_idP)
static void config_common_ue(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommon_t *scc, int cc_idP)
{
fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
mac->phy_config.Mod_id = mac->ue_id;
mac->phy_config.CC_id = cc_idP;
frame_type_t frame_type = mac->frame_structure.frame_type;
// carrier config
LOG_D(MAC, "[UE %d] Entering UE Config Common\n", mac->ue_id);
AssertFatal(scc->downlinkConfigCommon, "Not expecting downlinkConfigCommon to be NULL here\n");
NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
if (frequencyInfoDL) { // NeedM for inter-freq handover
mac->nr_band = *frequencyInfoDL->frequencyBandList.list.array[0];
mac->frame_type = get_frame_type(mac->nr_band, get_softmodem_params()->numerology);
frame_type = get_frame_type(mac->nr_band, get_softmodem_params()->numerology);
mac->frequency_range = mac->nr_band < 256 ? FR1 : FR2;
int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
@@ -371,7 +345,7 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac,
// cell config
cfg->cell_config.phy_cell_id = *scc->physCellId;
cfg->cell_config.frame_duplex_type = mac->frame_type;
cfg->cell_config.frame_duplex_type = frame_type;
// SSB config
cfg->ssb_config.ss_pbch_power = scc->ss_PBCH_BlockPower;
@@ -412,14 +386,16 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac,
AssertFatal(1==0,"SSB bitmap size value %d undefined (allowed values 1,2,3) \n", scc->ssb_PositionsInBurst->present);
}
int period_idx = mac->tdd_UL_DL_ConfigurationCommon ? get_tdd_period_idx(mac->tdd_UL_DL_ConfigurationCommon) : 0;
config_frame_structure(*scc->ssbSubcarrierSpacing,
mac->tdd_UL_DL_ConfigurationCommon,
period_idx,
frame_type,
&mac->frame_structure);
// TDD Table Configuration
if (cfg->cell_config.frame_duplex_type == TDD){
set_tdd_config_nr_ue(&cfg->tdd_table_1, cfg->ssb_config.scs_common, &mac->tdd_UL_DL_ConfigurationCommon->pattern1);
if (mac->tdd_UL_DL_ConfigurationCommon->pattern2) {
cfg->tdd_table_2 = (fapi_nr_tdd_table_t *) malloc(sizeof(fapi_nr_tdd_table_t));
set_tdd_config_nr_ue(cfg->tdd_table_2, cfg->ssb_config.scs_common, mac->tdd_UL_DL_ConfigurationCommon->pattern2);
}
}
if (cfg->cell_config.frame_duplex_type == TDD)
set_tdd_config_nr_ue(&cfg->tdd_table, &mac->frame_structure);
// PRACH configuration
uint8_t nb_preambles = 64;
@@ -437,7 +413,7 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac,
else {
// If absent, the UE applies the SCS as derived from the prach-ConfigurationIndex (for 839)
int config_index = rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex;
const int64_t *prach_config_info_p = get_prach_config_info(mac->frequency_range, config_index, mac->frame_type);
const int64_t *prach_config_info_p = get_prach_config_info(mac->frequency_range, config_index, frame_type);
int format = prach_config_info_p[0];
cfg->prach_config.prach_sub_c_spacing = format == 3 ? 5 : 4;
}
@@ -461,7 +437,7 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac,
prach_fd_occasion->k1 = rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart;
prach_fd_occasion->prach_zero_corr_conf = rach_ConfigCommon->rach_ConfigGeneric.zeroCorrelationZoneConfig;
prach_fd_occasion->num_root_sequences =
compute_nr_root_seq(rach_ConfigCommon, nb_preambles, mac->frame_type, mac->frequency_range);
compute_nr_root_seq(rach_ConfigCommon, nb_preambles, frame_type, mac->frequency_range);
cfg->prach_config.ssb_per_rach = rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present - 1;
// prach_fd_occasion->num_unused_root_sequences = ???
@@ -893,9 +869,8 @@ static void configure_logicalChannelBearer(NR_UE_MAC_INST_t *mac,
}
}
void ue_init_config_request(NR_UE_MAC_INST_t *mac, int scs)
void ue_init_config_request(NR_UE_MAC_INST_t *mac, int slots_per_frame)
{
int slots_per_frame = nr_slots_per_frame[scs];
LOG_I(NR_MAC, "Initializing dl and ul config_request. num_slots = %d\n", slots_per_frame);
mac->dl_config_request = calloc(slots_per_frame, sizeof(*mac->dl_config_request));
mac->ul_config_request = calloc(slots_per_frame, sizeof(*mac->ul_config_request));
@@ -2107,17 +2082,17 @@ static void configure_maccellgroup(NR_UE_MAC_INST_t *mac, const NR_MAC_CellGroup
}
}
}
int slots_per_subframe = mac->frame_structure.numb_slots_frame / 10;
if (mcg->bsr_Config) {
int subframes_per_slot = nr_slots_per_frame[scs] / 10;
uint32_t periodic_sf = nr_get_sf_periodicBSRTimer(mcg->bsr_Config->periodicBSR_Timer);
uint32_t target = periodic_sf < UINT_MAX ? periodic_sf * subframes_per_slot : periodic_sf;
uint32_t target = periodic_sf < UINT_MAX ? periodic_sf * slots_per_subframe : periodic_sf;
nr_timer_setup(&si->periodicBSR_Timer, target, 1); // 1 slot update rate
nr_timer_start(&si->periodicBSR_Timer);
uint32_t retx_sf = nr_get_sf_retxBSRTimer(mcg->bsr_Config->retxBSR_Timer);
nr_timer_setup(&si->retxBSR_Timer, retx_sf * subframes_per_slot, 1); // 1 slot update rate
nr_timer_setup(&si->retxBSR_Timer, retx_sf * slots_per_subframe, 1); // 1 slot update rate
if (mcg->bsr_Config->logicalChannelSR_DelayTimer) {
uint32_t dt_sf = get_sr_DelayTimer(*mcg->bsr_Config->logicalChannelSR_DelayTimer);
nr_timer_setup(&si->sr_DelayTimer, dt_sf * subframes_per_slot, 1); // 1 slot update rate
nr_timer_setup(&si->sr_DelayTimer, dt_sf * slots_per_subframe, 1); // 1 slot update rate
}
}
if (mcg->tag_Config) {
@@ -2151,7 +2126,6 @@ static void configure_maccellgroup(NR_UE_MAC_INST_t *mac, const NR_MAC_CellGroup
nr_phr_info_t *phr_info = &si->phr_info;
phr_info->is_configured = mcg->phr_Config->choice.setup != NULL;
if (phr_info->is_configured) {
int slots_per_subframe = nr_slots_per_frame[scs] / 10;
struct NR_PHR_Config *config = mcg->phr_Config->choice.setup;
AssertFatal(config->multiplePHR == 0, "mulitplePHR not supported");
phr_info->PathlossChange_db = config->phr_Tx_PowerFactorChange;
@@ -2644,9 +2618,7 @@ void nr_rrc_mac_config_req_cg(module_id_t module_id,
configure_timeAlignmentTimer(&mac->time_alignment_timer, mac->TAG_list.array[j]->timeAlignmentTimer, mac->current_UL_BWP->scs);
}
configure_logicalChannelBearer(mac,
cell_group_config->rlc_BearerToAddModList,
cell_group_config->rlc_BearerToReleaseList);
configure_logicalChannelBearer(mac, cell_group_config->rlc_BearerToAddModList, cell_group_config->rlc_BearerToReleaseList);
if (ue_Capability)
handle_mac_uecap_info(mac, ue_Capability);
@@ -2657,7 +2629,7 @@ void nr_rrc_mac_config_req_cg(module_id_t module_id,
build_ssb_to_ro_map(mac);
if (!mac->dl_config_request || !mac->ul_config_request)
ue_init_config_request(mac, mac->current_DL_BWP->scs);
ue_init_config_request(mac, mac->frame_structure.numb_slots_frame);
ret = pthread_mutex_unlock(&mac->if_mutex);
AssertFatal(!ret, "mutex failed %d\n", ret);
}
+1 -1
View File
@@ -599,7 +599,7 @@ typedef struct NR_UE_MAC_INST_s {
NR_UL_TIME_ALIGNMENT_t ul_time_alignment;
NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon;
frame_type_t frame_type;
frame_structure_t frame_structure;
/* Random Access */
/// CRNTI
+1 -2
View File
@@ -367,7 +367,7 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *p
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);
void ue_init_config_request(NR_UE_MAC_INST_t *mac, int slots_per_frame);
fapi_nr_dl_config_request_t *get_dl_config_request(NR_UE_MAC_INST_t *mac, int slot);
@@ -376,7 +376,6 @@ void remove_ul_config_last_item(fapi_nr_ul_config_request_pdu_t *pdu);
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);
void clear_ul_config_request(NR_UE_MAC_INST_t *mac, int scs);
int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm);
// PUSCH scheduler:
+2 -2
View File
@@ -94,7 +94,7 @@ void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac)
// sf80 default for retxBSR_Timer sf10 for periodicBSR_Timer
int mu = mac->current_UL_BWP ? mac->current_UL_BWP->scs : get_softmodem_params()->numerology;
int subframes_per_slot = nr_slots_per_frame[mu] / 10;
int subframes_per_slot = get_slots_per_frame_from_scs(mu) / 10;
nr_timer_setup(&mac->scheduling_info.retxBSR_Timer, 80 * subframes_per_slot, 1); // 1 slot update rate
nr_timer_setup(&mac->scheduling_info.periodicBSR_Timer, 10 * subframes_per_slot, 1); // 1 slot update rate
@@ -139,7 +139,7 @@ NR_UE_MAC_INST_t *nr_l2_init_ue(int nb_inst)
nr_ue_init_mac(mac);
nr_ue_mac_default_configs(mac);
if (IS_SA_MODE(get_softmodem_params()))
ue_init_config_request(mac, get_softmodem_params()->numerology);
ue_init_config_request(mac, get_slots_per_frame_from_scs(get_softmodem_params()->numerology));
}
int rc = rlc_module_init(0);
+5 -8
View File
@@ -84,7 +84,7 @@ void init_RA(NR_UE_MAC_INST_t *mac,
// PRACH shall be as specified for QPSK modulated DFT-s-OFDM of equivalent RB allocation (38.101-1)
prach_resources->RA_PCMAX = nr_get_Pcmax(mac->p_Max,
mac->nr_band,
mac->frame_type,
mac->frame_structure.frame_type,
mac->frequency_range,
mac->current_UL_BWP->channel_bandwidth,
2,
@@ -617,8 +617,7 @@ void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac, uint8_t CC_id, frame_t frameP, s
RA_config_t *ra = &mac->ra;
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->current_UL_BWP->rach_ConfigCommon;
const double ta_Common_ms = GET_COMPLETE_TIME_ADVANCE_MS(&mac->ntn_ta);
const int mu = mac->current_UL_BWP->scs;
const int slots_per_ms = nr_slots_per_frame[mu] / 10;
const int slots_per_ms = mac->frame_structure.numb_slots_frame / 10;
// start contention resolution timer
const int RA_contention_resolution_timer_ms = (nr_rach_ConfigCommon->ra_ContentionResolutionTimer + 1) << 3;
@@ -914,14 +913,12 @@ int16_t nr_get_RA_window_4Step(const NR_RACH_ConfigCommon_t *rach_ConfigCommon)
void nr_get_RA_window(NR_UE_MAC_INST_t *mac)
{
RA_config_t *ra = &mac->ra;
NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon;
AssertFatal(&setup->rach_ConfigGeneric != NULL, "In %s: FATAL! rach_ConfigGeneric is NULL...\n", __FUNCTION__);
const double ta_Common_ms = GET_COMPLETE_TIME_ADVANCE_MS(&mac->ntn_ta);
const int mu = mac->current_DL_BWP->scs;
const int slots_per_ms = nr_slots_per_frame[mu] / 10;
const int ra_Offset_slots = ra->RA_offset * nr_slots_per_frame[mu];
int slots_per_frame = mac->frame_structure.numb_slots_frame;
const int slots_per_ms = slots_per_frame / 10;
const int ra_Offset_slots = ra->RA_offset * slots_per_frame;
const int ta_Common_slots = (int)ceil(ta_Common_ms * slots_per_ms);
ra->RA_window_cnt = ra_Offset_slots + ta_Common_slots; // taking into account the 2 frames gap introduced by OAI gNB
@@ -515,7 +515,7 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
NR_BWP_Id_t dl_bwp_id = current_DL_BWP ? current_DL_BWP->bwp_id : 0;
NR_BWP_PDCCH_t *pdcch_config = &mac->config_BWP_PDCCH[dl_bwp_id];
int scs = current_DL_BWP ? current_DL_BWP->scs : get_softmodem_params()->numerology;
const int slots_per_frame = nr_slots_per_frame[scs];
const int slots_per_frame = get_slots_per_frame_from_scs(scs);
if (mac->get_sib1) {
int ssb_sc_offset_norm;
if (mac->ssb_subcarrier_offset < 24 && mac->frequency_range == FR1)
@@ -347,7 +347,7 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
// modulated CP-OFDM of equivalent RB allocation.
int P_CMAX = nr_get_Pcmax(mac->p_Max,
mac->nr_band,
mac->frame_type,
mac->frame_structure.frame_type,
mac->frequency_range,
current_UL_BWP->channel_bandwidth,
2,
@@ -529,7 +529,7 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac,
int M_pusch_component = 10 * log10((pow(2, mu)) * num_rb);
int P_CMAX = nr_get_Pcmax(mac->p_Max,
mac->nr_band,
mac->frame_type,
mac->frame_structure.frame_type,
mac->frequency_range,
mac->current_UL_BWP->channel_bandwidth,
qm,
@@ -619,7 +619,7 @@ int get_srs_tx_power_ue(NR_UE_MAC_INST_t *mac,
// allocation.
int P_CMAX = nr_get_Pcmax(mac->p_Max,
mac->nr_band,
mac->frame_type,
mac->frame_structure.frame_type,
mac->frequency_range,
mac->current_UL_BWP->channel_bandwidth,
2,
+11 -12
View File
@@ -235,6 +235,7 @@ static void configure_ratematching_csi(fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsc
int frame,
int slot,
int mu,
int slots_per_frame,
NR_PDSCH_Config_t *pdsch_config)
{
// only for C-RNTI, MCS-C-RNTI, CS-RNTI (and only C-RNTI is supported for now)
@@ -258,7 +259,7 @@ static void configure_ratematching_csi(fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsc
AssertFatal(zp_res->periodicityAndOffset, "periodicityAndOffset cannot be null for periodic ZP resource\n");
int period, offset;
csi_period_offset(NULL, zp_res->periodicityAndOffset, &period, &offset);
if((frame * nr_slots_per_frame[mu] + slot - offset) % period != 0)
if((frame * slots_per_frame + slot - offset) % period != 0)
continue;
AssertFatal(dlsch_pdu->numCsiRsForRateMatching < NFAPI_MAX_NUM_CSI_RATEMATCH, "csiRsForRateMatching out of bounds\n");
fapi_nr_dl_config_csirs_pdu_rel15_t *csi_pdu = &dlsch_pdu->csiRsForRateMatching[dlsch_pdu->numCsiRsForRateMatching];
@@ -705,7 +706,8 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac,
}
dlsch_pdu->numCsiRsForRateMatching = 0;
configure_ratematching_csi(dlsch_pdu, dl_config, rnti_type, frame, slot, dlsch_pdu->SubcarrierSpacing, pdsch_config);
int slots_frame = mac->frame_structure.numb_slots_frame;
configure_ratematching_csi(dlsch_pdu, dl_config, rnti_type, frame, slot, dlsch_pdu->SubcarrierSpacing, slots_frame, pdsch_config);
/* IDENTIFIER_DCI_FORMATS */
@@ -1034,7 +1036,8 @@ static int nr_ue_process_dci_dl_11(NR_UE_MAC_INST_t *mac,
nr_rnti_type_t rnti_type = get_rnti_type(mac, dci_ind->rnti);
dlsch_pdu->numCsiRsForRateMatching = 0;
configure_ratematching_csi(dlsch_pdu, dl_config, rnti_type, frame, slot, current_DL_BWP->scs, pdsch_Config);
int slots_frame = mac->frame_structure.numb_slots_frame;
configure_ratematching_csi(dlsch_pdu, dl_config, rnti_type, frame, slot, current_DL_BWP->scs, slots_frame, pdsch_Config);
/* IDENTIFIER_DCI_FORMATS */
/* CARRIER_IND */
@@ -1468,8 +1471,7 @@ void set_harq_status(NR_UE_MAC_INST_t *mac,
current_harq->dai_cumul = 0;
current_harq->delta_pucch = delta_pucch;
// FIXME k0 != 0 currently not taken into consideration
int scs = mac->current_DL_BWP ? mac->current_DL_BWP->scs : get_softmodem_params()->numerology;
int slots_per_frame = nr_slots_per_frame[scs];
int slots_per_frame = mac->frame_structure.numb_slots_frame;
current_harq->ul_frame = frame;
current_harq->ul_slot = slot + data_toul_fb;
if (current_harq->ul_slot >= slots_per_frame) {
@@ -1532,8 +1534,7 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
long *pusch_id = NULL;
long *id0 = NULL;
const int scs = current_UL_BWP->scs;
int subframe_number = slot / (nr_slots_per_frame[scs]/10);
int subframe_number = slot / (mac->frame_structure.numb_slots_frame / 10);
pucch_pdu->rnti = rnti;
LOG_D(NR_MAC, "initial_pucch_id %d, pucch_resource %p\n", pucch->initial_pucch_id, pucch->pucch_resource);
@@ -2503,7 +2504,7 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *p
int SR_period; int SR_offset;
find_period_offset_SR(sr_Config, &SR_period, &SR_offset);
const int n_slots_frame = nr_slots_per_frame[current_UL_BWP->scs];
const int n_slots_frame = mac->frame_structure.numb_slots_frame;
int sfn_sf = frame * n_slots_frame + slot;
if ((sfn_sf - SR_offset) % SR_period == 0) {
@@ -2613,7 +2614,7 @@ int nr_get_csi_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCC
if(csirep->reportConfigType.present == NR_CSI_ReportConfig__reportConfigType_PR_periodic) {
int period, offset;
csi_period_offset(csirep, NULL, &period, &offset);
const int n_slots_frame = nr_slots_per_frame[current_UL_BWP->scs];
const int n_slots_frame = mac->frame_structure.numb_slots_frame;
if (((n_slots_frame*frame + slot - offset)%period) == 0 && pucch_Config) {
int csi_res_id = -1;
for (int i = 0; i < csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.count; i++) {
@@ -3433,12 +3434,10 @@ static void set_time_alignment(NR_UE_MAC_INST_t *mac, int ta, ta_type_t type, in
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &mac->ul_time_alignment;
ul_time_alignment->ta_command = ta;
ul_time_alignment->ta_apply = type;
const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, mac->current_UL_BWP->scs);
const int n_slots_frame = nr_slots_per_frame[mac->current_UL_BWP->scs];
const int n_slots_frame = mac->frame_structure.numb_slots_frame;
ul_time_alignment->frame = (frame + (slot + ntn_ue_koffset) / n_slots_frame) % MAX_FRAME_NUMBER;
ul_time_alignment->slot = (slot + ntn_ue_koffset) % n_slots_frame;
// start or restart the timeAlignmentTimer associated with the indicated TAG
nr_timer_start(&mac->time_alignment_timer);
}
+22 -34
View File
@@ -81,9 +81,9 @@ static uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac,
int P_MAX,
bool *BSRsent);
void clear_ul_config_request(NR_UE_MAC_INST_t *mac, int scs)
static void clear_ul_config_request(NR_UE_MAC_INST_t *mac)
{
int slots = nr_slots_per_frame[scs];
int slots = mac->frame_structure.numb_slots_frame;
for (int i = 0; i < slots ; i++) {
fapi_nr_ul_config_request_t *ul_config = mac->ul_config_request + i;
verifyMutex(pthread_mutex_lock(&ul_config->mutex_ul_config));
@@ -94,10 +94,8 @@ void clear_ul_config_request(NR_UE_MAC_INST_t *mac, int scs)
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)
{
NR_TDD_UL_DL_ConfigCommon_t *tdd_config = mac->tdd_UL_DL_ConfigurationCommon;
// Check if requested on the right slot
if (!is_nr_UL_slot(tdd_config, slot_tx, mac->frame_type)) {
if (!is_ul_slot(slot_tx, &mac->frame_structure)) {
LOG_E(NR_MAC, "Lock of UL config for PDU type %d called for slot %d which is not UL\n", pdu_type, slot_tx);
return NULL;
}
@@ -177,11 +175,10 @@ void handle_time_alignment_timer_expired(NR_UE_MAC_INST_t *mac)
// release SRS for all Serving Cells;
release_PUCCH_SRS(mac);
// clear any configured downlink assignments and uplink grants;
int scs = mac->current_UL_BWP ? mac->current_UL_BWP->scs : get_softmodem_params()->numerology;
if (mac->dl_config_request)
memset(mac->dl_config_request, 0, sizeof(*mac->dl_config_request));
if (mac->ul_config_request)
clear_ul_config_request(mac, scs);
clear_ul_config_request(mac);
// clear any PUSCH resources for semi-persistent CSI reporting
// TODO we don't have semi-persistent CSI reporting
// maintain N_TA
@@ -284,9 +281,8 @@ fapi_nr_ul_config_request_pdu_t *fapiLockIterator(fapi_nr_ul_config_request_t *u
fapi_nr_ul_config_request_pdu_t *lockGet_ul_iterator(NR_UE_MAC_INST_t *mac, frame_t frame_tx, int slot_tx)
{
NR_TDD_UL_DL_ConfigCommon_t *tdd_config = mac->tdd_UL_DL_ConfigurationCommon;
//Check if requested on the right slot
if (!is_nr_UL_slot(tdd_config, slot_tx, mac->frame_type)) {
if (!is_ul_slot(slot_tx, &mac->frame_structure)) {
LOG_E(NR_MAC, "UL lock iterator called for slot %d which is not UL\n", slot_tx);
return NULL;
}
@@ -1271,10 +1267,9 @@ void nr_ue_aperiodic_srs_scheduling(NR_UE_MAC_INST_t *mac, long resource_trigger
AssertFatal(slot_offset > GET_DURATION_RX_TO_TX(&mac->ntn_ta),
"Slot offset between DCI and aperiodic SRS (%d) needs to be higher than DURATION_RX_TO_TX (%ld)\n",
slot_offset, GET_DURATION_RX_TO_TX(&mac->ntn_ta));
int n_slots_frame = nr_slots_per_frame[current_UL_BWP->scs];
int n_slots_frame = mac->frame_structure.numb_slots_frame;
int sched_slot = (slot + slot_offset) % n_slots_frame;
NR_TDD_UL_DL_ConfigCommon_t *tdd_config = mac->tdd_UL_DL_ConfigurationCommon;
if (!is_nr_UL_slot(tdd_config, sched_slot, mac->frame_type)) {
if (!is_ul_slot(sched_slot, &mac->frame_structure)) {
LOG_E(NR_MAC, "Slot for scheduling aperiodic SRS %d is not an UL slot\n", sched_slot);
return;
}
@@ -1326,8 +1321,7 @@ static bool nr_ue_periodic_srs_scheduling(NR_UE_MAC_INST_t *mac, frame_t frame,
uint16_t period = srs_period[srs_resource->resourceType.choice.periodic->periodicityAndOffset_p.present];
uint16_t offset = get_nr_srs_offset(srs_resource->resourceType.choice.periodic->periodicityAndOffset_p);
int n_slots_frame = nr_slots_per_frame[current_UL_BWP->scs];
int n_slots_frame = mac->frame_structure.numb_slots_frame;
// Check if UE should transmit the SRS
if((frame*n_slots_frame+slot-offset)%period == 0) {
@@ -1409,11 +1403,10 @@ void schedule_RA_after_SR_failure(NR_UE_MAC_INST_t *mac)
// release SRS for all Serving Cells;
release_PUCCH_SRS(mac);
// clear any configured downlink assignments and uplink grants;
int scs = mac->current_UL_BWP->scs;
if (mac->dl_config_request)
memset(mac->dl_config_request, 0, sizeof(*mac->dl_config_request));
if (mac->ul_config_request)
clear_ul_config_request(mac, scs);
clear_ul_config_request(mac);
// clear any PUSCH resources for semi-persistent CSI reporting
// TODO we don't have semi-persistent CSI reporting
}
@@ -1620,7 +1613,7 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info)
int tx_power = pdu->tx_power;
int P_CMAX = nr_get_Pcmax(mac->p_Max,
mac->nr_band,
mac->frame_type,
mac->frame_structure.frame_type,
mac->frequency_range,
mac->current_UL_BWP->channel_bandwidth,
pdu->qam_mod_order,
@@ -1756,6 +1749,7 @@ int nr_ue_pusch_scheduler(const NR_UE_MAC_INST_t *mac,
// Get the numerology to calculate the Tx frame and slot
int mu = current_UL_BWP->scs;
int slots_per_frame = mac->frame_structure.numb_slots_frame;
// k2 as per 3GPP TS 38.214 version 15.9.0 Release 15 ch 6.1.2.1.1
// PUSCH time domain resource allocation is higher layer configured from uschTimeDomainAllocationList in either pusch-ConfigCommon
@@ -1786,9 +1780,8 @@ int nr_ue_pusch_scheduler(const NR_UE_MAC_INST_t *mac,
GET_DURATION_RX_TO_TX(&mac->ntn_ta),
GET_DURATION_RX_TO_TX(&mac->ntn_ta));
*slot_tx = (current_slot + k2 + delta) % nr_slots_per_frame[mu];
*frame_tx = (current_frame + (current_slot + k2 + delta) / nr_slots_per_frame[mu]) % MAX_FRAME_NUMBER;
*slot_tx = (current_slot + k2 + delta) % slots_per_frame;
*frame_tx = (current_frame + (current_slot + k2 + delta) / slots_per_frame) % MAX_FRAME_NUMBER;
} else {
AssertFatal(k2 > GET_DURATION_RX_TO_TX(&mac->ntn_ta),
@@ -1804,13 +1797,11 @@ int nr_ue_pusch_scheduler(const NR_UE_MAC_INST_t *mac,
}
// Calculate TX slot and frame
*slot_tx = (current_slot + k2) % nr_slots_per_frame[mu];
*frame_tx = (current_frame + (current_slot + k2) / nr_slots_per_frame[mu]) % MAX_FRAME_NUMBER;
*slot_tx = (current_slot + k2) % slots_per_frame;
*frame_tx = (current_frame + (current_slot + k2) / slots_per_frame) % MAX_FRAME_NUMBER;
}
LOG_D(NR_MAC, "[%04d.%02d] UL transmission in [%04d.%02d] (k2 %ld delta %d)\n", current_frame, current_slot, *frame_tx, *slot_tx, k2, delta);
return 0;
}
@@ -1911,7 +1902,7 @@ static void build_ro_list(NR_UE_MAC_INST_t *mac)
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 / x;
nb_of_frames_per_prach_conf_period = 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
@@ -1923,7 +1914,7 @@ static void build_ro_list(NR_UE_MAC_INST_t *mac)
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 = nr_slots_per_frame[mu];
prach_conf_period_list->nb_of_slot = slots_per_frame;
LOG_D(NR_MAC,"PRACH Conf Period Idx %d\n", period_idx);
@@ -1938,7 +1929,7 @@ static void build_ro_list(NR_UE_MAC_INST_t *mac)
// For every slot in a frame
// -------------------------
for (int slot = 0; slot < nr_slots_per_frame[mu]; slot++) {
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 ((s_map>>map_shift) & 0x01) {
@@ -2561,7 +2552,7 @@ void nr_schedule_csi_for_im(NR_UE_MAC_INST_t *mac, int frame, int slot)
for (int id = 0; id < csi_measconfig->csi_IM_ResourceToAddModList->list.count; id++){
imcsi = csi_measconfig->csi_IM_ResourceToAddModList->list.array[id];
csi_period_offset(NULL,imcsi->periodicityAndOffset,&period,&offset);
if((frame*nr_slots_per_frame[mu]+slot-offset)%period != 0)
if((frame * mac->frame_structure.numb_slots_frame + slot - offset ) %period != 0)
continue;
fapi_nr_dl_config_csiim_pdu_rel15_t *csiim_config_pdu = &dl_config->dl_config_list[dl_config->number_pdus].csiim_config_pdu.csiim_config_rel15;
csiim_config_pdu->bwp_size = bwp_size;
@@ -2802,7 +2793,7 @@ void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot)
NR_NZP_CSI_RS_Resource_t *nzpcsi = csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.array[id];
int period, offset;
csi_period_offset(NULL, nzpcsi->periodicityAndOffset, &period, &offset);
if((frame * nr_slots_per_frame[mu] + slot-offset) % period != 0)
if((frame * mac->frame_structure.numb_slots_frame + slot-offset) % period != 0)
continue;
NR_CSI_ResourceConfigId_t csi_res_id = find_CSI_resourceconfig(csi_measconfig, dl_bwp_id, nzpcsi->nzp_CSI_RS_ResourceId);
// do not schedule reseption of this CSI-RS if not associated with current BWP
@@ -2850,10 +2841,8 @@ static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, sub_fra
NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon;
NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
const int bwp_id = mac->current_UL_BWP->bwp_id;
NR_TDD_UL_DL_ConfigCommon_t *tdd_config = mac->tdd_UL_DL_ConfigurationCommon;
if (is_nr_UL_slot(tdd_config, slotP, mac->frame_type)) {
if (is_ul_slot(slotP, &mac->frame_structure)) {
// WIP Need to get the proper selected ssb_idx
// Initial beam selection functionality is not available yet
uint8_t selected_gnb_ssb_idx = mac->mib_ssb;
@@ -2986,8 +2975,7 @@ static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, sub_fra
} else if (ra->ra_type == RA_2_STEP) {
NR_MsgA_PUSCH_Resource_r16_t *msgA_PUSCH_Resource =
mac->current_UL_BWP->msgA_ConfigCommon_r16->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16;
int mu = nr_get_prach_mu(mac->current_UL_BWP->msgA_ConfigCommon_r16, setup);
const int n_slots_frame = nr_slots_per_frame[mu];
const int n_slots_frame = mac->frame_structure.numb_slots_frame;
slot_t msgA_pusch_slot = (slotP + msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16) % n_slots_frame;
frame_t msgA_pusch_frame =
(frameP + ((slotP + msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16) / n_slots_frame)) % 1024;
+4 -17
View File
@@ -175,15 +175,9 @@ uint8_t sl_determine_if_SSB_slot(uint16_t frame, uint16_t slot, uint16_t slots_p
return 0;
}
static uint8_t sl_psbch_scheduler(sl_nr_ue_mac_params_t *sl_mac_params, int ue_id, int frame, int slot)
static uint8_t sl_psbch_scheduler(sl_nr_ue_mac_params_t *sl_mac_params, int ue_id, int frame, int slot, int slots_per_frame)
{
uint8_t config_type = 0, is_psbch_rx_slot = 0, is_psbch_tx_slot = 0;
sl_nr_phy_config_request_t *sl_cfg = &sl_mac_params->sl_phy_config.sl_config_req;
uint16_t scs = sl_cfg->sl_bwp_config.sl_scs;
uint16_t slots_per_frame = nr_slots_per_frame[scs];
if (sl_mac_params->rx_sl_bch.status) {
is_psbch_rx_slot = sl_determine_if_SSB_slot(frame, slot, slots_per_frame, &sl_mac_params->rx_sl_bch);
@@ -259,16 +253,9 @@ static void sl_adjust_indices_based_on_timing(sl_nr_ue_mac_params_t *sl_mac,
}
// Adjust indices as new timing is acquired
static void sl_actions_after_new_timing(sl_nr_ue_mac_params_t *sl_mac,
int ue_id,
int frame, int slot)
static void sl_actions_after_new_timing(sl_nr_ue_mac_params_t *sl_mac, int ue_id, int frame, int slot, int slots_per_frame)
{
uint8_t mu = sl_mac->sl_phy_config.sl_config_req.sl_bwp_config.sl_scs;
uint8_t slots_per_frame = nr_slots_per_frame[mu];
sl_determine_slot_bitmap(sl_mac, ue_id);
sl_mac->N_SL_SLOTS = sl_determine_num_sidelink_slots(sl_mac, ue_id, &sl_mac->N_SSB_16frames);
sl_adjust_indices_based_on_timing(sl_mac, ue_id, frame, slot, slots_per_frame);
}
@@ -385,7 +372,7 @@ void nr_ue_sidelink_scheduler(nr_sidelink_indication_t *sl_ind, NR_UE_MAC_INST_t
// Adjust indices as new timing is acquired
if (sl_mac->timing_acquired) {
sl_actions_after_new_timing(sl_mac, ue_id, sl_ind->frame_tx, sl_ind->slot_tx);
sl_actions_after_new_timing(sl_mac, ue_id, sl_ind->frame_tx, sl_ind->slot_tx, mac->frame_structure.numb_slots_frame);
sl_mac->timing_acquired = false;
}
@@ -399,7 +386,7 @@ void nr_ue_sidelink_scheduler(nr_sidelink_indication_t *sl_ind, NR_UE_MAC_INST_t
uint8_t tti_action = 0;
// Check if PSBCH slot and PSBCH should be transmitted or Received
tti_action = sl_psbch_scheduler(sl_mac, ue_id, frame, slot);
tti_action = sl_psbch_scheduler(sl_mac, ue_id, frame, slot, mac->frame_structure.numb_slots_frame);
#if 0 // To be expanded later
// TBD .. Check for Actions coming out of TX resource pool
@@ -92,7 +92,7 @@ TEST(test_pucch_power_state, test_accumulated_delta_pucch)
pucch_Config.pucch_PowerControl = &power_config;
mac.G_b_f_c = 0;
mac.pucch_power_control_initialized = true;
mac.frame_type = TDD;
mac.frame_structure.frame_type = TDD;
int scs = 1;
int sum_delta_pucch = 3;
@@ -106,7 +106,7 @@ TEST(test_pucch_power_state, test_accumulated_delta_pucch)
uint16_t start_prb = 0;
int P_CMAX = nr_get_Pcmax(23,
mac.nr_band,
mac.frame_type,
mac.frame_structure.frame_type,
FR1,
current_UL_BWP.channel_bandwidth,
2,
@@ -201,7 +201,7 @@ TEST(pusch_power_control, pusch_power_control_msg3)
pusch_Config.pusch_PowerControl = &pusch_PowerControl;
pusch_PowerControl.tpc_Accumulation = (long*)1;
mac.pusch_power_control_initialized = true;
mac.frame_type = TDD;
mac.frame_structure.frame_type = TDD;
// msg3 cofiguration as in 5g_rfsimulator testcase
int num_rb = 8;
@@ -218,7 +218,7 @@ TEST(pusch_power_control, pusch_power_control_msg3)
int P_CMAX = nr_get_Pcmax(23,
mac.nr_band,
mac.frame_type,
mac.frame_structure.frame_type,
FR1,
current_UL_BWP.channel_bandwidth,
Qm,
@@ -294,7 +294,7 @@ TEST(pusch_power_control, pusch_power_data)
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
mac.nr_band = 78;
mac.frame_type = TDD;
mac.frame_structure.frame_type = TDD;
bool is_rar_tx_retx = false;
int num_rb = 5;
@@ -319,7 +319,7 @@ TEST(pusch_power_control, pusch_power_data)
int P_CMAX = nr_get_Pcmax(23,
mac.nr_band,
mac.frame_type,
mac.frame_structure.frame_type,
FR1,
current_UL_BWP.channel_bandwidth,
Qm,
@@ -444,11 +444,11 @@ TEST(pusch_power_control, pusch_power_control_state)
pusch_Config.pusch_PowerControl = &pusch_PowerControl;
long p0_NominalWithGrant = 0;
current_UL_BWP.p0_NominalWithGrant = &p0_NominalWithGrant;
mac.frame_type = TDD;
mac.frame_structure.frame_type = TDD;
int P_CMAX = nr_get_Pcmax(23,
mac.nr_band,
mac.frame_type,
mac.frame_structure.frame_type,
FR1,
current_UL_BWP.channel_bandwidth,
Qm,
@@ -96,7 +96,7 @@ TEST(test_init_ra, four_step_cbra)
nr_rach_ConfigCommon.msg1_SubcarrierSpacing = &scs;
mac.p_Max = 23;
mac.nr_band = 78;
mac.frame_type = TDD;
mac.frame_structure.frame_type = TDD;
mac.frequency_range = FR1;
init_RA(&mac, &prach_resources, &nr_rach_ConfigCommon, &rach_ConfigGeneric, rach_ConfigDedicated);
@@ -121,7 +121,7 @@ TEST(test_init_ra, four_step_cfra)
nr_rach_ConfigCommon.msg1_SubcarrierSpacing = &scs;
mac.p_Max = 23;
mac.nr_band = 78;
mac.frame_type = TDD;
mac.frame_structure.frame_type = TDD;
mac.frequency_range = FR1;
NR_RACH_ConfigDedicated_t rach_ConfigDedicated = {0};
+13 -131
View File
@@ -279,97 +279,6 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort
return mat;
}
/**
* @brief Configures the TDD period, including bitmap, in the frame structure
*
* This function sets the TDD period configuration for DL, UL, and mixed slots in
* the specified frame structure instance, according to the given pattern, and
* updates the bitmap.
*
* @param pattern NR_TDD_UL_DL_Pattern_t configuration containing TDD slots and symbols configuration
* @param fs frame_structure_t pointer
* @param curr_total_slot current position in the slot bitmap to start from
*
* @return Number of slots in the configured TDD period
*/
static uint8_t set_tdd_bmap_period(NR_TDD_UL_DL_Pattern_t *pattern, tdd_period_config_t *pc, int8_t curr_total_slot)
{
int8_t n_dl_slot = pattern->nrofDownlinkSlots;
int8_t n_ul_slot = pattern->nrofUplinkSlots;
int8_t n_dl_symbols = pattern->nrofDownlinkSymbols;
int8_t n_ul_symbols = pattern->nrofUplinkSymbols;
// Total slots in the period: if DL/UL symbols are present, is mixed slot
const bool has_mixed_slot = (n_ul_symbols + n_dl_symbols) > 0;
int8_t total_slot = has_mixed_slot ? n_dl_slot + n_ul_slot + 1 : n_dl_slot + n_ul_slot;
/** Update TDD period configuration:
* mixed slots with DL symbols are counted as DL slots
* mixed slots with UL symbols are counted as UL slots */
pc->num_dl_slots += (n_dl_slot + (n_dl_symbols > 0));
pc->num_ul_slots += (n_ul_slot + (n_ul_symbols > 0));
// Populate the slot bitmap for each slot in the TDD period
for (int i = 0; i < total_slot; i++) {
tdd_bitmap_t *bitmap = &pc->tdd_slot_bitmap[i + curr_total_slot];
if (i < n_dl_slot)
bitmap->slot_type = TDD_NR_DOWNLINK_SLOT;
else if ((i == n_dl_slot) && has_mixed_slot) {
bitmap->slot_type = TDD_NR_MIXED_SLOT;
bitmap->num_dl_symbols = n_dl_symbols;
bitmap->num_ul_symbols = n_ul_symbols;
} else if (n_ul_slot)
bitmap->slot_type = TDD_NR_UPLINK_SLOT;
}
LOG_I(NR_MAC,
"Set TDD configuration period to: %d DL slots, %d UL slots, %d slots per period (NR_TDD_UL_DL_Pattern is %d DL slots, %d "
"UL slots, %d DL symbols, %d UL symbols)\n",
pc->num_dl_slots,
pc->num_ul_slots,
total_slot,
n_dl_slot,
n_ul_slot,
n_dl_symbols,
n_ul_symbols);
return total_slot;
}
/**
* @brief Configures TDD patterns (1 or 2) in the frame structure
*
* This function sets up the TDD configuration in the frame structure by applying
* DL and UL patterns as defined in NR_TDD_UL_DL_ConfigCommon.
* It handles both TDD pattern1 and pattern2.
*
* @param tdd NR_TDD_UL_DL_ConfigCommon_t pointer containing pattern1 and pattern2
* @param fs Pointer to the frame structure to update with the configured TDD patterns.
*
* @return void
*/
static void config_tdd_patterns(NR_TDD_UL_DL_ConfigCommon_t *tdd, frame_structure_t *fs)
{
int num_of_patterns = 1;
uint8_t nb_slots_p2 = 0;
// Reset num dl/ul slots
tdd_period_config_t *pc = &fs->period_cfg;
pc->num_dl_slots = 0;
pc->num_ul_slots = 0;
// Pattern1
uint8_t nb_slots_p1 = set_tdd_bmap_period(&tdd->pattern1, pc, 0);
// Pattern2
if (tdd->pattern2) {
num_of_patterns++;
nb_slots_p2 = set_tdd_bmap_period(tdd->pattern2, pc, nb_slots_p1);
}
LOG_I(NR_MAC,
"Configured %d TDD patterns (total slots: pattern1 = %d, pattern2 = %d)\n",
num_of_patterns,
nb_slots_p1,
nb_slots_p2);
}
/**
* @brief Get the first UL slot index in period
* @param fs frame structure
@@ -380,7 +289,7 @@ int get_first_ul_slot(const frame_structure_t *fs, bool mixed)
{
DevAssert(fs);
if (fs->is_tdd) {
if (fs->frame_type == TDD) {
for (int i = 0; i < fs->numb_slots_period; i++) {
if ((mixed && is_ul_slot(i, fs)) || fs->period_cfg.tdd_slot_bitmap[i].slot_type == TDD_NR_UPLINK_SLOT) {
return i;
@@ -396,7 +305,7 @@ int get_first_ul_slot(const frame_structure_t *fs, bool mixed)
*/
int get_dl_slots_per_period(const frame_structure_t *fs)
{
return fs->is_tdd ? fs->period_cfg.num_dl_slots : fs->numb_slots_frame;
return fs->frame_type == TDD ? fs->period_cfg.num_dl_slots : fs->numb_slots_frame;
}
/**
@@ -404,7 +313,7 @@ int get_dl_slots_per_period(const frame_structure_t *fs)
*/
int get_ul_slots_per_period(const frame_structure_t *fs)
{
return fs->is_tdd ? fs->period_cfg.num_ul_slots : fs->numb_slots_frame;
return fs->frame_type == TDD ? fs->period_cfg.num_ul_slots : fs->numb_slots_frame;
}
/**
@@ -416,7 +325,7 @@ int get_full_ul_slots_per_period(const frame_structure_t *fs)
{
DevAssert(fs);
if (!fs->is_tdd)
if (fs->frame_type == FDD)
return fs->numb_slots_frame;
int count = 0;
@@ -438,7 +347,7 @@ int get_full_dl_slots_per_period(const frame_structure_t *fs)
{
DevAssert(fs);
if (!fs->is_tdd)
if (fs->frame_type == FDD)
return fs->numb_slots_frame;
int count = 0;
@@ -456,7 +365,7 @@ int get_full_dl_slots_per_period(const frame_structure_t *fs)
*/
int get_ul_slots_per_frame(const frame_structure_t *fs)
{
return fs->is_tdd ? fs->numb_period_frame * get_ul_slots_per_period(fs) : fs->numb_slots_frame;
return fs->frame_type == TDD ? fs->numb_period_frame * get_ul_slots_per_period(fs) : fs->numb_slots_frame;
}
/**
@@ -471,7 +380,7 @@ int get_ul_slot_offset(const frame_structure_t *fs, int idx, bool count_mixed)
DevAssert(fs);
// FDD
if (!fs->is_tdd)
if (fs->frame_type == FDD)
return idx;
// UL slots indexes in period
@@ -493,37 +402,6 @@ int get_ul_slot_offset(const frame_structure_t *fs, int idx, bool count_mixed)
return ul_slot_idxs[ul_slot_idx_in_period] + period_idx * fs->numb_slots_period;
}
/**
* @brief Configures the frame structure and the NFAPI config request
* depending on the duplex mode. If TDD, does the TDD patterns
* and TDD periods configuration.
*
* @param mu numerology
* @param scc pointer to scc
* @param tdd_period TDD period
* @param frame_type type of frame structure (FDD or TDD)
* @param fs pointer to the frame structure to update
*/
void config_frame_structure(int mu,
NR_ServingCellConfigCommon_t *scc,
uint8_t tdd_period,
uint8_t frame_type,
frame_structure_t *fs)
{
fs->numb_slots_frame = nr_slots_per_frame[mu];
if (frame_type == TDD) {
fs->numb_period_frame = get_nb_periods_per_frame(tdd_period);
fs->numb_slots_period = fs->numb_slots_frame / fs->numb_period_frame;
fs->is_tdd = true;
config_tdd_patterns(scc->tdd_UL_DL_ConfigurationCommon, fs);
} else { // FDD
fs->is_tdd = false;
fs->numb_period_frame = 1;
fs->numb_slots_period = nr_slots_per_frame[mu];
}
AssertFatal(fs->numb_period_frame > 0, "Frame configuration cannot be configured!\n");
}
static void config_common(gNB_MAC_INST *nrmac,
const nr_mac_config_t *config,
NR_ServingCellConfigCommon_t *scc)
@@ -820,7 +698,11 @@ static void config_common(gNB_MAC_INST *nrmac,
LOG_D(NR_MAC, "Setting TDD configuration period to %d\n", cfg->tdd_table.tdd_period.value);
}
frame_structure_t *fs = &nrmac->frame_structure;
config_frame_structure(mu, scc, cfg->tdd_table.tdd_period.value, cfg->cell_config.frame_duplex_type.value, fs);
config_frame_structure(mu,
scc->tdd_UL_DL_ConfigurationCommon,
cfg->tdd_table.tdd_period.value,
cfg->cell_config.frame_duplex_type.value,
fs);
if (cfg->cell_config.frame_duplex_type.value == TDD)
set_tdd_config_nr(cfg, fs);
@@ -887,7 +769,7 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, c
scc->ssb_PositionsInBurst->present);
const int NTN_gNB_Koffset = get_NTN_Koffset(scc);
const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
const int n = get_slots_per_frame_from_scs(*scc->ssbSubcarrierSpacing);
const int size = n << (int)ceil(log2((NTN_gNB_Koffset + 13) / n + 1)); // 13 is upper limit for max_fb_time
nrmac->vrb_map_UL_size = size;
+10 -60
View File
@@ -64,10 +64,7 @@ void clear_nr_nfapi_information(gNB_MAC_INST *gNB,
nfapi_nr_ul_dci_request_t *UL_dci_req)
{
/* called below and in simulators, so we assume a lock but don't require it */
NR_ServingCellConfigCommon_t *scc = gNB->common_channels->ServingCellConfigCommon;
const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
const int num_slots = gNB->frame_structure.numb_slots_frame;
UL_tti_req_ahead_initialization(gNB, num_slots, CC_idP, frameP, slotP);
nfapi_nr_dl_tti_pdcch_pdu_rel15_t **pdcch = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t **)gNB->pdcch_pdu_idx[CC_idP];
@@ -103,14 +100,13 @@ void clear_nr_nfapi_information(gNB_MAC_INST *gNB,
TX_req[CC_idP].Number_of_PDUs = 0;
}
void clear_beam_information(NR_beam_info_t *beam_info, int frame, int slot, int mu)
static void clear_beam_information(NR_beam_info_t *beam_info, int frame, int slot, int slots_per_frame)
{
// for now we use the same logic of UL_tti_req_ahead
// reset after 1 frame with the exception of 15kHz
if(!beam_info->beam_allocation)
return;
// initialization done only once
const int slots_per_frame = nr_slots_per_frame[mu];
AssertFatal(beam_info->beam_allocation_size >= 0, "Beam information not initialized\n");
int idx_to_clear = (frame * slots_per_frame + slot) / beam_info->beam_duration;
idx_to_clear = (idx_to_clear + beam_info->beam_allocation_size - 1) % beam_info->beam_allocation_size;
@@ -122,51 +118,6 @@ void clear_beam_information(NR_beam_info_t *beam_info, int frame, int slot, int
}
}
/**
* @brief Returns true for:
* (1) FDD
* (2) Mixed slot with UL symbols
* (3) Full UL slot
*/
bool is_ul_slot(const slot_t slot, const frame_structure_t *fs)
{
if (!fs->is_tdd)
return true;
const tdd_period_config_t *pc = &fs->period_cfg;
slot_t s = get_slot_idx_in_period(slot, fs);
return ((is_mixed_slot(s, fs) && pc->tdd_slot_bitmap[s].num_ul_symbols)
|| (pc->tdd_slot_bitmap[s].slot_type == TDD_NR_UPLINK_SLOT));
}
/**
* @brief Returns true for:
* (1) FDD
* (2) Mixed slot with DL symbols
* (3) Full DL slot
*/
bool is_dl_slot(const slot_t slot, const frame_structure_t *fs)
{
if (!fs->is_tdd)
return true;
const tdd_period_config_t *pc = &fs->period_cfg;
slot_t s = get_slot_idx_in_period(slot, fs);
return ((is_mixed_slot(s, fs) && pc->tdd_slot_bitmap[s].num_dl_symbols)
|| (pc->tdd_slot_bitmap[s].slot_type == TDD_NR_DOWNLINK_SLOT));
}
/**
* @brief Returns true for:
* (1) Mixed slot with DL and/or UL symbols
*/
bool is_mixed_slot(const slot_t slot, const frame_structure_t *fs)
{
if (!fs->is_tdd)
return false;
slot_t s = get_slot_idx_in_period(slot, fs);
const tdd_period_config_t *pc = &fs->period_cfg;
return pc->tdd_slot_bitmap[s].slot_type == TDD_NR_MIXED_SLOT;
}
/* the structure nfapi_nr_ul_tti_request_t is very big, let's copy only what is necessary */
static void copy_ul_tti_req(nfapi_nr_ul_tti_request_t *to, nfapi_nr_ul_tti_request_t *from)
{
@@ -215,8 +166,8 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
NR_SCHED_LOCK(&gNB->sched_lock);
clear_beam_information(&gNB->beam_info, frame, slot, *scc->ssbSubcarrierSpacing);
int slots_frame = gNB->frame_structure.numb_slots_frame;
clear_beam_information(&gNB->beam_info, frame, slot, slots_frame);
gNB->frame = frame;
start_meas(&gNB->eNB_scheduler);
@@ -240,9 +191,8 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_
for (int i = 0; i < num_beams; i++)
memset(cc[CC_id].vrb_map[i], 0, sizeof(uint16_t) * MAX_BWP_SIZE);
// clear last scheduled slot's content (only)!
const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
const int size = gNB->vrb_map_UL_size;
const int prev_slot = frame * num_slots + slot + size - 1;
const int prev_slot = frame * slots_frame + slot + size - 1;
for (int i = 0; i < num_beams; i++) {
uint16_t *vrb_map_UL = cc[CC_id].vrb_map_UL[i];
memcpy(&vrb_map_UL[prev_slot % size * MAX_BWP_SIZE], &gNB->ulprbbl, sizeof(uint16_t) * MAX_BWP_SIZE);
@@ -277,14 +227,14 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_
slot, because otherwise we would allocate the current slot in
UL_tti_req_ahead), but be aware that, e.g., K2 is allowed to be larger
(schedule_nr_prach will assert if resources are not free). */
const sub_frame_t n_slots_ahead = nr_slots_per_frame[*scc->ssbSubcarrierSpacing] - 1 + get_NTN_Koffset(scc);
const frame_t f = (frame + (slot + n_slots_ahead) / nr_slots_per_frame[*scc->ssbSubcarrierSpacing]) % 1024;
const sub_frame_t s = (slot + n_slots_ahead) % nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
const sub_frame_t n_slots_ahead = slots_frame - 1 + get_NTN_Koffset(scc);
const frame_t f = (frame + (slot + n_slots_ahead) / slots_frame) % 1024;
const sub_frame_t s = (slot + n_slots_ahead) % slots_frame;
schedule_nr_prach(module_idP, f, s);
}
// Schedule CSI-RS transmission
nr_csirs_scheduling(module_idP, frame, slot, nr_slots_per_frame[*scc->ssbSubcarrierSpacing], &sched_info->DL_req);
nr_csirs_scheduling(module_idP, frame, slot, &sched_info->DL_req);
// Schedule CSI measurement reporting
nr_csi_meas_reporting(module_idP, frame, slot);
@@ -313,7 +263,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_
* is more than 1 CC supported?
*/
AssertFatal(MAX_NUM_CCs == 1, "only 1 CC supported\n");
const int current_index = ul_buffer_index(frame, slot, *scc->ssbSubcarrierSpacing, gNB->UL_tti_req_ahead_size);
const int current_index = ul_buffer_index(frame, slot, slots_frame, gNB->UL_tti_req_ahead_size);
copy_ul_tti_req(&sched_info->UL_tti_req, &gNB->UL_tti_req_ahead[0][current_index]);
stop_meas(&gNB->eNB_scheduler);
+39 -39
View File
@@ -264,14 +264,11 @@ static void schedule_nr_MsgA_pusch(NR_UplinkConfigCommon_t *uplinkConfigCommon,
NR_MsgA_PUSCH_Resource_r16_t *msgA_PUSCH_Resource = uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice
.setup->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16;
int mu = nr_get_prach_mu(uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup,
uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup);
const int n_slots_frame = nr_slots_per_frame[mu];
const int n_slots_frame = nr_mac->frame_structure.numb_slots_frame;
slot_t msgA_pusch_slot = (slotP + msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16) % n_slots_frame;
frame_t msgA_pusch_frame = (frameP + ((slotP + msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16) / n_slots_frame)) % 1024;
int index = ul_buffer_index((int)msgA_pusch_frame, (int)msgA_pusch_slot, mu, nr_mac->UL_tti_req_ahead_size);
int index = ul_buffer_index((int)msgA_pusch_frame, (int)msgA_pusch_slot, n_slots_frame, nr_mac->UL_tti_req_ahead_size);
nfapi_nr_ul_tti_request_t *UL_tti_req = &nr_mac[module_idP].UL_tti_req_ahead[0][index];
UL_tti_req->SFN = msgA_pusch_frame;
@@ -370,7 +367,8 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
if (scc->uplinkConfigCommon->initialUplinkBWP->ext1 && scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16)
msgacc = scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup;
int mu = nr_get_prach_mu(msgacc, rach_ConfigCommon);
int index = ul_buffer_index(frameP, slotP, mu, gNB->UL_tti_req_ahead_size);
int slots_frame = gNB->frame_structure.numb_slots_frame;
int index = ul_buffer_index(frameP, slotP, slots_frame, gNB->UL_tti_req_ahead_size);
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[0][index];
nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
@@ -435,7 +433,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
// fapi beam index
beam_index = get_fapi_beamforming_index(gNB, cc->ssb_index[n_ssb]);
// multi-beam allocation structure
beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, nr_slots_per_frame[mu]);
beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, slots_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate PRACH corresponding to %d SSB transmitted in any available beam\n", n_ssb + 1);
}
else {
@@ -444,7 +442,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
// fapi beam index
beam_index = get_fapi_beamforming_index(gNB, cc->ssb_index[j]);
// multi-beam allocation structure
beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, nr_slots_per_frame[mu]);
beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, slots_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate PRACH corresponding to SSB %d in any available beam\n", j);
}
}
@@ -556,7 +554,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
// block resources in vrb_map_UL
const int mu_pusch = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
const int16_t n_ra_rb = get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing.value, mu_pusch);
index = ul_buffer_index(frameP, slotP, mu, gNB->vrb_map_UL_size);
index = ul_buffer_index(frameP, slotP, slots_frame, gNB->vrb_map_UL_size);
uint16_t *vrb_map_UL = &cc->vrb_map_UL[beam.idx][index * MAX_BWP_SIZE];
for (int i = 0; i < n_ra_rb * fdm; ++i) {
AssertFatal(
@@ -781,18 +779,18 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = ul_bwp->tdaList_Common;
int mu = ul_bwp->scs;
int slots_frame = nr_mac->frame_structure.numb_slots_frame;
uint16_t K2 = *pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2 + get_NTN_Koffset(scc);
const int sched_frame = (frame + (slot + K2) / nr_slots_per_frame[mu]) % MAX_FRAME_NUMBER;
const int sched_slot = (slot + K2) % nr_slots_per_frame[mu];
const int sched_frame = (frame + (slot + K2) / slots_frame) % MAX_FRAME_NUMBER;
const int sched_slot = (slot + K2) % slots_frame;
if (is_ul_slot(sched_slot, &nr_mac->frame_structure)) {
const int n_slots_frame = nr_slots_per_frame[mu];
NR_beam_alloc_t beam_ul = beam_allocation_procedure(&nr_mac->beam_info, sched_frame, sched_slot, ra->beam_id, n_slots_frame);
NR_beam_alloc_t beam_ul = beam_allocation_procedure(&nr_mac->beam_info, sched_frame, sched_slot, ra->beam_id, slots_frame);
if (beam_ul.idx < 0)
return;
NR_beam_alloc_t beam_dci = beam_allocation_procedure(&nr_mac->beam_info, frame, slot, ra->beam_id, n_slots_frame);
NR_beam_alloc_t beam_dci = beam_allocation_procedure(&nr_mac->beam_info, frame, slot, ra->beam_id, slots_frame);
if (beam_dci.idx < 0) {
reset_beam_status(&nr_mac->beam_info, sched_frame, sched_slot, ra->beam_id, n_slots_frame, beam_ul.new_beam);
reset_beam_status(&nr_mac->beam_info, sched_frame, sched_slot, ra->beam_id, slots_frame, beam_ul.new_beam);
return;
}
int fh = 0;
@@ -801,7 +799,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols);
int mappingtype = pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->mappingType;
int buffer_index = ul_buffer_index(sched_frame, sched_slot, mu, nr_mac->vrb_map_UL_size);
int buffer_index = ul_buffer_index(sched_frame, sched_slot, slots_frame, nr_mac->vrb_map_UL_size);
uint16_t *vrb_map_UL = &nr_mac->common_channels[CC_id].vrb_map_UL[beam_ul.idx][buffer_index * MAX_BWP_SIZE];
const int BWPSize = sc_info->initial_ul_BWPSize;
@@ -828,7 +826,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
sched_frame,
sched_slot);
buffer_index = ul_buffer_index(sched_frame, sched_slot, mu, nr_mac->UL_tti_req_ahead_size);
buffer_index = ul_buffer_index(sched_frame, sched_slot, slots_frame, nr_mac->UL_tti_req_ahead_size);
nfapi_nr_ul_tti_request_t *future_ul_tti_req = &nr_mac->UL_tti_req_ahead[CC_id][buffer_index];
AssertFatal(future_ul_tti_req->SFN == sched_frame
&& future_ul_tti_req->Slot == sched_slot,
@@ -974,7 +972,7 @@ static bool get_feasible_msg3_tda(const NR_ServingCellConfigCommon_t *scc,
int abs_slot = slot + k2 + mu_delta;
int temp_frame = (frame + (abs_slot / slots_per_frame)) & 1023;
int temp_slot = abs_slot % slots_per_frame; // msg3 slot according to 8.3 in 38.213
if (fs->is_tdd && !is_ul_slot(temp_slot, fs))
if (fs->frame_type == TDD && !is_ul_slot(temp_slot, fs))
continue;
const tdd_bitmap_t *tdd_slot_bitmap = fs->period_cfg.tdd_slot_bitmap;
@@ -1024,7 +1022,6 @@ static bool nr_get_Msg3alloc(gNB_MAC_INST *mac, int CC_id, int current_slot, fra
NR_UE_ServingCell_Info_t *sc_info = &ra->sc_info;
const NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = ul_bwp->tdaList_Common;
int mu = ul_bwp->scs;
int startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength;
SLIV2SL(startSymbolAndLength, &ra->msg3_startsymb, &ra->msg3_nbSymb);
@@ -1037,7 +1034,10 @@ static bool nr_get_Msg3alloc(gNB_MAC_INST *mac, int CC_id, int current_slot, fra
current_frame,
current_slot,
ra->Msg3_tda_id);
const int buffer_index = ul_buffer_index(ra->Msg3_frame, ra->Msg3_slot, mu, mac->vrb_map_UL_size);
const int buffer_index = ul_buffer_index(ra->Msg3_frame,
ra->Msg3_slot,
mac->frame_structure.numb_slots_frame,
mac->vrb_map_UL_size);
uint16_t *vrb_map_UL = &mac->common_channels[CC_id].vrb_map_UL[ra->Msg3_beam.idx][buffer_index * MAX_BWP_SIZE];
int bwpSize = sc_info->initial_ul_BWPSize;
@@ -1181,9 +1181,9 @@ static void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_f
return;
}
const int scs = ul_bwp->scs;
const uint16_t mask = SL_to_bitmap(ra->msg3_startsymb, ra->msg3_nbSymb);
int buffer_index = ul_buffer_index(ra->Msg3_frame, ra->Msg3_slot, scs, mac->vrb_map_UL_size);
int slots_frame = mac->frame_structure.numb_slots_frame;
int buffer_index = ul_buffer_index(ra->Msg3_frame, ra->Msg3_slot, slots_frame, mac->vrb_map_UL_size);
uint16_t *vrb_map_UL = &RC.nrmac[module_idP]->common_channels[CC_id].vrb_map_UL[ra->Msg3_beam.idx][buffer_index * MAX_BWP_SIZE];
for (int i = 0; i < ra->msg3_nb_rb; ++i) {
AssertFatal(!(vrb_map_UL[i + ra->msg3_first_rb + ra->msg3_bwp_start] & mask),
@@ -1195,7 +1195,7 @@ static void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_f
}
LOG_D(NR_MAC, "UE %04x: %d.%d RA is active, Msg3 in (%d,%d)\n", ra->rnti, frameP, slotP, ra->Msg3_frame, ra->Msg3_slot);
buffer_index = ul_buffer_index(ra->Msg3_frame, ra->Msg3_slot, scs, mac->UL_tti_req_ahead_size);
buffer_index = ul_buffer_index(ra->Msg3_frame, ra->Msg3_slot, slots_frame, mac->UL_tti_req_ahead_size);
nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[CC_id][buffer_index];
AssertFatal(future_ul_tti_req->SFN == ra->Msg3_frame
&& future_ul_tti_req->Slot == ra->Msg3_slot,
@@ -1225,7 +1225,7 @@ static void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_f
ra->msg3_first_rb,
ra->msg3_round);
fill_msg3_pusch_pdu(pusch_pdu, scc, ra, startSymbolAndLength, scs, ibwp_size, ra->msg3_bwp_start, mappingtype, fh);
fill_msg3_pusch_pdu(pusch_pdu, scc, ra, startSymbolAndLength, ul_bwp->scs, ibwp_size, ra->msg3_bwp_start, mappingtype, fh);
future_ul_tti_req->n_pdus += 1;
// calling function to fill rar message
@@ -1302,14 +1302,12 @@ static void find_monitoring_periodicity_offset_common(const NR_SearchSpace_t *ss
}
}
static bool check_msg2_monitoring(const NR_RA_t *ra, int mu, int current_frame, int current_slot)
static bool check_msg2_monitoring(const NR_RA_t *ra, int slots_per_frame, int current_frame, int current_slot)
{
int n = nr_slots_per_frame[mu];
// check if the slot is not among the PDCCH monitored ones (38.213 10.1)
uint16_t monitoring_slot_period, monitoring_offset;
find_monitoring_periodicity_offset_common(ra->ra_ss, &monitoring_slot_period, &monitoring_offset);
if ((current_frame * n + current_slot - monitoring_offset) % monitoring_slot_period != 0)
if ((current_frame * slots_per_frame + current_slot - monitoring_offset) % monitoring_slot_period != 0)
return false;
return true;
}
@@ -1348,14 +1346,17 @@ static int get_response_window(e_NR_RACH_ConfigGeneric__ra_ResponseWindow respon
return slots;
}
static bool msg2_in_response_window(int rach_frame, int rach_slot, int mu, long rrc_ra_ResponseWindow, int current_frame, int current_slot)
static bool msg2_in_response_window(int rach_frame,
int rach_slot,
int n_slots_frame,
long rrc_ra_ResponseWindow,
int current_frame,
int current_slot)
{
int window_slots = get_response_window(rrc_ra_ResponseWindow);
int n = nr_slots_per_frame[mu];
int abs_rach = n * rach_frame + rach_slot;
int abs_now = n * current_frame + current_slot;
int diff = (n * 1024 + abs_now - abs_rach) % (n * 1024);
int abs_rach = n_slots_frame * rach_frame + rach_slot;
int abs_now = n_slots_frame * current_frame + current_slot;
int diff = (n_slots_frame * 1024 + abs_now - abs_rach) % (n_slots_frame * 1024);
bool in_window = diff <= window_slots;
if (!in_window) {
@@ -1394,18 +1395,17 @@ static void nr_generate_Msg2(module_id_t module_idP,
long rrc_ra_ResponseWindow =
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.ra_ResponseWindow;
if (!msg2_in_response_window(ra->preamble_frame, ra->preamble_slot, dl_bwp->scs, rrc_ra_ResponseWindow, frameP, slotP)) {
const int n_slots_frame = nr_mac->frame_structure.numb_slots_frame;
if (!msg2_in_response_window(ra->preamble_frame, ra->preamble_slot, n_slots_frame, rrc_ra_ResponseWindow, frameP, slotP)) {
LOG_E(NR_MAC, "UE RA-RNTI %04x TC-RNTI %04x: exceeded RA window, cannot schedule Msg2\n", ra->RA_rnti, ra->rnti);
nr_clear_ra_proc(ra);
return;
}
if (!check_msg2_monitoring(ra, dl_bwp->scs, frameP, slotP)) {
if (!check_msg2_monitoring(ra, n_slots_frame, frameP, slotP)) {
LOG_E(NR_MAC, "UE RA-RNTI %04x TC-RNTI %04x: Msg2 not monitored by UE\n", ra->RA_rnti, ra->rnti);
return;
}
const int n_slots_frame = nr_slots_per_frame[dl_bwp->scs];
NR_beam_alloc_t beam = beam_allocation_procedure(&nr_mac->beam_info, frameP, slotP, ra->beam_id, n_slots_frame);
if (beam.idx < 0)
return;
@@ -1981,7 +1981,7 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
mac_sdu_length = srb_status.bytes_in_buffer;
}
const int n_slots_frame = nr_slots_per_frame[dl_bwp->scs];
const int n_slots_frame = nr_mac->frame_structure.numb_slots_frame;
NR_beam_alloc_t beam = beam_allocation_procedure(&nr_mac->beam_info, frameP, slotP, ra->beam_id, n_slots_frame);
if (beam.idx < 0)
return;
@@ -125,7 +125,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP,
NR_COMMON_channels_t *cc= &gNB->common_channels[CC_id];
const NR_MIB_t *mib = cc->mib->message.choice.mib;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
const int slots_per_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
const int slots_per_frame = gNB->frame_structure.numb_slots_frame;
dl_req = &DL_req->dl_tti_request_body;
// get MIB every 8 frames
@@ -170,7 +170,6 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP,
const BIT_STRING_t *mediumBitmap = &scc->ssb_PositionsInBurst->choice.mediumBitmap;
const BIT_STRING_t *longBitmap = &scc->ssb_PositionsInBurst->choice.longBitmap;
const int n_slots_frame = nr_slots_per_frame[scs];
switch (scc->ssb_PositionsInBurst->present) {
case 1:
// short bitmap (<3GHz) max 4 SSBs
@@ -180,7 +179,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP,
// if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters
if ((ssb_start_symbol / 14) == rel_slot) {
int beam_index = get_fapi_beamforming_index(gNB, i_ssb);
NR_beam_alloc_t beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, n_slots_frame);
NR_beam_alloc_t beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, slots_per_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate SSB %d in any available beam\n", i_ssb);
const int prb_offset = offset_pointa >> scs;
schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, beam_index, ssbSubcarrierOffset, offset_pointa, mib_pdu);
@@ -212,7 +211,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP,
// if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters
if ((ssb_start_symbol / 14) == rel_slot) {
int beam_index = get_fapi_beamforming_index(gNB, i_ssb);
NR_beam_alloc_t beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, n_slots_frame);
NR_beam_alloc_t beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, slots_per_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate SSB %d in any available beam\n", i_ssb);
const int prb_offset = offset_pointa >> scs;
schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, beam_index, ssbSubcarrierOffset, offset_pointa, mib_pdu);
@@ -244,7 +243,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP,
// if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters
if ((ssb_start_symbol / 14) == rel_slot) {
int beam_index = get_fapi_beamforming_index(gNB, i_ssb);
NR_beam_alloc_t beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, n_slots_frame);
NR_beam_alloc_t beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, slots_per_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate SSB %d in any available beam\n", i_ssb);
const int prb_offset = offset_pointa >> (scs-2); // reference 60kHz
schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, beam_index, ssbSubcarrierOffset, offset_pointa, mib_pdu);
@@ -366,7 +365,7 @@ static uint32_t schedule_control_sib1(module_id_t module_id,
gNB_mac->sched_ctrlCommon->search_space = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->search_space));
gNB_mac->sched_ctrlCommon->coreset = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->coreset));
fill_searchSpaceZero(gNB_mac->sched_ctrlCommon->search_space,
nr_slots_per_frame[*scc->ssbSubcarrierSpacing],
gNB_mac->frame_structure.numb_slots_frame,
type0_PDCCH_CSS_config);
fill_coresetZero(gNB_mac->sched_ctrlCommon->coreset, type0_PDCCH_CSS_config);
gNB_mac->cset0_bwp_start = type0_PDCCH_CSS_config->cset_start_rb;
@@ -698,7 +697,7 @@ void schedule_nr_sib1(module_id_t module_idP,
(type0_PDCCH_CSS_config->num_rbs > 0) &&
(type0_PDCCH_CSS_config->active == true)) {
const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
const int n_slots_frame = gNB_mac->frame_structure.numb_slots_frame;
int beam_index = get_fapi_beamforming_index(gNB_mac, i);
NR_beam_alloc_t beam = beam_allocation_procedure(&gNB_mac->beam_info, frameP, slotP, beam_index, n_slots_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate SIB1 corresponding to SSB %d in any available beam\n", i);
@@ -846,7 +845,7 @@ void schedule_nr_sib19(module_id_t module_idP,
(slotP == ((sib19_sched_info->si_WindowPosition_r17 % window_length) - 1)) &&
(type0_PDCCH_CSS_config->num_rbs > 0)) {
const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
const int n_slots_frame = gNB_mac->frame_structure.numb_slots_frame;
int beam_index = get_fapi_beamforming_index(gNB_mac, i);
NR_beam_alloc_t beam = beam_allocation_procedure(&gNB_mac->beam_info, frameP, slotP, beam_index, n_slots_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate SIB19 corresponding to SSB %d in any available beam\n", i);
@@ -61,7 +61,7 @@ int get_dl_tda(const gNB_MAC_INST *nrmac, int slot)
if (nrmac->UE_info.sched_csirs > 0)
return 1;
if (fs->is_tdd) {
if (fs->frame_type == TDD) {
int s = get_slot_idx_in_period(slot, fs);
// if there is a mixed slot where we can transmit DL
const tdd_bitmap_t *tdd_slot_bitmap = fs->period_cfg.tdd_slot_bitmap;
@@ -615,6 +615,7 @@ static void pf_dl(module_id_t module_id,
remainUEs[i] = max_num_ue;
int curUE = 0;
int CC_id = 0;
int slots_per_frame = mac->frame_structure.numb_slots_frame;
/* Loop UE_info->list to check retransmission */
UE_iterator(UE_list, UE) {
@@ -644,18 +645,14 @@ static void pf_dl(module_id_t module_id,
/* retransmission */
if (sched_pdsch->dl_harq_pid >= 0) {
NR_beam_alloc_t beam = beam_allocation_procedure(&mac->beam_info,
frame,
slot,
UE->UE_beam_index,
nr_slots_per_frame[current_BWP->scs]);
NR_beam_alloc_t beam = beam_allocation_procedure(&mac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame);
bool sch_ret = beam.idx >= 0;
/* Allocate retransmission */
if (sch_ret)
sch_ret = allocate_dl_retransmission(module_id, frame, slot, &n_rb_sched[beam.idx], UE, beam.idx, sched_pdsch->dl_harq_pid);
if (!sch_ret) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] DL retransmission could not be allocated\n", UE->rnti, frame, slot);
reset_beam_status(&mac->beam_info, frame, slot, UE->UE_beam_index, nr_slots_per_frame[current_BWP->scs], beam.new_beam);
reset_beam_status(&mac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
continue;
}
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
@@ -738,11 +735,7 @@ static void pf_dl(module_id_t module_id,
continue;
}
NR_beam_alloc_t beam = beam_allocation_procedure(&mac->beam_info,
frame,
slot,
iterator->UE->UE_beam_index,
nr_slots_per_frame[dl_bwp->scs]);
NR_beam_alloc_t beam = beam_allocation_procedure(&mac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame);
if (beam.idx < 0) {
// no available beam
@@ -750,12 +743,7 @@ static void pf_dl(module_id_t module_id,
continue;
}
if (remainUEs[beam.idx] == 0 || n_rb_sched[beam.idx] < min_rbSize) {
reset_beam_status(&mac->beam_info,
frame,
slot,
iterator->UE->UE_beam_index,
nr_slots_per_frame[dl_bwp->scs],
beam.new_beam);
reset_beam_status(&mac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, beam.new_beam);
iterator++;
continue;
}
@@ -822,12 +810,7 @@ static void pf_dl(module_id_t module_id,
sched_ctrl->pdcch_cl_adjust);
if (CCEIndex < 0) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find free CCE for DL DCI\n", rnti, frame, slot);
reset_beam_status(&mac->beam_info,
frame,
slot,
iterator->UE->UE_beam_index,
nr_slots_per_frame[dl_bwp->scs],
beam.new_beam);
reset_beam_status(&mac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, beam.new_beam);
iterator++;
continue;
}
@@ -841,12 +824,7 @@ static void pf_dl(module_id_t module_id,
alloc = nr_acknack_scheduling(mac, iterator->UE, frame, slot, iterator->UE->UE_beam_index, r_pucch, 0);
if (alloc < 0) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find PUCCH for DL DCI\n", rnti, frame, slot);
reset_beam_status(&mac->beam_info,
frame,
slot,
iterator->UE->UE_beam_index,
nr_slots_per_frame[dl_bwp->scs],
beam.new_beam);
reset_beam_status(&mac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, beam.new_beam);
iterator++;
continue;
}
@@ -1416,11 +1394,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
if (sched_ctrl->ta_apply) {
sched_ctrl->ta_apply = false;
sched_ctrl->ta_frame = frame;
LOG_D(NR_MAC,
"%d.%2d UE %04x TA scheduled, resetting TA frame\n",
frame,
slot,
UE->rnti);
LOG_D(NR_MAC, "%d.%2d UE %04x TA scheduled, resetting TA frame\n", frame, slot, UE->rnti);
}
T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti),
@@ -234,7 +234,6 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
const int mu = ul_bwp->scs;
/* return if all UL HARQ processes wait for feedback */
if (sched_ctrl->retrans_ul_harq.head == -1 && sched_ctrl->available_ul_harq.head == -1) {
@@ -249,13 +248,12 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
const int temp_tda = get_ul_tda(nr_mac, frame, slot);
if (temp_tda < 0)
return false;
AssertFatal(temp_tda < tdaList->list.count,
"time domain assignment %d >= %d\n",
temp_tda,
tdaList->list.count);
AssertFatal(temp_tda < tdaList->list.count, "time domain assignment %d >= %d\n", temp_tda, tdaList->list.count);
const int mu = ul_bwp->scs;
int K2 = get_K2(tdaList, temp_tda, mu, scc);
const int sched_frame = (frame + (slot + K2) / nr_slots_per_frame[mu]) % MAX_FRAME_NUMBER;
const int sched_slot = (slot + K2) % nr_slots_per_frame[mu];
int slots_frame = nr_mac->frame_structure.numb_slots_frame;
const int sched_frame = (frame + (slot + K2) / slots_frame) % MAX_FRAME_NUMBER;
const int sched_slot = (slot + K2) % slots_frame;
const int tda = get_ul_tda(nr_mac, sched_frame, sched_slot);
if (tda < 0)
return false;
@@ -294,7 +292,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
// TODO implement beam procedures for phy-test mode
int beam = 0;
const int buffer_index = ul_buffer_index(sched_frame, sched_slot, mu, nr_mac->vrb_map_UL_size);
const int buffer_index = ul_buffer_index(sched_frame, sched_slot, slots_frame, nr_mac->vrb_map_UL_size);
uint16_t *vrb_map_UL = &nr_mac->common_channels[CC_id].vrb_map_UL[beam][buffer_index * MAX_BWP_SIZE];
for (int i = rbStart; i < rbStart + rbSize; ++i) {
if ((vrb_map_UL[i+BWPStart] & SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols)) != 0) {
@@ -2777,12 +2777,12 @@ int get_pdsch_to_harq_feedback(NR_PUCCH_Config_t *pucch_Config,
}
}
void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slots_frame, nfapi_nr_dl_tti_request_t *DL_req)
void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, nfapi_nr_dl_tti_request_t *DL_req)
{
int CC_id = 0;
NR_UEs_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
gNB_MAC_INST *gNB_mac = RC.nrmac[Mod_idP];
int n_slots_frame = gNB_mac->frame_structure.numb_slots_frame;
NR_SCHED_ENSURE_LOCKED(&gNB_mac->sched_lock);
UE_info->sched_csirs = 0;
@@ -3178,9 +3178,9 @@ void nr_mac_update_timers(module_id_t module_id,
}
}
int ul_buffer_index(int frame, int slot, int scs, int size)
int ul_buffer_index(int frame, int slot, int slots_per_frame, int size)
{
const int abs_slot = frame * nr_slots_per_frame[scs] + slot;
const int abs_slot = frame * slots_per_frame + slot;
return abs_slot % size;
}
+15 -18
View File
@@ -407,15 +407,16 @@ void nr_srs_ri_computation(const nfapi_nr_srs_normalized_channel_iq_matrix_t *nr
}
}
static void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu,
static void nr_configure_srs(gNB_MAC_INST *nrmac,
nfapi_nr_srs_pdu_t *srs_pdu,
int frame,
int slot,
int module_id,
int CC_id,
NR_UE_info_t *UE,
NR_SRS_ResourceSet_t *srs_resource_set,
NR_SRS_Resource_t *srs_resource,
int buffer_index)
int buffer_index,
int slots_per_frame)
{
NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP;
@@ -461,26 +462,22 @@ static void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu,
srs_pdu->srs_parameters_v4.report_type[0] = 1;
srs_pdu->srs_parameters_v4.iq_representation = 1;
srs_pdu->srs_parameters_v4.prg_size = 1;
srs_pdu->srs_parameters_v4.num_total_ue_antennas = 1<<srs_pdu->num_ant_ports;
srs_pdu->srs_parameters_v4.num_total_ue_antennas = 1 << srs_pdu->num_ant_ports;
if (srs_resource_set->usage == NR_SRS_ResourceSet__usage_beamManagement) {
srs_pdu->beamforming.trp_scheme = 0;
srs_pdu->beamforming.num_prgs = m_SRS[srs_pdu->config_index];
srs_pdu->beamforming.prg_size = 1;
}
srs_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = UE->UE_beam_index;
NR_beam_alloc_t beam = beam_allocation_procedure(&RC.nrmac[module_id]->beam_info,
frame,
slot,
UE->UE_beam_index,
nr_slots_per_frame[current_BWP->scs]);
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate SRS in any available beam\n");
uint16_t *vrb_map_UL = &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[beam.idx][buffer_index * MAX_BWP_SIZE];
uint16_t *vrb_map_UL = &nrmac->common_channels[CC_id].vrb_map_UL[beam.idx][buffer_index * MAX_BWP_SIZE];
uint64_t mask = SL_to_bitmap(srs_pdu->time_start_position, srs_pdu->num_symbols);
for (int i = 0; i < srs_pdu->bwp_size; ++i)
vrb_map_UL[i + srs_pdu->bwp_start] |= mask;
}
static void nr_fill_nfapi_srs(int module_id,
static void nr_fill_nfapi_srs(gNB_MAC_INST *nrmac,
int CC_id,
NR_UE_info_t *UE,
int frame,
@@ -488,9 +485,9 @@ static void nr_fill_nfapi_srs(int module_id,
NR_SRS_ResourceSet_t *srs_resource_set,
NR_SRS_Resource_t *srs_resource)
{
int index = ul_buffer_index(frame, slot, UE->current_UL_BWP.scs, RC.nrmac[module_id]->UL_tti_req_ahead_size);
nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_id]->UL_tti_req_ahead[0][index];
int slots_frame = nrmac->frame_structure.numb_slots_frame;
int index = ul_buffer_index(frame, slot, slots_frame, nrmac->UL_tti_req_ahead_size);
nfapi_nr_ul_tti_request_t *future_ul_tti_req = &nrmac->UL_tti_req_ahead[0][index];
AssertFatal(future_ul_tti_req->n_pdus <
sizeof(future_ul_tti_req->pdus_list) / sizeof(future_ul_tti_req->pdus_list[0]),
"Invalid future_ul_tti_req->n_pdus %d\n", future_ul_tti_req->n_pdus);
@@ -499,8 +496,8 @@ static void nr_fill_nfapi_srs(int module_id,
nfapi_nr_srs_pdu_t *srs_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].srs_pdu;
memset(srs_pdu, 0, sizeof(nfapi_nr_srs_pdu_t));
future_ul_tti_req->n_pdus += 1;
index = ul_buffer_index(frame, slot, UE->current_UL_BWP.scs, RC.nrmac[module_id]->vrb_map_UL_size);
nr_configure_srs(srs_pdu, frame, slot, module_id, CC_id, UE, srs_resource_set, srs_resource, index);
index = ul_buffer_index(frame, slot, slots_frame, nrmac->vrb_map_UL_size);
nr_configure_srs(nrmac, srs_pdu, frame, slot, CC_id, UE, srs_resource_set, srs_resource, index, slots_frame);
}
/*******************************************************************
@@ -583,7 +580,7 @@ void nr_schedule_srs(int module_id, frame_t frame, int slot)
}
// we are sheduling SRS max_k2 slot in advance for the presence of SRS to be taken into account when scheduling PUSCH
const int n_slots_frame = nr_slots_per_frame[current_BWP->scs];
const int n_slots_frame = nrmac->frame_structure.numb_slots_frame;
const int sched_slot = (slot + max_k2) % n_slots_frame;
const int sched_frame = (frame + (slot + max_k2) / n_slots_frame) % MAX_FRAME_NUMBER;
@@ -593,7 +590,7 @@ void nr_schedule_srs(int module_id, frame_t frame, int slot)
// Check if UE will transmit the SRS in this frame
if ((sched_frame * n_slots_frame + sched_slot - offset) % period == 0) {
LOG_D(NR_MAC," %d.%d Scheduling SRS reception for %d.%d\n", frame, slot, sched_frame, sched_slot);
nr_fill_nfapi_srs(module_id, CC_id, UE, sched_frame, sched_slot, srs_resource_set, srs_resource);
nr_fill_nfapi_srs(nrmac, CC_id, UE, sched_frame, sched_slot, srs_resource_set, srs_resource);
sched_ctrl->sched_srs.frame = sched_frame;
sched_ctrl->sched_srs.slot = sched_slot;
sched_ctrl->sched_srs.srs_scheduled = true;
+27 -15
View File
@@ -40,10 +40,13 @@ static void nr_fill_nfapi_pucch(gNB_MAC_INST *nrmac,
NR_UE_info_t* UE)
{
const int index = ul_buffer_index(pucch->frame, pucch->ul_slot, UE->current_UL_BWP.scs, nrmac->UL_tti_req_ahead_size);
const int index = ul_buffer_index(pucch->frame,
pucch->ul_slot,
nrmac->frame_structure.numb_slots_frame,
nrmac->UL_tti_req_ahead_size);
nfapi_nr_ul_tti_request_t *future_ul_tti_req = &nrmac->UL_tti_req_ahead[0][index];
if (future_ul_tti_req->SFN != pucch->frame || future_ul_tti_req->Slot != pucch->ul_slot)
LOG_W(MAC,
LOG_W(NR_MAC,
"Current %d.%d : future UL_tti_req's frame.slot %4d.%2d does not match PUCCH %4d.%2d\n",
frame,slot,
future_ul_tti_req->SFN,
@@ -53,8 +56,11 @@ static void nr_fill_nfapi_pucch(gNB_MAC_INST *nrmac,
// n_pdus is number of pdus, so, in the array, it is the index of the next free element
if (future_ul_tti_req->n_pdus >= sizeofArray(future_ul_tti_req->pdus_list) ) {
LOG_E(NR_MAC,"future_ul_tti_req->n_pdus %d is full, slot: %d, sr flag %d dropping request\n",
future_ul_tti_req->n_pdus, pucch->ul_slot, pucch->sr_flag);
LOG_E(NR_MAC,
"future_ul_tti_req->n_pdus %d is full, slot: %d, sr flag %d dropping request\n",
future_ul_tti_req->n_pdus,
pucch->ul_slot,
pucch->sr_flag);
return;
}
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE;
@@ -77,8 +83,14 @@ static void nr_fill_nfapi_pucch(gNB_MAC_INST *nrmac,
NR_COMMON_channels_t * common_ch=nrmac->common_channels;
NR_ServingCellConfigCommon_t *scc = common_ch->ServingCellConfigCommon;
LOG_D(NR_MAC,"%4d.%2d Calling nr_configure_pucch (pucch_Config %p,r_pucch %d) pucch to be scheduled in %4d.%2d\n",
frame,slot,UE->current_UL_BWP.pucch_Config,pucch->r_pucch,pucch->frame,pucch->ul_slot);
LOG_D(NR_MAC,
"%4d.%2d Calling nr_configure_pucch (pucch_Config %p,r_pucch %d) pucch to be scheduled in %4d.%2d\n",
frame,
slot,
UE->current_UL_BWP.pucch_Config,
pucch->r_pucch,
pucch->frame,
pucch->ul_slot);
nr_configure_pucch(pucch_pdu,
scc,
@@ -213,7 +225,7 @@ void nr_csi_meas_reporting(int Mod_idP,frame_t frame, sub_frame_t slot)
UE_iterator(nrmac->UE_info.list, UE ) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs];
const int n_slots_frame = nrmac->frame_structure.numb_slots_frame;
if (nr_timer_is_active(&sched_ctrl->transm_interrupt) || (sched_ctrl->ul_failure && !get_softmodem_params()->phy_test)) {
continue;
}
@@ -270,7 +282,7 @@ void nr_csi_meas_reporting(int Mod_idP,frame_t frame, sub_frame_t slot)
// going through the list of PUCCH resources to find the one indexed by resource_id
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, n_slots_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate CSI measurements on PUCCH in any available beam\n");
const int index = ul_buffer_index(sched_frame, sched_slot, ul_bwp->scs, nrmac->vrb_map_UL_size);
const int index = ul_buffer_index(sched_frame, sched_slot, n_slots_frame, nrmac->vrb_map_UL_size);
uint16_t *vrb_map_UL = &nrmac->common_channels[0].vrb_map_UL[beam.idx][index * MAX_BWP_SIZE];
const int m = pucch_Config->resourceToAddModList->list.count;
for (int j = 0; j < m; j++) {
@@ -623,10 +635,10 @@ static void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP;
const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs];
const int n_slots_frame = nrmac->frame_structure.numb_slots_frame;
int cumul_bits = 0;
int r_index = -1;
for (int csi_report_id = 0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++ ) {
for (int csi_report_id = 0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++) {
nr_csi_report_t *csi_report = &UE->csi_report_template[csi_report_id];
csi_report->nb_of_csi_ssb_report = 0;
uint8_t cri_bitlen = 0;
@@ -1003,7 +1015,7 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac,
const int minfbtime = mac->radio_config.minRXTXTIME + NTN_gNB_Koffset;
const NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs];
const int n_slots_frame = mac->frame_structure.numb_slots_frame;
const frame_structure_t *fs = &mac->frame_structure;
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
@@ -1025,7 +1037,7 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac,
continue;
const int pucch_slot = (slot + pdsch_to_harq_feedback[f] + NTN_gNB_Koffset) % n_slots_frame;
// check if the slot is UL
if (fs->is_tdd) {
if (fs->frame_type == TDD) {
int mod_slot = pucch_slot % fs->numb_slots_period;
if (!is_ul_slot(mod_slot, fs))
continue;
@@ -1090,7 +1102,7 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac,
pucch_slot);
continue;
}
const int index = ul_buffer_index(pucch_frame, pucch_slot, ul_bwp->scs, mac->vrb_map_UL_size);
const int index = ul_buffer_index(pucch_frame, pucch_slot, n_slots_frame, mac->vrb_map_UL_size);
uint16_t *vrb_map_UL = &mac->common_channels[CC_id].vrb_map_UL[beam.idx][index * MAX_BWP_SIZE];
bool ret = test_pucch0_vrb_occupation(curr_pucch, vrb_map_UL, bwp_start, bwp_size);
if(!ret) {
@@ -1137,7 +1149,7 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot)
UE_iterator(nrmac->UE_info.list, UE) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs];
const int n_slots_frame = nrmac->frame_structure.numb_slots_frame;
if (sched_ctrl->ul_failure || nr_timer_is_active(&sched_ctrl->transm_interrupt))
continue;
NR_PUCCH_Config_t *pucch_Config = ul_bwp->pucch_Config;
@@ -1188,7 +1200,7 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot)
else {
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, SFN, slot, UE->UE_beam_index, n_slots_frame);
AssertFatal(beam.idx >= 0, "Cannot allocate SR in any available beam\n");
const int index = ul_buffer_index(SFN, slot, ul_bwp->scs, nrmac->vrb_map_UL_size);
const int index = ul_buffer_index(SFN, slot, n_slots_frame, nrmac->vrb_map_UL_size);
uint16_t *vrb_map_UL = &nrmac->common_channels[CC_id].vrb_map_UL[beam.idx][index * MAX_BWP_SIZE];
const int bwp_start = ul_bwp->BWPStart;
const int bwp_size = ul_bwp->BWPSize;
@@ -48,7 +48,7 @@ int get_ul_tda(gNB_MAC_INST *nrmac, int frame, int slot)
/* there is a mixed slot only when in TDD */
frame_structure_t *fs = &nrmac->frame_structure;
if (fs->is_tdd) {
if (fs->frame_type == TDD) {
// if there is uplink symbols in mixed slot
int s = get_slot_idx_in_period(slot, fs);
tdd_bitmap_t *tdd_slot_bitmap = fs->period_cfg.tdd_slot_bitmap;
@@ -1535,7 +1535,7 @@ static bool nr_UE_is_to_be_scheduled(const frame_structure_t *fs,
* Force the default transmission in a full slot as early
* as possible in the UL portion of TDD period (last_ul_slot) */
int num_slots_per_period = fs->numb_slots_period;
int last_ul_slot = fs->is_tdd ? get_first_ul_slot(fs, false) : sched_ctrl->last_ul_slot;
int last_ul_slot = fs->frame_type == TDD ? get_first_ul_slot(fs, false) : sched_ctrl->last_ul_slot;
const int last_ul_sched = sched_ctrl->last_ul_frame * n + last_ul_slot;
const int diff = (now - last_ul_sched + 1024 * n) % (1024 * n);
/* UE is to be scheduled if
@@ -1751,9 +1751,9 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
sched_ctrl->cce_index = CCEIndex;
fill_pdcch_vrb_map(nrmac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, dci_beam_idx);
retInfo->frame = (frame + (slot + tda_info.k2) / nr_slots_per_frame[ul_bwp->scs]) % MAX_FRAME_NUMBER;
retInfo->slot = (slot + tda_info.k2) % nr_slots_per_frame[ul_bwp->scs];
int slots_frame = nrmac->frame_structure.numb_slots_frame;
retInfo->frame = (frame + (slot + tda_info.k2) / slots_frame) % MAX_FRAME_NUMBER;
retInfo->slot = (slot + tda_info.k2) % slots_frame;
/* Get previous PSUCH field info */
sched_ctrl->sched_pusch = *retInfo;
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
@@ -1800,7 +1800,7 @@ static void pf_ul(module_id_t module_id,
const int CC_id = 0;
gNB_MAC_INST *nrmac = RC.nrmac[module_id];
NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
int slots_per_frame = nrmac->frame_structure.numb_slots_frame;
const int min_rb = nrmac->min_grant_prb;
// UEs that could be scheduled
UEsched_t UE_sched[MAX_MOBILES_PER_GNB + 1] = {0};
@@ -1833,21 +1833,19 @@ static void pf_ul(module_id_t module_id,
if (total_rem_ues == 0)
continue;
int n_dl = nr_slots_per_frame[UE->current_DL_BWP.scs];
NR_beam_alloc_t dci_beam = beam_allocation_procedure(&nrmac->beam_info, frame, slot, UE->UE_beam_index, n_dl);
NR_beam_alloc_t dci_beam = beam_allocation_procedure(&nrmac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame);
if (dci_beam.idx < 0) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] Beam could not be allocated\n", UE->rnti, frame, slot);
continue;
}
int n = nr_slots_per_frame[current_BWP->scs];
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, n);
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_per_frame);
if (beam.idx < 0) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] Beam could not be allocated\n", UE->rnti, frame, slot);
reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, n_dl, dci_beam.new_beam);
reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
continue;
}
const int index = ul_buffer_index(sched_frame, sched_slot, current_BWP->scs, nrmac->vrb_map_UL_size);
const int index = ul_buffer_index(sched_frame, sched_slot, slots_per_frame, nrmac->vrb_map_UL_size);
uint16_t *rballoc_mask = &nrmac->common_channels[CC_id].vrb_map_UL[beam.idx][index * MAX_BWP_SIZE];
/* Check if retransmission is necessary */
@@ -1868,8 +1866,8 @@ static void pf_ul(module_id_t module_id,
tda);
if (!r) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] UL retransmission could not be allocated\n", UE->rnti, frame, slot);
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, n, beam.new_beam);
reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, n_dl, dci_beam.new_beam);
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
continue;
}
else
@@ -1884,8 +1882,8 @@ static void pf_ul(module_id_t module_id,
* if the UE disconnected in L2sim, in which case the gNB is not notified
* (this can be considered a design flaw) */
if (sched_ctrl->available_ul_harq.head < 0) {
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, n, beam.new_beam);
reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, n_dl, dci_beam.new_beam);
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] has no free UL HARQ process, skipping\n", UE->rnti, frame, slot);
continue;
}
@@ -1900,8 +1898,8 @@ static void pf_ul(module_id_t module_id,
LOG_D(NR_MAC,"pf_ul: do_sched UE %04x => %s\n", UE->rnti, do_sched ? "yes" : "no");
if ((B == 0 && !do_sched) || nr_timer_is_active(&sched_ctrl->transm_interrupt)) {
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, n, beam.new_beam);
reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, n_dl, dci_beam.new_beam);
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
continue;
}
@@ -1931,8 +1929,8 @@ static void pf_ul(module_id_t module_id,
sched_ctrl->pdcch_cl_adjust);
if (CCEIndex < 0) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] no free CCE for UL DCI (BSR 0)\n", UE->rnti, frame, slot);
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, n, beam.new_beam);
reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, n_dl, dci_beam.new_beam);
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
continue;
}
@@ -1966,8 +1964,8 @@ static void pf_ul(module_id_t module_id,
rbStart,
min_rb,
bwpSize);
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, n, beam.new_beam);
reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, n_dl, dci_beam.new_beam);
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
continue;
}
@@ -2041,12 +2039,10 @@ static void pf_ul(module_id_t module_id,
/* Loop UE_sched to find max coeff and allocate transmission */
while (iterator->UE != NULL) {
NR_UE_UL_BWP_t *current_BWP = &iterator->UE->current_UL_BWP;
NR_UE_DL_BWP_t *dl_BWP = &iterator->UE->current_DL_BWP;
NR_UE_sched_ctrl_t *sched_ctrl = &iterator->UE->UE_sched_ctrl;
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
int n = nr_slots_per_frame[current_BWP->scs];
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, n);
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, slots_per_frame);
if (beam.idx < 0) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] Beam could not be allocated\n", iterator->UE->rnti, frame, slot);
iterator++;
@@ -2054,16 +2050,15 @@ static void pf_ul(module_id_t module_id,
}
if (remainUEs[beam.idx] == 0 || n_rb_sched[beam.idx] < min_rb) {
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, n, beam.new_beam);
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, slots_per_frame, beam.new_beam);
iterator++;
continue;
}
int n_dl = nr_slots_per_frame[dl_BWP->scs];
NR_beam_alloc_t dci_beam = beam_allocation_procedure(&nrmac->beam_info, frame, slot, iterator->UE->UE_beam_index, n_dl);
NR_beam_alloc_t dci_beam = beam_allocation_procedure(&nrmac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame);
if (dci_beam.idx < 0) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] Beam could not be allocated\n", iterator->UE->rnti, frame, slot);
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, n, beam.new_beam);
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, slots_per_frame, beam.new_beam);
iterator++;
continue;
}
@@ -2079,8 +2074,8 @@ static void pf_ul(module_id_t module_id,
sched_ctrl->pdcch_cl_adjust);
if (CCEIndex < 0) {
reset_beam_status(&nrmac->beam_info, frame, slot, iterator->UE->UE_beam_index, n_dl, dci_beam.new_beam);
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, n, beam.new_beam);
reset_beam_status(&nrmac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, slots_per_frame, beam.new_beam);
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] no free CCE for UL DCI\n", iterator->UE->rnti, frame, slot);
iterator++;
continue;
@@ -2100,7 +2095,7 @@ static void pf_ul(module_id_t module_id,
AssertFatal(sched_pusch->tda_info.valid_tda, "Invalid TDA from get_ul_tda_info\n");
sched_pusch->dmrs_info = get_ul_dmrs_params(scc, current_BWP, &sched_pusch->tda_info, sched_pusch->nrOfLayers);
const int index = ul_buffer_index(sched_frame, sched_slot, current_BWP->scs, nrmac->vrb_map_UL_size);
const int index = ul_buffer_index(sched_frame, sched_slot, slots_per_frame, nrmac->vrb_map_UL_size);
uint16_t *rballoc_mask = &nrmac->common_channels[CC_id].vrb_map_UL[beam.idx][index * MAX_BWP_SIZE];
int rbStart = 0;
@@ -2115,8 +2110,8 @@ static void pf_ul(module_id_t module_id,
max_rbSize++;
if (rbStart + min_rb >= bwpSize || max_rbSize < min_rb) {
reset_beam_status(&nrmac->beam_info, frame, slot, iterator->UE->UE_beam_index, n_dl, dci_beam.new_beam);
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, n, beam.new_beam);
reset_beam_status(&nrmac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, slots_per_frame, beam.new_beam);
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate UL data: no resources (rbStart %d, min_rb %d, bwpSize %d)\n",
iterator->UE->rnti,
frame,
@@ -2215,7 +2210,7 @@ static bool nr_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_fram
const NR_SIB1_t *sib1 = nr_mac->common_channels[0].sib1 ? nr_mac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
NR_ServingCellConfigCommonSIB_t *scc_sib1 = sib1 ? sib1->servingCellConfigCommon : NULL;
AssertFatal(scc || scc_sib1, "We need one serving cell config common\n");
const int slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
const int slots_frame = nr_mac->frame_structure.numb_slots_frame;
// TODO we assume the same K2 for all UEs
const int K2 = nr_mac->radio_config.minRXTXTIME + get_NTN_Koffset(scc);
const int sched_frame = (frame + (slot + K2) / slots_frame) % MAX_FRAME_NUMBER;
@@ -2408,7 +2403,10 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n
sched_ctrl->tpc0);
/* PUSCH in a later slot, but corresponding DCI now! */
const int index = ul_buffer_index(sched_pusch->frame, sched_pusch->slot, current_BWP->scs, nr_mac->UL_tti_req_ahead_size);
const int index = ul_buffer_index(sched_pusch->frame,
sched_pusch->slot,
nr_mac->frame_structure.numb_slots_frame,
nr_mac->UL_tti_req_ahead_size);
nfapi_nr_ul_tti_request_t *future_ul_tti_req = &nr_mac->UL_tti_req_ahead[0][index];
if (future_ul_tti_req->SFN != sched_pusch->frame || future_ul_tti_req->Slot != sched_pusch->slot)
LOG_W(NR_MAC,
+3 -14
View File
@@ -39,11 +39,6 @@ void set_cset_offset(uint16_t);
void get_K1_K2(int N1, int N2, int *K1, int *K2, int layers);
int get_NTN_Koffset(const NR_ServingCellConfigCommon_t *scc);
void config_frame_structure(int mu,
NR_ServingCellConfigCommon_t *scc,
uint8_t tdd_period,
uint8_t frame_type,
frame_structure_t *fs);
int get_first_ul_slot(const frame_structure_t *fs, bool mixed);
int get_ul_slots_per_period(const frame_structure_t *fs);
int get_ul_slots_per_frame(const frame_structure_t *fs);
@@ -191,11 +186,9 @@ int get_pucch_resourceid(NR_PUCCH_Config_t *pucch_Config, int O_uci, int pucch_r
void nr_schedule_srs(int module_id, frame_t frame, int slot);
void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slots_frame, nfapi_nr_dl_tti_request_t *DL_req);
void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, nfapi_nr_dl_tti_request_t *DL_req);
void nr_csi_meas_reporting(int Mod_idP,
frame_t frameP,
sub_frame_t slotP);
void nr_csi_meas_reporting(int Mod_idP, frame_t frameP, sub_frame_t slotP);
int nr_acknack_scheduling(gNB_MAC_INST *mac,
NR_UE_info_t *UE,
@@ -355,10 +348,6 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
int binomial(int n, int k);
bool is_ul_slot(const slot_t slot, const frame_structure_t *fs);
bool is_dl_slot(const slot_t slot, const frame_structure_t *fs);
bool is_mixed_slot(const slot_t slot, const frame_structure_t *fs);
/* \brief Function to indicate a received SDU on ULSCH.
@param Mod_id Instance ID of gNB
@param CC_id Component carrier index
@@ -454,7 +443,7 @@ int get_mcs_from_bler(const NR_bler_options_t *bler_options,
int max_mcs,
frame_t frame);
int ul_buffer_index(int frame, int slot, int scs, int size);
int ul_buffer_index(int frame, int slot, int slots_per_frame, int size);
void UL_tti_req_ahead_initialization(gNB_MAC_INST *gNB, int n, int CCid, frame_t frameP, int slotP);
void fapi_beam_index_allocation(NR_ServingCellConfigCommon_t *scc, gNB_MAC_INST *mac);
+2 -2
View File
@@ -794,7 +794,7 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request,
int slots_per_frame = 20; //30 kHZ subcarrier spacing
int slot_ahead = 2; // TODO: Make this dynamic
if (is_nr_UL_slot(mac->tdd_UL_DL_ConfigurationCommon, (slot + slot_ahead) % slots_per_frame, mac->frame_type)
if (is_ul_slot((slot + slot_ahead) % slots_per_frame, &mac->frame_structure)
&& mac->ra.ra_state != nrRA_SUCCEEDED) {
// If we filled dl_info AFTER we got the slot indication, we want to check if we should fill tx_req:
nr_uplink_indication_t ul_info = {.slot = (slot + slot_ahead) % slots_per_frame,
@@ -1203,7 +1203,7 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info)
LOG_T(NR_MAC, "Not calling scheduler mac->ra.ra_state = %d\n", mac->ra.ra_state);
if (is_nr_UL_slot(mac->tdd_UL_DL_ConfigurationCommon, ul_info->slot, mac->frame_type))
if (is_ul_slot(ul_info->slot, &mac->frame_structure))
nr_ue_ul_scheduler(mac, ul_info);
ret = pthread_mutex_unlock(&mac->if_mutex);
AssertFatal(!ret, "mutex failed %d\n", ret);
+1 -55
View File
@@ -1018,60 +1018,6 @@ void nr_rrc_config_dl_tda(struct NR_PDSCH_TimeDomainResourceAllocationList *pdsc
}
}
const float tdd_ms_period_pattern[] = {0.5, 0.625, 1.0, 1.25, 2.0, 2.5, 5.0, 10.0};
const float tdd_ms_period_ext[] = {3.0, 4.0};
/**
* @brief Retrieves the periodicity in milliseconds for the given TDD pattern
* depending on the presence of the extension
* @param pattern Pointer to the NR_TDD_UL_DL_Pattern_t pattern structure
* @return Periodicity value in milliseconds.
*/
static float get_tdd_periodicity(NR_TDD_UL_DL_Pattern_t *pattern) {
if (!pattern->ext1) {
LOG_D(NR_MAC, "Setting TDD configuration period to dl_UL_TransmissionPeriodicity %ld\n", pattern->dl_UL_TransmissionPeriodicity);
return tdd_ms_period_pattern[pattern->dl_UL_TransmissionPeriodicity];
} else {
DevAssert(pattern->ext1->dl_UL_TransmissionPeriodicity_v1530 != NULL);
LOG_D(NR_MAC,
"Setting TDD configuration period to dl_UL_TransmissionPeriodicity_v1530 %ld\n",
*pattern->ext1->dl_UL_TransmissionPeriodicity_v1530);
return tdd_ms_period_ext[*pattern->ext1->dl_UL_TransmissionPeriodicity_v1530];
}
}
/**
* @brief Determines the TDD period index based on pattern periodicities
* @note Not applicabile to pattern extension
* @param tdd Pointer to the NR_TDD_UL_DL_ConfigCommon_t containing patterns
* @return Index of the TDD period in tdd_ms_period_pattern
*/
int get_tdd_period_idx(NR_TDD_UL_DL_ConfigCommon_t *tdd)
{
int tdd_period_idx = 0;
float pattern1_ms = get_tdd_periodicity(&tdd->pattern1);
float pattern2_ms = tdd->pattern2 ? get_tdd_periodicity(tdd->pattern2) : 0.0;
bool found_match = false;
// Find matching TDD period in the predefined list of periodicities
for (int i = 0; i < NFAPI_MAX_NUM_PERIODS; i++) {
if ((pattern1_ms + pattern2_ms) == tdd_ms_period_pattern[i]) {
tdd_period_idx = i;
LOG_I(NR_MAC,
"TDD period index = %d, based on the sum of dl_UL_TransmissionPeriodicity "
"from Pattern1 (%f ms) and Pattern2 (%f ms): Total = %f ms\n",
tdd_period_idx,
pattern1_ms,
pattern2_ms,
pattern1_ms + pattern2_ms);
found_match = true;
break;
}
}
// Assert if no match was found
AssertFatal(found_match, "The sum of pattern1_ms and pattern2_ms does not match any value in tdd_ms_period_pattern");
return tdd_period_idx;
}
static struct NR_PUSCH_TimeDomainResourceAllocation *set_TimeDomainResourceAllocation(const int k2, uint8_t index, int ul_symb)
{
struct NR_PUSCH_TimeDomainResourceAllocation *puschTdrAlloc = calloc_or_fail(1, sizeof(*puschTdrAlloc));
@@ -1297,7 +1243,7 @@ static void set_SR_periodandoffset(NR_SchedulingRequestResourceConfig_t *schedul
{
const frame_structure_t *fs = &RC.nrmac[0]->frame_structure;
int sr_slot = 1; // in FDD SR in slot 1
if (fs->is_tdd)
if (fs->frame_type == TDD)
sr_slot = get_first_ul_slot(fs, true);
schedulingRequestResourceConfig->periodicityAndOffset = calloc(1,sizeof(*schedulingRequestResourceConfig->periodicityAndOffset));
-1
View File
@@ -115,6 +115,5 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC
int uid);
NR_ReconfigurationWithSync_t *get_reconfiguration_with_sync(rnti_t rnti, uid_t uid, const NR_ServingCellConfigCommon_t *scc);
int get_tdd_period_idx(NR_TDD_UL_DL_ConfigCommon_t *tdd);
#endif