pre_processor.c 42.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 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 55 56
#include "LAYER2/MAC/extern.h"
#include "UTIL/LOG/log.h"
#include "UTIL/OPT/opt.h"
#include "OCG.h"
#include "OCG_extern.h"
#include "RRC/LITE/extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"


57

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

//#define ICIC 0

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

extern inline unsigned int taus(void);


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

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

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

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

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

    for(i=0; i< MAX_NUM_LCID; i++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
94 95 96 97 98
      UE_template->dl_buffer_info[i]=0;
      UE_template->dl_pdus_in_buffer[i]=0;
      UE_template->dl_buffer_head_sdu_creation_time[i]=0;
      UE_template->dl_buffer_head_sdu_remaining_size_to_send[i]=0;
    }
99

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
104 105 106 107
      rlc_status = mac_rlc_status_ind(Mod_id,UE_id, frameP,ENB_FLAG_YES,MBMS_FLAG_NO,i,0 );
      UE_template->dl_buffer_info[i] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel
      UE_template->dl_pdus_in_buffer[i] = rlc_status.pdus_in_buffer;
      UE_template->dl_buffer_head_sdu_creation_time[i] = rlc_status.head_sdu_creation_time ;
108 109
      UE_template->dl_buffer_head_sdu_creation_time_max = cmax(UE_template->dl_buffer_head_sdu_creation_time_max,
          rlc_status.head_sdu_creation_time );
Raymond Knopp's avatar
 
Raymond Knopp committed
110 111
      UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = rlc_status.head_sdu_remaining_size_to_send;
      UE_template->dl_buffer_head_sdu_is_segmented[i] = rlc_status.head_sdu_is_segmented;
112 113
      UE_template->dl_buffer_total += UE_template->dl_buffer_info[i];//storing the total dlsch buffer
      UE_template->dl_pdus_total   += UE_template->dl_pdus_in_buffer[i];
114

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

Raymond Knopp's avatar
 
Raymond Knopp committed
117 118 119 120
      /* note for dl_buffer_head_sdu_remaining_size_to_send[i] :
       * 0 if head SDU has not been segmented (yet), else remaining size not already segmented and sent
       */
      if (UE_template->dl_buffer_info[i]>0)
121 122 123 124 125 126 127 128
        LOG_D(MAC,"[eNB %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and size %d, head sdu queuing time %d, remaining size %d, is segmeneted %d \n",
              Mod_id, frameP, subframeP, UE_id,
              i, UE_template->dl_pdus_in_buffer[i],UE_template->dl_buffer_info[i],
              UE_template->dl_buffer_head_sdu_creation_time[i],
              UE_template->dl_buffer_head_sdu_remaining_size_to_send[i],
              UE_template->dl_buffer_head_sdu_is_segmented[i]
             );

Cedric Roux's avatar
Cedric Roux committed
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 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238

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

        if (eNB_UE_stats[CC_id]->dlsch_mcs1==0) nb_rbs_required[CC_id][UE_id] = 4;  // don't let the TBS get too small
        else nb_rbs_required[CC_id][UE_id] = min_rb_unit[CC_id];

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

        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
239 240 241 242
      }
    }
  }
}
243 244


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

247 248
int maxround(module_id_t Mod_id,uint16_t rnti,int frame,sub_frame_t subframe,uint8_t ul_flag )
{
249

Raymond Knopp's avatar
 
Raymond Knopp committed
250 251
  uint8_t round,round_max=0,harq_pid;
  int CC_id;
252

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

Raymond Knopp's avatar
 
Raymond Knopp committed
256 257
    if (round > round_max)
      round_max = round;
258 259
  }

260
  return round_max;
Raymond Knopp's avatar
 
Raymond Knopp committed
261
}
262

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

265 266
int maxcqi(module_id_t Mod_id,int32_t UE_id)
{
267

Raymond Knopp's avatar
 
Raymond Knopp committed
268
  LTE_eNB_UE_stats *eNB_UE_stats = NULL;
269 270
  UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
  int CC_id,n;
Raymond Knopp's avatar
 
Raymond Knopp committed
271
  int CQI = 0;
272

273
  for (n=0; n<UE_list->numactiveCCs[UE_id]; n++) {
274 275
    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));
