pre_processor.c 55.3 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
/*
72
int phy_stats_exist(module_id_t Mod_id, int rnti)
73
74
{
  int CC_id;
Cedric Roux's avatar
Cedric Roux committed
75
76
  int i;
  int UE_id          = find_UE_id(Mod_id, rnti);
77
  UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
Cedric Roux's avatar
Cedric Roux committed
78
79
80
81
82
83
84
85
86
87
88
89
  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];
90
91
    if (mac_xface->get_eNB_UE_stats(Mod_id, CC_id, rnti) == NULL)
      return 0;
92
  }
93
94
  return 1;
}
95
*/
96

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

knopp's avatar
   
knopp committed
103
  int                   UE_id,i;
gauthier's avatar
gauthier committed
104
  rnti_t                rnti;
105
  mac_rlc_status_resp_t rlc_status;
106
  UE_list_t             *UE_list = &RC.mac[Mod_id]->UE_list;
knopp's avatar
   
knopp committed
107
108
  UE_TEMPLATE           *UE_template;

109
110
  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
111
112

    UE_template = &UE_list->UE_template[UE_PCCID(Mod_id,UE_id)][UE_id];
113
114

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

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

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

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

129
      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
130
131
132
      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 ;
133
134
      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
135
136
      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;
137
138
      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];
139

Cedric Roux's avatar
Cedric Roux committed
140
#ifdef DEBUG_eNB_SCHEDULER
141

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

knopp's avatar
   
knopp committed
157
    }
158

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

    //#endif
168
169
170
  }
}

171

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

knopp's avatar
   
knopp committed
180
  uint16_t         TBS = 0;
181

knopp's avatar
   
knopp committed
182
  int              UE_id,n,i,j,CC_id,pCCid,tmp;
183
  UE_list_t        *UE_list = &RC.mac[Mod_id]->UE_list;
184
  eNB_UE_STATS     *eNB_UE_stats,*eNB_UE_stats_i,*eNB_UE_stats_j;
knopp's avatar
knopp committed
185
  int N_RB_DL;
186

knopp's avatar
knopp committed
187
  // clear rb allocations across all CC_id
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

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

knopp's avatar
   
knopp committed
196
      CC_id = UE_list->ordered_CCids[n][UE_id];
197
      eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
198

199
      eNB_UE_stats->dlsch_mcs1=cqi_to_mcs[eNB_UE_stats->dl_cqi];
200

knopp's avatar
   
knopp committed
201
    }
202

knopp's avatar
   
knopp committed
203
    // provide the list of CCs sorted according to MCS
204
    for (i=0; i<UE_list->numactiveCCs[UE_id]; i++) {
205
      eNB_UE_stats_i = &UE_list->eNB_UE_stats[UE_list->ordered_CCids[i][UE_id]][UE_id];
206
      for (j=i+1; j<UE_list->numactiveCCs[UE_id]; j++) {
207
        DevAssert( j < MAX_NUM_CCs );
208
209
210
	eNB_UE_stats_j = &UE_list->eNB_UE_stats[UE_list->ordered_CCids[j][UE_id]][UE_id];
        if (eNB_UE_stats_j->dlsch_mcs1 >
            eNB_UE_stats_i->dlsch_mcs1) {
211
212
213
214
          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
215
      }
knopp's avatar
   
knopp committed
216
    }
217
218

    if (UE_list->UE_template[pCCid][UE_id].dl_buffer_total> 0) {
219
      LOG_D(MAC,"[preprocessor] assign RB for UE %d\n",UE_id);
220
221
222

      for (i=0; i<UE_list->numactiveCCs[UE_id]; i++) {
        CC_id = UE_list->ordered_CCids[i][UE_id];
223
	eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
224

225
        if (eNB_UE_stats->dlsch_mcs1==0) {
226
227
228
229
          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];
        }
230

231
        TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_rbs_required[CC_id][UE_id]);
232
233
234

        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,
235
              nb_rbs_required[CC_id][UE_id],eNB_UE_stats->dlsch_mcs1,TBS);
