phy_procedures_lte_eNb.c 112 KB
Newer Older
1

2
/*******************************************************************************
3
    OpenAirInterface
ghaddab's avatar
ghaddab committed
4
    Copyright(c) 1999 - 2014 Eurecom
5

ghaddab's avatar
ghaddab committed
6
7
8
9
    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.
10
11


ghaddab's avatar
ghaddab committed
12
13
14
15
    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.
16

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

  Contact Information
ghaddab's avatar
ghaddab committed
23
24
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
25
  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
26

ghaddab's avatar
ghaddab committed
27
  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
28

ghaddab's avatar
ghaddab committed
29
 *******************************************************************************/
30
31
32

/*! \file phy_procedures_lte_eNB.c
 * \brief Implementation of eNB procedures from 36.213 LTE specifications
33
 * \author R. Knopp, F. Kaltenberger, N. Nikaein
34
35
36
 * \date 2011
 * \version 0.1
 * \company Eurecom
37
 * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr,navid.nikaein@eurecom.fr
38
39
40
41
42
43
44
45
46
 * \note
 * \warning
 */

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

47
#include "PHY/LTE_TRANSPORT/if4_tools.h"
Sandeep Kumar's avatar
Sandeep Kumar committed
48
#include "PHY/LTE_TRANSPORT/if5_tools.h"
49

50
51
52
53
#ifdef EMOS
#include "SCHED/phy_procedures_emos.h"
#endif

54
//#define DEBUG_PHY_PROC (Already defined in cmake)
55
56
57
58
59
60
61
//#define DEBUG_ULSCH

#include "LAYER2/MAC/extern.h"
#include "LAYER2/MAC/defs.h"
#include "UTIL/LOG/log.h"
#include "UTIL/LOG/vcd_signal_dumper.h"

62
63
#include "T.h"

64
#include "assertions.h"
gauthier's avatar
gauthier committed
65
#include "msc.h"
66

67
68
#include <time.h>

69
#if defined(ENABLE_ITTI)
gauthier's avatar
For RAL    
gauthier committed
70
#   include "intertask_interface.h"
71
72
#endif

73
74
75
76
77
78
//#define DIAG_PHY

#define NS_PER_SLOT 500000

#define PUCCH 1

79
80
void exit_fun(const char* s);

81
82
extern int exit_openair;

83
84
// Fix per CC openair rf/if device update
// extern openair0_device openair0;
85

86
87
88
unsigned char dlsch_input_buffer[2700] __attribute__ ((aligned(32)));
int eNB_sync_buffer0[640*6] __attribute__ ((aligned(32)));
int eNB_sync_buffer1[640*6] __attribute__ ((aligned(32)));
89
90
int *eNB_sync_buffer[2] = {eNB_sync_buffer0, eNB_sync_buffer1};

91
extern uint16_t hundred_times_log10_NPRB[100];
92

93
unsigned int max_peak_val;
94
int max_sync_pos;
95
96
97
98
99
100
101

//DCI_ALLOC_t dci_alloc[8];

#ifdef EMOS
fifo_dump_emos_eNB emos_dump_eNB;
#endif

102
#if defined(SMBV) 
103
104
extern const char smbv_fname[];
extern unsigned short config_frames[4];
gauthier's avatar
gauthier committed
105
extern uint8_t smbv_frame_cnt;
106
107
108
109
110
111
#endif

#ifdef DIAG_PHY
extern int rx_sig_fifo;
#endif

knopp's avatar
knopp committed
112
uint8_t is_SR_subframe(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,uint8_t UE_id)
113
{
knopp's avatar
   
knopp committed
114

115
116
  const int subframe = proc->subframe_rx;
  const int frame = proc->frame_rx;
117

118
  LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Checking for SR TXOp(sr_ConfigIndex %d)\n",
119
120
        eNB->Mod_id,eNB->ulsch[UE_id]->rnti,frame,subframe,
        eNB->scheduling_request_config[UE_id].sr_ConfigIndex);
121

122
123
  if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 4) {        // 5 ms SR period
    if ((subframe%5) == eNB->scheduling_request_config[UE_id].sr_ConfigIndex)
124
      return(1);
125
126
  } else if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 14) { // 10 ms SR period
    if (subframe==(eNB->scheduling_request_config[UE_id].sr_ConfigIndex-5))
127
      return(1);
128
129
  } else if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 34) { // 20 ms SR period
    if ((10*(frame&1)+subframe) == (eNB->scheduling_request_config[UE_id].sr_ConfigIndex-15))
130
      return(1);
131
132
  } else if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 74) { // 40 ms SR period
    if ((10*(frame&3)+subframe) == (eNB->scheduling_request_config[UE_id].sr_ConfigIndex-35))
133
      return(1);
134
135
  } else if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 154) { // 80 ms SR period
    if ((10*(frame&7)+subframe) == (eNB->scheduling_request_config[UE_id].sr_ConfigIndex-75))
136
      return(1);
137
138
139
140
  }

  return(0);
}
141

142
143
144
145
146
147
void put_harq_pid_in_freelist(LTE_eNB_DLSCH_t *DLSCH_ptr, int harq_pid)
{
  DLSCH_ptr->harq_pid_freelist[DLSCH_ptr->tail_freelist] = harq_pid;
  DLSCH_ptr->tail_freelist = (DLSCH_ptr->tail_freelist + 1) % 10;
}

