pre_processor.c 56.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */
21
22

/*! \file pre_processor.c
23
 * \brief eNB scheduler preprocessing fuction prior to scheduling
24
 * \author Navid Nikaein and Ankit Bhamri
nikaeinn's avatar
nikaeinn committed
25
 * \date 2013 - 2014
26
 * \email navid.nikaein@eurecom.fr
nikaeinn's avatar
nikaeinn committed
27
 * \version 1.0
28
29
30
31
 * @ingroup _mac

 */

32
33
34
#define _GNU_SOURCE
#include <stdlib.h>

35
#include "assertions.h"
36
37
38
39
40
41
42
#include "PHY/defs.h"
#include "PHY/extern.h"

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

#include "LAYER2/MAC/defs.h"
43
#include "LAYER2/MAC/proto.h"
44
45
#include "LAYER2/MAC/extern.h"
#include "UTIL/LOG/log.h"
46
#include "UTIL/LOG/vcd_signal_dumper.h"
47
48
49
50
51
#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"
52
#include "rlc.h"
53
54


gauthier's avatar
gauthier committed
55

56
57
58
59
60
61
62
63
64
65
#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
knopp's avatar
   
knopp committed
66
*/
67

68
/* this function checks that get_eNB_UE_stats returns
Cedric Roux's avatar
Cedric Roux committed
69
 * a non-NULL pointer for all the active CCs of an UE
70
 */
71
int phy_stats_exist(module_id_t Mod_id, int rnti)
72
73
{
  int CC_id;
Cedric Roux's avatar
Cedric Roux committed
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
  int i;
  int UE_id          = find_UE_id(Mod_id, rnti);
  UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
  if (UE_id == -1) {
    LOG_W(MAC, "[eNB %d] UE %x not found, should be there (in phy_stats_exist)\n",
	  Mod_id, rnti);
    return 0;
  }
  if (UE_list->numactiveCCs[UE_id] == 0) {
    LOG_W(MAC, "[eNB %d] UE %x has no active CC (in phy_stats_exist)\n",
	  Mod_id, rnti);
    return 0;
  }
  for (i = 0; i < UE_list->numactiveCCs[UE_id]; i++) {
    CC_id = UE_list->ordered_CCids[i][UE_id];
    if (mac_xface->get_eNB_UE_stats(Mod_id, CC_id, rnti) == NULL)
      return 0;
91
  }
92
93
  return 1;
}
94

95
// This function stores the downlink buffer for all the logical channels
gauthier's avatar
gauthier committed
96
97
void store_dlsch_buffer (module_id_t Mod_id,
                         frame_t     frameP,
98
99
                         sub_frame_t subframeP)
{
Cedric Roux's avatar
Cedric Roux committed
100

knopp's avatar
   
knopp committed
101
  int                   UE_id,i;
gauthier's avatar
gauthier committed
102
  rnti_t                rnti;
103
  mac_rlc_status_resp_t rlc_status;
knopp's avatar
   
knopp committed
104
105
106
  UE_list_t             *UE_list = &eNB_mac_inst[Mod_id].UE_list;
  UE_TEMPLATE           *UE_template;

107
108
  for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
    if (UE_list->active[UE_id] != TRUE) continue;
knopp's avatar
   
knopp committed
109
110

    UE_template = &UE_list->UE_template[UE_PCCID(Mod_id,UE_id)][UE_id];
111
112

    // clear logical channel interface variables
knopp's avatar
   
knopp committed
113
114
    UE_template->dl_buffer_total = 0;
    UE_template->dl_pdus_total = 0;
115
116

    for(i=0; i< MAX_NUM_LCID; i++) {
knopp's avatar
   
knopp committed
117
118
119
120
121
      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;
    }
122

knopp's avatar
   
knopp committed
123
    rnti = UE_RNTI(Mod_id,UE_id);
124
125
126

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

127
      rlc_status = mac_rlc_status_ind(Mod_id,rnti, Mod_id,frameP,subframeP,ENB_FLAG_YES,MBMS_FLAG_NO,i,0 );
knopp's avatar
   
knopp committed
128
129
130
      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 ;
131
132
      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 );
knopp's avatar
   
