pre_processor.c 26 KB
Newer Older
1
/*******************************************************************************
2 3
    OpenAirInterface
    Copyright(c) 1999 - 2014 Eurecom
4

5 6 7 8
    OpenAirInterface is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
9 10


11 12 13 14
    OpenAirInterface is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
15

16 17 18 19
    You should have received a copy of the GNU General Public License
    along with OpenAirInterface.The full GNU General Public License is
    included in this distribution in the file called "COPYING". If not,
    see <http://www.gnu.org/licenses/>.
20 21

  Contact Information
22 23 24 25 26
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
  OpenAirInterface Dev  : openair4g-devel@eurecom.fr

  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
27

28
*******************************************************************************/
29
/*! \file pre_processor.c
30
 * \brief eNB scheduler preprocessing fuction prior to scheduling 
31
 * \author Navid Nikaein and Ankit Bhamri
32
 * \date 2013 - 2014
33
 * \email navid.nikaein@eurecom.fr
34
 * \version 1.0
35 36 37 38
 * @ingroup _mac

 */

39
#include "assertions.h"
40 41 42 43 44 45 46
#include "PHY/defs.h"
#include "PHY/extern.h"

#include "SCHED/defs.h"
#include "SCHED/extern.h"

#include "LAYER2/MAC/defs.h"
47
#include "LAYER2/MAC/proto.h"
48 49 50 51 52 53 54 55 56
#include "LAYER2/MAC/extern.h"
#include "UTIL/LOG/log.h"
#include "UTIL/OPT/opt.h"
#include "OCG.h"
#include "OCG_extern.h"
#include "RRC/LITE/extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"


57

58 59 60 61 62 63 64 65 66 67
#define DEBUG_eNB_SCHEDULER 1
#define DEBUG_HEADER_PARSING 1
//#define DEBUG_PACKET_TRACE 1

//#define ICIC 0

/*
  #ifndef USER_MODE
  #define msg debug_msg
  #endif
Raymond Knopp's avatar
 
Raymond Knopp committed
68
*/
69 70 71 72 73

extern inline unsigned int taus(void);


// This function stores the downlink buffer for all the logical channels 
74 75 76
void store_dlsch_buffer (module_id_t Mod_id,
                         frame_t     frameP,
                         sub_frame_t subframeP){
Cedric Roux's avatar
Cedric Roux committed
77

Raymond Knopp's avatar
 
Raymond Knopp committed
78
  int                   UE_id,i;
79
  rnti_t                rnti;
80
  mac_rlc_status_resp_t rlc_status;
Raymond Knopp's avatar
 
Raymond Knopp committed
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
  UE_list_t             *UE_list = &eNB_mac_inst[Mod_id].UE_list;
  UE_TEMPLATE           *UE_template;

  for (UE_id=UE_list->head;UE_id>=0;UE_id=UE_list->next[UE_id]){

    UE_template = &UE_list->UE_template[UE_PCCID(Mod_id,UE_id)][UE_id];
    
  // clear logical channel interface variables
    UE_template->dl_buffer_total = 0;
    UE_template->dl_pdus_total = 0;
    for(i=0;i< MAX_NUM_LCID; i++) {
      UE_template->dl_buffer_info[i]=0;
      UE_template->dl_pdus_in_buffer[i]=0;
      UE_template->dl_buffer_head_sdu_creation_time[i]=0;
      UE_template->dl_buffer_head_sdu_remaining_size_to_send[i]=0;
    }
 
    rnti = UE_RNTI(Mod_id,UE_id);
      
    for(i=0;i< MAX_NUM_LCID; i++){ // loop over all the logical channels
      
      rlc_status = mac_rlc_status_ind(Mod_id,UE_id, frameP,ENB_FLAG_YES,MBMS_FLAG_NO,i,0 );
      UE_template->dl_buffer_info[i] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel
      UE_template->dl_pdus_in_buffer[i] = rlc_status.pdus_in_buffer;
      UE_template->dl_buffer_head_sdu_creation_time[i] = rlc_status.head_sdu_creation_time ;
106 107
      UE_template->dl_buffer_head_sdu_creation_time_max = cmax(UE_template->dl_buffer_head_sdu_creation_time_max, 
							       rlc_status.head_sdu_creation_time );
Raymond Knopp's avatar
 
Raymond Knopp committed
108 109
      UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = rlc_status.head_sdu_remaining_size_to_send;
      UE_template->dl_buffer_head_sdu_is_segmented[i] = rlc_status.head_sdu_is_segmented;
110 111
      UE_template->dl_buffer_total += UE_template->dl_buffer_info[i];//storing the total dlsch buffer
      UE_template->dl_pdus_total   += UE_template->dl_pdus_in_buffer[i];
Raymond Knopp's avatar
 
Raymond Knopp committed
112
      
Cedric Roux's avatar
Cedric Roux committed
113
#ifdef DEBUG_eNB_SCHEDULER
Raymond Knopp's avatar
 
Raymond Knopp committed
114 115 116 117 118 119 120 121 122 123 124
      /* note for dl_buffer_head_sdu_remaining_size_to_send[i] :
       * 0 if head SDU has not been segmented (yet), else remaining size not already segmented and sent
       */
      if (UE_template->dl_buffer_info[i]>0)
	LOG_D(MAC,"[eNB %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and size %d, head sdu queuing time %d, remaining size %d, is segmeneted %d \n",
	      Mod_id, frameP, subframeP, UE_id,
	      i, UE_template->dl_pdus_in_buffer[i],UE_template->dl_buffer_info[i],
	      UE_template->dl_buffer_head_sdu_creation_time[i],
	      UE_template->dl_buffer_head_sdu_remaining_size_to_send[i],
	      UE_template->dl_buffer_head_sdu_is_segmented[i]
	      );
Cedric Roux's avatar
Cedric Roux committed
125
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
126 127
      
    }
128
    //#ifdef DEBUG_eNB_SCHEDULER
Raymond Knopp's avatar
 
Raymond Knopp committed
129 130 131 132 133 134
    if ( UE_template->dl_buffer_total>0)
      LOG_D(MAC,"[eNB %d] Frame %d Subframe %d : RLC status for UE %d : total DL buffer size %d and total number of pdu %d \n",
	    Mod_id, frameP, subframeP, UE_id,
	    UE_template->dl_buffer_total,
	    UE_template->dl_pdus_total
	    );
135
    //#endif   
136 137 138
  }
}

