pre_processor.c 46.1 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
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
24
  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
25

ghaddab's avatar
ghaddab committed
26
  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, 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
#include "LAYER2/MAC/extern.h"
#include "UTIL/LOG/log.h"
50
#include "UTIL/LOG/vcd_signal_dumper.h"
51 52 53 54 55
#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"
56
#include "rlc.h"
57 58


59

60 61 62 63 64 65 66 67 68 69
#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
70
*/
71 72


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

Raymond Knopp's avatar
 
Raymond Knopp committed
79
  int                   UE_id,i;
80
  rnti_t                rnti;
81
  mac_rlc_status_resp_t rlc_status;
Raymond Knopp's avatar
 
Raymond Knopp committed
82 83 84
  UE_list_t             *UE_list = &eNB_mac_inst[Mod_id].UE_list;
  UE_TEMPLATE           *UE_template;

85
  for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
86 87

    UE_template = &UE_list->UE_template[UE_PCCID(Mod_id,UE_id)][UE_id];
88 89

    // clear logical channel interface variables
Raymond Knopp's avatar
 
Raymond Knopp committed
90 91
    UE_template->dl_buffer_total = 0;
    UE_template->dl_pdus_total = 0;
92 93

    for(i=0; i< MAX_NUM_LCID; i++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
94 95 96 97 98
      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;
    }
99

Raymond Knopp's avatar
 
Raymond Knopp committed
100
    rnti = UE_RNTI(Mod_id,UE_id);
101 102 103

    for(i=0; i< MAX_NUM_LCID; i++) { // loop over all the logical channels

104
      rlc_status = mac_rlc_status_ind(Mod_id,rnti, Mod_id,frameP,ENB_FLAG_YES,MBMS_FLAG_NO,i,0 );
Raymond Knopp's avatar
 
Raymond Knopp committed
105 106 107
      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 ;
108 109
      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
110 111
      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;
112 113
      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];
114

Cedric Roux's avatar
Cedric Roux committed
115
#ifdef DEBUG_eNB_SCHEDULER
116

Raymond Knopp's avatar
 
Raymond Knopp committed
117 118 119 120
      /* 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)
121 122
        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",
123 124 125 126 127 128 129
              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
130
#endif
131

Raymond Knopp's avatar
 
Raymond Knopp committed
132
    }
133

134
    //#ifdef DEBUG_eNB_SCHEDULER
Raymond Knopp's avatar
 
Raymond Knopp committed
135 136
    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",
137 138 139 140 141 142
            Mod_id, frameP, subframeP, UE_id,
            UE_template->dl_buffer_total,
            UE_template->dl_pdus_total
           );

    //#endif
143 144 145
  }
}

146

147
// This function returns the estimated number of RBs required by each UE for downlink scheduling
Raymond Knopp's avatar
 
Raymond Knopp committed
148
void assign_rbs_required (module_id_t Mod_id,
149 150 151 152 153
                          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])
{
154

155

Raymond Knopp's avatar
 
Raymond Knopp committed
156 157 158 159 160
  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;
161
  //  UE_TEMPLATE           *UE_template;
162
  LTE_DL_FRAME_PARMS   *frame_parms[MAX_NUM_CCs];
163

Raymond Knopp's avatar
 
Raymond Knopp committed
164
  // clear rb allocations across all CC_ids
165
  for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
166
    pCCid = UE_PCCID(Mod_id,UE_id);
167
    rnti = UE_list->UE_template[pCCid][UE_id].rnti;
168

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

Raymond Knopp's avatar
 
Raymond Knopp committed
172
      CC_id = UE_list->ordered_CCids[n][UE_id];
173 174
      frame_parms[CC_id] = mac_xface->get_lte_frame_parms(Mod_id,CC_id);
      eNB_UE_stats[CC_id] = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti);
175
      /*
176 177
      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);
178 179
      */
      eNB_UE_stats[CC_id]->dlsch_mcs1=cqi_to_mcs[eNB_UE_stats[CC_id]->DL_cqi[0]];
180

181
      eNB_UE_stats[CC_id]->dlsch_mcs1 = cmin(eNB_UE_stats[CC_id]->dlsch_mcs1,openair_daq_vars.target_ue_dl_mcs);
182

Raymond Knopp's avatar
 
Raymond Knopp committed
183
    }
184

Raymond Knopp's avatar
 
Raymond Knopp committed
185
    // provide the list of CCs sorted according to MCS
186 187
    for (i=0; i<UE_list->numactiveCCs[UE_id]; i++) {
      for (j=i+1; j<UE_list->numactiveCCs[UE_id]; j++) {
188
        DevAssert( j < MAX_NUM_CCs );
189 190 191 192 193 194 195

        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;
        }
196
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
197
    }
198

199
    /*
Raymond Knopp's avatar
 
Raymond Knopp committed
200 201 202 203
    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;
    }
204 205
    */
    /* NN --> RK
206 207
     * check the index of UE_template"
     */
208 209
    //    if (UE_list->UE_template[UE_id]->dl_buffer_total> 0) {
    if (UE_list->UE_template[pCCid][UE_id].dl_buffer_total> 0) {
210
      LOG_D(MAC,"[preprocessor] assign RB for UE %d\n",UE_id);
211 212 213 214 215 216

      for (i=0; i<UE_list->numactiveCCs[UE_id]; i++) {
        CC_id = UE_list->ordered_CCids[i][UE_id];
        frame_parms[CC_id] = mac_xface->get_lte_frame_parms(Mod_id,CC_id);
        eNB_UE_stats[CC_id] = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti);

217 218 219 220 221
        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];
        }
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243

        TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1,nb_rbs_required[CC_id][UE_id]);

        LOG_D(MAC,"[preprocessor] start RB assignement for UE %d CC_id %d dl buffer %d (RB unit %d, MCS %d, TBS %d) \n",
              UE_id, CC_id, UE_list->UE_template[pCCid][UE_id].dl_buffer_total,
              nb_rbs_required[CC_id][UE_id],eNB_UE_stats[CC_id]->dlsch_mcs1,TBS);

        /* calculating required number of RBs for each UE */
        while (TBS < UE_list->UE_template[pCCid][UE_id].dl_buffer_total)  {
          nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id];

          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;
            break;
          }

          TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1,nb_rbs_required[CC_id][UE_id]);
        } // end of while

        LOG_D(MAC,"[eNB %d] Frame %d: UE %d on CC %d: RB unit %d,  nb_required RB %d (TBS %d, mcs %d)\n",
              Mod_id, frameP,UE_id, CC_id,  min_rb_unit[CC_id], nb_rbs_required[CC_id][UE_id], TBS, eNB_UE_stats[CC_id]->dlsch_mcs1);
Raymond Knopp's avatar
 
Raymond Knopp committed
244 245 246 247
      }
    }
  }
}
248 249


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

252 253
int maxround(module_id_t Mod_id,uint16_t rnti,int frame,sub_frame_t subframe,uint8_t ul_flag )
{
254

255
  uint8_t round,round_max=0,UE_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
256
  int CC_id;
257
  UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
258

259 260
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {

261 262
    UE_id = find_UE_id(Mod_id,rnti);
    round    = UE_list->UE_sched_ctrl[UE_id].round[CC_id];
263
    if (round > round_max) {
Raymond Knopp's avatar
 
Raymond Knopp committed
264
      round_max = round;
265
    }
266 267
  }

268
  return round_max;
Raymond Knopp's avatar
 
Raymond Knopp committed
269
}
270

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

273 274
int maxcqi(module_id_t Mod_id,int32_t UE_id)
{
275

Raymond Knopp's avatar
 
Raymond Knopp committed
276
  LTE_eNB_UE_stats *eNB_UE_stats = NULL;
277 278
  UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
  int CC_id,n;
Raymond Knopp's avatar
 
Raymond Knopp committed
279
  int CQI = 0;
280

281
  for (n=0; n<UE_list->numactiveCCs[UE_id]; n++) {
282 283
    CC_id = UE_list->ordered_CCids[n][UE_id];
    eNB_UE_stats = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,UE_RNTI(Mod_id,UE_id));
284

285
    if (eNB_UE_stats==NULL) {
286
      mac_xface->macphy_exit("maxcqi: could not get eNB_UE_stats\n");
287 288
      return 0; // not reached
    }
289

290
    if (eNB_UE_stats->DL_cqi[0] > CQI) {
Raymond Knopp's avatar
 
Raymond Knopp committed
291
      CQI = eNB_UE_stats->DL_cqi[0];
292
    }
293
  }
294

Raymond Knopp's avatar
 
Raymond Knopp committed
295 296
  return(CQI);
}
297 298 299



Raymond Knopp's avatar
 
Raymond Knopp committed
300
// This fuction sorts the UE in order their dlsch buffer and CQI
Raymond Knopp's avatar
 
Raymond Knopp committed
301
void sort_UEs (module_id_t Mod_idP,
302 303 304
               int         frameP,
               sub_frame_t subframeP)
{
305 306


Raymond Knopp's avatar
 
Raymond Knopp committed
307 308 309
  int               UE_id1,UE_id2;
  int               pCC_id1,pCC_id2;
  int               cqi1,cqi2,round1,round2;
310
  int               i=0,ii=0;//,j=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
311
  rnti_t            rnti1,rnti2;
312

Raymond Knopp's avatar
 
Raymond Knopp committed
313
  UE_list_t *UE_list = &eNB_mac_inst[Mod_idP].UE_list;
314

315
  for (i=UE_list->head; i>=0; i=UE_list->next[i]) {
316

317
    for(ii=UE_list->next[i]; ii>=0; ii=UE_list->next[ii]) {
318

319 320
      UE_id1  = i;
      rnti1 = UE_RNTI(Mod_idP,UE_id1);
321 322
      if(rnti1 == NOT_A_RNTI)
	continue;
kaltenbe's avatar
kaltenbe committed
323 324
      if (UE_list->UE_sched_ctrl[UE_id1].ul_out_of_sync == 1)
	continue;
325 326 327
      pCC_id1 = UE_PCCID(Mod_idP,UE_id1);
      cqi1    = maxcqi(Mod_idP,UE_id1); //
      round1  = maxround(Mod_idP,rnti1,frameP,subframeP,0);
328

329 330
      UE_id2 = ii;
      rnti2 = UE_RNTI(Mod_idP,UE_id2);
331 332
      if(rnti2 == NOT_A_RNTI)
        continue;
kaltenbe's avatar
kaltenbe committed
333 334
      if (UE_list->UE_sched_ctrl[UE_id2].ul_out_of_sync == 1)
	continue;
335
      cqi2    = maxcqi(Mod_idP,UE_id2);
336
      round2  = maxround(Mod_idP,rnti2,frameP,subframeP,0);  //mac_xface->get_ue_active_harq_pid(Mod_id,rnti2,subframe,&harq_pid2,&round2,0);
Raymond Knopp's avatar
 
Raymond Knopp committed
337
      pCC_id2 = UE_PCCID(Mod_idP,UE_id2);
338

339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
      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,0);
      } 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]){

        // first check the buffer status for SRB1 and SRB2

        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,0);
        } 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,0);
        } 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,0);
        } else if (cqi1 < cqi2) {
          swap_UEs(UE_list,UE_id1,UE_id2,0);
        }
Raymond Knopp's avatar
 
Raymond Knopp committed
361 362
      }
    }
363 364 365
  }
}

366

Raymond Knopp's avatar
 
Raymond Knopp committed
367 368


369
// This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done
Raymond Knopp's avatar
 
Raymond Knopp committed
370
void dlsch_scheduler_pre_processor (module_id_t   Mod_id,
371 372 373 374 375
                                    frame_t       frameP,
                                    sub_frame_t   subframeP,
                                    int           N_RBG[MAX_NUM_CCs],
                                    int           *mbsfn_flag)
{
Raymond Knopp's avatar
 
Raymond Knopp committed
376

377
  unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],harq_pid=0,round=0,total_ue_count;
Raymond Knopp's avatar
 
Raymond Knopp committed
378
  unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX];
379
  int                     UE_id, i; 
380
  uint16_t                ii,j;
Raymond Knopp's avatar
 
Raymond Knopp committed
381 382 383
  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];
384
  uint16_t                average_rbs_per_user[MAX_NUM_CCs] = {0};
385
  rnti_t             rnti;
Raymond Knopp's avatar
 
Raymond Knopp committed
386
  int                min_rb_unit[MAX_NUM_CCs];
387
  uint16_t r1=0;
388
  uint8_t CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
389
  UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
390
  LTE_DL_FRAME_PARMS   *frame_parms[MAX_NUM_CCs] = {0};
391

392
  int transmission_mode = 0;
393 394 395 396 397 398 399 400 401 402 403 404 405
  UE_sched_ctrl *ue_sched_ctl;
  //  int rrc_status           = RRC_IDLE;

#ifdef TM5
  int harq_pid1=0,harq_pid2=0;
  int round1=0,round2=0;
  int UE_id2;
  uint16_t                i1,i2,i3;
  rnti_t             rnti1,rnti2;
  LTE_eNB_UE_stats  *eNB_UE_stats1 = NULL;
  LTE_eNB_UE_stats  *eNB_UE_stats2 = NULL;
  UE_sched_ctrl *ue_sched_ctl1,*ue_sched_ctl2;
#endif
406 407

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
408 409 410

    if (mbsfn_flag[CC_id]>0)  // If this CC is allocated for MBSFN skip it here
      continue;
411 412 413

    frame_parms[CC_id] = mac_xface->get_lte_frame_parms(Mod_id,CC_id);

Raymond Knopp's avatar
 
Raymond Knopp committed
414

415
    min_rb_unit[CC_id]=get_min_rb_unit(Mod_id,CC_id);
416 417

    for (i=UE_list->head; i>=0; i=UE_list->next[i]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
418
      UE_id = i;
419
      // Initialize scheduling information for all active UEs
420 421
      

422

423
      dlsch_scheduler_pre_processor_reset(Mod_id,
424 425
        UE_id,
        CC_id,
426 427
        frameP,
        subframeP,
428 429 430 431 432
        N_RBG[CC_id],
        nb_rbs_required,
        nb_rbs_required_remaining,
        rballoc_sub,
        MIMO_mode_indicator);
433

Raymond Knopp's avatar
 
Raymond Knopp committed
434
    }
435
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
436 437


438
  // Store the DLSCH buffer for each logical channel
439
  store_dlsch_buffer (Mod_id,frameP,subframeP);
440

Raymond Knopp's avatar
 
Raymond Knopp committed
441 442


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

Raymond Knopp's avatar
 
Raymond Knopp committed
446 447


448
  // Sorts the user on the basis of dlsch logical channel buffer and CQI
Raymond Knopp's avatar
 
Raymond Knopp committed
449 450 451
  sort_UEs (Mod_id,frameP,subframeP);


Raymond Knopp's avatar
 
Raymond Knopp committed
452

453
  total_ue_count =0;
454

Raymond Knopp's avatar
 
Raymond Knopp committed
455
  // loop over all active UEs
456
  for (i=UE_list->head; i>=0; i=UE_list->next[i]) {
457
    rnti = UE_RNTI(Mod_id,i);
458

459
    if(rnti == NOT_A_RNTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
460
      continue;
kaltenbe's avatar
kaltenbe committed
461 462
    if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
      continue;
463
    UE_id = i;
464

465 466 467 468
    // if there is no available harq_process, skip the UE
    if (UE_list->UE_sched_ctrl[UE_id].harq_pid[CC_id]<0)
      continue;

469
    for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
470
      CC_id = UE_list->ordered_CCids[ii][UE_id];
471 472 473
      ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
      harq_pid = ue_sched_ctl->harq_pid[CC_id];
      round    = ue_sched_ctl->round[CC_id];
Raymond Knopp's avatar
 
Raymond Knopp committed
474 475 476

      average_rbs_per_user[CC_id]=0;

477
      frame_parms[CC_id] = mac_xface->get_lte_frame_parms(Mod_id,CC_id);
Raymond Knopp's avatar
 
Raymond Knopp committed
478

479
      //      mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0);
480

481
      if(round>0) {
482
        nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
483
      }
484

Raymond Knopp's avatar
 
Raymond Knopp committed
485 486
      //nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id];
      if (nb_rbs_required[CC_id][UE_id] > 0) {
487
        total_ue_count = total_ue_count + 1;
Raymond Knopp's avatar
 
Raymond Knopp committed
488
      }
489 490 491 492 493 494 495 496 497 498 499 500


      // hypotetical assignement
      /*
       * 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.
       */

501
      if (total_ue_count == 0) {
502
        average_rbs_per_user[CC_id] = 0;
503
      } else if( (min_rb_unit[CC_id] * total_ue_count) <= (frame_parms[CC_id]->N_RB_DL) ) {
504
        average_rbs_per_user[CC_id] = (uint16_t) floor(frame_parms[CC_id]->N_RB_DL/total_ue_count);
505
      } else {
506
        average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; // consider the total number of use that can be scheduled UE
507
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
508 509
    }
  }
510

511 512
  // note: nb_rbs_required is assigned according to total_buffer_dl
  // extend nb_rbs_required to capture per LCID RB required
513
  for(i=UE_list->head; i>=0; i=UE_list->next[i]) {
514
    rnti = UE_RNTI(Mod_id,i);
515

516
    for (ii=0; ii<UE_num_active_CC(UE_list,i); ii++) {
517
      CC_id = UE_list->ordered_CCids[ii][i];
518

519
      // control channel
520
      if (mac_eNB_get_rrc_status(Mod_id,rnti) < RRC_RECONFIGURED) {
521
        nb_rbs_required_remaining_1[CC_id][i] = nb_rbs_required[CC_id][i];
522
      } else {
523 524
        nb_rbs_required_remaining_1[CC_id][i] = cmin(average_rbs_per_user[CC_id],nb_rbs_required[CC_id][i]);

525
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
526
    }
527
  }
528

529
  //Allocation to UEs is done in 2 rounds,
530 531
  // 1st stage: average number of RBs allocated to each UE
  // 2nd stage: remaining RBs are allocated to high priority UEs
532 533 534 535 536 537
  for(r1=0; r1<2; r1++) {

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

538
        if(r1 == 0) {
539
          nb_rbs_required_remaining[CC_id][i] = nb_rbs_required_remaining_1[CC_id][i];
540
        } else { // rb required based only on the buffer - rb allloctaed in the 1st round + extra reaming rb form the 1st round
541
          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];
542
        }
543 544 545 546 547 548 549

        if (nb_rbs_required[CC_id][i]> 0 )
          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],
550
                UE_list->UE_sched_ctrl[i].pre_nb_available_rbs[CC_id],
551 552 553
                N_RBG[CC_id],
                min_rb_unit[CC_id]);

554
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
555
    }
556

557
    if (total_ue_count > 0 ) {
558 559 560 561 562
      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];
563 564 565
	  ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
	  harq_pid = ue_sched_ctl->harq_pid[CC_id];
	  round    = ue_sched_ctl->round[CC_id];
566 567 568 569

          rnti = UE_RNTI(Mod_id,UE_id);

          // LOG_D(MAC,"UE %d rnti 0x\n", UE_id, rnti );
570
          if(rnti == NOT_A_RNTI)
571
            continue;
kaltenbe's avatar
kaltenbe committed
572 573
	  if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1)
	    continue;
574 575

          transmission_mode = mac_xface->get_transmission_mode(Mod_id,CC_id,rnti);
576 577
	  //          mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0);
          //rrc_status = mac_eNB_get_rrc_status(Mod_id,rnti);
578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595
          /* 1st allocate for the retx */

          // retransmission in data channels
          // control channel in the 1st transmission
          // data channel for all TM
          LOG_T(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,
                                                  nb_rbs_required,
                                                  nb_rbs_required_remaining,
                                                  rballoc_sub,
                                                  MIMO_mode_indicator);

596
#ifdef TM5
597 598 599 600

          // data chanel TM5: to be revisted
          if ((round == 0 )  &&
              (transmission_mode == 5)  &&
601
              (ue_sched_ctl->dl_pow_off[CC_id] != 1)) {
602 603 604

            for(j=0; j<N_RBG[CC_id]; j+=2) {

605 606
              if( (((j == (N_RBG[CC_id]-1))&& (rballoc_sub[CC_id][j] == 0) && (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 0))  ||
                   ((j < (N_RBG[CC_id]-1)) && (rballoc_sub[CC_id][j+1] == 0) && (ue_sched_ctl->rballoc_sub_UE[CC_id][j+1] == 0)) ) &&
607 608 609 610 611 612
                  (nb_rbs_required_remaining[CC_id][UE_id]>0)) {

                for (ii = UE_list->next[i+1]; ii >=0; ii=UE_list->next[ii]) {

                  UE_id2 = ii;
                  rnti2 = UE_RNTI(Mod_id,UE_id2);
613 614 615
		  ue_sched_ctl2 = &UE_list->UE_sched_ctrl[UE_id2];
		  harq_pid2 = ue_sched_ctl2->harq_pid[CC_id];
		  round2    = ue_sched_ctl2->round[CC_id];
616
                  if(rnti2 == NOT_A_RNTI)
617
                    continue;
kaltenbe's avatar
kaltenbe committed
618 619
		  if (UE_list->UE_sched_ctrl[UE_id2].ul_out_of_sync == 1)
		    continue;
620 621

                  eNB_UE_stats2 = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti2);
622
                  //mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,frameP,subframeP,&harq_pid2,&round2,0);
623

624
                  if ((mac_eNB_get_rrc_status(Mod_id,rnti2) >= RRC_RECONFIGURED) &&
625 626
                      (round2==0) &&
                      (mac_xface->get_transmission_mode(Mod_id,CC_id,rnti2)==5) &&
627
                      (ue_sched_ctl->dl_pow_off[CC_id] != 1)) {
628

629 630
                    if( (((j == (N_RBG[CC_id]-1)) && (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 0)) ||
                         ((j < (N_RBG[CC_id]-1)) && (ue_sched_ctl->rballoc_sub_UE[CC_id][j+1] == 0))  ) &&
631 632 633 634 635
                        (nb_rbs_required_remaining[CC_id][UE_id2]>0)) {

                      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;
636 637
                        ue_sched_ctl->rballoc_sub_UE[CC_id][j] = 1;
                        ue_sched_ctl2->rballoc_sub_UE[CC_id][j] = 1;
638 639 640 641
                        MIMO_mode_indicator[CC_id][j] = 0;

                        if (j< N_RBG[CC_id]-1) {
                          rballoc_sub[CC_id][j+1] = 1;
642 643
                          ue_sched_ctl->rballoc_sub_UE[CC_id][j+1] = 1;
                          ue_sched_ctl2->rballoc_sub_UE[CC_id][j+1] = 1;
644 645 646
                          MIMO_mode_indicator[CC_id][j+1] = 0;
                        }

647 648
                        ue_sched_ctl->dl_pow_off[CC_id] = 0;
                        ue_sched_ctl2->dl_pow_off[CC_id] = 0;
649 650 651 652 653


                        if ((j == N_RBG[CC_id]-1) &&
                            ((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))) {
654
			  
655
                          nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id]+1;
656
                          ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit[CC_id]-1;
657
                          nb_rbs_required_remaining[CC_id][UE_id2] = nb_rbs_required_remaining[CC_id][UE_id2] - min_rb_unit[CC_id]+1;
658
                          ue_sched_ctl2->pre_nb_available_rbs[CC_id] = ue_sched_ctl2->pre_nb_available_rbs[CC_id] + min_rb_unit[CC_id]-1;
659
                        } else {
660 661
                          
			  nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - 4;
662
                          ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + 4;
663
                          nb_rbs_required_remaining[CC_id][UE_id2] = nb_rbs_required_remaining[CC_id][UE_id2] - 4;
664
                          ue_sched_ctl2->pre_nb_available_rbs[CC_id] = ue_sched_ctl2->pre_nb_available_rbs[CC_id] + 4;
665 666 667 668 669 670 671 672 673 674 675 676 677
                        }

                        break;
                      }
                    }
                  }
                }
              }
            }
          }

#endif
        }
Raymond Knopp's avatar
 
Raymond Knopp committed
678
      }
679
    } // total_ue_count
680
  } // end of for for r1 and r2
681 682 683

#ifdef TM5

Raymond Knopp's avatar
 
Raymond Knopp committed
684
  // This has to be revisited!!!!
685
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
686 687 688
    i1=0;
    i2=0;
    i3=0;
689 690

    for (j=0; j<N_RBG[CC_id]; j++) {
691
      if(MIMO_mode_indicator[CC_id][j] == 2) {
692
        i1 = i1+1;
693
      } else if(MIMO_mode_indicator[CC_id][j] == 1) {
694
        i2 = i2+1;
695
      } else if(MIMO_mode_indicator[CC_id][j] == 0) {
696
        i3 = i3+1;
697
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
698
    }
699

700
    if((i1 < N_RBG[CC_id]) && (i2>0) && (i3==0)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
701
      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;
702
    }
703

704
    if(i3 == N_RBG[CC_id] && i1==0 && i2==0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
705
      PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions + 1;
706
    }
707

708
    if((i1 < N_RBG[CC_id]) && (i3 > 0)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
709
      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;
710
    }
711

Raymond Knopp's avatar
 
Raymond Knopp committed
712
    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;
713

714 715
  }

716 717 718
#endif

  for(i=UE_list->head; i>=0; i=UE_list->next[i]) {
719
    UE_id = i;
720
    ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
721 722

    for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
723
      CC_id = UE_list->ordered_CCids[ii][UE_id];
724
      //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id];
725

726
      if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0 ) {
727
        LOG_D(MAC,"******************DL Scheduling Information for UE%d ************************\n",UE_id);
728
        LOG_D(MAC,"dl power offset UE%d = %d \n",UE_id,ue_sched_ctl->dl_pow_off[CC_id]);
729 730 731 732
        LOG_D(MAC,"***********RB Alloc for every subband for UE%d ***********\n",UE_id);

        for(j=0; j<N_RBG[CC_id]; j++) {
          //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[i] = rballoc_sub_UE[CC_id][UE_id][i];
733
          LOG_D(MAC,"RB Alloc for UE%d and Subband%d = %d\n",UE_id,j,ue_sched_ctl->rballoc_sub_UE[CC_id][j]);
734 735 736
        }

        //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id];
737
        LOG_D(MAC,"Total RBs allocated for UE%d = %d\n",UE_id,ue_sched_ctl->pre_nb_available_rbs[CC_id]);
738
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
739
    }
740 741 742
  }
}

743
#define SF05_LIMIT 1
744

745
void dlsch_scheduler_pre_processor_reset (int module_idP,
746 747 748 749 750 751 752 753 754 755
					  int UE_id,
					  uint8_t  CC_id,
					  int frameP,
					  int subframeP,					  
					  int N_RBG,
					  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],
					  unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
					  unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX])
  
756
{
757
  int i,j;
758 759 760
  UE_list_t *UE_list=&eNB_mac_inst[module_idP].UE_list;
  UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
  rnti_t rnti = UE_RNTI(module_idP,UE_id);
Cedric Roux's avatar
Cedric Roux committed
761
  uint8_t *vrb_map = eNB_mac_inst[module_idP].common_channels[CC_id].vrb_map;
762
  int RBGsize = PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL/N_RBG;
763
#ifdef SF05_LIMIT
764
  //int subframe05_limit=0;
765 766
  int sf05_upper=-1,sf05_lower=-1;
#endif
767
  LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti);
768 769 770 771 772 773
  // initialize harq_pid and round
  mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,
				    frameP,subframeP,
				    &ue_sched_ctl->harq_pid[CC_id],
				    &ue_sched_ctl->round[CC_id],
				    0);
774
  if (ue_sched_ctl->ta_timer == 0) {
775

776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810
    // WE SHOULD PROTECT the eNB_UE_stats with a mutex here ...

    ue_sched_ctl->ta_timer = 20;  // wait 20 subframes before taking TA measurement from PHY
    switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) {
    case 6:
      ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update;
      break;
      
    case 15:
      ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/2;
      break;
      
    case 25:
      ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/4;
      break;
      
    case 50:
      ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/8;
      break;
      
    case 75:
      ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/12;
      break;
      
    case 100:
      ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/16;
      break;
    }
    // clear the update in case PHY does not have a new measurement after timer expiry
    eNB_UE_stats->timing_advance_update =  0;
  }
  else {
    ue_sched_ctl->ta_timer--;
    ue_sched_ctl->ta_update =0; // don't trigger a timing advance command
  }
811 812 813
  if (UE_id==0) {
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_TIMING_ADVANCE,ue_sched_ctl->ta_update);
  }
814
  nb_rbs_required[CC_id][UE_id]=0;
815 816
  ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0;
  ue_sched_ctl->dl_pow_off[CC_id] = 2;
817
  nb_rbs_required_remaining[CC_id][UE_id] = 0;
818

819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842
#ifdef SF05_LIMIT  
  switch (N_RBG) {
  case 6:
    sf05_lower=0;
    sf05_upper=5;
    break;
  case 8:
    sf05_lower=2;
    sf05_upper=5;
    break;
  case 13:
    sf05_lower=4;
    sf05_upper=7;
    break;
  case 17:
    sf05_lower=7;
    sf05_upper=9;
    break;
  case 25:
    sf05_lower=11;
    sf05_upper=13;
    break;
  }
#endif
843
  // Initialize Subbands according to VRB map
844
  for (i=0; i<N_RBG; i++) {
845
    ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0;
846
    rballoc_sub[CC_id][i] = 0;
847 848 849 850 851 852 853 854
#ifdef SF05_LIMIT
    // for avoiding 6+ PRBs around DC in subframe 0-5 (avoid excessive errors)

    if ((subframeP==0 || subframeP==5) && 
	(i>=sf05_lower && i<=sf05_upper))
      rballoc_sub[CC_id][i]=1;
#endif
    // for SI-RNTI,RA-RNTI and P-RNTI allocations
855
    for (j=0;j<RBGsize;j++) {
856
      if (vrb_map[j+(i*RBGsize)]!=0)  {
857
	rballoc_sub[CC_id][i] = 1;
858
	LOG_D(MAC,"Frame %d, subframe %d : vrb %d allocated\n",frameP,subframeP,j+(i*RBGsize));
859 860 861 862
	break;
      }
    }
    LOG_D(MAC,"Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n",frameP,subframeP,CC_id,i,rballoc_sub[CC_id][i]);
863
    MIMO_mode_indicator[CC_id][i] = 2;
864 865 866 867 868
  }
}


void dlsch_scheduler_pre_processor_allocate (module_id_t   Mod_id,
869 870 871 872 873 874 875 876 877 878 879 880
    int           UE_id,
    uint8_t       CC_id,
    int           N_RBG,
    int           transmission_mode,
    int           min_rb_unit,
    uint8_t       N_RB_DL,
    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],
    unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
    unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX])
{

881
  int i;
882 883
  UE_list_t *UE_list=&eNB_mac_inst[Mod_id].UE_list;
  UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
884 885 886 887

  for(i=0; i<N_RBG; i++) {

    if((rballoc_sub[CC_id][i] == 0)           &&
888
        (ue_sched_ctl->rballoc_sub_UE[CC_id][i] == 0) &&
889
        (nb_rbs_required_remaining[CC_id][UE_id]>0)   &&
890
        (ue_sched_ctl->pre_nb_available_rbs[CC_id] < nb_rbs_required[CC_id][UE_id])) {
891

892
      // if this UE is not scheduled for TM5
893
      if (ue_sched_ctl->dl_pow_off[CC_id] != 0 )  {
894

895 896
	if ((i == N_RBG-1) && ((N_RB_DL == 25) || (N_RB_DL == 50))) {
	  rballoc_sub[CC_id][i] = 1;
897
	  ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1;
898 899
	  MIMO_mode_indicator[CC_id][i] = 1;
	  if (transmission_mode == 5 ) {
900
	    ue_sched_ctl->dl_pow_off[CC_id] = 1;
901 902
	  }   
	  nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit+1;
903
          ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit - 1;
904
        } else {
905 906
	  if (nb_rbs_required_remaining[CC_id][UE_id] >=  min_rb_unit){
	    rballoc_sub[CC_id][i] = 1;
907
	    ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1;
908 909
	    MIMO_mode_indicator[CC_id][i] = 1;
	    if (transmission_mode == 5 ) {
910
	      ue_sched_ctl->dl_pow_off[CC_id] = 1;
911 912
	    }
	    nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit;
913
	    ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit;
914 915
	  }
	}
916 917
      } // dl_pow_off[CC_id][UE_id] ! = 0
    }
918 919
  }

920 921 922
}


923
/// ULSCH PRE_PROCESSOR
924

925

926
void ulsch_scheduler_pre_processor(module_id_t module_idP,
927 928 929
                                   int frameP,
                                   sub_frame_t subframeP,
                                   uint16_t *first_rb,
930
                                   uint8_t aggregation)
931
{
932 933 934 935 936 937 938 939

  int16_t            i;
  uint16_t           UE_id,n,r;
  uint8_t            CC_id, round, harq_pid;
  uint16_t           nb_allocated_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX],total_allocated_rbs[MAX_NUM_CCs],average_rbs_per_user[MAX_NUM_CCs];
  int16_t            total_remaining_rbs[MAX_NUM_CCs];
  uint16_t           max_num_ue_to_be_scheduled=0,total_ue_count=0;
  rnti_t             rnti= -1;
940
  UE_list_t          *UE_list = &eNB_mac_inst[module_idP].UE_list;
941 942
  UE_TEMPLATE        *UE_template = 0;
  LTE_DL_FRAME_PARMS   *frame_parms = 0;
943

944

945
  //LOG_I(MAC,"assign max mcs min rb\n");
946 947
  // maximize MCS and then allocate required RB according to the buffer occupancy with the limit of max available UL RB
  assign_max_mcs_min_rb(module_idP,frameP, subframeP, first_rb);
948

949
  //LOG_I(MAC,"sort ue \n");
950
  // sort ues
951 952
  sort_ue_ul (module_idP,frameP, subframeP);

953

954 955
  // we need to distribute RBs among UEs
  // step1:  reset the vars
956
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
957 958 959
    total_allocated_rbs[CC_id]=0;
    total_remaining_rbs[CC_id]=0;
    average_rbs_per_user[CC_id]=0;
960 961

    for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) {
962 963 964 965
      nb_allocated_rbs[CC_id][i]=0;
    }
  }

966
  //LOG_I(MAC,"step2 \n");
967 968 969
  // step 2: calculate the average rb per UE
  total_ue_count =0;
  max_num_ue_to_be_scheduled=0;
970 971 972 973 974

  for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) {

    rnti = UE_RNTI(module_idP,i);

975
    if (rnti==NOT_A_RNTI)
976 977
      continue;

kaltenbe's avatar
kaltenbe committed
978 979 980
    if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
      continue;

981
    UE_id = i;
982 983

    for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) {
984 985 986 987
      // This is the actual CC_id in the list
      CC_id = UE_list->ordered_ULCCids[n][UE_id];
      UE_template = &UE_list->UE_template[CC_id][UE_id];
      average_rbs_per_user[CC_id]=0;
988 989
      frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id);

990
      if (UE_template->pre_allocated_nb_rb_ul > 0) {
991
        total_ue_count+=1;
992
      }
993 994
      /*
      if((mac_xface->get_nCCE_max(module_idP,CC_id,3,subframeP) - nCCE_to_be_used[CC_id])  > (1<<aggregation)) {
995 996
        nCCE_to_be_used[CC_id] = nCCE_to_be_used[CC_id] + (1<<aggregation);
        max_num_ue_to_be_scheduled+=1;
997 998 999
	}*/

      max_num_ue_to_be_scheduled+=1;
1000

1001
      if (total_ue_count == 0) {
1002
        average_rbs_per_user[CC_id] = 0;
1003
      } else if (total_ue_count == 1 ) { // increase the available RBs, special case,
1004
        average_rbs_per_user[CC_id] = frame_parms->N_RB_UL-first_rb[CC_id]+1;
1005
      } else if( (total_ue_count <= (frame_parms->N_RB_DL-first_rb[CC_id])) &&
1006
                 (total_ue_count <= max_num_ue_to_be_scheduled)) {
1007
        average_rbs_per_user[CC_id] = (uint16_t) floor((frame_parms->N_RB_UL-first_rb[CC_id])/total_ue_count);
1008
      } else if (max_num_ue_to_be_scheduled > 0 ) {
1009
        average_rbs_per_user[CC_id] = (uint16_t) floor((frame_parms->N_RB_UL-first_rb[CC_id])/max_num_ue_to_be_scheduled);
1010
      } else {
1011 1012 1013
        average_rbs_per_user[CC_id]=1;
        LOG_W(MAC,"[eNB %d] frame %d subframe %d: UE %d CC %d: can't get average rb per user (should not be here)\n",
              module_idP,frameP,subframeP,UE_id,CC_id);
1014 1015 1016
      }
    }
  }
1017 1018 1019
  if (total_ue_count > 0)
    LOG_D(MAC,"[eNB %d] Frame %d subframe %d: total ue to be scheduled %d/%d\n",
	  module_idP, frameP, subframeP,total_ue_count, max_num_ue_to_be_scheduled);
1020

1021
  //LOG_D(MAC,"step3\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1022

1023 1024 1025 1026
  // step 3: assigne RBS
  for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) {
    rnti = UE_RNTI(module_idP,i);

1027
    if (rnti==NOT_A_RNTI)
1028
      continue;
kaltenbe's avatar
kaltenbe committed
1029 1030
    if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
      continue;
1031

1032
    UE_id = i;
1033 1034

    for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) {
1035 1036
      // This is the actual CC_id in the list
      CC_id = UE_list->ordered_ULCCids[n][UE_id];
1037

1038
      mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,1);
1039

1040
      if(round>0) {
1041
        nb_allocated_rbs[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb_ul[harq_pid];
1042
      } else {
1043
        nb_allocated_rbs[CC_id][UE_id] = cmin(UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul, average_rbs_per_user[CC_id]);
1044
      }
1045

1046
      total_allocated_rbs[CC_id]+= nb_allocated_rbs[CC_id][UE_id];
1047

1048 1049
    }
  }
1050

1051
  // step 4: assigne the remaining RBs and set the pre_allocated rbs accordingly
1052 1053 1054 1055 1056
  for(r=0; r<2; r++) {

    for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) {
      rnti = UE_RNTI(module_idP,i);

1057
      if (rnti==NOT_A_RNTI)
1058
        continue;
kaltenbe's avatar
kaltenbe committed
1059 1060
      if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
	continue;
1061

1062
      UE_id = i;
1063 1064 1065 1066 1067 1068 1069 1070

      for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) {
        // This is the actual CC_id in the list
        CC_id = UE_list->ordered_ULCCids[n][UE_id];
        UE_template = &UE_list->UE_template[CC_id][UE_id];
        frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id);
        total_remaining_rbs[CC_id]=frame_parms->N_RB_UL - first_rb[CC_id] - total_allocated_rbs[CC_id];

1071
        if (total_ue_count == 1 ) {
1072
          total_remaining_rbs[CC_id]+=1;
1073
        }
1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087

        if ( r == 0 ) {
          while ( (UE_template->pre_allocated_nb_rb_ul > 0 ) &&
                  (nb_allocated_rbs[CC_id][UE_id] < UE_template->pre_allocated_nb_rb_ul) &&
                  (total_remaining_rbs[CC_id] > 0)) {
            nb_allocated_rbs[CC_id][UE_id] = cmin(nb_allocated_rbs[CC_id][UE_id]+1,UE_template->pre_allocated_nb_rb_ul);
            total_remaining_rbs[CC_id]--;
            total_allocated_rbs[CC_id]++;
          }
        } else {
          UE_template->pre_allocated_nb_rb_ul= nb_allocated_rbs[CC_id][UE_id];
          LOG_D(MAC,"******************UL Scheduling Information for UE%d CC_id %d ************************\n",UE_id, CC_id);
          LOG_D(MAC,"[eNB %d] total RB allocated for UE%d CC_id %d  = %d\n", module_idP, UE_id, CC_id, UE_template->pre_allocated_nb_rb_ul);
        }
1088 1089 1090
      }
    }
  }
1091 1092

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
1093
    frame_parms= mac_xface->get_lte_frame_parms(module_idP,CC_id);
1094

1095
    if (total_allocated_rbs[CC_id]>0) {
1096
      LOG_D(MAC,"[eNB %d] total RB allocated for all UEs = %d/%d\n", module_idP, total_allocated_rbs[CC_id], frame_parms->N_RB_UL - first_rb[CC_id]);
1097
    }
1098
  }
1099 1100
}

1101

1102 1103 1104
void assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subframeP, uint16_t *first_rb)
{

1105 1106 1107 1108
  int                i;
  uint16_t           n,UE_id;
  uint8_t            CC_id;
  rnti_t             rnti           = -1;
1109
  int                mcs;
Raymond Knopp's avatar
 
Raymond Knopp committed
1110
  int                rb_table_index=0,tbs,tx_power;
1111
  eNB_MAC_INST       *eNB = &eNB_mac_inst[module_idP];
1112 1113
  UE_list_t          *UE_list = &eNB->UE_list;

1114 1115
  UE_TEMPLATE       *UE_template;
  LTE_DL_FRAME_PARMS   *frame_parms;
1116

1117

1118 1119 1120 1121
  for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) {

    rnti = UE_RNTI(module_idP,i);

1122
    if (rnti==NOT_A_RNTI)
1123
      continue;
kaltenbe's avatar
kaltenbe committed
1124 1125
    if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
      continue;
1126

1127 1128 1129 1130 1131
    if (UE_list->UE_sched_ctrl[i].phr_received == 1)
      mcs = 20; // if we've received the power headroom information the UE, we can go to maximum mcs
    else
      mcs = 10; // otherwise, limit to QPSK PUSCH

1132
    UE_id = i;
1133 1134

    for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) {
1135 1136
      // This is the actual CC_id in the list
      CC_id = UE_list->ordered_ULCCids[n][UE_id];
1137

1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152
      if (CC_id >= MAX_NUM_CCs) {
        LOG_E( MAC, "CC_id %u should be < %u, loop n=%u < numactiveULCCs[%u]=%u",
               CC_id,
               MAX_NUM_CCs,
               n,
               UE_id,
               UE_list->numactiveULCCs[UE_id]);
      }

      AssertFatal( CC_id < MAX_NUM_CCs, "CC_id %u should be < %u, loop n=%u < numactiveULCCs[%u]=%u",
                   CC_id,
                   MAX_NUM_CCs,
                   n,
                   UE_id,
                   UE_list->numactiveULCCs[UE_id]);
1153
      frame_parms=mac_xface->get_lte_frame_parms(module_idP,CC_id);
1154
      UE_template = &UE_list->UE_template[CC_id][UE_id];
1155 1156

      // if this UE has UL traffic
1157
      if (UE_template->ul_total_buffer > 0 ) {
1158

1159
        tbs = mac_xface->get_TBS_UL(mcs,3);  // 1 or 2 PRB with cqi enabled does not work well!
1160 1161 1162
        // fixme: set use_srs flag
        tx_power= mac_xface->estimate_ue_tx_power(tbs,rb_table[rb_table_index],0,frame_parms->Ncp,0);

1163
        while ((((UE_template->phr_info - tx_power) < 0 ) || (tbs > UE_template->ul_total_buffer))&&
1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180
               (mcs > 3)) {
          // LOG_I(MAC,"UE_template->phr_info %d tx_power %d mcs %d\n", UE_template->phr_info,tx_power, mcs);
          mcs--;
          tbs = mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]);
          tx_power = mac_xface->estimate_ue_tx_power(tbs,rb_table[rb_table_index],0,frame_parms->Ncp,0); // fixme: set use_srs
        }

        while ((tbs < UE_template->ul_total_buffer) &&
               (rb_table[rb_table_index]<(frame_parms->N_RB_UL-first_rb[CC_id])) &&
               ((UE_template->phr_info - tx_power) > 0) &&
               (rb_table_index < 32 )) {
          //  LOG_I(MAC,"tbs %d ul buffer %d rb table %d max ul rb %d\n", tbs, UE_template->ul_total_buffer, rb_table[rb_table_index], frame_parms->N_RB_UL-first_rb[CC_id]);
          rb_table_index++;
          tbs = mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]);
          tx_power = mac_xface->estimate_ue_tx_power(tbs,rb_table[rb_table_index],0,frame_parms->Ncp,0);
        }

