pre_processor.c 46.9 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 50 51 52 53 54
#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"
55
#include "rlc.h"
56 57


58

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


72
// This function stores the downlink buffer for all the logical channels
73 74
void store_dlsch_buffer (module_id_t Mod_id,
                         frame_t     frameP,
75 76
                         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
  UE_list_t             *UE_list = &eNB_mac_inst[Mod_id].UE_list;
  UE_TEMPLATE           *UE_template;

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

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

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

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

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

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

103
      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
104 105 106
      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 ;
107 108
      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
109 110
      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;
111 112
      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];
113

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
131
    }
132

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

    //#endif
142 143 144
  }
}

145

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

154

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

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
171
      CC_id = UE_list->ordered_CCids[n][UE_id];
172 173
      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);
174
      /*
175 176
      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);
177 178
      */
      eNB_UE_stats[CC_id]->dlsch_mcs1=cqi_to_mcs[eNB_UE_stats[CC_id]->DL_cqi[0]];
179

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

Raymond Knopp's avatar
 
Raymond Knopp committed
182
    }
183

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

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

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

      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);

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

        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
243 244 245 246
      }
    }
  }
}
247 248


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

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

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

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

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

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

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

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

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

280
  for (n=0; n<UE_list->numactiveCCs[UE_id]; n++) {
281 282
    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));
283

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

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

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



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


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

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

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

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

318 319
      UE_id1  = i;
      rnti1 = UE_RNTI(Mod_idP,UE_id1);
320 321 322 323 324
      if(rnti1 == NOT_A_RNTI)
	continue;
      pCC_id1 = UE_PCCID(Mod_idP,UE_id1);
      cqi1    = maxcqi(Mod_idP,UE_id1); //
      round1  = maxround(Mod_idP,rnti1,frameP,subframeP,0);
325

326 327
      UE_id2 = ii;
      rnti2 = UE_RNTI(Mod_idP,UE_id2);
328 329
      if(rnti2 == NOT_A_RNTI)
        continue;
330
      cqi2    = maxcqi(Mod_idP,UE_id2);
331
      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
332
      pCC_id2 = UE_PCCID(Mod_idP,UE_id2);
333

334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355
      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
356 357
      }
    }
358 359 360
  }
}

361

Raymond Knopp's avatar
 
Raymond Knopp committed
362 363


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

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

387
  int transmission_mode = 0;
388 389 390 391 392 393 394 395 396 397 398 399 400
  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
401 402

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
403 404 405

    if (mbsfn_flag[CC_id]>0)  // If this CC is allocated for MBSFN skip it here
      continue;
406 407 408

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

Raymond Knopp's avatar
 
Raymond Knopp committed
409

410
    min_rb_unit[CC_id]=get_min_rb_unit(Mod_id,CC_id);
411 412

    for (i=UE_list->head; i>=0; i=UE_list->next[i]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
413
      UE_id = i;
414
      // Initialize scheduling information for all active UEs
415 416
      

417

418
      dlsch_scheduler_pre_processor_reset(Mod_id,
419 420
        UE_id,
        CC_id,
421 422
        frameP,
        subframeP,
423 424 425 426 427
        N_RBG[CC_id],
        nb_rbs_required,
        nb_rbs_required_remaining,
        rballoc_sub,
        MIMO_mode_indicator);
428

Raymond Knopp's avatar
 
Raymond Knopp committed
429
    }
430
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
431 432


433
  // Store the DLSCH buffer for each logical channel
434
  store_dlsch_buffer (Mod_id,frameP,subframeP);
435

Raymond Knopp's avatar
 
Raymond Knopp committed
436 437


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

Raymond Knopp's avatar
 
Raymond Knopp committed
441 442


443
  // Sorts the user on the basis of dlsch logical channel buffer and CQI
Raymond Knopp's avatar
 
Raymond Knopp committed
444 445 446
  sort_UEs (Mod_id,frameP,subframeP);