139
 
140
// This function returns the estimated number of RBs required by each UE for downlink scheduling
Raymond Knopp's avatar
 
Raymond Knopp committed
141 142 143 144 145
void assign_rbs_required (module_id_t Mod_id,
			  frame_t     frameP,
			  sub_frame_t subframe,
			  uint16_t    nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
			  int         min_rb_unit[MAX_NUM_CCs]){
146

147

Raymond Knopp's avatar
 
Raymond Knopp committed
148 149 150 151 152
  rnti_t           rnti;
  uint16_t         TBS = 0;
  LTE_eNB_UE_stats *eNB_UE_stats[MAX_NUM_CCs];
  int              UE_id,n,i,j,CC_id,pCCid,tmp;
  UE_list_t        *UE_list = &eNB_mac_inst[Mod_id].UE_list;
153 154
  UE_TEMPLATE           *UE_template;
  LTE_DL_FRAME_PARMS   *frame_parms[MAX_NUM_CCs];
155

Raymond Knopp's avatar
 
Raymond Knopp committed
156 157 158
  // clear rb allocations across all CC_ids
  for (UE_id=UE_list->head;UE_id>=0;UE_id=UE_list->next[UE_id]){
    pCCid = UE_PCCID(Mod_id,UE_id);
159

Raymond Knopp's avatar
 
Raymond Knopp committed
160 161
    //update CQI information across component carriers
    for (n=0;n<UE_list->numactiveCCs[UE_id];n++) {
162

Raymond Knopp's avatar
 
Raymond Knopp committed
163
      CC_id = UE_list->ordered_CCids[n][UE_id];
164
      frame_parms[CC_id] = mac_xface->get_lte_frame_parms(Mod_id,CC_id); 
Raymond Knopp's avatar
 
Raymond Knopp committed
165
      eNB_UE_stats[CC_id] = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti);	
166 167 168 169 170
      /*
	DevCheck(((eNB_UE_stats[CC_id]->DL_cqi[0] < MIN_CQI_VALUE) || (eNB_UE_stats[CC_id]->DL_cqi[0] > MAX_CQI_VALUE)), 
	eNB_UE_stats[CC_id]->DL_cqi[0], MIN_CQI_VALUE, MAX_CQI_VALUE);
      */
      eNB_UE_stats[CC_id]->dlsch_mcs1=cqi_to_mcs[eNB_UE_stats[CC_id]->DL_cqi[0]];
Raymond Knopp's avatar
 
Raymond Knopp committed
171 172 173 174 175 176 177 178 179 180
    }
    // provide the list of CCs sorted according to MCS
    for (i=0;i<UE_list->numactiveCCs[UE_id];i++) {
      for (j=i+1;j<UE_list->numactiveCCs[UE_id];j++) {
	if (eNB_UE_stats[UE_list->ordered_CCids[i][UE_id]]->dlsch_mcs1 > 
	    eNB_UE_stats[UE_list->ordered_CCids[j][UE_id]]->dlsch_mcs1) {
	  tmp = UE_list->ordered_CCids[i][UE_id];
	  UE_list->ordered_CCids[i][UE_id] = UE_list->ordered_CCids[j][UE_id];
	  UE_list->ordered_CCids[j][UE_id] = tmp;
	}
181
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
182
    }
183
    /*
Raymond Knopp's avatar
 
Raymond Knopp committed
184 185 186 187
    if ((mac_get_rrc_status(Mod_id,1,UE_id) < RRC_RECONFIGURED)){  // If we still don't have a default radio bearer
      nb_rbs_required[pCCid][UE_id] = PHY_vars_eNB_g[Mod_id][pCCid]->lte_frame_parms.N_RB_DL;
      continue;
    }
188 189 190 191 192 193 194
    */ 
    /* NN --> RK 
     * check the index of UE_template"
     */
    //    if (UE_list->UE_template[UE_id]->dl_buffer_total> 0) { 
    if (UE_list->UE_template[pCCid][UE_id].dl_buffer_total> 0) { 
      LOG_D(MAC,"[preprocessor] assign RB for UE %d\n",UE_id);
Raymond Knopp's avatar
 
Raymond Knopp committed
195 196
      for (i=0;i<UE_list->numactiveCCs[UE_id];i++) {
	CC_id = UE_list->ordered_CCids[i][UE_id];
197
	LOG_D(MAC,"[preprocessor] assign RB for UE %d\n",UE_id);
Raymond Knopp's avatar
 
Raymond Knopp committed
198 199 200 201
	if (eNB_UE_stats[CC_id]->dlsch_mcs1==0) nb_rbs_required[CC_id][UE_id] = 4;  // don't let the TBS get too small
	else nb_rbs_required[CC_id][UE_id] = min_rb_unit[CC_id];
	
	TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1,nb_rbs_required[CC_id][UE_id]);
202
	/* calculating required number of RBs for each UE */
Raymond Knopp's avatar
 
Raymond Knopp committed
203 204
	while (TBS < UE_list->UE_template[UE_id]->dl_buffer_total)  {
	  nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id];
205 206 207
	  if (nb_rbs_required[CC_id][UE_id] > frame_parms[CC_id]->N_RB_DL) {
	    TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1,frame_parms[CC_id]->N_RB_DL);
	    nb_rbs_required[CC_id][UE_id] = frame_parms[CC_id]->N_RB_DL;
Raymond Knopp's avatar
 
Raymond Knopp committed
208 209 210
	    break;
	  }
	  TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1,nb_rbs_required[CC_id][UE_id]);
211 212 213
	} // end of while 
	LOG_D(MAC,"[eNB %d] Frame %d: UE %d on CC %d nb_required RB %d (TBS %d, mcs %d)\n", 
	      Mod_id, frameP,UE_id, CC_id, nb_rbs_required[CC_id][UE_id], TBS, eNB_UE_stats[CC_id]->dlsch_mcs1);
