Dynamic PDCCH aggregation level
The aggregation level search order for PDCCH candidates is modified: - the search starts from desired_agg_level_index, which is a value from 0 to 4 proportial to pdcch_cl_adjust. - pdcch_cl_adjust is a value between 0 and 1 that indicates PDCCH channel quality by averaging HARQ DTX rate. A value of 0 means perfect channel, a value o 1 means impaired channel.
This commit is contained in:
@@ -38,6 +38,28 @@ The actual scheduler implementation can be found in functions `pf_dl()` and
|
|||||||
[`gNB_scheduler_ulsch.c`](../../openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c)
|
[`gNB_scheduler_ulsch.c`](../../openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c)
|
||||||
(for UL), respectively.
|
(for UL), respectively.
|
||||||
|
|
||||||
|
## PDDCH aggregation level
|
||||||
|
|
||||||
|
PDCCH aggregation level is selected using closed loop controller, where DL HARQ
|
||||||
|
feedback is the controller feedback signal. It is used to increment `pdcch_cl_adjust`
|
||||||
|
variable if no feedback is detected and decrement the variable when feedback is detected.
|
||||||
|
`pdcch_cl_adjust` is later mapped PDCCH aggregation level range.
|
||||||
|
|
||||||
|
The value of `pdcch_cl_adjust` is clamped to range <0,1>, the increment value is 0.05 while
|
||||||
|
the decrement value is 0.01.
|
||||||
|
|
||||||
|
### Examples:
|
||||||
|
#### Example 1:
|
||||||
|
Say we have 90% PDCCH success rate at aggregation level 1, `pdcch_cl_adjust` will stay at 0
|
||||||
|
for most of the time. 2 consecutive PDCCH failures will not result in increasing the aggregation
|
||||||
|
level (because (0.05 + 0.05) * 4 = 0.4 which is closer to 0 than to 1). If PDCCH fails 3 times
|
||||||
|
in a row the aggregation level will change to 2 and hopefully back to 1 once more PDDCH successes
|
||||||
|
happen.
|
||||||
|
|
||||||
|
### Example 2
|
||||||
|
Say we have 0% PDCCH success rate (radio link failure scenario) but `pdcch_cl_adjust` is 0 indicating
|
||||||
|
perfect PDCCH channel. it would take ~18 PDCCH failures to reach maximum aggregation level.
|
||||||
|
|
||||||
# Periodic output and interpretation
|
# Periodic output and interpretation
|
||||||
|
|
||||||
The scheduler periodically outputs statistics that can help you judge the radio
|
The scheduler periodically outputs statistics that can help you judge the radio
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ static void nr_generate_dci(PHY_VARS_gNB *gNB,
|
|||||||
if (dci_pdu->RNTI != 0xFFFF)
|
if (dci_pdu->RNTI != 0xFFFF)
|
||||||
LOG_D(NR_PHY_DCI,
|
LOG_D(NR_PHY_DCI,
|
||||||
"DL_DCI : rb_offset %d, nb_rb %d, DMRS length per symbol %d\t DCI encoded length %d (precoder_granularity %d, "
|
"DL_DCI : rb_offset %d, nb_rb %d, DMRS length per symbol %d\t DCI encoded length %d (precoder_granularity %d, "
|
||||||
"reg_mapping %d), Scrambling_Id %d, ScramblingRNTI %x, PayloadSizeBits %d\n",
|
"reg_mapping %d), Scrambling_Id %d, ScramblingRNTI %x, PayloadSizeBits %d AggregationLevel %d\n",
|
||||||
rb_offset,
|
rb_offset,
|
||||||
n_rb,
|
n_rb,
|
||||||
dmrs_length,
|
dmrs_length,
|
||||||
@@ -108,7 +108,8 @@ static void nr_generate_dci(PHY_VARS_gNB *gNB,
|
|||||||
pdcch_pdu_rel15->CceRegMappingType,
|
pdcch_pdu_rel15->CceRegMappingType,
|
||||||
dci_pdu->ScramblingId,
|
dci_pdu->ScramblingId,
|
||||||
dci_pdu->ScramblingRNTI,
|
dci_pdu->ScramblingRNTI,
|
||||||
dci_pdu->PayloadSizeBits);
|
dci_pdu->PayloadSizeBits,
|
||||||
|
dci_pdu->AggregationLevel);
|
||||||
dmrs_length += rb_offset*6; // To accommodate more DMRS symbols in case of rb offset
|
dmrs_length += rb_offset*6; // To accommodate more DMRS symbols in case of rb offset
|
||||||
|
|
||||||
/// DMRS QPSK modulation
|
/// DMRS QPSK modulation
|
||||||
|
|||||||
@@ -874,7 +874,8 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
|
|||||||
ss,
|
ss,
|
||||||
coreset,
|
coreset,
|
||||||
&ra->sched_pdcch,
|
&ra->sched_pdcch,
|
||||||
true);
|
true,
|
||||||
|
0);
|
||||||
if (CCEIndex < 0) {
|
if (CCEIndex < 0) {
|
||||||
LOG_E(NR_MAC, "UE %04x cannot find free CCE!\n", ra->rnti);
|
LOG_E(NR_MAC, "UE %04x cannot find free CCE!\n", ra->rnti);
|
||||||
return;
|
return;
|
||||||
@@ -1484,7 +1485,7 @@ static void nr_generate_Msg2(module_id_t module_idP,
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t aggregation_level;
|
uint8_t aggregation_level;
|
||||||
int CCEIndex = get_cce_index(nr_mac, CC_id, slotP, 0, &aggregation_level, beam.idx, ss, coreset, &ra->sched_pdcch, true);
|
int CCEIndex = get_cce_index(nr_mac, CC_id, slotP, 0, &aggregation_level, beam.idx, ss, coreset, &ra->sched_pdcch, true, 0);
|
||||||
|
|
||||||
if (CCEIndex < 0) {
|
if (CCEIndex < 0) {
|
||||||
LOG_W(NR_MAC, "UE %04x: %d.%d cannot find free CCE for Msg2!\n", ra->rnti, frameP, slotP);
|
LOG_W(NR_MAC, "UE %04x: %d.%d cannot find free CCE for Msg2!\n", ra->rnti, frameP, slotP);
|
||||||
@@ -2006,7 +2007,8 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
|
|||||||
ss,
|
ss,
|
||||||
coreset,
|
coreset,
|
||||||
&ra->sched_pdcch,
|
&ra->sched_pdcch,
|
||||||
true);
|
true,
|
||||||
|
0);
|
||||||
|
|
||||||
if (CCEIndex < 0) {
|
if (CCEIndex < 0) {
|
||||||
LOG_E(NR_MAC, "Cannot find free CCE for RA RNTI 0x%04x!\n", ra->rnti);
|
LOG_E(NR_MAC, "Cannot find free CCE for RA RNTI 0x%04x!\n", ra->rnti);
|
||||||
|
|||||||
@@ -553,7 +553,8 @@ static bool allocate_dl_retransmission(module_id_t module_id,
|
|||||||
sched_ctrl->search_space,
|
sched_ctrl->search_space,
|
||||||
sched_ctrl->coreset,
|
sched_ctrl->coreset,
|
||||||
&sched_ctrl->sched_pdcch,
|
&sched_ctrl->sched_pdcch,
|
||||||
false);
|
false,
|
||||||
|
sched_ctrl->pdcch_cl_adjust);
|
||||||
if (CCEIndex<0) {
|
if (CCEIndex<0) {
|
||||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find free CCE for DL DCI retransmission\n", UE->rnti, frame, slot);
|
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find free CCE for DL DCI retransmission\n", UE->rnti, frame, slot);
|
||||||
return false;
|
return false;
|
||||||
@@ -817,7 +818,8 @@ static void pf_dl(module_id_t module_id,
|
|||||||
sched_ctrl->search_space,
|
sched_ctrl->search_space,
|
||||||
sched_ctrl->coreset,
|
sched_ctrl->coreset,
|
||||||
&sched_ctrl->sched_pdcch,
|
&sched_ctrl->sched_pdcch,
|
||||||
false);
|
false,
|
||||||
|
sched_ctrl->pdcch_cl_adjust);
|
||||||
if (CCEIndex < 0) {
|
if (CCEIndex < 0) {
|
||||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find free CCE for DL DCI\n", rnti, frame, slot);
|
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,
|
reset_beam_status(&mac->beam_info,
|
||||||
|
|||||||
@@ -148,7 +148,8 @@ void nr_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_t s
|
|||||||
sched_ctrl->search_space,
|
sched_ctrl->search_space,
|
||||||
sched_ctrl->coreset,
|
sched_ctrl->coreset,
|
||||||
&sched_ctrl->sched_pdcch,
|
&sched_ctrl->sched_pdcch,
|
||||||
false);
|
false,
|
||||||
|
0);
|
||||||
AssertFatal(CCEIndex >= 0, "Could not find CCE for UE %04x\n", UE->rnti);
|
AssertFatal(CCEIndex >= 0, "Could not find CCE for UE %04x\n", UE->rnti);
|
||||||
|
|
||||||
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
|
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
|
||||||
@@ -312,7 +313,8 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
|
|||||||
sched_ctrl->search_space,
|
sched_ctrl->search_space,
|
||||||
sched_ctrl->coreset,
|
sched_ctrl->coreset,
|
||||||
&sched_ctrl->sched_pdcch,
|
&sched_ctrl->sched_pdcch,
|
||||||
false);
|
false,
|
||||||
|
0);
|
||||||
if (CCEIndex < 0) {
|
if (CCEIndex < 0) {
|
||||||
LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PUSCH\n", __func__);
|
LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PUSCH\n", __func__);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -119,6 +119,9 @@ static const uint16_t cqi_table3[16][2] = {{0, 0},
|
|||||||
{6, 6660},
|
{6, 6660},
|
||||||
{6, 7720}};
|
{6, 7720}};
|
||||||
|
|
||||||
|
static void determine_aggregation_level_search_order(int agg_level_search_order[NUM_PDCCH_AGG_LEVELS],
|
||||||
|
float pdcch_cl_adjust);
|
||||||
|
|
||||||
uint8_t get_dl_nrOfLayers(const NR_UE_sched_ctrl_t *sched_ctrl,
|
uint8_t get_dl_nrOfLayers(const NR_UE_sched_ctrl_t *sched_ctrl,
|
||||||
const nr_dci_format_t dci_format) {
|
const nr_dci_format_t dci_format) {
|
||||||
|
|
||||||
@@ -550,15 +553,18 @@ int get_cce_index(const gNB_MAC_INST *nrmac,
|
|||||||
const NR_SearchSpace_t *ss,
|
const NR_SearchSpace_t *ss,
|
||||||
const NR_ControlResourceSet_t *coreset,
|
const NR_ControlResourceSet_t *coreset,
|
||||||
NR_sched_pdcch_t *sched_pdcch,
|
NR_sched_pdcch_t *sched_pdcch,
|
||||||
bool is_common)
|
bool is_common,
|
||||||
|
float pdcch_cl_adjust)
|
||||||
{
|
{
|
||||||
|
|
||||||
const uint32_t Y = is_common ? 0 : get_Y(ss, slot, rnti);
|
const uint32_t Y = is_common ? 0 : get_Y(ss, slot, rnti);
|
||||||
uint8_t nr_of_candidates;
|
uint8_t nr_of_candidates;
|
||||||
for (int i = 0; i < 5; i++) {
|
|
||||||
// for now taking the lowest value among the available aggregation levels
|
int agg_level_search_order[NUM_PDCCH_AGG_LEVELS];
|
||||||
find_aggregation_candidates(aggregation_level, &nr_of_candidates, ss, 1 << i);
|
determine_aggregation_level_search_order(agg_level_search_order, pdcch_cl_adjust);
|
||||||
if(nr_of_candidates > 0)
|
|
||||||
|
for (int i = 0; i < NUM_PDCCH_AGG_LEVELS; i++) {
|
||||||
|
find_aggregation_candidates(aggregation_level, &nr_of_candidates, ss, 1 << agg_level_search_order[i]);
|
||||||
|
if (nr_of_candidates > 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
int CCEIndex = find_pdcch_candidate(nrmac, CC_id, *aggregation_level, nr_of_candidates, beam_idx, sched_pdcch, coreset, Y);
|
int CCEIndex = find_pdcch_candidate(nrmac, CC_id, *aggregation_level, nr_of_candidates, beam_idx, sched_pdcch, coreset, Y);
|
||||||
@@ -2516,6 +2522,7 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf
|
|||||||
sched_ctrl->ta_update = 31;
|
sched_ctrl->ta_update = 31;
|
||||||
sched_ctrl->sched_srs.frame = -1;
|
sched_ctrl->sched_srs.frame = -1;
|
||||||
sched_ctrl->sched_srs.slot = -1;
|
sched_ctrl->sched_srs.slot = -1;
|
||||||
|
sched_ctrl->pdcch_cl_adjust = 0;
|
||||||
|
|
||||||
// initialize LCID structure
|
// initialize LCID structure
|
||||||
seq_arr_init(&sched_ctrl->lc_config, sizeof(nr_lc_config_t));
|
seq_arr_init(&sched_ctrl->lc_config, sizeof(nr_lc_config_t));
|
||||||
@@ -3524,3 +3531,31 @@ bool nr_mac_get_new_rnti(NR_UEs_t *UEs, const NR_RA_t *ra_base, int ra_count, rn
|
|||||||
} while (loop < 100 && (exist_connected_ue || exist_in_pending_ra_ue));
|
} while (loop < 100 && (exist_connected_ue || exist_in_pending_ra_ue));
|
||||||
return loop < 100; // nothing found: loop count 100
|
return loop < 100; // nothing found: loop count 100
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief Orders PDCCH aggregation levels so that we first check desired aggregation level according to
|
||||||
|
/// pdcch_cl_adjust
|
||||||
|
/// @param agg_level_search_order in/out 5-element array of aggregation levels from 0 to 4
|
||||||
|
/// @param pdcch_cl_adjust value from 0 to 1 indication channel impariments (0 - good channel, 1 - bad channel)
|
||||||
|
static void determine_aggregation_level_search_order(int agg_level_search_order[NUM_PDCCH_AGG_LEVELS], float pdcch_cl_adjust)
|
||||||
|
{
|
||||||
|
int desired_agg_level_index = round(4 * pdcch_cl_adjust);
|
||||||
|
int agg_level_search_index = 0;
|
||||||
|
for (int i = desired_agg_level_index; i < NUM_PDCCH_AGG_LEVELS; i++) {
|
||||||
|
agg_level_search_order[agg_level_search_index++] = i;
|
||||||
|
}
|
||||||
|
for (int i = desired_agg_level_index - 1; i >= 0; i--) {
|
||||||
|
agg_level_search_order[agg_level_search_index++] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Update PDCCH closed loop adjust for UE depending on detection of feedback.
|
||||||
|
/// @param sched_ctrl UE scheduling control info
|
||||||
|
/// @param feedback_not_detected Whether feedback (PUSCH or HARQ) was detected
|
||||||
|
void nr_mac_update_pdcch_closed_loop_adjust(NR_UE_sched_ctrl_t *sched_ctrl, bool feedback_not_detected)
|
||||||
|
{
|
||||||
|
if (feedback_not_detected) {
|
||||||
|
sched_ctrl->pdcch_cl_adjust = min(1, sched_ctrl->pdcch_cl_adjust + 0.05);
|
||||||
|
} else {
|
||||||
|
sched_ctrl->pdcch_cl_adjust = max(0, sched_ctrl->pdcch_cl_adjust - 0.01);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -787,6 +787,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
|
|||||||
const int8_t pid = sched_ctrl->feedback_dl_harq.head;
|
const int8_t pid = sched_ctrl->feedback_dl_harq.head;
|
||||||
remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
|
remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
|
||||||
LOG_D(NR_MAC,"%4d.%2d bit %d pid %d ack/nack %d\n",frame, slot, harq_bit,pid,harq_value);
|
LOG_D(NR_MAC,"%4d.%2d bit %d pid %d ack/nack %d\n",frame, slot, harq_bit,pid,harq_value);
|
||||||
|
nr_mac_update_pdcch_closed_loop_adjust(sched_ctrl, harq_confidence != 0);
|
||||||
handle_dl_harq(UE, pid, harq_value == 0 && harq_confidence == 0, nrmac->dl_bler.harq_round_max);
|
handle_dl_harq(UE, pid, harq_value == 0 && harq_confidence == 0, nrmac->dl_bler.harq_round_max);
|
||||||
if (!UE->Msg4_MsgB_ACKed && harq_value == 0 && harq_confidence == 0)
|
if (!UE->Msg4_MsgB_ACKed && harq_value == 0 && harq_confidence == 0)
|
||||||
UE->Msg4_MsgB_ACKed = true;
|
UE->Msg4_MsgB_ACKed = true;
|
||||||
|
|||||||
@@ -1742,7 +1742,8 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
|
|||||||
sched_ctrl->search_space,
|
sched_ctrl->search_space,
|
||||||
sched_ctrl->coreset,
|
sched_ctrl->coreset,
|
||||||
&sched_ctrl->sched_pdcch,
|
&sched_ctrl->sched_pdcch,
|
||||||
false);
|
false,
|
||||||
|
sched_ctrl->pdcch_cl_adjust);
|
||||||
if (CCEIndex<0) {
|
if (CCEIndex<0) {
|
||||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] no free CCE for retransmission UL DCI UE\n", UE->rnti, frame, slot);
|
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] no free CCE for retransmission UL DCI UE\n", UE->rnti, frame, slot);
|
||||||
return false;
|
return false;
|
||||||
@@ -1926,7 +1927,8 @@ static void pf_ul(module_id_t module_id,
|
|||||||
sched_ctrl->search_space,
|
sched_ctrl->search_space,
|
||||||
sched_ctrl->coreset,
|
sched_ctrl->coreset,
|
||||||
&sched_ctrl->sched_pdcch,
|
&sched_ctrl->sched_pdcch,
|
||||||
false);
|
false,
|
||||||
|
sched_ctrl->pdcch_cl_adjust);
|
||||||
if (CCEIndex < 0) {
|
if (CCEIndex < 0) {
|
||||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] no free CCE for UL DCI (BSR 0)\n", UE->rnti, frame, slot);
|
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, sched_frame, sched_slot, UE->UE_beam_index, n, beam.new_beam);
|
||||||
@@ -2073,7 +2075,8 @@ static void pf_ul(module_id_t module_id,
|
|||||||
sched_ctrl->search_space,
|
sched_ctrl->search_space,
|
||||||
sched_ctrl->coreset,
|
sched_ctrl->coreset,
|
||||||
&sched_ctrl->sched_pdcch,
|
&sched_ctrl->sched_pdcch,
|
||||||
false);
|
false,
|
||||||
|
sched_ctrl->pdcch_cl_adjust);
|
||||||
|
|
||||||
if (CCEIndex < 0) {
|
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, frame, slot, iterator->UE->UE_beam_index, n_dl, dci_beam.new_beam);
|
||||||
|
|||||||
@@ -433,7 +433,8 @@ int get_cce_index(const gNB_MAC_INST *nrmac,
|
|||||||
const NR_SearchSpace_t *ss,
|
const NR_SearchSpace_t *ss,
|
||||||
const NR_ControlResourceSet_t *coreset,
|
const NR_ControlResourceSet_t *coreset,
|
||||||
NR_sched_pdcch_t *sched_pdcch,
|
NR_sched_pdcch_t *sched_pdcch,
|
||||||
bool is_common);
|
bool is_common,
|
||||||
|
float pdcch_cl_adjust);
|
||||||
|
|
||||||
bool nr_find_nb_rb(uint16_t Qm,
|
bool nr_find_nb_rb(uint16_t Qm,
|
||||||
uint16_t R,
|
uint16_t R,
|
||||||
@@ -493,5 +494,6 @@ bool nr_mac_add_lcid(NR_UE_sched_ctrl_t *sched_ctrl, const nr_lc_config_t *c);
|
|||||||
bool nr_mac_remove_lcid(NR_UE_sched_ctrl_t *sched_ctrl, long lcid);
|
bool nr_mac_remove_lcid(NR_UE_sched_ctrl_t *sched_ctrl, long lcid);
|
||||||
|
|
||||||
bool nr_mac_get_new_rnti(NR_UEs_t *UEs, const NR_RA_t *ra_base, int ra_count, rnti_t *rnti);
|
bool nr_mac_get_new_rnti(NR_UEs_t *UEs, const NR_RA_t *ra_base, int ra_count, rnti_t *rnti);
|
||||||
|
void nr_mac_update_pdcch_closed_loop_adjust(NR_UE_sched_ctrl_t *sched_ctrl, bool feedback_not_detected);
|
||||||
|
|
||||||
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
|
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
|
||||||
|
|||||||
@@ -125,6 +125,15 @@ typedef enum {
|
|||||||
nrRA_WAIT_Msg4_MsgB_ACK,
|
nrRA_WAIT_Msg4_MsgB_ACK,
|
||||||
} RA_gNB_state_t;
|
} RA_gNB_state_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PDCCH_AGG_LEVEL1 = 0,
|
||||||
|
PDCCH_AGG_LEVEL2,
|
||||||
|
PDCCH_AGG_LEVEL4,
|
||||||
|
PDCCH_AGG_LEVEL8,
|
||||||
|
PDCCH_AGG_LEVEL16,
|
||||||
|
NUM_PDCCH_AGG_LEVELS
|
||||||
|
} Pdcch_Aggregation_Level_t;
|
||||||
|
|
||||||
static const char *const nrra_text[] =
|
static const char *const nrra_text[] =
|
||||||
{"IDLE", "Msg2", "WAIT_MsgA_PUSCH", "WAIT_Msg3", "Msg3_retransmission", "Msg3_dcch_dtch", "Msg4", "MsgB", "WAIT_Msg4_ACK"};
|
{"IDLE", "Msg2", "WAIT_MsgA_PUSCH", "WAIT_Msg3", "Msg3_retransmission", "Msg3_dcch_dtch", "Msg4", "MsgB", "WAIT_Msg4_ACK"};
|
||||||
|
|
||||||
@@ -675,6 +684,10 @@ typedef struct {
|
|||||||
|
|
||||||
/// per-LC configuration
|
/// per-LC configuration
|
||||||
seq_arr_t lc_config;
|
seq_arr_t lc_config;
|
||||||
|
|
||||||
|
// pdcch closed loop adjust for PDCCH aggregation level, range <0, 1>
|
||||||
|
// 0 - good channel, 1 - bad channel
|
||||||
|
float pdcch_cl_adjust;
|
||||||
} NR_UE_sched_ctrl_t;
|
} NR_UE_sched_ctrl_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user