236

knopp's avatar
knopp committed
237
238
	N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth);

239
240
241
242
        /* 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];

knopp's avatar
knopp committed
243
          if (nb_rbs_required[CC_id][UE_id] > N_RB_DL) {
244
            TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1,N_RB_DL);
knopp's avatar
knopp committed
245
            nb_rbs_required[CC_id][UE_id] = N_RB_DL;
246
247
248
            break;
          }

249
          TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_rbs_required[CC_id][UE_id]);
250
251
252
        } // 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",
253
              Mod_id, frameP,UE_id, CC_id,  min_rb_unit[CC_id], nb_rbs_required[CC_id][UE_id], TBS, eNB_UE_stats->dlsch_mcs1);
knopp's avatar
   
knopp committed
254
255
256
257
      }
    }
  }
}
gauthier's avatar
gauthier committed
258
259


knopp's avatar
   
knopp committed
260
// 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
261

262
263
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
264

265
  uint8_t round,round_max=0,UE_id;
266
  int CC_id,harq_pid;
267
  UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
268
  COMMON_channels_t *cc;
gauthier's avatar
gauthier committed
269

270
271
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {

272
273
    cc = &RC.mac[Mod_id]->common_channels[CC_id];

274
    UE_id = find_UE_id(Mod_id,rnti);
275
276
277
278
    if (cc->tdd_Config) harq_pid = ((frame*10)+subframe)%10;
    else harq_pid = ((frame*10)+subframe)&7;

    round    = UE_list->UE_sched_ctrl[UE_id].round[CC_id][harq_pid];
279
    if (round > round_max) {
knopp's avatar
   
knopp committed
280
      round_max = round;
281
    }
282
283
  }

284
  return round_max;
knopp's avatar
   
knopp committed
285
}
gauthier's avatar
gauthier committed
286

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

292
  eNB_UE_STATS *eNB_UE_stats = NULL;
293
  UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
294
  int CC_id,n;
knopp's avatar
   
knopp committed
295
  int CQI = 0;
gauthier's avatar
gauthier committed
296

297
  for (n=0; n<UE_list->numactiveCCs[UE_id]; n++) {
298
    CC_id = UE_list->ordered_CCids[n][UE_id];
299
    eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
300

301
302
    if (eNB_UE_stats->dl_cqi > CQI) {
      CQI = eNB_UE_stats->dl_cqi;
303
    }
304
  }
gauthier's avatar
gauthier committed
305

knopp's avatar
   
knopp committed
306
307
  return(CQI);
}
gauthier's avatar
gauthier committed
308

309
310
311
312
313
struct sort_ue_dl_params {
  int Mod_idP;
  int frameP;
  int subframeP;
};
gauthier's avatar
gauthier committed
314

315
316
317
static int ue_dl_compare(const void *_a, const void *_b, void *_params)
{
  struct sort_ue_dl_params *params = _params;
318
  UE_list_t *UE_list = &RC.mac[params->Mod_idP]->UE_list;
319
320
321
322
323
324
325
326
327
328
329
330
331
332
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

  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
373

374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
        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
389

knopp's avatar
   
knopp committed
390
// This fuction sorts the UE in order their dlsch buffer and CQI
knopp's avatar
   
knopp committed
391
void sort_UEs (module_id_t Mod_idP,
392
393
394
               int         frameP,
               sub_frame_t subframeP)
{
395
396
397
398
399
400
  int               i;
  int               list[NUMBER_OF_UE_MAX];
  int               list_size = 0;
  int               rnti;
  struct sort_ue_dl_params params = { Mod_idP, frameP, subframeP };

401
  UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list;
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424

  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;
    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
425
426


knopp's avatar
   
knopp committed
427
428
429
  int               UE_id1,UE_id2;
  int               pCC_id1,pCC_id2;
  int               cqi1,cqi2,round1,round2;
430
  int               i=0,ii=0;//,j=0;
knopp's avatar
   
knopp committed
431
  rnti_t            rnti1,rnti2;
gauthier's avatar
gauthier committed
432

433
  UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list;
gauthier's avatar
gauthier committed
434

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

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

439
440
      UE_id1  = i;
      rnti1 = UE_RNTI(Mod_idP,UE_id1);
441
442
      if(rnti1 == NOT_A_RNTI)
	continue;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
443
444
      if (UE_list->UE_sched_ctrl[UE_id1].ul_out_of_sync == 1)
	continue;
445
446
447
      pCC_id1 = UE_PCCID(Mod_idP,UE_id1);
      cqi1    = maxcqi(Mod_idP,UE_id1); //
      round1  = maxround(Mod_idP,rnti1,frameP,subframeP,0);
448

449
450
      UE_id2 = ii;
      rnti2 = UE_RNTI(Mod_idP,UE_id2);
451
452
      if(rnti2 == NOT_A_RNTI)
        continue;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
453
454
      if (UE_list->UE_sched_ctrl[UE_id2].ul_out_of_sync == 1)
	continue;
455
      cqi2    = maxcqi(Mod_idP,UE_id2);
456
      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
457
      pCC_id2 = UE_PCCID(Mod_idP,UE_id2);
458

459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
      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
481
482
      }
    }
483
  }
484
#endif
485
486
}

gauthier's avatar
gauthier committed
487

knopp's avatar
   
knopp committed
488
489


490
// This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done
knopp's avatar
   
knopp committed
491
void dlsch_scheduler_pre_processor (module_id_t   Mod_id,
492
493
494
495
496
                                    frame_t       frameP,
                                    sub_frame_t   subframeP,
                                    int           N_RBG[MAX_NUM_CCs],
                                    int           *mbsfn_flag)
{
knopp's avatar
   
knopp committed
497

498
  unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],harq_pid=0,round=0,total_ue_count;
knopp's avatar
   
knopp committed
499
  unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX];
500
  int                     UE_id, i; 
gauthier's avatar
gauthier committed
501
  uint16_t                ii,j;
knopp's avatar
   
knopp committed
502
503
504
  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];
505
  uint16_t                average_rbs_per_user[MAX_NUM_CCs] = {0};
506
  rnti_t             rnti;
knopp's avatar
   
knopp committed
507
  int                min_rb_unit[MAX_NUM_CCs];
508
  uint16_t r1=0;
509
  uint8_t CC_id;
510
  UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
511

knopp's avatar
knopp committed
512
  int N_RB_DL;
513
  int transmission_mode = 0;
514
515
  UE_sched_ctrl *ue_sched_ctl;
  //  int rrc_status           = RRC_IDLE;
516
  COMMON_channels_t *cc;
517
518

#ifdef TM5
519
  int harq_pid1=0;
520
521
522
523
524
525
526
527
  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
528
529

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
knopp's avatar
   
knopp committed
530
531
532

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


knopp's avatar
   
knopp committed
535

536
    min_rb_unit[CC_id]=get_min_rb_unit(Mod_id,CC_id);
537

538
539
540
    for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
      if (UE_list->active[i] != TRUE) continue;

knopp's avatar
   
knopp committed
541
      UE_id = i;
542
      // Initialize scheduling information for all active UEs
543
544
      

545

546
      dlsch_scheduler_pre_processor_reset(Mod_id,
547
548
        UE_id,
        CC_id,
549
550
        frameP,
        subframeP,
551
552
553
554
555
        N_RBG[CC_id],
        nb_rbs_required,
        nb_rbs_required_remaining,
        rballoc_sub,
        MIMO_mode_indicator);
556

knopp's avatar
   
knopp committed
557
    }
558
  }
knopp's avatar
   
knopp committed
559
560


561
  // Store the DLSCH buffer for each logical channel
gauthier's avatar
gauthier committed
562
  store_dlsch_buffer (Mod_id,frameP,subframeP);
563

knopp's avatar
   
knopp committed
564
565


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

knopp's avatar
   
knopp committed
569
570


571
  // Sorts the user on the basis of dlsch logical channel buffer and CQI
knopp's avatar
   
knopp committed
572
573
574
  sort_UEs (Mod_id,frameP,subframeP);


knopp's avatar
   
knopp committed
575

576
  total_ue_count =0;
577

knopp's avatar
   
knopp committed
578
  // loop over all active UEs
579
  for (i=UE_list->head; i>=0; i=UE_list->next[i]) {
580
    rnti = UE_RNTI(Mod_id,i);
581

582
    if(rnti == NOT_A_RNTI)
knopp's avatar
   
knopp committed
583
      continue;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
584
585
    if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
      continue;
586
    UE_id = i;
587

588
    for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) {
knopp's avatar
   
knopp committed
589
      CC_id = UE_list->ordered_CCids[ii][UE_id];
590
      ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
591
592
593
594
      cc=&RC.mac[Mod_id]->common_channels[ii];
      if (cc->tdd_Config) harq_pid = ((frameP*10)+subframeP)%10;
      else harq_pid = ((frameP*10)+subframeP)&7;
      round    = ue_sched_ctl->round[CC_id][harq_pid];
595

knopp's avatar
   
knopp committed
596
597
      average_rbs_per_user[CC_id]=0;

598

Cedric Roux's avatar
Cedric Roux committed
599
      if(round != 8) {
600
        nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
601
      }
602

knopp's avatar
   
knopp committed
603
604
      //nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id];
      if (nb_rbs_required[CC_id][UE_id] > 0) {
605
        total_ue_count = total_ue_count + 1;
knopp's avatar
   
knopp committed
606
      }
607
608


609
      // hypothetical assignment
610
611
612
613
614
615
616
617
618
      /*
       * 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.
       */