Cedric Roux's avatar
Cedric Roux committed
148
void remove_harq_pid_from_freelist(LTE_eNB_DLSCH_t *DLSCH_ptr, int harq_pid)
149
150
151
152
153
{
  if (DLSCH_ptr->head_freelist == DLSCH_ptr->tail_freelist) {
    LOG_E(PHY, "%s:%d: you cannot read this!\n", __FILE__, __LINE__);
    abort();
  }
Cedric Roux's avatar
Cedric Roux committed
154
155
156
157
158
159
160
161
162
  /* basic check, in case several threads deal with the free list at the same time
   * in normal situations it should not happen, that's also why we don't use any
   * locking mechanism to protect the free list
   * to be refined in case things don't work properly
   */
  if (harq_pid != DLSCH_ptr->harq_pid_freelist[DLSCH_ptr->head_freelist]) {
    LOG_E(PHY, "%s:%d: critical error, get in touch with the authors\n", __FILE__, __LINE__);
    abort();
  }
163
164
165
  DLSCH_ptr->head_freelist = (DLSCH_ptr->head_freelist + 1) % 10;
}

166
int32_t add_ue(int16_t rnti, PHY_VARS_eNB *eNB)
167
{
gauthier's avatar
gauthier committed
168
  uint8_t i;
169

170
171

  LOG_D(PHY,"[eNB %d/%d] Adding UE with rnti %x\n",
172
173
        eNB->Mod_id,
        eNB->CC_id,
Cedric Roux's avatar
Cedric Roux committed
174
        (uint16_t)rnti);
175
176

  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
177
    if ((eNB->dlsch[i]==NULL) || (eNB->ulsch[i]==NULL)) {
178
      MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed add ue %"PRIx16" (ENOMEM)", rnti);
179
180
      LOG_E(PHY,"Can't add UE, not enough memory allocated\n");
      return(-1);
181
    } else {
182
      if (eNB->UE_stats[i].crnti==0) {
183
        MSC_LOG_EVENT(MSC_PHY_ENB, "0 Add ue %"PRIx16" ", rnti);
184
        LOG_D(PHY,"UE_id %d associated with rnti %x\n",i, (uint16_t)rnti);
185
186
187
        eNB->dlsch[i][0]->rnti = rnti;
        eNB->ulsch[i]->rnti = rnti;
        eNB->UE_stats[i].crnti = rnti;
knopp's avatar
knopp committed
188

189
190
191
	eNB->UE_stats[i].Po_PUCCH1_below = 0;
	eNB->UE_stats[i].Po_PUCCH1_above = (int32_t)pow(10.0,.1*(eNB->frame_parms.ul_power_control_config_common.p0_NominalPUCCH+eNB->rx_total_gain_dB));
	eNB->UE_stats[i].Po_PUCCH        = (int32_t)pow(10.0,.1*(eNB->frame_parms.ul_power_control_config_common.p0_NominalPUCCH+eNB->rx_total_gain_dB));
192
	LOG_D(PHY,"Initializing Po_PUCCH: p0_NominalPUCCH %d, gain %d => %d\n",
193
194
195
	      eNB->frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
	      eNB->rx_total_gain_dB,
	      eNB->UE_stats[i].Po_PUCCH);
knopp's avatar
knopp committed
196
  
197
        return(i);
198
      }
199
    }
200
201
202
203
  }
  return(-1);
}

204
int mac_phy_remove_ue(module_id_t Mod_idP,rnti_t rntiP) {
gauthier's avatar
gauthier committed
205
  uint8_t i;
206
  int j,CC_id;
207
  PHY_VARS_eNB *eNB;
208
209

  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
210
    eNB = PHY_vars_eNB_g[Mod_idP][CC_id];
211
    for (i=0; i<NUMBER_OF_UE_MAX; i++) {
212
      if ((eNB->dlsch[i]==NULL) || (eNB->ulsch[i]==NULL)) {
213
214
215
216
	MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed remove ue %"PRIx16" (ENOMEM)", rnti);
	LOG_E(PHY,"Can't remove UE, not enough memory allocated\n");
	return(-1);
      } else {
217
	if (eNB->UE_stats[i].crnti==rntiP) {
218
	  MSC_LOG_EVENT(MSC_PHY_ENB, "0 Removed ue %"PRIx16" ", rntiP);
219
220
221

	  LOG_D(PHY,"eNB %d removing UE %d with rnti %x\n",eNB->Mod_id,i,rntiP);

222
	  //LOG_D(PHY,("[PHY] UE_id %d\n",i);
223
224
225
226
	  clean_eNb_dlsch(eNB->dlsch[i][0]);
	  clean_eNb_ulsch(eNB->ulsch[i]);
	  //eNB->UE_stats[i].crnti = 0;
	  memset(&eNB->UE_stats[i],0,sizeof(LTE_eNB_UE_stats));
227
228
229
	  //  mac_exit_wrapper("Removing UE");
	  
	  /* clear the harq pid freelist */
230
231
	  eNB->dlsch[i][0]->head_freelist = 0;
	  eNB->dlsch[i][0]->tail_freelist = 0;
232
	  for (j = 0; j < 8; j++)
233
	    put_harq_pid_in_freelist(eNB->dlsch[i][0], j);
234
235
236
	  
	  return(i);
	}
237
      }
238
    }
239
  }
240
  MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed remove ue %"PRIx16" (not found)", rntiP);
241
242
243
  return(-1);
}

244
int8_t find_next_ue_index(PHY_VARS_eNB *eNB)
245
{
gauthier's avatar
gauthier committed
246
  uint8_t i;
247

248
  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
249
250
251
252
    if (eNB->UE_stats[i].crnti==0) {
      /*if ((eNB->dlsch[i]) &&
      (eNB->dlsch[i][0]) &&
      (eNB->dlsch[i][0]->rnti==0))*/
253
254
255
      LOG_D(PHY,"Next free UE id is %d\n",i);
      return(i);
    }
256
  }
257

258
259
260
  return(-1);
}

