Commit 56405aee authored by Niccolò Iardella's avatar Niccolò Iardella Committed by Robert Schmidt

Implement interslice_multiplexing, add new constants

parent e2c270ee
......@@ -68,6 +68,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
......@@ -353,7 +355,6 @@ set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP,
UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI;
break;
}
break;
case 2:
// if ((subframeP==3)||(subframeP==8))
......@@ -412,41 +413,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_I(MAC,"update dl scheduler slice %d\n", i);
LOG_I(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_I(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);
......@@ -483,7 +484,7 @@ 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_I(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: DL scheduler for this slice is updated: %s \n",
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 +492,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_I(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n",
LOG_I(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 +543,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];
}
......@@ -589,10 +593,10 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP,
UE_sched_ctrl *ue_sched_ctl;
int mcs;
int i;
int min_rb_unit[MAX_NUM_CCs];
int N_RB_DL[MAX_NUM_CCs];
int total_nb_available_rb[MAX_NUM_CCs];
int N_RBG[MAX_NUM_CCs];
int min_rb_unit[NFAPI_CC_MAX];
int N_RB_DL[NFAPI_CC_MAX];
int total_nb_available_rb[NFAPI_CC_MAX];
int N_RBG[NFAPI_CC_MAX];
nfapi_dl_config_request_body_t *dl_req;
nfapi_dl_config_request_pdu_t *dl_config_pdu;
int tdd_sfa;
......@@ -645,7 +649,7 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP,
}
//weight = get_ue_weight(module_idP,UE_id);
aggregation = 2;
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
for (CC_id = 0; CC_id < NFAPI_CC_MAX; CC_id++) {
N_RB_DL[CC_id] = to_prb(cc[CC_id].mib->message.dl_Bandwidth);
min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id);
// get number of PRBs less those used by common channels
......@@ -678,7 +682,17 @@ 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);
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
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 < NFAPI_CC_MAX; CC_id++) {
LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n", CC_id);
dl_req = &eNB->DL_req[CC_id].dl_config_request_body;
......@@ -776,7 +790,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
......@@ -1540,6 +1555,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[NFAPI_CC_MAX];
int8_t free_rbgs_map[NFAPI_CC_MAX][N_RBG_MAX];
int has_traffic[NFAPI_CC_MAX][MAX_NUM_SLICES];
uint8_t allocation_mask[NFAPI_CC_MAX][N_RBG_MAX];
uint16_t (*nb_rbs_remaining)[MAX_MOBILES_PER_ENB];
uint16_t (*nb_rbs_required)[MAX_MOBILES_PER_ENB];
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 < NFAPI_CC_MAX; ++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 < NFAPI_CC_MAX; ++CC_id) {
for (i = 0; i < n_active_slices; ++i) {
has_traffic[CC_id][i] = 0;
for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; ++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 < NFAPI_CC_MAX; ++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,
......@@ -1569,7 +1728,7 @@ fill_DLSCH_dci(module_id_t module_idP,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_IN);
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
for (CC_id = 0; CC_id < NFAPI_CC_MAX; CC_id++) {
LOG_D(MAC, "Doing fill DCI for CC_id %d\n", CC_id);
if (mbsfn_flagP[CC_id] > 0)
......@@ -1608,13 +1767,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);
}
}
}
......@@ -1643,13 +1803,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,
......@@ -1699,7 +1859,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) {
......@@ -1757,13 +1917,12 @@ set_ue_dai(sub_frame_t subframeP,
default:
UE_list->UE_template[CC_id][UE_id].DAI = 0;
LOG_I(MAC, "unknow TDD config %d\n", tdd_config);
LOG_I(MAC, "unknown TDD config %d\n", tdd_config);
break;
}
}
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;
......@@ -1799,9 +1958,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 < NFAPI_CC_MAX; 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 < MAX_MOBILES_PER_ENB; i++) {
......@@ -1812,14 +1971,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 == 0 || subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) ||
......@@ -1945,36 +2105,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);
......@@ -1985,7 +2145,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;
......@@ -2024,7 +2184,7 @@ 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
......
......@@ -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__
......@@ -1571,6 +1571,16 @@ typedef struct {
mui_t rrc_mui[128];
}mac_rlc_am_muilist_t;
/// Structure for saving the output of each pre_processor instance
typedef struct {
uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX];
uint8_t slice_allocated_rbgs[NFAPI_CC_MAX][N_RBG_MAX];
uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX];
} pre_processor_results_t;
#include "mac_proto.h"
/*@}*/
......
......@@ -226,8 +226,8 @@ void dlsch_scheduler_pre_processor_reset(module_id_t module_idP,
sub_frame_t subframeP,
int min_rb_unit[NFAPI_CC_MAX],
uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
unsigned char rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX],
unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX],
uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX],
uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][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[NFAPI_CC_MAX][N_RBG_MAX],
uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][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[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
unsigned char rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX],
uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX],
uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX],
unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]);
uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][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.
......
......@@ -61,7 +61,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
......@@ -977,7 +977,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[NFAPI_CC_MAX][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;
int N_RBG[NFAPI_CC_MAX];
......@@ -1205,13 +1205,13 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
uint8_t CC_id;
uint16_t i, j;
uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX];
uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]; // If TM5 is revisited, we can move this inside accounting
int min_rb_unit[NFAPI_CC_MAX];
uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
uint16_t (*nb_rbs_required)[MAX_MOBILES_PER_ENB] = pre_processor_results[slice_id].nb_rbs_required;
uint16_t (*nb_rbs_accounted)[MAX_MOBILES_PER_ENB] = pre_processor_results[slice_id].nb_rbs_accounted;
uint16_t (*nb_rbs_remaining)[MAX_MOBILES_PER_ENB] = 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;
......@@ -1354,8 +1354,8 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP,
sub_frame_t subframeP,
int min_rb_unit[NFAPI_CC_MAX],
uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
unsigned char rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX],
unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX],
uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX],
uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX],
int *mbsfn_flag)
{
......@@ -1579,9 +1579,9 @@ dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id,
int min_rb_unit,
uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
unsigned char rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX],
uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX],
uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX],
unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX])
uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX])
{
int i;
int tm = get_tmode(Mod_id, CC_id, UE_id);
......
......@@ -75,7 +75,7 @@ extern uint32_t timeToTrigger_ms[16];
extern float RSRP_meas_mapping[98];
extern float RSRQ_meas_mapping[35];
extern UE_PF_PO_t UE_PF_PO[MAX_NUM_CCs][MAX_MOBILES_PER_ENB];
extern UE_PF_PO_t UE_PF_PO[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
extern pthread_mutex_t ue_pf_po_mutex;
extern uint16_t reestablish_rnti_map[MAX_MOBILES_PER_ENB][2];
......
......@@ -36,7 +36,7 @@
#include "COMMON/mac_rrc_primitives.h"
#include "LAYER2/MAC/mac.h"
UE_PF_PO_t UE_PF_PO[MAX_NUM_CCs][MAX_MOBILES_PER_ENB];
UE_PF_PO_t UE_PF_PO[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB];
pthread_mutex_t ue_pf_po_mutex;
UE_RRC_INST *UE_rrc_inst;
#include "LAYER2/MAC/mac_extern.h"
......
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