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
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user