gauthier's avatar
gauthier committed
261
int get_ue_active_harq_pid(const uint8_t Mod_id,const uint8_t CC_id,const uint16_t rnti, const int frame, const uint8_t subframe,uint8_t *harq_pid,uint8_t *round,const uint8_t ul_flag)
262
263
264
265
{
  LTE_eNB_DLSCH_t *DLSCH_ptr;
  LTE_eNB_ULSCH_t *ULSCH_ptr;
  uint8_t ulsch_subframe,ulsch_frame;
gauthier's avatar
gauthier committed
266
  uint8_t i;
knopp's avatar
   
knopp committed
267
  int8_t UE_id = find_ue(rnti,PHY_vars_eNB_g[Mod_id][CC_id]);
268
  int sf1=(10*frame)+subframe,sf2,sfdiff,sfdiff_max=7;
269
270

  if (UE_id==-1) {
271
    LOG_D(PHY,"Cannot find UE with rnti %x (Mod_id %d, CC_id %d)\n",rnti, Mod_id, CC_id);
272
273
    *round=0;
    return(-1);
274
275
276
  }

  if (ul_flag == 0)  {// this is a DL request
277
    DLSCH_ptr = PHY_vars_eNB_g[Mod_id][CC_id]->dlsch[(uint32_t)UE_id][0];
278

279
280
281
282
283
    // set to no available process first
    *harq_pid = -1;

    for (i=0; i<DLSCH_ptr->Mdlharq; i++) {
      if (DLSCH_ptr->harq_processes[i]!=NULL) {
284
	if (DLSCH_ptr->harq_processes[i]->status == ACTIVE) {
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
	  sf2 = (DLSCH_ptr->harq_processes[i]->frame*10) + DLSCH_ptr->harq_processes[i]->subframe;
	  if (sf2<=sf1)
	    sfdiff = sf1-sf2;
	  else // this happens when wrapping around 1024 frame barrier
	    sfdiff = 10240 + sf1-sf2;
	  LOG_D(PHY,"process %d is active, round %d (waiting %d)\n",i,DLSCH_ptr->harq_processes[i]->round,sfdiff);

	  if (sfdiff>sfdiff_max) { // this is an active process that is waiting longer than the others (and longer than 7 ms)
	    sfdiff_max = sfdiff; 
	    *harq_pid = i;
	    *round = DLSCH_ptr->harq_processes[i]->round;
	  }
	}
      } else { // a process is not defined
	LOG_E(PHY,"[eNB %d] DLSCH process %d for rnti %x (UE_id %d) not allocated\n",Mod_id,i,rnti,UE_id);
	return(-1);
301
      }
302
    }
303
304
305
306
307
308
309
310

    /* if no active harq pid, get the oldest in the freelist, if any */
    if (*harq_pid == 255 && DLSCH_ptr->head_freelist != DLSCH_ptr->tail_freelist) {
      *harq_pid = DLSCH_ptr->harq_pid_freelist[DLSCH_ptr->head_freelist];
      *round = 0;
      LOG_D(PHY,"process %d is first free process\n", *harq_pid);
    }

311
312
    LOG_D(PHY,"get_ue_active_harq_pid DL => Frame %d, Subframe %d : harq_pid %d\n",
	  frame,subframe,*harq_pid);
313
  } else { // This is a UL request
314

315
316
317
    ULSCH_ptr = PHY_vars_eNB_g[Mod_id][CC_id]->ulsch[(uint32_t)UE_id];
    ulsch_subframe = pdcch_alloc2ul_subframe(&PHY_vars_eNB_g[Mod_id][CC_id]->frame_parms,subframe);
    ulsch_frame    = pdcch_alloc2ul_frame(&PHY_vars_eNB_g[Mod_id][CC_id]->frame_parms,frame,subframe);
318
    // Note this is for TDD configuration 3,4,5 only
319
    *harq_pid = subframe2harq_pid(&PHY_vars_eNB_g[Mod_id][CC_id]->frame_parms,
320
321
                                  ulsch_frame,
                                  ulsch_subframe);
322
    *round    = ULSCH_ptr->harq_processes[*harq_pid]->round;
323
    LOG_T(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d Checking HARQ, round %d\n",Mod_id,*harq_pid,frame,subframe,*round);
324
  }
325

326
327
328
  return(0);
}

knopp's avatar
knopp committed
329
int16_t get_target_pusch_rx_power(const module_id_t module_idP, const uint8_t CC_id)
330
{
331
  return PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.ul_power_control_config_common.p0_NominalPUSCH;
332
333
}

knopp's avatar
knopp committed
334
335
int16_t get_target_pucch_rx_power(const module_id_t module_idP, const uint8_t CC_id)
{
336
  return PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.ul_power_control_config_common.p0_NominalPUCCH;
knopp's avatar
knopp committed
337
338
}

339
#ifdef EMOS
340
void phy_procedures_emos_eNB_TX(unsigned char subframe, PHY_VARS_eNB *eNB)
341
{
342
343
344
345
346
347

}
#endif



knopp's avatar
knopp committed
348
void phy_procedures_eNB_S_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,uint8_t abstraction_flag,relaying_type_t r_type)
349
350
{
  UNUSED(r_type);
351
  int subframe = proc->subframe_rx;
352

353
#ifdef DEBUG_PHY_PROC
354
  LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_S_RX(%d)\n", eNB->Mod_id,proc->frame_rx, subframe);
355
#endif
356

357

knopp's avatar
   
knopp committed
358
  if (abstraction_flag == 0) {
359
    lte_eNB_I0_measurements(eNB,
360
			    subframe,
361
                            0,
362
                            eNB->first_run_I0_measurements);
knopp's avatar
   
knopp committed
363
  }
364

365
#ifdef PHY_ABSTRACTION
knopp's avatar
   
knopp committed
366
  else {
367
    lte_eNB_I0_measurements_emul(eNB,
368
                                 0);
369
  }
370

knopp's avatar
   
knopp committed
371
372
#endif

373

374
375
}