Raymond Knopp's avatar
 
Raymond Knopp committed
214 215 216 217
      }
    }
  }
}
218 219


Raymond Knopp's avatar
 
Raymond Knopp committed
220
// This function scans all CC_ids for a particular UE to find the maximum round index of its HARQ processes
221

Raymond Knopp's avatar
 
Raymond Knopp committed
222
int maxround(module_id_t Mod_id,uint16_t rnti,sub_frame_t subframe) {
223

Raymond Knopp's avatar
 
Raymond Knopp committed
224 225
  uint8_t round,round_max=0,harq_pid;
  int CC_id;
226

Raymond Knopp's avatar
 
Raymond Knopp committed
227 228 229 230
  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++){
    mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,subframe,&harq_pid,&round,0);
    if (round > round_max)
      round_max = round;
231 232
  }

Raymond Knopp's avatar
 
Raymond Knopp committed
233
}
234

Raymond Knopp's avatar
 
Raymond Knopp committed
235
// This function scans all CC_ids for a particular UE to find the maximum DL CQI
236

Raymond Knopp's avatar
 
Raymond Knopp committed
237
int maxcqi(module_id_t Mod_id,uint16_t rnti) {
238

Raymond Knopp's avatar
 
Raymond Knopp committed
239 240 241
  LTE_eNB_UE_stats *eNB_UE_stats = NULL;
  int CC_id;
  int CQI = 0;
242

Raymond Knopp's avatar
 
Raymond Knopp committed
243 244 245 246
  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++){
    eNB_UE_stats = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti);
    if (eNB_UE_stats->DL_cqi[0] > CQI)
      CQI = eNB_UE_stats->DL_cqi[0];
247
  }
248

Raymond Knopp's avatar
 
Raymond Knopp committed
249 250
  return(CQI);
}
251 252 253



Raymond Knopp's avatar
 