knopp committed
133
134
      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;
135
136
      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];
137

Cedric Roux's avatar
Cedric Roux committed
138
#ifdef DEBUG_eNB_SCHEDULER
139

knopp's avatar
   
knopp committed
140
141
142
143
      /* 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)
144
145
        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",
146
147
148
149
150
151
152
              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
153
#endif
154

knopp's avatar
   
knopp committed
155
    }
156

157
    //#ifdef DEBUG_eNB_SCHEDULER
knopp's avatar
   
knopp committed
158
159
    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",
160
161
162
163
164
165
            Mod_id, frameP, subframeP, UE_id,
            UE_template->dl_buffer_total,
            UE_template->dl_pdus_total
           );

    //#endif
166
167
168
  }
}

169

170
// This function returns the estimated number of RBs required by each UE for downlink scheduling
knopp's avatar
   
knopp committed
171
void assign_rbs_required (module_id_t Mod_id,
172
173
174
175
176
                          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])
{
177

gauthier's avatar
gauthier committed
178

knopp's avatar
   
knopp committed
179
180
181
182
183
  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;
184
  //  UE_TEMPLATE           *UE_template;
185
  LTE_DL_FRAME_PARMS   *frame_parms[MAX_NUM_CCs];
186

knopp's avatar
   
knopp committed
187
  // clear rb allocations across all CC_ids
188
189
190
  for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
    if (UE_list->active[UE_id] != TRUE) continue;

knopp's avatar
   
knopp committed
191
    pCCid = UE_PCCID(Mod_id,UE_id);
192
    rnti = UE_list->UE_template[pCCid][UE_id].rnti;
193

Cedric Roux's avatar
Cedric Roux committed
194
    /* skip UE not present in PHY (for any of its active CCs) */
195
    if (!phy_stats_exist(Mod_id, rnti))
Cedric Roux's avatar
Cedric Roux committed
196
197
      continue;

knopp's avatar
   
knopp committed
198
    //update CQI information across component carriers
199
    for (n=0; n<UE_list->numactiveCCs[UE_id]; n++) {
gauthier's avatar
gauthier committed
200

knopp's avatar
   
knopp committed
201
      CC_id = UE_list->ordered_CCids[n][UE_id];
202
203
      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);
204
      /*
205
206
      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);
207
208
      */
      eNB_UE_stats[CC_id]->dlsch_mcs1=cqi_to_mcs[eNB_UE_stats[CC_id]->DL_cqi[0]];
209

210
      eNB_UE_stats[CC_id]->dlsch_mcs1 = eNB_UE_stats[CC_id]->dlsch_mcs1;//cmin(eNB_UE_stats[CC_id]->dlsch_mcs1,openair_daq_vars.target_ue_dl_mcs);
211

knopp's avatar
   
knopp committed
212
    }
213

knopp's avatar
   
knopp committed
214
    // provide the list of CCs sorted according to MCS
215
216
    for (i=0; i<UE_list->numactiveCCs[UE_id]; i++) {
      for (j=i+1; j<UE_list->numactiveCCs[UE_id]; j++) {
217
        DevAssert( j < MAX_NUM_CCs );
218
219
220
221
222
223
224

        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;
        }
gauthier's avatar
gauthier committed
225
      }
knopp's avatar
   
knopp committed
226
    }
227

228
    /*
knopp's avatar
   
knopp committed
229
    if ((mac_get_rrc_status(Mod_id,1,UE_id) < RRC_RECONFIGURED)){  // If we still don't have a default radio bearer
230
      nb_rbs_required[pCCid][UE_id] = PHY_vars_eNB_g[Mod_id][pCCid]->frame_parms.N_RB_DL;
knopp's avatar
   
knopp committed
231
232
      continue;
    }
233
234
    */
    /* NN --> RK
235
236
     * check the index of UE_template"
     */
237
238
    //    if (UE_list->UE_template[UE_id]->dl_buffer_total> 0) {
    if (UE_list->UE_template[pCCid][UE_id].dl_buffer_total> 0) {
239
      LOG_D(MAC,"[preprocessor] assign RB for UE %d\n",UE_id);
240
241
242
243
244
245

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

246
247
248
249
250
        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];
        }
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272

        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);
