Commit eb0af3a5 authored by Robert Schmidt's avatar Robert Schmidt

Simplify DLSCH code

* do not check rlc_ind()
* Simplify retransmission part and remove nb_rb_available var
* Simplify new transmission code
* Simplify fill_DLSCH_dci(), avoid unnecessary copies
* fix: first check No. RBs, then check CCE alloc
parent eeaa5a99
...@@ -519,43 +519,25 @@ schedule_ue_spec(module_id_t module_idP, ...@@ -519,43 +519,25 @@ schedule_ue_spec(module_id_t module_idP,
sub_frame_t subframeP) sub_frame_t subframeP)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
int UE_id; int aggregation = 2;
int aggregation;
mac_rlc_status_resp_t rlc_status;
int ta_len = 0; int ta_len = 0;
unsigned char sdu_lcids[NB_RB_MAX]; unsigned char sdu_lcids[NB_RB_MAX];
int lcid, offset, num_sdus = 0;
int nb_rb, nb_rb_temp, nb_available_rb;
uint16_t sdu_lengths[NB_RB_MAX];
int TBS, j, padding = 0, post_padding = 0; int TBS, j, padding = 0, post_padding = 0;
rnti_t rnti;
unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES];
int round_DL = 0;
int harq_pid = 0;
eNB_UE_STATS *eNB_UE_stats = NULL;
UE_TEMPLATE *ue_template = NULL;
DLSCH_PDU *dlsch_pdu = NULL; DLSCH_PDU *dlsch_pdu = NULL;
int sdu_length_total = 0;
eNB_MAC_INST *eNB = RC.mac[module_idP]; eNB_MAC_INST *eNB = RC.mac[module_idP];
COMMON_channels_t *cc = eNB->common_channels; COMMON_channels_t *cc = eNB->common_channels;
UE_info_t *UE_info = &eNB->UE_info; UE_info_t *UE_info = &eNB->UE_info;
int continue_flag = 0; int continue_flag = 0;
int32_t snr, target_snr; int32_t snr, target_snr;
int tpc = 1; int tpc = 1;
UE_sched_ctrl_t *ue_sched_ctrl;
int mcs;
const int min_rb_unit = get_min_rb_unit(module_idP, CC_id);
const int dl_Bandwidth = cc[CC_id].mib->message.dl_Bandwidth; const int dl_Bandwidth = cc[CC_id].mib->message.dl_Bandwidth;
const int N_RB_DL = to_prb(dl_Bandwidth); const int N_RB_DL = to_prb(dl_Bandwidth);
const int N_RBG = to_rbg(dl_Bandwidth);
int total_nb_available_rb = N_RB_DL; int total_nb_available_rb = N_RB_DL;
nfapi_dl_config_request_body_t *dl_req; nfapi_dl_config_request_body_t *dl_req;
nfapi_dl_config_request_pdu_t *dl_config_pdu; nfapi_dl_config_request_pdu_t *dl_config_pdu;
int tdd_sfa; int tdd_sfa;
int ta_update; int ta_update;
int header_length_last;
int header_length_total;
rrc_eNB_ue_context_t *ue_contextP = NULL;
if(is_pmch_subframe(frameP,subframeP,&RC.eNB[module_idP][0]->frame_parms)){ if(is_pmch_subframe(frameP,subframeP,&RC.eNB[module_idP][0]->frame_parms)){
//LOG_E(MAC,"Frame[%d] SF:%d This SF should not be allocated\n",frameP,subframeP); //LOG_E(MAC,"Frame[%d] SF:%d This SF should not be allocated\n",frameP,subframeP);
...@@ -615,8 +597,6 @@ schedule_ue_spec(module_id_t module_idP, ...@@ -615,8 +597,6 @@ schedule_ue_spec(module_id_t module_idP,
} }
} }
aggregation = 2;
for (int i = 0; i < N_RB_DL; i++) for (int i = 0; i < N_RB_DL; i++)
if (cc[CC_id].vrb_map[i] != 0) if (cc[CC_id].vrb_map[i] != 0)
total_nb_available_rb--; total_nb_available_rb--;
...@@ -645,14 +625,16 @@ schedule_ue_spec(module_id_t module_idP, ...@@ -645,14 +625,16 @@ schedule_ue_spec(module_id_t module_idP,
CC_id); CC_id);
dl_req = &eNB->DL_req[CC_id].dl_config_request_body; dl_req = &eNB->DL_req[CC_id].dl_config_request_body;
for (UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
LOG_D(MAC, "doing schedule_ue_spec for CC_id %d UE %d\n", LOG_D(MAC, "doing schedule_ue_spec for CC_id %d UE %d\n",
CC_id, CC_id,
UE_id); UE_id);
continue_flag = 0; // reset the flag to allow allocation for the remaining UEs continue_flag = 0; // reset the flag to allow allocation for the remaining UEs
rnti = UE_RNTI(module_idP, UE_id); UE_sched_ctrl_t *ue_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
ue_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; UE_TEMPLATE *ue_template = &UE_info->UE_template[CC_id][UE_id];
ue_template = &UE_info->UE_template[CC_id][UE_id]; eNB_UE_STATS *eNB_UE_stats = &UE_info->eNB_UE_stats[CC_id][UE_id];
const rnti_t rnti = ue_template->rnti;
ue_rrc_release(rnti); ue_rrc_release(rnti);
check_ra_rnti_mui(module_idP, CC_id, frameP, subframeP, rnti); check_ra_rnti_mui(module_idP, CC_id, frameP, subframeP, rnti);
...@@ -661,13 +643,6 @@ schedule_ue_spec(module_id_t module_idP, ...@@ -661,13 +643,6 @@ schedule_ue_spec(module_id_t module_idP,
continue_flag = 1; continue_flag = 1;
} }
if (&(UE_info->eNB_UE_stats[CC_id][UE_id]) == NULL) {
LOG_D(MAC, "[eNB] Cannot find eNB_UE_stats\n");
continue_flag = 1;
} else {
eNB_UE_stats = &(UE_info->eNB_UE_stats[CC_id][UE_id]);
}
if (continue_flag != 1) { if (continue_flag != 1) {
switch (get_tmode(module_idP, switch (get_tmode(module_idP,
CC_id, CC_id,
...@@ -696,18 +671,26 @@ schedule_ue_spec(module_id_t module_idP, ...@@ -696,18 +671,26 @@ schedule_ue_spec(module_id_t module_idP,
} }
/* if (continue_flag != 1 */ /* if (continue_flag != 1 */
if (ue_sched_ctrl->pre_nb_available_rbs[CC_id] == 0 || // no RBs allocated if (ue_sched_ctrl->pre_nb_available_rbs[CC_id] == 0) { // no RBs allocated
CCE_allocation_infeasible(module_idP, LOG_D(MAC, "%d.%d: no RBs allocated for UE %d on CC_id %d\n",
frameP,
subframeP,
UE_id,
CC_id);
continue_flag = 1;
}
if (CCE_allocation_infeasible(module_idP,
CC_id, CC_id,
1, 1,
subframeP, subframeP,
aggregation, aggregation,
rnti)) { rnti)) {
LOG_D(MAC, "[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n", LOG_W(MAC, "%d.%d: Dropping Allocation for RNTI 0x%04x/UE %d\n",
module_idP,
frameP, frameP,
UE_id, subframeP,
CC_id); rnti,
UE_id);
continue_flag = 1; //to next user (there might be rbs availiable for other UEs in TM5 continue_flag = 1; //to next user (there might be rbs availiable for other UEs in TM5
} }
...@@ -736,11 +719,10 @@ schedule_ue_spec(module_id_t module_idP, ...@@ -736,11 +719,10 @@ schedule_ue_spec(module_id_t module_idP,
continue; continue;
} }
nb_available_rb = ue_sched_ctrl->pre_nb_available_rbs[CC_id]; const int harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,
harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,
frameP, frameP,
subframeP); subframeP);
round_DL = ue_sched_ctrl->round[CC_id][harq_pid]; const int round_DL = ue_sched_ctrl->round[CC_id][harq_pid];
eNB_UE_stats->crnti = rnti; eNB_UE_stats->crnti = rnti;
eNB_UE_stats->rrc_status = mac_eNB_get_rrc_status(module_idP, rnti); eNB_UE_stats->rrc_status = mac_eNB_get_rrc_status(module_idP, rnti);
eNB_UE_stats->harq_pid = harq_pid; eNB_UE_stats->harq_pid = harq_pid;
...@@ -755,29 +737,12 @@ schedule_ue_spec(module_id_t module_idP, ...@@ -755,29 +737,12 @@ schedule_ue_spec(module_id_t module_idP,
continue; continue;
} }
header_length_total = 0; //if (NFAPI_MODE != NFAPI_MONOLITHIC) {
sdu_length_total = 0; // eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[ue_sched_ctrl->dl_cqi[CC_id]];
num_sdus = 0; //} else { // this operation is also done in the preprocessor
// eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1,
/* // eNB->slice_info.dl[0/*slice_idxP*/].maxmcs); // cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs);
DevCheck(((eNB_UE_stats->dl_cqi < MIN_CQI_VALUE) || //}
(eNB_UE_stats->dl_cqi > MAX_CQI_VALUE)),
eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE);
*/
if (NFAPI_MODE != NFAPI_MONOLITHIC) {
eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[ue_sched_ctrl->dl_cqi[CC_id]];
} else { // this operation is also done in the preprocessor
eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1,
eNB->slice_info.dl[0/*slice_idxP*/].maxmcs); // cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs);
}
// Store stats
// eNB_UE_stats->dl_cqi= eNB_UE_stats->dl_cqi;
// Initializing the rb allocation indicator for each UE
for (j = 0; j < N_RBG; j++) {
ue_template->rballoc_subband[harq_pid][j] = 0;
}
LOG_D(MAC, "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n", LOG_D(MAC, "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n",
module_idP, module_idP,
...@@ -787,7 +752,7 @@ schedule_ue_spec(module_id_t module_idP, ...@@ -787,7 +752,7 @@ schedule_ue_spec(module_id_t module_idP,
rnti, rnti,
harq_pid, harq_pid,
round_DL, round_DL,
nb_available_rb, ue_sched_ctrl->pre_nb_available_rbs[CC_id],
ue_sched_ctrl->dl_cqi[CC_id], ue_sched_ctrl->dl_cqi[CC_id],
eNB_UE_stats->dlsch_mcs1, eNB_UE_stats->dlsch_mcs1,
eNB_UE_stats->rrc_status); eNB_UE_stats->rrc_status);
...@@ -795,11 +760,11 @@ schedule_ue_spec(module_id_t module_idP, ...@@ -795,11 +760,11 @@ schedule_ue_spec(module_id_t module_idP,
/* Process retransmission */ /* Process retransmission */
if (round_DL != 8) { if (round_DL != 8) {
// get freq_allocation // get freq_allocation
nb_rb = ue_template->nb_rb[harq_pid]; const int nb_rb = ue_template->nb_rb[harq_pid];
TBS = get_TBS_DL(ue_template->oldmcs1[harq_pid], TBS = get_TBS_DL(ue_template->oldmcs1[harq_pid],
nb_rb); nb_rb);
if (nb_rb <= nb_available_rb) { if (nb_rb <= ue_sched_ctrl->pre_nb_available_rbs[CC_id]) {
/* CDRX */ /* CDRX */
ue_sched_ctrl->harq_rtt_timer[CC_id][harq_pid] = 1; // restart HARQ RTT timer ue_sched_ctrl->harq_rtt_timer[CC_id][harq_pid] = 1; // restart HARQ RTT timer
...@@ -828,32 +793,6 @@ schedule_ue_spec(module_id_t module_idP, ...@@ -828,32 +793,6 @@ schedule_ue_spec(module_id_t module_idP,
ue_template->DAI); ue_template->DAI);
} }
if (nb_rb == ue_sched_ctrl->pre_nb_available_rbs[CC_id]) {
for (j = 0; j < N_RBG; j++) { // for indicating the rballoc for each sub-band
ue_template->rballoc_subband[harq_pid][j] = ue_sched_ctrl->rballoc_sub_UE[CC_id][j];
}
} else {
nb_rb_temp = nb_rb;
j = 0;
while ((nb_rb_temp > 0) && (j < N_RBG)) {
if (ue_sched_ctrl->rballoc_sub_UE[CC_id][j] == 1) {
if (ue_template->rballoc_subband[harq_pid][j])
LOG_W(MAC, "WARN: rballoc_subband not free for retrans?\n");
ue_template->rballoc_subband[harq_pid][j] = ue_sched_ctrl->rballoc_sub_UE[CC_id][j];
nb_rb_temp -= min_rb_unit;
if ((j == N_RBG - 1) && (N_RB_DL == 25 || N_RB_DL == 50))
nb_rb_temp++;
}
j++;
}
}
nb_available_rb -= nb_rb;
switch (get_tmode(module_idP, CC_id, UE_id)) { switch (get_tmode(module_idP, CC_id, UE_id)) {
case 1: case 1:
case 2: case 2:
...@@ -975,12 +914,10 @@ schedule_ue_spec(module_id_t module_idP, ...@@ -975,12 +914,10 @@ schedule_ue_spec(module_id_t module_idP,
UE_id); UE_id);
} }
} else { } else {
/* This is a potentially new SDU opportunity */
rlc_status.bytes_in_buffer = 0;
// Now check RLC information to compute number of required RBs // Now check RLC information to compute number of required RBs
// get maximum TBS size for RLC request // get maximum TBS size for RLC request
TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, /* TODO this assumes that UE is allocated continuously, can we do better? */
nb_available_rb); TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, ue_sched_ctrl->pre_nb_available_rbs[CC_id]);
// add the length for all the control elements (timing adv, drx, etc) : header + payload // add the length for all the control elements (timing adv, drx, etc) : header + payload
...@@ -1000,186 +937,53 @@ schedule_ue_spec(module_id_t module_idP, ...@@ -1000,186 +937,53 @@ schedule_ue_spec(module_id_t module_idP,
ta_len = (ta_update != 31) ? 2 : 0; ta_len = (ta_update != 31) ? 2 : 0;
// RLC data on DCCH
if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) {
rlc_status = mac_rlc_status_ind(module_idP,
rnti,
module_idP,
frameP,
subframeP,
ENB_FLAG_YES,
MBMS_FLAG_NO,
DCCH,
0,
0
);
sdu_lengths[0] = 0;
if (rlc_status.bytes_in_buffer > 0) { int num_sdus = 0;
LOG_D(MAC, "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", uint16_t sdu_lengths[NB_RB_MAX];
module_idP, int sdu_length_total = 0;
frameP, int header_length_total = 0;
subframeP, int header_length_last = 0;
CC_id, for (int i = 0; i < ue_sched_ctrl->dl_lc_num; ++i) {
TBS - ta_len - header_length_total - sdu_length_total - 3); const int lcid = ue_sched_ctrl->dl_lc_ids[i]; // will match DCCH, DCCH1, DTCH
sdu_lengths[0] = mac_rlc_data_req(module_idP,
rnti,
module_idP,
frameP,
ENB_FLAG_YES,
MBMS_FLAG_NO,
DCCH,
TBS - ta_len - header_length_total - sdu_length_total - 3,
(char *)&dlsch_buffer[0],
0,
0
);
T(T_ENB_MAC_UE_DL_SDU,
T_INT(module_idP),
T_INT(CC_id),
T_INT(rnti),
T_INT(frameP),
T_INT(subframeP),
T_INT(harq_pid),
T_INT(DCCH),
T_INT(sdu_lengths[0]));
LOG_D(MAC, "[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n",
module_idP,
CC_id,
sdu_lengths[0]);
sdu_length_total = sdu_lengths[0];
sdu_lcids[0] = DCCH;
eNB_UE_stats->lcid_sdu[0] = DCCH;
eNB_UE_stats->sdu_length_tx[DCCH] = sdu_lengths[0];
eNB_UE_stats->num_pdu_tx[DCCH] += 1;
eNB_UE_stats->num_bytes_tx[DCCH] += sdu_lengths[0];
header_length_last = 1 + 1 + (sdu_lengths[0] >= 128);
header_length_total += header_length_last;
num_sdus = 1;
#ifdef DEBUG_eNB_SCHEDULER
LOG_T(MAC, "[eNB %d][DCCH] CC_id %d Got %d bytes :",
module_idP,
CC_id,
sdu_lengths[0]);
for (j = 0; j < sdu_lengths[0]; ++j) { if (TBS - ta_len - header_length_total - sdu_length_total - 3 <= 0)
LOG_T(MAC, "%x ", break;
dlsch_buffer[j]);
}
LOG_T(MAC, "\n"); if (ue_sched_ctrl->dl_lc_bytes[i] == 0) // no data in this LC!
#endif continue;
}
}
// RLC data on DCCH1 LOG_D(MAC, "[eNB %d] SFN/SF %d.%d, LC%d->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) {
rlc_status = mac_rlc_status_ind(module_idP,
rnti,
module_idP, module_idP,
frameP, frameP,
subframeP, subframeP,
ENB_FLAG_YES, lcid,
MBMS_FLAG_NO, CC_id,
DCCH + 1,
0,
0
);
// DCCH SDU
sdu_lengths[num_sdus] = 0;
if (rlc_status.bytes_in_buffer > 0) {
LOG_D(MAC, "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
module_idP, frameP, CC_id,
TBS - ta_len - header_length_total - sdu_length_total - 3); TBS - ta_len - header_length_total - sdu_length_total - 3);
sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP,
sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
rnti, rnti,
module_idP, module_idP,
frameP, frameP,
ENB_FLAG_YES, ENB_FLAG_YES,
MBMS_FLAG_NO, DCCH + 1, MBMS_FLAG_NO,
lcid,
TBS - ta_len - header_length_total - sdu_length_total - 3, TBS - ta_len - header_length_total - sdu_length_total - 3,
(char *) &dlsch_buffer[sdu_length_total], (char *)&dlsch_buffer[sdu_length_total],
0, 0,
0 0
); );
T(T_ENB_MAC_UE_DL_SDU,
T_INT(module_idP),
T_INT(CC_id),
T_INT(rnti),
T_INT(frameP),
T_INT(subframeP),
T_INT(harq_pid),
T_INT(DCCH + 1),
T_INT(sdu_lengths[num_sdus]));
sdu_lcids[num_sdus] = DCCH1;
sdu_length_total += sdu_lengths[num_sdus];
eNB_UE_stats->lcid_sdu[num_sdus] = DCCH1;
eNB_UE_stats->sdu_length_tx[DCCH1] = sdu_lengths[num_sdus];
eNB_UE_stats->num_pdu_tx[DCCH1] += 1;
eNB_UE_stats->num_bytes_tx[DCCH1] += sdu_lengths[num_sdus];
header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128);
header_length_total += header_length_last;
num_sdus++;
#ifdef DEBUG_eNB_SCHEDULER #ifdef DEBUG_eNB_SCHEDULER
LOG_T(MAC, "[eNB %d][DCCH1] CC_id %d Got %d bytes :", LOG_T(MAC, "[eNB %d][%d] CC_id %d Got %d bytes :",
module_idP, module_idP,
lcid,
CC_id, CC_id,
sdu_lengths[num_sdus]); sdu_lengths[num_sdus]);
for (j = 0; j < sdu_lengths[num_sdus]; ++j)
for (j = 0; j < sdu_lengths[num_sdus]; ++j) { LOG_T(MAC, "%x ", dlsch_buffer[sdu_length_total+j]);
LOG_T(MAC, "%x ",
dlsch_buffer[j]);
}
LOG_T(MAC, "\n"); LOG_T(MAC, "\n");
#endif #endif
}
}
// TODO: lcid has to be sorted before the actual allocation (similar struct as ue_list).
for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) {
// TODO: check if the lcid is active
LOG_D(MAC, "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n",
module_idP,
frameP,
lcid,
TBS,
TBS - ta_len - header_length_total - sdu_length_total - 3);
if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) {
rlc_status = mac_rlc_status_ind(module_idP,
rnti,
module_idP,
frameP,
subframeP,
ENB_FLAG_YES,
MBMS_FLAG_NO,
lcid,
0,
0
);
if (rlc_status.bytes_in_buffer > 0) {
LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n",
module_idP,
frameP,
TBS - ta_len - header_length_total - sdu_length_total - 3,
lcid,
header_length_total);
sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
rnti,
module_idP,
frameP,
ENB_FLAG_YES,
MBMS_FLAG_NO,
lcid,
TBS - ta_len - header_length_total - sdu_length_total - 3,
(char *) &dlsch_buffer[sdu_length_total],
0,
0
);
T(T_ENB_MAC_UE_DL_SDU, T(T_ENB_MAC_UE_DL_SDU,
T_INT(module_idP), T_INT(module_idP),
T_INT(CC_id), T_INT(CC_id),
...@@ -1189,34 +993,32 @@ schedule_ue_spec(module_id_t module_idP, ...@@ -1189,34 +993,32 @@ schedule_ue_spec(module_id_t module_idP,
T_INT(harq_pid), T_INT(harq_pid),
T_INT(lcid), T_INT(lcid),
T_INT(sdu_lengths[num_sdus])); T_INT(sdu_lengths[num_sdus]));
LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", LOG_D(MAC, "[eNB %d][LC %d] CC_id %d Got %d bytes from RLC\n",
module_idP, module_idP,
sdu_lengths[num_sdus], lcid,
lcid); CC_id,
sdu_lengths[num_sdus]);
sdu_lcids[num_sdus] = lcid; sdu_lcids[num_sdus] = lcid;
sdu_length_total += sdu_lengths[num_sdus]; sdu_length_total += sdu_lengths[num_sdus];
eNB_UE_stats->num_pdu_tx[lcid]++; eNB_UE_stats->num_pdu_tx[lcid] += 1;
eNB_UE_stats->lcid_sdu[num_sdus] = lcid; eNB_UE_stats->lcid_sdu[num_sdus] = lcid;
eNB_UE_stats->sdu_length_tx[lcid] = sdu_lengths[num_sdus]; eNB_UE_stats->sdu_length_tx[lcid] = sdu_lengths[num_sdus];
eNB_UE_stats->num_bytes_tx[lcid] += sdu_lengths[num_sdus]; eNB_UE_stats->num_bytes_tx[lcid] += sdu_lengths[num_sdus];
header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128);
header_length_total += header_length_last; header_length_total += header_length_last;
num_sdus++; num_sdus += 1;
if (lcid >= 3) { // if this is DTCH
ue_sched_ctrl->uplane_inactivity_timer = 0; ue_sched_ctrl->uplane_inactivity_timer = 0;
// reset RRC inactivity timer after uplane activity
ue_contextP = rrc_eNB_get_ue_context(RC.rrc[module_idP], rnti);
if (ue_contextP != NULL) { // reset RRC inactivity timer after uplane activity
ue_contextP->ue_context.ue_rrc_inactivity_timer = 1; rrc_eNB_ue_context_t *ue_contextP = rrc_eNB_get_ue_context(RC.rrc[module_idP], rnti);
} else { if (ue_contextP == NULL)
LOG_E(MAC, "[eNB %d] CC_id %d Couldn't find the context associated to UE (RNTI %d) and reset RRC inactivity timer\n", LOG_E(MAC, "[eNB %d] CC_id %d Couldn't find the context associated to UE (RNTI %d) and reset RRC inactivity timer\n",
module_idP, module_idP,
CC_id, CC_id,
rnti); rnti);
} ue_contextP->ue_context.ue_rrc_inactivity_timer = 1;
} // end if (rlc_status.bytes_in_buffer > 0)
} else { // no TBS left
break; // break for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--)
} }
} }
...@@ -1227,85 +1029,31 @@ schedule_ue_spec(module_id_t module_idP, ...@@ -1227,85 +1029,31 @@ schedule_ue_spec(module_id_t module_idP,
} }
// there is at least one SDU or TA command // there is at least one SDU or TA command
// if (num_sdus > 0 ){
if (ta_len + sdu_length_total + header_length_total > 0) { if (ta_len + sdu_length_total + header_length_total > 0) {
// Now compute number of required RBs for total sdu length // Now compute number of required RBs for total sdu length
// Assume RAH format 2 // Assume RAH format 2
mcs = eNB_UE_stats->dlsch_mcs1; int mcs = eNB_UE_stats->dlsch_mcs1;
const int nb_rb = ue_sched_ctrl->pre_nb_available_rbs[CC_id];
if (mcs == 0) {
nb_rb = 4; // don't let the TBS get too small
} else {
nb_rb = min_rb_unit;
}
TBS = get_TBS_DL(mcs, nb_rb);
while (TBS < sdu_length_total + header_length_total + ta_len) {
nb_rb += min_rb_unit; //
if (nb_rb > nb_available_rb) { // if we've gone beyond the maximum number of RBs
// (can happen if N_RB_DL is odd)
TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1,
nb_available_rb);
nb_rb = nb_available_rb;
break;
}
TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1,
nb_rb);
}
if (nb_rb == ue_sched_ctrl->pre_nb_available_rbs[CC_id]) {
for (j = 0; j < N_RBG; ++j) { // for indicating the rballoc for each sub-band
ue_template->rballoc_subband[harq_pid][j] = ue_sched_ctrl->rballoc_sub_UE[CC_id][j];
}
} else {
nb_rb_temp = nb_rb;
j = 0;
while ((nb_rb_temp > 0) && (j < N_RBG)) {
if (ue_sched_ctrl->rballoc_sub_UE[CC_id][j] == 1) {
ue_template->rballoc_subband[harq_pid][j] = ue_sched_ctrl->rballoc_sub_UE[CC_id][j];
if ((j == N_RBG - 1) && ((N_RB_DL == 25) || (N_RB_DL == 50))) {
nb_rb_temp = nb_rb_temp - min_rb_unit + 1;
} else {
nb_rb_temp = nb_rb_temp - min_rb_unit;
}
}
j++;
}
}
/* TODO make special function */
// decrease mcs until TBS falls below required length // decrease mcs until TBS falls below required length
while ((TBS > sdu_length_total + header_length_total + ta_len) && (mcs > 0)) { while ((TBS > sdu_length_total + header_length_total + ta_len) && (mcs > 0)) {
mcs--; mcs--;
TBS = get_TBS_DL(mcs, TBS = get_TBS_DL(mcs, nb_rb);
nb_rb);
} }
// if we have decreased too much or we don't have enough RBs, increase MCS // if we have decreased too much or we don't have enough RBs, increase MCS
while (TBS < sdu_length_total + header_length_total + ta_len && while (TBS < sdu_length_total + header_length_total + ta_len && mcs < 28) {
((ue_sched_ctrl->dl_pow_off[CC_id] > 0 && mcs < 28) || (ue_sched_ctrl->dl_pow_off[CC_id] == 0 && mcs <= 15))) { // the second part of this condition is useless since dl_pow_off is
// always 2?
//&& ((ue_sched_ctrl->dl_pow_off[CC_id] > 0 && mcs < 28) || (ue_sched_ctrl->dl_pow_off[CC_id] == 0 && mcs <= 15))) {
mcs++; mcs++;
TBS = get_TBS_DL(mcs, TBS = get_TBS_DL(mcs,
nb_rb); nb_rb);
} }
LOG_D(MAC, "dlsch_mcs before and after the rate matching = (%d, %d)\n", LOG_D(MAC, "dlsch_mcs before and after the rate matching = (%d, %d), TBS %d, nb_rb %d\n",
eNB_UE_stats->dlsch_mcs1, eNB_UE_stats->dlsch_mcs1, mcs, TBS, nb_rb);
mcs);
#ifdef DEBUG_eNB_SCHEDULER
LOG_D(MAC, "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n",
module_idP,
CC_id,
mcs, TBS,
nb_rb);
// msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n",
// TBS, sdu_length_total, offset, TBS-sdu_length_total-offset);
#endif
if (TBS - header_length_total - sdu_length_total - ta_len <= 2) { if (TBS - header_length_total - sdu_length_total - ta_len <= 2) {
padding = TBS - header_length_total - sdu_length_total - ta_len; padding = TBS - header_length_total - sdu_length_total - ta_len;
...@@ -1315,7 +1063,7 @@ schedule_ue_spec(module_id_t module_idP, ...@@ -1315,7 +1063,7 @@ schedule_ue_spec(module_id_t module_idP,
post_padding = 1; post_padding = 1;
} }
offset = generate_dlsch_header((unsigned char *) UE_info->DLSCH_pdu[CC_id][0][UE_id].payload[0], const int offset = generate_dlsch_header((unsigned char *) UE_info->DLSCH_pdu[CC_id][0][UE_id].payload[0],
num_sdus, //num_sdus num_sdus, //num_sdus
sdu_lengths, // sdu_lengths, //
sdu_lcids, sdu_lcids,
...@@ -1360,10 +1108,7 @@ schedule_ue_spec(module_id_t module_idP, ...@@ -1360,10 +1108,7 @@ schedule_ue_spec(module_id_t module_idP,
#endif #endif
// cycle through SDUs and place in dlsch_buffer // cycle through SDUs and place in dlsch_buffer
dlsch_pdu = &UE_info->DLSCH_pdu[CC_id][0][UE_id]; dlsch_pdu = &UE_info->DLSCH_pdu[CC_id][0][UE_id];
memcpy(&dlsch_pdu->payload[0][offset], memcpy(&dlsch_pdu->payload[0][offset], dlsch_buffer, sdu_length_total);
dlsch_buffer,
sdu_length_total);
// memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]);
// fill remainder of DLSCH with 0 // fill remainder of DLSCH with 0
for (j = 0; j < (TBS - sdu_length_total - offset); j++) { for (j = 0; j < (TBS - sdu_length_total - offset); j++) {
...@@ -1592,10 +1337,10 @@ schedule_ue_spec(module_id_t module_idP, ...@@ -1592,10 +1337,10 @@ schedule_ue_spec(module_id_t module_idP,
UE_id, UE_id,
rnti); rnti);
} }
} else { // There is no data from RLC or MAC header, so don't schedule
} }
} }
/* TODO this seems to not be necessary, we already do this above */
if (cc[CC_id].tdd_Config != NULL) { // TDD if (cc[CC_id].tdd_Config != NULL) { // TDD
set_ul_DAI(module_idP, set_ul_DAI(module_idP,
UE_id, UE_id,
...@@ -1606,6 +1351,7 @@ schedule_ue_spec(module_id_t module_idP, ...@@ -1606,6 +1351,7 @@ schedule_ue_spec(module_id_t module_idP,
} // UE_id loop } // UE_id loop
fill_DLSCH_dci(module_idP, fill_DLSCH_dci(module_idP,
CC_id,
frameP, frameP,
subframeP); subframeP);
stop_meas(&eNB->schedule_dlsch); stop_meas(&eNB->schedule_dlsch);
...@@ -2297,92 +2043,56 @@ schedule_ue_spec_br(module_id_t module_idP, ...@@ -2297,92 +2043,56 @@ schedule_ue_spec_br(module_id_t module_idP,
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void
fill_DLSCH_dci(module_id_t module_idP, fill_DLSCH_dci(module_id_t module_idP,
int CC_id,
frame_t frameP, frame_t frameP,
sub_frame_t subframeP) sub_frame_t subframeP)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
// loop over all allocated UEs and compute frequency allocations for PDSCH
int UE_id = -1;
uint8_t /* first_rb, */ nb_rb = 3;
rnti_t rnti;
//unsigned char *vrb_map;
uint8_t rballoc_sub[25];
//uint8_t number_of_subbands=13;
//unsigned char round;
unsigned char harq_pid;
int i;
int CC_id;
eNB_MAC_INST *eNB = RC.mac[module_idP]; eNB_MAC_INST *eNB = RC.mac[module_idP];
UE_info_t *UE_info = &eNB->UE_info; const UE_info_t *UE_info = &eNB->UE_info;
int N_RBG; const int N_RBG = to_rbg(eNB->common_channels[CC_id].mib->message.dl_Bandwidth);
int N_RB_DL; const int N_RB_DL = to_prb(eNB->common_channels[CC_id].mib->message.dl_Bandwidth);
COMMON_channels_t *cc;
eNB_DLSCH_INFO *dlsch_info;
UE_TEMPLATE *ue_template;
start_meas(&eNB->fill_DLSCH_dci);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI,
VCD_FUNCTION_IN);
for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) {
LOG_D(MAC, "Doing fill DCI for CC_id %d\n",
CC_id);
cc = &eNB->common_channels[CC_id]; start_meas(&eNB->fill_DLSCH_dci);
N_RBG = to_rbg(cc->mib->message.dl_Bandwidth); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_IN);
N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth);
// UE specific DCIs // UE specific DCIs
for (UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
dlsch_info = &eNB_dlsch_info[module_idP][CC_id][UE_id]; eNB_DLSCH_INFO *dlsch_info = &eNB_dlsch_info[module_idP][CC_id][UE_id];
LOG_T(MAC, "CC_id %d, UE_id: %d => status %d\n", LOG_T(MAC, "CC_id %d, UE_id: %d => status %d\n", CC_id, UE_id, dlsch_info->status);
CC_id,
UE_id, if (dlsch_info->status != S_DL_SCHEDULED)
dlsch_info->status); continue;
if (dlsch_info->status == S_DL_SCHEDULED) {
// clear scheduling flag // clear scheduling flag
dlsch_info->status = S_DL_WAITING; dlsch_info->status = S_DL_WAITING;
rnti = UE_RNTI(module_idP, UE_id); const rnti_t rnti = UE_info->UE_template[CC_id][UE_id].rnti;
harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP, const UE_sched_ctrl_t *ue_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
subframeP); const int nb_rb = ue_sched_ctrl->pre_nb_available_rbs[CC_id];
ue_template = &UE_info->UE_template[CC_id][UE_id];
nb_rb = ue_template->nb_rb[harq_pid];
/// Synchronizing rballoc with rballoc_sub
for (i = 0; i < N_RBG; i++) {
rballoc_sub[i] = ue_template->rballoc_subband[harq_pid][i];
}
nfapi_dl_config_request_body_t *dl_config_request_body = &RC.mac[module_idP]->DL_req[CC_id].dl_config_request_body; nfapi_dl_config_request_body_t *dl_config_request_body = &RC.mac[module_idP]->DL_req[CC_id].dl_config_request_body;
nfapi_dl_config_request_pdu_t *dl_config_pdu; nfapi_dl_config_request_pdu_t *dl_config_pdu;
for (i = 0; i < dl_config_request_body->number_pdu; i++) { for (int i = 0; i < dl_config_request_body->number_pdu; i++) {
dl_config_pdu = &dl_config_request_body->dl_config_pdu_list[i]; dl_config_pdu = &dl_config_request_body->dl_config_pdu_list[i];
if (dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE && if (dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti && && dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format != 1) { && dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format != 1) {
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding =
N_RB_DL, allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG, ue_sched_ctrl->rballoc_sub_UE[CC_id]);
N_RBG,
rballoc_sub);
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0;
} else if (dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE && } else if (dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == rnti && && dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == rnti
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type == 0) { && dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type == 0) {
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding =
N_RB_DL, allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG, ue_sched_ctrl->rballoc_sub_UE[CC_id]);
N_RBG,
rballoc_sub);
}
}
} }
} }
} }
stop_meas(&eNB->fill_DLSCH_dci); stop_meas(&eNB->fill_DLSCH_dci);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_OUT);
VCD_FUNCTION_OUT);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
......
...@@ -2653,7 +2653,7 @@ uint32_t ...@@ -2653,7 +2653,7 @@ uint32_t
allocate_prbs_sub(int nb_rb, allocate_prbs_sub(int nb_rb,
int N_RB_DL, int N_RB_DL,
int N_RBG, int N_RBG,
uint8_t *rballoc) const uint8_t *rballoc)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
int check = 0; //check1=0,check2=0; int check = 0; //check1=0,check2=0;
......
...@@ -140,10 +140,11 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, ...@@ -140,10 +140,11 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
/** \brief Second stage of DLSCH scheduling, after schedule_SI, schedule_RA and schedule_dlsch have been called. This routine first allocates random frequency assignments for SI and RA SDUs using distributed VRB allocations and adds the corresponding DCI SDU to the DCI buffer for PHY. It then loops over the UE specific DCIs previously allocated and fills in the remaining DCI fields related to frequency allocation. It assumes localized allocation of type 0 (DCI.rah=0). The allocation is done for tranmission modes 1,2,4. /** \brief Second stage of DLSCH scheduling, after schedule_SI, schedule_RA and schedule_dlsch have been called. This routine first allocates random frequency assignments for SI and RA SDUs using distributed VRB allocations and adds the corresponding DCI SDU to the DCI buffer for PHY. It then loops over the UE specific DCIs previously allocated and fills in the remaining DCI fields related to frequency allocation. It assumes localized allocation of type 0 (DCI.rah=0). The allocation is done for tranmission modes 1,2,4.
@param Mod_id Instance of eNB @param Mod_id Instance of eNB
@param CC_id the component carrier
@param frame Frame index @param frame Frame index
@param subframe Index of subframe @param subframe Index of subframe
*/ */
void fill_DLSCH_dci(module_id_t module_idP,frame_t frameP,sub_frame_t subframe); void fill_DLSCH_dci(module_id_t module_idP, int CC_id, frame_t frameP,sub_frame_t subframe);
/** \brief UE specific DLSCH scheduling. Retrieves next ue to be schduled from round-robin scheduler and gets the appropriate harq_pid for the subframe from PHY. If the process is active and requires a retransmission, it schedules the retransmission with the same PRB count and MCS as the first transmission. Otherwise it consults RLC for DCCH/DTCH SDUs (status with maximum number of available PRBS), builds the MAC header (timing advance sent by default) and copies /** \brief UE specific DLSCH scheduling. Retrieves next ue to be schduled from round-robin scheduler and gets the appropriate harq_pid for the subframe from PHY. If the process is active and requires a retransmission, it schedules the retransmission with the same PRB count and MCS as the first transmission. Otherwise it consults RLC for DCCH/DTCH SDUs (status with maximum number of available PRBS), builds the MAC header (timing advance sent by default) and copies
@param Mod_id Instance ID of eNB @param Mod_id Instance ID of eNB
...@@ -874,8 +875,7 @@ void add_common_dci(DCI_PDU *DCI_pdu, ...@@ -874,8 +875,7 @@ void add_common_dci(DCI_PDU *DCI_pdu,
uint8_t ra_flag); uint8_t ra_flag);
*/ */
uint32_t allocate_prbs_sub(int nb_rb, int N_RB_DL, int N_RBG, uint32_t allocate_prbs_sub(int nb_rb, int N_RB_DL, int N_RBG, const uint8_t *rballoc);
uint8_t *rballoc);
void update_ul_dci(module_id_t module_idP, uint8_t CC_id, rnti_t rnti, void update_ul_dci(module_id_t module_idP, uint8_t CC_id, rnti_t rnti,
uint8_t dai, sub_frame_t subframe); uint8_t dai, sub_frame_t subframe);
......
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