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

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


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

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

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

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, 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 161
  UE_TEMPLATE           *UE_template;
  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
      eNB_UE_stats[CC_id]->dlsch_mcs1 = cmin(eNB_UE_stats[CC_id]->dlsch_mcs1,openair_daq_vars.target_ue_dl_mcs);
180

Raymond Knopp's avatar
 
Raymond Knopp committed
181
    }
182

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

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

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

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

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

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


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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
253 254
  uint8_t round,round_max=0,harq_pid;
  int CC_id;
255

256
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
257
    mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frame,subframe,&harq_pid,&round,ul_flag);
258

259
    if (round > round_max) {
Raymond Knopp's avatar
 
Raymond Knopp committed
260
      round_max = round;
261
    }
262 263
  }

264
  return round_max;
Raymond Knopp's avatar
 
Raymond Knopp committed
265
}
266

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

269 270
int maxcqi(module_id_t Mod_id,int32_t UE_id)
{
271

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

277
  for (n=0; n<UE_list->numactiveCCs[UE_id]; n++) {
278 279
    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));
280

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

286
    if (eNB_UE_stats->DL_cqi[0] > CQI) {
Raymond Knopp's avatar
 
Raymond Knopp committed
287
      CQI = eNB_UE_stats->DL_cqi[0];
288
    }
289
  }
290

Raymond Knopp's avatar
 
Raymond Knopp committed
291 292
  return(CQI);
}
293 294 295



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


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

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

311
  for (i=UE_list->head; i>=0; i=UE_list->next[i]) {
312

Raymond Knopp's avatar
 
Raymond Knopp committed
313
    rnti1 = UE_RNTI(Mod_idP,i);
314

315
    if(rnti1 == NOT_A_RNTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
316
      continue;
317

Raymond Knopp's avatar
 
Raymond Knopp committed
318
    UE_id1  = i;
Raymond Knopp's avatar
 
Raymond Knopp committed
319
    pCC_id1 = UE_PCCID(Mod_idP,UE_id1);
320
    cqi1    = maxcqi(Mod_idP,UE_id1); //
321
    round1  = maxround(Mod_idP,rnti1,frameP,subframeP,0);
322 323


324
    for(ii=UE_list->next[i]; ii>=0; ii=UE_list->next[ii]) {
325

Raymond Knopp's avatar
 
Raymond Knopp committed
326
      UE_id2 = ii;
Raymond Knopp's avatar
 
Raymond Knopp committed
327
      rnti2 = UE_RNTI(Mod_idP,UE_id2);
328

329
      if(rnti2 == NOT_A_RNTI)
330
        continue;
331

332
      cqi2    = maxcqi(Mod_idP,UE_id2);
333
      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
334
      pCC_id2 = UE_PCCID(Mod_idP,UE_id2);
335

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

363

Raymond Knopp's avatar
 
Raymond Knopp committed
364 365


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

Raymond Knopp's avatar
 
Raymond Knopp committed
377 378
  unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],harq_pid=0,harq_pid1=0,harq_pid2=0,round=0,round1=0,round2=0,total_ue_count;
  unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX];
Raymond Knopp's avatar
 
Raymond Knopp committed
379
  int                     UE_id, UE_id2, 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                i1,i2,i3,r1=0;
385
  uint16_t                average_rbs_per_user[MAX_NUM_CCs] = {0};
386 387 388
  rnti_t             rnti,rnti1,rnti2;
  LTE_eNB_UE_stats  *eNB_UE_stats1 = NULL;
  LTE_eNB_UE_stats  *eNB_UE_stats2 = NULL;
Raymond Knopp's avatar
 
Raymond Knopp committed
389 390
  int                min_rb_unit[MAX_NUM_CCs];

391
  uint8_t CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
392
  UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
393
  LTE_DL_FRAME_PARMS   *frame_parms[MAX_NUM_CCs] = {0};
394 395
  int rrc_status           = RRC_IDLE;
  int transmission_mode = 0;
396 397

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
398 399 400

    if (mbsfn_flag[CC_id]>0)  // If this CC is allocated for MBSFN skip it here
      continue;
401 402 403

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

Raymond Knopp's avatar
 
Raymond Knopp committed
404

405
    min_rb_unit[CC_id]=get_min_rb_unit(Mod_id,CC_id);
406 407

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

411
      dlsch_scheduler_pre_processor_reset(
412 413 414 415 416 417 418 419 420 421
        UE_id,
        CC_id,
        N_RBG[CC_id],
        dl_pow_off,
        nb_rbs_required,
        pre_nb_available_rbs,
        nb_rbs_required_remaining,
        rballoc_sub_UE,
        rballoc_sub,
        MIMO_mode_indicator);
422

Raymond Knopp's avatar
 
Raymond Knopp committed
423
    }