knopp's avatar
knopp committed
619
620
      N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth);

621
      if (total_ue_count == 0) {
622
        average_rbs_per_user[CC_id] = 0;
knopp's avatar
knopp committed
623
624
      } else if( (min_rb_unit[CC_id] * total_ue_count) <= (N_RB_DL) ) {
        average_rbs_per_user[CC_id] = (uint16_t) floor(N_RB_DL/total_ue_count);
625
      } else {
626
        average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; // consider the total number of use that can be scheduled UE
627
      }
knopp's avatar
   
knopp committed
628
629
    }
  }
630

631
632
  // note: nb_rbs_required is assigned according to total_buffer_dl
  // extend nb_rbs_required to capture per LCID RB required
633
  for(i=UE_list->head; i>=0; i=UE_list->next[i]) {
634
    rnti = UE_RNTI(Mod_id,i);
635

636
637
638
639
640
    if(rnti == NOT_A_RNTI)
      continue;
    if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
      continue;

641
    for (ii=0; ii<UE_num_active_CC(UE_list,i); ii++) {
642
      CC_id = UE_list->ordered_CCids[ii][i];
Cedric Roux's avatar
Cedric Roux committed
643
      ue_sched_ctl = &UE_list->UE_sched_ctrl[i];
644
      round    = ue_sched_ctl->round[CC_id][harq_pid];
645

Cedric Roux's avatar
Cedric Roux committed
646
647
648
      // control channel or retransmission
      /* TODO: do we have to check for retransmission? */
      if (mac_eNB_get_rrc_status(Mod_id,rnti) < RRC_RECONFIGURED || round > 0) {
649
        nb_rbs_required_remaining_1[CC_id][i] = nb_rbs_required[CC_id][i];
650
      } else {
651
652
        nb_rbs_required_remaining_1[CC_id][i] = cmin(average_rbs_per_user[CC_id],nb_rbs_required[CC_id][i]);

653
      }
knopp's avatar
   
knopp committed
654
    }
655
  }