knopp's avatar
   
knopp committed
376
377


378
#ifdef EMOS
379
void phy_procedures_emos_eNB_RX(unsigned char subframe,PHY_VARS_eNB *eNB)
380
381
{

gauthier's avatar
gauthier committed
382
383
  uint8_t aa;
  uint16_t last_subframe_emos;
384
  uint16_t pilot_pos1 = 3 - eNB->frame_parms.Ncp, pilot_pos2 = 10 - 2*eNB->frame_parms.Ncp;
gauthier's avatar
gauthier committed
385
  uint32_t bytes;
386
387
388

  last_subframe_emos=0;

knopp's avatar
   
knopp committed
389

knopp's avatar
   
knopp committed
390

knopp's avatar
   
knopp committed
391

392
#ifdef EMOS_CHANNEL
393

394
  //if (last_slot%2==1) // this is for all UL subframes
395
  if (subframe==3)
396
397
398
399
400
401
402
    for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) {
      memcpy(&emos_dump_eNB.channel[aa][last_subframe_emos*2*eNB->frame_parms.N_RB_UL*12],
             &eNB->pusch_vars[0]->drs_ch_estimates[0][aa][eNB->frame_parms.N_RB_UL*12*pilot_pos1],
             eNB->frame_parms.N_RB_UL*12*sizeof(int));
      memcpy(&emos_dump_eNB.channel[aa][(last_subframe_emos*2+1)*eNB->frame_parms.N_RB_UL*12],
             &eNB->pusch_vars[0]->drs_ch_estimates[0][aa][eNB->frame_parms.N_RB_UL*12*pilot_pos2],
             eNB->frame_parms.N_RB_UL*12*sizeof(int));
403
    }
404

405
406
#endif

knopp's avatar
   
knopp committed
407
  if (subframe==4) {
408
    emos_dump_eNB.timestamp = rt_get_time_ns();
409
410
411
412
413
    emos_dump_eNB.frame_tx = eNB->proc[subframe].frame_rx;
    emos_dump_eNB.rx_total_gain_dB = eNB->rx_total_gain_dB;
    emos_dump_eNB.mimo_mode = eNB->transmission_mode[0];
    memcpy(&emos_dump_eNB.measurements,
           &eNB->measurements[0],
414
           sizeof(PHY_MEASUREMENTS_eNB));
415
    memcpy(&emos_dump_eNB.UE_stats[0],&eNB->UE_stats[0],NUMBER_OF_UE_MAX*sizeof(LTE_eNB_UE_stats));
416
417

    bytes = rtf_put(CHANSOUNDER_FIFO_MINOR, &emos_dump_eNB, sizeof(fifo_dump_emos_eNB));
418

419
420
    //bytes = rtf_put(CHANSOUNDER_FIFO_MINOR, "test", sizeof("test"));
    if (bytes!=sizeof(fifo_dump_emos_eNB)) {
knopp's avatar
   
knopp committed
421
      LOG_W(PHY,"[eNB %d] Frame %d, subframe %d, Problem writing EMOS data to FIFO (bytes=%d, size=%d)\n",
422
            eNB->Mod_id,eNB->proc[(subframe+1)%10].frame_rx, subframe,bytes,sizeof(fifo_dump_emos_eNB));
423
    } else {
424
      if (eNB->proc[(subframe+1)%10].frame_tx%100==0) {
knopp's avatar
   
knopp committed
425
        LOG_I(PHY,"[eNB %d] Frame %d (%d), subframe %d, Writing %d bytes EMOS data to FIFO\n",
426
              eNB->Mod_id,eNB->proc[(subframe+1)%10].frame_rx, ((fifo_dump_emos_eNB*)&emos_dump_eNB)->frame_tx, subframe, bytes);
427
      }
428
    }
429
430
431
432
433
434
435
  }
}
#endif


#define AMP_OVER_SQRT2 ((AMP*ONE_OVER_SQRT2_Q15)>>15)
#define AMP_OVER_2 (AMP>>1)
436
437
int QPSK[4]= {AMP_OVER_SQRT2|(AMP_OVER_SQRT2<<16),AMP_OVER_SQRT2|((65536-AMP_OVER_SQRT2)<<16),((65536-AMP_OVER_SQRT2)<<16)|AMP_OVER_SQRT2,((65536-AMP_OVER_SQRT2)<<16)|(65536-AMP_OVER_SQRT2)};
int QPSK2[4]= {AMP_OVER_2|(AMP_OVER_2<<16),AMP_OVER_2|((65536-AMP_OVER_2)<<16),((65536-AMP_OVER_2)<<16)|AMP_OVER_2,((65536-AMP_OVER_2)<<16)|(65536-AMP_OVER_2)};
438

gauthier's avatar
For RAL    
gauthier committed
439

knopp's avatar
   
knopp committed
440

Cedric Roux's avatar
Cedric Roux committed
441
unsigned int taus(void);
442
DCI_PDU DCI_pdu_tmp;
knopp's avatar
   
knopp committed
443

knopp's avatar
   
knopp committed
444