Raymond Knopp's avatar
 
Raymond Knopp committed
447

448
  total_ue_count =0;
449

Raymond Knopp's avatar
 
Raymond Knopp committed
450
  // loop over all active UEs
451
  for (i=UE_list->head; i>=0; i=UE_list->next[i]) {
452
    rnti = UE_RNTI(Mod_id,i);
453

454
    if(rnti == NOT_A_RNTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
455
      continue;
456

457
    UE_id = i;
458

459 460 461 462
    // if there is no available harq_process, skip the UE
    if (UE_list->UE_sched_ctrl[UE_id].harq_pid[CC_id]<0)
      continue;

463
    for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
464
      CC_id = UE_list->ordered_CCids[ii][UE_id];
465 466 467
      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
468 469 470

      average_rbs_per_user[CC_id]=0;

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

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

475
      if(round>0) {
476
        nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
477
      }
478

Raymond Knopp's avatar
 
Raymond Knopp committed
479 480
      //nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id];
      if (nb_rbs_required[CC_id][UE_id] > 0) {
481
        total_ue_count = total_ue_count + 1;
Raymond Knopp's avatar
 
Raymond Knopp committed
482
      }
483 484 485 486 487 488 489 490 491 492 493 494


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

495
      if (total_ue_count == 0) {
496
        average_rbs_per_user[CC_id] = 0;
497
      } else if( (min_rb_unit[CC_id] * total_ue_count) <= (frame_parms[CC_id]->N_RB_DL) ) {
498
        average_rbs_per_user[CC_id] = (uint16_t) floor(frame_parms[CC_id]->N_RB_DL/total_ue_count);
499
      } else {
500
        average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; // consider the total number of use that can be scheduled UE
501
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
502 503
    }
  }
504

505 506
  // note: nb_rbs_required is assigned according to total_buffer_dl
  // extend nb_rbs_required to capture per LCID RB required
507
  for(i=UE_list->head; i>=0; i=UE_list->next[i]) {
508
    rnti = UE_RNTI(Mod_id,i);
509

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

513
      // control channel
514
      if (mac_eNB_get_rrc_status(Mod_id,rnti) < RRC_RECONFIGURED) {
515
        nb_rbs_required_remaining_1[CC_id][i] = nb_rbs_required[CC_id][i];
516
      } else {
517 518
        nb_rbs_required_remaining_1[CC_id][i] = cmin(average_rbs_per_user[CC_id],nb_rbs_required[CC_id][i]);

519
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
520
    }
521
  }
522

523
  //Allocation to UEs is done in 2 rounds,
524 525
  // 1st stage: average number of RBs allocated to each UE
  // 2nd stage: remaining RBs are allocated to high priority UEs
526 527 528 529 530 531
  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];

532
        if(r1 == 0) {
533
          nb_rbs_required_remaining[CC_id][i] = nb_rbs_required_remaining_1[CC_id][i];
534
        } else { // rb required based only on the buffer - rb allloctaed in the 1st round + extra reaming rb form the 1st round
535
          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];
536
        }
537 538 539 540 541 542 543

        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],
544
                UE_list->UE_sched_ctrl[i].pre_nb_available_rbs[CC_id],
545 546 547
                N_RBG[CC_id],
                min_rb_unit[CC_id]);

548
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
549
    }
550

551
    if (total_ue_count > 0 ) {
552 553 554 555 556
      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];
557 558 559
	  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];
560 561 562 563

          rnti = UE_RNTI(Mod_id,UE_id);

          // LOG_D(MAC,"UE %d rnti 0x\n", UE_id, rnti );
564
          if(rnti == NOT_A_RNTI)
565 566 567
            continue;

          transmission_mode = mac_xface->get_transmission_mode(Mod_id,CC_id,rnti);
568 569
	  //          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);