Raymond Knopp committed
254 255 256
// This fuction sorts the UE in order their dlsch buffer and CQI
void sort_UEs (module_id_t Mod_id,
	       sub_frame_t subframe) {
257 258


Raymond Knopp's avatar
 
Raymond Knopp committed
259 260 261 262 263
  int               UE_id1,UE_id2;
  int               pCC_id1,pCC_id2;
  int               cqi1,cqi2,round1,round2;
  int               i=0,ii=0,j=0;
  rnti_t            rnti1,rnti2;
264

Raymond Knopp's avatar
 
Raymond Knopp committed
265
  UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
266

Raymond Knopp's avatar
 
Raymond Knopp committed
267
  for (i=UE_list->head;i>=0;i=UE_list->next[i]) {
268

Raymond Knopp's avatar
 
Raymond Knopp committed
269 270 271
    rnti1 = UE_RNTI(Mod_id,i);
    if(rnti1 == 0)
      continue;
272

Raymond Knopp's avatar
 
Raymond Knopp committed
273 274 275 276
    UE_id1  = i;
    pCC_id1 = UE_PCCID(Mod_id,UE_id1);
    cqi1    = maxcqi(Mod_id,rnti1); //
    round1  = maxround(Mod_id,rnti1,subframe);  
277 278


Raymond Knopp's avatar
 
Raymond Knopp committed
279
    for(ii=UE_list->next[i];ii>=0;ii=UE_list->next[ii]){
280

Raymond Knopp's avatar
 
Raymond Knopp committed
281 282 283 284
      UE_id2 = ii;
      rnti2 = UE_RNTI(Mod_id,UE_id2);
      if(rnti2 == 0)
	continue;
285

Raymond Knopp's avatar
 
Raymond Knopp committed
286 287 288
      cqi2    = maxcqi(Mod_id,rnti2);
      round2  = maxround(Mod_id,rnti2,subframe);  //mac_xface->get_ue_active_harq_pid(Mod_id,rnti2,subframe,&harq_pid2,&round2,0);
      pCC_id2 = UE_PCCID(Mod_id,UE_id2);
289

Raymond Knopp's avatar
 
Raymond Knopp committed
290 291
      if(round2 > round1){  // Check first if one of the UEs has an active HARQ process which needs service and swap order
	swap_UEs(UE_list,UE_id1,UE_id2);
292
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
293 294 295 296 297 298
      else if (round2 == round1){
	// RK->NN : I guess this is for fairness in the scheduling. This doesn't make sense unless all UEs have the same configuration of logical channels.  This should be done on the sum of all information that has to be sent.  And still it wouldn't ensure fairness.  It should be based on throughput seen by each UE or maybe using the head_sdu_creation_time, i.e. swap UEs if one is waiting longer for service.
	//	for(j=0;j<MAX_NUM_LCID;j++){
	//	  if (eNB_mac_inst[Mod_id][pCC_id1].UE_template[UE_id1].dl_buffer_info[j] < 
	//      eNB_mac_inst[Mod_id][pCC_id2].UE_template[UE_id2].dl_buffer_info[j]){

299
	// first check the buffer status for SRB1 and SRB2 
Raymond Knopp's avatar
 
Raymond Knopp committed
300
	
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
	if ( (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] + UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2]) < 
	     (UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] + UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2])   ){
	  swap_UEs(UE_list,UE_id1,UE_id2);
	}
	else if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max < 
		 UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max   ){
	  swap_UEs(UE_list,UE_id1,UE_id2);
	} 
	else if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total < 
		 UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total   ){
	  swap_UEs(UE_list,UE_id1,UE_id2);
	}
	else if (cqi1 < cqi2){
	  swap_UEs(UE_list,UE_id1,UE_id2);
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
316 317
      }
    }
318 319 320
  }
}

321

Raymond Knopp's avatar
 
Raymond Knopp committed
322 323


324
// This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done
Raymond Knopp's avatar
 