knopp's avatar
   
knopp committed
273
274
275
276
      }
    }
  }
}
gauthier's avatar
gauthier committed
277
278


knopp's avatar
   
knopp committed
279
// This function scans all CC_ids for a particular UE to find the maximum round index of its HARQ processes
gauthier's avatar
gauthier committed
280

281
282
int maxround(module_id_t Mod_id,uint16_t rnti,int frame,sub_frame_t subframe,uint8_t ul_flag )
{
gauthier's avatar
gauthier committed
283

284
  uint8_t round,round_max=0,UE_id;
knopp's avatar
   
knopp committed
285
  int CC_id;
286
  UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
gauthier's avatar
gauthier committed
287

288
289
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {

290
291
    UE_id = find_UE_id(Mod_id,rnti);
    round    = UE_list->UE_sched_ctrl[UE_id].round[CC_id];
292
    if (round > round_max) {
knopp's avatar
   
knopp committed
293
      round_max = round;
294
    }
295
296
  }

297
  return round_max;
knopp's avatar
   
knopp committed
298
}
gauthier's avatar
gauthier committed
299

knopp's avatar
   
knopp committed
300
// This function scans all CC_ids for a particular UE to find the maximum DL CQI
Cedric Roux's avatar
Cedric Roux committed
301
// it returns -1 if the UE is not found in PHY layer (get_eNB_UE_stats gives NULL)
302
303
int maxcqi(module_id_t Mod_id,int32_t UE_id)
{
gauthier's avatar
gauthier committed
304

knopp's avatar
   
knopp committed
305
  LTE_eNB_UE_stats *eNB_UE_stats = NULL;
306
307
  UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
  int CC_id,n;
knopp's avatar
   
knopp committed
308
  int CQI = 0;
gauthier's avatar
gauthier committed
309

310
  for (n=0; n<UE_list->numactiveCCs[UE_id]; n++) {
311
312
    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));
313

314
    if (eNB_UE_stats==NULL) {
Cedric Roux's avatar
Cedric Roux committed
315
316
317
      /* the UE may have been removed in the PHY layer, don't exit */
      //mac_xface->macphy_exit("maxcqi: could not get eNB_UE_stats\n");
      return -1;
318
    }
319

320
    if (eNB_UE_stats->DL_cqi[0] > CQI) {
knopp's avatar
   
knopp committed
321
      CQI = eNB_UE_stats->DL_cqi[0];
322
    }
323
  }
gauthier's avatar
gauthier committed
324

knopp's avatar
   
knopp committed
325
326
  return(CQI);
}
gauthier's avatar
gauthier committed
327

328
329
330
331
332
struct sort_ue_dl_params {
  int Mod_idP;
  int frameP;
  int subframeP;
};
gauthier's avatar
gauthier committed
333

334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
static int ue_dl_compare(const void *_a, const void *_b, void *_params)
{
  struct sort_ue_dl_params *params = _params;
  UE_list_t *UE_list = &eNB_mac_inst[params->Mod_idP].UE_list;

  int UE_id1 = *(const int *)_a;
  int UE_id2 = *(const int *)_b;

  int rnti1  = UE_RNTI(params->Mod_idP, UE_id1);
  int pCC_id1 = UE_PCCID(params->Mod_idP, UE_id1);
  int round1 = maxround(params->Mod_idP, rnti1, params->frameP, params->subframeP, 1);

  int rnti2  = UE_RNTI(params->Mod_idP, UE_id2);
  int pCC_id2 = UE_PCCID(params->Mod_idP, UE_id2);
  int round2 = maxround(params->Mod_idP, rnti2, params->frameP, params->subframeP, 1);

  int cqi1 = maxcqi(params->Mod_idP, UE_id1);
  int cqi2 = maxcqi(params->Mod_idP, UE_id2);

  if (round1 > round2) return -1;
  if (round1 < round2) return 1;

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

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

  if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total >
      UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total)
    return -1;
  if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total <
      UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total)
    return 1;

  if (cqi1 > cqi2) return -1;
  if (cqi1 < cqi2) return 1;

  return 0;
#if 0
  /* The above order derives from the following.  */
      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
