Commit d794e7ed authored by Niccolò Iardella's avatar Niccolò Iardella

Implement interslice_multiplexing

parent 1d388d71
......@@ -1355,6 +1355,16 @@ typedef struct {
uint8_t n_adj_cells;
} neigh_cell_id_t;
/// Structure for saving the output of each pre_processor instance
typedef struct {
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
uint16_t nb_rbs_accounted[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
uint16_t nb_rbs_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
uint8_t slice_allocation_mask[MAX_NUM_CCs][N_RBG_MAX];
uint8_t slice_allocated_rbgs[MAX_NUM_CCs][N_RBG_MAX];
uint8_t MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX];
} pre_processor_results_t;
#include "proto.h"
/*@}*/
#endif /*__LAYER2_MAC_DEFS_H__ */
......@@ -71,6 +71,8 @@
extern RAN_CONTEXT_t RC;
extern uint8_t nfapi_mode;
extern pre_processor_results_t pre_processor_results[MAX_NUM_SLICES];
extern int slice_isolation[MAX_NUM_SLICES];
//------------------------------------------------------------------------------
void
......@@ -412,41 +414,41 @@ set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP,
//------------------------------------------------------------------------------
void
schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag)
{
schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) {
int i = 0;
slice_percentage_total=0;
slice_percentage_avg=1.0/n_active_slices;
slice_percentage_total = 0;
slice_percentage_avg = 1.0 / n_active_slices;
slice_counter = n_active_slices;
// reset the slice percentage for inactive slices
for (i = n_active_slices; i< MAX_NUM_SLICES; i++) {
slice_percentage[i]=0;
for (i = n_active_slices; i < MAX_NUM_SLICES; i++) {
slice_percentage[i] = 0;
}
for (i = 0; i < n_active_slices; i++) {
if (slice_percentage[i] < 0 ){
if (slice_percentage[i] < 0) {
LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero",
module_idP, frameP, subframeP, i, slice_percentage[i]);
slice_percentage[i]=0;
slice_percentage[i] = 0;
}
slice_percentage_total+=slice_percentage[i];
slice_percentage_total += slice_percentage[i];
}
for (i = 0; i < n_active_slices; i++) {
// Load any updated functions
if (update_dl_scheduler[i] > 0 ) {
if (update_dl_scheduler[i] > 0) {
slice_sched_dl[i] = dlsym(NULL, dl_scheduler_type[i]);
update_dl_scheduler[i] = 0 ;
update_dl_scheduler[i] = 0;
update_dl_scheduler_current[i] = 0;
LOG_N(MAC,"update dl scheduler slice %d\n", i);
LOG_N(MAC, "update dl scheduler slice %d\n", i);
}
if (slice_percentage_total <= 1.0){ // the new total RB share is within the range
if (slice_percentage_total <= 1.0) { // the new total RB share is within the range
// check if the number of slices has changed, and log
if (n_active_slices_current != n_active_slices ){
if (n_active_slices_current != n_active_slices) {
if ((n_active_slices > 0) && (n_active_slices <= MAX_NUM_SLICES)) {
LOG_N(MAC, "[eNB %d]frame %d subframe %d: number of active DL slices has changed: %d-->%d\n",
module_idP, frameP, subframeP, n_active_slices_current, n_active_slices);
......@@ -482,8 +484,8 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in
}
// check if a new scheduler, and log the console
if (update_dl_scheduler_current[i] != update_dl_scheduler[i]){
LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: DL scheduler for this slice is updated: %s \n",
if (update_dl_scheduler_current[i] != update_dl_scheduler[i]) {
LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: DL scheduler for this slice is updated: %s \n",
module_idP, i, frameP, subframeP, dl_scheduler_type[i]);
update_dl_scheduler_current[i] = update_dl_scheduler[i];
}
......@@ -491,48 +493,50 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in
} else {
// here we can correct the values, e.g. reduce proportionally
if (n_active_slices == n_active_slices_current){
LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n",
if (n_active_slices == n_active_slices_current) {
LOG_W(MAC,
"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n",
module_idP, i, slice_percentage_total_current, slice_percentage_total);
if (slice_percentage[i] >= slice_percentage_avg){
slice_percentage[i]-=0.1;
slice_percentage_total-=0.1;
if (slice_percentage[i] >= slice_percentage_avg) {
slice_percentage[i] -= 0.1;
slice_percentage_total -= 0.1;
}
} else {
LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n",
LOG_W(MAC,
"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n",
module_idP, i, slice_percentage_total_current, slice_percentage_total,
n_active_slices, n_active_slices_current );
n_active_slices, n_active_slices_current);
n_active_slices = n_active_slices_current;
slice_percentage[i] = slice_percentage_current[i];
}
}
// Check for new slice positions
if (slice_position[i*2] > slice_position[i*2 + 1] ||
slice_position[i*2] < 0 ||
slice_position[i*2 + 1] > N_RBG_MAX) {
if (slice_position[i * 2] > slice_position[i * 2 + 1] ||
slice_position[i * 2] < 0 ||
slice_position[i * 2 + 1] > N_RBG_MAX) {
LOG_W(MAC, "[eNB %d][SLICE %d][DL] invalid slicing position (%d-%d), using previous values (%d-%d)\n",
module_idP, i,
slice_position[i*2], slice_position[i*2 + 1],
slice_position_current[i*2], slice_position_current[i*2 + 1]);
slice_position[i*2] = slice_position_current[i*2];
slice_position[i*2 + 1] = slice_position_current[i*2 + 1];
slice_position[i * 2], slice_position[i * 2 + 1],
slice_position_current[i * 2], slice_position_current[i * 2 + 1]);
slice_position[i * 2] = slice_position_current[i * 2];
slice_position[i * 2 + 1] = slice_position_current[i * 2 + 1];
} else {
if (slice_position_current[i*2] != slice_position[i*2]) {
LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: start frequency has changed (%d-->%d)\n",
module_idP, i, frameP, subframeP, slice_position_current[i*2], slice_position[i*2]);
slice_position_current[i*2] = slice_position[i*2];
if (slice_position_current[i * 2] != slice_position[i * 2]) {
LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: start frequency has changed (%d-->%d)\n",
module_idP, i, frameP, subframeP, slice_position_current[i * 2], slice_position[i * 2]);
slice_position_current[i * 2] = slice_position[i * 2];
}
if (slice_position_current[i*2 + 1] != slice_position[i*2 + 1]) {
LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: end frequency has changed (%d-->%d)\n",
module_idP, i, frameP, subframeP, slice_position_current[i*2 + 1], slice_position[i*2 + 1]);
slice_position_current[i*2 + 1] = slice_position[i*2 + 1];
if (slice_position_current[i * 2 + 1] != slice_position[i * 2 + 1]) {
LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: end frequency has changed (%d-->%d)\n",
module_idP, i, frameP, subframeP, slice_position_current[i * 2 + 1], slice_position[i * 2 + 1]);
slice_position_current[i * 2 + 1] = slice_position[i * 2 + 1];
}
}
// Check for new sorting policy
if (slice_sorting_policy_current[i] != slice_sorting_policy[i]) {
LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n",
LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n",
module_idP, i, frameP, subframeP, slice_sorting_policy_current[i], slice_sorting_policy[i]);
slice_sorting_policy_current[i] = slice_sorting_policy[i];
}
......@@ -540,11 +544,12 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in
// Check for new accounting policy
if (slice_accounting_policy_current[i] != slice_accounting_policy[i]) {
if (slice_accounting_policy[i] > 1 || slice_accounting_policy[i] < 0) {
LOG_W(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: invalid accounting policy (%d), revert to its previous value (%d)\n",
LOG_W(MAC,
"[eNB %d][SLICE %d][DL] frame %d subframe %d: invalid accounting policy (%d), revert to its previous value (%d)\n",
module_idP, i, frameP, subframeP, slice_accounting_policy[i], slice_accounting_policy_current[i]);
slice_accounting_policy[i] = slice_accounting_policy_current[i];
} else {
LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n",
LOG_N(MAC, "[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n",
module_idP, i, frameP, subframeP, slice_accounting_policy_current[i], slice_accounting_policy[i]);
slice_accounting_policy_current[i] = slice_accounting_policy[i];
}
......@@ -687,6 +692,16 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT);
slice_counter--;
// Do the multiplexing and actual allocation only when all slices have been pre-processed.
if (slice_counter > 0) {
stop_meas(&eNB->schedule_dlsch);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT);
return;
}
dlsch_scheduler_interslice_multiplexing(module_idP, frameP, subframeP);
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n", CC_id);
......@@ -798,7 +813,8 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP,
if (nfapi_mode) {
eNB_UE_stats->dlsch_mcs1 = 10; // cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]];
} else { // this operation is also done in the preprocessor
eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, slice_maxmcs[slice_idP]); // cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs);
eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1,
slice_maxmcs[slice_idP]); // cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs);
}
// Store stats
......@@ -1491,6 +1507,150 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT);
}
//------------------------------------------------------------------------------
void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, int frameP, sub_frame_t subframeP)
//------------------------------------------------------------------------------
{
// FIXME: I'm prototyping the algorithm, so there may be arrays and variables that carry redundant information here and in pre_processor_results struct.
int UE_id, CC_id, rbg, i;
int N_RB_DL, min_rb_unit, tm;
int owned, used;
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
UE_sched_ctrl *ue_sched_ctl;
COMMON_channels_t *cc;
int N_RBG[MAX_NUM_CCs];
int8_t free_rbgs_map[MAX_NUM_CCs][N_RBG_MAX];
int has_traffic[MAX_NUM_CCs][MAX_NUM_SLICES];
uint8_t allocation_mask[MAX_NUM_CCs][N_RBG_MAX];
uint16_t (*nb_rbs_remaining)[NUMBER_OF_UE_MAX];
uint16_t (*nb_rbs_required)[NUMBER_OF_UE_MAX];
uint8_t (*rballoc_sub)[N_RBG_MAX];
uint8_t (*MIMO_mode_indicator)[N_RBG_MAX];
// Initialize the free RBGs map
// free_rbgs_map[CC_id][rbg] = -1 if RBG is allocated,
// otherwise it contains the id of the slice it belongs to.
// (Information about slicing must be retained to deal with isolation).
// FIXME: This method does not consider RBGs that are free and belong to no slices
for (CC_id = 0; CC_id < MAX_NUM_CCs; ++CC_id) {
cc = &RC.mac[Mod_id]->common_channels[CC_id];
N_RBG[CC_id] = to_rbg(cc->mib->message.dl_Bandwidth);
for (rbg = 0; rbg < N_RBG[CC_id]; ++rbg) {
for (i = 0; i < n_active_slices; ++i) {
owned = pre_processor_results[i].slice_allocation_mask[CC_id][rbg];
if (owned) {
used = pre_processor_results[i].slice_allocated_rbgs[CC_id][rbg];
free_rbgs_map[CC_id][rbg] = used ? -1 : i;
break;
}
}
}
}
// Find out which slices need other resources.
// FIXME: I don't think is really needed since we check nb_rbs_remaining later
for (CC_id = 0; CC_id < MAX_NUM_CCs; ++CC_id) {
for (i = 0; i < n_active_slices; ++i) {
has_traffic[CC_id][i] = 0;
for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; ++UE_id) {
if (pre_processor_results[i].nb_rbs_remaining[CC_id][UE_id] > 0) {
has_traffic[CC_id][i] = 1;
break;
}
}
}
}
// TODO: Sort slices by priority and use the sorted list in the code below (For now we assume 0 = max_priority)
// MULTIPLEXING
// This part is an adaptation of dlsch_scheduler_pre_processor_allocate() code
for (CC_id = 0; CC_id < MAX_NUM_CCs; ++CC_id) {
N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth);
min_rb_unit = get_min_rb_unit(Mod_id, CC_id);
for (i = 0; i < n_active_slices; ++i) {
if (has_traffic[CC_id][i] == 0) continue;
// Build an ad-hoc allocation mask fo the slice
for (rbg = 0; rbg < N_RBG[CC_id]; ++rbg) {
if (free_rbgs_map[CC_id][rbg] == -1) {
// RBG is already allocated
allocation_mask[CC_id][rbg] = 0;
continue;
}
if (slice_isolation[free_rbgs_map[CC_id][rbg]] == 1) {
// RBG belongs to an isolated slice
allocation_mask[CC_id][rbg] = 0;
continue;
}
// RBG is free
allocation_mask[CC_id][rbg] = 1;
}
// Sort UE again
// (UE list gets sorted every time pre_processor is called so it is probably dirty at this point)
sort_UEs(Mod_id, (slice_id_t) i, frameP, subframeP);
nb_rbs_remaining = pre_processor_results[i].nb_rbs_remaining;
nb_rbs_required = pre_processor_results[i].nb_rbs_required;
rballoc_sub = pre_processor_results[i].slice_allocated_rbgs;
MIMO_mode_indicator = pre_processor_results[i].MIMO_mode_indicator;
// Allocation
for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
tm = get_tmode(Mod_id, CC_id, UE_id);
for (rbg = 0; rbg < N_RBG[CC_id]; ++rbg) {
// FIXME: I think that some of these checks are redundant
if (allocation_mask[CC_id][rbg] == 0) continue;
if (rballoc_sub[CC_id][rbg] != 0) continue;
if (ue_sched_ctl->rballoc_sub_UE[CC_id][rbg] != 0) continue;
if (nb_rbs_remaining[CC_id][UE_id] <= 0) continue;
if (ue_sched_ctl->pre_nb_available_rbs[CC_id] >= nb_rbs_required[CC_id][UE_id]) continue;
if (ue_sched_ctl->dl_pow_off[CC_id] == 0) continue;
if ((rbg == N_RBG[CC_id] - 1) && ((N_RB_DL == 25) || (N_RB_DL == 50))) {
// Allocating last, smaller RBG
if (nb_rbs_remaining[CC_id][UE_id] >= min_rb_unit - 1) {
rballoc_sub[CC_id][rbg] = 1;
free_rbgs_map[CC_id][rbg] = -1;
ue_sched_ctl->rballoc_sub_UE[CC_id][rbg] = 1;
MIMO_mode_indicator[CC_id][rbg] = 1;
if (tm == 5) {
ue_sched_ctl->dl_pow_off[CC_id] = 1;
}
nb_rbs_remaining[CC_id][UE_id] = nb_rbs_remaining[CC_id][UE_id] - min_rb_unit + 1;
ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit - 1;
}
} else {
// Allocating a standard-sized RBG
if (nb_rbs_remaining[CC_id][UE_id] >= min_rb_unit) {
rballoc_sub[CC_id][rbg] = 1;
free_rbgs_map[CC_id][rbg] = -1;
ue_sched_ctl->rballoc_sub_UE[CC_id][rbg] = 1;
MIMO_mode_indicator[CC_id][rbg] = 1;
if (tm == 5) {
ue_sched_ctl->dl_pow_off[CC_id] = 1;
}
nb_rbs_remaining[CC_id][UE_id] = nb_rbs_remaining[CC_id][UE_id] - min_rb_unit;
ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit;
}
}
}
}
}
}
}
//------------------------------------------------------------------------------
void
fill_DLSCH_dci(module_id_t module_idP,
......@@ -1560,13 +1720,14 @@ fill_DLSCH_dci(module_id_t module_idP,
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.dci_format != 1)) {
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG,rballoc_sub);
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG,
rballoc_sub);
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.resource_allocation_type == 0)) {
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding =allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG,rballoc_sub);
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG,
rballoc_sub);
}
}
}
......@@ -1595,13 +1756,13 @@ unsigned char *get_dlsch_sdu(module_id_t module_idP,
return ((unsigned char *) &eNB->common_channels[CC_id].BCCH_pdu.payload[0]);
}
if (rntiP==P_RNTI) {
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d Get PCH sdu for PCCH \n", module_idP, CC_id, frameP);
if (rntiP == P_RNTI) {
LOG_D(MAC, "[eNB %d] CC_id %d Frame %d Get PCH sdu for PCCH \n", module_idP, CC_id, frameP);
return((unsigned char *)&eNB->common_channels[CC_id].PCCH_pdu.payload[0]);
return ((unsigned char *) &eNB->common_channels[CC_id].PCCH_pdu.payload[0]);
}
UE_id = find_UE_id(module_idP,rntiP);
UE_id = find_UE_id(module_idP, rntiP);
if (UE_id != -1) {
LOG_D(MAC,
......@@ -1651,7 +1812,7 @@ update_ul_dci(module_id_t module_idP,
void
set_ue_dai(sub_frame_t subframeP,
int UE_id, uint8_t CC_id, uint8_t tdd_config,
UE_list_t * UE_list)
UE_list_t *UE_list)
//------------------------------------------------------------------------------
{
switch (tdd_config) {
......@@ -1714,8 +1875,7 @@ set_ue_dai(sub_frame_t subframeP,
}
}
void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
{
void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) {
/* DCI:format 1A/1C P-RNTI:0xFFFE */
/* PDU:eNB_rrc_inst[Mod_idP].common_channels[CC_id].PCCH_pdu.payload */
uint16_t pcch_sdu_length;
......@@ -1751,9 +1911,9 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
start_meas(&eNB->schedule_pch);
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
cc = &eNB->common_channels[CC_id];
vrb_map = (void*)&cc->vrb_map;
vrb_map = (void *) &cc->vrb_map;
n_rb_dl = to_prb(cc->mib->message.dl_Bandwidth);
dl_req = &eNB->DL_req[CC_id].dl_config_request_body;
for (uint16_t i = 0; i < NUMBER_OF_UE_MAX; i++) {
......@@ -1764,14 +1924,15 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
pcch_sdu_length = mac_rrc_data_req(module_idP,
CC_id,
frameP,
PCCH,1,
PCCH, 1,
&cc->PCCH_pdu.payload[0],
i); // used for ue index
if (pcch_sdu_length == 0) {
LOG_D(MAC,"[eNB %d] Frame %d subframe %d: PCCH not active(size = 0 byte)\n", module_idP,frameP, subframeP);
LOG_D(MAC, "[eNB %d] Frame %d subframe %d: PCCH not active(size = 0 byte)\n", module_idP, frameP, subframeP);
continue;
}
LOG_D(MAC,"[eNB %d] Frame %d subframe %d: PCCH->PCH CC_id %d UE_id %d, Received %d bytes \n", module_idP, frameP, subframeP, CC_id,i, pcch_sdu_length);
LOG_D(MAC, "[eNB %d] Frame %d subframe %d: PCCH->PCH CC_id %d UE_id %d, Received %d bytes \n", module_idP,
frameP, subframeP, CC_id, i, pcch_sdu_length);
#ifdef FORMAT1C
//NO SIB
if ((subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) ||
......@@ -1921,36 +2082,36 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
}
vrb_map[first_rb] = 1;
vrb_map[first_rb+1] = 1;
vrb_map[first_rb+2] = 1;
vrb_map[first_rb+3] = 1;
vrb_map[first_rb + 1] = 1;
vrb_map[first_rb + 2] = 1;
vrb_map[first_rb + 3] = 1;
/* Get MCS for length of PCH */
if (pcch_sdu_length <= get_TBS_DL(0,3)) {
mcs=0;
} else if (pcch_sdu_length <= get_TBS_DL(1,3)) {
mcs=1;
} else if (pcch_sdu_length <= get_TBS_DL(2,3)) {
mcs=2;
} else if (pcch_sdu_length <= get_TBS_DL(3,3)) {
mcs=3;
} else if (pcch_sdu_length <= get_TBS_DL(4,3)) {
mcs=4;
} else if (pcch_sdu_length <= get_TBS_DL(5,3)) {
mcs=5;
} else if (pcch_sdu_length <= get_TBS_DL(6,3)) {
mcs=6;
} else if (pcch_sdu_length <= get_TBS_DL(7,3)) {
mcs=7;
} else if (pcch_sdu_length <= get_TBS_DL(8,3)) {
mcs=8;
} else if (pcch_sdu_length <= get_TBS_DL(9,3)) {
mcs=9;
if (pcch_sdu_length <= get_TBS_DL(0, 3)) {
mcs = 0;
} else if (pcch_sdu_length <= get_TBS_DL(1, 3)) {
mcs = 1;
} else if (pcch_sdu_length <= get_TBS_DL(2, 3)) {
mcs = 2;
} else if (pcch_sdu_length <= get_TBS_DL(3, 3)) {
mcs = 3;
} else if (pcch_sdu_length <= get_TBS_DL(4, 3)) {
mcs = 4;
} else if (pcch_sdu_length <= get_TBS_DL(5, 3)) {
mcs = 5;
} else if (pcch_sdu_length <= get_TBS_DL(6, 3)) {
mcs = 6;
} else if (pcch_sdu_length <= get_TBS_DL(7, 3)) {
mcs = 7;
} else if (pcch_sdu_length <= get_TBS_DL(8, 3)) {
mcs = 8;
} else if (pcch_sdu_length <= get_TBS_DL(9, 3)) {
mcs = 9;
}
#endif
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t));
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu));
dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu));
#ifdef FORMAT1C
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1C;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step);
......@@ -1961,7 +2122,7 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 1;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_rb_dl,first_rb,4);
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_rb_dl, first_rb, 4);
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0;
#endif
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4;
......@@ -1977,14 +2138,15 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF;
if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, P_RNTI)) {
LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for P_RNTI\n", frameP,subframeP);
if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP,
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, P_RNTI)) {
LOG_D(MAC, "Frame %d: Subframe %d : Adding common DCI for P_RNTI\n", frameP, subframeP);
dl_req->number_dci++;
dl_req->number_pdu++;
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t));
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu));
dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu));
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id];
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFE;
#ifdef FORMAT1C
......@@ -1992,14 +2154,14 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step);
#else
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_rb_dl,first_rb,4);
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_rb_dl, first_rb, 4);
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized
#endif
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB==1 ) ? 0 : 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ;
......@@ -2008,13 +2170,13 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB==1 ) ? 1 : 2;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ;
dl_req->number_pdu++;
eNB->TX_req[CC_id].sfn_sf = (frameP<<4)+subframeP;
eNB->TX_req[CC_id].sfn_sf = (frameP << 4) + subframeP;
TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus];
TX_req->pdu_length = pcch_sdu_length;
TX_req->pdu_index = eNB->pdu_index[CC_id]++;
......@@ -2023,7 +2185,8 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
TX_req->segments[0].segment_data = cc[CC_id].PCCH_pdu.payload;
eNB->TX_req[CC_id].tx_request_body.number_of_pdus++;
} else {
LOG_E(MAC,"[eNB %d] CCid %d Frame %d, subframe %d : Cannot add DCI 1A/1C for Paging\n",module_idP, CC_id, frameP, subframeP);
LOG_E(MAC, "[eNB %d] CCid %d Frame %d, subframe %d : Cannot add DCI 1A/1C for Paging\n", module_idP, CC_id,
frameP, subframeP);
continue;
}
......@@ -2038,15 +2201,15 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
eNB->subframe,
0,
0);
LOG_D(OPT,"[eNB %d][PCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n",
LOG_D(OPT, "[eNB %d][PCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n",
module_idP, frameP, CC_id, 0xffff, pcch_sdu_length);
}
eNB->eNB_stats[CC_id].total_num_pcch_pdu+=1;
eNB->eNB_stats[CC_id].pcch_buffer=pcch_sdu_length;
eNB->eNB_stats[CC_id].total_pcch_buffer+=pcch_sdu_length;
eNB->eNB_stats[CC_id].pcch_mcs=mcs;
eNB->eNB_stats[CC_id].total_num_pcch_pdu += 1;
eNB->eNB_stats[CC_id].pcch_buffer = pcch_sdu_length;
eNB->eNB_stats[CC_id].total_pcch_buffer += pcch_sdu_length;
eNB->eNB_stats[CC_id].pcch_mcs = mcs;
//paging first_rb log
LOG_D(MAC,"[eNB %d] Frame %d subframe %d PCH: paging_ue_index %d pcch_sdu_length %d mcs %d first_rb %d\n",
LOG_D(MAC, "[eNB %d] Frame %d subframe %d PCH: paging_ue_index %d pcch_sdu_length %d mcs %d first_rb %d\n",
module_idP, frameP, subframeP, UE_PF_PO[CC_id][i].ue_index_value, pcch_sdu_length, mcs, first_rb);
pthread_mutex_lock(&ue_pf_po_mutex);
......
......@@ -40,6 +40,7 @@
// number of active slices for past and current time
int n_active_slices = 1;
int n_active_slices_current = 1;
int slice_counter = 0;
// RB share for each slice for past and current time
float slice_percentage[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0};
......@@ -47,6 +48,7 @@ float slice_percentage_current[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0};
float slice_percentage_total = 0;
float slice_percentage_total_current = 0;
float slice_percentage_avg = 0.25;
int slice_isolation[MAX_NUM_SLICES] = {0, 0, 0, 0};
// Frequency ranges for slice positioning
int slice_position[MAX_NUM_SLICES*2] = {0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX, 0, N_RBG_MAX};
......@@ -78,4 +80,6 @@ char *dl_scheduler_type[MAX_NUM_SLICES] =
// pointer to the slice specific scheduler
slice_scheduler_dl slice_sched_dl[MAX_NUM_SLICES] = {0};
pre_processor_results_t pre_processor_results[MAX_NUM_SLICES];
#endif //__LAYER2_MAC_ENB_SCHEDULER_DLSCH_H__
......@@ -50,6 +50,7 @@
#include "RRC/LITE/extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
#include "rlc.h"
#include "defs.h"
#define DEBUG_eNB_SCHEDULER 1
......@@ -63,7 +64,7 @@ extern uint32_t slice_sorting_policy[MAX_NUM_SLICES];
extern int slice_accounting_policy[MAX_NUM_SLICES];
extern int slice_maxmcs[MAX_NUM_SLICES];
extern int slice_maxmcs_uplink[MAX_NUM_SLICES];
extern pre_processor_results_t pre_processor_results[MAX_NUM_SLICES];
//#define ICIC 0
......@@ -1007,7 +1008,7 @@ void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id,
int UE_id, CC_id;
int i;
uint8_t transmission_mode;
uint8_t slice_allocation_mask[MAX_NUM_CCs][N_RBG_MAX];
uint8_t (*slice_allocation_mask)[N_RBG_MAX] = pre_processor_results[slice_id].slice_allocation_mask;
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
decode_slice_positioning(Mod_id, slice_id, slice_allocation_mask);
......@@ -1231,11 +1232,12 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
int N_RBG[MAX_NUM_CCs];
int min_rb_unit[MAX_NUM_CCs];
uint8_t rballoc_sub[MAX_NUM_CCs][N_RBG_MAX];
uint8_t MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]; // If TM5 is revisited, we can move this inside accounting
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
uint16_t nb_rbs_accounted[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
uint16_t nb_rbs_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
uint16_t (*nb_rbs_required)[NUMBER_OF_UE_MAX] = pre_processor_results[slice_id].nb_rbs_required;
uint16_t (*nb_rbs_accounted)[NUMBER_OF_UE_MAX] = pre_processor_results[slice_id].nb_rbs_accounted;
uint16_t (*nb_rbs_remaining)[NUMBER_OF_UE_MAX] = pre_processor_results[slice_id].nb_rbs_remaining;
uint8_t (*rballoc_sub)[N_RBG_MAX] = pre_processor_results[slice_id].slice_allocated_rbgs;
uint8_t (*MIMO_mode_indicator)[N_RBG_MAX] = pre_processor_results[slice_id].MIMO_mode_indicator;
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
UE_sched_ctrl *ue_sched_ctl;
......@@ -1377,8 +1379,8 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP,
int N_RBG[MAX_NUM_CCs],
int min_rb_unit[MAX_NUM_CCs],
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX],
uint8_t rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
uint8_t MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX],
int *mbsfn_flag)
{
......@@ -1596,9 +1598,9 @@ dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id,
int min_rb_unit,
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
uint16_t nb_rbs_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
uint8_t rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
uint8_t slice_allocation_mask[MAX_NUM_CCs][N_RBG_MAX],
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]) {
uint8_t MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]) {
int i;
int tm = get_tmode(Mod_id, CC_id, UE_id);
......
......@@ -224,8 +224,8 @@ void dlsch_scheduler_pre_processor_reset(module_id_t module_idP,
int N_RBG[MAX_NUM_CCs],
int min_rb_unit[MAX_NUM_CCs],
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX],
uint8_t rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
uint8_t MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX],
int *mbsfn_flag);
void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id,
......@@ -260,6 +260,10 @@ void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id,
uint8_t rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
uint8_t MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]);
void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id,
int frameP,
sub_frame_t subframeP);
void dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id,
int UE_id,
uint8_t CC_id,
......@@ -267,9 +271,9 @@ void dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id,
int min_rb_unit,
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
uint16_t nb_rbs_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
uint8_t rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
uint8_t slice_allocation_mask[MAX_NUM_CCs][N_RBG_MAX],
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]);
uint8_t MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]);
/* \brief Function to trigger the eNB scheduling procedure. It is called by PHY at the beginning of each subframe, \f$n$\f
and generates all DLSCH allocations for subframe \f$n\f$ and ULSCH allocations for subframe \f$n+k$\f.
......
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