Raymond Knopp committed
325 326 327 328 329
void dlsch_scheduler_pre_processor (module_id_t   Mod_id,
				    frame_t       frameP,
				    sub_frame_t   subframeP,
				    uint8_t       dl_pow_off[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
				    uint16_t      pre_nb_available_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
330 331 332
				    int           N_RBG[MAX_NUM_CCs],
				    unsigned char rballoc_sub_UE[MAX_NUM_CCs][NUMBER_OF_UE_MAX][N_RBG_MAX],
				    int           *mbsfn_flag){
Raymond Knopp's avatar
 
Raymond Knopp committed
333

334
  unsigned char rballoc_sub[MAX_NUM_CCs][13],harq_pid=0,harq_pid1=0,harq_pid2=0,round=0,round1=0,round2=0,total_ue_count;
Raymond Knopp's avatar
 
Raymond Knopp committed
335 336
  unsigned char MIMO_mode_indicator[MAX_NUM_CCs][13];
  int                     UE_id, UE_id2, i;
337
  uint16_t                ii,j;
Raymond Knopp's avatar
 
Raymond Knopp committed
338 339 340
  uint16_t                nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
  uint16_t                nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
  uint16_t                nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
341
  uint16_t                i1,i2,i3,r1=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
342
  uint16_t                average_rbs_per_user[MAX_NUM_CCs];
343 344 345
  rnti_t             rnti,rnti1,rnti2;
  LTE_eNB_UE_stats  *eNB_UE_stats1 = NULL;
  LTE_eNB_UE_stats  *eNB_UE_stats2 = NULL;
Raymond Knopp's avatar
 
Raymond Knopp committed
346 347
  int                min_rb_unit[MAX_NUM_CCs];

348
  uint8_t CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
349
  UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
350 351 352 353
  LTE_DL_FRAME_PARMS   *frame_parms[MAX_NUM_CCs];
  int rrc_status           = RRC_IDLE;
  int transmission_mode = 0;
  
Raymond Knopp's avatar
 
Raymond Knopp committed
354 355 356 357
  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {

    if (mbsfn_flag[CC_id]>0)  // If this CC is allocated for MBSFN skip it here
      continue;
358 359 360 361
    
    frame_parms[CC_id] = mac_xface->get_lte_frame_parms(Mod_id,CC_id); 
    min_rb_unit[CC_id]=get_min_rb_unit(Mod_id,CC_id);
    
Raymond Knopp's avatar
 
Raymond Knopp committed
362 363
    for (i=UE_list->head;i>=0;i=UE_list->next[i]) {
      UE_id = i;
364 365 366 367 368 369 370 371 372 373 374 375
      // Initialize scheduling information for all active UEs
      dlsch_scheduler_pre_processor_reset(UE_id,
					  CC_id,
					  N_RBG[CC_id],
					  dl_pow_off,
					  nb_rbs_required,
					  pre_nb_available_rbs,
					  nb_rbs_required_remaining,
					  rballoc_sub_UE,
					  rballoc_sub,
					  MIMO_mode_indicator);
 
Raymond Knopp's avatar
 
Raymond Knopp committed
376
    }
377
  }
378
  
379
  // Store the DLSCH buffer for each logical channel
380
  store_dlsch_buffer (Mod_id,frameP,subframeP);
381 382

  // Calculate the number of RBs required by each UE on the basis of logical channel's buffer
Raymond Knopp's avatar
 
Raymond Knopp committed
383
  assign_rbs_required (Mod_id,frameP,subframeP,nb_rbs_required,min_rb_unit);
384 385

  // Sorts the user on the basis of dlsch logical channel buffer and CQI
Raymond Knopp's avatar
 
Raymond Knopp committed
386 387
  sort_UEs (Mod_id,subframeP);

388
  total_ue_count =0;
Raymond Knopp's avatar
 
Raymond Knopp committed
389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
  // loop over all active UEs
  for (i=UE_list->head;i>=0;i=UE_list->next[i]) {

    UE_id = i;


    rnti = UE_RNTI(Mod_id,UE_id);
    if(rnti == 0)
      continue;

    for (ii=0;ii<UE_num_active_CC(UE_list,UE_id);ii++) {
      CC_id = UE_list->ordered_CCids[ii][UE_id];

      average_rbs_per_user[CC_id]=0;


      mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,subframeP,&harq_pid,&round,0);
406
      if(round>0)
Raymond Knopp's avatar
 
Raymond Knopp committed
407 408 409
	nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
      //nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id];
      if (nb_rbs_required[CC_id][UE_id] > 0) {
410
	total_ue_count = total_ue_count + 1;
Raymond Knopp's avatar
 
Raymond Knopp committed
411 412
      }
      
413
          
414
  // hypotetical assignement
Raymond Knopp's avatar
 
Raymond Knopp committed
415 416 417 418 419 420 421 422 423
  /*
   * If schedule is enabled and if the priority of the UEs is modified
   * The average rbs per logical channel per user will depend on the level of  
   * priority. Concerning the hypothetical assignement, we should assign more 
   * rbs to prioritized users. Maybe, we can do a mapping between the
   * average rbs per user and the level of priority or multiply the average rbs 
   * per user by a coefficient which represents the degree of priority.
   */

424 425 426 427
      if (total_ue_count == 0) 
	average_rbs_per_user[CC_id] = 0;
      else if( (min_rb_unit[CC_id] * total_ue_count) <= (frame_parms[CC_id]->N_RB_DL) )
	average_rbs_per_user[CC_id] = (uint16_t) ceil(frame_parms[CC_id]->N_RB_DL/total_ue_count);
Raymond Knopp's avatar
 
Raymond Knopp committed
428 429 430 431 432
      else 
	average_rbs_per_user[CC_id] = min_rb_unit[CC_id];
    }
  }

433 434
  // note: nb_rbs_required is assigned according to total_buffer_dl
  // extend nb_rbs_required to capture per LCID RB required
Raymond Knopp's avatar
 
Raymond Knopp committed
435 436 437
  for(i=UE_list->head;i>=0;i=UE_list->next[i]){
    for (ii=0;ii<UE_num_active_CC(UE_list,UE_id);ii++) {
      CC_id = UE_list->ordered_CCids[ii][UE_id];
438 439
      // control channel
      if (mac_get_rrc_status(Mod_id,1,i) < RRC_RECONFIGURED)
Raymond Knopp's avatar
 
Raymond Knopp committed
440
	nb_rbs_required_remaining_1[CC_id][i] = nb_rbs_required[CC_id][i];
441
      else
Raymond Knopp's avatar
 
Raymond Knopp committed
442 443
	nb_rbs_required_remaining_1[CC_id][i] = cmin(average_rbs_per_user[CC_id],nb_rbs_required[CC_id][i]);
    }
444
  }
445

446 447 448 449 450
  //Allocation to UEs is done in 2 rounds,
  // 1st round: average number of RBs allocated to each UE
  // 2nd round: remaining RBs are allocated to high priority UEs
  for(r1=0;r1<2;r1++){ 

Raymond Knopp's avatar
 
Raymond Knopp committed
451 452 453
    for(i=UE_list->head; i>=0;i=UE_list->next[i]) {
      for (ii=0;ii<UE_num_active_CC(UE_list,UE_id);ii++) {
	CC_id = UE_list->ordered_CCids[ii][UE_id];
454
 	
Raymond Knopp's avatar
 
Raymond Knopp committed
455 456 457 458 459
	if(r1 == 0)
	  nb_rbs_required_remaining[CC_id][i] = nb_rbs_required_remaining_1[CC_id][i];
	else  // rb required based only on the buffer - rb allloctaed in the 1st round + extra reaming rb form the 1st round
	  nb_rbs_required_remaining[CC_id][i] = nb_rbs_required[CC_id][i]-nb_rbs_required_remaining_1[CC_id][i]+nb_rbs_required_remaining[CC_id][i];

460 461 462 463 464 465 466 467
	LOG_D(MAC,"round %d : nb_rbs_required_remaining[%d][%d]= %d (remaining_1 %d, required %d,  pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n", 
	      r1, CC_id, i, 
	      nb_rbs_required_remaining[CC_id][i],
	      nb_rbs_required_remaining_1[CC_id][i], 
	      nb_rbs_required[CC_id][i],
	      pre_nb_available_rbs[CC_id][i],
	      N_RBG[CC_id],
	      min_rb_unit[CC_id]);
Raymond Knopp's avatar
 
Raymond Knopp committed
468
	
469
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
470
    }
471 472 473 474 475 476
  
    if (total_ue_count > 0 ) {
      for(i=UE_list->head; i>=0;i=UE_list->next[i]) {
	UE_id = i;
	for (ii=0;ii<UE_num_active_CC(UE_list,UE_id);ii++) {
	  CC_id = UE_list->ordered_CCids[ii][UE_id];
Raymond Knopp's avatar
 
Raymond Knopp committed
477
	
478 479 480 481 482 483 484 485
	  rnti = UE_RNTI(Mod_id,UE_id);
	  // LOG_D(MAC,"UE %d rnti 0x\n", UE_id, rnti );
	  if(rnti == 0)
	    continue;
	  transmission_mode = mac_xface->get_transmission_mode(Mod_id,CC_id,rnti);
	  mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,subframeP,&harq_pid,&round,0);
	  rrc_status = mac_get_rrc_status(Mod_id,1,UE_id);
	  /* 1st allocate for the retx */ 
Raymond Knopp's avatar
 
Raymond Knopp committed
486
	  
487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504
	  // retransmission in data channels 
	  // control channel in the 1st transmission
	  // data channel for all TM 
	  LOG_D(MAC,"calling dlsch_scheduler_pre_processor_allocate .. \n ");
	  dlsch_scheduler_pre_processor_allocate (Mod_id,
						  UE_id, 
						  CC_id,
						  N_RBG[CC_id],
						  transmission_mode,
						  min_rb_unit[CC_id],
						  frame_parms[CC_id]->N_RB_DL,
						  dl_pow_off,
						  nb_rbs_required,
						  pre_nb_available_rbs,
						  nb_rbs_required_remaining,
						  rballoc_sub_UE,
						  rballoc_sub,
						  MIMO_mode_indicator);
Raymond Knopp's avatar
 
Raymond Knopp committed
505
	  
506 507 508 509 510
#ifdef TM5
	// data chanel TM5: to be revisted 
	if ((round == 0 )  &&
	    (transmission_mode == 5)  && 
	    (dl_pow_off[CC_id][UE_id] != 1)){
Raymond Knopp's avatar
 
Raymond Knopp committed
511
	  
512
	  for(j=0;j<N_RBG[CC_id];j+=2) {
Raymond Knopp's avatar
 
Raymond Knopp committed
513
	    
514 515 516
	    if( (((j == (N_RBG[CC_id]-1))&& (rballoc_sub[CC_id][j] == 0) && (rballoc_sub_UE[CC_id][UE_id][j] == 0))  || 
		 ((j < (N_RBG[CC_id]-1)) && (rballoc_sub[CC_id][j+1] == 0) && (rballoc_sub_UE[CC_id][UE_id][j+1] == 0)) ) && 
		(nb_rbs_required_remaining[CC_id][UE_id]>0)){
Raymond Knopp's avatar
 
Raymond Knopp committed
517 518 519 520 521 522 523 524 525 526 527
	      
	      for (ii = UE_list->next[i+1];ii >=0;ii=UE_list->next[ii]) {
		
		UE_id2 = ii;
		rnti2 = UE_RNTI(Mod_id,UE_id2);
		if(rnti2 == 0)
		  continue;
		
		eNB_UE_stats2 = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti2);
		mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,subframeP,&harq_pid2,&round2,0);
		
528 529 530 531
		if ((mac_get_rrc_status(Mod_id,1,UE_id2) >= RRC_RECONFIGURED) && 
		    (round2==0) && 
		    (mac_xface->get_transmission_mode(Mod_id,CC_id,rnti2)==5) && 
		    (dl_pow_off[CC_id][UE_id2] != 1)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
532
		  
533 534 535
		  if( (((j == (N_RBG[CC_id]-1)) && (rballoc_sub_UE[CC_id][UE_id2][j] == 0)) || 
		       ((j < (N_RBG[CC_id]-1)) && (rballoc_sub_UE[CC_id][UE_id2][j+1] == 0))  ) && 
		      (nb_rbs_required_remaining[CC_id][UE_id2]>0)){
Raymond Knopp's avatar
 
Raymond Knopp committed
536 537 538 539 540 541 542 543
		    
		    if((((eNB_UE_stats2->DL_pmi_single^eNB_UE_stats1->DL_pmi_single)<<(14-j))&0xc000)== 0x4000){ //MU-MIMO only for 25 RBs configuration
		      
		      rballoc_sub[CC_id][j] = 1;
		      rballoc_sub_UE[CC_id][UE_id][j] = 1;
		      rballoc_sub_UE[CC_id][UE_id2][j] = 1;
		      MIMO_mode_indicator[CC_id][j] = 0;
		      
544
		      if (j< N_RBG[CC_id]-1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
545 546 547 548 549 550 551 552 553 554
			rballoc_sub[CC_id][j+1] = 1;
			rballoc_sub_UE[CC_id][UE_id][j+1] = 1;
			rballoc_sub_UE[CC_id][UE_id2][j+1] = 1;
			MIMO_mode_indicator[CC_id][j+1] = 0;
		      }
		      
		      dl_pow_off[CC_id][UE_id] = 0;
		      dl_pow_off[CC_id][UE_id2] = 0;
		      
		      
555
		      if ((j == N_RBG[CC_id]-1) &&
Raymond Knopp's avatar
 
Raymond Knopp committed
556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575
			  ((PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL == 25) ||
			   (PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL == 50))){
			nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id]+1;
			pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + min_rb_unit[CC_id]-1;
			nb_rbs_required_remaining[CC_id][UE_id2] = nb_rbs_required_remaining[CC_id][UE_id2] - min_rb_unit[CC_id]+1;
			pre_nb_available_rbs[CC_id][UE_id2] = pre_nb_available_rbs[CC_id][UE_id2] + min_rb_unit[CC_id]-1;
		      }
		      else {
			nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - 4;
			pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + 4;
			nb_rbs_required_remaining[CC_id][UE_id2] = nb_rbs_required_remaining[CC_id][UE_id2] - 4;
			pre_nb_available_rbs[CC_id][UE_id2] = pre_nb_available_rbs[CC_id][UE_id2] + 4;
		      }
		      break;
		    }
		  }
		}
	      }
	    }
	  }
576 577
	}  
#endif 
Raymond Knopp's avatar
 
Raymond Knopp committed
578 579
	}
      }