424
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
425 426 427



428
  // Store the DLSCH buffer for each logical channel
429
  store_dlsch_buffer (Mod_id,frameP,subframeP);
430

Raymond Knopp's avatar
 
Raymond Knopp committed
431 432


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

Raymond Knopp's avatar
 
Raymond Knopp committed
436 437


438
  // Sorts the user on the basis of dlsch logical channel buffer and CQI
Raymond Knopp's avatar
 
Raymond Knopp committed
439 440 441
  sort_UEs (Mod_id,frameP,subframeP);


Raymond Knopp's avatar
 
Raymond Knopp committed
442

443
  total_ue_count =0;
444

Raymond Knopp's avatar
 
Raymond Knopp committed
445
  // loop over all active UEs
446
  for (i=UE_list->head; i>=0; i=UE_list->next[i]) {
447
    rnti = UE_RNTI(Mod_id,i);
448

449
    if(rnti == NOT_A_RNTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
450
      continue;
451

452
    UE_id = i;
453 454

    for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
455 456 457 458
      CC_id = UE_list->ordered_CCids[ii][UE_id];

      average_rbs_per_user[CC_id]=0;

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

Raymond Knopp's avatar
 
Raymond Knopp committed
461
      mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0);
462

463
      if(round>0) {
464
        nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
465
      }
466

Raymond Knopp's avatar
 
Raymond Knopp committed
467 468
      //nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id];
      if (nb_rbs_required[CC_id][UE_id] > 0) {
469
        total_ue_count = total_ue_count + 1;
Raymond Knopp's avatar
 
Raymond Knopp committed
470
      }
471 472 473 474 475 476 477 478 479 480 481 482


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

483
      if (total_ue_count == 0) {
484
        average_rbs_per_user[CC_id] = 0;
485
      } else if( (min_rb_unit[CC_id] * total_ue_count) <= (frame_parms[CC_id]->N_RB_DL) ) {
486
        average_rbs_per_user[CC_id] = (uint16_t) floor(frame_parms[CC_id]->N_RB_DL/total_ue_count);
487
      } else {
488
        average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; // consider the total number of use that can be scheduled UE
489
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
490 491
    }
  }
492

493 494
  // note: nb_rbs_required is assigned according to total_buffer_dl
  // extend nb_rbs_required to capture per LCID RB required
495
  for(i=UE_list->head; i>=0; i=UE_list->next[i]) {
496
    rnti = UE_RNTI(Mod_id,i);
497

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

501
      // control channel
502
      if (mac_eNB_get_rrc_status(Mod_id,rnti) < RRC_RECONFIGURED) {
503
        nb_rbs_required_remaining_1[CC_id][i] = nb_rbs_required[CC_id][i];
504
      } else {
505 506
        nb_rbs_required_remaining_1[CC_id][i] = cmin(average_rbs_per_user[CC_id],nb_rbs_required[CC_id][i]);

507
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
508
    }
509
  }
510

511
  //Allocation to UEs is done in 2 rounds,
512 513
  // 1st stage: average number of RBs allocated to each UE
  // 2nd stage: remaining RBs are allocated to high priority UEs
514 515 516 517 518 519
  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];