gauthier's avatar
gauthier committed
392

393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
        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);
        }
      }
#endif
}
gauthier's avatar
gauthier committed
408

knopp's avatar
   
knopp committed
409
// This fuction sorts the UE in order their dlsch buffer and CQI
knopp's avatar
   
knopp committed
410
void sort_UEs (module_id_t Mod_idP,
411
412
413
               int         frameP,
               sub_frame_t subframeP)
{
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
  int               i;
  int               list[NUMBER_OF_UE_MAX];
  int               list_size = 0;
  int               rnti;
  struct sort_ue_dl_params params = { Mod_idP, frameP, subframeP };

  UE_list_t *UE_list = &eNB_mac_inst[Mod_idP].UE_list;

  for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
    rnti = UE_RNTI(Mod_idP, i);
    if (rnti == NOT_A_RNTI)
      continue;
    if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
      continue;
    if (!phy_stats_exist(Mod_idP, rnti))
      continue;
    list[list_size] = i;
    list_size++;
  }

  qsort_r(list, list_size, sizeof(int), ue_dl_compare, &params);

  if (list_size) {
    for (i = 0; i < list_size-1; i++)
      UE_list->next[list[i]] = list[i+1];
    UE_list->next[list[list_size-1]] = -1;
    UE_list->head = list[0];
  } else {
    UE_list->head = -1;
  }

#if 0
gauthier's avatar
gauthier committed
446
447


knopp's avatar
   
knopp committed
448
449
450
  int               UE_id1,UE_id2;
  int               pCC_id1,pCC_id2;
  int               cqi1,cqi2,round1,round2;
451
  int               i=0,ii=0;//,j=0;
knopp's avatar
   
knopp committed
452
  rnti_t            rnti1,rnti2;
gauthier's avatar
gauthier committed
453

knopp's avatar
   
knopp committed
454
  UE_list_t *UE_list = &eNB_mac_inst[Mod_idP].UE_list;
gauthier's avatar
gauthier committed
455

456
  for (i=UE_list->head; i>=0; i=UE_list->next[i]) {
gauthier's avatar
gauthier committed
457

458
    for(ii=UE_list->next[i]; ii>=0; ii=UE_list->next[ii]) {
gauthier's avatar
gauthier committed
459

460
461
      UE_id1  = i;
      rnti1 = UE_RNTI(Mod_idP,UE_id1);
462
463
      if(rnti1 == NOT_A_RNTI)
	continue;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
464
465
      if (UE_list->UE_sched_ctrl[UE_id1].ul_out_of_sync == 1)
	continue;
466
467
      if (!phy_stats_exist(Mod_idP, rnti1))
        continue;
468
469
470
      pCC_id1 = UE_PCCID(Mod_idP,UE_id1);
      cqi1    = maxcqi(Mod_idP,UE_id1); //
      round1  = maxround(Mod_idP,rnti1,frameP,subframeP,0);
471

472
473
      UE_id2 = ii;
      rnti2 = UE_RNTI(Mod_idP,UE_id2);
474
475
      if(rnti2 == NOT_A_RNTI)
        continue;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
476
477
      if (UE_list->UE_sched_ctrl[UE_id2].ul_out_of_sync == 1)
	continue;
478
479
      if (!phy_stats_exist(Mod_idP, rnti2))
        continue;
480
      cqi2    = maxcqi(Mod_idP,UE_id2);
481
      round2  = maxround(Mod_idP,rnti2,frameP,subframeP,0);  //mac_xface->get_ue_active_harq_pid(Mod_id,rnti2,subframe,&harq_pid2,&round2,0);
knopp's avatar
   
knopp committed
482
      pCC_id2 = UE_PCCID(Mod_idP,UE_id2);
483

484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
      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);
        }
knopp's avatar
   
knopp committed
506
507
      }
    }
508
  }
509
#endif
510
511
}

gauthier's avatar
gauthier committed
512

knopp's avatar
   
knopp committed
513
514


515
// This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done
knopp's avatar
   
knopp committed
516
void dlsch_scheduler_pre_processor (module_id_t   Mod_id,
517
518
519
520
521
                                    frame_t       frameP,
                                    sub_frame_t   subframeP,
                                    int           N_RBG[MAX_NUM_CCs],
                                    int           *mbsfn_flag)
{
knopp's avatar
   
knopp committed
522

523
  unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],harq_pid=0,round=0,total_ue_count;
knopp's avatar
   
knopp committed
524
  unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX];
525
  int                     UE_id, i; 
gauthier's avatar
gauthier committed
526
  uint16_t                ii,j;
knopp's avatar
   
knopp committed
527
528
529
  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];
530
  uint16_t                average_rbs_per_user[MAX_NUM_CCs] = {0};
531
  rnti_t             rnti;
knopp's avatar
   
knopp committed
532
  int                min_rb_unit[MAX_NUM_CCs];
533
  uint16_t r1=0;
534
  uint8_t CC_id;
knopp's avatar
   
knopp committed
535
  UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
536
  LTE_DL_FRAME_PARMS   *frame_parms[MAX_NUM_CCs] = {0};
537

538
  int transmission_mode = 0;
539
540
541
542
543
544
545
546
547
548
549
550
551
  UE_sched_ctrl *ue_sched_ctl;
  //  int rrc_status           = RRC_IDLE;

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

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
knopp's avatar
   
knopp committed
554
555
556

    if (mbsfn_flag[CC_id]>0)  // If this CC is allocated for MBSFN skip it here
      continue;
557
558
559

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

knopp's avatar
   
knopp committed
560

561
    min_rb_unit[CC_id]=get_min_rb_unit(Mod_id,CC_id);
562

563
564
565
    for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
      if (UE_list->active[i] != TRUE) continue;

knopp's avatar
   
knopp committed
566
      UE_id = i;
567
      // Initialize scheduling information for all active UEs
568
569
      

570

571
      dlsch_scheduler_pre_processor_reset(Mod_id,
572
573
        UE_id,
        CC_id,
574
575
        frameP,
        subframeP,
576
577
578
579
580
        N_RBG[CC_id],
        nb_rbs_required,
        nb_rbs_required_remaining,
        rballoc_sub,
        MIMO_mode_indicator);
581

knopp's avatar
   
knopp committed
582
    }
583
  }
knopp's avatar
   
knopp committed
584
585


586
  // Store the DLSCH buffer for each logical channel
gauthier's avatar
gauthier committed
587
  store_dlsch_buffer (Mod_id,frameP,subframeP);
588

knopp's avatar
   
knopp committed
589
590


591
  // Calculate the number of RBs required by each UE on the basis of logical channel's buffer
knopp's avatar
   
knopp committed
592
  assign_rbs_required (Mod_id,frameP,subframeP,nb_rbs_required,min_rb_unit);
593

knopp's avatar
   
knopp committed
594
595


596
  // Sorts the user on the basis of dlsch logical channel buffer and CQI
knopp's avatar
   
knopp committed
597
598
599
  sort_UEs (Mod_id,frameP,subframeP);


knopp's avatar
   
knopp committed
600

601
  total_ue_count =0;
602

knopp's avatar
   
knopp committed
603
  // loop over all active UEs
604
  for (i=UE_list->head; i>=0; i=UE_list->next[i]) {
605
    rnti = UE_RNTI(Mod_id,i);
606

607
    if(rnti == NOT_A_RNTI)
knopp's avatar
   
knopp committed
608
      continue;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
609
610
    if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
      continue;
611
    if (!phy_stats_exist(Mod_id, rnti))
612
      continue;
613
    UE_id = i;
614

615
    for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) {
knopp's avatar
   
knopp committed
616
      CC_id = UE_list->ordered_CCids[ii][UE_id];
617
618
619
      ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
      harq_pid = ue_sched_ctl->harq_pid[CC_id];
      round    = ue_sched_ctl->round[CC_id];
knopp's avatar
   
knopp committed
620

621
622
623
624
      // if there is no available harq_process, skip the UE
      if (UE_list->UE_sched_ctrl[UE_id].harq_pid[CC_id]<0)
        continue;

knopp's avatar
   
knopp committed
625
626
      average_rbs_per_user[CC_id]=0;

627
      frame_parms[CC_id] = mac_xface->get_lte_frame_parms(Mod_id,CC_id);
knopp's avatar
   
knopp committed
628

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

631
      if(round>0) {
632
        nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
633
      }
634

knopp's avatar
   
knopp committed
635
636
      //nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id];
      if (nb_rbs_required[CC_id][UE_id] > 0) {
637
        total_ue_count = total_ue_count + 1;
knopp's avatar
   
knopp committed
638
      }
639
640
641
642
643
644
645
646
647
648
649
650


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

651
      if (total_ue_count == 0) {
652
        average_rbs_per_user[CC_id] = 0;
653
      } else if( (min_rb_unit[CC_id] * total_ue_count) <= (frame_parms[CC_id]->N_RB_DL) ) {
654
        average_rbs_per_user[CC_id] = (uint16_t) floor(frame_parms[CC_id]->N_RB_DL/total_ue_count);
655
      } else {
656
        average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; // consider the total number of use that can be scheduled UE
657
      }
knopp's avatar
   
knopp committed
658
659
    }
  }
660

661
662
  // note: nb_rbs_required is assigned according to total_buffer_dl
  // extend nb_rbs_required to capture per LCID RB required
663
  for(i=UE_list->head; i>=0; i=UE_list->next[i]) {
664
    rnti = UE_RNTI(Mod_id,i);
665

666
667
668
669
670
671
672
    if(rnti == NOT_A_RNTI)
      continue;
    if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
      continue;
    if (!phy_stats_exist(Mod_id, rnti))
      continue;

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

gauthier's avatar
gauthier committed
676
      // control channel
677
      if (mac_eNB_get_rrc_status(Mod_id,rnti) < RRC_RECONFIGURED) {
678
        nb_rbs_required_remaining_1[CC_id][i] = nb_rbs_required[CC_id][i];
679
      } else {
680
681
        nb_rbs_required_remaining_1[CC_id][i] = cmin(average_rbs_per_user[CC_id],nb_rbs_required[CC_id][i]);

682
      }
knopp's avatar
   
knopp committed
683
    }
684
  }
gauthier's avatar
gauthier committed
685

686
  //Allocation to UEs is done in 2 rounds,
687
688
  // 1st stage: average number of RBs allocated to each UE
  // 2nd stage: remaining RBs are allocated to high priority UEs
689
690
691
692
693
694
  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];

695
        if(r1 == 0) {
696
          nb_rbs_required_remaining[CC_id][i] = nb_rbs_required_remaining_1[CC_id][i];
697
        } else { // rb required based only on the buffer - rb allloctaed in the 1st round + extra reaming rb form the 1st round
698
          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];
699
        }
700
701
702
703
704
705
706

        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],
707
                UE_list->UE_sched_ctrl[i].pre_nb_available_rbs[CC_id],
708
709
710
                N_RBG[CC_id],
                min_rb_unit[CC_id]);

711
      }
knopp's avatar
   
knopp committed
712
    }
713

714
    if (total_ue_count > 0 ) {
715
716
717
718
719
      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];
720
721
722
	  ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
	  harq_pid = ue_sched_ctl->harq_pid[CC_id];
	  round    = ue_sched_ctl->round[CC_id];
723
724
725
726

          rnti = UE_RNTI(Mod_id,UE_id);

          // LOG_D(MAC,"UE %d rnti 0x\n", UE_id, rnti );
727
          if(rnti == NOT_A_RNTI)
728
            continue;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
729
730
	  if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1)
	    continue;
731
732
          if (!phy_stats_exist(Mod_id, rnti))
            continue;
733
734

          transmission_mode = mac_xface->get_transmission_mode(Mod_id,CC_id,rnti);
735
736
	  //          mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0);
          //rrc_status = mac_eNB_get_rrc_status(Mod_id,rnti);
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
          /* 1st allocate for the retx */

          // retransmission in data channels
          // control channel in the 1st transmission
          // data channel for all TM
          LOG_T(MAC,"calling dlsch_scheduler_pre_processor_allocate .. \n ");
          dlsch_scheduler_pre_processor_allocate (Mod_id,
                                                  UE_id,
                                                  CC_id,
                                                  N_RBG[CC_id],
                                                  transmission_mode,
                                                  min_rb_unit[CC_id],
                                                  frame_parms[CC_id]->N_RB_DL,
                                                  nb_rbs_required,
                                                  nb_rbs_required_remaining,
                                                  rballoc_sub,
                                                  MIMO_mode_indicator);

