mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-18 15:10:29 +00:00
Compare commits
3 Commits
pre-commit
...
beam_symbo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
26fe404fde | ||
|
|
2fb03fd59a | ||
|
|
f1180d09d4 |
@@ -63,8 +63,9 @@ int beam_index_allocation(bool das,
|
||||
|
||||
int idx = -1;
|
||||
for (int j = 0; j < common_vars->num_beams_period; j++) {
|
||||
// L2 analog beam implementation is slot based, so we need to verify occupancy for the whole slot
|
||||
for (int i = 0; i < symbols_per_slot; i++) {
|
||||
if (!((bitmap_symbols >> i) & 0x01))
|
||||
continue;
|
||||
int current_beam = common_vars->beam_id[j][slot * symbols_per_slot + i];
|
||||
if (current_beam == -1 || current_beam == ru_beam_idx)
|
||||
idx = j;
|
||||
|
||||
@@ -114,14 +114,12 @@
|
||||
{MACRLC_TRANSPORT_S_SHM_PREFIX, NULL, 0, .strptr=NULL, .defstrval="nvipc", TYPE_STRING, 0}, \
|
||||
{MACRLC_TRANSPORT_S_POLL_CORE, NULL, 0, .i8ptr=NULL, .defintval=-1, TYPE_INT8, 0}, \
|
||||
{MACRLC_ANALOG_BEAMFORMING, HLP_MACRLC_AB, 0, .strptr=NULL, .defstrval="none", TYPE_STRING, 0}, \
|
||||
{MACRLC_BEAM_DURATION, HLP_MACRLC_BEAM_DURATION, 0, .u8ptr=NULL, .defintval=1, TYPE_UINT8, 0}, \
|
||||
{MACRLC_BEAM_DURATION, HLP_MACRLC_BEAM_DURATION, 0, .i8ptr=NULL, .defintval=1, TYPE_INT8, 0}, \
|
||||
{MACRLC_BEAMS_PERIOD, HLP_MACRLC_BEAMS_PERIOD, 0, .u8ptr=NULL, .defintval=1, TYPE_UINT8, 0}, \
|
||||
{MACRLC_BEAM_WEIGHTS_LIST, NULL, 0, .iptr=NULL, .defintarrayval=0, TYPE_INTARRAY,0}, \
|
||||
{MACRLC_DBT_FILE, HLP_MACRLC_DBT_FILE, 0, .strptr=NULL, .defstrval=NULL, TYPE_STRING, 0}, \
|
||||
{MACRLC_PUSCH_RSSI_THRESHOLD, HLP_MACRLC_PUSCH_RSSI_THRESHOLD, \
|
||||
0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \
|
||||
{MACRLC_PUCCH_RSSI_THRESHOLD, HLP_MACRLC_PUCCH_RSSI_THRESHOLD, \
|
||||
0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \
|
||||
{MACRLC_PUSCH_RSSI_THRESHOLD, HLP_MACRLC_PUSCH_RSSI_THRESHOLD, 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \
|
||||
{MACRLC_PUCCH_RSSI_THRESHOLD, HLP_MACRLC_PUCCH_RSSI_THRESHOLD, 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \
|
||||
{MACRLC_STATS_MAX_UE, HLP_MACRLC_STATS_MAX_UE, 0, .iptr=NULL, .defintval=8, TYPE_INT, 0}, \
|
||||
}
|
||||
// clang-format off
|
||||
|
||||
@@ -1748,9 +1748,13 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
|
||||
NR_beam_info_t *beam_info = &RC.nrmac[j]->beam_info;
|
||||
int beams_per_period = *gpd(params, np, MACRLC_BEAMS_PERIOD)->u8ptr;
|
||||
beam_info->beam_allocation = malloc16(beams_per_period * sizeof(beam_info->beam_allocation));
|
||||
beam_info->beam_duration = *gpd(params, np, MACRLC_BEAM_DURATION)->u8ptr;
|
||||
int duration = *gpd(params, np, MACRLC_BEAM_DURATION)->i8ptr;
|
||||
AssertFatal(duration > -15 && duration != 0, "Invalid beam duration %d\n", duration);
|
||||
beam_info->beam_slot_duration = duration > 0 ? duration : 1;
|
||||
beam_info->beam_symbol_duration = duration < 0 ? -duration : 0;
|
||||
beam_info->beams_per_period = beams_per_period;
|
||||
beam_info->beam_allocation_size = -1; // to be initialized once we have information on frame configuration
|
||||
beam_info->beam_allocation_size[0] = -1; // to be initialized once we have information on frame configuration
|
||||
beam_info->beam_allocation_size[1] = -1;
|
||||
}
|
||||
bool das_enabled = false;
|
||||
if (NFAPI_MODE == NFAPI_MONOLITHIC) {
|
||||
|
||||
@@ -832,15 +832,24 @@ static void initialize_beam_information(NR_beam_info_t *beam_info, int mu, int s
|
||||
|
||||
int size = mu == 0 ? slots_per_frame << 1 : slots_per_frame;
|
||||
// slots in beam duration gives the number of consecutive slots tied the the same beam
|
||||
AssertFatal(size % beam_info->beam_duration == 0,
|
||||
AssertFatal(size % beam_info->beam_slot_duration == 0,
|
||||
"Beam duration %d should be divider of number of slots per frame %d\n",
|
||||
beam_info->beam_duration,
|
||||
beam_info->beam_slot_duration,
|
||||
slots_per_frame);
|
||||
beam_info->beam_allocation_size = size / beam_info->beam_duration;
|
||||
beam_info->beam_allocation_size[0] = size / beam_info->beam_slot_duration;
|
||||
int symb_dur = beam_info->beam_symbol_duration ? beam_info->beam_symbol_duration : NR_SYMBOLS_PER_SLOT;
|
||||
AssertFatal(NR_SYMBOLS_PER_SLOT % symb_dur == 0,
|
||||
"Beam duration in symbols %d should be a divider of number of symbols per slot %d\n",
|
||||
symb_dur,
|
||||
NR_SYMBOLS_PER_SLOT);
|
||||
beam_info->beam_allocation_size[1] = NR_SYMBOLS_PER_SLOT / symb_dur;
|
||||
for (int i = 0; i < beam_info->beams_per_period; i++) {
|
||||
beam_info->beam_allocation[i] = malloc16(beam_info->beam_allocation_size * sizeof(*beam_info->beam_allocation));
|
||||
for (int j = 0; j < beam_info->beam_allocation_size; j++)
|
||||
beam_info->beam_allocation[i][j] = -1;
|
||||
beam_info->beam_allocation[i] = malloc16(beam_info->beam_allocation_size[0] * sizeof(**beam_info->beam_allocation));
|
||||
for (int j = 0; j < beam_info->beam_allocation_size[0]; j++) {
|
||||
beam_info->beam_allocation[i][j] = malloc16(beam_info->beam_allocation_size[1] * sizeof(*beam_info->beam_allocation));
|
||||
for (int k = 0; k < beam_info->beam_allocation_size[1]; k++)
|
||||
beam_info->beam_allocation[i][j][k] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,14 +66,17 @@ static void clear_beam_information(NR_beam_info_t *beam_info, int frame, int slo
|
||||
if (beam_info->beam_mode == NO_BEAM_MODE)
|
||||
return;
|
||||
// initialization done only once
|
||||
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;
|
||||
if (slot % beam_info->beam_duration == 0) {
|
||||
AssertFatal(beam_info->beam_allocation_size[0] >= 0
|
||||
&& beam_info->beam_allocation_size[1] >= 0,
|
||||
"Beam information not initialized\n");
|
||||
int idx_to_clear = (frame * slots_per_frame + slot) / beam_info->beam_slot_duration;
|
||||
idx_to_clear = (idx_to_clear + beam_info->beam_allocation_size[0] - 1) % beam_info->beam_allocation_size[0];
|
||||
if (slot % beam_info->beam_slot_duration == 0) {
|
||||
// resetting previous period allocation
|
||||
LOG_D(NR_MAC, "%d.%d Clear beam information for index %d\n", frame, slot, idx_to_clear);
|
||||
for (int i = 0; i < beam_info->beams_per_period; i++)
|
||||
beam_info->beam_allocation[i][idx_to_clear] = -1;
|
||||
for (int k = 0; k < beam_info->beam_allocation_size[1]; k++)
|
||||
beam_info->beam_allocation[i][idx_to_clear][k] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -371,9 +371,16 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, slot_t slotP)
|
||||
UL_tti_req->SFN = frameP;
|
||||
UL_tti_req->Slot = slotP;
|
||||
UL_tti_req->rach_present = 1;
|
||||
NR_beam_alloc_t beam = {0};
|
||||
uint32_t N_t_slot = cc->prach_info.N_t_slot;
|
||||
uint32_t start_symb = cc->prach_info.start_symbol;
|
||||
int total_prach_slots = 1;
|
||||
uint32_t N_dur = cc->prach_info.N_dur;
|
||||
if (format0 < 4) {
|
||||
N_dur = 14; // number of PRACH symbols in PRACH slot
|
||||
total_prach_slots = get_long_prach_dur(format0, mu_pusch);
|
||||
AssertFatal(slotP + total_prach_slots - 1 < slots_frame, "PRACH cannot extend across frames\n");
|
||||
}
|
||||
NR_beam_alloc_t beam[total_prach_slots];
|
||||
for (int fdm_index = 0; fdm_index < fdm; fdm_index++) { // one structure per frequency domain occasion
|
||||
AssertFatal(UL_tti_req->n_pdus < sizeofArray(UL_tti_req->pdus_list), "Invalid UL_tti_req->n_pdus %d\n", UL_tti_req->n_pdus);
|
||||
nfapi_nr_ul_tti_request_number_of_pdus_t *newpdu = UL_tti_req->pdus_list + UL_tti_req->n_pdus;
|
||||
@@ -395,22 +402,29 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, slot_t slotP)
|
||||
num_td_occ++;
|
||||
float num_ssb_per_RO = ssb_per_rach_occasion[cfg->prach_config.ssb_per_rach.value];
|
||||
int beam_index = 0;
|
||||
int td_start = td_index * N_dur + start_symb;
|
||||
if(num_ssb_per_RO <= 1) {
|
||||
// ordered ssb number
|
||||
int n_ssb = (int) (prach_occasion_id / (int)(1 / num_ssb_per_RO)) % cc->num_active_ssb;
|
||||
// fapi beam index
|
||||
beam_index = get_beam_from_ssbidx(gNB, cc->ssb_index[n_ssb]);
|
||||
// multi-beam allocation structure
|
||||
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);
|
||||
// mark beam as occupied for current and future slots if prach extends beyond current slot
|
||||
for (int i = 0; i < total_prach_slots; i++) {
|
||||
beam[i] = beam_allocation_procedure(&gNB->beam_info, frameP, slotP + i, td_start, N_dur, beam_index, slots_frame);
|
||||
AssertFatal(beam[i].idx >= 0, "Cannot allocate PRACH corresponding to %d SSB transmitted in any available beam\n", n_ssb + 1);
|
||||
}
|
||||
} else {
|
||||
int first_ssb_index = (prach_occasion_id * (int)num_ssb_per_RO) % cc->num_active_ssb;
|
||||
for(int j = first_ssb_index; j < first_ssb_index + num_ssb_per_RO; j++) {
|
||||
// fapi beam index
|
||||
beam_index = get_beam_from_ssbidx(gNB, cc->ssb_index[j]);
|
||||
// multi-beam allocation structure
|
||||
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);
|
||||
// mark beam as occupied for current and future slots if prach extends beyond current slot
|
||||
for (int i = 0; i < total_prach_slots; i++) {
|
||||
beam[i] = beam_allocation_procedure(&gNB->beam_info, frameP, slotP + i, td_start, N_dur, beam_index, slots_frame);
|
||||
AssertFatal(beam[i].idx >= 0, "Cannot allocate PRACH corresponding to SSB %d in any available beam\n", j);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(num_td_occ == 1) {
|
||||
@@ -515,21 +529,12 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, slot_t slotP)
|
||||
|
||||
// block resources in vrb_map_UL
|
||||
// mark PRBs as occupied for current and future slots if prach extends beyond current slot
|
||||
int total_prach_slots;
|
||||
uint32_t N_dur = cc->prach_info.N_dur;
|
||||
if (format0 < 4) {
|
||||
N_dur = 14; // number of PRACH symbols in PRACH slot
|
||||
total_prach_slots = get_long_prach_dur(format0, mu_pusch);
|
||||
AssertFatal(slotP + total_prach_slots - 1 < slots_frame, "PRACH cannot extend across frames\n");
|
||||
} else {
|
||||
total_prach_slots = 1;
|
||||
}
|
||||
// reserve PRBs occupied by PRACH in all PRACH slot.
|
||||
for (int i = 0; i < total_prach_slots; i++) {
|
||||
fill_vrb(frameP,
|
||||
slotP + i,
|
||||
n_ra_rb * fdm,
|
||||
beam.idx,
|
||||
beam[i].idx,
|
||||
gNB->vrb_map_UL_size,
|
||||
slots_frame,
|
||||
bwp_start + rach_ConfigGeneric->msg1_FrequencyStart,
|
||||
@@ -792,16 +797,29 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
|
||||
const int sched_slot = (slot + K2) % slots_frame;
|
||||
uint16_t slot_bitmap = get_ul_bitmap(&nr_mac->frame_structure, sched_slot);
|
||||
uint16_t msg3_mask = SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols);
|
||||
NR_sched_pdcch_t *pdcch = &UE->UE_sched_ctrl.sched_pdcch;
|
||||
|
||||
if (!is_dl_slot(slot, &nr_mac->frame_structure)
|
||||
|| !is_ul_slot(sched_slot, &nr_mac->frame_structure)
|
||||
|| !((msg3_mask & slot_bitmap) == msg3_mask))
|
||||
return;
|
||||
|
||||
NR_beam_alloc_t beam_ul = beam_allocation_procedure(&nr_mac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_frame);
|
||||
NR_beam_alloc_t beam_ul = beam_allocation_procedure(&nr_mac->beam_info,
|
||||
sched_frame,
|
||||
sched_slot,
|
||||
tda_info.startSymbolIndex,
|
||||
tda_info.nrOfSymbols,
|
||||
UE->UE_beam_index,
|
||||
slots_frame);
|
||||
if (beam_ul.idx < 0)
|
||||
return;
|
||||
NR_beam_alloc_t beam_dci = beam_allocation_procedure(&nr_mac->beam_info, frame, slot, UE->UE_beam_index, slots_frame);
|
||||
NR_beam_alloc_t beam_dci = beam_allocation_procedure(&nr_mac->beam_info,
|
||||
frame,
|
||||
slot,
|
||||
pdcch->StartSymbolIndex,
|
||||
pdcch->DurationSymbols,
|
||||
UE->UE_beam_index,
|
||||
slots_frame);
|
||||
if (beam_dci.idx < 0) {
|
||||
reset_beam_status(&nr_mac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_frame, beam_ul.new_beam);
|
||||
return;
|
||||
@@ -895,19 +913,12 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
|
||||
ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
|
||||
pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15;
|
||||
ul_dci_req->numPdus += 1;
|
||||
nr_configure_pdcch(pdcch_pdu_rel15, coreset, &UE->UE_sched_ctrl.sched_pdcch);
|
||||
nr_configure_pdcch(pdcch_pdu_rel15, coreset, pdcch);
|
||||
nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15;
|
||||
}
|
||||
|
||||
int aggregation_level;
|
||||
int CCEIndex = get_cce_index(nr_mac,
|
||||
CC_id, slot, 0,
|
||||
&aggregation_level,
|
||||
beam_dci.idx,
|
||||
ss,
|
||||
coreset,
|
||||
&UE->UE_sched_ctrl.sched_pdcch,
|
||||
0);
|
||||
int CCEIndex = get_cce_index(nr_mac, CC_id, slot, 0, &aggregation_level, beam_dci.idx, ss, coreset, pdcch, 0);
|
||||
if (CCEIndex < 0) {
|
||||
LOG_E(NR_MAC, "UE %04x cannot find free CCE!\n", UE->rnti);
|
||||
reset_beam_status(&nr_mac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_frame, beam_ul.new_beam);
|
||||
@@ -949,12 +960,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
|
||||
nr_mac->cset0_bwp_size);
|
||||
|
||||
// Mark the corresponding RBs as used
|
||||
fill_pdcch_vrb_map(nr_mac,
|
||||
CC_id,
|
||||
&UE->UE_sched_ctrl.sched_pdcch,
|
||||
CCEIndex,
|
||||
aggregation_level,
|
||||
beam_dci.idx);
|
||||
fill_pdcch_vrb_map(nr_mac, CC_id, pdcch, CCEIndex, aggregation_level, beam_dci.idx);
|
||||
|
||||
for (int rb = 0; rb < ra->msg3_nb_rb; rb++) {
|
||||
vrb_map_UL[rbStart + sched_pusch.bwp_info.bwpStart + rb] |= msg3_mask;
|
||||
@@ -1012,7 +1018,7 @@ static bool get_feasible_msg3_tda(const NR_ServingCellConfigCommon_t *scc,
|
||||
continue;
|
||||
|
||||
// check if it is possible to allocate MSG3 in a beam in this slot
|
||||
NR_beam_alloc_t beam = beam_allocation_procedure(beam_info, temp_frame, temp_slot, ue_beam_idx, slots_per_frame);
|
||||
NR_beam_alloc_t beam = beam_allocation_procedure(beam_info, temp_frame, temp_slot, start, nr, ue_beam_idx, slots_per_frame);
|
||||
if (beam.idx < 0)
|
||||
continue;
|
||||
|
||||
@@ -1415,37 +1421,15 @@ static void nr_generate_Msg2(module_id_t module_idP,
|
||||
return;
|
||||
}
|
||||
|
||||
// Checking if the DCI allocation is feasible in current subframe
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
|
||||
if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) {
|
||||
LOG_W(NR_MAC, "UE %04x: %d.%d FAPI DL structure is full\n", UE->rnti, frameP, slotP);
|
||||
return;
|
||||
}
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
NR_SearchSpace_t *ss = sched_ctrl->search_space;
|
||||
if (!check_msg2_monitoring(ss, 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, UE->rnti);
|
||||
return;
|
||||
}
|
||||
NR_beam_alloc_t beam = beam_allocation_procedure(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame);
|
||||
if (beam.idx < 0)
|
||||
return;
|
||||
|
||||
const NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
|
||||
// check the feasibility of Msg3, the actual Msg3 allocation
|
||||
// is further below. In the case of CFRA, we don't need Msg3, but 38.321
|
||||
// §5.1.4 does not clearly exclude Msg3, and UL TA might still be useful.
|
||||
// Before the change in this commit, we used CFRA but required Msg3, which
|
||||
// COTS UE would often (but not always) send.
|
||||
bool ret = get_feasible_msg3_tda(scc,
|
||||
get_delta_for_k2(ul_bwp->scs),
|
||||
ul_bwp->tdaList_Common,
|
||||
frameP,
|
||||
slotP,
|
||||
ra,
|
||||
&nr_mac->beam_info,
|
||||
UE->UE_beam_index,
|
||||
&nr_mac->frame_structure);
|
||||
if (!ret || ra->Msg3_tda_id > 15) {
|
||||
LOG_D(NR_MAC, "UE RNTI %04x %d.%d: infeasible Msg3 TDA\n", UE->rnti, frameP, slotP);
|
||||
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
|
||||
return;
|
||||
}
|
||||
|
||||
NR_ControlResourceSet_t *coreset = sched_ctrl->coreset;
|
||||
AssertFatal(coreset, "Coreset cannot be null for RA-Msg2\n");
|
||||
const int coresetid = coreset->controlResourceSetId;
|
||||
@@ -1465,6 +1449,55 @@ static void nr_generate_Msg2(module_id_t module_idP,
|
||||
if (!tda_info.valid_tda)
|
||||
return;
|
||||
|
||||
if (!check_msg2_monitoring(ss, 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, UE->rnti);
|
||||
return;
|
||||
}
|
||||
|
||||
NR_beam_alloc_t beam = beam_allocation_procedure(&nr_mac->beam_info,
|
||||
frameP,
|
||||
slotP,
|
||||
tda_info.startSymbolIndex,
|
||||
tda_info.nrOfSymbols,
|
||||
UE->UE_beam_index,
|
||||
n_slots_frame);
|
||||
if (beam.idx < 0)
|
||||
return;
|
||||
|
||||
NR_beam_alloc_t dci_beam = beam_allocation_procedure(&nr_mac->beam_info,
|
||||
frameP,
|
||||
slotP,
|
||||
sched_ctrl->sched_pdcch.StartSymbolIndex,
|
||||
sched_ctrl->sched_pdcch.DurationSymbols,
|
||||
UE->UE_beam_index,
|
||||
n_slots_frame);
|
||||
if (dci_beam.idx < 0) {
|
||||
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
|
||||
return;
|
||||
}
|
||||
|
||||
const NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
|
||||
// check the feasibility of Msg3, the actual Msg3 allocation
|
||||
// is further below. In the case of CFRA, we don't need Msg3, but 38.321
|
||||
// §5.1.4 does not clearly exclude Msg3, and UL TA might still be useful.
|
||||
// Before the change in this commit, we used CFRA but required Msg3, which
|
||||
// COTS UE would often (but not always) send.
|
||||
bool ret = get_feasible_msg3_tda(scc,
|
||||
get_delta_for_k2(ul_bwp->scs),
|
||||
ul_bwp->tdaList_Common,
|
||||
frameP,
|
||||
slotP,
|
||||
ra,
|
||||
&nr_mac->beam_info,
|
||||
UE->UE_beam_index,
|
||||
&nr_mac->frame_structure);
|
||||
if (!ret || ra->Msg3_tda_id > 15) {
|
||||
LOG_D(NR_MAC, "UE RNTI %04x %d.%d: infeasible Msg3 TDA\n", UE->rnti, frameP, slotP);
|
||||
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
|
||||
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, dci_beam.new_beam);
|
||||
return;
|
||||
}
|
||||
|
||||
int rbStart = 0;
|
||||
int rbSize = 0;
|
||||
uint16_t msg2_nb_rb = max(8, nr_mac->min_grant_prb); // RAR TBS is 9 bytes
|
||||
@@ -1475,15 +1508,7 @@ static void nr_generate_Msg2(module_id_t module_idP,
|
||||
LOG_W(NR_MAC, "Cannot find free vrb_map for RA RNTI %04x!\n", ra->RA_rnti);
|
||||
reset_beam_status(&nr_mac->beam_info, ra->Msg3_frame, ra->Msg3_slot, UE->UE_beam_index, n_slots_frame, ra->Msg3_beam.new_beam);
|
||||
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
|
||||
return;
|
||||
}
|
||||
|
||||
// Checking if the DCI allocation is feasible in current subframe
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
|
||||
if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) {
|
||||
LOG_W(NR_MAC, "UE %04x: %d.%d FAPI DL structure is full\n", UE->rnti, frameP, slotP);
|
||||
reset_beam_status(&nr_mac->beam_info, ra->Msg3_frame, ra->Msg3_slot, UE->UE_beam_index, n_slots_frame, ra->Msg3_beam.new_beam);
|
||||
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
|
||||
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, dci_beam.new_beam);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1494,6 +1519,7 @@ static void nr_generate_Msg2(module_id_t module_idP,
|
||||
LOG_W(NR_MAC, "UE %04x: %d.%d cannot find free CCE for Msg2!\n", UE->rnti, frameP, slotP);
|
||||
reset_beam_status(&nr_mac->beam_info, ra->Msg3_frame, ra->Msg3_slot, UE->UE_beam_index, n_slots_frame, ra->Msg3_beam.new_beam);
|
||||
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
|
||||
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, dci_beam.new_beam);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1502,6 +1528,7 @@ static void nr_generate_Msg2(module_id_t module_idP,
|
||||
if (!msg3_ret) {
|
||||
reset_beam_status(&nr_mac->beam_info, ra->Msg3_frame, ra->Msg3_slot, UE->UE_beam_index, n_slots_frame, ra->Msg3_beam.new_beam);
|
||||
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
|
||||
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, dci_beam.new_beam);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1627,7 +1654,7 @@ static void nr_generate_Msg2(module_id_t module_idP,
|
||||
T_BUFFER(&tx_req->TLVs[0].value.direct[0], tx_req->TLVs[0].length));
|
||||
|
||||
// Mark the corresponding symbols RBs as used
|
||||
fill_pdcch_vrb_map(nr_mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, aggregation_level, beam.idx);
|
||||
fill_pdcch_vrb_map(nr_mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, aggregation_level, dci_beam.idx);
|
||||
for (int rb = 0; rb < rbSize; rb++) {
|
||||
vrb_map[bwp_info.bwpStart + rb + rbStart] |= msg2_mask;
|
||||
}
|
||||
@@ -1682,11 +1709,51 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
|
||||
}
|
||||
}
|
||||
|
||||
// Checking if the DCI allocation is feasible in current subframe
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
|
||||
if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) {
|
||||
LOG_I(NR_MAC, "UE %04x: %d.%d FAPI DL structure is full\n", UE->rnti, frameP, slotP);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t time_domain_assignment = get_dl_tda(nr_mac, slotP);
|
||||
int ssb_index = get_ssbidx_from_beam(nr_mac, UE->UE_beam_index);
|
||||
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[ssb_index];
|
||||
int mux_pattern = type0_PDCCH_CSS_config ? type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern : 1;
|
||||
NR_tda_info_t msg4_tda = get_dl_tda_info(dl_bwp,
|
||||
ss->searchSpaceType->present,
|
||||
time_domain_assignment,
|
||||
scc->dmrs_TypeA_Position,
|
||||
mux_pattern,
|
||||
TYPE_TC_RNTI_,
|
||||
coreset->controlResourceSetId,
|
||||
false);
|
||||
if (!msg4_tda.valid_tda)
|
||||
return;
|
||||
|
||||
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, UE->UE_beam_index, n_slots_frame);
|
||||
NR_beam_alloc_t beam = beam_allocation_procedure(&nr_mac->beam_info,
|
||||
frameP,
|
||||
slotP,
|
||||
msg4_tda.startSymbolIndex,
|
||||
msg4_tda.nrOfSymbols,
|
||||
UE->UE_beam_index,
|
||||
n_slots_frame);
|
||||
if (beam.idx < 0)
|
||||
return;
|
||||
|
||||
NR_beam_alloc_t dci_beam = beam_allocation_procedure(&nr_mac->beam_info,
|
||||
frameP,
|
||||
slotP,
|
||||
sched_ctrl->sched_pdcch.StartSymbolIndex,
|
||||
sched_ctrl->sched_pdcch.DurationSymbols,
|
||||
UE->UE_beam_index,
|
||||
n_slots_frame);
|
||||
if (dci_beam.idx < 0) {
|
||||
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
|
||||
return;
|
||||
}
|
||||
|
||||
// get CCEindex, needed also for PUCCH and then later for PDCCH
|
||||
int aggregation_level;
|
||||
int CCEIndex = get_cce_index(nr_mac,
|
||||
@@ -1701,30 +1768,7 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
|
||||
if (CCEIndex < 0) {
|
||||
LOG_E(NR_MAC, "Cannot find free CCE for RA RNTI 0x%04x!\n", UE->rnti);
|
||||
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
|
||||
return;
|
||||
}
|
||||
|
||||
// Checking if the DCI allocation is feasible in current subframe
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
|
||||
if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) {
|
||||
LOG_I(NR_MAC, "UE %04x: %d.%d FAPI DL structure is full\n", UE->rnti, frameP, slotP);
|
||||
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
|
||||
return;
|
||||
}
|
||||
int ssb_index = get_ssbidx_from_beam(nr_mac, UE->UE_beam_index);
|
||||
uint8_t time_domain_assignment = get_dl_tda(nr_mac, slotP);
|
||||
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[ssb_index];
|
||||
int mux_pattern = type0_PDCCH_CSS_config ? type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern : 1;
|
||||
NR_tda_info_t msg4_tda = get_dl_tda_info(dl_bwp,
|
||||
ss->searchSpaceType->present,
|
||||
time_domain_assignment,
|
||||
scc->dmrs_TypeA_Position,
|
||||
mux_pattern,
|
||||
TYPE_TC_RNTI_,
|
||||
coreset->controlResourceSetId,
|
||||
false);
|
||||
if (!msg4_tda.valid_tda) {
|
||||
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
|
||||
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, dci_beam.new_beam);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1771,6 +1815,7 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
|
||||
if (!get_rb_alloc(msg4_nr_rb, msg4_nr_rb, bwp_info.bwpStart, bwp_info.bwpSize, vrb_map, msg4_mask, &rbStart, &rbSize)) {
|
||||
LOG_E(NR_MAC, "Cannot find free vrb_map for RNTI %04x!\n", UE->rnti);
|
||||
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
|
||||
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, dci_beam.new_beam);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1780,6 +1825,7 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
|
||||
if (alloc < 0) {
|
||||
LOG_D(NR_MAC,"Couldn't find a pucch allocation for ack nack (msg4) in frame %d slot %d\n", frameP, slotP);
|
||||
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam);
|
||||
reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, dci_beam.new_beam);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1903,7 +1949,7 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
CCEIndex,
|
||||
aggregation_level,
|
||||
beam.idx);
|
||||
dci_beam.idx);
|
||||
for (int rb = 0; rb < rbSize; rb++) {
|
||||
vrb_map[bwp_info.bwpStart + rb + rbStart] |= msg4_mask;
|
||||
}
|
||||
|
||||
@@ -188,14 +188,16 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, slot_t slotP, nfapi
|
||||
if (is_ssb_configured(scc, i_ssb)) {
|
||||
uint16_t ssb_start_symbol = get_ssb_start_symbol(band, scs, i_ssb);
|
||||
// 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) {
|
||||
if ((ssb_start_symbol / NR_SYMBOLS_PER_SLOT) == rel_slot) {
|
||||
const uint16_t alloc_beam_idx = get_beam_from_ssbidx(gNB, i_ssb);
|
||||
NR_beam_alloc_t beam = beam_allocation_procedure(&gNB->beam_info,
|
||||
frameP,
|
||||
slotP,
|
||||
get_beam_from_ssbidx(gNB, i_ssb),
|
||||
ssb_start_symbol % NR_SYMBOLS_PER_SLOT,
|
||||
4,
|
||||
alloc_beam_idx,
|
||||
slots_per_frame);
|
||||
AssertFatal(beam.idx >= 0, "Cannot allocate SSB %d in any available beam\n", i_ssb);
|
||||
const uint16_t alloc_beam_idx = get_allocated_beam(&gNB->beam_info, frameP, slotP, slots_per_frame, beam.idx);
|
||||
const uint16_t fapi_beam = convert_to_fapi_beam(alloc_beam_idx, gNB->beam_info.beam_mode);
|
||||
schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, fapi_beam, ssbSubcarrierOffset, offset_pointa, mib_pdu);
|
||||
fill_ssb_vrb_map(cc, prb_offset, ssbSubcarrierOffset, ssb_start_symbol, CC_id, beam.idx);
|
||||
@@ -510,17 +512,24 @@ void schedule_nr_sib1(module_id_t module_idP,
|
||||
"Trying to schedule SIB1 for SSB %d in slot %d which is not DL. Check searchSpaceZero configuration.\n",
|
||||
type0_PDCCH_CSS_config->ssb_index,
|
||||
slotP);
|
||||
const int n_slots_frame = gNB_mac->frame_structure.numb_slots_frame;
|
||||
int beam_index = get_beam_from_ssbidx(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);
|
||||
LOG_D(NR_MAC,"(%d.%d) SIB1 transmission: ssb_index %d\n", frameP, slotP, type0_PDCCH_CSS_config->ssb_index);
|
||||
NR_sched_pdcch_t sched_pdcch = set_pdcch_structure(NULL,
|
||||
&gNB_mac->sched_ctrlSIB1->search_space[i],
|
||||
&gNB_mac->sched_ctrlSIB1->coreset,
|
||||
scc,
|
||||
NULL,
|
||||
type0_PDCCH_CSS_config);
|
||||
const int n_slots_frame = gNB_mac->frame_structure.numb_slots_frame;
|
||||
int beam_index = get_beam_from_ssbidx(gNB_mac, i);
|
||||
// DCI BEAM
|
||||
NR_beam_alloc_t beam = beam_allocation_procedure(&gNB_mac->beam_info,
|
||||
frameP,
|
||||
slotP,
|
||||
sched_pdcch.StartSymbolIndex,
|
||||
sched_pdcch.DurationSymbols,
|
||||
beam_index,
|
||||
n_slots_frame);
|
||||
AssertFatal(beam.idx >= 0, "Cannot allocate DCI for SIB1 corresponding to SSB %d in any available beam\n", i);
|
||||
LOG_D(NR_MAC,"(%d.%d) SIB1 transmission: ssb_index %d\n", frameP, slotP, type0_PDCCH_CSS_config->ssb_index);
|
||||
|
||||
int nr_of_candidates, aggregation_level;
|
||||
for (int c = 0; c < 3; c++) {
|
||||
@@ -560,6 +569,16 @@ void schedule_nr_sib1(module_id_t module_idP,
|
||||
gNB_mac->sib1_pdsch[i].time_domain_allocation,
|
||||
i,
|
||||
CC_id);
|
||||
|
||||
// PDSCH BEAM
|
||||
NR_beam_alloc_t beam_sib = beam_allocation_procedure(&gNB_mac->beam_info,
|
||||
frameP,
|
||||
slotP,
|
||||
gNB_mac->sib1_pdsch[i].tda_info.startSymbolIndex,
|
||||
gNB_mac->sib1_pdsch[i].tda_info.nrOfSymbols,
|
||||
beam_index,
|
||||
n_slots_frame);
|
||||
AssertFatal(beam_sib.idx >= 0, "Cannot allocate SIB1 corresponding to SSB %d in any available beam\n", i);
|
||||
int tb_size = gNB_mac->sib1_pdsch[i].tb_size;
|
||||
AssertFatal(res && tb_size > 0, "Couldn't allocate TB for SIB1 for an already allocated TDA\n");
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
|
||||
@@ -635,8 +654,6 @@ static void other_sib_sched_control(module_id_t module_idP,
|
||||
NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[0].ServingCellConfigCommon;
|
||||
int n_slots_frame = gNB_mac->frame_structure.numb_slots_frame;
|
||||
beam_index = get_beam_from_ssbidx(gNB_mac, beam_index);
|
||||
NR_beam_alloc_t beam = beam_allocation_procedure(&gNB_mac->beam_info, frame, slot, beam_index, n_slots_frame);
|
||||
AssertFatal(beam.idx >= 0, "Cannot allocate otherSIB corresponding for SSB number %d in any available beam\n", beam_index);
|
||||
LOG_D(NR_MAC, "(%d.%d) otherSIB payload %d transmission for ssb number %d\n", frame, slot, payload_idx, beam_index);
|
||||
|
||||
NR_COMMON_channels_t *cc = &gNB_mac->common_channels[0];
|
||||
@@ -664,6 +681,16 @@ static void other_sib_sched_control(module_id_t module_idP,
|
||||
gNB_mac->sched_pdcch_otherSI = calloc(1, sizeof(*gNB_mac->sched_pdcch_otherSI));
|
||||
*gNB_mac->sched_pdcch_otherSI = set_pdcch_structure(gNB_mac, ss, coreset, scc, NULL, type0_PDCCH_CSS_config);
|
||||
}
|
||||
// DCI BEAM
|
||||
NR_beam_alloc_t beam = beam_allocation_procedure(&gNB_mac->beam_info,
|
||||
frame,
|
||||
slot,
|
||||
gNB_mac->sched_pdcch_otherSI->StartSymbolIndex,
|
||||
gNB_mac->sched_pdcch_otherSI->DurationSymbols,
|
||||
beam_index,
|
||||
n_slots_frame);
|
||||
AssertFatal(beam.idx >= 0, "Cannot allocate otherSIB corresponding for SSB number %d in any available beam\n", beam_index);
|
||||
|
||||
int cce_index = find_pdcch_candidate(gNB_mac,
|
||||
0,
|
||||
aggregation_level,
|
||||
@@ -687,7 +714,17 @@ static void other_sib_sched_control(module_id_t module_idP,
|
||||
sched_pdsch_otherSI.pm_index = 0;
|
||||
sched_pdsch_otherSI.mcs = 0; // starting from mcs 0
|
||||
|
||||
uint16_t *vrb_map = cc->vrb_map[beam.idx];
|
||||
// PDSCH BEAM
|
||||
NR_beam_alloc_t si_beam = beam_allocation_procedure(&gNB_mac->beam_info,
|
||||
frame,
|
||||
slot,
|
||||
tda_info.startSymbolIndex,
|
||||
tda_info.nrOfSymbols,
|
||||
beam_index,
|
||||
n_slots_frame);
|
||||
AssertFatal(si_beam.idx >= 0, "Cannot allocate otherSIB corresponding for SSB number %d in any available beam\n", beam_index);
|
||||
|
||||
uint16_t *vrb_map = cc->vrb_map[si_beam.idx];
|
||||
uint8_t *sib_bcch_pdu = cc->other_sib_bcch_pdu[payload_idx];
|
||||
int num_total_bytes = cc->other_sib_bcch_length[payload_idx];
|
||||
bool success = update_rb_mcs_tbs(&sched_pdsch_otherSI, num_total_bytes, vrb_map);
|
||||
|
||||
@@ -404,12 +404,12 @@ bwp_info_t get_pdsch_bwp_start_size(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE)
|
||||
return bwp_info;
|
||||
}
|
||||
|
||||
static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac,
|
||||
post_process_pdsch_t *pp_pdsch,
|
||||
int *n_rb_sched,
|
||||
NR_UE_info_t *UE,
|
||||
int beam_idx,
|
||||
int current_harq_pid)
|
||||
static NR_rtx_ret_t allocate_dl_retransmission(gNB_MAC_INST *nr_mac,
|
||||
post_process_pdsch_t *pp_pdsch,
|
||||
NR_UE_info_t *UE,
|
||||
int dci_beam_idx,
|
||||
int current_harq_pid,
|
||||
int slots_per_frame)
|
||||
{
|
||||
frame_t frame = pp_pdsch->frame;
|
||||
slot_t slot = pp_pdsch->slot;
|
||||
@@ -443,8 +443,10 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac,
|
||||
TYPE_C_RNTI_,
|
||||
coresetid,
|
||||
false);
|
||||
|
||||
NR_rtx_ret_t ret = {0};
|
||||
if (!temp_tda.valid_tda)
|
||||
return false;
|
||||
return ret;
|
||||
|
||||
bool reuse_old_tda = (new_sched.tda_info.startSymbolIndex == temp_tda.startSymbolIndex) && (new_sched.tda_info.nrOfSymbols <= temp_tda.nrOfSymbols);
|
||||
LOG_D(NR_MAC, "[UE %x] %s old TDA, %s number of layers\n",
|
||||
@@ -452,27 +454,48 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac,
|
||||
reuse_old_tda ? "reuse" : "do not reuse",
|
||||
layers == new_sched.nrOfLayers ? "same" : "different");
|
||||
|
||||
uint16_t *rballoc_mask = nr_mac->common_channels[CC_id].vrb_map[beam_idx];
|
||||
|
||||
bwp_info_t bwp_info = get_pdsch_bwp_start_size(nr_mac, UE);
|
||||
const int bwp_start = bwp_info.bwpStart;
|
||||
const int bwp_size = bwp_info.bwpSize;
|
||||
// WRT the BWP start, the RBs are indexed from 0 to bwpSize-1
|
||||
int rbStart = 0;
|
||||
int rbSize = 0;
|
||||
|
||||
uint16_t *rballoc_mask;
|
||||
NR_beam_alloc_t beam;
|
||||
if (reuse_old_tda && layers == new_sched.nrOfLayers) {
|
||||
beam = beam_allocation_procedure(&nr_mac->beam_info,
|
||||
frame,
|
||||
slot,
|
||||
new_sched.tda_info.startSymbolIndex,
|
||||
new_sched.tda_info.nrOfSymbols,
|
||||
UE->UE_beam_index,
|
||||
slots_per_frame);
|
||||
if (beam.idx < 0)
|
||||
return ret; // no rtx, couldn't allocate beam
|
||||
/* Check that there are enough resources for retransmission */
|
||||
rballoc_mask = nr_mac->common_channels[CC_id].vrb_map[beam.idx];
|
||||
const uint16_t slbitmap = SL_to_bitmap(new_sched.tda_info.startSymbolIndex, new_sched.tda_info.nrOfSymbols);
|
||||
if (!get_rb_alloc(new_sched.rbSize, new_sched.rbSize, bwp_start, bwp_size, rballoc_mask, slbitmap, &rbStart, &rbSize)) {
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate DL retransmission: no resources\n", UE->rnti, frame, slot);
|
||||
return false;
|
||||
reset_beam_status(&nr_mac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
/* the retransmission will use a different time domain allocation, check
|
||||
* that we have enough resources */
|
||||
NR_pdsch_dmrs_t temp_dmrs = get_dl_dmrs_params(scc, dl_bwp, &temp_tda, layers);
|
||||
beam = beam_allocation_procedure(&nr_mac->beam_info,
|
||||
frame,
|
||||
slot,
|
||||
temp_tda.startSymbolIndex,
|
||||
temp_tda.nrOfSymbols,
|
||||
UE->UE_beam_index,
|
||||
slots_per_frame);
|
||||
if (beam.idx < 0)
|
||||
return ret; // no rtx, couldn't allocate beam
|
||||
/* Check that there are enough resources for retransmission */
|
||||
rballoc_mask = nr_mac->common_channels[CC_id].vrb_map[beam.idx];
|
||||
|
||||
NR_pdsch_dmrs_t temp_dmrs = get_dl_dmrs_params(scc, dl_bwp, &temp_tda, layers);
|
||||
uint32_t new_tbs;
|
||||
uint16_t new_rbSize;
|
||||
bool success = nr_find_nb_rb(new_sched.Qm,
|
||||
@@ -494,13 +517,15 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac,
|
||||
slot,
|
||||
new_tbs,
|
||||
new_sched.tb_size);
|
||||
return false; /* the maximum TBsize we might have is smaller than what we need */
|
||||
reset_beam_status(&nr_mac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
|
||||
return ret; /* the maximum TBsize we might have is smaller than what we need */
|
||||
}
|
||||
|
||||
const uint16_t slbitmap = SL_to_bitmap(temp_tda.startSymbolIndex, temp_tda.nrOfSymbols);
|
||||
if (!get_rb_alloc(new_rbSize, new_rbSize, bwp_start, bwp_size, rballoc_mask, slbitmap, &rbStart, &rbSize)) {
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate DL retransmission: no resources\n", UE->rnti, frame, slot);
|
||||
return false;
|
||||
reset_beam_status(&nr_mac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* we can allocate it. Overwrite the time_domain_allocation, the number
|
||||
@@ -520,15 +545,16 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac,
|
||||
slot,
|
||||
UE->rnti,
|
||||
&sched_ctrl->aggregation_level,
|
||||
beam_idx,
|
||||
dci_beam_idx,
|
||||
sched_ctrl->search_space,
|
||||
sched_ctrl->coreset,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
sched_ctrl->pdcch_cl_adjust);
|
||||
if (CCEIndex<0) {
|
||||
sched_ctrl->dl_cce_fail++;
|
||||
reset_beam_status(&nr_mac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
|
||||
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 ret;
|
||||
}
|
||||
|
||||
/* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH
|
||||
@@ -539,13 +565,14 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac,
|
||||
int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, ul_bwp->pucch_Config, CCEIndex);
|
||||
alloc = nr_acknack_scheduling(nr_mac, UE, frame, slot, UE->UE_beam_index, r_pucch, 0);
|
||||
if (alloc < 0) {
|
||||
reset_beam_status(&nr_mac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find PUCCH for DL DCI retransmission\n", UE->rnti, frame, slot);
|
||||
return false;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
sched_ctrl->cce_index = CCEIndex;
|
||||
fill_pdcch_vrb_map(nr_mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, beam_idx);
|
||||
fill_pdcch_vrb_map(nr_mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, dci_beam_idx);
|
||||
|
||||
new_sched.rbStart = rbStart;
|
||||
new_sched.pucch_allocation = alloc;
|
||||
@@ -554,12 +581,14 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac,
|
||||
post_process_dlsch(nr_mac, pp_pdsch, UE, &new_sched);
|
||||
|
||||
/* retransmissions: directly allocate */
|
||||
*n_rb_sched -= new_sched.rbSize;
|
||||
ret.rbsize = new_sched.rbSize;
|
||||
ret.valid = true;
|
||||
ret.beam_idx = beam.idx;
|
||||
|
||||
for (int rb = new_sched.bwp_info.bwpStart + new_sched.rbStart; rb < new_sched.bwp_info.bwpStart + new_sched.rbStart + new_sched.rbSize; rb++)
|
||||
rballoc_mask[rb] |= SL_to_bitmap(new_sched.tda_info.startSymbolIndex, new_sched.tda_info.nrOfSymbols);
|
||||
|
||||
return true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ack_reconfig(gNB_MAC_INST *mac, NR_UE_info_t *UE)
|
||||
@@ -659,19 +688,26 @@ static void pf_dl(gNB_MAC_INST *mac,
|
||||
|
||||
/* retransmission */
|
||||
if (harq_pid >= 0) {
|
||||
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;
|
||||
NR_beam_alloc_t dci_beam = beam_allocation_procedure(&mac->beam_info,
|
||||
frame,
|
||||
slot,
|
||||
sched_ctrl->sched_pdcch.StartSymbolIndex,
|
||||
sched_ctrl->sched_pdcch.DurationSymbols,
|
||||
UE->UE_beam_index,
|
||||
slots_per_frame);
|
||||
|
||||
if (dci_beam.idx < 0)
|
||||
continue; // Couldn't allocate beam for DCI
|
||||
/* Allocate retransmission */
|
||||
if (sch_ret)
|
||||
sch_ret = allocate_dl_retransmission(mac, pp_pdsch, &n_rb_sched[beam.idx], UE, beam.idx, harq_pid);
|
||||
if (!sch_ret) {
|
||||
NR_rtx_ret_t ret = allocate_dl_retransmission(mac, pp_pdsch, UE, dci_beam.idx, harq_pid, slots_per_frame);
|
||||
if (!ret.valid) {
|
||||
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, slots_per_frame, beam.new_beam);
|
||||
reset_beam_status(&mac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
|
||||
continue;
|
||||
}
|
||||
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
||||
remainUEs[beam.idx]--;
|
||||
|
||||
remainUEs[ret.beam_idx]--;
|
||||
n_rb_sched[ret.beam_idx] -= ret.rbsize;
|
||||
} else {
|
||||
/* skip this UE if there are no free HARQ processes. This can happen e.g.
|
||||
* if the UE disconnected in L2sim, in which case the gNB is not notified
|
||||
@@ -684,7 +720,7 @@ static void pf_dl(gNB_MAC_INST *mac,
|
||||
continue;
|
||||
}
|
||||
|
||||
update_dlsch_buffer(pp_pdsch->frame, pp_pdsch->slot, UE);
|
||||
update_dlsch_buffer(frame, slot, UE);
|
||||
|
||||
if (!dlsch_to_schedule(sched_ctrl))
|
||||
continue;
|
||||
@@ -751,15 +787,15 @@ static void pf_dl(gNB_MAC_INST *mac,
|
||||
continue;
|
||||
}
|
||||
|
||||
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
|
||||
iterator++;
|
||||
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, slots_per_frame, beam.new_beam);
|
||||
NR_beam_alloc_t dci_beam = beam_allocation_procedure(&mac->beam_info,
|
||||
frame,
|
||||
slot,
|
||||
sched_ctrl->sched_pdcch.StartSymbolIndex,
|
||||
sched_ctrl->sched_pdcch.DurationSymbols,
|
||||
iterator->UE->UE_beam_index,
|
||||
slots_per_frame);
|
||||
if (dci_beam.idx < 0) {
|
||||
// no available beam for PDSCH
|
||||
iterator++;
|
||||
continue;
|
||||
}
|
||||
@@ -779,6 +815,26 @@ static void pf_dl(gNB_MAC_INST *mac,
|
||||
false);
|
||||
AssertFatal(tda_info.valid_tda, "Invalid TDA from get_dl_tda_info\n");
|
||||
|
||||
NR_beam_alloc_t beam = beam_allocation_procedure(&mac->beam_info,
|
||||
frame,
|
||||
slot,
|
||||
tda_info.startSymbolIndex,
|
||||
tda_info.nrOfSymbols,
|
||||
iterator->UE->UE_beam_index,
|
||||
slots_per_frame);
|
||||
if (beam.idx < 0) {
|
||||
// no available beam for PDSCH
|
||||
reset_beam_status(&mac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
|
||||
iterator++;
|
||||
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, slots_per_frame, dci_beam.new_beam);
|
||||
reset_beam_status(&mac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, beam.new_beam);
|
||||
iterator++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const uint16_t slbitmap = SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols);
|
||||
|
||||
uint16_t *rballoc_mask = mac->common_channels[CC_id].vrb_map[beam.idx];
|
||||
@@ -797,6 +853,7 @@ static void pf_dl(gNB_MAC_INST *mac,
|
||||
rbStart,
|
||||
max_rbSize);
|
||||
reset_beam_status(&mac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, beam.new_beam);
|
||||
reset_beam_status(&mac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
|
||||
iterator++;
|
||||
continue;
|
||||
}
|
||||
@@ -806,7 +863,7 @@ static void pf_dl(gNB_MAC_INST *mac,
|
||||
slot,
|
||||
iterator->UE->rnti,
|
||||
&sched_ctrl->aggregation_level,
|
||||
beam.idx,
|
||||
dci_beam.idx,
|
||||
sched_ctrl->search_space,
|
||||
sched_ctrl->coreset,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
@@ -815,6 +872,7 @@ static void pf_dl(gNB_MAC_INST *mac,
|
||||
sched_ctrl->dl_cce_fail++;
|
||||
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, slots_per_frame, beam.new_beam);
|
||||
reset_beam_status(&mac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
|
||||
iterator++;
|
||||
continue;
|
||||
}
|
||||
@@ -829,13 +887,14 @@ static void pf_dl(gNB_MAC_INST *mac,
|
||||
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, slots_per_frame, beam.new_beam);
|
||||
reset_beam_status(&mac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
|
||||
iterator++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
sched_ctrl->cce_index = CCEIndex;
|
||||
fill_pdcch_vrb_map(mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, beam.idx);
|
||||
fill_pdcch_vrb_map(mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, dci_beam.idx);
|
||||
|
||||
int l = get_dl_nrOfLayers(sched_ctrl, dl_bwp->dci_format);
|
||||
NR_sched_pdsch_t sched_pdsch = {
|
||||
|
||||
@@ -95,10 +95,23 @@ void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch)
|
||||
}
|
||||
}
|
||||
}
|
||||
int beam_idx = get_beam_from_ssbidx(mac, ssb_idx_beam);
|
||||
NR_beam_alloc_t beam = beam_allocation_procedure(&mac->beam_info, frame, slot, beam_idx, mac->frame_structure.numb_slots_frame);
|
||||
AssertFatal(beam.idx > -1, "Can't allocate beam %d in phytest scheduler\n", beam_idx);
|
||||
UE->UE_beam_index = get_allocated_beam(&mac->beam_info, frame, slot, mac->frame_structure.numb_slots_frame, beam.idx);
|
||||
UE->UE_beam_index = get_beam_from_ssbidx(mac, ssb_idx_beam);
|
||||
NR_beam_alloc_t dci_beam = beam_allocation_procedure(&mac->beam_info,
|
||||
frame,
|
||||
slot,
|
||||
sched_ctrl->sched_pdcch.StartSymbolIndex,
|
||||
sched_ctrl->sched_pdcch.DurationSymbols,
|
||||
UE->UE_beam_index,
|
||||
mac->frame_structure.numb_slots_frame);
|
||||
AssertFatal(dci_beam.idx > -1, "Can't allocate DCI beam %d in phytest scheduler\n", UE->UE_beam_index);
|
||||
NR_beam_alloc_t beam = beam_allocation_procedure(&mac->beam_info,
|
||||
frame,
|
||||
slot,
|
||||
tda_info.startSymbolIndex,
|
||||
tda_info.nrOfSymbols,
|
||||
UE->UE_beam_index,
|
||||
mac->frame_structure.numb_slots_frame);
|
||||
AssertFatal(beam.idx > -1, "Can't allocate beam %d in phytest scheduler\n", UE->UE_beam_index);
|
||||
|
||||
int rbStart = 0;
|
||||
int rbSize = 0;
|
||||
@@ -125,7 +138,7 @@ void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch)
|
||||
slot,
|
||||
UE->rnti,
|
||||
&sched_ctrl->aggregation_level,
|
||||
beam.idx,
|
||||
dci_beam.idx,
|
||||
sched_ctrl->search_space,
|
||||
sched_ctrl->coreset,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
@@ -147,7 +160,7 @@ void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch)
|
||||
|
||||
sched_ctrl->cce_index = CCEIndex;
|
||||
|
||||
fill_pdcch_vrb_map(mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, beam.idx);
|
||||
fill_pdcch_vrb_map(mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, dci_beam.idx);
|
||||
|
||||
NR_sched_pdsch_t sched_pdsch = {
|
||||
.rbSize = rbSize,
|
||||
|
||||
@@ -3264,9 +3264,6 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, slot_t slot, nfapi_nr_dl_tt
|
||||
if((frame * n_slots_frame + slot - offset) % period == 0) {
|
||||
|
||||
LOG_D(NR_MAC,"Scheduling CSI-RS in frame %d slot %d Resource ID %ld\n", frame, slot, nzpcsi->nzp_CSI_RS_ResourceId);
|
||||
NR_beam_alloc_t beam_csi = beam_allocation_procedure(&gNB_mac->beam_info, frame, slot, UE->UE_beam_index, n_slots_frame);
|
||||
AssertFatal(beam_csi.idx >= 0, "Cannot allocate CSI-RS in any available beam\n");
|
||||
uint16_t *vrb_map = gNB_mac->common_channels[CC_id].vrb_map[beam_csi.idx];
|
||||
UE_info->sched_csirs |= (1 << dl_bwp->bwp_id);
|
||||
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_tti_csirs_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
|
||||
@@ -3313,79 +3310,68 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, slot_t slot, nfapi_nr_dl_tt
|
||||
csirs_pdu_rel15->freq_density--;
|
||||
csirs_pdu_rel15->scramb_id = nzpcsi->scramblingID;
|
||||
csirs_pdu_rel15->power_control_offset = nzpcsi->powerControlOffset + 8;
|
||||
int n_symb_l0 = 0;
|
||||
int n_symb_l1 = 0;
|
||||
if (nzpcsi->powerControlOffsetSS)
|
||||
csirs_pdu_rel15->power_control_offset_ss = *nzpcsi->powerControlOffsetSS;
|
||||
else
|
||||
csirs_pdu_rel15->power_control_offset_ss = 1; // 0 dB
|
||||
switch(resourceMapping.frequencyDomainAllocation.present){
|
||||
switch(resourceMapping.frequencyDomainAllocation.present) {
|
||||
case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1:
|
||||
csirs_pdu_rel15->row = 1;
|
||||
csirs_pdu_rel15->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.row1.buf[0])>>4)&0x0f;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
|
||||
n_symb_l0 = 1;
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2:
|
||||
csirs_pdu_rel15->row = 2;
|
||||
csirs_pdu_rel15->freq_domain = (((resourceMapping.frequencyDomainAllocation.choice.row2.buf[1]>>4)&0x0f) |
|
||||
((resourceMapping.frequencyDomainAllocation.choice.row2.buf[0]<<4)&0xff0));
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
|
||||
n_symb_l0 = 1;
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row4:
|
||||
csirs_pdu_rel15->row = 4;
|
||||
csirs_pdu_rel15->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.row4.buf[0])>>5)&0x07;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
|
||||
n_symb_l0 = 1;
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other:
|
||||
csirs_pdu_rel15->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.other.buf[0])>>2)&0x3f;
|
||||
// determining the row of table 7.4.1.5.3-1 in 38.211
|
||||
switch(resourceMapping.nrofPorts){
|
||||
switch(resourceMapping.nrofPorts) {
|
||||
case NR_CSI_RS_ResourceMapping__nrofPorts_p1:
|
||||
AssertFatal(1==0,"Resource with 1 CSI port shouldn't be within other rows\n");
|
||||
AssertFatal(false, "Resource with 1 CSI port shouldn't be within other rows\n");
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__nrofPorts_p2:
|
||||
csirs_pdu_rel15->row = 3;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
|
||||
n_symb_l0 = 1;
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__nrofPorts_p4:
|
||||
csirs_pdu_rel15->row = 5;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
|
||||
n_symb_l0 = 2;
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__nrofPorts_p8:
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
|
||||
csirs_pdu_rel15->row = 8;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
|
||||
}
|
||||
else{
|
||||
n_symb_l0 = 2;
|
||||
} else {
|
||||
int num_k = 0;
|
||||
for (int k=0; k<6; k++)
|
||||
num_k+=(((csirs_pdu_rel15->freq_domain)>>k)&0x01);
|
||||
if(num_k==4) {
|
||||
csirs_pdu_rel15->row = 6;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
|
||||
}
|
||||
else {
|
||||
n_symb_l0 = 1;
|
||||
} else {
|
||||
csirs_pdu_rel15->row = 7;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
|
||||
n_symb_l0 = 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__nrofPorts_p12:
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
|
||||
csirs_pdu_rel15->row = 10;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
|
||||
}
|
||||
else {
|
||||
n_symb_l0 = 2;
|
||||
} else {
|
||||
csirs_pdu_rel15->row = 9;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
|
||||
n_symb_l0 = 2;
|
||||
}
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__nrofPorts_p16:
|
||||
@@ -3393,53 +3379,69 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, slot_t slot, nfapi_nr_dl_tt
|
||||
csirs_pdu_rel15->row = 12;
|
||||
else
|
||||
csirs_pdu_rel15->row = 11;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
|
||||
n_symb_l0 = 2;
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__nrofPorts_p24:
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
|
||||
csirs_pdu_rel15->row = 14;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= (SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2) | SL_to_bitmap(csirs_pdu_rel15->symb_l1, 2));
|
||||
}
|
||||
else{
|
||||
n_symb_l0 = 2;
|
||||
n_symb_l1 = 2;
|
||||
} else {
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) {
|
||||
csirs_pdu_rel15->row = 15;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 3);
|
||||
}
|
||||
else {
|
||||
n_symb_l0 = 4;
|
||||
} else {
|
||||
csirs_pdu_rel15->row = 13;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= (SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2) | SL_to_bitmap(csirs_pdu_rel15->symb_l1, 2));
|
||||
n_symb_l0 = 2;
|
||||
n_symb_l1 = 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__nrofPorts_p32:
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
|
||||
csirs_pdu_rel15->row = 17;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= (SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2) | SL_to_bitmap(csirs_pdu_rel15->symb_l1, 2));
|
||||
}
|
||||
else{
|
||||
n_symb_l0 = 2;
|
||||
n_symb_l1 = 2;
|
||||
} else {
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) {
|
||||
csirs_pdu_rel15->row = 18;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 3);
|
||||
}
|
||||
else {
|
||||
n_symb_l0 = 4;
|
||||
} else {
|
||||
csirs_pdu_rel15->row = 16;
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= (SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2) | SL_to_bitmap(csirs_pdu_rel15->symb_l1, 2));
|
||||
n_symb_l0 = 2;
|
||||
n_symb_l1 = 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"Invalid number of ports in CSI-RS resource\n");
|
||||
AssertFatal(false, "Invalid number of ports in CSI-RS resource\n");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"Invalid freqency domain allocation in CSI-RS resource\n");
|
||||
AssertFatal(false, "Invalid freqency domain allocation in CSI-RS resource\n");
|
||||
}
|
||||
NR_beam_alloc_t beam_csi = beam_allocation_procedure(&gNB_mac->beam_info,
|
||||
frame,
|
||||
slot,
|
||||
csirs_pdu_rel15->symb_l0,
|
||||
n_symb_l0,
|
||||
UE->UE_beam_index,
|
||||
n_slots_frame);
|
||||
AssertFatal(beam_csi.idx >= 0, "Cannot allocate CSI-RS in any available beam\n");
|
||||
uint16_t *vrb_map = gNB_mac->common_channels[CC_id].vrb_map[beam_csi.idx];
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, n_symb_l0);
|
||||
if (n_symb_l1) {
|
||||
NR_beam_alloc_t beam_csi1 = beam_allocation_procedure(&gNB_mac->beam_info,
|
||||
frame,
|
||||
slot,
|
||||
csirs_pdu_rel15->symb_l1,
|
||||
n_symb_l1,
|
||||
UE->UE_beam_index,
|
||||
n_slots_frame);
|
||||
AssertFatal(beam_csi1.idx >= 0 && beam_csi1.idx == beam_csi.idx, "Cannot allocate CSI-RS in any available beam\n");
|
||||
for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
|
||||
vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l1, n_symb_l1);
|
||||
}
|
||||
dl_req->nPDUs++;
|
||||
}
|
||||
@@ -3709,32 +3711,57 @@ void fill_beam_index_list(NR_ServingCellConfigCommon_t *scc, const nr_mac_config
|
||||
}
|
||||
}
|
||||
|
||||
static inline int get_beam_index(const NR_beam_info_t *beam_info, int frame, int slot, int slots_per_frame)
|
||||
static inline int get_beam_allocation_slot_index(const NR_beam_info_t *beam_info, int frame, int slot, int slots_per_frame)
|
||||
{
|
||||
return ((frame * slots_per_frame + slot) / beam_info->beam_duration) % beam_info->beam_allocation_size;
|
||||
return ((frame * slots_per_frame + slot) / beam_info->beam_slot_duration) % beam_info->beam_allocation_size[0];
|
||||
}
|
||||
|
||||
NR_beam_alloc_t beam_allocation_procedure(NR_beam_info_t *beam_info, int frame, int slot, int16_t beam_index, int slots_per_frame)
|
||||
NR_beam_alloc_t beam_allocation_procedure(NR_beam_info_t *beam_info,
|
||||
int frame,
|
||||
int slot,
|
||||
int start_symbol,
|
||||
int nb_symbols,
|
||||
int16_t beam_index,
|
||||
int slots_per_frame)
|
||||
{
|
||||
// if no beam allocation for analog beamforming we always return beam index 0 (no multiple beams)
|
||||
if (beam_info->beam_mode == NO_BEAM_MODE)
|
||||
return (NR_beam_alloc_t) {.new_beam = false, .idx = 0};
|
||||
return (NR_beam_alloc_t) {.new_beam = 0, .idx = 0};
|
||||
|
||||
const int index = get_beam_index(beam_info, frame, slot, slots_per_frame);
|
||||
const int index = get_beam_allocation_slot_index(beam_info, frame, slot, slots_per_frame);
|
||||
int alloc_start = 0;
|
||||
int alloc_end = 0;
|
||||
if (beam_info->beam_allocation_size[1] > 1) {
|
||||
int step_size = NR_SYMBOLS_PER_SLOT / beam_info->beam_allocation_size[1];
|
||||
alloc_start = start_symbol / step_size;
|
||||
alloc_end = (start_symbol + nb_symbols - 1) / step_size;
|
||||
}
|
||||
for (int i = 0; i < beam_info->beams_per_period; i++) {
|
||||
NR_beam_alloc_t beam_struct = {.new_beam = false, .idx = i};
|
||||
int16_t *beam = &beam_info->beam_allocation[i][index];
|
||||
if (*beam == -1) {
|
||||
beam_struct.new_beam = true;
|
||||
*beam = beam_index;
|
||||
bool beam_found = true;
|
||||
uint16_t new_beam = 0;
|
||||
for (int j = alloc_start; j <= alloc_end; j++) {
|
||||
int16_t beam = beam_info->beam_allocation[i][index][j];
|
||||
if (beam != -1 && beam != beam_index) {
|
||||
beam_found = false;
|
||||
break;
|
||||
} else if (beam == -1)
|
||||
new_beam |= (1 << j);
|
||||
}
|
||||
if (*beam == beam_index) {
|
||||
LOG_D(NR_MAC, "%d.%d Using beam structure with index %d for beam %d (%s)\n", frame, slot, beam_struct.idx, beam_index, beam_struct.new_beam ? "new beam" : "old beam");
|
||||
if (beam_found) {
|
||||
NR_beam_alloc_t beam_struct = {.new_beam = new_beam, .idx = i};
|
||||
for (int j = alloc_start; j <= alloc_end; j++)
|
||||
beam_info->beam_allocation[i][index][j] = beam_index;
|
||||
LOG_D(NR_MAC,
|
||||
"%d.%d Using beam structure with index %d for beam %d (%s)\n",
|
||||
frame,
|
||||
slot,
|
||||
beam_struct.idx,
|
||||
beam_index,
|
||||
beam_struct.new_beam ? "new beam" : "old beam");
|
||||
return beam_struct;
|
||||
}
|
||||
}
|
||||
|
||||
return (NR_beam_alloc_t) {.new_beam = false, .idx = -1};
|
||||
return (NR_beam_alloc_t) {.new_beam = 0, .idx = -1};
|
||||
}
|
||||
|
||||
uint16_t convert_to_fapi_beam(const uint16_t beam_idx, const nr_beam_mode_t mode)
|
||||
@@ -3743,24 +3770,17 @@ uint16_t convert_to_fapi_beam(const uint16_t beam_idx, const nr_beam_mode_t mode
|
||||
return (mode == LOPHY_BEAM_IDX) ? SET_BIT(beam_idx, 15) : beam_idx;
|
||||
}
|
||||
|
||||
int16_t get_allocated_beam(const NR_beam_info_t *beam_info, int frame, int slot, int slots_per_frame, int beam_number_in_period)
|
||||
void reset_beam_status(NR_beam_info_t *beam_info, int frame, int slot, int16_t beam_index, int slots_per_frame, uint16_t beam_alloc)
|
||||
{
|
||||
int16_t beam_idx = 0;
|
||||
if (beam_info->beam_mode != NO_BEAM_MODE) {
|
||||
const int index = get_beam_index(beam_info, frame, slot, slots_per_frame);
|
||||
beam_idx = beam_info->beam_allocation[beam_number_in_period][index];
|
||||
}
|
||||
return beam_idx;
|
||||
}
|
||||
|
||||
void reset_beam_status(NR_beam_info_t *beam_info, int frame, int slot, int16_t beam_index, int slots_per_frame, bool new_beam)
|
||||
{
|
||||
if(!new_beam) // need to reset only if the beam was allocated specifically for this instance
|
||||
if(beam_alloc == 0) // need to reset only if the beam was allocated specifically for this instance
|
||||
return;
|
||||
const int index = get_beam_index(beam_info, frame, slot, slots_per_frame);
|
||||
const int index = get_beam_allocation_slot_index(beam_info, frame, slot, slots_per_frame);
|
||||
for (int i = 0; i < beam_info->beams_per_period; i++) {
|
||||
if (beam_info->beam_allocation[i][index] == beam_index)
|
||||
beam_info->beam_allocation[i][index] = -1;
|
||||
for (int j = 0; j < NR_SYMBOLS_PER_SLOT; j++) {
|
||||
if (IS_BIT_SET(beam_alloc, j))
|
||||
if (beam_info->beam_allocation[i][index][j] == beam_index)
|
||||
beam_info->beam_allocation[i][index][j] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -458,11 +458,11 @@ static void nr_configure_srs(gNB_MAC_INST *nrmac,
|
||||
}
|
||||
const uint16_t fapi_beam = convert_to_fapi_beam(UE->UE_beam_index, nrmac->beam_info.beam_mode);
|
||||
srs_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = fapi_beam;
|
||||
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 = &nrmac->common_channels[CC_id].vrb_map_UL[beam.idx][buffer_index * MAX_BWP_SIZE];
|
||||
uint16_t num = 1 << srs_pdu->num_symbols; // 0,1,2 means 1,2,4 symbols, see 222.10.04 table 3-105
|
||||
const uint8_t l0 = NR_SYMBOLS_PER_SLOT - 1 - srs_pdu->time_start_position;
|
||||
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, frame, slot, l0, num, UE->UE_beam_index, slots_per_frame);
|
||||
AssertFatal(beam.idx >= 0, "Cannot allocate SRS in any available beam\n");
|
||||
uint16_t *vrb_map_UL = &nrmac->common_channels[CC_id].vrb_map_UL[beam.idx][buffer_index * MAX_BWP_SIZE];
|
||||
uint16_t mask = SL_to_bitmap(l0, num);
|
||||
DevAssert(mask != 0);
|
||||
for (int i = 0; i < srs_pdu->bwp_size; ++i) {
|
||||
|
||||
@@ -254,12 +254,6 @@ void nr_csi_meas_reporting(int Mod_idP,frame_t frame, slot_t slot)
|
||||
curr_pucch->active = true;
|
||||
|
||||
int bwp_start = ul_bwp->BWPStart;
|
||||
|
||||
// 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, 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++) {
|
||||
NR_PUCCH_Resource_t *pucchres = pucch_Config->resourceToAddModList->list.array[j];
|
||||
@@ -267,11 +261,13 @@ void nr_csi_meas_reporting(int Mod_idP,frame_t frame, slot_t slot)
|
||||
continue;
|
||||
int start = pucchres->startingPRB;
|
||||
int len = 1;
|
||||
uint64_t mask = 0;
|
||||
int startingSymbolIndex = 0;
|
||||
int nrofSymbols = 0;
|
||||
switch(pucchres->format.present){
|
||||
case NR_PUCCH_Resource__format_PR_format2:
|
||||
len = pucchres->format.choice.format2->nrofPRBs;
|
||||
mask = SL_to_bitmap(pucchres->format.choice.format2->startingSymbolIndex, pucchres->format.choice.format2->nrofSymbols);
|
||||
nrofSymbols = pucchres->format.choice.format2->nrofSymbols;
|
||||
startingSymbolIndex = pucchres->format.choice.format2->startingSymbolIndex;
|
||||
curr_pucch->simultaneous_harqcsi = pucch_Config->format2->choice.setup->simultaneousHARQ_ACK_CSI;
|
||||
LOG_D(NR_MAC,
|
||||
"%d.%d Allocating PUCCH format 2, startPRB %d, nPRB %d, simulHARQ %d, num_bits %d\n",
|
||||
@@ -284,17 +280,30 @@ void nr_csi_meas_reporting(int Mod_idP,frame_t frame, slot_t slot)
|
||||
break;
|
||||
case NR_PUCCH_Resource__format_PR_format3:
|
||||
len = pucchres->format.choice.format3->nrofPRBs;
|
||||
mask = SL_to_bitmap(pucchres->format.choice.format3->startingSymbolIndex, pucchres->format.choice.format3->nrofSymbols);
|
||||
nrofSymbols = pucchres->format.choice.format3->nrofSymbols;
|
||||
startingSymbolIndex = pucchres->format.choice.format3->startingSymbolIndex;
|
||||
curr_pucch->simultaneous_harqcsi = pucch_Config->format3->choice.setup->simultaneousHARQ_ACK_CSI;
|
||||
break;
|
||||
case NR_PUCCH_Resource__format_PR_format4:
|
||||
mask = SL_to_bitmap(pucchres->format.choice.format4->startingSymbolIndex, pucchres->format.choice.format4->nrofSymbols);
|
||||
nrofSymbols = pucchres->format.choice.format4->nrofSymbols;
|
||||
startingSymbolIndex = pucchres->format.choice.format4->startingSymbolIndex;
|
||||
curr_pucch->simultaneous_harqcsi = pucch_Config->format4->choice.setup->simultaneousHARQ_ACK_CSI;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(0, "Invalid PUCCH format type\n");
|
||||
}
|
||||
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info,
|
||||
sched_frame,
|
||||
sched_slot,
|
||||
startingSymbolIndex,
|
||||
nrofSymbols,
|
||||
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, 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];
|
||||
// verify resources are free
|
||||
uint64_t mask = SL_to_bitmap(startingSymbolIndex, nrofSymbols);
|
||||
for (int i = start; i < start + len; ++i) {
|
||||
if((vrb_map_UL[i+bwp_start] & mask) != 0) {
|
||||
LOG_E(NR_MAC,
|
||||
@@ -1221,7 +1230,13 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac,
|
||||
else { // unoccupied occasion
|
||||
// checking if in ul_slot the resources potentially to be assigned to this PUCCH are available
|
||||
set_pucch_allocation(ul_bwp, r_pucch, bwp_size, curr_pucch);
|
||||
NR_beam_alloc_t beam = beam_allocation_procedure(&mac->beam_info, pucch_frame, pucch_slot, ue_beam, n_slots_frame);
|
||||
NR_beam_alloc_t beam = beam_allocation_procedure(&mac->beam_info,
|
||||
pucch_frame,
|
||||
pucch_slot,
|
||||
curr_pucch->start_symb,
|
||||
curr_pucch->nr_of_symb,
|
||||
ue_beam,
|
||||
n_slots_frame);
|
||||
if (beam.idx < 0) {
|
||||
LOG_D(NR_MAC,
|
||||
"DL %4d.%2d, UL_ACK %4d.%2d beam resources for this occasion are already occupied, move to the following occasion\n",
|
||||
@@ -1325,18 +1340,24 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, slot_t slot)
|
||||
slot);
|
||||
memset(curr_pucch, 0, sizeof(*curr_pucch));
|
||||
continue;
|
||||
}
|
||||
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, 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];
|
||||
} else {
|
||||
const int bwp_start = ul_bwp->BWPStart;
|
||||
const int bwp_size = ul_bwp->BWPSize;
|
||||
set_pucch_allocation(ul_bwp, -1, bwp_size, curr_pucch);
|
||||
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info,
|
||||
SFN,
|
||||
slot,
|
||||
curr_pucch->start_symb,
|
||||
curr_pucch->nr_of_symb,
|
||||
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, 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];
|
||||
bool ret = test_pucch0_vrb_occupation(curr_pucch, vrb_map_UL, bwp_start);
|
||||
if (!ret) {
|
||||
LOG_E(NR_MAC,"Cannot schedule SR. PRBs not available\n");
|
||||
reset_beam_status(&nrmac->beam_info, SFN, slot, UE->UE_beam_index, n_slots_frame, beam.new_beam);
|
||||
continue;
|
||||
}
|
||||
curr_pucch->frame = SFN;
|
||||
|
||||
@@ -1709,16 +1709,15 @@ static void nr_ue_max_mcs_min_rb(int mu,
|
||||
*mcs = pot.mcs;
|
||||
}
|
||||
|
||||
static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
|
||||
post_process_pusch_t *pp_pusch,
|
||||
uint16_t *rballoc_mask,
|
||||
int *n_rb_sched,
|
||||
int dci_beam_idx,
|
||||
NR_UE_info_t *UE,
|
||||
int harq_pid,
|
||||
const NR_ServingCellConfigCommon_t *scc,
|
||||
const int tda,
|
||||
const NR_tda_info_t *tda_info)
|
||||
static NR_rtx_ret_t allocate_ul_retransmission(gNB_MAC_INST *nrmac,
|
||||
post_process_pusch_t *pp_pusch,
|
||||
int dci_beam_idx,
|
||||
int buf_idx,
|
||||
NR_UE_info_t *UE,
|
||||
int harq_pid,
|
||||
const NR_ServingCellConfigCommon_t *scc,
|
||||
const int tda,
|
||||
const NR_tda_info_t *tda_info)
|
||||
{
|
||||
const int CC_id = 0;
|
||||
int frame = pp_pusch->frame;
|
||||
@@ -1744,10 +1743,24 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
|
||||
new_sched.bwp_info = bwp_info;
|
||||
DevAssert(new_sched.ul_harq_pid == harq_pid);
|
||||
|
||||
NR_rtx_ret_t ret = {0};
|
||||
uint16_t *rballoc_mask;
|
||||
NR_beam_alloc_t beam;
|
||||
int slots_per_frame = nrmac->frame_structure.numb_slots_frame;
|
||||
bool reuse_old_tda = retInfo->time_domain_allocation == tda;
|
||||
if (reuse_old_tda && nrOfLayers == retInfo->nrOfLayers) {
|
||||
/* Check the resource is enough for retransmission */
|
||||
beam = beam_allocation_procedure(&nrmac->beam_info,
|
||||
new_sched.frame,
|
||||
new_sched.slot,
|
||||
retInfo->tda_info.startSymbolIndex,
|
||||
retInfo->tda_info.nrOfSymbols,
|
||||
UE->UE_beam_index,
|
||||
slots_per_frame);
|
||||
if (beam.idx < 0)
|
||||
return ret;
|
||||
const uint16_t slbitmap = SL_to_bitmap(retInfo->tda_info.startSymbolIndex, retInfo->tda_info.nrOfSymbols);
|
||||
rballoc_mask = &nrmac->common_channels[0].vrb_map_UL[beam.idx][buf_idx * MAX_BWP_SIZE];
|
||||
if (!get_rb_alloc(retInfo->rbSize, retInfo->rbSize, bwpStart, bwpSize, rballoc_mask, slbitmap, &rbStart, &rbSize)) {
|
||||
LOG_D(NR_MAC,
|
||||
"[UE %04x][%4d.%2d] could not allocate UL retransmission: no resources (rbStart %d, retInfo->rbSize %d, bwpSize %d) \n",
|
||||
@@ -1757,12 +1770,22 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
|
||||
rbStart,
|
||||
retInfo->rbSize,
|
||||
bwpSize);
|
||||
return false;
|
||||
reset_beam_status(&nrmac->beam_info, new_sched.frame, new_sched.slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
|
||||
return ret;
|
||||
}
|
||||
new_sched.rbStart = rbStart;
|
||||
LOG_D(NR_MAC, "Retransmission keeping TDA %d and TBS %d\n", tda, retInfo->tb_size);
|
||||
} else {
|
||||
NR_pusch_dmrs_t dmrs_info = get_ul_dmrs_params(scc, ul_bwp, tda_info, nrOfLayers);
|
||||
beam = beam_allocation_procedure(&nrmac->beam_info,
|
||||
new_sched.frame,
|
||||
new_sched.slot,
|
||||
tda_info->startSymbolIndex,
|
||||
tda_info->nrOfSymbols,
|
||||
UE->UE_beam_index,
|
||||
slots_per_frame);
|
||||
if (beam.idx < 0)
|
||||
return ret;
|
||||
/* the retransmission will use a different time domain allocation, check
|
||||
* that we have enough resources */
|
||||
uint32_t new_tbs;
|
||||
@@ -1786,13 +1809,16 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
|
||||
slot,
|
||||
new_tbs,
|
||||
retInfo->tb_size);
|
||||
return false; /* the maximum TBsize we might have is smaller than what we need */
|
||||
reset_beam_status(&nrmac->beam_info, new_sched.frame, new_sched.slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
|
||||
return ret; /* the maximum TBsize we might have is smaller than what we need */
|
||||
}
|
||||
|
||||
rballoc_mask = &nrmac->common_channels[0].vrb_map_UL[beam.idx][buf_idx * MAX_BWP_SIZE];
|
||||
const uint16_t slbitmap = SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols);
|
||||
if (!get_rb_alloc(new_rbSize, new_rbSize, bwpStart, bwpSize, rballoc_mask, slbitmap, &rbStart, &rbSize)) {
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate UL retransmission: no resources\n", UE->rnti, frame, slot);
|
||||
return false;
|
||||
reset_beam_status(&nrmac->beam_info, new_sched.frame, new_sched.slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LOG_D(NR_MAC,
|
||||
@@ -1825,7 +1851,8 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
|
||||
if (CCEIndex<0) {
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] no free CCE for retransmission UL DCI UE\n", UE->rnti, frame, slot);
|
||||
sched_ctrl->ul_cce_fail++;
|
||||
return false;
|
||||
reset_beam_status(&nrmac->beam_info, new_sched.frame, new_sched.slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
|
||||
return ret;
|
||||
}
|
||||
|
||||
sched_ctrl->cce_index = CCEIndex;
|
||||
@@ -1844,10 +1871,12 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
|
||||
new_sched.rbSize);
|
||||
|
||||
/* Mark the corresponding RBs as used */
|
||||
n_rb_sched -= new_sched.rbSize;
|
||||
ret.rbsize = new_sched.rbSize;
|
||||
ret.valid = true;
|
||||
ret.beam_idx = beam.idx;
|
||||
for (int rb = bwpStart + new_sched.rbStart; rb < bwpStart + new_sched.rbStart + new_sched.rbSize; rb++)
|
||||
rballoc_mask[rb] |= SL_to_bitmap(new_sched.tda_info.startSymbolIndex, new_sched.tda_info.nrOfSymbols);
|
||||
return true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef struct UEsched_s {
|
||||
@@ -1906,14 +1935,12 @@ static int pf_ul(gNB_MAC_INST *nrmac,
|
||||
|
||||
/* Loop UE_list to calculate throughput and coeff */
|
||||
UE_iterator(UE_list, UE) {
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
if (!nr_mac_ue_is_active(UE))
|
||||
continue;
|
||||
|
||||
LOG_D(NR_MAC,"pf_ul: preparing UL scheduling for UE %04x\n",UE->rnti);
|
||||
NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP;
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
NR_mac_dir_stats_t *stats = &UE->mac_stats.ul;
|
||||
|
||||
/* Calculate throughput */
|
||||
@@ -1930,47 +1957,34 @@ static int pf_ul(gNB_MAC_INST *nrmac,
|
||||
if (total_rem_ues == 0)
|
||||
continue;
|
||||
|
||||
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] ULSCH DCI Beam could not be allocated\n", UE->rnti, frame, slot);
|
||||
continue;
|
||||
}
|
||||
|
||||
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] ULSCH Beam could not be allocated\n", UE->rnti, frame, slot);
|
||||
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, 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 */
|
||||
int ul_harq_pid = sched_ctrl->retrans_ul_harq.head;
|
||||
LOG_D(NR_MAC,"pf_ul: UE %04x harq_pid %d\n", UE->rnti, ul_harq_pid);
|
||||
if (ul_harq_pid >= 0) {
|
||||
/* Allocate retransmission*/
|
||||
bool r = allocate_ul_retransmission(nrmac,
|
||||
pp_pusch,
|
||||
rballoc_mask,
|
||||
&n_rb_sched[beam.idx],
|
||||
dci_beam.idx,
|
||||
UE,
|
||||
ul_harq_pid,
|
||||
scc,
|
||||
tda,
|
||||
tda_info);
|
||||
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, 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);
|
||||
NR_beam_alloc_t dci_beam = beam_allocation_procedure(&nrmac->beam_info,
|
||||
frame,
|
||||
slot,
|
||||
sched_ctrl->sched_pdcch.StartSymbolIndex,
|
||||
sched_ctrl->sched_pdcch.DurationSymbols,
|
||||
UE->UE_beam_index,
|
||||
slots_per_frame);
|
||||
if (dci_beam.idx < 0) {
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] DCI for ULSCH beam could not be allocated\n", UE->rnti, frame, slot);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
/* Allocate retransmission*/
|
||||
const int index = ul_buffer_index(sched_frame, sched_slot, slots_per_frame, nrmac->vrb_map_UL_size);
|
||||
NR_rtx_ret_t ret = allocate_ul_retransmission(nrmac, pp_pusch, dci_beam.idx, index, UE, ul_harq_pid, scc, tda, tda_info);
|
||||
if (!ret.valid) {
|
||||
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, frame, slot, UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
|
||||
continue;
|
||||
} else
|
||||
LOG_D(NR_MAC,"%4d.%2d UL Retransmission UE RNTI %04x to be allocated, max_num_ue %d\n", frame, slot, UE->rnti,max_num_ue);
|
||||
|
||||
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
||||
remainUEs[beam.idx]--;
|
||||
remainUEs[ret.beam_idx]--;
|
||||
n_rb_sched[ret.beam_idx] -= ret.rbsize;
|
||||
scheduled_something = true;
|
||||
continue;
|
||||
}
|
||||
@@ -1980,8 +1994,6 @@ static int pf_ul(gNB_MAC_INST *nrmac,
|
||||
* 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, 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;
|
||||
}
|
||||
@@ -1995,11 +2007,8 @@ static int pf_ul(gNB_MAC_INST *nrmac,
|
||||
nrmac->ulsch_max_frame_inactivity);
|
||||
|
||||
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, 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);
|
||||
if ((B == 0 && !do_sched) || nr_timer_is_active(&sched_ctrl->transm_interrupt))
|
||||
continue;
|
||||
}
|
||||
|
||||
const NR_bler_options_t *bo = &nrmac->ul_bler;
|
||||
const int max_mcs_table = (current_BWP->mcs_table == 0 || current_BWP->mcs_table == 2) ? 28 : 27;
|
||||
@@ -2055,7 +2064,13 @@ static int pf_ul(gNB_MAC_INST *nrmac,
|
||||
NR_UE_UL_BWP_t *current_BWP = &iterator->UE->current_UL_BWP;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &iterator->UE->UE_sched_ctrl;
|
||||
|
||||
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, slots_per_frame);
|
||||
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info,
|
||||
sched_frame,
|
||||
sched_slot,
|
||||
tda_info->startSymbolIndex,
|
||||
tda_info->nrOfSymbols,
|
||||
iterator->UE->UE_beam_index,
|
||||
slots_per_frame);
|
||||
if (beam.idx < 0) {
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] ULSCH Beam could not be allocated\n", iterator->UE->rnti, sched_frame, sched_slot);
|
||||
iterator++;
|
||||
@@ -2068,7 +2083,13 @@ static int pf_ul(gNB_MAC_INST *nrmac,
|
||||
continue;
|
||||
}
|
||||
|
||||
NR_beam_alloc_t dci_beam = beam_allocation_procedure(&nrmac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame);
|
||||
NR_beam_alloc_t dci_beam = beam_allocation_procedure(&nrmac->beam_info,
|
||||
frame,
|
||||
slot,
|
||||
sched_ctrl->sched_pdcch.StartSymbolIndex,
|
||||
sched_ctrl->sched_pdcch.DurationSymbols,
|
||||
iterator->UE->UE_beam_index,
|
||||
slots_per_frame);
|
||||
if (dci_beam.idx < 0) {
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] ULSCH DCI 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, slots_per_frame, beam.new_beam);
|
||||
|
||||
@@ -446,10 +446,15 @@ uint64_t get_ssb_bitmap(const NR_ServingCellConfigCommon_t *scc);
|
||||
uint64_t get_ssb_bitmap_and_len(const NR_ServingCellConfigCommon_t *scc, uint8_t *len);
|
||||
void fill_beam_index_list(NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *config, gNB_MAC_INST *mac);
|
||||
int get_beam_from_ssbidx(gNB_MAC_INST *mac, int ssb_idx);
|
||||
int16_t get_allocated_beam(const NR_beam_info_t *beam_info, int frame, int slot, int slots_per_frame, int beam_number_in_period);
|
||||
uint16_t convert_to_fapi_beam(const uint16_t beam_idx, const nr_beam_mode_t mode);
|
||||
NR_beam_alloc_t beam_allocation_procedure(NR_beam_info_t *beam_info, int frame, int slot, int16_t beam_index, int slots_per_frame);
|
||||
void reset_beam_status(NR_beam_info_t *beam_info, int frame, int slot, int16_t beam_index, int slots_per_frame, bool new_beam);
|
||||
NR_beam_alloc_t beam_allocation_procedure(NR_beam_info_t *beam_info,
|
||||
int frame,
|
||||
int slot,
|
||||
int start_symbol,
|
||||
int nb_symbols,
|
||||
int16_t beam_index,
|
||||
int slots_per_frame);
|
||||
void reset_beam_status(NR_beam_info_t *beam_info, int frame, int slot, int16_t beam_alloc, int slots_per_frame, uint16_t new_beam);
|
||||
int beam_selection_procedures(gNB_MAC_INST *mac, NR_UE_info_t *UE);
|
||||
void beam_switching_procedure(gNB_MAC_INST *mac, NR_UE_info_t *UE, int new_beam_index);
|
||||
void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t frameP, slot_t slotP);
|
||||
|
||||
@@ -98,9 +98,15 @@ typedef enum {
|
||||
static const char *const nrra_text[] =
|
||||
{"IDLE", "Msg2", "WAIT_MsgA_PUSCH", "WAIT_Msg3", "Msg3_retransmission", "Msg4", "MsgB", "WAIT_Msg4_MsgB_ACK"};
|
||||
|
||||
typedef struct {
|
||||
bool valid;
|
||||
int beam_idx;
|
||||
int rbsize;
|
||||
} NR_rtx_ret_t;
|
||||
|
||||
typedef struct {
|
||||
int idx;
|
||||
bool new_beam;
|
||||
uint16_t new_beam; // each bit a group of symbols
|
||||
} NR_beam_alloc_t;
|
||||
|
||||
typedef struct nr_pdsch_AntennaPorts_t {
|
||||
@@ -814,10 +820,11 @@ typedef enum {
|
||||
|
||||
typedef struct {
|
||||
/// list of allocated beams per period
|
||||
int16_t **beam_allocation;
|
||||
int beam_duration; // in slots
|
||||
int16_t ***beam_allocation;
|
||||
int beam_slot_duration;
|
||||
int beam_symbol_duration;
|
||||
int beams_per_period;
|
||||
int beam_allocation_size;
|
||||
int beam_allocation_size[2];
|
||||
nr_beam_mode_t beam_mode;
|
||||
} NR_beam_info_t;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user