580 581 582
    } // total_ue_count 
  } // end of for for r1 and r2
#ifdef TM5  
Raymond Knopp's avatar
 
Raymond Knopp committed
583 584 585 586 587
  // This has to be revisited!!!!
  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
    i1=0;
    i2=0;
    i3=0;
588
    for (j=0;j<N_RBG[CC_id];j++){
Raymond Knopp's avatar
 
Raymond Knopp committed
589 590 591 592 593 594 595
      if(MIMO_mode_indicator[CC_id][j] == 2)
	i1 = i1+1;
      else if(MIMO_mode_indicator[CC_id][j] == 1)
	i2 = i2+1;
      else if(MIMO_mode_indicator[CC_id][j] == 0)
	i3 = i3+1;
    }
596
    if((i1 < N_RBG[CC_id]) && (i2>0) && (i3==0))
Raymond Knopp's avatar
 
Raymond Knopp committed
597 598
      PHY_vars_eNB_g[Mod_id][CC_id]->check_for_SUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->check_for_SUMIMO_transmissions + 1;
    
599
    if(i3 == N_RBG[CC_id] && i1==0 && i2==0)
Raymond Knopp's avatar
 
Raymond Knopp committed
600 601
      PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions + 1;
    
602
    if((i1 < N_RBG[CC_id]) && (i3 > 0))