knopp's avatar
knopp committed
445
void pmch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,PHY_VARS_RN *rn, int abstraction_flag,relaying_type_t r_type) {
446

knopp's avatar
   
knopp committed
447

448
#ifdef Rel10
449
450
  MCH_PDU *mch_pduP;
  MCH_PDU  mch_pdu;
451
  //  uint8_t sync_area=255;
452
#endif
453

454
  int subframe = proc->subframe_tx;
455

knopp's avatar
   
knopp committed
456
  if (abstraction_flag==0) {
457
458
    // This is DL-Cell spec pilots in Control region
    generate_pilots_slot(eNB,
459
			 eNB->common_vars.txdataF[0],
460
461
			 AMP,
			 subframe<<1,1);
knopp's avatar
   
knopp committed
462
  }
463
  
464
#ifdef Rel10
465
466
467
468
  // if mcch is active, send regardless of the node type: eNB or RN
  // when mcch is active, MAC sched does not allow MCCH and MTCH multiplexing
  mch_pduP = mac_xface->get_mch_sdu(eNB->Mod_id,
				    eNB->CC_id,
469
				    proc->frame_tx,
470
471
472
473
474
475
				    subframe);
  
  switch (r_type) {
  case no_relay:
    if ((mch_pduP->Pdu_size > 0) && (mch_pduP->sync_area == 0)) // TEST: only transmit mcch for sync area 0
      LOG_I(PHY,"[eNB%"PRIu8"] Frame %d subframe %d : Got MCH pdu for MBSFN (MCS %"PRIu8", TBS %d) \n",
476
477
	    eNB->Mod_id,proc->frame_tx,subframe,mch_pduP->mcs,
	    eNB->dlsch_MCH->harq_processes[0]->TBS>>3);
478
479
    else {
      LOG_D(PHY,"[DeNB %"PRIu8"] Frame %d subframe %d : Do not transmit MCH pdu for MBSFN sync area %"PRIu8" (%s)\n",
480
	    eNB->Mod_id,proc->frame_tx,subframe,mch_pduP->sync_area,
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
	    (mch_pduP->Pdu_size == 0)? "Empty MCH PDU":"Let RN transmit for the moment");
      mch_pduP = NULL;
    }
    
    break;
    
  case multicast_relay:
    if ((mch_pduP->Pdu_size > 0) && ((mch_pduP->mcch_active == 1) || mch_pduP->msi_active==1)) {
      LOG_I(PHY,"[RN %"PRIu8"] Frame %d subframe %d: Got the MCH PDU for MBSFN  sync area %"PRIu8" (MCS %"PRIu8", TBS %"PRIu16")\n",
	    rn->Mod_id,rn->frame, subframe,
	    mch_pduP->sync_area,mch_pduP->mcs,mch_pduP->Pdu_size);
    } else if (rn->mch_avtive[subframe%5] == 1) { // SF2 -> SF7, SF3 -> SF8
      mch_pduP= &mch_pdu;
      memcpy(&mch_pduP->payload, // could be a simple copy
	     rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->b,
	     rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->TBS>>3);
      mch_pduP->Pdu_size = (uint16_t) (rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->TBS>>3);
      mch_pduP->mcs = rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->mcs;
      LOG_I(PHY,"[RN %"PRIu8"] Frame %d subframe %d: Forward the MCH PDU for MBSFN received on SF %d sync area %"PRIu8" (MCS %"PRIu8", TBS %"PRIu16")\n",
	    rn->Mod_id,rn->frame, subframe,subframe%5,
	    rn->sync_area[subframe%5],mch_pduP->mcs,mch_pduP->Pdu_size);
knopp's avatar
   
knopp committed
502
    } else {
503
      mch_pduP=NULL;
504
    }
505
506
507
508
509
510
    
    rn->mch_avtive[subframe]=0;
    break;
    
  default:
    LOG_W(PHY,"[eNB %"PRIu8"] Frame %d subframe %d: unknown relaying type %d \n",
511
	  eNB->Mod_id,proc->frame_tx,subframe,r_type);
512
513
514
515
516
517
518
    mch_pduP=NULL;
    break;
  }// switch
  
  if (mch_pduP) {
    fill_eNB_dlsch_MCH(eNB,mch_pduP->mcs,1,0, abstraction_flag);
    // Generate PMCH
knopp's avatar
knopp committed
519
    generate_mch(eNB,proc,(uint8_t*)mch_pduP->payload,abstraction_flag);
520
  } else {
521
    LOG_D(PHY,"[eNB/RN] Frame %d subframe %d: MCH not generated \n",proc->frame_tx,subframe);
knopp's avatar
   
knopp committed
522
  }
523
524
525
  
#endif
}
526

knopp's avatar
knopp committed
527
void common_signal_procedures (PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int abstraction_flag) {
528

529
530
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
  int **txdataF = eNB->common_vars.txdataF[0];
531
  uint8_t *pbch_pdu=&eNB->pbch_pdu[0];
532
533
  int subframe = proc->subframe_tx;
  int frame = proc->frame_tx;
534

535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
  // generate Cell-Specific Reference Signals for both slots
  if (abstraction_flag==0) {
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX,1);
    generate_pilots_slot(eNB,
			 txdataF,
			 AMP,
			 subframe<<1,0);
    // check that 2nd slot is for DL
    if (subframe_select(fp,subframe) == SF_DL)
      generate_pilots_slot(eNB,
			   txdataF,
			   AMP,
			   (subframe<<1)+1,0);
    
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX,0);
  }    
knopp's avatar
   
knopp committed
551

552
  // First half of PSS/SSS (FDD, slot 0)
knopp's avatar
   