570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587
          /* 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);

588
#ifdef TM5
589 590 591 592

          // data chanel TM5: to be revisted
          if ((round == 0 )  &&
              (transmission_mode == 5)  &&
593
              (ue_sched_ctl->dl_pow_off[CC_id] != 1)) {
594 595 596

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

597 598
              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)) ) &&
599 600 601 602 603 604
                  (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);
605 606 607
		  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];
608
                  if(rnti2 == NOT_A_RNTI)
609 610 611
                    continue;

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

614
                  if ((mac_eNB_get_rrc_status(Mod_id,rnti2) >= RRC_RECONFIGURED) &&
615 616
                      (round2==0) &&
                      (mac_xface->get_transmission_mode(Mod_id,CC_id,rnti2)==5) &&
617
                      (ue_sched_ctl->dl_pow_off[CC_id] != 1)) {
618

619 620
                    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))  ) &&
621 622 623 624 625
                        (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;
626 627
                        ue_sched_ctl->rballoc_sub_UE[CC_id][j] = 1;
                        ue_sched_ctl2->rballoc_sub_UE[CC_id][j] = 1;
628 629 630 631
                        MIMO_mode_indicator[CC_id][j] = 0;

                        if (j< N_RBG[CC_id]-1) {
                          rballoc_sub[CC_id][j+1] = 1;
632 633
                          ue_sched_ctl->rballoc_sub_UE[CC_id][j+1] = 1;
                          ue_sched_ctl2->rballoc_sub_UE[CC_id][j+1] = 1;
634 635 636
                          MIMO_mode_indicator[CC_id][j+1] = 0;
                        }

637 638
                        ue_sched_ctl->dl_pow_off[CC_id] = 0;
                        ue_sched_ctl2->dl_pow_off[CC_id] = 0;
639 640 641 642 643


                        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))) {
644
			  
645
                          nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id]+1;
646
                          ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit[CC_id]-1;
647
                          nb_rbs_required_remaining[CC_id][UE_id2] = nb_rbs_required_remaining[CC_id][UE_id2] - min_rb_unit[CC_id]+1;
648
                          ue_sched_ctl2->pre_nb_available_rbs[CC_id] = ue_sched_ctl2->pre_nb_available_rbs[CC_id] + min_rb_unit[CC_id]-1;
649
                        } else {
650 651
                          
			  nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - 4;
652
                          ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + 4;
653
                          nb_rbs_required_remaining[CC_id][UE_id2] = nb_rbs_required_remaining[CC_id][UE_id2] - 4;
654
                          ue_sched_ctl2->pre_nb_available_rbs[CC_id] = ue_sched_ctl2->pre_nb_available_rbs[CC_id] + 4;
655 656 657 658 659 660 661 662 663 664 665 666 667
                        }

                        break;
                      }
                    }
                  }
                }
              }
            }
          }

#endif
        }
Raymond Knopp's avatar
 
Raymond Knopp committed
668
      }
669
    } // total_ue_count
670
  } // end of for for r1 and r2
671 672 673

#ifdef TM5

Raymond Knopp's avatar
 
Raymond Knopp committed
674
  // This has to be revisited!!!!
675
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
676 677 678
    i1=0;
    i2=0;
    i3=0;
679 680

    for (j=0; j<N_RBG[CC_id]; j++) {
681
      if(MIMO_mode_indicator[CC_id][j] == 2) {
682
        i1 = i1+1;
683
      } else if(MIMO_mode_indicator[CC_id][j] == 1) {
684
        i2 = i2+1;
685
      } else if(MIMO_mode_indicator[CC_id][j] == 0) {
686
        i3 = i3+1;
687
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
688
    }
689

690
    if((i1 < N_RBG[CC_id]) && (i2>0) && (i3==0)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
691
      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;
692
    }
693

694
    if(i3 == N_RBG[CC_id] && i1==0 && i2==0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
695
      PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions + 1;
696
    }
697

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

Raymond Knopp's avatar
 
Raymond Knopp committed
702
    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;
703

704 705
  }

706 707 708
#endif

  for(i=UE_list->head; i>=0; i=UE_list->next[i]) {
709
    UE_id = i;
710
    ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
711 712

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

716
      if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0 ) {
717
        LOG_D(MAC,"******************DL Scheduling Information for UE%d ************************\n",UE_id);
718
        LOG_D(MAC,"dl power offset UE%d = %d \n",UE_id,ue_sched_ctl->dl_pow_off[CC_id]);
719 720 721 722
        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];
723
          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]);
724 725 726
        }

        //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id];
727
        LOG_D(MAC,"Total RBs allocated for UE%d = %d\n",UE_id,ue_sched_ctl->pre_nb_available_rbs[CC_id]);
728
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
729
    }
730 731 732
  }
}

733
#define SF05_LIMIT 1
734

735
void dlsch_scheduler_pre_processor_reset (int module_idP,
736 737 738 739 740 741 742 743 744 745
					  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])
  
746
{
747
  int i,j;
748 749 750
  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);
751 752
  uint8_t *vrb_map = &eNB_mac_inst[module_idP].common_channels[CC_id].vrb_map;
  int RBGsize = PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL/N_RBG;
753 754 755 756
#ifdef SF05_LIMIT
  int subframe05_limit=0;
  int sf05_upper=-1,sf05_lower=-1;
#endif
757
  LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti);
758 759 760 761 762 763
  // 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);
764
  if (ue_sched_ctl->ta_timer == 0) {
765

766 767 768 769 770 771 772 773 774 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
    // 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
  }
801
  nb_rbs_required[CC_id][UE_id]=0;
802 803
  ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0;
  ue_sched_ctl->dl_pow_off[CC_id] = 2;
804
  nb_rbs_required_remaining[CC_id][UE_id] = 0;
805

806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829
#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
830
  // Initialize Subbands according to VRB map
831
  for (i=0; i<N_RBG; i++) {
832
    ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0;
833
    rballoc_sub[CC_id][i] = 0;
834 835 836 837 838 839 840 841
#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
842
    for (j=0;j<RBGsize;j++) {
843
      if (vrb_map[j+(i*RBGsize)]!=0)  {
844
	rballoc_sub[CC_id][i] = 1;
845
	LOG_D(MAC,"Frame %d, subframe %d : vrb %d allocated\n",frameP,subframeP,j+(i*RBGsize));
846 847 848 849
	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]);
850
    MIMO_mode_indicator[CC_id][i] = 2;
851 852 853 854 855
  }
}


void dlsch_scheduler_pre_processor_allocate (module_id_t   Mod_id,
856 857 858 859 860 861 862 863 864 865 866 867
    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])
{

868
  int i;
869 870
  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];
871 872 873 874

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

    if((rballoc_sub[CC_id][i] == 0)           &&
875
        (ue_sched_ctl->rballoc_sub_UE[CC_id][i] == 0) &&
876
        (nb_rbs_required_remaining[CC_id][UE_id]>0)   &&
877
        (ue_sched_ctl->pre_nb_available_rbs[CC_id] < nb_rbs_required[CC_id][UE_id])) {
878

879
      // if this UE is not scheduled for TM5
880
      if (ue_sched_ctl->dl_pow_off[CC_id] != 0 )  {
881

882 883
	if ((i == N_RBG-1) && ((N_RB_DL == 25) || (N_RB_DL == 50))) {
	  rballoc_sub[CC_id][i] = 1;
884
	  ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1;
885 886
	  MIMO_mode_indicator[CC_id][i] = 1;
	  if (transmission_mode == 5 ) {
887
	    ue_sched_ctl->dl_pow_off[CC_id] = 1;
888 889
	  }   
	  nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit+1;
890
          ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit - 1;
891
        } else {
892 893
	  if (nb_rbs_required_remaining[CC_id][UE_id] >=  min_rb_unit){
	    rballoc_sub[CC_id][i] = 1;
894
	    ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1;
895 896
	    MIMO_mode_indicator[CC_id][i] = 1;
	    if (transmission_mode == 5 ) {
897
	      ue_sched_ctl->dl_pow_off[CC_id] = 1;
898 899
	    }
	    nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit;
900
	    ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit;
901 902
	  }
	}
903 904
      } // dl_pow_off[CC_id][UE_id] ! = 0
    }
905 906
  }

907 908 909
}


910
/// ULSCH PRE_PROCESSOR
911

912

913
void ulsch_scheduler_pre_processor(module_id_t module_idP,
914 915 916
                                   int frameP,
                                   sub_frame_t subframeP,
                                   uint16_t *first_rb,
917
                                   uint8_t aggregation)
918
{
919 920 921 922 923 924 925 926

  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;
927
  UE_list_t          *UE_list = &eNB_mac_inst[module_idP].UE_list;
928 929
  UE_TEMPLATE        *UE_template = 0;
  LTE_DL_FRAME_PARMS   *frame_parms = 0;
930

931
  // LOG_I(MAC,"store ulsch buffers\n");
932 933
  // convert BSR to bytes for comparison with tbs
  store_ulsch_buffer(module_idP,frameP, subframeP);
934

935
  //LOG_I(MAC,"assign max mcs min rb\n");
936 937
  // 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);
938

939
  //LOG_I(MAC,"sort ue \n");
940
  // sort ues
941 942
  sort_ue_ul (module_idP,frameP, subframeP);

943

944 945
  // we need to distribute RBs among UEs
  // step1:  reset the vars
946
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
947 948 949
    total_allocated_rbs[CC_id]=0;
    total_remaining_rbs[CC_id]=0;
    average_rbs_per_user[CC_id]=0;
950 951

    for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) {
952 953 954 955
      nb_allocated_rbs[CC_id][i]=0;
    }
  }

956
  //LOG_I(MAC,"step2 \n");
957 958 959
  // step 2: calculate the average rb per UE
  total_ue_count =0;
  max_num_ue_to_be_scheduled=0;
960 961 962 963 964

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

    rnti = UE_RNTI(module_idP,i);

965
    if (rnti==NOT_A_RNTI)
966 967 968
      continue;

    UE_id = i;
969 970

    for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) {
971 972 973 974
      // 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;
975 976
      frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id);

977
      if (UE_template->pre_allocated_nb_rb_ul > 0) {
978
        total_ue_count+=1;
979
      }
980 981
      /*
      if((mac_xface->get_nCCE_max(module_idP,CC_id,3,subframeP) - nCCE_to_be_used[CC_id])  > (1<<aggregation)) {
982 983
        nCCE_to_be_used[CC_id] = nCCE_to_be_used[CC_id] + (1<<aggregation);
        max_num_ue_to_be_scheduled+=1;
984 985 986
	}*/

      max_num_ue_to_be_scheduled+=1;