Raymond Knopp's avatar
 
Raymond Knopp committed
603 604 605
      PHY_vars_eNB_g[Mod_id][CC_id]->check_for_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->check_for_MUMIMO_transmissions + 1;
    
    PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions + 1;
606
	  	  
607
  }
608 609
  
#endif 
610

Raymond Knopp's avatar
 
Raymond Knopp committed
611 612 613 614
  for(i=UE_list->head; i>=0;i=UE_list->next[i]) {
    for (ii=0;ii<UE_num_active_CC(UE_list,UE_id);ii++) {
      CC_id = UE_list->ordered_CCids[ii][UE_id];
      UE_id = i;
615
      //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id];
616
      LOG_D(MAC,"******************Scheduling Information for UE%d ************************\n",UE_id);
Raymond Knopp's avatar
 
Raymond Knopp committed
617
      LOG_D(MAC,"dl power offset UE%d = %d \n",UE_id,dl_pow_off[CC_id][UE_id]);
618
      LOG_D(MAC,"***********RB Alloc for every subband for UE%d ***********\n",UE_id);
619
      for(j=0;j<N_RBG[CC_id];j++){
Raymond Knopp's avatar
 
Raymond Knopp committed
620 621
	//PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[i] = rballoc_sub_UE[CC_id][UE_id][i];
	LOG_D(MAC,"RB Alloc for UE%d and Subband%d = %d\n",UE_id,j,rballoc_sub_UE[CC_id][UE_id][j]);
622
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
623 624 625
      //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id];
      LOG_D(MAC,"Total RBs allocated for UE%d = %d\n",UE_id,pre_nb_available_rbs[CC_id][UE_id]);
    }
626 627 628
  }
}