knopp committed
553
  if (subframe == 0) {
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
    if ((fp->frame_type == FDD) &&
	(abstraction_flag==0)) {
      generate_pss(txdataF,
		   AMP,
		   fp,
		   (fp->Ncp==NORMAL) ? 6 : 5,
		   0);
      generate_sss(txdataF,
		   AMP,
		   fp,
		   (fp->Ncp==NORMAL) ? 5 : 4,
		   0);
      
    }
    
569
    // generate PBCH (Physical Broadcast CHannel) info
570
    if ((frame&3) == 0) {
571
      pbch_pdu[2] = 0;
572
      
573
      // FIXME setting pbch_pdu[2] to zero makes the switch statement easier: remove all the or-operators
574
      switch (fp->N_RB_DL) {
knopp's avatar
   
knopp committed
575
      case 6:
576
577
578
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (0<<5);
	break;
	
knopp's avatar
   
knopp committed
579
      case 15:
580
581
582
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (1<<5);
	break;
	
knopp's avatar
   
knopp committed
583
      case 25:
584
585
586
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (2<<5);
	break;
	
knopp's avatar
   
knopp committed
587
      case 50:
588
589
590
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (3<<5);
	break;
	
knopp's avatar
   
knopp committed
591
      case 75:
592
593
594
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (4<<5);
	break;
	
knopp's avatar
   
knopp committed
595
      case 100:
596
597
598
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (5<<5);
	break;
	
knopp's avatar
   
knopp committed
599
      default:
600
601
602
	// FIXME if we get here, this should be flagged as an error, right?
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (2<<5);
	break;
knopp's avatar
   
knopp committed
603
      }
604
      
605
      pbch_pdu[2] = (pbch_pdu[2]&0xef) |
606
607
608
	((fp->phich_config_common.phich_duration << 4)&0x10);
      
      switch (fp->phich_config_common.phich_resource) {
knopp's avatar
   
knopp committed
609
      case oneSixth:
610
611
612
	pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (0<<2);
	break;
	
knopp's avatar
   
knopp committed
613
      case half:
614
615
616
	pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (1<<2);
	break;
	
knopp's avatar
   
knopp committed
617
      case one:
618
619
620
	pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (2<<2);
	break;
	
knopp's avatar
   
knopp committed
621
      case two:
622
623
624
	pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (3<<2);
	break;
	
knopp's avatar
   
knopp committed
625
      default:
626
627
	// unreachable
	break;
knopp's avatar
   
knopp committed
628
      }
629
      
630
631
      pbch_pdu[2] = (pbch_pdu[2]&0xfc) | ((frame>>8)&0x3);
      pbch_pdu[1] = frame&0xfc;
632
      pbch_pdu[0] = 0;
knopp's avatar
   
knopp committed
633
    }
634
635
636
637
638
639
640
641
642
643
644
      
    /// First half of SSS (TDD, slot 1)
    
    if ((fp->frame_type == TDD)&&
	(abstraction_flag==0)){
      generate_sss(txdataF,
		   AMP,
		   fp,
		   (fp->Ncp==NORMAL) ? 6 : 5,
		   1);
    }
645

646
    /// generate PBCH
knopp's avatar
   
knopp committed
647
    if (abstraction_flag==0) {
648
      generate_pbch(&eNB->pbch,
649
650
651
652
                    txdataF,
                    AMP,
                    fp,
                    pbch_pdu,
653
                    frame&3);
654
655
656
657
658
659
    }
#ifdef PHY_ABSTRACTION
    else {
      generate_pbch_emul(eNB,pbch_pdu);
    }
#endif
660

661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
  }
  else if ((subframe == 1) &&
	   (fp->frame_type == TDD)&&
	   (abstraction_flag==0)) {
    generate_pss(txdataF,
		 AMP,
		 fp,
		 2,
		 2);
  }
  
  // Second half of PSS/SSS (FDD, slot 10)
  else if ((subframe == 5) && 
	   (fp->frame_type == FDD) &&
	   (abstraction_flag==0)) {
        generate_pss(txdataF,
677
                     AMP,
678
                     &eNB->frame_parms,
679
680
681
682
                     (fp->Ncp==NORMAL) ? 6 : 5,
                     10);
        generate_sss(txdataF,
                     AMP,
683
                     &eNB->frame_parms,
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
                     (fp->Ncp==NORMAL) ? 5 : 4,
                     10);

  }

  //  Second-half of SSS (TDD, slot 11)
  else if ((subframe == 5) &&
	   (fp->frame_type == TDD) &&
	   (abstraction_flag==0)) {
    generate_sss(txdataF,
		 AMP,
		 fp,
		 (fp->Ncp==NORMAL) ? 6 : 5,
		 11);
  }

  // Second half of PSS (TDD, slot 12)
  else if ((subframe == 6) &&
	   (fp->frame_type == TDD) &&
	   (abstraction_flag==0)) {
    generate_pss(txdataF,
		 AMP,
		 fp,
		 2,
		 12);
  }

}

knopp's avatar
knopp committed
713
void generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,const int UE_id) {
714

715
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
716
717
  int frame = proc->frame_tx;
  int subframe = proc->subframe_tx;
718
719
720
721
722
723
724
725
726

  // if we have SI_RNTI, configure dlsch parameters and CCE index
  if (dci_alloc->rnti == SI_RNTI) {
    LOG_D(PHY,"Generating dlsch params for SI_RNTI\n");
    generate_eNB_dlsch_params_from_dci(frame,
				       subframe,
				       &dci_alloc->dci_pdu[0],
				       dci_alloc->rnti,
				       dci_alloc->format,
727
				       &eNB->dlsch_SI,
728
729
730
731
732
				       fp,
				       eNB->pdsch_config_dedicated,
				       SI_RNTI,
				       0,
				       P_RNTI,
733
				       eNB->UE_stats[0].DL_pmi_single);
734
735
    
    
736
    eNB->dlsch_SI->nCCE[subframe] = dci_alloc->firstCCE;
737
    
738
    LOG_T(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for common DCI (SI)  => %"PRIu8"\n",eNB->Mod_id,frame,subframe,
739
	  eNB->dlsch_SI->nCCE[subframe]);
740
741
742
743
    
#if defined(SMBV) 
    
    // configure SI DCI
744
745
    if (smbv_is_config_frame(frame) && (smbv_frame_cnt < 4)) {
      LOG_D(PHY,"[SMBV] Frame %3d, SI in SF %d DCI %"PRIu32"\n",frame,subframe,i);
746
747
748
749
750
751
752
753
754
755
756
757
758
759
      smbv_configure_common_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), "SI", dci_alloc, i);
    }
    