987

988
      if (total_ue_count == 0) {
989
        average_rbs_per_user[CC_id] = 0;
990
      } else if (total_ue_count == 1 ) { // increase the available RBs, special case,
991
        average_rbs_per_user[CC_id] = frame_parms->N_RB_UL-first_rb[CC_id]+1;
992
      } else if( (total_ue_count <= (frame_parms->N_RB_DL-first_rb[CC_id])) &&
993
                 (total_ue_count <= max_num_ue_to_be_scheduled)) {
994
        average_rbs_per_user[CC_id] = (uint16_t) floor((frame_parms->N_RB_UL-first_rb[CC_id])/total_ue_count);
995
      } else if (max_num_ue_to_be_scheduled > 0 ) {
996
        average_rbs_per_user[CC_id] = (uint16_t) floor((frame_parms->N_RB_UL-first_rb[CC_id])/max_num_ue_to_be_scheduled);
997
      } else {
998 999 1000
        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);
1001 1002 1003
      }
    }
  }
1004 1005 1006
  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);
1007

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

1010 1011 1012 1013
  // step 3: assigne RBS
  for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) {
    rnti = UE_RNTI(module_idP,i);

1014
    if (rnti==NOT_A_RNTI)
1015
      continue;
1016

1017
    UE_id = i;
1018 1019

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

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

1025
      if(round>0) {
1026
        nb_allocated_rbs[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb_ul[harq_pid];
1027
      } else {
1028
        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]);
1029
      }
