Commit e3c4c4da authored by Jaroslava Fiedlerova's avatar Jaroslava Fiedlerova

Merge remote-tracking branch 'origin/prb-overlap-fix' into integration_2026_w13 (!3933)

mac: fixes to prevent prb overlapping

- this patch fixes a bug in the MAC where the scheduled PRB resources can
  overlap
- at the same time, we try to enforce the same semantics for "rbStart" (which
  should be relative to the BWP) across the code as much as possible
parents 15239d25 5287ed68
......@@ -859,14 +859,11 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
.dmrs_info = dmrs_info,
};
const int bwpStart = sched_pusch.bwp_info.bwpStart;
const int bwpSize = sched_pusch.bwp_info.bwpSize;
int rbStart = 0;
for (int i = 0; (i < ra->msg3_nb_rb) && (rbStart <= (sched_pusch.bwp_info.bwpSize - ra->msg3_nb_rb)); i++) {
if (vrb_map_UL[rbStart + sched_pusch.bwp_info.bwpStart + i] & SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols)) {
rbStart += i;
i = 0;
}
}
if (rbStart > (sched_pusch.bwp_info.bwpSize - ra->msg3_nb_rb)) {
int rbSize = 0;
if (!get_rb_alloc(ra->msg3_nb_rb, ra->msg3_nb_rb, bwpStart, bwpSize, vrb_map_UL, msg3_mask, &rbStart, &rbSize)) {
// cannot find free vrb_map for msg3 retransmission in this slot
reset_beam_status(&nr_mac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_frame, beam_ul.new_beam);
reset_beam_status(&nr_mac->beam_info, frame, slot, UE->UE_beam_index, slots_frame, beam_dci.new_beam);
......@@ -980,7 +977,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
beam_dci.idx);
for (int rb = 0; rb < ra->msg3_nb_rb; rb++) {
vrb_map_UL[rbStart + sched_pusch.bwp_info.bwpStart + rb] |= SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols);
vrb_map_UL[rbStart + sched_pusch.bwp_info.bwpStart + rb] |= msg3_mask;
}
// Restart RA contention resolution timer in Msg3 retransmission slot (current slot + K2)
......@@ -1064,6 +1061,7 @@ static bool nr_get_Msg3alloc(gNB_MAC_INST *mac, int CC_id, int current_slot, fra
int startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength;
SLIV2SL(startSymbolAndLength, &ra->msg3_startsymb, &ra->msg3_nbSymb);
const uint16_t msg3_mask = SL_to_bitmap(ra->msg3_startsymb, ra->msg3_nbSymb);
const int buffer_index = ul_buffer_index(ra->Msg3_frame,
ra->Msg3_slot,
......@@ -1083,18 +1081,9 @@ static bool nr_get_Msg3alloc(gNB_MAC_INST *mac, int CC_id, int current_slot, fra
/* search msg3_nb_rb free RBs */
int rbSize = 0;
int rbStart = 0;
while (rbSize < msg3_nb_rb) {
rbStart += rbSize; /* last iteration rbSize was not enough, skip it */
rbSize = 0;
while (rbStart < bwpSize && (vrb_map_UL[rbStart + bwpStart] & SL_to_bitmap(ra->msg3_startsymb, ra->msg3_nbSymb)))
rbStart++;
if (rbStart + msg3_nb_rb > bwpSize) {
LOG_D(NR_MAC, "No space to allocate Msg 3\n");
return false;
}
while (rbStart + rbSize < bwpSize
&& !(vrb_map_UL[rbStart + bwpStart + rbSize] & SL_to_bitmap(ra->msg3_startsymb, ra->msg3_nbSymb)) && rbSize < msg3_nb_rb)
rbSize++;
if (!get_rb_alloc(msg3_nb_rb, msg3_nb_rb, bwpStart, bwpSize, vrb_map_UL, msg3_mask, &rbStart, &rbSize)) {
LOG_D(NR_MAC, "No space to allocate Msg 3\n");
return false;
}
ra->msg3_nb_rb = msg3_nb_rb;
ra->msg3_first_rb = rbStart;
......@@ -1476,10 +1465,6 @@ static void nr_generate_Msg2(module_id_t module_idP,
return;
}
int mcsIndex = -1; // initialization value
int rbStart = 0;
int rbSize = 8;
bwp_info_t bwp_info = get_pdsch_bwp_start_size(nr_mac, UE);
NR_ControlResourceSet_t *coreset = sched_ctrl->coreset;
AssertFatal(coreset, "Coreset cannot be null for RA-Msg2\n");
const int coresetid = coreset->controlResourceSetId;
......@@ -1499,15 +1484,13 @@ static void nr_generate_Msg2(module_id_t module_idP,
if (!tda_info.valid_tda)
return;
int rbStart = 0;
int rbSize = 0;
uint16_t msg2_nb_rb = max(8, nr_mac->min_grant_prb); // RAR TBS is 9 bytes
const uint16_t msg2_mask = SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols);
bwp_info_t bwp_info = get_pdsch_bwp_start_size(nr_mac, UE);
uint16_t *vrb_map = cc[CC_id].vrb_map[beam.idx];
for (int i = 0; (i < rbSize) && (rbStart <= (bwp_info.bwpSize - rbSize)); i++) {
if (vrb_map[bwp_info.bwpStart + rbStart + i] & SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols)) {
rbStart += i;
i = 0;
}
}
if (rbStart > (bwp_info.bwpSize - rbSize)) {
if (!get_rb_alloc(msg2_nb_rb, msg2_nb_rb, bwp_info.bwpStart, bwp_info.bwpSize, vrb_map, msg2_mask, &rbStart, &rbSize)) {
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);
......@@ -1568,6 +1551,7 @@ static void nr_generate_Msg2(module_id_t module_idP,
NR_pdsch_dmrs_t dmrs_parms = get_dl_dmrs_params(scc, dl_bwp, &tda_info, 1);
int mcsIndex = -1; // initialization value
uint8_t tb_scaling = 0;
int R, Qm;
uint32_t TBS = 0;
......@@ -1665,7 +1649,7 @@ static void nr_generate_Msg2(module_id_t module_idP,
// Mark the corresponding symbols RBs as used
fill_pdcch_vrb_map(nr_mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, aggregation_level, beam.idx);
for (int rb = 0; rb < rbSize; rb++) {
vrb_map[bwp_info.bwpStart + rb + rbStart] |= SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols);
vrb_map[bwp_info.bwpStart + rb + rbStart] |= msg2_mask;
}
// In CFRA: in Msg3 handling, will unconditionally mark succeeded
......@@ -1764,14 +1748,6 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
return;
}
NR_pdsch_dmrs_t dmrs_info = get_dl_dmrs_params(scc, dl_bwp, &msg4_tda, 1);
bwp_info_t bwp_info = get_pdsch_bwp_start_size(nr_mac, UE);
uint8_t mcsTableIdx = dl_bwp->mcsTableIdx;
uint8_t mcsIndex = 0;
int rbStart = 0;
int rbSize = 0;
uint8_t tb_scaling = 0;
uint32_t tb_size = 0;
uint16_t pdu_length;
if(current_harq_pid >= 0) { // in case of retransmission
NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid];
......@@ -1783,16 +1759,23 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
// BI MAC subheader (1 Oct) + SuccessRAR MAC subheader (1 Oct) + SuccessRAR (11 Oct)
}
NR_pdsch_dmrs_t dmrs_info = get_dl_dmrs_params(scc, dl_bwp, &msg4_tda, 1);
bwp_info_t bwp_info = get_pdsch_bwp_start_size(nr_mac, UE);
uint8_t mcsTableIdx = dl_bwp->mcsTableIdx;
uint8_t mcsIndex = 0;
uint8_t tb_scaling = 0;
uint32_t tb_size = 0;
int msg4_nr_rb = 0;
// increase PRBs until we get to BWPSize or TBS is bigger than MAC PDU size
do {
if(rbSize < bwp_info.bwpSize)
rbSize++;
if(msg4_nr_rb < bwp_info.bwpSize)
msg4_nr_rb++;
else
mcsIndex++;
LOG_D(NR_MAC,"Calling nr_compute_tbs with N_PRB_DMRS %d, N_DMRS_SLOT %d\n",dmrs_info.N_PRB_DMRS,dmrs_info.N_DMRS_SLOT);
tb_size = nr_compute_tbs(nr_get_Qm_dl(mcsIndex, mcsTableIdx),
nr_get_code_rate_dl(mcsIndex, mcsTableIdx),
rbSize,
msg4_nr_rb,
msg4_tda.nrOfSymbols,
dmrs_info.N_PRB_DMRS * dmrs_info.N_DMRS_SLOT,
0,
......@@ -1801,18 +1784,11 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
AssertFatal(tb_size >= pdu_length, "Cannot allocate %s\n", ra_type_str);
int i = 0;
int rbStart = 0;
int rbSize = 0;
const uint16_t msg4_mask = SL_to_bitmap(msg4_tda.startSymbolIndex, msg4_tda.nrOfSymbols);
uint16_t *vrb_map = cc[CC_id].vrb_map[beam.idx];
while ((i < rbSize) && (rbStart + rbSize <= bwp_info.bwpSize)) {
if (vrb_map[bwp_info.bwpStart + rbStart + i]&SL_to_bitmap(msg4_tda.startSymbolIndex, msg4_tda.nrOfSymbols)) {
rbStart += i+1;
i = 0;
} else {
i++;
}
}
if (rbStart > (bwp_info.bwpSize - rbSize)) {
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);
return;
......@@ -1953,7 +1929,7 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
aggregation_level,
beam.idx);
for (int rb = 0; rb < rbSize; rb++) {
vrb_map[bwp_info.bwpStart + rb + rbStart] |= SL_to_bitmap(msg4_tda.startSymbolIndex, msg4_tda.nrOfSymbols);
vrb_map[bwp_info.bwpStart + rb + rbStart] |= msg4_mask;
}
ra->ra_state = nrRA_WAIT_Msg4_MsgB_ACK;
......
......@@ -257,37 +257,31 @@ static bool update_rb_mcs_tbs(NR_sched_pdsch_t *pdsch, uint32_t num_total_bytes,
const uint16_t slbitmap = SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols);
int bwpSize = pdsch->bwp_info.bwpSize;
int bwpStart = pdsch->bwp_info.bwpStart;
int rbStop = bwpSize - 1;
while (pdsch->rbStart < rbStop) {
if (vrb_map[pdsch->rbStart + bwpStart] & slbitmap)
pdsch->rbStart++;
else {
int max_rbSize = 0;
while (pdsch->rbStart + max_rbSize <= rbStop && !(vrb_map[pdsch->rbStart + max_rbSize + bwpStart] & slbitmap))
max_rbSize++;
bool res = false;
while (res == false && pdsch->mcs < 10) {
pdsch->Qm = nr_get_Qm_dl(pdsch->mcs, mcsTableIdx);
pdsch->R = nr_get_code_rate_dl(pdsch->mcs, mcsTableIdx);
res = nr_find_nb_rb(pdsch->Qm,
pdsch->R,
1, // no transform precoding for DL
1, // single layer
tda_info->nrOfSymbols,
pdsch->dmrs_parms.N_PRB_DMRS * pdsch->dmrs_parms.N_DMRS_SLOT,
num_total_bytes,
1, // min_rbSize
max_rbSize,
&pdsch->tb_size,
&pdsch->rbSize);
if (!res)
pdsch->mcs++;
}
for (pdsch->mcs = 0; pdsch->mcs < 10; pdsch->mcs++) {
pdsch->Qm = nr_get_Qm_dl(pdsch->mcs, mcsTableIdx);
pdsch->R = nr_get_code_rate_dl(pdsch->mcs, mcsTableIdx);
if (!nr_find_nb_rb(pdsch->Qm,
pdsch->R,
1, // no transform precoding for DL
1, // single layer
tda_info->nrOfSymbols,
pdsch->dmrs_parms.N_PRB_DMRS * pdsch->dmrs_parms.N_DMRS_SLOT,
num_total_bytes,
1, // min_rbSize
bwpSize, // max_rbSize,
&pdsch->tb_size,
&pdsch->rbSize))
continue;
int rbStart, rbSize;
if (get_rb_alloc(pdsch->rbSize, pdsch->rbSize, bwpStart, bwpSize, vrb_map, slbitmap, &rbStart, &rbSize)) {
pdsch->rbStart = rbStart;
pdsch->rbSize = rbSize;
break;
}
}
if (pdsch->tb_size < num_total_bytes) {
if (pdsch->mcs >= 10 || pdsch->tb_size < num_total_bytes) {
LOG_D(NR_MAC,
"Couldn't allocate enough resources for %d bytes in SIB PDSCH (rbStart %d, rbSize %d, bwpSize %d)\n",
num_total_bytes,
......
......@@ -478,47 +478,24 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac,
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);
int rbStart = bwp_info.bwpStart;
int rbStop = bwp_info.bwpStart + bwp_info.bwpSize - 1;
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;
if (reuse_old_tda && layers == new_sched.nrOfLayers) {
/* Check that there are enough resources for retransmission */
while (rbSize < new_sched.rbSize) {
rbStart += rbSize; /* last iteration rbSize was not enough, skip it */
rbSize = 0;
const uint16_t slbitmap = SL_to_bitmap(new_sched.tda_info.startSymbolIndex, new_sched.tda_info.nrOfSymbols);
while (rbStart < rbStop && (rballoc_mask[rbStart] & slbitmap))
rbStart++;
if (rbStart >= rbStop) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate DL retransmission: no resources\n", UE->rnti, frame, slot);
return false;
}
while (rbStart + rbSize <= rbStop && !(rballoc_mask[rbStart + rbSize] & slbitmap) && rbSize < new_sched.rbSize)
rbSize++;
DevAssert(rbSize > 0);
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;
}
} 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);
const uint16_t slbitmap = SL_to_bitmap(temp_tda.startSymbolIndex, temp_tda.nrOfSymbols);
while (rbStart < rbStop && (rballoc_mask[rbStart] & slbitmap))
rbStart++;
if (rbStart >= rbStop) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate DL retransmission: no resources\n", UE->rnti, frame, slot);
return false;
}
while (rbStart + rbSize <= rbStop && !(rballoc_mask[rbStart + rbSize] & slbitmap))
rbSize++;
DevAssert(rbSize > 0);
uint32_t new_tbs;
uint16_t new_rbSize;
bool success = nr_find_nb_rb(new_sched.Qm,
......@@ -529,7 +506,7 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac,
temp_dmrs.N_PRB_DMRS * temp_dmrs.N_DMRS_SLOT,
new_sched.tb_size,
1, /* minimum of 1RB: need to find exact TBS, don't preclude any number */
rbSize,
bwp_size,
&new_tbs,
&new_rbSize);
......@@ -543,6 +520,12 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac,
return false; /* 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;
}
/* we can allocate it. Overwrite the time_domain_allocation, the number
* of RBs, and the new TB size. The rest is done below */
new_sched.tb_size = new_tbs;
......@@ -587,7 +570,7 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac,
sched_ctrl->cce_index = CCEIndex;
fill_pdcch_vrb_map(nr_mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, beam_idx);
new_sched.rbStart = rbStart - bwp_info.bwpStart;
new_sched.rbStart = rbStart;
new_sched.pucch_allocation = alloc;
new_sched.bwp_info = bwp_info;
......@@ -596,7 +579,7 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac,
/* retransmissions: directly allocate */
*n_rb_sched -= new_sched.rbSize;
for (int rb = rbStart; rb < new_sched.rbSize; rb++)
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;
......@@ -824,26 +807,18 @@ static void pf_dl(gNB_MAC_INST *mac,
uint16_t *rballoc_mask = mac->common_channels[CC_id].vrb_map[beam.idx];
bwp_info_t bwp_info = get_pdsch_bwp_start_size(mac, iterator->UE);
int rbStart = 0; // WRT BWP start
int rbStop = bwp_info.bwpSize - 1;
int bwp_start = bwp_info.bwpStart;
int bwp_size = bwp_info.bwpSize;
// Freq-demain allocation
while (rbStart < rbStop && (rballoc_mask[rbStart + bwp_start] & slbitmap))
rbStart++;
uint16_t max_rbSize = 1;
while (rbStart + max_rbSize <= rbStop && !(rballoc_mask[rbStart + max_rbSize + bwp_start] & slbitmap))
max_rbSize++;
if (max_rbSize < min_rbSize) {
int max_rbSize = 0;
if (!get_rb_alloc(min_rbSize, bwp_size, bwp_start, bwp_size, rballoc_mask, slbitmap, &rbStart, &max_rbSize)) {
LOG_D(NR_MAC,
"(%d.%d) Cannot schedule RNTI %04x, rbStart %d, rbSize %d, rbStop %d\n",
"(%d.%d) Cannot schedule RNTI %04x, rbStart %d, rbSize %d\n",
frame,
slot,
rnti,
rbStart,
max_rbSize,
rbStop);
max_rbSize);
reset_beam_status(&mac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, beam.new_beam);
iterator++;
continue;
......@@ -932,8 +907,8 @@ static void pf_dl(gNB_MAC_INST *mac,
/* transmissions: directly allocate */
n_rb_sched[beam.idx] -= sched_pdsch.rbSize;
for (int rb = bwp_start; rb < sched_pdsch.rbSize; rb++)
rballoc_mask[rb + sched_pdsch.rbStart] |= slbitmap;
for (int rb = bwp_start + sched_pdsch.rbStart; rb < bwp_start + sched_pdsch.rbStart + sched_pdsch.rbSize; rb++)
rballoc_mask[rb] |= slbitmap;
remainUEs[beam.idx]--;
iterator++;
......
......@@ -127,26 +127,10 @@ void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch)
if (target_dl_bw>bwpSize)
target_dl_bw = bwpSize;
uint16_t *vrb_map = mac->common_channels[CC_id].vrb_map[beam.idx];
/* loop ensures that we allocate exactly target_dl_bw, or return */
while (true) {
/* advance to first free RB */
while (rbStart < bwpSize &&
(vrb_map[rbStart + BWPStart]&SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols)))
rbStart++;
rbSize = 1;
/* iterate until we are at target_dl_bw or no available RBs */
while (rbStart + rbSize < bwpSize &&
!(vrb_map[rbStart + rbSize + BWPStart]&SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols)) &&
rbSize < target_dl_bw)
rbSize++;
/* found target_dl_bw? */
if (rbSize == target_dl_bw)
break;
/* at end and below target_dl_bw? */
if (rbStart + rbSize >= bwpSize)
return;
rbStart += rbSize;
}
const uint16_t slbitmap = SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols);
/* ensure that we allocate exactly target_dl_bw, or return */
if (!get_rb_alloc(target_dl_bw, target_dl_bw, BWPStart, bwpSize, vrb_map, slbitmap, &rbStart, &rbSize))
return;
sched_ctrl->num_total_bytes = 0;
DevAssert(seq_arr_size(&sched_ctrl->lc_config) == 1);
......@@ -218,7 +202,7 @@ void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch)
/* mark the corresponding RBs as used */
for (int rb = 0; rb < sched_pdsch.rbSize; rb++)
vrb_map[rb + sched_pdsch.rbStart + BWPStart] = SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols);
vrb_map[rb + sched_pdsch.rbStart + BWPStart] = slbitmap;
}
uint32_t target_ul_mcs = 9;
......
......@@ -719,6 +719,45 @@ bool nr_find_nb_rb(uint16_t Qm,
return *tbs >= bytes && *nb_rb <= nb_rb_max;
}
bool get_rb_alloc(int rbSize_min,
int rbSize_max,
int bwpStart,
int bwpSize,
const uint16_t *vrb_map,
uint16_t sym_mask,
int *rbStart_ptr,
int *rbSize_ptr)
{
const uint16_t *bwp_map = &vrb_map[bwpStart];
int rbStart = 0;
while (rbStart + rbSize_min <= bwpSize) {
// 1. Find the first free RB
if ((bwp_map[rbStart] & sym_mask) != 0) {
rbStart++;
continue;
}
// 2. Measure contiguous block
int current_limit = min(rbStart + rbSize_max, bwpSize);
int rbEnd = rbStart + 1;
while (rbEnd < current_limit && (bwp_map[rbEnd] & sym_mask) == 0) {
rbEnd++;
}
int rbSize = rbEnd - rbStart;
// 3. Validate
if (rbSize >= rbSize_min) {
*rbStart_ptr = rbStart;
*rbSize_ptr = rbSize;
return true;
}
// Skip the block we just checked + the occupied one that stopped us
rbStart = rbEnd + 1;
}
return false;
}
const NR_DMRS_UplinkConfig_t *get_DMRS_UplinkConfig(const NR_PUSCH_Config_t *pusch_Config, const NR_tda_info_t *tda_info)
{
if (pusch_Config == NULL)
......
......@@ -1715,9 +1715,9 @@ static void nr_ue_max_mcs_min_rb(int mu,
int ph_limit,
NR_sched_pusch_t *sched_pusch,
NR_UE_UL_BWP_t *ul_bwp,
uint16_t minRb,
uint32_t tbs,
uint16_t *Rb,
int minRb,
int tbs,
int *Rb,
uint8_t *mcs)
{
AssertFatal(*Rb >= minRb, "illegal Rb %d < minRb %d\n", *Rb, minRb);
......@@ -1810,6 +1810,7 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
int rbStart = 0; // wrt BWP start
int rbSize = 0;
bwp_info_t bwp_info = get_pusch_bwp_start_size(UE);
const uint32_t bwpSize = bwp_info.bwpSize;
const uint32_t bwpStart = bwp_info.bwpStart;
......@@ -1827,10 +1828,9 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
if (reuse_old_tda && nrOfLayers == retInfo->nrOfLayers) {
/* Check the resource is enough for retransmission */
const uint16_t slbitmap = SL_to_bitmap(retInfo->tda_info.startSymbolIndex, retInfo->tda_info.nrOfSymbols);
while (rbStart < bwpSize && (rballoc_mask[rbStart + bwpStart] & slbitmap))
rbStart++;
if (rbStart + retInfo->rbSize > bwpSize) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate UL retransmission: no resources (rbStart %d, retInfo->rbSize %d, bwpSize %d) \n",
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",
UE->rnti,
frame,
slot,
......@@ -1845,16 +1845,6 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
NR_pusch_dmrs_t dmrs_info = get_ul_dmrs_params(scc, ul_bwp, tda_info, nrOfLayers);
/* the retransmission will use a different time domain allocation, check
* that we have enough resources */
const uint16_t slbitmap = SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols);
while (rbStart < bwpSize && (rballoc_mask[rbStart + bwpStart] & slbitmap))
rbStart++;
if (rbStart >= bwpSize) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate UL retransmission: no resources\n", UE->rnti, frame, slot);
return false;
}
int rbSize = 0;
while (rbStart + rbSize < bwpSize && !(rballoc_mask[rbStart + bwpStart + rbSize] & slbitmap))
rbSize++;
uint32_t new_tbs;
uint16_t new_rbSize;
bool success = nr_find_nb_rb(retInfo->Qm,
......@@ -1865,11 +1855,12 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
dmrs_info.N_PRB_DMRS * dmrs_info.num_dmrs_symb,
retInfo->tb_size,
1, /* minimum of 1RB: need to find exact TBS, don't preclude any number */
rbSize,
bwpSize,
&new_tbs,
&new_rbSize);
if (!success || new_tbs != retInfo->tb_size) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] allocation of UL retransmission failed: new TBsize %d of new TDA does not match old TBS %d \n",
LOG_D(NR_MAC,
"[UE %04x][%4d.%2d] allocation of UL retransmission failed: new TBsize %d of new TDA does not match old TBS %d \n",
UE->rnti,
frame,
slot,
......@@ -1877,7 +1868,19 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
retInfo->tb_size);
return false; /* the maximum TBsize we might have is smaller than what we need */
}
LOG_D(NR_MAC, "Retransmission with TDA %d->%d and TBS %d -> %d\n", retInfo->time_domain_allocation, tda, retInfo->tb_size, new_tbs);
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;
}
LOG_D(NR_MAC,
"Retransmission with TDA %d->%d and TBS %d -> %d\n",
retInfo->time_domain_allocation,
tda,
retInfo->tb_size,
new_tbs);
/* we can allocate it. Overwrite the time_domain_allocation, the number
* of RBs, and the new TB size. The rest is done below */
new_sched.rbSize = new_rbSize;
......@@ -1922,8 +1925,8 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
/* Mark the corresponding RBs as used */
n_rb_sched -= new_sched.rbSize;
for (int rb = bwpStart; rb < new_sched.rbSize; rb++)
rballoc_mask[rb + new_sched.rbStart] |= SL_to_bitmap(new_sched.tda_info.startSymbolIndex, new_sched.tda_info.nrOfSymbols);
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;
}
......@@ -2178,18 +2181,13 @@ static int pf_ul(gNB_MAC_INST *nrmac,
/* find maximum amount of RBs that we can schedule starting from first free RB */
int rbStart = 0;
int available_rb = 0;
const uint16_t slbitmap = SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols);
bwp_info_t bi = get_pusch_bwp_start_size(iterator->UE);
while (rbStart < bi.bwpSize && (rballoc_mask[rbStart + bi.bwpStart] & slbitmap))
rbStart++;
/* if it's for inactivity, min_grant_prb is enough, otherwise check what
* would be the maximum */
uint16_t max_rbSize = iterator->sched_inactive ? min_rb : bi.bwpSize;
uint16_t available_rb = 1;
while (rbStart + available_rb < bi.bwpSize && !(rballoc_mask[rbStart + bi.bwpStart + available_rb] & slbitmap) && available_rb < max_rbSize)
available_rb++;
if (rbStart + min_rb > bi.bwpSize || available_rb < min_rb) {
if (!get_rb_alloc(min_rb, max_rbSize, bi.bwpStart, bi.bwpSize, rballoc_mask, slbitmap, &rbStart, &available_rb)) {
reset_beam_status(&nrmac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, dci_beam.new_beam);
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, slots_per_frame, beam.new_beam);
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate UL data: no resources (rbStart %d, min_rb %d, bwpSize %d)\n",
......@@ -2300,8 +2298,8 @@ static int pf_ul(gNB_MAC_INST *nrmac,
post_process_ulsch(nrmac, pp_pusch, iterator->UE, &sched);
n_rb_sched[beam.idx] -= sched.rbSize;
for (int rb = bi.bwpStart; rb < sched.rbSize; rb++)
rballoc_mask[rb + sched.rbStart] |= slbitmap;
for (int rb = bi.bwpStart + sched.rbStart; rb < bi.bwpStart + sched.rbStart + sched.rbSize; rb++)
rballoc_mask[rb] |= slbitmap;
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
remainUEs[beam.idx]--;
......
......@@ -439,6 +439,27 @@ bool nr_find_nb_rb(uint16_t Qm,
uint32_t *tbs,
uint16_t *nb_rb);
/**
* \brief Function to return a free block of RBs of a required size within an BWP
* \param rbSize_min Minimum size of the free block of RBs
* \param rbSize_max Maximum size of the free block of RBs
* \param bwpStart Start RB of the BWP
* \param bwpSize Size of the BWP in RBs
* \param vrb_map Pointer to the RB allocation map
* \param sym_mask Mask indicating the symbols to be used in the block of RBs
* \param rbStart_ptr Pointer returning the start RB of the found free block
* \param rbSize_ptr Pointer returning the size of the found free block of RBs
* \return Indicates if a free block of RBs of the required size could be found and *rbStart_ptr and *rbSize_ptr are set accordingly
*/
bool get_rb_alloc(int rbSize_min,
int rbSize_max,
int bwpStart,
int bwpSize,
const uint16_t *vrb_map,
uint16_t sym_mask,
int *rbStart_ptr,
int *rbSize_ptr);
int get_mcs_from_bler(const NR_bler_options_t *bler_options,
const NR_mac_dir_stats_t *stats,
NR_bler_stats_t *bler_stats,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment