Commit 68471d05 authored by Guido Casati's avatar Guido Casati Committed by Robert Schmidt

Extending DL scheduling to multiple LCIDs

parent 6fbfa3b0
......@@ -466,76 +466,49 @@ void nr_store_dlsch_buffer(module_id_t module_id,
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
sched_ctrl->num_total_bytes = 0;
sched_ctrl->dl_pdus_total = 0;
int lcid;
const uint16_t rnti = UE_info->rnti[UE_id];
LOG_D(NR_MAC,"UE %d/%x : lcid_mask %x\n",UE_id,rnti,sched_ctrl->lcid_mask);
if ((sched_ctrl->lcid_mask&(1<<2)) > 0)
sched_ctrl->rlc_status[DL_SCH_LCID_DCCH1] = mac_rlc_status_ind(module_id,
/* loop over all activated logical channels */
// Note: DL_SCH_LCID_DCCH, DL_SCH_LCID_DCCH1, DL_SCH_LCID_DTCH
for (int i = 0; i < sched_ctrl->dl_lc_num; ++i) {
const int lcid = sched_ctrl->dl_lc_ids[i];
const uint16_t rnti = UE_info->rnti[UE_id];
LOG_D(NR_MAC, "In %s: UE %d/%x: LCID %d\n", __FUNCTION__, UE_id, rnti, lcid);
start_meas(&RC.nrmac[module_id]->rlc_status_ind);
sched_ctrl->rlc_status[lcid] = mac_rlc_status_ind(module_id,
rnti,
module_id,
frame,
slot,
ENB_FLAG_YES,
MBMS_FLAG_NO,
DL_SCH_LCID_DCCH1,
0,
0);
if ((sched_ctrl->lcid_mask&(1<<1)) > 0)
sched_ctrl->rlc_status[DL_SCH_LCID_DCCH] = mac_rlc_status_ind(module_id,
rnti,
module_id,
frame,
slot,
ENB_FLAG_YES,
MBMS_FLAG_NO,
DL_SCH_LCID_DCCH,
lcid,
0,
0);
if ((sched_ctrl->lcid_mask&(1<<4)) > 0) {
start_meas(&RC.nrmac[module_id]->rlc_status_ind);
sched_ctrl->rlc_status[DL_SCH_LCID_DTCH] = mac_rlc_status_ind(module_id,
rnti,
module_id,
frame,
slot,
ENB_FLAG_YES,
MBMS_FLAG_NO,
DL_SCH_LCID_DTCH,
0,
0);
stop_meas(&RC.nrmac[module_id]->rlc_status_ind);
}
if(sched_ctrl->rlc_status[DL_SCH_LCID_DCCH].bytes_in_buffer > 0){
lcid = DL_SCH_LCID_DCCH;
}
else if (sched_ctrl->rlc_status[DL_SCH_LCID_DCCH1].bytes_in_buffer > 0)
{
lcid = DL_SCH_LCID_DCCH1;
}else{
lcid = DL_SCH_LCID_DTCH;
}
sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer;
//later multiplex here. Just select DCCH/SRB before DTCH/DRB
sched_ctrl->lcid_to_schedule = lcid;
stop_meas(&RC.nrmac[module_id]->rlc_status_ind);
if (sched_ctrl->num_total_bytes == 0
&& !sched_ctrl->ta_apply) /* If TA should be applied, give at least one RB */
continue;
if (sched_ctrl->rlc_status[lcid].bytes_in_buffer == 0)
continue;
LOG_D(NR_MAC,
"[%s][%d.%d], %s%d->DLSCH, RLC status %d bytes TA %d\n",
__func__,
frame,
slot,
lcid<4?"DCCH":"DTCH",
lcid,
sched_ctrl->rlc_status[lcid].bytes_in_buffer,
sched_ctrl->ta_apply);
sched_ctrl->dl_pdus_total += sched_ctrl->rlc_status[lcid].pdus_in_buffer;
sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer;
LOG_D(MAC,
"[gNB %d][%4d.%2d] %s%d->DLSCH, RLC status for UE %d: %d bytes in buffer, total DL buffer size = %d bytes, %d total PDU bytes, %s TA command\n",
module_id,
frame,
slot,
lcid < 4 ? "DCCH":"DTCH",
lcid,
UE_id,
sched_ctrl->rlc_status[lcid].bytes_in_buffer,
sched_ctrl->num_total_bytes,
sched_ctrl->dl_pdus_total,
sched_ctrl->ta_apply ? "send":"do not send");
}
}
}
......@@ -882,7 +855,7 @@ void pf_dl(module_id_t module_id,
sched_pdsch->pucch_allocation = alloc;
uint32_t TBS = 0;
uint16_t rbSize;
const int oh = 3 + 2 * (frame == (sched_ctrl->ta_frame + 10) % 1024);
const int oh = 3*sched_ctrl->dl_pdus_total + 2 * (frame == (sched_ctrl->ta_frame + 10) % 1024);
nr_find_nb_rb(sched_pdsch->Qm,
sched_pdsch->R,
ps->nrOfLayers,
......@@ -1326,68 +1299,70 @@ void nr_schedule_ue_spec(module_id_t module_id,
buf += written;
int size = TBS - written;
DevAssert(size >= 0);
/* next, get RLC data */
// const int lcid = DL_SCH_LCID_DTCH;
const int lcid = sched_ctrl->lcid_to_schedule;
int dlsch_total_bytes = 0;
start_meas(&gNB_mac->rlc_data_req);
if (sched_ctrl->num_total_bytes > 0) {
tbs_size_t len = 0;
while (size > 3) {
// we do not know how much data we will get from RLC, i.e., whether it
// will be longer than 256B or not. Therefore, reserve space for long header, then
// fetch data, then fill real length
NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf;
buf += 3;
size -= 3;
/* limit requested number of bytes to what preprocessor specified, or
* such that TBS is full */
const rlc_buffer_occupancy_t ndata = min(sched_ctrl->rlc_status[lcid].bytes_in_buffer, size);
len = mac_rlc_data_req(module_id,
rnti,
module_id,
frame,
ENB_FLAG_YES,
MBMS_FLAG_NO,
lcid,
ndata,
(char *)buf,
0,
0);
LOG_D(NR_MAC,
"%4d.%2d RNTI %04x: %d bytes from %s %d (ndata %d, remaining size %d)\n",
frame,
slot,
rnti,
len,
lcid < 4 ? "DCCH" : "DTCH",
lcid,
ndata,
size);
if (len == 0)
break;
header->R = 0;
header->F = 1;
header->LCID = lcid;
header->L1 = (len >> 8) & 0xff;
header->L2 = len & 0xff;
size -= len;
buf += len;
dlsch_total_bytes += len;
}
if (len == 0) {
/* RLC did not have data anymore, mark buffer as unused */
buf -= 3;
size += 3;
/* loop over all activated logical channels */
for (int i = 0; i < sched_ctrl->dl_lc_num; ++i) {
const int lcid = sched_ctrl->dl_lc_ids[i];
int dlsch_total_bytes = 0;
while (size > 3) {
// we do not know how much data we will get from RLC, i.e., whether it
// will be longer than 256B or not. Therefore, reserve space for long header, then
// fetch data, then fill real length
NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf;
buf += 3;
size -= 3;
/* limit requested number of bytes to what preprocessor specified, or
* such that TBS is full */
const rlc_buffer_occupancy_t ndata = min(sched_ctrl->rlc_status[lcid].bytes_in_buffer, size);
tbs_size_t len = mac_rlc_data_req(module_id,
rnti,
module_id,
frame,
ENB_FLAG_YES,
MBMS_FLAG_NO,
lcid,
ndata,
(char *)buf,
0,
0);
LOG_D(NR_MAC,
"%4d.%2d RNTI %04x: %d bytes from %s %d (ndata %d, remaining size %d)\n",
frame,
slot,
rnti,
len,
lcid < 4 ? "DCCH" : "DTCH",
lcid,
ndata,
size);
if (len == 0) {
/* RLC did not have data anymore, mark buffer as unused */
buf -= 3;
size += 3;
break;
}
header->R = 0;
header->F = 1;
header->LCID = lcid;
header->L1 = (len >> 8) & 0xff;
header->L2 = len & 0xff;
size -= len;
buf += len;
dlsch_total_bytes += len;
}
UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += dlsch_total_bytes;
}
}
else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra || get_softmodem_params()->sa) {
} else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra) {
/* we will need the large header, phy-test typically allocates all
* resources and fills to the last byte below */
NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf;
......@@ -1405,7 +1380,6 @@ void nr_schedule_ue_spec(module_id_t module_id,
header->L2 = size & 0xff;
size -= size;
buf += size;
dlsch_total_bytes += size;
}
stop_meas(&gNB_mac->rlc_data_req);
......@@ -1425,7 +1399,6 @@ void nr_schedule_ue_spec(module_id_t module_id,
UE_info->mac_stats[UE_id].dlsch_total_bytes += TBS;
UE_info->mac_stats[UE_id].dlsch_current_bytes = TBS;
UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += dlsch_total_bytes;
/* save retransmission information */
harq->sched_pdsch = *sched_pdsch;
......
......@@ -597,8 +597,9 @@ typedef struct {
/// total amount of data awaiting for this UE
uint32_t num_total_bytes;
uint16_t dl_pdus_total;
/// per-LC status data
mac_rlc_status_resp_t rlc_status[MAX_NUM_LCID];
mac_rlc_status_resp_t rlc_status[NR_MAX_NUM_LCID];
/// Estimation of HARQ from BLER
NR_DL_bler_stats_t dl_bler_stats;
......@@ -638,6 +639,12 @@ typedef struct {
/// UL HARQ processes that await retransmission
NR_list_t retrans_ul_harq;
NR_UE_mac_ce_ctrl_t UE_mac_ce_ctrl;// MAC CE related information
/// number of active DL LCs
uint8_t dl_lc_num;
/// order in which DLSCH scheduler should allocate LCs
uint8_t dl_lc_ids[NR_MAX_NUM_LCID];
} NR_UE_sched_ctrl_t;
typedef struct {
......
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