1030

1031
      total_allocated_rbs[CC_id]+= nb_allocated_rbs[CC_id][UE_id];
1032

1033 1034
    }
  }
1035

1036
  // step 4: assigne the remaining RBs and set the pre_allocated rbs accordingly
1037 1038 1039 1040 1041
  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);

1042
      if (rnti==NOT_A_RNTI)
1043 1044
        continue;

1045
      UE_id = i;
1046 1047 1048 1049 1050 1051 1052 1053

      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];

1054
        if (total_ue_count == 1 ) {
1055
          total_remaining_rbs[CC_id]+=1;
1056
        }
1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070

        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);
        }
1071 1072 1073
      }
    }
  }
1074 1075

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

1078
    if (total_allocated_rbs[CC_id]>0) {
1079
      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]);
1080
    }
1081
  }
1082 1083 1084 1085 1086
}


void store_ulsch_buffer(module_id_t module_idP, int frameP, sub_frame_t subframeP)
{
1087 1088 1089

  int                 UE_id,pCC_id,lcgid;
  UE_list_t           *UE_list = &eNB_mac_inst[module_idP].UE_list;
1090 1091 1092 1093 1094
  UE_TEMPLATE         *UE_template;

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


1095
    UE_template = &UE_list->UE_template[UE_PCCID(module_idP,UE_id)][UE_id];
1096 1097
    //LOG_I(MAC,"[UE %d next %d] SR is %d\n",UE_id, UE_list->next_ul[UE_id], UE_template->ul_SR);

1098
    UE_template->ul_total_buffer=0;
1099 1100

    for (lcgid=0; lcgid<MAX_NUM_LCGID; lcgid++) {
1101
      UE_template->ul_buffer_info[lcgid]=BSR_TABLE[UE_template->bsr_info[lcgid]];
1102
      UE_template->ul_total_buffer+= UE_template->ul_buffer_info[lcgid]; // apply traffic aggregtaion if packets are small
1103 1104
      //   UE_template->ul_buffer_creation_time_max=cmax(UE_template->ul_buffer_creation_time_max, frame_cycle*1024 + frameP-UE_template->ul_buffer_creation_time[lcgid]));
    }
1105

1106
    if ( UE_template->ul_total_buffer >0)
1107 1108 1109 1110 1111 1112 1113 1114
      LOG_D(MAC,"[eNB %d] Frame %d subframe %d UE %d CC id %d: LCGID0 %d, LCGID1 %d, LCGID2 %d LCGID3 %d, BO %d\n",
            module_idP, frameP,subframeP, UE_id, UE_PCCID(module_idP,UE_id),
            UE_template->ul_buffer_info[LCGID0],
            UE_template->ul_buffer_info[LCGID1],
            UE_template->ul_buffer_info[LCGID2],
            UE_template->ul_buffer_info[LCGID3],
            UE_template->ul_total_buffer);
    else if (UE_is_to_be_scheduled(module_idP,UE_PCCID(module_idP,UE_id),UE_id) > 0 ) {
1115
      if (UE_template->ul_total_buffer == 0 ) {
1116
        UE_template->ul_total_buffer = BSR_TABLE[11];
1117
      }
1118

1119
      LOG_D(MAC,"[eNB %d] Frame %d subframe %d UE %d CC id %d: SR active, set BO to %d \n",
1120 1121
            module_idP, frameP,subframeP, UE_id, UE_PCCID(module_idP,UE_id),
            UE_template->ul_total_buffer);
1122
    }
1123
  }