276

277
    if (eNB_UE_stats==NULL) {
278
      mac_xface->macphy_exit("maxcqi: could not get eNB_UE_stats\n");
279 280
      return 0; // not reached
    }
281

Raymond Knopp's avatar
 
Raymond Knopp committed
282 283
    if (eNB_UE_stats->DL_cqi[0] > CQI)
      CQI = eNB_UE_stats->DL_cqi[0];
284
  }
285

Raymond Knopp's avatar
 
Raymond Knopp committed
286 287
  return(CQI);
}
288 289 290



Raymond Knopp's avatar
 
Raymond Knopp committed
291
// This fuction sorts the UE in order their dlsch buffer and CQI
Raymond Knopp's avatar
 
Raymond Knopp committed
292
void sort_UEs (module_id_t Mod_idP,
293 294 295
               int         frameP,
               sub_frame_t subframeP)
{
296 297


Raymond Knopp's avatar
 
Raymond Knopp committed
298 299 300 301 302
  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;
303

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

306
  for (i=UE_list->head; i>=0; i=UE_list->next[i]) {
307

Raymond Knopp's avatar
 
Raymond Knopp committed
308
    rnti1 = UE_RNTI(Mod_idP,i);
309

Raymond Knopp's avatar
 
Raymond Knopp committed
310 311
    if(rnti1 == 0)
      continue;
312

Raymond Knopp's avatar
 
Raymond Knopp committed
313
    UE_id1  = i;
Raymond Knopp's avatar
 
Raymond Knopp committed
314
    pCC_id1 = UE_PCCID(Mod_idP,UE_id1);
315
    cqi1    = maxcqi(Mod_idP,UE_id1); //
316
    round1  = maxround(Mod_idP,rnti1,frameP,subframeP,0);
317 318


319
    for(ii=UE_list->next[i]; ii>=0; ii=UE_list->next[ii]) {
320

Raymond Knopp's avatar
 
Raymond Knopp committed
321
      UE_id2 = ii;
Raymond Knopp's avatar
 
Raymond Knopp committed
322
      rnti2 = UE_RNTI(Mod_idP,UE_id2);
323

Raymond Knopp's avatar
 
Raymond Knopp committed
324
      if(rnti2 == 0)
325
        continue;
326

327
      cqi2    = maxcqi(Mod_idP,UE_id2);
328
      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
329
      pCC_id2 = UE_PCCID(Mod_idP,UE_id2);
330

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

358

Raymond Knopp's avatar
 
Raymond Knopp committed
359 360


361
// This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done
Raymond Knopp's avatar
 
Raymond Knopp committed
362
void dlsch_scheduler_pre_processor (module_id_t   Mod_id,
363 364 365 366 367 368 369 370
                                    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
371

Raymond Knopp's avatar
 
Raymond Knopp committed
372 373
  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
374
  int                     UE_id, UE_id2, 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                i1,i2,i3,r1=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
380
  uint16_t                average_rbs_per_user[MAX_NUM_CCs];
381 382 383
  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
384 385
  int                min_rb_unit[MAX_NUM_CCs];

386
  uint8_t CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
387
  UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
388
  LTE_DL_FRAME_PARMS   *frame_parms[MAX_NUM_CCs] = {0};
389 390
  int rrc_status           = RRC_IDLE;
  int transmission_mode = 0;
391 392

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
393 394 395

    if (mbsfn_flag[CC_id]>0)  // If this CC is allocated for MBSFN skip it here
      continue;
396 397 398

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

Raymond Knopp's avatar
 
Raymond Knopp committed
399

400
    min_rb_unit[CC_id]=get_min_rb_unit(Mod_id,CC_id);
401 402

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

406
      dlsch_scheduler_pre_processor_reset(UE_id,
407 408 409 410 411 412 413 414 415 416
                                          CC_id,
                                          N_RBG[CC_id],
                                          dl_pow_off,
                                          nb_rbs_required,
                                          pre_nb_available_rbs,
                                          nb_rbs_required_remaining,
                                          rballoc_sub_UE,
                                          rballoc_sub,
                                          MIMO_mode_indicator);

Raymond Knopp's avatar
 
Raymond Knopp committed
417
    }
418
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
419 420 421



422
  // Store the DLSCH buffer for each logical channel
423
  store_dlsch_buffer (Mod_id,frameP,subframeP);
424

Raymond Knopp's avatar
 
Raymond Knopp committed
425 426


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

Raymond Knopp's avatar
 
Raymond Knopp committed
430 431


432
  // Sorts the user on the basis of dlsch logical channel buffer and CQI
Raymond Knopp's avatar
 
Raymond Knopp committed
433 434 435
  sort_UEs (Mod_id,frameP,subframeP);


Raymond Knopp's avatar
 
Raymond Knopp committed
436

437
  total_ue_count =0;
438

Raymond Knopp's avatar
 
Raymond Knopp committed
439
  // loop over all active UEs
440
  for (i=UE_list->head; i>=0; i=UE_list->next[i]) {
441
    rnti = UE_RNTI(Mod_id,i);
442

Raymond Knopp's avatar
 
Raymond Knopp committed
443 444
    if(rnti == 0)
      continue;
445

446
    UE_id = i;
447 448

    for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
449 450 451 452
      CC_id = UE_list->ordered_CCids[ii][UE_id];

      average_rbs_per_user[CC_id]=0;

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

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

457
      if(round>0)
458 459
        nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];

Raymond Knopp's avatar
 
Raymond Knopp committed
460 461
      //nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id];
      if (nb_rbs_required[CC_id][UE_id] > 0) {
462
        total_ue_count = total_ue_count + 1;
Raymond Knopp's avatar
 
Raymond Knopp committed
463
      }
464 465 466 467 468 469 470 471 472 473 474 475 476 477


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

      if (total_ue_count == 0)
        average_rbs_per_user[CC_id] = 0;
478
      else if( (min_rb_unit[CC_id] * total_ue_count) <= (frame_parms[CC_id]->N_RB_DL) )
479 480 481
        average_rbs_per_user[CC_id] = (uint16_t) floor(frame_parms[CC_id]->N_RB_DL/total_ue_count);
      else
        average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; // consider the total number of use that can be scheduled UE
Raymond Knopp's avatar
 
Raymond Knopp committed
482 483
    }
  }
484

485 486
  // note: nb_rbs_required is assigned according to total_buffer_dl
  // extend nb_rbs_required to capture per LCID RB required
487 488
  for(i=UE_list->head; i>=0; i=UE_list->next[i]) {
    for (ii=0; ii<UE_num_active_CC(UE_list,i); ii++) {
489
      CC_id = UE_list->ordered_CCids[ii][i];
490

491 492
      // control channel
      if (mac_get_rrc_status(Mod_id,1,i) < RRC_RECONFIGURED)
493 494 495 496
        nb_rbs_required_remaining_1[CC_id][i] = nb_rbs_required[CC_id][i];
      else {
        nb_rbs_required_remaining_1[CC_id][i] = cmin(average_rbs_per_user[CC_id],nb_rbs_required[CC_id][i]);

497
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
498
    }
499
  }
500

501
  //Allocation to UEs is done in 2 rounds,
502 503
  // 1st stage: average number of RBs allocated to each UE
  // 2nd stage: remaining RBs are allocated to high priority UEs
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524
  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];

        if(r1 == 0)
          nb_rbs_required_remaining[CC_id][i] = nb_rbs_required_remaining_1[CC_id][i];
        else  // rb required based only on the buffer - rb allloctaed in the 1st round + extra reaming rb form the 1st round
          nb_rbs_required_remaining[CC_id][i] = nb_rbs_required[CC_id][i]-nb_rbs_required_remaining_1[CC_id][i]+nb_rbs_required_remaining[CC_id][i];

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

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

528
    if (total_ue_count > 0 ) {
529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564
      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 );
          if(rnti == 0)
            continue;

          transmission_mode = mac_xface->get_transmission_mode(Mod_id,CC_id,rnti);
          mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0);
          rrc_status = mac_get_rrc_status(Mod_id,1,UE_id);
          /* 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);

565
#ifdef TM5
566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 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

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

                  if(rnti2 == 0)
                    continue;

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

                  if ((mac_get_rrc_status(Mod_id,1,UE_id2) >= RRC_RECONFIGURED) &&
                      (round2==0) &&
                      (mac_xface->get_transmission_mode(Mod_id,CC_id,rnti2)==5) &&
                      (dl_pow_off[CC_id][UE_id2] != 1)) {

                    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
641
      }
642
    } // total_ue_count
643
  } // end of for for r1 and r2
644 645 646

#ifdef TM5

Raymond Knopp's avatar
 
Raymond Knopp committed
647
  // This has to be revisited!!!!
648
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
649 650 651
    i1=0;
    i2=0;
    i3=0;
652 653

    for (j=0; j<N_RBG[CC_id]; j++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
654
      if(MIMO_mode_indicator[CC_id][j] == 2)
655
        i1 = i1+1;
Raymond Knopp's avatar
 
Raymond Knopp committed
656
      else if(MIMO_mode_indicator[CC_id][j] == 1)
657
        i2 = i2+1;
Raymond Knopp's avatar
 
Raymond Knopp committed
658
      else if(MIMO_mode_indicator[CC_id][j] == 0)
659
        i3 = i3+1;
Raymond Knopp's avatar
 
Raymond Knopp committed
660
    }
661

662
    if((i1 < N_RBG[CC_id]) && (i2>0) && (i3==0))
Raymond Knopp's avatar
 
Raymond Knopp committed
663
      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;
664

665
    if(i3 == N_RBG[CC_id] && i1==0 && i2==0)
Raymond Knopp's avatar
 
Raymond Knopp committed
666
      PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions + 1;
667

668
    if((i1 < N_RBG[CC_id]) && (i3 > 0))
Raymond Knopp's avatar
 
Raymond Knopp committed
669
      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;
670

Raymond Knopp's avatar
 
Raymond Knopp committed
671
    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;
672

673 674
  }

675 676 677
#endif

  for(i=UE_list->head; i>=0; i=UE_list->next[i]) {
678
    UE_id = i;
679 680

    for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
681
      CC_id = UE_list->ordered_CCids[ii][UE_id];
682
      //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id];
683 684 685 686 687 688 689 690 691 692 693 694 695

      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]);
696
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
697
    }
698 699 700
  }
}

701

702 703 704 705 706 707 708 709 710 711 712
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])
{
713 714 715 716 717
  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;
718 719

  for (i=0; i<N_RBG; i++) {
720 721
    rballoc_sub_UE[CC_id][UE_id][i] = 0;
    rballoc_sub[CC_id][i] = 0;
722
    MIMO_mode_indicator[CC_id][i] = 2;
723 724 725 726 727
  }
}


void dlsch_scheduler_pre_processor_allocate (module_id_t   Mod_id,
728 729 730 731 732 733 734 735 736 737 738 739 740 741 742
    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])
{

743
  int i;
744 745 746 747 748 749 750 751

  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])) {

752 753
      // if this UE is not scheduled for TM5
      if (dl_pow_off[CC_id][UE_id] != 0 )  {
754 755 756 757 758 759 760 761 762 763 764 765 766 767 768

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

        if (transmission_mode == 5 )
          dl_pow_off[CC_id][UE_id] = 1;

        if ((i == N_RBG-1) && ((N_RB_DL == 25) || (N_RB_DL == 50))) {
          nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit+1;
          pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + min_rb_unit - 1;
        } else {
          nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit;
          pre_nb_available_rbs[CC_id][UE_id] = pre_nb_available_rbs[CC_id][UE_id] + min_rb_unit;
        }
769 770
      } // dl_pow_off[CC_id][UE_id] ! = 0
    }
771 772
  }

773 774 775
}


776
/// ULSCH PRE_PROCESSOR
777

778

779
void ulsch_scheduler_pre_processor(module_id_t module_idP,
780 781 782 783 784 785
                                   int frameP,
                                   sub_frame_t subframeP,
                                   uint16_t *first_rb,
                                   uint8_t aggregation,
                                   uint32_t *nCCE)
{
786 787 788 789 790 791 792 793

  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;
794
  uint32_t            nCCE_to_be_used[MAX_NUM_CCs];
795
  UE_list_t          *UE_list = &eNB_mac_inst[module_idP].UE_list;
796 797
  UE_TEMPLATE        *UE_template = 0;
  LTE_DL_FRAME_PARMS   *frame_parms = 0;
798

799
  // LOG_I(MAC,"store ulsch buffers\n");
800 801
  // convert BSR to bytes for comparison with tbs
  store_ulsch_buffer(module_idP,frameP, subframeP);
802

803
  //LOG_I(MAC,"assign max mcs min rb\n");
804 805
  // 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);
806

807
  //LOG_I(MAC,"sort ue \n");
808
  // sort ues
809 810
  sort_ue_ul (module_idP,frameP, subframeP);

811

812 813
  // we need to distribute RBs among UEs
  // step1:  reset the vars
814
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
815 816 817 818
    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;
819 820

    for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) {
821 822 823 824
      nb_allocated_rbs[CC_id][i]=0;
    }
  }

825
  //LOG_I(MAC,"step2 \n");
826 827 828
  // step 2: calculate the average rb per UE
  total_ue_count =0;
  max_num_ue_to_be_scheduled=0;
829 830 831 832 833 834

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

    rnti = UE_RNTI(module_idP,i);

    if (rnti==0)
835 836 837
      continue;

    UE_id = i;
838 839

    for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) {
840 841 842 843
      // 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;
844 845
      frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id);

846
      if (UE_template->pre_allocated_nb_rb_ul > 0) {
847
        total_ue_count+=1;
848
      }
849 850 851 852

      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;
853 854
      }

855 856
      if (total_ue_count == 0)
        average_rbs_per_user[CC_id] = 0;
857
      else if (total_ue_count == 1 ) // increase the available RBs, special case,
858 859 860 861 862 863
        average_rbs_per_user[CC_id] = frame_parms->N_RB_UL-first_rb[CC_id]+1;
      else if( (total_ue_count <= (frame_parms->N_RB_DL-first_rb[CC_id])) &&
               (total_ue_count <= max_num_ue_to_be_scheduled))
        average_rbs_per_user[CC_id] = (uint16_t) floor((frame_parms->N_RB_UL-first_rb[CC_id])/total_ue_count);
      else if (max_num_ue_to_be_scheduled > 0 )
        average_rbs_per_user[CC_id] = (uint16_t) floor((frame_parms->N_RB_UL-first_rb[CC_id])/max_num_ue_to_be_scheduled);
864
      else {
865 866 867
        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);
868 869 870
      }
    }
  }
871 872 873

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

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

877 878 879 880 881
  // step 3: assigne RBS
  for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) {
    rnti = UE_RNTI(module_idP,i);

    if (rnti==0)
882
      continue;
883

884
    UE_id = i;
885 886

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

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

892
      if(round>0)
893 894 895 896
        nb_allocated_rbs[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb_ul[harq_pid];
      else
        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]);

897
      total_allocated_rbs[CC_id]+= nb_allocated_rbs[CC_id][UE_id];
898

899 900
    }
  }
901

902
  // step 4: assigne the remaining RBs and set the pre_allocated rbs accordingly
903 904 905 906 907 908 909 910
  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);

      if (rnti==0)
        continue;

911
      UE_id = i;
912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935

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

        if (total_ue_count == 1 )
          total_remaining_rbs[CC_id]+=1;

        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);
        }
936 937 938
      }
    }
  }
939 940

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

943 944 945
    if (total_allocated_rbs[CC_id]>0)
      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]);
  }
946

947 948 949 950 951
}


void store_ulsch_buffer(module_id_t module_idP, int frameP, sub_frame_t subframeP)
{
952 953 954

  int                 UE_id,pCC_id,lcgid;
  UE_list_t           *UE_list = &eNB_mac_inst[module_idP].UE_list;
955 956 957 958 959
  UE_TEMPLATE         *UE_template;

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


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

963
    UE_template->ul_total_buffer=0;
964 965

    for (lcgid=0; lcgid<MAX_NUM_LCGID; lcgid++) {
966
      UE_template->ul_buffer_info[lcgid]=BSR_TABLE[UE_template->bsr_info[lcgid]];
967
      UE_template->ul_total_buffer+= UE_template->ul_buffer_info[lcgid]; // apply traffic aggregtaion if packets are small
968 969
      //   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]));
    }
970

971
    if ( UE_template->ul_total_buffer >0)
972 973 974 975 976 977 978 979
      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 ) {
980
      if (UE_template->ul_total_buffer == 0 )
981 982
        UE_template->ul_total_buffer = BSR_TABLE[11];

983
      LOG_D(MAC,"[eNB %d] Frame %d subframe %d UE %d CC id %d: SR active, set BO to %d \n",
984 985
            module_idP, frameP,subframeP, UE_id, UE_PCCID(module_idP,UE_id),
            UE_template->ul_total_buffer);
986
    }
987
  }
988 989 990 991
}



992 993 994
void assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subframeP, uint16_t *first_rb)
{

995 996 997 998
  int                i;
  uint16_t           n,UE_id;
  uint8_t            CC_id;
  rnti_t             rnti           = -1;
999
  int                mcs=cmin(16,openair_daq_vars.target_ue_ul_mcs);
Raymond Knopp's avatar
 
Raymond Knopp committed
1000
  int                rb_table_index=0,tbs,tx_power;
1001
  eNB_MAC_INST       *eNB = &eNB_mac_inst[module_idP];
1002 1003
  UE_list_t          *UE_list = &eNB->UE_list;

1004 1005
  UE_TEMPLATE       *UE_template;
  LTE_DL_FRAME_PARMS   *frame_parms;
1006 1007 1008 1009 1010 1011

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

    rnti = UE_RNTI(module_idP,i);

    if (rnti==0)
1012 1013 1014
      continue;

    UE_id = i;
1015 1016

    for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) {
1017 1018
      // This is the actual CC_id in the list
      CC_id = UE_list->ordered_ULCCids[n][UE_id];
1019
      frame_parms=mac_xface->get_lte_frame_parms(module_idP,CC_id);
1020
      UE_template = &UE_list->UE_template[CC_id][UE_id];
1021 1022

      // if this UE has UL traffic
1023
      if (UE_template->ul_total_buffer > 0 ) {
1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046

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

1047
        UE_template->ue_tx_power = tx_power;
1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065

        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!
        if (rb_table[rb_table_index]<3)
          rb_table_index=2; //3PRB

        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);
1066
      } else {
1067 1068
        UE_template->pre_allocated_rb_table_index_ul=-1;
        UE_template->pre_allocated_nb_rb_ul=0;
1069 1070 1071 1072 1073 1074
      }
    }
  }
}


1075 1076
void sort_ue_ul (module_id_t module_idP,int frameP, sub_frame_t subframeP)
{
1077 1078 1079 1080 1081 1082 1083 1084

  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;
1085 1086

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

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

1090
    rnti1 = UE_RNTI(module_idP,i);
1091

1092 1093
    if(rnti1 == 0)
      continue;
1094

1095 1096
    UE_id1  = i;
    pCCid1 = UE_PCCID(module_idP,UE_id1);
1097
    round1  = maxround(module_idP,rnti1,frameP,subframeP,1);
1098

1099
    for (ii=UE_list->next_ul[i]; ii>=0; ii=UE_list->next_ul[ii]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1100 1101 1102

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

1103
      rnti2 = UE_RNTI(module_idP,ii);
1104

1105
      if(rnti2 == 0)
1106 1107
        continue;

1108 1109
      UE_id2  = ii;
      pCCid2 = UE_PCCID(module_idP,UE_id2);
1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122
      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) {
          if (UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer > 0 )
            swap_UEs(UE_list,UE_id1,UE_id2,1);
        }
1123 1124 1125 1126
      }
    }
  }
}