gauthier's avatar
gauthier committed
656

657
  //Allocation to UEs is done in 2 rounds,
658
659
  // 1st stage: average number of RBs allocated to each UE
  // 2nd stage: remaining RBs are allocated to high priority UEs
660
661
662
663
664
665
  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];

666
        if(r1 == 0) {
667
          nb_rbs_required_remaining[CC_id][i] = nb_rbs_required_remaining_1[CC_id][i];
668
        } else { // rb required based only on the buffer - rb allloctaed in the 1st round + extra reaming rb form the 1st round
669
          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];
Cedric Roux's avatar
Cedric Roux committed
670
if (nb_rbs_required_remaining[CC_id][i]<0) abort();
671
        }
672
673
674
675
676
677
678

        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],
679
                UE_list->UE_sched_ctrl[i].pre_nb_available_rbs[CC_id],
680
681
682
                N_RBG[CC_id],
                min_rb_unit[CC_id]);

683
      }
knopp's avatar
   
knopp committed
684
    }
685

686
    if (total_ue_count > 0 ) {
687
688
689
690
691
      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];
692
	  ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
693
	  round    = ue_sched_ctl->round[CC_id][harq_pid];
694
695
696
697

          rnti = UE_RNTI(Mod_id,UE_id);

          // LOG_D(MAC,"UE %d rnti 0x\n", UE_id, rnti );