1124 1125 1126 1127
}



1128 1129 1130
void assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subframeP, uint16_t *first_rb)
{

1131 1132 1133 1134
  int                i;
  uint16_t           n,UE_id;
  uint8_t            CC_id;
  rnti_t             rnti           = -1;
1135
  int                mcs=cmin(16,openair_daq_vars.target_ue_ul_mcs);
Raymond Knopp's avatar
 
Raymond Knopp committed
1136
  int                rb_table_index=0,tbs,tx_power;
1137
  eNB_MAC_INST       *eNB = &eNB_mac_inst[module_idP];
1138 1139
  UE_list_t          *UE_list = &eNB->UE_list;

1140 1141
  UE_TEMPLATE       *UE_template;
  LTE_DL_FRAME_PARMS   *frame_parms;
1142 1143 1144 1145 1146

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

    rnti = UE_RNTI(module_idP,i);

1147
    if (rnti==NOT_A_RNTI)
1148 1149 1150
      continue;

    UE_id = i;
1151 1152

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

1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170
      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]);
1171
      frame_parms=mac_xface->get_lte_frame_parms(module_idP,CC_id);
1172
      UE_template = &UE_list->UE_template[CC_id][UE_id];
1173 1174

      // if this UE has UL traffic
1175
      if (UE_template->ul_total_buffer > 0 ) {
1176

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

1181
        while ((((UE_template->phr_info - tx_power) < 0 ) || (tbs > UE_template->ul_total_buffer))&&
1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198
               (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);
        }

1199
        UE_template->ue_tx_power = tx_power;
1200 1201 1202 1203 1204 1205

        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!
1206
	if (rb_table[rb_table_index]<3) {
1207
          rb_table_index=2; //3PRB
1208
        }
1209 1210 1211 1212 1213 1214 1215 1216 1217 1218

        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);