755
#ifdef TM5
756
757
758
759

          // data chanel TM5: to be revisted
          if ((round == 0 )  &&
              (transmission_mode == 5)  &&
760
              (ue_sched_ctl->dl_pow_off[CC_id] != 1)) {
761
762
763

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

764
765
              if( (((j == (N_RBG[CC_id]-1))&& (rballoc_sub[CC_id][j] == 0) && (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 0))  ||
                   ((j < (N_RBG[CC_id]-1)) && (rballoc_sub[CC_id][j+1] == 0) && (ue_sched_ctl->rballoc_sub_UE[CC_id][j+1] == 0)) ) &&
766
767
768
769
770
771
                  (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);
772
773
774
		  ue_sched_ctl2 = &UE_list->UE_sched_ctrl[UE_id2];
		  harq_pid2 = ue_sched_ctl2->harq_pid[CC_id];
		  round2    = ue_sched_ctl2->round[CC_id];
775
                  if(rnti2 == NOT_A_RNTI)
776
                    continue;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
777
778
		  if (UE_list->UE_sched_ctrl[UE_id2].ul_out_of_sync == 1)
		    continue;
779
780
                  if (!phy_stats_exist(Mod_idP, rnti2))
                    continue;
781
782

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

785
                  if ((mac_eNB_get_rrc_status(Mod_id,rnti2) >= RRC_RECONFIGURED) &&
786
787
                      (round2==0) &&
                      (mac_xface->get_transmission_mode(Mod_id,CC_id,rnti2)==5) &&
788
                      (ue_sched_ctl->dl_pow_off[CC_id] != 1)) {
789

790
791
                    if( (((j == (N_RBG[CC_id]-1)) && (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 0)) ||
                         ((j < (N_RBG[CC_id]-1)) && (ue_sched_ctl->rballoc_sub_UE[CC_id][j+1] == 0))  ) &&
792
793
794
795
796
                        (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;
797
798
                        ue_sched_ctl->rballoc_sub_UE[CC_id][j] = 1;
                        ue_sched_ctl2->rballoc_sub_UE[CC_id][j] = 1;
799
800
801
802
                        MIMO_mode_indicator[CC_id][j] = 0;

                        if (j< N_RBG[CC_id]-1) {
                          rballoc_sub[CC_id][j+1] = 1;
803
804
                          ue_sched_ctl->rballoc_sub_UE[CC_id][j+1] = 1;
                          ue_sched_ctl2->rballoc_sub_UE[CC_id][j+1] = 1;
805
806
807
                          MIMO_mode_indicator[CC_id][j+1] = 0;
                        }

808
809
                        ue_sched_ctl->dl_pow_off[CC_id] = 0;
                        ue_sched_ctl2->dl_pow_off[CC_id] = 0;
810
811
812


                        if ((j == N_RBG[CC_id]-1) &&
813
814
                            ((PHY_vars_eNB_g[Mod_id][CC_id]->frame_parms.N_RB_DL == 25) ||
                             (PHY_vars_eNB_g[Mod_id][CC_id]->frame_parms.N_RB_DL == 50))) {
815
			  
816
                          nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id]+1;
817
                          ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit[CC_id]-1;
818
                          nb_rbs_required_remaining[CC_id][UE_id2] = nb_rbs_required_remaining[CC_id][UE_id2] - min_rb_unit[CC_id]+1;
819
                          ue_sched_ctl2->pre_nb_available_rbs[CC_id] = ue_sched_ctl2->pre_nb_available_rbs[CC_id] + min_rb_unit[CC_id]-1;
820
                        } else {
821
822
                          
			  nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - 4;
823
                          ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + 4;
824
                          nb_rbs_required_remaining[CC_id][UE_id2] = nb_rbs_required_remaining[CC_id][UE_id2] - 4;
825
                          ue_sched_ctl2->pre_nb_available_rbs[CC_id] = ue_sched_ctl2->pre_nb_available_rbs[CC_id] + 4;
826
827
828
829
830
831
832
833
834
835
836
837
838
                        }

                        break;
                      }
                    }
                  }
                }
              }
            }
          }