#endif
    
    
  } else if (dci_alloc->ra_flag == 1) {  // This is format 1A allocation for RA
    // configure dlsch parameters and CCE index
    LOG_D(PHY,"Generating dlsch params for RA_RNTI\n");    
    generate_eNB_dlsch_params_from_dci(frame,
				       subframe,
				       &dci_alloc->dci_pdu[0],
				       dci_alloc->rnti,
				       dci_alloc->format,
760
				       &eNB->dlsch_ra,
761
762
763
764
765
				       fp,
				       eNB->pdsch_config_dedicated,
				       SI_RNTI,
				       dci_alloc->rnti,
				       P_RNTI,
766
				       eNB->UE_stats[0].DL_pmi_single);
767
768
    
    
769
    eNB->dlsch_ra->nCCE[subframe] = dci_alloc->firstCCE;
770
    
771
    LOG_D(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for common DCI (RA)  => %"PRIu8"\n",eNB->Mod_id,frame,subframe,
772
	  eNB->dlsch_ra->nCCE[subframe]);
773
774
775
#if defined(SMBV) 
    
    // configure RA DCI
776
777
    if (smbv_is_config_frame(frame) && (smbv_frame_cnt < 4)) {
      LOG_D(PHY,"[SMBV] Frame %3d, RA in SF %d DCI %"PRIu32"\n",frame,subframe,i);
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
      smbv_configure_common_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), "RA", dci_alloc, i);
    }
    
#endif
    
  }
  
  else if ((dci_alloc->format != format0)&&
	   (dci_alloc->format != format3)&&
	   (dci_alloc->format != format3A)&&
	   (dci_alloc->format != format4)){ // this is a normal DLSCH allocation
    

    
    if (UE_id>=0) {
#if defined(SMBV) 
      // Configure this user
795
796
      if (smbv_is_config_frame(frame) && (smbv_frame_cnt < 4)) {
	LOG_D(PHY,"[SMBV] Frame %3d, SF %d (SMBV SF %d) Configuring user %d with RNTI %"PRIu16" in TM%"PRIu8"\n",frame,subframe,(smbv_frame_cnt*10) + (subframe),UE_id+1,
797
798
799
800
801
802
803
804
805
806
807
808
              dci_alloc->rnti,eNB->transmission_mode[(uint8_t)UE_id]);
	smbv_configure_user(smbv_fname,UE_id+1,eNB->transmission_mode[(uint8_t)UE_id],dci_alloc->rnti);
      }
      
#endif

      LOG_D(PHY,"Generating dlsch params for RNTI %x\n",dci_alloc->rnti);      
      generate_eNB_dlsch_params_from_dci(frame,
					 subframe,
					 &dci_alloc->dci_pdu[0],
					 dci_alloc->rnti,
					 dci_alloc->format,
809
					 eNB->dlsch[(uint8_t)UE_id],
810
811
812
813
814
					 fp,
					 eNB->pdsch_config_dedicated,
					 SI_RNTI,
					 0,
					 P_RNTI,
815
					 eNB->UE_stats[(uint8_t)UE_id].DL_pmi_single);
816
      LOG_D(PHY,"[eNB %"PRIu8"][PDSCH %"PRIx16"/%"PRIu8"] Frame %d subframe %d: Generated dlsch params\n",
817
	    eNB->Mod_id,dci_alloc->rnti,eNB->dlsch[(uint8_t)UE_id][0]->current_harq_pid,frame,subframe);
818
819
      
      
820
      eNB->dlsch[(uint8_t)UE_id][0]->nCCE[subframe] = dci_alloc->firstCCE;
821
      
822
      LOG_D(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for ue DCI (PDSCH %"PRIx16")  => %"PRIu8"/%u\n",eNB->Mod_id,frame,subframe,
823
	    dci_alloc->rnti,eNB->dlsch[(uint8_t)UE_id][0]->nCCE[subframe]);
824
825
826
827
      
#if defined(SMBV) 
      
      // configure UE-spec DCI
828
829
      if (smbv_is_config_frame(frame) && (smbv_frame_cnt < 4)) {
	LOG_D(PHY,"[SMBV] Frame %3d, PDSCH in SF %d DCI %"PRIu32"\n",frame,subframe,i);
830
	smbv_configure_ue_spec_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), UE_id+1,dci_alloc, i);
knopp's avatar
   
knopp committed
831
      }
832
833
834
835
836
      
#endif
      
      LOG_D(PHY,"[eNB %"PRIu8"][DCI][PDSCH %"PRIx16"] Frame %d subframe %d UE_id %"PRId8" Generated DCI format %d, aggregation %d\n",
	    eNB->Mod_id, dci_alloc->rnti,
837
	    frame, subframe,UE_id,
838
839
840
841
	    dci_alloc->format,
	    1<<dci_alloc->L);
    } else {
      LOG_D(PHY,"[eNB %"PRIu8"][PDSCH] Frame %d : No UE_id with corresponding rnti %"PRIx16", dropping DLSCH\n",
842
	    eNB->Mod_id,frame,dci_alloc->rnti);
knopp's avatar
   
knopp committed
843
    }
844
845
846
  }
  
}
847