1219
      } else {
1220 1221
        UE_template->pre_allocated_rb_table_index_ul=-1;
        UE_template->pre_allocated_nb_rb_ul=0;
1222 1223 1224 1225 1226 1227
      }
    }
  }
}


1228 1229
void sort_ue_ul (module_id_t module_idP,int frameP, sub_frame_t subframeP)
{
1230 1231 1232 1233 1234 1235 1236 1237

  int               UE_id1,UE_id2;
  int               pCCid1,pCCid2;
  int               round1,round2;
  int               i=0,ii=0,j=0;
  rnti_t            rnti1,rnti2;

  UE_list_t *UE_list = &eNB_mac_inst[module_idP].UE_list;
1238 1239

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

    //LOG_I(MAC,"sort ue ul i %d\n",i);
1242
    for (ii=UE_list->next_ul[i]; ii>=0; ii=UE_list->next_ul[ii]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1243
      //LOG_I(MAC,"sort ul ue 2 ii %d\n",ii);
1244 1245 1246 1247 1248 1249
 
      UE_id1  = i;
      rnti1 = UE_RNTI(module_idP,UE_id1);
      
      if(rnti1 == NOT_A_RNTI)
      continue;
Raymond Knopp's avatar
 
Raymond Knopp committed
1250

1251 1252 1253 1254 1255 1256
      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);
      
1257
      if(rnti2 == NOT_A_RNTI)
1258 1259
        continue;

1260
      pCCid2 = UE_PCCID(module_idP,UE_id2);
1261 1262 1263 1264 1265 1266 1267 1268 1269 1270
      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) {
1271
          if (UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer > 0 ) {
1272
            swap_UEs(UE_list,UE_id1,UE_id2,1);
1273
          }
1274
        }
1275 1276 1277 1278
      }
    }
  }
}