520
        if(r1 == 0) {
521
          nb_rbs_required_remaining[CC_id][i] = nb_rbs_required_remaining_1[CC_id][i];
522
        } else { // rb required based only on the buffer - rb allloctaed in the 1st round + extra reaming rb form the 1st round
523
          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];
524
        }
525 526 527 528 529 530 531 532 533 534 535

        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],
                pre_nb_available_rbs[CC_id][i],
                N_RBG[CC_id],
                min_rb_unit[CC_id]);

536
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
537
    }
538

539
    if (total_ue_count > 0 ) {
540 541 542 543 544 545 546 547 548
      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];

          rnti = UE_RNTI(Mod_id,UE_id);

          // LOG_D(MAC,"UE %d rnti 0x\n", UE_id, rnti );
549
          if(rnti == NOT_A_RNTI)
550 551 552 553
            continue;

          transmission_mode = mac_xface->get_transmission_mode(Mod_id,CC_id,rnti);
          mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0);
554
          rrc_status = mac_eNB_get_rrc_status(Mod_id,rnti);
555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575
          /* 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,
                                                  dl_pow_off,
                                                  nb_rbs_required,
                                                  pre_nb_available_rbs,
                                                  nb_rbs_required_remaining,
                                                  rballoc_sub_UE,
                                                  rballoc_sub,
                                                  MIMO_mode_indicator);

576
#ifdef TM5
577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593

          // data chanel TM5: to be revisted
          if ((round == 0 )  &&
              (transmission_mode == 5)  &&
              (dl_pow_off[CC_id][UE_id] != 1)) {

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

              if( (((j == (N_RBG[CC_id]-1))&& (rballoc_sub[CC_id][j] == 0) && (rballoc_sub_UE[CC_id][UE_id][j] == 0))  ||
                   ((j < (N_RBG[CC_id]-1)) && (rballoc_sub[CC_id][j+1] == 0) && (rballoc_sub_UE[CC_id][UE_id][j+1] == 0)) ) &&
                  (nb_rbs_required_remaining[CC_id][UE_id]>0)) {

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

                  UE_id2 = ii;
                  rnti2 = UE_RNTI(Mod_id,UE_id2);

594
                  if(rnti2 == NOT_A_RNTI)
595 596 597 598 599
                    continue;

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

600
                  if ((mac_eNB_get_rrc_status(Mod_id,rnti2) >= RRC_RECONFIGURED) &&
601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651
                      (round2==0) &&
                      (mac_xface->get_transmission_mode(Mod_id,CC_id,rnti2)==5) &&
                      (dl_pow_off[CC_id][UE_id2] != 1)) {

                    if( (((j == (N_RBG[CC_id]-1)) && (rballoc_sub_UE[CC_id][UE_id2][j] == 0)) ||
                         ((j < (N_RBG[CC_id]-1)) && (rballoc_sub_UE[CC_id][UE_id2][j+1] == 0))  ) &&
                        (nb_rbs_required_remaining[CC_id][UE_id2]>0)) {

                      if((((eNB_UE_stats2->DL_pmi_single^eNB_UE_stats1->DL_pmi_single)<<(14-j))&0xc000)== 0x4000) { //MU-MIMO only for 25 RBs configuration

                        rballoc_sub[CC_id][j] = 1;
                        rballoc_sub_UE[CC_id][UE_id][j] = 1;
                        rballoc_sub_UE[CC_id][UE_id2][j] = 1;
                        MIMO_mode_indicator[CC_id][j] = 0;

                        if (j< N_RBG[CC_id]-1) {
                          rballoc_sub[CC_id][j+1] = 1;
                          rballoc_sub_UE[CC_id][UE_id][j+1] = 1;
                          rballoc_sub_UE[CC_id][UE_id2][j+1] = 1;
                          MIMO_mode_indicator[CC_id][j+1] = 0;
                        }

                        dl_pow_off[CC_id][UE_id] = 0;
                        dl_pow_off[CC_id][UE_id2] = 0;


                        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))) {
                          nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id]+1;
                          pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + min_rb_unit[CC_id]-1;
                          nb_rbs_required_remaining[CC_id][UE_id2] = nb_rbs_required_remaining[CC_id][UE_id2] - min_rb_unit[CC_id]+1;
                          pre_nb_available_rbs[CC_id][UE_id2] = pre_nb_available_rbs[CC_id][UE_id2] + min_rb_unit[CC_id]-1;
                        } else {
                          nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - 4;
                          pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + 4;
                          nb_rbs_required_remaining[CC_id][UE_id2] = nb_rbs_required_remaining[CC_id][UE_id2] - 4;
                          pre_nb_available_rbs[CC_id][UE_id2] = pre_nb_available_rbs[CC_id][UE_id2] + 4;
                        }

                        break;
                      }
                    }
                  }
                }
              }
            }
          }

#endif
        }
Raymond Knopp's avatar
 
Raymond Knopp committed
652
      }
653
    } // total_ue_count
654
  } // end of for for r1 and r2
655 656 657

#ifdef TM5

Raymond Knopp's avatar
 
Raymond Knopp committed
658
  // This has to be revisited!!!!
659
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
660 661 662
    i1=0;
    i2=0;
    i3=0;
663 664

    for (j=0; j<N_RBG[CC_id]; j++) {
665
      if(MIMO_mode_indicator[CC_id][j] == 2) {
666
        i1 = i1+1;
667
      } else if(MIMO_mode_indicator[CC_id][j] == 1) {
668
        i2 = i2+1;
669
      } else if(MIMO_mode_indicator[CC_id][j] == 0) {
670
        i3 = i3+1;
671
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
672
    }
673

674
    if((i1 < N_RBG[CC_id]) && (i2>0) && (i3==0)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
675
      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;
676
    }
677

678
    if(i3 == N_RBG[CC_id] && i1==0 && i2==0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
679
      PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions + 1;
680
    }
681

682
    if((i1 < N_RBG[CC_id]) && (i3 > 0)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
683
      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;
684
    }
685

Raymond Knopp's avatar
 
Raymond Knopp committed
686
    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;
687

688 689
  }

690 691 692
#endif

  for(i=UE_list->head; i>=0; i=UE_list->next[i]) {
693
    UE_id = i;
694 695

    for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
696
      CC_id = UE_list->ordered_CCids[ii][UE_id];
697
      //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id];
698 699 700 701 702 703 704 705 706 707 708 709 710

      if (pre_nb_available_rbs[CC_id][UE_id] > 0 ) {
        LOG_D(MAC,"******************DL Scheduling Information for UE%d ************************\n",UE_id);
        LOG_D(MAC,"dl power offset UE%d = %d \n",UE_id,dl_pow_off[CC_id][UE_id]);
        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];
          LOG_D(MAC,"RB Alloc for UE%d and Subband%d = %d\n",UE_id,j,rballoc_sub_UE[CC_id][UE_id][j]);
        }

        //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id];
        LOG_D(MAC,"Total RBs allocated for UE%d = %d\n",UE_id,pre_nb_available_rbs[CC_id][UE_id]);
711
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
712
    }
713 714 715
  }
}

716

717 718 719 720 721 722 723 724 725 726 727
void dlsch_scheduler_pre_processor_reset (int UE_id,
    uint8_t  CC_id,
    int N_RBG,
    uint8_t dl_pow_off[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
    uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
    uint16_t pre_nb_available_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
    uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
    unsigned char rballoc_sub_UE[MAX_NUM_CCs][NUMBER_OF_UE_MAX][N_RBG_MAX],
    unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
    unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX])
{
728 729 730 731 732
  int i;
  nb_rbs_required[CC_id][UE_id]=0;
  pre_nb_available_rbs[CC_id][UE_id] = 0;
  dl_pow_off[CC_id][UE_id] = 2;
  nb_rbs_required_remaining[CC_id][UE_id] = 0;
733 734

  for (i=0; i<N_RBG; i++) {
735 736
    rballoc_sub_UE[CC_id][UE_id][i] = 0;
    rballoc_sub[CC_id][i] = 0;
737
    MIMO_mode_indicator[CC_id][i] = 2;
738 739 740 741 742
  }
}


void dlsch_scheduler_pre_processor_allocate (module_id_t   Mod_id,
743 744 745 746 747 748 749 750 751 752 753 754 755 756 757
    int           UE_id,
    uint8_t       CC_id,
    int           N_RBG,
    int           transmission_mode,
    int           min_rb_unit,
    uint8_t       N_RB_DL,
    uint8_t       dl_pow_off[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
    uint16_t      nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
    uint16_t      pre_nb_available_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
    uint16_t      nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
    unsigned char rballoc_sub_UE[MAX_NUM_CCs][NUMBER_OF_UE_MAX][N_RBG_MAX],
    unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
    unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX])
{

758
  int i;
759 760 761 762 763 764 765 766

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

    if((rballoc_sub[CC_id][i] == 0)           &&
        (rballoc_sub_UE[CC_id][UE_id][i] == 0) &&
        (nb_rbs_required_remaining[CC_id][UE_id]>0)   &&
        (pre_nb_available_rbs[CC_id][UE_id] < nb_rbs_required[CC_id][UE_id])) {

767 768
      // if this UE is not scheduled for TM5
      if (dl_pow_off[CC_id][UE_id] != 0 )  {
769 770 771 772 773

        rballoc_sub[CC_id][i] = 1;
        rballoc_sub_UE[CC_id][UE_id][i] = 1;
        MIMO_mode_indicator[CC_id][i] = 1;

774
        if (transmission_mode == 5 ) {
775
          dl_pow_off[CC_id][UE_id] = 1;
776
        }
777 778 779 780 781 782 783 784

        if ((i == N_RBG-1) && ((N_RB_DL == 25) || (N_RB_DL == 50))) {
          nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit+1;
          pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + min_rb_unit - 1;
        } else {
          nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit;
          pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + min_rb_unit;
        }
785 786
      } // dl_pow_off[CC_id][UE_id] ! = 0
    }
787 788
  }

789 790 791
}


792
/// ULSCH PRE_PROCESSOR
793

794

795
void ulsch_scheduler_pre_processor(module_id_t module_idP,
796 797 798 799 800 801
                                   int frameP,
                                   sub_frame_t subframeP,
                                   uint16_t *first_rb,
                                   uint8_t aggregation,
                                   uint32_t *nCCE)
{
802 803 804 805 806 807 808 809

  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;
810
  uint32_t            nCCE_to_be_used[MAX_NUM_CCs];
811
  UE_list_t          *UE_list = &eNB_mac_inst[module_idP].UE_list;
812 813
  UE_TEMPLATE        *UE_template = 0;
  LTE_DL_FRAME_PARMS   *frame_parms = 0;
814

815
  // LOG_I(MAC,"store ulsch buffers\n");
816 817
  // convert BSR to bytes for comparison with tbs
  store_ulsch_buffer(module_idP,frameP, subframeP);
818

819
  //LOG_I(MAC,"assign max mcs min rb\n");
820 821
  // 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);
822

823
  //LOG_I(MAC,"sort ue \n");
824
  // sort ues
825 826
  sort_ue_ul (module_idP,frameP, subframeP);

827

828 829
  // we need to distribute RBs among UEs
  // step1:  reset the vars
830
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
831 832 833 834
    nCCE_to_be_used[CC_id]= nCCE[CC_id];
    total_allocated_rbs[CC_id]=0;
    total_remaining_rbs[CC_id]=0;
    average_rbs_per_user[CC_id]=0;
835 836

    for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) {
837 838 839 840
      nb_allocated_rbs[CC_id][i]=0;
    }
  }

841
  //LOG_I(MAC,"step2 \n");
842 843 844
  // step 2: calculate the average rb per UE
  total_ue_count =0;
  max_num_ue_to_be_scheduled=0;
845 846 847 848 849

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

    rnti = UE_RNTI(module_idP,i);

850
    if (rnti==NOT_A_RNTI)
851 852 853
      continue;

    UE_id = i;
854 855

    for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) {
856 857 858 859
      // 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;
860 861
      frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id);

862
      if (UE_template->pre_allocated_nb_rb_ul > 0) {
863
        total_ue_count+=1;
864
      }
865 866 867 868

      if((mac_xface->get_nCCE_max(module_idP,CC_id) - nCCE_to_be_used[CC_id])  > (1<<aggregation)) {
        nCCE_to_be_used[CC_id] = nCCE_to_be_used[CC_id] + (1<<aggregation);
        max_num_ue_to_be_scheduled+=1;
869 870
      }

871
      if (total_ue_count == 0) {
872
        average_rbs_per_user[CC_id] = 0;
873
      } else if (total_ue_count == 1 ) { // increase the available RBs, special case,
874
        average_rbs_per_user[CC_id] = frame_parms->N_RB_UL-first_rb[CC_id]+1;
875
      } else if( (total_ue_count <= (frame_parms->N_RB_DL-first_rb[CC_id])) &&
876
                 (total_ue_count <= max_num_ue_to_be_scheduled)) {
877
        average_rbs_per_user[CC_id] = (uint16_t) floor((frame_parms->N_RB_UL-first_rb[CC_id])/total_ue_count);
878
      } else if (max_num_ue_to_be_scheduled > 0 ) {
879
        average_rbs_per_user[CC_id] = (uint16_t) floor((frame_parms->N_RB_UL-first_rb[CC_id])/max_num_ue_to_be_scheduled);
880
      } else {
881 882 883
        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);
884 885 886
      }
    }
  }
887 888 889

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

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

893 894 895 896
  // step 3: assigne RBS
  for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) {
    rnti = UE_RNTI(module_idP,i);

897
    if (rnti==NOT_A_RNTI)
898
      continue;
899

900
    UE_id = i;
901 902

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

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

908
      if(round>0) {
909
        nb_allocated_rbs[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb_ul[harq_pid];
910
      } else {
911
        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]);
912
      }
913

914
      total_allocated_rbs[CC_id]+= nb_allocated_rbs[CC_id][UE_id];
915

916 917
    }
  }
918

919
  // step 4: assigne the remaining RBs and set the pre_allocated rbs accordingly
920 921 922 923 924
  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);

925
      if (rnti==NOT_A_RNTI)
926 927
        continue;

928
      UE_id = i;
929 930 931 932 933 934 935 936

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

937
        if (total_ue_count == 1 ) {
938
          total_remaining_rbs[CC_id]+=1;
939
        }
940 941 942 943 944 945 946 947 948 949 950 951 952 953

        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);
        }
954 955 956
      }
    }
  }
957 958

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

961
    if (total_allocated_rbs[CC_id]>0) {
962
      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]);
963
    }
964
  }
965 966 967 968 969
}


void store_ulsch_buffer(module_id_t module_idP, int frameP, sub_frame_t subframeP)
{
970 971 972

  int                 UE_id,pCC_id,lcgid;
  UE_list_t           *UE_list = &eNB_mac_inst[module_idP].UE_list;
973 974 975 976 977
  UE_TEMPLATE         *UE_template;

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


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

981
    UE_template->ul_total_buffer=0;
982 983

    for (lcgid=0; lcgid<MAX_NUM_LCGID; lcgid++) {
984
      UE_template->ul_buffer_info[lcgid]=BSR_TABLE[UE_template->bsr_info[lcgid]];
985
      UE_template->ul_total_buffer+= UE_template->ul_buffer_info[lcgid]; // apply traffic aggregtaion if packets are small
986 987
      //   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]));
    }
988

989
    if ( UE_template->ul_total_buffer >0)
990 991 992 993 994 995 996 997
      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 ) {
998
      if (UE_template->ul_total_buffer == 0 ) {
999
        UE_template->ul_total_buffer = BSR_TABLE[11];
1000
      }
1001

1002
      LOG_D(MAC,"[eNB %d] Frame %d subframe %d UE %d CC id %d: SR active, set BO to %d \n",
1003 1004
            module_idP, frameP,subframeP, UE_id, UE_PCCID(module_idP,UE_id),
            UE_template->ul_total_buffer);
1005
    }
1006
  }
1007 1008 1009 1010
}



1011 1012 1013
void assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subframeP, uint16_t *first_rb)
{

1014 1015 1016 1017
  int                i;
  uint16_t           n,UE_id;
  uint8_t            CC_id;
  rnti_t             rnti           = -1;
1018
  int                mcs=cmin(16,openair_daq_vars.target_ue_ul_mcs);
Raymond Knopp's avatar
 
Raymond Knopp committed
1019
  int                rb_table_index=0,tbs,tx_power;
1020
  eNB_MAC_INST       *eNB = &eNB_mac_inst[module_idP];
1021 1022
  UE_list_t          *UE_list = &eNB->UE_list;

1023 1024
  UE_TEMPLATE       *UE_template;
  LTE_DL_FRAME_PARMS   *frame_parms;
1025 1026 1027 1028 1029

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

    rnti = UE_RNTI(module_idP,i);

1030
    if (rnti==NOT_A_RNTI)
1031 1032 1033
      continue;

    UE_id = i;
1034 1035

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

1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053
      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]);
1054
      frame_parms=mac_xface->get_lte_frame_parms(module_idP,CC_id);
1055
      UE_template = &UE_list->UE_template[CC_id][UE_id];
1056 1057

      // if this UE has UL traffic
1058
      if (UE_template->ul_total_buffer > 0 ) {
1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081

        tbs = mac_xface->get_TBS_UL(mcs,1);
        // fixme: set use_srs flag
        tx_power= mac_xface->estimate_ue_tx_power(tbs,rb_table[rb_table_index],0,frame_parms->Ncp,0);

        while (((UE_template->phr_info - tx_power) < 0 )  &&
               (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);
        }

1082
        UE_template->ue_tx_power = tx_power;
1083 1084 1085 1086 1087 1088

        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!
1089
        if (rb_table[rb_table_index]<3) {
1090
          rb_table_index=2; //3PRB
1091
        }
1092 1093 1094 1095 1096 1097 1098 1099 1100 1101

        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);
1102
      } else {
1103 1104
        UE_template->pre_allocated_rb_table_index_ul=-1;
        UE_template->pre_allocated_nb_rb_ul=0;
1105 1106 1107 1108 1109 1110
      }
    }
  }
}


1111 1112
void sort_ue_ul (module_id_t module_idP,int frameP, sub_frame_t subframeP)
{
1113 1114 1115 1116 1117 1118 1119 1120

  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;
1121 1122

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

    //LOG_I(MAC,"sort ue ul i %d\n",i);

1126
    rnti1 = UE_RNTI(module_idP,i);
1127

1128
    if(rnti1 == NOT_A_RNTI)
1129
      continue;
1130

1131 1132
    UE_id1  = i;
    pCCid1 = UE_PCCID(module_idP,UE_id1);
1133
    round1  = maxround(module_idP,rnti1,frameP,subframeP,1);
1134

1135
    for (ii=UE_list->next_ul[i]; ii>=0; ii=UE_list->next_ul[ii]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1136 1137 1138

      //LOG_I(MAC,"sort ul ue 2 ii %d\n",ii);

1139
      rnti2 = UE_RNTI(module_idP,ii);
1140

1141
      if(rnti2 == NOT_A_RNTI)
1142 1143
        continue;

1144 1145
      UE_id2  = ii;
      pCCid2 = UE_PCCID(module_idP,UE_id2);
1146 1147 1148 1149 1150 1151 1152 1153 1154 1155
      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) {
1156
          if (UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer > 0 ) {
1157
            swap_UEs(UE_list,UE_id1,UE_id2,1);
1158
          }
1159
        }
1160 1161 1162 1163
      }
    }
  }
}