#endif
        }
knopp's avatar
   
knopp committed
839
      }
840
    } // total_ue_count
841
  } // end of for for r1 and r2
842
843
844

#ifdef TM5

knopp's avatar
   
knopp committed
845
  // This has to be revisited!!!!
846
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
knopp's avatar
   
knopp committed
847
848
849
    i1=0;
    i2=0;
    i3=0;
850
851

    for (j=0; j<N_RBG[CC_id]; j++) {
852
      if(MIMO_mode_indicator[CC_id][j] == 2) {
853
        i1 = i1+1;
854
      } else if(MIMO_mode_indicator[CC_id][j] == 1) {
855
        i2 = i2+1;
856
      } else if(MIMO_mode_indicator[CC_id][j] == 0) {
857
        i3 = i3+1;
858
      }
knopp's avatar
   
knopp committed
859
    }
860

861
    if((i1 < N_RBG[CC_id]) && (i2>0) && (i3==0)) {
knopp's avatar
   
knopp committed
862
      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;
863
    }
864

865
    if(i3 == N_RBG[CC_id] && i1==0 && i2==0) {
knopp's avatar
   
knopp committed
866
      PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions + 1;
867
    }
868

869
    if((i1 < N_RBG[CC_id]) && (i3 > 0)) {
knopp's avatar
   
knopp committed
870
      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;
871
    }
872

knopp's avatar
   
knopp committed
873
    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;
874

875
876
  }

877
878
879
#endif

  for(i=UE_list->head; i>=0; i=UE_list->next[i]) {
880
    UE_id = i;
881
    ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
882
883

    for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) {
knopp's avatar
   
knopp committed
884
      CC_id = UE_list->ordered_CCids[ii][UE_id];
gauthier's avatar
gauthier committed
885
      //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id];
886

887
      if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0 ) {
888
        LOG_D(MAC,"******************DL Scheduling Information for UE%d ************************\n",UE_id);
889
        LOG_D(MAC,"dl power offset UE%d = %d \n",UE_id,ue_sched_ctl->dl_pow_off[CC_id]);
890
891
892
893
        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];
894
          LOG_D(MAC,"RB Alloc for UE%d and Subband%d = %d\n",UE_id,j,ue_sched_ctl->rballoc_sub_UE[CC_id][j]);
895
896
897
        }

        //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id];
898
        LOG_D(MAC,"Total RBs allocated for UE%d = %d\n",UE_id,ue_sched_ctl->pre_nb_available_rbs[CC_id]);
gauthier's avatar
gauthier committed
899
      }
knopp's avatar
   
knopp committed
900
    }
901
902
903
  }
}

904
#define SF05_LIMIT 1
905

906
void dlsch_scheduler_pre_processor_reset (int module_idP,
907
908
909
910
911
912
913
914
915
916
					  int UE_id,
					  uint8_t  CC_id,
					  int frameP,
					  int subframeP,					  
					  int N_RBG,
					  uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
					  uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
					  unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
					  unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX])
  
917
{
918
  int i,j;
919
920
921
  UE_list_t *UE_list=&eNB_mac_inst[module_idP].UE_list;
  UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
  rnti_t rnti = UE_RNTI(module_idP,UE_id);
Cedric Roux's avatar
Cedric Roux committed
922
  uint8_t *vrb_map = eNB_mac_inst[module_idP].common_channels[CC_id].vrb_map;
923
  int RBGsize = PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.N_RB_DL/N_RBG;
924
#ifdef SF05_LIMIT
925
  //int subframe05_limit=0;
926
927
  int sf05_upper=-1,sf05_lower=-1;
#endif
928
  LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti);
Cedric Roux's avatar
Cedric Roux committed
929
930
  if (eNB_UE_stats == NULL) return;

931
  // initialize harq_pid and round
932
933
934
935

  if (eNB_UE_stats == NULL)
    return;

936
937
938
939
  mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,
				    frameP,subframeP,
				    &ue_sched_ctl->harq_pid[CC_id],
				    &ue_sched_ctl->round[CC_id],