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

Implement interslice_multiplexing, add new constants

parent 7b4a7761
...@@ -68,18 +68,20 @@ ...@@ -68,18 +68,20 @@
extern RAN_CONTEXT_t RC; extern RAN_CONTEXT_t RC;
extern uint8_t nfapi_mode; extern uint8_t nfapi_mode;
extern pre_processor_results_t pre_processor_results[MAX_NUM_SLICES];
extern int slice_isolation[MAX_NUM_SLICES];
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void
add_ue_dlsch_info(module_id_t module_idP, add_ue_dlsch_info(module_id_t module_idP,
int CC_id, int CC_id,
int UE_id, sub_frame_t subframeP, UE_DLSCH_STATUS status) 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)); //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 = 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_mod_idP].weight = weight;
eNB_dlsch_info[module_idP][CC_id][UE_id].subframe = subframeP; eNB_dlsch_info[module_idP][CC_id][UE_id].subframe = subframeP;
eNB_dlsch_info[module_idP][CC_id][UE_id].status = status; eNB_dlsch_info[module_idP][CC_id][UE_id].status = status;
...@@ -91,7 +93,7 @@ add_ue_dlsch_info(module_id_t module_idP, ...@@ -91,7 +93,7 @@ add_ue_dlsch_info(module_id_t module_idP,
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int int
schedule_next_dlue(module_id_t module_idP, int CC_id, 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, ...@@ -101,7 +103,7 @@ schedule_next_dlue(module_id_t module_idP, int CC_id,
for (next_ue = UE_list->head; next_ue >= 0; for (next_ue = UE_list->head; next_ue >= 0;
next_ue = UE_list->next[next_ue]) { next_ue = UE_list->next[next_ue]) {
if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == if (eNB_dlsch_info[module_idP][CC_id][next_ue].status ==
S_DL_WAITING) { S_DL_WAITING) {
return next_ue; return next_ue;
} }
} }
...@@ -113,21 +115,21 @@ schedule_next_dlue(module_id_t module_idP, int CC_id, ...@@ -113,21 +115,21 @@ schedule_next_dlue(module_id_t module_idP, int CC_id,
} }
} }
return (-1); //next_ue; return (-1); //next_ue;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int int
generate_dlsch_header(unsigned char *mac_header, generate_dlsch_header(unsigned char *mac_header,
unsigned char num_sdus, unsigned char num_sdus,
unsigned short *sdu_lengths, unsigned short *sdu_lengths,
unsigned char *sdu_lcids, unsigned char *sdu_lcids,
unsigned char drx_cmd, unsigned char drx_cmd,
unsigned short timing_advance_cmd, unsigned short timing_advance_cmd,
unsigned char *ue_cont_res_id, unsigned char *ue_cont_res_id,
unsigned char short_padding, unsigned char short_padding,
unsigned short post_padding) unsigned short post_padding)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
...@@ -185,10 +187,10 @@ generate_dlsch_header(unsigned char *mac_header, ...@@ -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); // msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);
((TIMING_ADVANCE_CMD *) ce_ptr)->R = 0; ((TIMING_ADVANCE_CMD *) ce_ptr)->R = 0;
AssertFatal(timing_advance_cmd < 64, AssertFatal(timing_advance_cmd < 64,
"timing_advance_cmd %d > 63\n", timing_advance_cmd); "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 *) ce_ptr)->TA = timing_advance_cmd; //(timing_advance_cmd+31)&0x3f;
LOG_D(MAC, "timing advance =%d (%d)\n", timing_advance_cmd, 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); ce_ptr += sizeof(TIMING_ADVANCE_CMD);
//msg("offset %d\n",ce_ptr-mac_header_control_elements); //msg("offset %d\n",ce_ptr-mac_header_control_elements);
} }
...@@ -213,9 +215,9 @@ generate_dlsch_header(unsigned char *mac_header, ...@@ -213,9 +215,9 @@ generate_dlsch_header(unsigned char *mac_header,
last_size = 1; last_size = 1;
LOG_T(MAC, LOG_T(MAC,
"[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n", "[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[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]); ue_cont_res_id[3], ue_cont_res_id[4], ue_cont_res_id[5]);
memcpy(ce_ptr, ue_cont_res_id, 6); memcpy(ce_ptr, ue_cont_res_id, 6);
ce_ptr += 6; ce_ptr += 6;
...@@ -225,7 +227,7 @@ generate_dlsch_header(unsigned char *mac_header, ...@@ -225,7 +227,7 @@ generate_dlsch_header(unsigned char *mac_header,
for (i = 0; i < num_sdus; i++) { for (i = 0; i < num_sdus; i++) {
LOG_T(MAC, "[eNB] Generate DLSCH header num sdu %d len sdu %d\n", 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) { if (first_element > 0) {
mac_header_ptr->E = 1; mac_header_ptr->E = 1;
...@@ -258,10 +260,10 @@ generate_dlsch_header(unsigned char *mac_header, ...@@ -258,10 +260,10 @@ generate_dlsch_header(unsigned char *mac_header,
last_size = 3; last_size = 3;
#ifdef DEBUG_HEADER_PARSING #ifdef DEBUG_HEADER_PARSING
LOG_D(MAC, LOG_D(MAC,
"[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n", "[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n",
sdu_lengths[i], sdu_lengths[i],
((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB, ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB,
((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB); ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB);
#endif #endif
} }
} }
...@@ -283,7 +285,7 @@ generate_dlsch_header(unsigned char *mac_header, ...@@ -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)); 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->E = 1;
mac_header_ptr += last_size; mac_header_ptr += last_size;
// add a padding element // add a padding element
...@@ -291,7 +293,7 @@ generate_dlsch_header(unsigned char *mac_header, ...@@ -291,7 +293,7 @@ generate_dlsch_header(unsigned char *mac_header,
mac_header_ptr->E = 0; mac_header_ptr->E = 0;
mac_header_ptr->LCID = SHORT_PADDING; mac_header_ptr->LCID = SHORT_PADDING;
mac_header_ptr++; 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) // last SDU subhead is of fixed type (sdu length implicitly to be computed at UE)
mac_header_ptr++; mac_header_ptr++;
} }
...@@ -301,9 +303,9 @@ generate_dlsch_header(unsigned char *mac_header, ...@@ -301,9 +303,9 @@ generate_dlsch_header(unsigned char *mac_header,
if ((ce_ptr - mac_header_control_elements) > 0) { if ((ce_ptr - mac_header_control_elements) > 0) {
// printf("Copying %d bytes for control elements\n",ce_ptr-mac_header_control_elements); // printf("Copying %d bytes for control elements\n",ce_ptr-mac_header_control_elements);
memcpy((void *) mac_header_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 += 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); //msg("After CEs %d\n",(uint8_t*)mac_header_ptr - mac_header);
...@@ -313,7 +315,7 @@ generate_dlsch_header(unsigned char *mac_header, ...@@ -313,7 +315,7 @@ generate_dlsch_header(unsigned char *mac_header,
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void
set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP, 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, ...@@ -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; UE_list_t *UE_list = &eNB->UE_list;
unsigned char DAI; unsigned char DAI;
COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; 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; DAI = (UE_list->UE_template[CC_idP][UE_idP].DAI - 1) & 3;
LOG_D(MAC, LOG_D(MAC,
"[eNB %d] CC_id %d Frame %d, subframe %d: DAI %d for UE %d\n", "[eNB %d] CC_id %d Frame %d, subframe %d: DAI %d for UE %d\n",
module_idP, CC_idP, frameP, subframeP, DAI, UE_idP); module_idP, CC_idP, frameP, subframeP, DAI, UE_idP);
// Save DAI for Format 0 DCI // Save DAI for Format 0 DCI
switch (cc->tdd_Config->subframeAssignment) { switch (cc->tdd_Config->subframeAssignment) {
case 0:
// if ((subframeP==0)||(subframeP==1)||(subframeP==5)||(subframeP==6))
break;
case 1:
switch (subframeP) {
case 0: case 0:
case 1: // if ((subframeP==0)||(subframeP==1)||(subframeP==5)||(subframeP==6))
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;
break; break;
case 5: case 1:
case 6: switch (subframeP) {
UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; case 0:
case 1:
UE_list->UE_template[CC_idP][UE_idP].DAI_ul[7] = DAI;
break; break;
case 9: case 4:
UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; UE_list->UE_template[CC_idP][UE_idP].DAI_ul[8] = DAI;
break; break;
}
break;
case 2: case 5:
// if ((subframeP==3)||(subframeP==8)) case 6:
// UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI;
break; 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)) { case 2:
// LOG_D(MAC,"schedule_ue_spec: setting UL DAI to %d for subframeP %d => %d\n",DAI,subframeP, ((subframeP+8)%10)>>1); // if ((subframeP==3)||(subframeP==8))
// UE_list->UE_template[CC_idP][UE_idP].DAI_ul[((subframeP+8)%10)>>1] = DAI; // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI;
//} break;
switch (subframeP) {
case 5:
case 6:
case 1:
UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI;
break;
case 7: case 3:
case 8:
UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI;
break;
case 9: //if ((subframeP==6)||(subframeP==8)||(subframeP==0)) {
case 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[4] = DAI; // UE_list->UE_template[CC_idP][UE_idP].DAI_ul[((subframeP+8)%10)>>1] = DAI;
break; //}
switch (subframeP) {
case 5:
case 6:
case 1:
UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI;
break;
default: case 7:
break; 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: default:
// if ((subframeP==8)||(subframeP==9)) break;
// UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; }
break;
case 5: break;
// if (subframeP==8)
// UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI;
break;
case 6: case 4:
// if ((subframeP==1)||(subframeP==4)||(subframeP==6)||(subframeP==9)) // if ((subframeP==8)||(subframeP==9))
// UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI; // UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI;
break; break;
default: case 5:
break; // 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 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; int i = 0;
slice_percentage_total=0; slice_percentage_total = 0;
slice_percentage_avg=1.0/n_active_slices; slice_percentage_avg = 1.0 / n_active_slices;
slice_counter = n_active_slices;
// reset the slice percentage for inactive slices // reset the slice percentage for inactive slices
for (i = n_active_slices; i< MAX_NUM_SLICES; i++) { for (i = n_active_slices; i < MAX_NUM_SLICES; i++) {
slice_percentage[i]=0; slice_percentage[i] = 0;
} }
for (i = 0; i < n_active_slices; i++) { 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", 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]); 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++) { for (i = 0; i < n_active_slices; i++) {
// Load any updated functions // 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]); 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; 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 // 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)) { 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", 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); 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 ...@@ -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 // check if a new scheduler, and log the console
if (update_dl_scheduler_current[i] != update_dl_scheduler[i]){ 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]); module_idP, i, frameP, subframeP, dl_scheduler_type[i]);
update_dl_scheduler_current[i] = update_dl_scheduler[i]; update_dl_scheduler_current[i] = update_dl_scheduler[i];
} }
} else { } else {
// here we can correct the values, e.g. reduce proportionally // here we can correct the values, e.g. reduce proportionally
if (n_active_slices == n_active_slices_current){ 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", LOG_W(MAC,
module_idP, i, slice_percentage_total_current, slice_percentage_total); "[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n",
if (slice_percentage[i] >= slice_percentage_avg){ module_idP, i, slice_percentage_total_current, slice_percentage_total);
slice_percentage[i]-=0.1; if (slice_percentage[i] >= slice_percentage_avg) {
slice_percentage_total-=0.1; slice_percentage[i] -= 0.1;
} slice_percentage_total -= 0.1;
}
} else { } 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,
module_idP, i, slice_percentage_total_current, slice_percentage_total, "[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n",
n_active_slices, n_active_slices_current ); 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]; n_active_slices = n_active_slices_current;
slice_percentage[i] = slice_percentage_current[i];
} }
} }
// Check for new slice positions // Check for new slice positions
if (slice_position[i*2] > slice_position[i*2 + 1] || if (slice_position[i * 2] > slice_position[i * 2 + 1] ||
slice_position[i*2] < 0 || slice_position[i * 2] < 0 ||
slice_position[i*2 + 1] > N_RBG_MAX) { 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", LOG_W(MAC, "[eNB %d][SLICE %d][DL] invalid slicing position (%d-%d), using previous values (%d-%d)\n",
module_idP, i, module_idP, i,
slice_position[i*2], slice_position[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_current[i * 2], slice_position_current[i * 2 + 1]);
slice_position[i*2] = slice_position_current[i*2]; slice_position[i * 2] = slice_position_current[i * 2];
slice_position[i*2 + 1] = slice_position_current[i*2 + 1]; slice_position[i * 2 + 1] = slice_position_current[i * 2 + 1];
} else { } else {
if (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", 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]); module_idP, i, frameP, subframeP, slice_position_current[i * 2], slice_position[i * 2]);
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]) { 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", 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]); 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]; slice_position_current[i * 2 + 1] = slice_position[i * 2 + 1];
} }
} }
// Check for new sorting policy // Check for new sorting policy
if (slice_sorting_policy_current[i] != slice_sorting_policy[i]) { 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]); module_idP, i, frameP, subframeP, slice_sorting_policy_current[i], slice_sorting_policy[i]);
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 ...@@ -540,11 +543,12 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in
// Check for new accounting policy // Check for new accounting policy
if (slice_accounting_policy_current[i] != slice_accounting_policy[i]) { if (slice_accounting_policy_current[i] != slice_accounting_policy[i]) {
if (slice_accounting_policy[i] > 1 || slice_accounting_policy[i] < 0) { 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]); module_idP, i, frameP, subframeP, slice_accounting_policy[i], slice_accounting_policy_current[i]);
slice_accounting_policy[i] = slice_accounting_policy_current[i]; slice_accounting_policy[i] = slice_accounting_policy_current[i];
} else { } 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]); module_idP, i, frameP, subframeP, slice_accounting_policy_current[i], slice_accounting_policy[i]);
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, ...@@ -589,10 +593,10 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP,
UE_sched_ctrl *ue_sched_ctl; UE_sched_ctrl *ue_sched_ctl;
int mcs; int mcs;
int i; int i;
int min_rb_unit[MAX_NUM_CCs]; int min_rb_unit[NFAPI_CC_MAX];
int N_RB_DL[MAX_NUM_CCs]; int N_RB_DL[NFAPI_CC_MAX];
int total_nb_available_rb[MAX_NUM_CCs]; int total_nb_available_rb[NFAPI_CC_MAX];
int N_RBG[MAX_NUM_CCs]; int N_RBG[NFAPI_CC_MAX];
nfapi_dl_config_request_body_t *dl_req; nfapi_dl_config_request_body_t *dl_req;
nfapi_dl_config_request_pdu_t *dl_config_pdu; nfapi_dl_config_request_pdu_t *dl_config_pdu;
int tdd_sfa; int tdd_sfa;
...@@ -645,7 +649,7 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, ...@@ -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); //weight = get_ue_weight(module_idP,UE_id);
aggregation = 2; 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); 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); min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id);
// get number of PRBs less those used by common channels // 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, ...@@ -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); 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); 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; 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, ...@@ -776,7 +790,8 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP,
if (nfapi_mode) { if (nfapi_mode) {
eNB_UE_stats->dlsch_mcs1 = 10; // cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; 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 } 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 // Store stats
...@@ -1540,10 +1555,154 @@ schedule_ue_spec(module_id_t module_idP, slice_id_t slice_idP, ...@@ -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); 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 void
fill_DLSCH_dci(module_id_t module_idP, 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, ...@@ -1567,9 +1726,9 @@ fill_DLSCH_dci(module_id_t module_idP,
start_meas(&eNB->fill_DLSCH_dci); start_meas(&eNB->fill_DLSCH_dci);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME 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); LOG_D(MAC, "Doing fill DCI for CC_id %d\n", CC_id);
if (mbsfn_flagP[CC_id] > 0) if (mbsfn_flagP[CC_id] > 0)
...@@ -1581,42 +1740,43 @@ fill_DLSCH_dci(module_id_t module_idP, ...@@ -1581,42 +1740,43 @@ fill_DLSCH_dci(module_id_t module_idP,
// UE specific DCIs // UE specific DCIs
for (UE_id = UE_list->head; UE_id >= 0; 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, 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) { if (eNB_dlsch_info[module_idP][CC_id][UE_id].status == S_DL_SCHEDULED) {
// clear scheduling flag // clear scheduling flag
eNB_dlsch_info[module_idP][CC_id][UE_id].status = S_DL_WAITING; eNB_dlsch_info[module_idP][CC_id][UE_id].status = S_DL_WAITING;
rnti = UE_RNTI(module_idP, UE_id); rnti = UE_RNTI(module_idP, UE_id);
harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); 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 /// Synchronizing rballoc with rballoc_sub
for (i = 0; i < N_RBG; i++) { for (i = 0; i < N_RBG; i++) {
rballoc_sub[i] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][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_t *DL_req = &RC.mac[module_idP]->DL_req[0];
nfapi_dl_config_request_pdu_t *dl_config_pdu; nfapi_dl_config_request_pdu_t *dl_config_pdu;
for (i = 0; for (i = 0;
i < DL_req[CC_id].dl_config_request_body.number_pdu; i < DL_req[CC_id].dl_config_request_body.number_pdu;
i++) { i++) {
dl_config_pdu = &DL_req[CC_id].dl_config_request_body.dl_config_pdu_list[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) if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE)
&& (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti) && (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti)
&& (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format != 1)) { && (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format != 1)) {
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb, 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,
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0; rballoc_sub);
} else dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0;
if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) } else if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE)
&& (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == rnti) && (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == rnti)
&& (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type == 0)) { && (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type == 0)) {
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding =allocate_prbs_sub(nb_rb, 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);
} }
}
} }
} }
...@@ -1628,8 +1788,8 @@ fill_DLSCH_dci(module_id_t module_idP, ...@@ -1628,8 +1788,8 @@ fill_DLSCH_dci(module_id_t module_idP,
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
unsigned char *get_dlsch_sdu(module_id_t module_idP, unsigned char *get_dlsch_sdu(module_id_t module_idP,
int CC_id, frame_t frameP, rnti_t rntiP, int CC_id, frame_t frameP, rnti_t rntiP,
uint8_t TBindex) uint8_t TBindex)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
...@@ -1638,28 +1798,28 @@ unsigned char *get_dlsch_sdu(module_id_t module_idP, ...@@ -1638,28 +1798,28 @@ unsigned char *get_dlsch_sdu(module_id_t module_idP,
if (rntiP == SI_RNTI) { if (rntiP == SI_RNTI) {
LOG_D(MAC, "[eNB %d] CC_id %d Frame %d Get DLSCH sdu for BCCH \n", 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]); return ((unsigned char *) &eNB->common_channels[CC_id].BCCH_pdu.payload[0]);
} }
if (rntiP==P_RNTI) { 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); 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) { if (UE_id != -1) {
LOG_D(MAC, LOG_D(MAC,
"[eNB %d] Frame %d: CC_id %d Get DLSCH sdu for rnti %x => UE_id %d\n", "[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); module_idP, frameP, CC_id, rntiP, UE_id);
return ((unsigned char *) &eNB->UE_list.DLSCH_pdu[CC_id][TBindex][UE_id].payload[0]); return ((unsigned char *) &eNB->UE_list.DLSCH_pdu[CC_id][TBindex][UE_id].payload[0]);
} else { } else {
LOG_E(MAC, LOG_E(MAC,
"[eNB %d] Frame %d: CC_id %d UE with RNTI %x does not exist\n", "[eNB %d] Frame %d: CC_id %d UE with RNTI %x does not exist\n",
module_idP, frameP, CC_id, rntiP); module_idP, frameP, CC_id, rntiP);
return NULL; return NULL;
} }
...@@ -1676,7 +1836,7 @@ update_ul_dci(module_id_t module_idP, ...@@ -1676,7 +1836,7 @@ update_ul_dci(module_id_t module_idP,
nfapi_hi_dci0_request_t *HI_DCI0_req = nfapi_hi_dci0_request_t *HI_DCI0_req =
&RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframe]; &RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframe];
nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = 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]; COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_idP];
int i; int i;
...@@ -1687,8 +1847,8 @@ update_ul_dci(module_id_t module_idP, ...@@ -1687,8 +1847,8 @@ update_ul_dci(module_id_t module_idP,
i++) { i++) {
if ((hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) && 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.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.dl_assignment_index = (daiP - 1) & 3;
} }
} }
...@@ -1698,84 +1858,83 @@ update_ul_dci(module_id_t module_idP, ...@@ -1698,84 +1858,83 @@ update_ul_dci(module_id_t module_idP,
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void
set_ue_dai(sub_frame_t subframeP, set_ue_dai(sub_frame_t subframeP,
int UE_id, uint8_t CC_id, uint8_t tdd_config, int UE_id, uint8_t CC_id, uint8_t tdd_config,
UE_list_t * UE_list) UE_list_t *UE_list)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
{ {
switch (tdd_config) { switch (tdd_config) {
case 0: case 0:
if ((subframeP == 0) || (subframeP == 1) || (subframeP == 3) if ((subframeP == 0) || (subframeP == 1) || (subframeP == 3)
|| (subframeP == 5) || (subframeP == 6) || (subframeP == 8)) { || (subframeP == 5) || (subframeP == 6) || (subframeP == 8)) {
UE_list->UE_template[CC_id][UE_id].DAI = 0; UE_list->UE_template[CC_id][UE_id].DAI = 0;
} }
break; break;
case 1: case 1:
if ((subframeP == 0) || (subframeP == 4) || (subframeP == 5) if ((subframeP == 0) || (subframeP == 4) || (subframeP == 5)
|| (subframeP == 9)) { || (subframeP == 9)) {
UE_list->UE_template[CC_id][UE_id].DAI = 0; UE_list->UE_template[CC_id][UE_id].DAI = 0;
} }
break; break;
case 2: case 2:
if ((subframeP == 4) || (subframeP == 5)) { if ((subframeP == 4) || (subframeP == 5)) {
UE_list->UE_template[CC_id][UE_id].DAI = 0; UE_list->UE_template[CC_id][UE_id].DAI = 0;
} }
break; break;
case 3: case 3:
if ((subframeP == 5) || (subframeP == 7) || (subframeP == 9)) { if ((subframeP == 5) || (subframeP == 7) || (subframeP == 9)) {
UE_list->UE_template[CC_id][UE_id].DAI = 0; UE_list->UE_template[CC_id][UE_id].DAI = 0;
} }
break; break;
case 4: case 4:
if ((subframeP == 0) || (subframeP == 6)) { if ((subframeP == 0) || (subframeP == 6)) {
UE_list->UE_template[CC_id][UE_id].DAI = 0; UE_list->UE_template[CC_id][UE_id].DAI = 0;
} }
break; break;
case 5: case 5:
if (subframeP == 9) { if (subframeP == 9) {
UE_list->UE_template[CC_id][UE_id].DAI = 0; UE_list->UE_template[CC_id][UE_id].DAI = 0;
} }
break; break;
case 6: case 6:
if ((subframeP == 0) || (subframeP == 1) || (subframeP == 5) if ((subframeP == 0) || (subframeP == 1) || (subframeP == 5)
|| (subframeP == 6) || (subframeP == 9)) { || (subframeP == 6) || (subframeP == 9)) {
UE_list->UE_template[CC_id][UE_id].DAI = 0; UE_list->UE_template[CC_id][UE_id].DAI = 0;
} }
break; break;
default: default:
UE_list->UE_template[CC_id][UE_id].DAI = 0; 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; 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 */ /* DCI:format 1A/1C P-RNTI:0xFFFE */
/* PDU:eNB_rrc_inst[Mod_idP].common_channels[CC_id].PCCH_pdu.payload */ /* PDU:eNB_rrc_inst[Mod_idP].common_channels[CC_id].PCCH_pdu.payload */
uint16_t pcch_sdu_length; uint16_t pcch_sdu_length;
int mcs = -1; int mcs = -1;
int CC_id; int CC_id;
eNB_MAC_INST *eNB = RC.mac[module_idP]; eNB_MAC_INST *eNB = RC.mac[module_idP];
COMMON_channels_t *cc; COMMON_channels_t *cc;
uint8_t *vrb_map; uint8_t *vrb_map;
int n_rb_dl; int n_rb_dl;
int first_rb = -1; int first_rb = -1;
nfapi_dl_config_request_pdu_t *dl_config_pdu; nfapi_dl_config_request_pdu_t *dl_config_pdu;
nfapi_tx_request_pdu_t *TX_req; nfapi_tx_request_pdu_t *TX_req;
nfapi_dl_config_request_body_t *dl_req; nfapi_dl_config_request_body_t *dl_req;
#ifdef FORMAT1C #ifdef FORMAT1C
int gap_index = 0; /* indicate which gap(1st or 2nd) is used (0:1st) */ 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) ...@@ -1799,9 +1958,9 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
start_meas(&eNB->schedule_pch); 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]; 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); n_rb_dl = to_prb(cc->mib->message.dl_Bandwidth);
dl_req = &eNB->DL_req[CC_id].dl_config_request_body; dl_req = &eNB->DL_req[CC_id].dl_config_request_body;
for (uint16_t i = 0; i < MAX_MOBILES_PER_ENB; i++) { 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) ...@@ -1809,17 +1968,18 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
continue; 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) { 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, CC_id,
frameP, frameP,
PCCH,1, PCCH, 1,
&cc->PCCH_pdu.payload[0], &cc->PCCH_pdu.payload[0],
i); // used for ue index i); // used for ue index
if (pcch_sdu_length == 0) { 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; 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 #ifdef FORMAT1C
//NO SIB //NO SIB
if ((subframeP == 0 || subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) || 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) ...@@ -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;
vrb_map[first_rb+1] = 1; vrb_map[first_rb + 1] = 1;
vrb_map[first_rb+2] = 1; vrb_map[first_rb + 2] = 1;
vrb_map[first_rb+3] = 1; vrb_map[first_rb + 3] = 1;
/* Get MCS for length of PCH */ /* Get MCS for length of PCH */
if (pcch_sdu_length <= get_TBS_DL(0,3)) { if (pcch_sdu_length <= get_TBS_DL(0, 3)) {
mcs=0; mcs = 0;
} else if (pcch_sdu_length <= get_TBS_DL(1,3)) { } else if (pcch_sdu_length <= get_TBS_DL(1, 3)) {
mcs=1; mcs = 1;
} else if (pcch_sdu_length <= get_TBS_DL(2,3)) { } else if (pcch_sdu_length <= get_TBS_DL(2, 3)) {
mcs=2; mcs = 2;
} else if (pcch_sdu_length <= get_TBS_DL(3,3)) { } else if (pcch_sdu_length <= get_TBS_DL(3, 3)) {
mcs=3; mcs = 3;
} else if (pcch_sdu_length <= get_TBS_DL(4,3)) { } else if (pcch_sdu_length <= get_TBS_DL(4, 3)) {
mcs=4; mcs = 4;
} else if (pcch_sdu_length <= get_TBS_DL(5,3)) { } else if (pcch_sdu_length <= get_TBS_DL(5, 3)) {
mcs=5; mcs = 5;
} else if (pcch_sdu_length <= get_TBS_DL(6,3)) { } else if (pcch_sdu_length <= get_TBS_DL(6, 3)) {
mcs=6; mcs = 6;
} else if (pcch_sdu_length <= get_TBS_DL(7,3)) { } else if (pcch_sdu_length <= get_TBS_DL(7, 3)) {
mcs=7; mcs = 7;
} else if (pcch_sdu_length <= get_TBS_DL(8,3)) { } else if (pcch_sdu_length <= get_TBS_DL(8, 3)) {
mcs=8; mcs = 8;
} else if (pcch_sdu_length <= get_TBS_DL(9,3)) { } else if (pcch_sdu_length <= get_TBS_DL(9, 3)) {
mcs=9; mcs = 9;
} }
#endif #endif
dl_config_pdu = &dl_req->dl_config_pdu_list[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_DCI_DL_PDU_TYPE; 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 #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.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.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.ngap = n_gap;
#else #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.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.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.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.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.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; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0;
#endif #endif
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; 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 = 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.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.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.mcs_1 = mcs;
// Rel10 fields // Rel10 fields
#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) #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 #endif
// Rel13 fields // Rel13 fields
#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) #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.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.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.initial_transmission_sf_io = 0xFFFF;
#endif #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)) { 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) ...@@ -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.pdu_index = eNB->pdu_index[CC_id];
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFE; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFE;
#ifdef FORMAT1C #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_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_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step);
#else #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_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 dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized
#endif #endif
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK 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.redundancy_version = 1;
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
// number of active slices for past and current time // number of active slices for past and current time
int n_active_slices = 1; int n_active_slices = 1;
int n_active_slices_current = 1; int n_active_slices_current = 1;
int slice_counter = 0;
// RB share for each slice for past and current time // RB share for each slice for past and current time
float slice_percentage[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0}; 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}; ...@@ -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 = 0;
float slice_percentage_total_current = 0; float slice_percentage_total_current = 0;
float slice_percentage_avg = 0.25; float slice_percentage_avg = 0.25;
int slice_isolation[MAX_NUM_SLICES] = {0, 0, 0, 0};
// Frequency ranges for slice positioning // 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}; 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] = ...@@ -78,4 +80,6 @@ char *dl_scheduler_type[MAX_NUM_SLICES] =
// pointer to the slice specific scheduler // pointer to the slice specific scheduler
slice_scheduler_dl slice_sched_dl[MAX_NUM_SLICES] = {0}; 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__ #endif //__LAYER2_MAC_ENB_SCHEDULER_DLSCH_H__
...@@ -1571,6 +1571,16 @@ typedef struct { ...@@ -1571,6 +1571,16 @@ typedef struct {
mui_t rrc_mui[128]; mui_t rrc_mui[128];
}mac_rlc_am_muilist_t; }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" #include "mac_proto.h"
/*@}*/ /*@}*/
......
...@@ -226,8 +226,8 @@ void dlsch_scheduler_pre_processor_reset(module_id_t module_idP, ...@@ -226,8 +226,8 @@ void dlsch_scheduler_pre_processor_reset(module_id_t module_idP,
sub_frame_t subframeP, sub_frame_t subframeP,
int min_rb_unit[NFAPI_CC_MAX], int min_rb_unit[NFAPI_CC_MAX],
uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint16_t nb_rbs_required[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],
unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX], uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX],
int *mbsfn_flag); int *mbsfn_flag);
void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id, 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, ...@@ -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 rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX],
uint8_t MIMO_mode_indicator[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, void dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id,
int UE_id, int UE_id,
uint8_t CC_id, uint8_t CC_id,
...@@ -267,9 +271,9 @@ void dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, ...@@ -267,9 +271,9 @@ void dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id,
int min_rb_unit, int min_rb_unit,
uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
uint16_t nb_rbs_remaining[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], 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 /* \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. 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]; ...@@ -61,7 +61,7 @@ extern uint32_t slice_sorting_policy[MAX_NUM_SLICES];
extern int slice_accounting_policy[MAX_NUM_SLICES]; extern int slice_accounting_policy[MAX_NUM_SLICES];
extern int slice_maxmcs[MAX_NUM_SLICES]; extern int slice_maxmcs[MAX_NUM_SLICES];
extern int slice_maxmcs_uplink[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 //#define ICIC 0
...@@ -977,7 +977,7 @@ void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, ...@@ -977,7 +977,7 @@ void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id,
int UE_id, CC_id; int UE_id, CC_id;
int i; int i;
uint8_t transmission_mode; 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; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
int N_RBG[NFAPI_CC_MAX]; int N_RBG[NFAPI_CC_MAX];
...@@ -1205,13 +1205,13 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, ...@@ -1205,13 +1205,13 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id,
uint8_t CC_id; uint8_t CC_id;
uint16_t i, j; 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]; 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_required)[MAX_MOBILES_PER_ENB] = pre_processor_results[slice_id].nb_rbs_required;
uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; 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_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
UE_sched_ctrl *ue_sched_ctl; UE_sched_ctrl *ue_sched_ctl;
...@@ -1354,8 +1354,8 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, ...@@ -1354,8 +1354,8 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP,
sub_frame_t subframeP, sub_frame_t subframeP,
int min_rb_unit[NFAPI_CC_MAX], int min_rb_unit[NFAPI_CC_MAX],
uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint16_t nb_rbs_required[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],
unsigned char MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX], uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX],
int *mbsfn_flag) int *mbsfn_flag)
{ {
...@@ -1579,9 +1579,9 @@ dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, ...@@ -1579,9 +1579,9 @@ dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id,
int min_rb_unit, int min_rb_unit,
uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB],
uint16_t nb_rbs_remaining[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], 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 i;
int tm = get_tmode(Mod_id, CC_id, UE_id); int tm = get_tmode(Mod_id, CC_id, UE_id);
......
...@@ -75,7 +75,7 @@ extern uint32_t timeToTrigger_ms[16]; ...@@ -75,7 +75,7 @@ extern uint32_t timeToTrigger_ms[16];
extern float RSRP_meas_mapping[98]; extern float RSRP_meas_mapping[98];
extern float RSRQ_meas_mapping[35]; 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 pthread_mutex_t ue_pf_po_mutex;
extern uint16_t reestablish_rnti_map[MAX_MOBILES_PER_ENB][2]; extern uint16_t reestablish_rnti_map[MAX_MOBILES_PER_ENB][2];
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
#include "COMMON/mac_rrc_primitives.h" #include "COMMON/mac_rrc_primitives.h"
#include "LAYER2/MAC/mac.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; pthread_mutex_t ue_pf_po_mutex;
UE_RRC_INST *UE_rrc_inst; UE_RRC_INST *UE_rrc_inst;
#include "LAYER2/MAC/mac_extern.h" #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