629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705

void dlsch_scheduler_pre_processor_reset (int UE_id, 
					  uint8_t  CC_id,
					  int N_RBG,
					  uint8_t dl_pow_off[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
					  uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
					  uint16_t pre_nb_available_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
					  uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX], 
					  unsigned char rballoc_sub_UE[MAX_NUM_CCs][NUMBER_OF_UE_MAX][N_RBG_MAX],
					  unsigned char rballoc_sub[MAX_NUM_CCs][13],
					  unsigned char MIMO_mode_indicator[MAX_NUM_CCs][13]){
  int i;
  nb_rbs_required[CC_id][UE_id]=0;
  pre_nb_available_rbs[CC_id][UE_id] = 0;
  dl_pow_off[CC_id][UE_id] = 2;
  nb_rbs_required_remaining[CC_id][UE_id] = 0;
  for (i=0;i<N_RBG;i++){
    rballoc_sub_UE[CC_id][UE_id][i] = 0;
    rballoc_sub[CC_id][i] = 0;
    MIMO_mode_indicator[CC_id][i] = 2; 
  }
}


void dlsch_scheduler_pre_processor_allocate (module_id_t   Mod_id,
					     int           UE_id, 
					     uint8_t       CC_id,
					     int           N_RBG,
					     int           transmission_mode,
					     int           min_rb_unit, 
					     uint8_t       N_RB_DL,
					     uint8_t       dl_pow_off[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
					     uint16_t      nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
					     uint16_t      pre_nb_available_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
					     uint16_t      nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX], 
					     unsigned char rballoc_sub_UE[MAX_NUM_CCs][NUMBER_OF_UE_MAX][N_RBG_MAX],
					     unsigned char rballoc_sub[MAX_NUM_CCs][13],
					     unsigned char MIMO_mode_indicator[MAX_NUM_CCs][13]){
  
  int i;
  
  for(i=0;i<N_RBG;i++){
   
    if((rballoc_sub[CC_id][i] == 0)           && 
       (rballoc_sub_UE[CC_id][UE_id][i] == 0) && 
       (nb_rbs_required_remaining[UE_id]>0)   &&
       (pre_nb_available_rbs[CC_id][UE_id] < nb_rbs_required[CC_id][UE_id])){
      
      // if this UE is not scheduled for TM5
      if (dl_pow_off[CC_id][UE_id] != 0 )  {
	
	rballoc_sub[CC_id][i] = 1;
	rballoc_sub_UE[CC_id][UE_id][i] = 1;
	MIMO_mode_indicator[CC_id][i] = 1;
	
	if (transmission_mode == 5 )
	  dl_pow_off[CC_id][UE_id] = 1;
	
	if ((i == N_RBG-1) && ((N_RB_DL == 25) || (N_RB_DL == 50))) {
	  nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit+1;
	  pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + min_rb_unit - 1;
	}
	else {
	  nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit;
	  pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + min_rb_unit;
	}
      } // dl_pow_off[CC_id][UE_id] ! = 0
    }
  } 
  
}