698
          if(rnti == NOT_A_RNTI)
699
            continue;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
700
701
	  if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1)
	    continue;
702

703
          transmission_mode = get_tmode(Mod_id,CC_id,UE_id);
704
705
	  //          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);
706
707
708
709
710
711
712
713
714
715
716
717
          /* 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],
718
                                                  to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth),
719
720
721
722
723
                                                  nb_rbs_required,
                                                  nb_rbs_required_remaining,
                                                  rballoc_sub,
                                                  MIMO_mode_indicator);

724
#ifdef TM5
725
726
727
728

          // data chanel TM5: to be revisted
          if ((round == 0 )  &&
              (transmission_mode == 5)  &&
729
              (ue_sched_ctl->dl_pow_off[CC_id] != 1)) {
730
731
732

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

733
734
              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)) ) &&
735
736
737
738
739
740
                  (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);
741
742
		  ue_sched_ctl2 = &UE_list->UE_sched_ctrl[UE_id2];
		  round2    = ue_sched_ctl2->round[CC_id];
743
                  if(rnti2 == NOT_A_RNTI)
744
                    continue;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
745
746
		  if (UE_list->UE_sched_ctrl[UE_id2].ul_out_of_sync == 1)
		    continue;
747

748
                  eNB_UE_stats2 = UE_list->eNB_UE_stats[CC_id][UE_id2];
749
                  //mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,frameP,subframeP,&harq_pid2,&round2,0);
750

751
                  if ((mac_eNB_get_rrc_status(Mod_id,rnti2) >= RRC_RECONFIGURED) &&
752
                      (round2==0) &&
753
                      (get_tmode(Mod_id,CC_id,UE_id2)==5) &&
754
                      (ue_sched_ctl->dl_pow_off[CC_id] != 1)) {
755

756
757
                    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))  ) &&
758
759
760
761
762
                        (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;
763
764
                        ue_sched_ctl->rballoc_sub_UE[CC_id][j] = 1;
                        ue_sched_ctl2->rballoc_sub_UE[CC_id][j] = 1;
765
766
767
768
                        MIMO_mode_indicator[CC_id][j] = 0;

                        if (j< N_RBG[CC_id]-1) {
                          rballoc_sub[CC_id][j+1] = 1;
769
770
                          ue_sched_ctl->rballoc_sub_UE[CC_id][j+1] = 1;
                          ue_sched_ctl2->rballoc_sub_UE[CC_id][j+1] = 1;
771
772
773
                          MIMO_mode_indicator[CC_id][j+1] = 0;
                        }

774
775
                        ue_sched_ctl->dl_pow_off[CC_id] = 0;
                        ue_sched_ctl2->dl_pow_off[CC_id] = 0;
776
777
778


                        if ((j == N_RBG[CC_id]-1) &&
knopp's avatar
knopp committed
779
780
                            ((N_RB_DL == 25) ||
                             (N_RB_DL == 50))) {
781
			  
782
                          nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id]+1;
783
                          ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit[CC_id]-1;
784
                          nb_rbs_required_remaining[CC_id][UE_id2] = nb_rbs_required_remaining[CC_id][UE_id2] - min_rb_unit[CC_id]+1;
785
                          ue_sched_ctl2->pre_nb_available_rbs[CC_id] = ue_sched_ctl2->pre_nb_available_rbs[CC_id] + min_rb_unit[CC_id]-1;
786
                        } else {
787
788
                          
			  nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - 4;
789
                          ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + 4;
790
                          nb_rbs_required_remaining[CC_id][UE_id2] = nb_rbs_required_remaining[CC_id][UE_id2] - 4;
791
                          ue_sched_ctl2->pre_nb_available_rbs[CC_id] = ue_sched_ctl2->pre_nb_available_rbs[CC_id] + 4;
792
793
794
795
796
797
798
799
800
801
802
803
804
                        }

                        break;
                      }
                    }
                  }
                }
              }
            }
          }

#endif
        }
knopp's avatar
   
knopp committed
805
      }
806
    } // total_ue_count
807
  } // end of for for r1 and r2
808
809
810

#ifdef TM5

knopp's avatar
   
knopp committed
811
  // This has to be revisited!!!!
812
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
knopp's avatar
   
knopp committed
813
814
815
    i1=0;
    i2=0;
    i3=0;
816
817

    for (j=0; j<N_RBG[CC_id]; j++) {
818
      if(MIMO_mode_indicator[CC_id][j] == 2) {
819
        i1 = i1+1;
820
      } else if(MIMO_mode_indicator[CC_id][j] == 1) {
821
        i2 = i2+1;
822
      } else if(MIMO_mode_indicator[CC_id][j] == 0) {
823
        i3 = i3+1;
824
      }
knopp's avatar
   
knopp committed
825
    }
826

827
    if((i1 < N_RBG[CC_id]) && (i2>0) && (i3==0)) {
knopp's avatar
   
knopp committed
828
      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;
829
    }
830

831
    if(i3 == N_RBG[CC_id] && i1==0 && i2==0) {
knopp's avatar
   
knopp committed
832
      PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions + 1;
833
    }
834

835
    if((i1 < N_RBG[CC_id]) && (i3 > 0)) {
knopp's avatar
   
knopp committed
836
      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;
837
    }
838

knopp's avatar
   
knopp committed
839
    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;
840

841
842
  }

843
844
845
#endif

  for(i=UE_list->head; i>=0; i=UE_list->next[i]) {
846
    UE_id = i;
847
    ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
848
849

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

853
      if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0 ) {
854
        LOG_D(MAC,"******************DL Scheduling Information for UE%d ************************\n",UE_id);
855
        LOG_D(MAC,"dl power offset UE%d = %d \n",UE_id,ue_sched_ctl->dl_pow_off[CC_id]);
856
857
858
859
        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];
860
          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]);
861
862
863
        }

        //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id];
864
        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
865
      }
knopp's avatar
   
knopp committed
866
    }
867
868
869
  }
}

Cedric Roux's avatar
Cedric Roux committed
870
#define SF0_LIMIT 1
871

872
void dlsch_scheduler_pre_processor_reset (int module_idP,
873
874
875
876
877
878
879
880
881
882
					  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])
  
883
{
884
  int i,j;
885
  UE_list_t *UE_list=&RC.mac[module_idP]->UE_list;
886
887
  UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
  rnti_t rnti