knopp's avatar
knopp committed
848
void generate_eNB_ulsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,const int UE_id) {
849

850
  int harq_pid;
851
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
852
  int frame = proc->frame_tx;
knopp's avatar
knopp committed
853
  int subframe = proc->subframe_tx;
854

855
  LOG_D(PHY,
856
857
858
	"[eNB %"PRIu8"][PUSCH %"PRIu8"] Frame %d subframe %d UL Frame %"PRIu32", UL Subframe %"PRIu8", Generated ULSCH (format0) DCI (rnti %"PRIx16", dci %"PRIx8"), aggregation %d\n",
	eNB->Mod_id,
	subframe2harq_pid(fp,
859
			  pdcch_alloc2ul_frame(fp,frame,subframe),
860
			  pdcch_alloc2ul_subframe(fp,subframe)),
861
	frame,
862
	subframe,
863
	pdcch_alloc2ul_frame(fp,frame,subframe),
864
865
866
867
868
	pdcch_alloc2ul_subframe(fp,subframe),
	dci_alloc->rnti,
	dci_alloc->dci_pdu[0],
	1<<dci_alloc->L);
  
869
  generate_eNB_ulsch_params_from_dci(eNB,
knopp's avatar
knopp committed
870
				     proc,
871
				     &dci_alloc->dci_pdu[0],
872
873
874
875
876
877
878
879
880
881
				     dci_alloc->rnti,
				     format0,
				     UE_id,
				     SI_RNTI,
				     0,
				     P_RNTI,
				     CBA_RNTI,
				     0);  // do_srs
  
  LOG_T(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resources for UE spec DCI (PUSCH %"PRIx16") => %d\n",
882
	eNB->Mod_id,frame,subframe,dci_alloc->rnti,
883
884
885
886
887
	dci_alloc->firstCCE);
  
#if defined(SMBV) 
  
  // configure UE-spec DCI for UL Grant
888
889
  if (smbv_is_config_frame(frame) && (smbv_frame_cnt < 4)) {
    LOG_D(PHY,"[SMBV] Frame %3d, SF %d UL DCI %"PRIu32"\n",frame,subframe,i);
890
891
892
893
894
895
896
897
    smbv_configure_ue_spec_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), UE_id+1, &DCI_pdu->dci_alloc[i], i);
  }
  
#endif
  
  
  // get the hard_pid for this subframe 
  harq_pid = subframe2harq_pid(fp,
898
			       pdcch_alloc2ul_frame(fp,frame,subframe),
899
900
901
			       pdcch_alloc2ul_subframe(fp,subframe));
  
  if (harq_pid==255) { // should not happen, log an error and exit, this is a fatal error
902
    LOG_E(PHY,"[eNB %"PRIu8"] Frame %d: Bad harq_pid for ULSCH allocation\n",eNB->Mod_id,frame);
903
904
905
906
    mac_xface->macphy_exit("FATAL\n"); 
  }
  
  if ((dci_alloc->rnti  >= CBA_RNTI) && (dci_alloc->rnti < P_RNTI))
907
    eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_cba_scheduling_flag = 1;
908
  else
909
    eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
910
911
  
}
912

knopp's avatar
knopp committed
913
void pdsch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,LTE_eNB_DLSCH_t *dlsch, LTE_eNB_DLSCH_t *dlsch1,LTE_eNB_UE_stats *ue_stats,int ra_flag,int num_pdcch_symbols,int abstraction_flag) {
914

915
916
  int frame=proc->frame_tx;
  int subframe=proc->subframe_tx;
917
918
919
  int harq_pid = dlsch->current_harq_pid;
  LTE_DL_eNB_HARQ_t *dlsch_harq=dlsch->harq_processes[harq_pid];
  int input_buffer_length = dlsch_harq->TBS/8;
920
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
921
922
923
924
925
926
927
928
  uint8_t *DLSCH_pdu=NULL;
  uint8_t DLSCH_pdu_tmp[768*8];
  uint8_t DLSCH_pdu_rar[256];
  int i;

  LOG_D(PHY,
	"[eNB %"PRIu8"][PDSCH %"PRIx16"/%"PRIu8"] Frame %d, subframe %d: Generating PDSCH/DLSCH with input size = %"PRIu16", G %d, nb_rb %"PRIu16", mcs %"PRIu8", pmi_alloc %"PRIx16", rv %"PRIu8" (round %"PRIu8")\n",
	eNB->Mod_id, dlsch->rnti,harq_pid,
929
	frame, subframe, input_buffer_length,
930
931
932
933
934
	get_G(fp,
	      dlsch_harq->nb_rb,
	      dlsch_harq->rb_alloc,
	      get_Qm(dlsch_harq->mcs),
	      dlsch_harq->Nl,
935
	      num_pdcch_symbols,frame,subframe),
936
937
938
939
940
	dlsch_harq->nb_rb,
	dlsch_harq->mcs,
	pmi2hex_2Ar1(dlsch_harq->pmi_alloc),
	dlsch_harq->rvidx,
	dlsch_harq->round);
941

942
943
944
945
946
#if defined(MESSAGE_CHART_GENERATOR_PHY)
      MSC_LOG_TX_MESSAGE(
        MSC_PHY_ENB,MSC_PHY_UE,
        NULL,0,
        "%05u:%02u PDSCH/DLSCH input size = %"PRIu16", G %d, nb_rb %"PRIu16", mcs %"PRIu8", pmi_alloc %"PRIx16", rv %"PRIu8" (round %"PRIu8")",
947
        frame, subframe,
948
949
950
951
952
953
        input_buffer_length,
        get_G(fp,
        		dlsch_harq->nb_rb,
        		dlsch_harq->rb_alloc,
        		get_Qm(dlsch_harq