1181
        UE_template->ue_tx_power = tx_power;
1182 1183 1184 1185 1186 1187

        if (rb_table[rb_table_index]>(frame_parms->N_RB_UL-first_rb[CC_id]-1)) {
          rb_table_index--;
        }

        // 1 or 2 PRB with cqi enabled does not work well!
1188
	if (rb_table[rb_table_index]<3) {
1189
          rb_table_index=2; //3PRB
1190
        }
1191 1192 1193 1194 1195 1196 1197 1198 1199 1200

        UE_template->pre_assigned_mcs_ul=mcs;
        UE_template->pre_allocated_rb_table_index_ul=rb_table_index;
        UE_template->pre_allocated_nb_rb_ul= rb_table[rb_table_index];
        LOG_D(MAC,"[eNB %d] frame %d subframe %d: for UE %d CC %d: pre-assigned mcs %d, pre-allocated rb_table[%d]=%d RBs (phr %d, tx power %d)\n",
              module_idP, frameP, subframeP, UE_id, CC_id,
              UE_template->pre_assigned_mcs_ul,
              UE_template->pre_allocated_rb_table_index_ul,
              UE_template->pre_allocated_nb_rb_ul,
              UE_template->phr_info,tx_power);
1201
      } else {
1202 1203
        UE_template->pre_allocated_rb_table_index_ul=-1;
        UE_template->pre_allocated_nb_rb_ul=0;
1204 1205 1206 1207 1208 1209
      }
    }
  }
}


1210 1211
void sort_ue_ul (module_id_t module_idP,int frameP, sub_frame_t subframeP)
{
1212 1213 1214 1215

  int               UE_id1,UE_id2;
  int               pCCid1,pCCid2;
  int               round1,round2;
1216
  int               i=0,ii=0;
1217 1218 1219
  rnti_t            rnti1,rnti2;

  UE_list_t *UE_list = &eNB_mac_inst[module_idP].UE_list;
1220 1221

  for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1222 1223

    //LOG_I(MAC,"sort ue ul i %d\n",i);
1224
    for (ii=UE_list->next_ul[i]; ii>=0; ii=UE_list->next_ul[ii]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1225
      //LOG_I(MAC,"sort ul ue 2 ii %d\n",ii);
1226 1227 1228 1229 1230
 
      UE_id1  = i;
      rnti1 = UE_RNTI(module_idP,UE_id1);
      
      if(rnti1 == NOT_A_RNTI)
kaltenbe's avatar
kaltenbe committed
1231 1232 1233
	continue;
      if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
	continue;
Raymond Knopp's avatar
 
Raymond Knopp committed
1234

1235 1236 1237 1238 1239 1240
      pCCid1 = UE_PCCID(module_idP,UE_id1);
      round1  = maxround(module_idP,rnti1,frameP,subframeP,1);
      
      UE_id2  = ii;
      rnti2 = UE_RNTI(module_idP,UE_id2);
      
1241
      if(rnti2 == NOT_A_RNTI)
1242
        continue;
kaltenbe's avatar
kaltenbe committed
1243 1244
      if (UE_list->UE_sched_ctrl[UE_id2].ul_out_of_sync == 1)
	continue;
1245

1246
      pCCid2 = UE_PCCID(module_idP,UE_id2);
1247 1248 1249 1250 1251 1252 1253 1254 1255 1256
      round2  = maxround(module_idP,rnti2,frameP,subframeP,1);

      if(round2 > round1) {
        swap_UEs(UE_list,UE_id1,UE_id2,1);
      } else if (round2 == round1) {
        if (UE_list->UE_template[pCCid1][UE_id1].ul_buffer_info[LCGID0] < UE_list->UE_template[pCCid2][UE_id2].ul_buffer_info[LCGID0]) {
          swap_UEs(UE_list,UE_id1,UE_id2,1);
        } else if (UE_list->UE_template[pCCid1][UE_id1].ul_total_buffer <  UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer) {
          swap_UEs(UE_list,UE_id1,UE_id2,1);
        } else if (UE_list->UE_template[pCCid1][UE_id1].pre_assigned_mcs_ul <  UE_list->UE_template[pCCid2][UE_id2].pre_assigned_mcs_ul) {
1257
          if (UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer > 0 ) {
1258
            swap_UEs(UE_list,UE_id1,UE_id2,1);
1259
          }
1260
        }
1261 1262 1263 1264
      }
    }
  }
}