diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index db9ec66ef7bd90b57df6fa97be1bfc401cd89897..44083a461085eba47f90cab1727d46decfe3d0f0 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -68,18 +68,20 @@ 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 add_ue_dlsch_info(module_id_t module_idP, - int CC_id, - int UE_id, sub_frame_t subframeP, UE_DLSCH_STATUS status) + int CC_id, + int UE_id, sub_frame_t subframeP, UE_DLSCH_STATUS status) //------------------------------------------------------------------------------ { //LOG_D(MAC, "%s(module_idP:%d, CC_id:%d, UE_id:%d, subframeP:%d, status:%d) serving_num:%d rnti:%x\n", __FUNCTION__, module_idP, CC_id, UE_id, subframeP, status, eNB_dlsch_info[module_idP][CC_id][UE_id].serving_num, UE_RNTI(module_idP,UE_id)); eNB_dlsch_info[module_idP][CC_id][UE_id].rnti = - UE_RNTI(module_idP, UE_id); + UE_RNTI(module_idP, UE_id); // eNB_dlsch_info[module_idP][CC_id][ue_mod_idP].weight = weight; eNB_dlsch_info[module_idP][CC_id][UE_id].subframe = subframeP; eNB_dlsch_info[module_idP][CC_id][UE_id].status = status; @@ -91,7 +93,7 @@ add_ue_dlsch_info(module_id_t module_idP, //------------------------------------------------------------------------------ int schedule_next_dlue(module_id_t module_idP, int CC_id, - sub_frame_t subframeP) + sub_frame_t subframeP) //------------------------------------------------------------------------------ { @@ -101,7 +103,7 @@ schedule_next_dlue(module_id_t module_idP, int CC_id, for (next_ue = UE_list->head; next_ue >= 0; next_ue = UE_list->next[next_ue]) { if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == - S_DL_WAITING) { + S_DL_WAITING) { return next_ue; } } @@ -113,21 +115,21 @@ schedule_next_dlue(module_id_t module_idP, int CC_id, } } - return (-1); //next_ue; + return (-1); //next_ue; } //------------------------------------------------------------------------------ int generate_dlsch_header(unsigned char *mac_header, - unsigned char num_sdus, - unsigned short *sdu_lengths, - unsigned char *sdu_lcids, - unsigned char drx_cmd, - unsigned short timing_advance_cmd, - unsigned char *ue_cont_res_id, - unsigned char short_padding, - unsigned short post_padding) + unsigned char num_sdus, + unsigned short *sdu_lengths, + unsigned char *sdu_lcids, + unsigned char drx_cmd, + unsigned short timing_advance_cmd, + unsigned char *ue_cont_res_id, + unsigned char short_padding, + unsigned short post_padding) //------------------------------------------------------------------------------ { @@ -185,10 +187,10 @@ generate_dlsch_header(unsigned char *mac_header, // msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); ((TIMING_ADVANCE_CMD *) ce_ptr)->R = 0; AssertFatal(timing_advance_cmd < 64, - "timing_advance_cmd %d > 63\n", timing_advance_cmd); - ((TIMING_ADVANCE_CMD *) ce_ptr)->TA = timing_advance_cmd; //(timing_advance_cmd+31)&0x3f; + "timing_advance_cmd %d > 63\n", timing_advance_cmd); + ((TIMING_ADVANCE_CMD *) ce_ptr)->TA = timing_advance_cmd; //(timing_advance_cmd+31)&0x3f; LOG_D(MAC, "timing advance =%d (%d)\n", timing_advance_cmd, - ((TIMING_ADVANCE_CMD *) ce_ptr)->TA); + ((TIMING_ADVANCE_CMD *) ce_ptr)->TA); ce_ptr += sizeof(TIMING_ADVANCE_CMD); //msg("offset %d\n",ce_ptr-mac_header_control_elements); } @@ -213,9 +215,9 @@ generate_dlsch_header(unsigned char *mac_header, last_size = 1; LOG_T(MAC, - "[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n", - ue_cont_res_id[0], ue_cont_res_id[1], ue_cont_res_id[2], - ue_cont_res_id[3], ue_cont_res_id[4], ue_cont_res_id[5]); + "[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n", + ue_cont_res_id[0], ue_cont_res_id[1], ue_cont_res_id[2], + ue_cont_res_id[3], ue_cont_res_id[4], ue_cont_res_id[5]); memcpy(ce_ptr, ue_cont_res_id, 6); ce_ptr += 6; @@ -225,7 +227,7 @@ generate_dlsch_header(unsigned char *mac_header, for (i = 0; i < num_sdus; i++) { LOG_T(MAC, "[eNB] Generate DLSCH header num sdu %d len sdu %d\n", - num_sdus, sdu_lengths[i]); + num_sdus, sdu_lengths[i]); if (first_element > 0) { mac_header_ptr->E = 1; @@ -258,10 +260,10 @@ generate_dlsch_header(unsigned char *mac_header, last_size = 3; #ifdef DEBUG_HEADER_PARSING LOG_D(MAC, - "[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n", - sdu_lengths[i], - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB, - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB); + "[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n", + sdu_lengths[i], + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB, + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB); #endif } } @@ -283,7 +285,7 @@ generate_dlsch_header(unsigned char *mac_header, printf("F = 1, sdu len (L field) %d\n",(((SCH_SUBHEADER_LONG*)mac_header_ptr)->L)); } */ - if (post_padding > 0) { // we have lots of padding at the end of the packet + if (post_padding > 0) { // we have lots of padding at the end of the packet mac_header_ptr->E = 1; mac_header_ptr += last_size; // add a padding element @@ -291,7 +293,7 @@ generate_dlsch_header(unsigned char *mac_header, mac_header_ptr->E = 0; mac_header_ptr->LCID = SHORT_PADDING; mac_header_ptr++; - } else { // no end of packet padding + } else { // no end of packet padding // last SDU subhead is of fixed type (sdu length implicitly to be computed at UE) mac_header_ptr++; } @@ -301,9 +303,9 @@ generate_dlsch_header(unsigned char *mac_header, if ((ce_ptr - mac_header_control_elements) > 0) { // printf("Copying %d bytes for control elements\n",ce_ptr-mac_header_control_elements); memcpy((void *) mac_header_ptr, mac_header_control_elements, - ce_ptr - mac_header_control_elements); + ce_ptr - mac_header_control_elements); mac_header_ptr += - (unsigned char) (ce_ptr - mac_header_control_elements); + (unsigned char) (ce_ptr - mac_header_control_elements); } //msg("After CEs %d\n",(uint8_t*)mac_header_ptr - mac_header); @@ -313,7 +315,7 @@ generate_dlsch_header(unsigned char *mac_header, //------------------------------------------------------------------------------ void set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP, - int subframeP) + int subframeP) //------------------------------------------------------------------------------ { @@ -321,132 +323,131 @@ set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP, UE_list_t *UE_list = &eNB->UE_list; unsigned char DAI; COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; - if (cc->tdd_Config != NULL) { //TDD + if (cc->tdd_Config != NULL) { //TDD DAI = (UE_list->UE_template[CC_idP][UE_idP].DAI - 1) & 3; LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d, subframe %d: DAI %d for UE %d\n", - module_idP, CC_idP, frameP, subframeP, DAI, UE_idP); + "[eNB %d] CC_id %d Frame %d, subframe %d: DAI %d for UE %d\n", + module_idP, CC_idP, frameP, subframeP, DAI, UE_idP); // Save DAI for Format 0 DCI switch (cc->tdd_Config->subframeAssignment) { - case 0: - // if ((subframeP==0)||(subframeP==1)||(subframeP==5)||(subframeP==6)) - break; - - case 1: - switch (subframeP) { case 0: - case 1: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[7] = DAI; - break; - - case 4: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[8] = DAI; + // if ((subframeP==0)||(subframeP==1)||(subframeP==5)||(subframeP==6)) break; - case 5: - case 6: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; + case 1: + switch (subframeP) { + case 0: + case 1: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[7] = DAI; break; - case 9: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; - break; - } - break; + case 4: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[8] = DAI; + break; - case 2: - // if ((subframeP==3)||(subframeP==8)) - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; - break; + case 5: + case 6: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; + break; - case 3: + case 9: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; + break; + } - //if ((subframeP==6)||(subframeP==8)||(subframeP==0)) { - // LOG_D(MAC,"schedule_ue_spec: setting UL DAI to %d for subframeP %d => %d\n",DAI,subframeP, ((subframeP+8)%10)>>1); - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul[((subframeP+8)%10)>>1] = DAI; - //} - switch (subframeP) { - case 5: - case 6: - case 1: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; - break; + case 2: + // if ((subframeP==3)||(subframeP==8)) + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; + break; - case 7: - case 8: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; - break; + case 3: - case 9: - case 0: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[4] = DAI; - break; + //if ((subframeP==6)||(subframeP==8)||(subframeP==0)) { + // LOG_D(MAC,"schedule_ue_spec: setting UL DAI to %d for subframeP %d => %d\n",DAI,subframeP, ((subframeP+8)%10)>>1); + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul[((subframeP+8)%10)>>1] = DAI; + //} + switch (subframeP) { + case 5: + case 6: + case 1: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; + break; - default: - break; - } + case 7: + case 8: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; + break; - break; + case 9: + case 0: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[4] = DAI; + break; - case 4: - // if ((subframeP==8)||(subframeP==9)) - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; - break; + default: + break; + } - case 5: - // if (subframeP==8) - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; - break; + break; - case 6: - // if ((subframeP==1)||(subframeP==4)||(subframeP==6)||(subframeP==9)) - // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; - break; + case 4: + // if ((subframeP==8)||(subframeP==9)) + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; + break; - default: - break; + case 5: + // if (subframeP==8) + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; + break; + + case 6: + // if ((subframeP==1)||(subframeP==4)||(subframeP==6)||(subframeP==9)) + // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; + break; + + default: + break; } } } //------------------------------------------------------------------------------ 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,56 +484,58 @@ 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", - module_idP, i, frameP, subframeP, dl_scheduler_type[i]); - 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]; } } 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", - 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 (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; + } } 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", - module_idP, i, slice_percentage_total_current, slice_percentage_total, - n_active_slices, n_active_slices_current ); - n_active_slices = n_active_slices_current; - slice_percentage[i] = slice_percentage_current[i]; + 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; + 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,10 +1555,154 @@ 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, - frame_t frameP, sub_frame_t subframeP, int *mbsfn_flagP) + frame_t frameP, sub_frame_t subframeP, int *mbsfn_flagP) //------------------------------------------------------------------------------ { @@ -1567,9 +1726,9 @@ fill_DLSCH_dci(module_id_t module_idP, start_meas(&eNB->fill_DLSCH_dci); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_IN); + (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) @@ -1581,42 +1740,43 @@ fill_DLSCH_dci(module_id_t module_idP, // UE specific DCIs for (UE_id = UE_list->head; UE_id >= 0; - UE_id = UE_list->next[UE_id]) { + UE_id = UE_list->next[UE_id]) { LOG_T(MAC, "CC_id %d, UE_id: %d => status %d\n", CC_id, UE_id, - eNB_dlsch_info[module_idP][CC_id][UE_id].status); + eNB_dlsch_info[module_idP][CC_id][UE_id].status); if (eNB_dlsch_info[module_idP][CC_id][UE_id].status == S_DL_SCHEDULED) { - // clear scheduling flag - eNB_dlsch_info[module_idP][CC_id][UE_id].status = S_DL_WAITING; - rnti = UE_RNTI(module_idP, UE_id); + // clear scheduling flag + eNB_dlsch_info[module_idP][CC_id][UE_id].status = S_DL_WAITING; + rnti = UE_RNTI(module_idP, UE_id); harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); - nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - /// Synchronizing rballoc with rballoc_sub - for (i = 0; i < N_RBG; i++) { - rballoc_sub[i] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][i]; - } + /// Synchronizing rballoc with rballoc_sub + for (i = 0; i < N_RBG; i++) { + rballoc_sub[i] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][i]; + } - nfapi_dl_config_request_t *DL_req = &RC.mac[module_idP]->DL_req[0]; - nfapi_dl_config_request_pdu_t *dl_config_pdu; - - for (i = 0; - i < DL_req[CC_id].dl_config_request_body.number_pdu; - i++) { - dl_config_pdu = &DL_req[CC_id].dl_config_request_body.dl_config_pdu_list[i]; - 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_allocation_type = 0; - } 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); - } - } + nfapi_dl_config_request_t *DL_req = &RC.mac[module_idP]->DL_req[0]; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + + for (i = 0; + i < DL_req[CC_id].dl_config_request_body.number_pdu; + i++) { + dl_config_pdu = &DL_req[CC_id].dl_config_request_body.dl_config_pdu_list[i]; + 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_allocation_type = 0; + } 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); + } + } } } @@ -1628,8 +1788,8 @@ fill_DLSCH_dci(module_id_t module_idP, //------------------------------------------------------------------------------ unsigned char *get_dlsch_sdu(module_id_t module_idP, - int CC_id, frame_t frameP, rnti_t rntiP, - uint8_t TBindex) + int CC_id, frame_t frameP, rnti_t rntiP, + uint8_t TBindex) //------------------------------------------------------------------------------ { @@ -1638,28 +1798,28 @@ unsigned char *get_dlsch_sdu(module_id_t module_idP, if (rntiP == SI_RNTI) { LOG_D(MAC, "[eNB %d] CC_id %d Frame %d Get DLSCH sdu for BCCH \n", - module_idP, CC_id, frameP); + module_idP, CC_id, frameP); 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, - "[eNB %d] Frame %d: CC_id %d Get DLSCH sdu for rnti %x => UE_id %d\n", - module_idP, frameP, CC_id, rntiP, UE_id); + "[eNB %d] Frame %d: CC_id %d Get DLSCH sdu for rnti %x => UE_id %d\n", + module_idP, frameP, CC_id, rntiP, UE_id); return ((unsigned char *) &eNB->UE_list.DLSCH_pdu[CC_id][TBindex][UE_id].payload[0]); } else { LOG_E(MAC, - "[eNB %d] Frame %d: CC_id %d UE with RNTI %x does not exist\n", - module_idP, frameP, CC_id, rntiP); + "[eNB %d] Frame %d: CC_id %d UE with RNTI %x does not exist\n", + module_idP, frameP, CC_id, rntiP); return NULL; } @@ -1676,7 +1836,7 @@ update_ul_dci(module_id_t module_idP, nfapi_hi_dci0_request_t *HI_DCI0_req = &RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframe]; nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = - &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[0]; + &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[0]; COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_idP]; int i; @@ -1687,8 +1847,8 @@ update_ul_dci(module_id_t module_idP, i++) { if ((hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) && - (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti == rntiP)) - hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.dl_assignment_index = (daiP - 1) & 3; + (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti == rntiP)) + hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.dl_assignment_index = (daiP - 1) & 3; } } @@ -1698,84 +1858,83 @@ 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) + int UE_id, uint8_t CC_id, uint8_t tdd_config, + UE_list_t *UE_list) //------------------------------------------------------------------------------ { switch (tdd_config) { - case 0: - if ((subframeP == 0) || (subframeP == 1) || (subframeP == 3) - || (subframeP == 5) || (subframeP == 6) || (subframeP == 8)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } + case 0: + if ((subframeP == 0) || (subframeP == 1) || (subframeP == 3) + || (subframeP == 5) || (subframeP == 6) || (subframeP == 8)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } - break; + break; - case 1: - if ((subframeP == 0) || (subframeP == 4) || (subframeP == 5) - || (subframeP == 9)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } + case 1: + if ((subframeP == 0) || (subframeP == 4) || (subframeP == 5) + || (subframeP == 9)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } - break; + break; - case 2: - if ((subframeP == 4) || (subframeP == 5)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } + case 2: + if ((subframeP == 4) || (subframeP == 5)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } - break; + break; - case 3: - if ((subframeP == 5) || (subframeP == 7) || (subframeP == 9)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } + case 3: + if ((subframeP == 5) || (subframeP == 7) || (subframeP == 9)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } - break; + break; - case 4: - if ((subframeP == 0) || (subframeP == 6)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } + case 4: + if ((subframeP == 0) || (subframeP == 6)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } - break; + break; - case 5: - if (subframeP == 9) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } + case 5: + if (subframeP == 9) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } - break; + break; - case 6: - if ((subframeP == 0) || (subframeP == 1) || (subframeP == 5) - || (subframeP == 6) || (subframeP == 9)) { - UE_list->UE_template[CC_id][UE_id].DAI = 0; - } + case 6: + if ((subframeP == 0) || (subframeP == 1) || (subframeP == 5) + || (subframeP == 6) || (subframeP == 9)) { + UE_list->UE_template[CC_id][UE_id].DAI = 0; + } - break; + break; - default: - UE_list->UE_template[CC_id][UE_id].DAI = 0; - LOG_I(MAC, "unknow TDD config %d\n", tdd_config); - break; + default: + UE_list->UE_template[CC_id][UE_id].DAI = 0; + 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; - int mcs = -1; - int CC_id; - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc; - uint8_t *vrb_map; - int n_rb_dl; - int first_rb = -1; - nfapi_dl_config_request_pdu_t *dl_config_pdu; - nfapi_tx_request_pdu_t *TX_req; + uint16_t pcch_sdu_length; + int mcs = -1; + int CC_id; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc; + uint8_t *vrb_map; + int n_rb_dl; + int first_rb = -1; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + nfapi_tx_request_pdu_t *TX_req; nfapi_dl_config_request_body_t *dl_req; #ifdef FORMAT1C int gap_index = 0; /* indicate which gap(1st or 2nd) is used (0:1st) */ @@ -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++) { @@ -1809,17 +1968,18 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) continue; } if (frameP % UE_PF_PO[CC_id][i].T == UE_PF_PO[CC_id][i].PF_min && subframeP == UE_PF_PO[CC_id][i].PO) { - pcch_sdu_length = mac_rrc_data_req(module_idP, + 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); - 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); + 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); + 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); #ifdef FORMAT1C //NO SIB if ((subframeP == 0 || subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) || @@ -1944,65 +2104,65 @@ 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; - /* 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; - } + vrb_map[first_rb] = 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; + } #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)); - 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 = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + 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)); #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); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.ngap = n_gap; + 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); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.ngap = n_gap; #else - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; - 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.virtual_resource_block_assignment_flag = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; + 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.virtual_resource_block_assignment_flag = 0; #endif - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFE; // P-RNTI - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // P-RNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = 0xFFFE; // P-RNTI + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // P-RNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; - // Rel10 fields + // Rel10 fields #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; #endif - // Rel13 fields + // Rel13 fields #if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE - 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; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE + 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; #endif if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, P_RNTI)) { @@ -2020,12 +2180,12 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) 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 - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 3; // format 1C - 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); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 3; // format 1C + 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.virtual_resource_block_assignment_flag = 0; // localized + 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.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; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h index 8a5422a890e2bccfe63a411faa2a9fdda135f2ad..8bd227645cb78fe5dc8b2ad46de34dadb0d9c02d 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.h @@ -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__ diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index f8121310b1e413496d6663701662051d256f95ed..7bc73e11b9e879bb6077b166602f00846541310a 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.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" /*@}*/ diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index 23d7fb49d7aee1f1475c2793f95cd0311ab2849a..56bf7a25d42c6e72468d8011e0b6012f24905796 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/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. diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index e6bb773c86cbd7c1502ddbc496ac2c36d201054f..73f9724c8a800d6ad781bcf32b7d214fb338ee71 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -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); diff --git a/openair2/RRC/LTE/rrc_extern.h b/openair2/RRC/LTE/rrc_extern.h index 6c19fa9c7076202b934664657e2e9cc3c3c1508a..59200fb9cc4250c6e9cd13f457b779fd6ed0e757 100644 --- a/openair2/RRC/LTE/rrc_extern.h +++ b/openair2/RRC/LTE/rrc_extern.h @@ -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]; diff --git a/openair2/RRC/LTE/rrc_vars.h b/openair2/RRC/LTE/rrc_vars.h index 8a718581014a8c9d87fbf5ccffa8c76b1e7db732..028a59f7d96915928827a8c24090f40a7efc7c7a 100644 --- a/openair2/RRC/LTE/rrc_vars.h +++ b/openair2/RRC/LTE/rrc_vars.h @@ -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"