lte-enb.c 35.6 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
23
24
25
26
27
28
29
30
31

/*! \file lte-enb.c
 * \brief Top-level threads for eNodeB
 * \author R. Knopp, F. Kaltenberger, Navid Nikaein
 * \date 2012
 * \version 0.1
 * \company Eurecom
 * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr
 * \note
 * \warning
 */
32

33

34
35
#include "time_utils.h"

36
37
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all

38
39
#include "rt_wrapper.h"

40
#include "assertions.h"
41

42
43
44
45
46
47
48
49
50
51
52

#include "PHY/types.h"

#include "PHY/defs.h"
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all

#include "../../ARCH/COMMON/common_lib.h"

//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all

53
#include "PHY/LTE_TRANSPORT/if4_tools.h"
54
#include "PHY/LTE_TRANSPORT/if5_tools.h"
55

56
57
58
59
60
61
62
63
64
65
66
#include "PHY/extern.h"
#include "SCHED/extern.h"
#include "LAYER2/MAC/extern.h"

#include "../../SIMU/USER/init_lte.h"

#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/extern.h"
#include "LAYER2/MAC/proto.h"
#include "RRC/LITE/extern.h"
#include "PHY_INTERFACE/extern.h"
67
#include "PHY_INTERFACE/defs.h"
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#ifdef SMBV
#include "PHY/TOOLS/smbv.h"
unsigned short config_frames[4] = {2,9,11,13};
#endif
#include "UTIL/LOG/log_extern.h"
#include "UTIL/OTG/otg_tx.h"
#include "UTIL/OTG/otg_externs.h"
#include "UTIL/MATH/oml.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
#include "enb_config.h"
//#include "PHY/TOOLS/time_meas.h"

#ifndef OPENAIR2
#include "UTIL/OTG/otg_extern.h"
#endif

#if defined(ENABLE_ITTI)
# if defined(ENABLE_USE_MME)
#   include "s1ap_eNB.h"
#ifdef PDCP_USE_NETLINK
#   include "SIMULATION/ETH_TRANSPORT/proto.h"
#endif
# endif
#endif

Rohit Gupta's avatar
bugfix    
Rohit Gupta committed
94
95
#include "T.h"

96
97
98
99
100
101
102
103
104
105
//#define DEBUG_THREADS 1

//#define USRP_DEBUG 1
struct timing_info_t {
  //unsigned int frame, hw_slot, last_slot, next_slot;
  RTIME time_min, time_max, time_avg, time_last, time_now;
  //unsigned int mbox0, mbox1, mbox2, mbox_target;
  unsigned int n_samples;
} timing_info;

106
107
// Fix per CC openair rf/if device update
// extern openair0_device openair0;
108

knopp's avatar
knopp committed
109

110
111
112
113
114
115
116
117
#if defined(ENABLE_ITTI)
extern volatile int             start_eNB;
extern volatile int             start_UE;
#endif
extern volatile int                    oai_exit;

extern openair0_config_t openair0_cfg[MAX_CARDS];

Cedric Roux's avatar
Cedric Roux committed
118
extern int transmission_mode;
119

120
121
extern int oaisim_flag;

122
//pthread_t                       main_eNB_thread;
123
124
125

time_stats_t softmodem_stats_mt; // main thread
time_stats_t softmodem_stats_hw; //  hw acquisition
knopp's avatar
knopp committed
126
time_stats_t softmodem_stats_rxtx_sf; // total tx time
127
time_stats_t softmodem_stats_rx_sf; // total rx time
128
129
130
131
132
133
134
135
136

/* mutex, cond and variable to serialize phy proc TX calls
 * (this mechanism may be relaxed in the future for better
 * performances)
 */
static struct {
  pthread_mutex_t  mutex_phy_proc_tx;
  pthread_cond_t   cond_phy_proc_tx;
  volatile uint8_t phy_proc_CC_id;
137
} sync_phy_proc;
138

139
140
extern double cpuf;

141
142
void exit_fun(const char* s);

143
void init_eNB(int,int);
144
void stop_eNB(int nb_inst);
145

146
void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe);
147
148
149
#ifdef Rel14
void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe);
#endif
150

151
152
153
void oai_subframe_ind(uint16_t frame, uint16_t subframe);
extern uint8_t nfapi_pnf;

knopp's avatar
knopp committed
154
155
156
static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_name) {

  start_meas(&softmodem_stats_rxtx_sf);
157

158
159
160
161
162
163
164
165
166
167
168
169
  if (nfapi_pnf)
  {
    oai_subframe_ind(proc->frame_tx, proc->subframe_tx); // PNF ---> P7:subframe_ind --> VNF 
  }
  else
  {
  }
  // *******************************************************************

  //if (proc->subframe_tx==0) LOG_W(PHY, "sfn/sf:%d:%d eNB:%p eNB[0]:%p eNB[0][0]:%p dlsch:%p:%p:%p rnti:%d\n", proc->frame_tx, proc->subframe_tx, RC.eNB, RC.eNB[0], RC.eNB[0][0], RC.eNB[0][0]->dlsch, RC.eNB[0][0]->dlsch[0], RC.eNB[0][0]->dlsch[0][0], RC.eNB[0][0]->dlsch[0][0]->rnti);
  if ( proc->frame_tx == 22 && proc->subframe_tx==5) { LOG_D(PHY,"22/5\n"); }

knopp's avatar
knopp committed
170
171
  // ****************************************
  // Common RX procedures subframe n
172

173
  // if this is IF5 or 3GPP_eNB
174
175
  if (eNB && eNB->RU_list && eNB->RU_list[0] && eNB->RU_list[0]->function < NGFI_RAU_IF4p5) {
  LOG_D(PHY,"%s:%s() %u/%u Before wakeup_prach_eNB() proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
176
    wakeup_prach_eNB(eNB,NULL,proc->frame_rx,proc->subframe_rx);
177
  LOG_D(PHY,"%s:%s() %u/%u Before wakeup_prach_eNB_br() proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
178
179
#ifdef Rel14
    wakeup_prach_eNB_br(eNB,NULL,proc->frame_rx,proc->subframe_rx);
180
  LOG_D(PHY,"%s:%s() %u/%u proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
181
182
#endif
  }
knopp's avatar
knopp committed
183
  // UE-specific RX processing for subframe n
184
  LOG_D(PHY,"%s:%s() %u/%u Before phy_procedures_eNB_uespec_RX() proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
185
  phy_procedures_eNB_uespec_RX(eNB, proc, no_relay );
186

187
  LOG_D(PHY,"%s:%s() %u/%u Before UL_INFO_mutex proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
188
  pthread_mutex_lock(&eNB->UL_INFO_mutex);
189
  LOG_D(PHY,"%s:%s() %u/%u After UL_INFO_mutex proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
190
191
192
193
  eNB->UL_INFO.frame     = proc->frame_rx;
  eNB->UL_INFO.subframe  = proc->subframe_rx;
  eNB->UL_INFO.module_id = eNB->Mod_id;
  eNB->UL_INFO.CC_id     = eNB->CC_id;
194
  LOG_D(PHY,"%s:%s() %u/%u Before UL_ind proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
195
  eNB->if_inst->UL_indication(&eNB->UL_INFO);
196
  LOG_D(PHY,"%s:%s() %u/%u After UL_ind proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
197
  pthread_mutex_unlock(&eNB->UL_INFO_mutex);
198
  LOG_D(PHY,"%s:%s() %u/%u After UL_INFO_mutex unlock proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
knopp's avatar
knopp committed
199
200
201
202
203
  // *****************************************
  // TX processing for subframe n+4
  // run PHY TX procedures the one after the other for all CCs to avoid race conditions
  // (may be relaxed in the future for performance reasons)
  // *****************************************
204
  //if (wait_CCs(proc)<0) return(-1);
knopp's avatar
knopp committed
205
  
206
207

  
knopp's avatar
knopp committed
208
209
  if (oai_exit) return(-1);
  
210
  LOG_D(PHY,"%s:%s() %u/%u Before phy_procedures_eNB_TX() proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
211
  phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1);
212
  LOG_D(PHY,"%s:%s() %u/%u After phy_procedures_eNB_TX() proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
knopp's avatar
knopp committed
213
  
214
215
  LOG_D(PHY,"%s:%s() %u/%u Before release_thread() proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx,  proc->instance_cnt_rxtx);

knopp's avatar
knopp committed
216
217
  if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) return(-1);

218
219
  LOG_D(PHY,"%s:%s() %u/%u AFTER release_thread() proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx,  proc->instance_cnt_rxtx);

knopp's avatar
knopp committed
220
221
222
223
224
  stop_meas( &softmodem_stats_rxtx_sf );
  
  return(0);
}

225

226
/*!
knopp's avatar
knopp committed
227
 * \brief The RX UE-specific and TX thread of eNB.
228
229
230
 * \param param is a \ref eNB_proc_t structure which contains the info what to process.
 * \returns a pointer to an int. The storage is not on the heap and must not be freed.
 */
231

Sandeep Kumar's avatar
Sandeep Kumar committed
232
233
static void* eNB_thread_rxtx( void* param ) {

knopp's avatar
knopp committed
234
  static int eNB_thread_rxtx_status;
235

knopp's avatar
knopp committed
236
  eNB_rxtx_proc_t *proc = (eNB_rxtx_proc_t*)param;
237
  PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id];
238

knopp's avatar
knopp committed
239
240
  char thread_name[100];

241
  //LOG_D(PHY,"%s()\n", __FUNCTION__);
242

243
  // set default return value
knopp's avatar
knopp committed
244
  eNB_thread_rxtx_status = 0;
245
246


247
  sprintf(thread_name,"RXn_TXnp4_%d",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1);
248
  thread_top_init(thread_name,1,850000L,1000000L,2000000L);
249

250
251
  //LOG_D(PHY,"%s() thread_name:%s\n", __FUNCTION__, thread_name);

252
  while (!oai_exit) {
knopp's avatar
knopp committed
253
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
254

255
    LOG_D(PHY,"%s:%s() %u/%u About to wait on proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
knopp's avatar
knopp committed
256
    if (wait_on_condition(&proc->mutex_rxtx,&proc->cond_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break;
257

258
259
    LOG_D(PHY,"%s:%s() %u/%u - WOKEN on proc->instance_cnt_rxtx proc->instance_cnt_rxtx:%d \n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);

knopp's avatar
knopp committed
260
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 1 );
261

262
263
    if (oai_exit) break;

264
    LOG_D(PHY,"%s:%s() %u/%u About to rxtx()\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx);
265
266
    if (eNB->CC_id==0)
      if (rxtx(eNB,proc,thread_name) < 0) break;
267

268
269
    LOG_D(PHY,"%s:%s() %u/%u DONE rxtx()\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx);

knopp's avatar
knopp committed
270
  } // while !oai_exit
271

knopp's avatar
knopp committed
272
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
273

Raymond Knopp's avatar
Raymond Knopp committed
274
  printf( "Exiting eNB thread RXn_TXnp4\n");
275

knopp's avatar
knopp committed
276
277
  eNB_thread_rxtx_status = 0;
  return &eNB_thread_rxtx_status;
278
279
}

280

281
#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
Sandeep Kumar's avatar
Sandeep Kumar committed
282
283
284
/* Wait for eNB application initialization to be complete (eNB registration to MME) */
static void wait_system_ready (char *message, volatile int *start_flag) {
  
285
  static char *indicator[] = {".    ", "..   ", "...  ", ".... ", ".....",
Sandeep Kumar's avatar
Sandeep Kumar committed
286
			      " ....", "  ...", "   ..", "    .", "     "};
287
288
289
290
291
292
293
  int i = 0;
  
  while ((!oai_exit) && (*start_flag == 0)) {
    LOG_N(EMU, message, indicator[i]);
    fflush(stdout);
    i = (i + 1) % (sizeof(indicator) / sizeof(indicator[0]));
    usleep(200000);
294
  }
295
296
  
  LOG_D(EMU,"\n");
297
298
}
#endif
299

knopp's avatar
knopp committed
300
301


knopp's avatar
knopp committed
302

knopp's avatar
knopp committed
303

304
void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string) {
305

306

307
308
  eNB_proc_t *proc           = &eNB->proc;
  eNB_rxtx_proc_t *proc_rxtx = &proc->proc_rxtx[0];
309

310
311


knopp's avatar
knopp committed
312

313
314
  proc->frame_rx    = frame_rx;
  proc->subframe_rx = subframe_rx;
315
  
316
317
  if (!oai_exit) {

knopp's avatar
knopp committed
318

knopp's avatar
knopp committed
319
320
    LOG_D(PHY,"eNB_top in %p (proc %p, CC_id %d), frame %d, subframe %d, instance_cnt_prach %d\n",
	  pthread_self(), proc, eNB->CC_id, proc->frame_rx,proc->subframe_rx,proc->instance_cnt_prach);
321
 
knopp's avatar
knopp committed
322
323


324
    T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
knopp's avatar
knopp committed
325

326
327
328
329
330
331
    proc_rxtx->subframe_rx = proc->subframe_rx;
    proc_rxtx->frame_rx    = proc->frame_rx;
    proc_rxtx->subframe_tx = (proc->subframe_rx+4)%10;
    proc_rxtx->frame_tx    = (proc->subframe_rx>5) ? (1+proc->frame_rx)&1023 : proc->frame_rx;
    proc->frame_tx         = proc_rxtx->frame_tx;
    proc_rxtx->timestamp_tx = proc->timestamp_tx;
knopp's avatar
knopp committed
332

333
    if (rxtx(eNB,proc_rxtx,string) < 0) LOG_E(PHY,"eNB %d CC_id %d failed during execution\n",eNB->Mod_id,eNB->CC_id);
knopp's avatar
knopp committed
334
335
    LOG_D(PHY,"eNB_top out %p (proc %p, CC_id %d), frame %d, subframe %d, instance_cnt_prach %d\n",
	  pthread_self(), proc, eNB->CC_id, proc->frame_rx,proc->subframe_rx,proc->instance_cnt_prach);
336
  }
knopp's avatar
knopp committed
337
338
339
340
  
}


341
342
343
344
345
346
347
int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {

  eNB_proc_t *proc=&eNB->proc;

  eNB_rxtx_proc_t *proc_rxtx=&proc->proc_rxtx[proc->frame_rx&1];

  LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
348
349
350
351

  int i;
  struct timespec wait;
  
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
  pthread_mutex_lock(&proc->mutex_RU);
  for (i=0;i<eNB->num_RU;i++) {
    if (ru == eNB->RU_list[i]) {
      if ((proc->RU_mask&(1<<i)) > 0)
	LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n",
	      eNB->Mod_id,proc->frame_rx,proc->subframe_rx,ru->idx,eNB->num_RU,proc->RU_mask);
      proc->RU_mask |= (1<<i);
    }
  }
  if (proc->RU_mask != (1<<eNB->num_RU)-1) {  // not all RUs have provided their information so return
    pthread_mutex_unlock(&proc->mutex_RU);
    return(0);
  }
  else { // all RUs have provided their information so continue on and wakeup eNB processing
    proc->RU_mask = 0;
    pthread_mutex_unlock(&proc->mutex_RU);
  }




373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
  wait.tv_sec=0;
  wait.tv_nsec=5000000L;

  /* accept some delay in processing - up to 5ms */
  for (i = 0; i < 10 && proc_rxtx->instance_cnt_rxtx == 0; i++) {
    LOG_W( PHY,"[eNB] Frame %d, eNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", proc_rxtx->frame_tx, proc_rxtx->instance_cnt_rxtx);
    usleep(500);
  }
  if (proc_rxtx->instance_cnt_rxtx == 0) {
    exit_fun( "TX thread busy" );
    return(-1);
  }

  // wake up TX for subframe n+4
  // lock the TX mutex and make sure the thread is ready
  if (pthread_mutex_timedlock(&proc_rxtx->mutex_rxtx,&wait) != 0) {
    LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", proc_rxtx->subframe_rx&1,proc_rxtx->instance_cnt_rxtx );
    exit_fun( "error locking mutex_rxtx" );
    return(-1);
  }
  
  ++proc_rxtx->instance_cnt_rxtx;
395
  LOG_E(PHY,"%s() %u/%u Just incremented proc->instance_cnt_rxtx:%d\n", __FUNCTION__, proc_rxtx->frame_tx, proc_rxtx->subframe_tx, proc_rxtx->instance_cnt_rxtx);
396
397
398
399
400
  
  // We have just received and processed the common part of a subframe, say n. 
  // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired 
  // transmitted timestamp of the next TX slot (first).
  // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, 
knopp's avatar
knopp committed
401
402
  // we want to generate subframe (n+4), so TS_tx = TX_rx+4*samples_per_tti,
  // and proc->subframe_tx = proc->subframe_rx+4
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
  proc_rxtx->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti);
  proc_rxtx->frame_rx     = proc->frame_rx;
  proc_rxtx->subframe_rx  = proc->subframe_rx;
  proc_rxtx->frame_tx     = (proc_rxtx->subframe_rx > 5) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx;
  proc_rxtx->subframe_tx  = (proc_rxtx->subframe_rx + 4)%10;
  
  // the thread can now be woken up
  if (pthread_cond_signal(&proc_rxtx->cond_rxtx) != 0) {
    LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n");
    exit_fun( "ERROR pthread_cond_signal" );
    return(-1);
  }
  
  pthread_mutex_unlock( &proc_rxtx->mutex_rxtx );

  return(0);
}

421
void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) {
knopp's avatar
knopp committed
422
423
424

  eNB_proc_t *proc = &eNB->proc;
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
425
  int i;
knopp's avatar
knopp committed
426

427
428
429
430
  if (ru!=NULL) {
    pthread_mutex_lock(&proc->mutex_RU_PRACH);
    for (i=0;i<eNB->num_RU;i++) {
      if (ru == eNB->RU_list[i]) {
knopp's avatar
knopp committed
431
	LOG_D(PHY,"frame %d, subframe %d: RU %d for eNB %d signals PRACH (mask %x, num_RU %d)\n",frame,subframe,i,eNB->Mod_id,proc->RU_mask_prach,eNB->num_RU);
432
433
	if ((proc->RU_mask_prach&(1<<i)) > 0)
	  LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information (PRACH) from RU %d (num_RU %d, mask %x) has not been served yet!\n",
434
		eNB->Mod_id,frame,subframe,ru->idx,eNB->num_RU,proc->RU_mask_prach);
435
436
437
438
439
440
441
442
443
444
445
446
447
	proc->RU_mask_prach |= (1<<i);
      }
    }
    if (proc->RU_mask_prach != (1<<eNB->num_RU)-1) {  // not all RUs have provided their information so return
      pthread_mutex_unlock(&proc->mutex_RU_PRACH);
      return(0);
    }
    else { // all RUs have provided their information so continue on and wakeup eNB processing
      proc->RU_mask_prach = 0;
      pthread_mutex_unlock(&proc->mutex_RU_PRACH);
    }
  }
    
knopp's avatar
knopp committed
448
  // check if we have to detect PRACH first
449
  if (is_prach_subframe(fp,frame,subframe)>0) { 
450
    LOG_D(PHY,"Triggering prach processing, frame %d, subframe %d\n",frame,subframe);
knopp's avatar
knopp committed
451
    if (proc->instance_cnt_prach == 0) {
452
      LOG_W(PHY,"[eNB] Frame %d Subframe %d, dropping PRACH\n", frame,subframe);
knopp's avatar
knopp committed
453
454
455
456
457
458
459
460
461
462
463
464
      return;
    }
    
    // wake up thread for PRACH RX
    if (pthread_mutex_lock(&proc->mutex_prach) != 0) {
      LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB PRACH thread %d (IC %d)\n", proc->thread_index, proc->instance_cnt_prach);
      exit_fun( "error locking mutex_prach" );
      return;
    }
    
    ++proc->instance_cnt_prach;
    // set timing for prach thread
465
466
    proc->frame_prach = frame;
    proc->subframe_prach = subframe;
knopp's avatar
knopp committed
467
468
469
470
471
472
473
474
475
476
477
478
479
    
    // the thread can now be woken up
    if (pthread_cond_signal(&proc->cond_prach) != 0) {
      LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB PRACH thread %d\n", proc->thread_index);
      exit_fun( "ERROR pthread_cond_signal" );
      return;
    }
    
    pthread_mutex_unlock( &proc->mutex_prach );
  }

}

480
481
482
483
484
485
486
487
488
489
490
#ifdef Rel14
void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) {

  eNB_proc_t *proc = &eNB->proc;
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
  int i;

  if (ru!=NULL) {
    pthread_mutex_lock(&proc->mutex_RU_PRACH_br);
    for (i=0;i<eNB->num_RU;i++) {
      if (ru == eNB->RU_list[i]) {
knopp's avatar
knopp committed
491
	LOG_D(PHY,"frame %d, subframe %d: RU %d for eNB %d signals PRACH BR (mask %x, num_RU %d)\n",frame,subframe,i,eNB->Mod_id,proc->RU_mask_prach_br,eNB->num_RU);
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
	if ((proc->RU_mask_prach_br&(1<<i)) > 0)
	  LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information (PRACH BR) from RU %d (num_RU %d, mask %x) has not been served yet!\n",
		eNB->Mod_id,frame,subframe,ru->idx,eNB->num_RU,proc->RU_mask_prach_br);
	proc->RU_mask_prach_br |= (1<<i);
      }
    }
    if (proc->RU_mask_prach_br != (1<<eNB->num_RU)-1) {  // not all RUs have provided their information so return
      pthread_mutex_unlock(&proc->mutex_RU_PRACH_br);
      return(0);
    }
    else { // all RUs have provided their information so continue on and wakeup eNB processing
      proc->RU_mask_prach_br = 0;
      pthread_mutex_unlock(&proc->mutex_RU_PRACH_br);
    }
  }
    
  // check if we have to detect PRACH first
  if (is_prach_subframe(fp,frame,subframe)>0) { 
    LOG_D(PHY,"Triggering prach br processing, frame %d, subframe %d\n",frame,subframe);
    if (proc->instance_cnt_prach_br == 0) {
      LOG_W(PHY,"[eNB] Frame %d Subframe %d, dropping PRACH BR\n", frame,subframe);
      return;
    }
    
    // wake up thread for PRACH RX
    if (pthread_mutex_lock(&proc->mutex_prach_br) != 0) {
      LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB PRACH thread %d (IC %d)\n", proc->thread_index, proc->instance_cnt_prach_br);
      exit_fun( "error locking mutex_prach" );
      return;
    }
    
    ++proc->instance_cnt_prach_br;
    // set timing for prach thread
    proc->frame_prach_br = frame;
    proc->subframe_prach_br = subframe;
    
    // the thread can now be woken up
    if (pthread_cond_signal(&proc->cond_prach_br) != 0) {
      LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB PRACH BR thread %d\n", proc->thread_index);
      exit_fun( "ERROR pthread_cond_signal" );
      return;
    }
    
    pthread_mutex_unlock( &proc->mutex_prach_br );
  }

}
#endif

541
542
543
544
545
/*!
 * \brief The prach receive thread of eNB.
 * \param param is a \ref eNB_proc_t structure which contains the info what to process.
 * \returns a pointer to an int. The storage is not on the heap and must not be freed.
 */
Sandeep Kumar's avatar
Sandeep Kumar committed
546
static void* eNB_thread_prach( void* param ) {
547
548
  static int eNB_thread_prach_status;

549
550
551

  PHY_VARS_eNB *eNB= (PHY_VARS_eNB *)param;
  eNB_proc_t *proc = &eNB->proc;
Raymond Knopp's avatar
Raymond Knopp committed
552

553
554
555
  // set default return value
  eNB_thread_prach_status = 0;

556
  thread_top_init("eNB_thread_prach",1,500000L,1000000L,20000000L);
557

Sandeep Kumar's avatar
Sandeep Kumar committed
558
559
560
  while (!oai_exit) {
    
    if (oai_exit) break;
knopp's avatar
knopp committed
561
    
Sandeep Kumar's avatar
Sandeep Kumar committed
562

knopp's avatar
knopp committed
563
    if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break;
knopp's avatar
knopp committed
564
565

    LOG_D(PHY,"Running eNB prach procedures\n");
566
567
568
569
570
    prach_procedures(eNB
#ifdef Rel14
		     ,0
#endif
		     );
571
    
knopp's avatar
knopp committed
572
    if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break;
Sandeep Kumar's avatar
Sandeep Kumar committed
573
  }
574

knopp's avatar
knopp committed
575
  LOG_I(PHY, "Exiting eNB thread PRACH\n");
Raymond Knopp's avatar
Raymond Knopp committed
576

577
578
  eNB_thread_prach_status = 0;
  return &eNB_thread_prach_status;
579
580
}

581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
#ifdef Rel14
/*!
 * \brief The prach receive thread of eNB for BL/CE UEs.
 * \param param is a \ref eNB_proc_t structure which contains the info what to process.
 * \returns a pointer to an int. The storage is not on the heap and must not be freed.
 */
static void* eNB_thread_prach_br( void* param ) {
  static int eNB_thread_prach_status;


  PHY_VARS_eNB *eNB= (PHY_VARS_eNB *)param;
  eNB_proc_t *proc = &eNB->proc;

  // set default return value
  eNB_thread_prach_status = 0;

  thread_top_init("eNB_thread_prach_br",1,500000L,1000000L,20000000L);

  while (!oai_exit) {
    
    if (oai_exit) break;
    

    if (wait_on_condition(&proc->mutex_prach_br,&proc->cond_prach_br,&proc->instance_cnt_prach_br,"eNB_prach_thread_br") < 0) break;

    LOG_D(PHY,"Running eNB prach procedures for BL/CE UEs\n");
    prach_procedures(eNB,1);
    
    if (release_thread(&proc->mutex_prach_br,&proc->instance_cnt_prach_br,"eNB_prach_thread_br") < 0) break;
  }

  LOG_I(PHY, "Exiting eNB thread PRACH BR\n");

  eNB_thread_prach_status = 0;
  return &eNB_thread_prach_status;
}

#endif
knopp's avatar
knopp committed
619

knopp's avatar
knopp committed
620

621
extern void init_fep_thread(PHY_VARS_eNB *, pthread_attr_t *);
knopp's avatar
knopp committed
622
623
extern void init_td_thread(PHY_VARS_eNB *, pthread_attr_t *);
extern void init_te_thread(PHY_VARS_eNB *, pthread_attr_t *);
624

625
void init_eNB_proc(int inst) {
Sandeep Kumar's avatar
Sandeep Kumar committed
626
  
Rohit Gupta's avatar
Rohit Gupta committed
627
  int i=0;
628
  int CC_id;
629
630
  PHY_VARS_eNB *eNB;
  eNB_proc_t *proc;
knopp's avatar
knopp committed
631
  eNB_rxtx_proc_t *proc_rxtx;
632
  pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_FH=NULL,*attr_prach=NULL,*attr_asynch=NULL,*attr_single=NULL,*attr_fep=NULL,*attr_td=NULL,*attr_te=NULL,*attr_synch=NULL;
633
634
635
#ifdef Rel14
  pthread_attr_t *attr_prach_br=NULL;
#endif
knopp's avatar
knopp committed
636

637
638
  LOG_I(PHY,"%s(inst:%d) RC.nb_CC[inst]:%d \n",__FUNCTION__,inst,RC.nb_CC[inst]);

knopp's avatar
knopp committed
639
  for (CC_id=0; CC_id<RC.nb_CC[inst]; CC_id++) {
640
    eNB = RC.eNB[inst][CC_id];
laurent's avatar
small2    
laurent committed
641
#ifndef OCP_FRAMEWORK
642
    LOG_I(PHY,"Initializing eNB processes instance:%d CC_id %d \n",inst,CC_id);
laurent's avatar
small2    
laurent committed
643
#endif
644
    proc = &eNB->proc;
knopp's avatar
knopp committed
645

646
    proc_rxtx                      = proc->proc_rxtx;
647
648
    proc_rxtx[0].instance_cnt_rxtx = -1;
    proc_rxtx[1].instance_cnt_rxtx = -1;
649
    proc->instance_cnt_prach       = -1;
650
    proc->instance_cnt_asynch_rxtx = -1;
651
    proc->CC_id                    = CC_id;    
652

knopp's avatar
knopp committed
653
654
    proc->first_rx=1;
    proc->first_tx=1;
655
656
    proc->RU_mask=0;
    proc->RU_mask_prach=0;
knopp's avatar
knopp committed
657

658
    pthread_mutex_init( &eNB->UL_INFO_mutex, NULL);
659
660
661
662
    pthread_mutex_init( &proc_rxtx[0].mutex_rxtx, NULL);
    pthread_mutex_init( &proc_rxtx[1].mutex_rxtx, NULL);
    pthread_cond_init( &proc_rxtx[0].cond_rxtx, NULL);
    pthread_cond_init( &proc_rxtx[1].cond_rxtx, NULL);
knopp's avatar
knopp committed
663
664
665

    pthread_mutex_init( &proc->mutex_prach, NULL);
    pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL);
666
667
    pthread_mutex_init( &proc->mutex_RU,NULL);
    pthread_mutex_init( &proc->mutex_RU_PRACH,NULL);
knopp's avatar
knopp committed
668

669
    pthread_cond_init( &proc->cond_prach, NULL);
670
    pthread_cond_init( &proc->cond_asynch_rxtx, NULL);
671
672
673
674

    pthread_attr_init( &proc->attr_prach);
    pthread_attr_init( &proc->attr_asynch_rxtx);
    pthread_attr_init( &proc->attr_single);
675
676
    pthread_attr_init( &proc->attr_td);
    pthread_attr_init( &proc->attr_te);
677
678
    pthread_attr_init( &proc_rxtx[0].attr_rxtx);
    pthread_attr_init( &proc_rxtx[1].attr_rxtx);
679
680
681
682
683
684
685
686
#ifdef Rel14
    proc->instance_cnt_prach_br    = -1;
    proc->RU_mask_prach_br=0;
    pthread_mutex_init( &proc->mutex_prach_br, NULL);
    pthread_mutex_init( &proc->mutex_RU_PRACH_br,NULL);
    pthread_cond_init( &proc->cond_prach_br, NULL);
    pthread_attr_init( &proc->attr_prach_br);
#endif
687
#ifndef DEADLINE_SCHEDULER
knopp's avatar
knopp committed
688
689
690
    attr0       = &proc_rxtx[0].attr_rxtx;
    attr1       = &proc_rxtx[1].attr_rxtx;
    attr_prach  = &proc->attr_prach;
691
692
693
694
#ifdef Rel14
    attr_prach_br  = &proc->attr_prach_br;
#endif

knopp's avatar
knopp committed
695
696
    attr_asynch = &proc->attr_asynch_rxtx;
    attr_single = &proc->attr_single;
697
698
    attr_td     = &proc->attr_td;
    attr_te     = &proc->attr_te; 
knopp's avatar
knopp committed
699
700
#endif

701
702
    LOG_I(PHY,"eNB->single_thread_flag:%d\n", eNB->single_thread_flag);

703
704
705
706
    if (eNB->single_thread_flag==0) {
      pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, &proc_rxtx[0] );
      pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, eNB_thread_rxtx, &proc_rxtx[1] );
    }
707
    pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, eNB );
708
709
710
#ifdef Rel14
    pthread_create( &proc->pthread_prach_br, attr_prach_br, eNB_thread_prach_br, eNB );
#endif
711
    char name[16];
712
713
714
715
716
717
    if (eNB->single_thread_flag==0) {
      snprintf( name, sizeof(name), "RXTX0 %d", i );
      pthread_setname_np( proc_rxtx[0].pthread_rxtx, name );
      snprintf( name, sizeof(name), "RXTX1 %d", i );
      pthread_setname_np( proc_rxtx[1].pthread_rxtx, name );
    }
knopp's avatar
knopp committed
718
719
720

    AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach);

721
    
722
  }
723

724
  //for multiple CCs: setup master and slaves
725
726
727
  /* 
     for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
     eNB = PHY_vars_eNB_g[inst][CC_id];
728

729
730
731
     if (eNB->node_timing == synch_to_ext_device) { //master
     eNB->proc.num_slaves = MAX_NUM_CCs-1;
     eNB->proc.slave_proc = (eNB_proc_t**)malloc(eNB->proc.num_slaves*sizeof(eNB_proc_t*));
732

733
734
735
736
737
738
739
     for (i=0; i< eNB->proc.num_slaves; i++) {
     if (i < CC_id)  eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i]->proc);
     if (i >= CC_id)  eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i+1]->proc);
     }
     }
     }
  */
740

741
742
743
744
  /* setup PHY proc TX sync mechanism */
  pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL);
  pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL);
  sync_phy_proc.phy_proc_CC_id = 0;
745
746
}

747

748

749
750
751
/*!
 * \brief Terminate eNB TX and RX threads.
 */
752
void kill_eNB_proc(int inst) {
Sandeep Kumar's avatar
Sandeep Kumar committed
753

754
  int *status;
755
756
  PHY_VARS_eNB *eNB;
  eNB_proc_t *proc;
knopp's avatar
knopp committed
757
  eNB_rxtx_proc_t *proc_rxtx;
758
  for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
759
    eNB=RC.eNB[inst][CC_id];
760
761
    
    proc = &eNB->proc;
knopp's avatar
knopp committed
762
    proc_rxtx = &proc->proc_rxtx[0];
763
    
knopp's avatar
knopp committed
764
765

    LOG_I(PHY, "Killing TX CC_id %d inst %d\n", CC_id, inst );
766
767
768
769
770
771
772

    if (eNB->single_thread_flag==0) {
      proc_rxtx[0].instance_cnt_rxtx = 0; // FIXME data race!
      proc_rxtx[1].instance_cnt_rxtx = 0; // FIXME data race!
      pthread_cond_signal( &proc_rxtx[0].cond_rxtx );    
      pthread_cond_signal( &proc_rxtx[1].cond_rxtx );
    }
Raymond Knopp's avatar
Raymond Knopp committed
773
774
    proc->instance_cnt_prach = 0;
    pthread_cond_signal( &proc->cond_prach );
775

776
    pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx);
777
    pthread_join( proc->pthread_prach, (void**)&status );    
778

779
    LOG_I(PHY, "Destroying prach mutex/cond\n");
780
    pthread_mutex_destroy( &proc->mutex_prach );
781
782
    pthread_cond_destroy( &proc->cond_prach );
#ifdef Rel14
783
    proc->instance_cnt_prach_br = 0;
784
785
786
787
788
    pthread_cond_signal( &proc->cond_prach_br );
    pthread_join( proc->pthread_prach_br, (void**)&status );    
    pthread_mutex_destroy( &proc->mutex_prach_br );
    pthread_cond_destroy( &proc->cond_prach_br );
#endif         
789
    LOG_I(PHY, "Destroying UL_INFO mutex\n");
790
    pthread_mutex_destroy(&eNB->UL_INFO_mutex);
791
    int i;
792
793
794
795
796
797
798
799
    if (eNB->single_thread_flag==0) {
      for (i=0;i<2;i++) {
	LOG_I(PHY, "Joining rxtx[%d] mutex/cond\n");
	pthread_join( proc_rxtx[i].pthread_rxtx, (void**)&status );
	LOG_I(PHY, "Destroying rxtx[%d] mutex/cond\n");
	pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx );
	pthread_cond_destroy( &proc_rxtx[i].cond_rxtx );
      }
knopp's avatar
knopp committed
800
    }
801
  }
802
803
}

804

805
806
807


void reset_opp_meas(void) {
Sandeep Kumar's avatar
Sandeep Kumar committed
808

809
810
811
812
813
  int sfn;
  reset_meas(&softmodem_stats_mt);
  reset_meas(&softmodem_stats_hw);
  
  for (sfn=0; sfn < 10; sfn++) {
knopp's avatar
knopp committed
814
    reset_meas(&softmodem_stats_rxtx_sf);
815
    reset_meas(&softmodem_stats_rx_sf);
816
817
818
  }
}

Sandeep Kumar's avatar
Sandeep Kumar committed
819

820
821
822
823
824
825
826
void print_opp_meas(void) {

  int sfn=0;
  print_meas(&softmodem_stats_mt, "Main ENB Thread", NULL, NULL);
  print_meas(&softmodem_stats_hw, "HW Acquisation", NULL, NULL);
  
  for (sfn=0; sfn < 10; sfn++) {
knopp's avatar
knopp committed
827
    print_meas(&softmodem_stats_rxtx_sf,"[eNB][total_phy_proc_rxtx]",NULL, NULL);
828
    print_meas(&softmodem_stats_rx_sf,"[eNB][total_phy_proc_rx]",NULL,NULL);
829
830
  }
}
831

832
void init_transport(PHY_VARS_eNB *eNB) {
833

834
835
836
  int i;
  int j;
  LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
knopp's avatar
knopp committed
837

838
839
840
841
842
843
  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
    LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i);
    for (j=0; j<2; j++) {
      eNB->dlsch[i][j] = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL,0,fp);
      if (!eNB->dlsch[i][j]) {
	LOG_E(PHY,"Can't get eNB dlsch structures for UE %d \n", i);
knopp's avatar
knopp committed
844
	exit(-1);
845
846
      } else {
	eNB->dlsch[i][j]->rnti=0;
847
	LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,eNB->dlsch[i][j], eNB->dlsch[i][j]->rnti);
knopp's avatar
knopp committed
848
849
      }
    }
850
851
852
853
854
855
    
    LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i);
    eNB->ulsch[1+i] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,fp->N_RB_UL, 0);
    
    if (!eNB->ulsch[1+i]) {
      LOG_E(PHY,"Can't get eNB ulsch structures\n");
knopp's avatar
knopp committed
856
857
      exit(-1);
    }
858
859
860
861
    
    // this is the transmission mode for the signalling channels
    // this will be overwritten with the real transmission mode by the RRC once the UE is connected
    eNB->transmission_mode[i] = fp->nb_antenna_ports_eNB==1 ? 1 : 2;
knopp's avatar
knopp committed
862
  }
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
  // ULSCH for RA
  eNB->ulsch[0] = new_eNB_ulsch(MAX_TURBO_ITERATIONS, fp->N_RB_UL, 0);
  
  if (!eNB->ulsch[0]) {
    LOG_E(PHY,"Can't get eNB ulsch structures\n");
    exit(-1);
  }
  eNB->dlsch_SI  = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL, 0, fp);
  LOG_D(PHY,"eNB %d.%d : SI %p\n",eNB->Mod_id,eNB->CC_id,eNB->dlsch_SI);
  eNB->dlsch_ra  = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL, 0, fp);
  LOG_D(PHY,"eNB %d.%d : RA %p\n",eNB->Mod_id,eNB->CC_id,eNB->dlsch_ra);
  eNB->dlsch_MCH = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL, 0, fp);
  LOG_D(PHY,"eNB %d.%d : MCH %p\n",eNB->Mod_id,eNB->CC_id,eNB->dlsch_MCH);
  
  
  eNB->rx_total_gain_dB=130;
knopp's avatar
knopp committed
879
  
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
  for(i=0; i<NUMBER_OF_UE_MAX; i++)
    eNB->mu_mimo_mode[i].dl_pow_off = 2;
  
  eNB->check_for_total_transmissions = 0;
  
  eNB->check_for_MUMIMO_transmissions = 0;
  
  eNB->FULL_MUMIMO_transmissions = 0;
  
  eNB->check_for_SUMIMO_transmissions = 0;
  
  fp->pucch_config_common.deltaPUCCH_Shift = 1;
    
} 
void init_eNB_afterRU() {
knopp's avatar
knopp committed
895

896
897
  int inst,CC_id,ru_id,i,aa;
  PHY_VARS_eNB *eNB;
898

899
  LOG_I(PHY,"%s() RC.nb_inst:%d\n", __FUNCTION__, RC.nb_inst);
900

901
  for (inst=0;inst<RC.nb_inst;inst++) {
902
    LOG_I(PHY,"RC.nb_CC[inst]:%d\n", RC.nb_CC[inst]);
903
    for (CC_id=0;CC_id<RC.nb_CC[inst];CC_id++) {
904
905
906

      LOG_I(PHY,"RC.nb_CC[inst:%d][CC_id:%d]:%d\n", inst, CC_id, RC.eNB[inst][CC_id]);

907
908
909
      eNB                                  =  RC.eNB[inst][CC_id];
      phy_init_lte_eNB(eNB,0,0);
      // map antennas and PRACH signals to eNB RX
910
      if (0) AssertFatal(eNB->num_RU>0,"Number of RU attached to eNB %d is zero\n",eNB->Mod_id);
911
      LOG_I(PHY,"Mapping RX ports from %d RUs to eNB %d\n",eNB->num_RU,eNB->Mod_id);
912
      eNB->frame_parms.nb_antennas_rx       = 0;
913
914
915
916
917
      eNB->prach_vars.rxsigF[0] = (int16_t*)malloc16(64*sizeof(int16_t*));
#ifdef Rel14
      for (int ce_level=0;ce_level<4;ce_level++)
	eNB->prach_vars_br.rxsigF[ce_level] = (int16_t*)malloc16(64*sizeof(int16_t*));
#endif
918
919
920

      LOG_I(PHY,"eNB->num_RU:%d\n", eNB->num_RU);

921
922
      for (ru_id=0,aa=0;ru_id<eNB->num_RU;ru_id++) {
	eNB->frame_parms.nb_antennas_rx    += eNB->RU_list[ru_id]->nb_rx;
923
924
925
926
927
928
929
930
931

	AssertFatal(eNB->RU_list[ru_id]->common.rxdataF!=NULL,
		    "RU %d : common.rxdataF is NULL\n",
		    eNB->RU_list[ru_id]->idx);

	AssertFatal(eNB->RU_list[ru_id]->prach_rxsigF!=NULL,
		    "RU %d : prach_rxsigF is NULL\n",
		    eNB->RU_list[ru_id]->idx);

932
933
934
935
936
937
	for (i=0;i<eNB->RU_list[ru_id]->nb_rx;aa++,i++) { 
	  LOG_I(PHY,"Attaching RU %d antenna %d to eNB antenna %d\n",eNB->RU_list[ru_id]->idx,i,aa);
	  eNB->prach_vars.rxsigF[aa]       =  eNB->RU_list[ru_id]->prach_rxsigF[i];
	  eNB->common_vars.rxdataF[aa]     =  eNB->RU_list[ru_id]->common.rxdataF[i];
	}
      }
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956




      if (eNB->frame_parms.nb_antennas_rx < 1)
      {
        LOG_I(PHY, "%s() ************* DJP ***** eNB->frame_parms.nb_antennas_rx:%d - GOING TO HARD CODE TO 1", __FUNCTION__, eNB->frame_parms.nb_antennas_rx);
        eNB->frame_parms.nb_antennas_rx = 1;
      }

      if (eNB->frame_parms.nb_antennas_tx < 1)
      {
        LOG_I(PHY, "%s() ************* DJP ***** eNB->frame_parms.nb_antennas_tx:%d - GOING TO HARD CODE TO 1", __FUNCTION__, eNB->frame_parms.nb_antennas_tx);
        eNB->frame_parms.nb_antennas_tx = 1;
      }




957
958
959
      AssertFatal(eNB->frame_parms.nb_antennas_rx >0,
		  "inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,eNB->frame_parms.nb_antennas_rx);
      LOG_I(PHY,"inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,eNB->frame_parms.nb_antennas_rx);
960
961
962
963

      init_transport(eNB);
      init_precoding_weights(RC.eNB[inst][CC_id]);
    }
964
    printf("RC.nb_CC[inst:%d]:%d CC_id:%d AFTER LOOP - About to init_eNB_proc\n", inst, RC.nb_CC[inst], CC_id);
965
966
    init_eNB_proc(inst);
  }
967
  printf("%s() RC.nb_inst:%d AFTER LOOP\n", __FUNCTION__, RC.nb_inst);
knopp's avatar
knopp committed
968

969
  printf("%s:%d RC.nb_RU:%d\n", __FILE__, __LINE__, RC.nb_RU);
970
  for (ru_id=0;ru_id<RC.nb_RU;ru_id++) {
971
972

    AssertFatal(RC.ru[ru_id]!=NULL,"ru_id %d is null\n",ru_id);
973
    
974
975
976
977
    RC.ru[ru_id]->wakeup_rxtx         = wakeup_rxtx;
    RC.ru[ru_id]->wakeup_prach_eNB    = wakeup_prach_eNB;
    RC.ru[ru_id]->wakeup_prach_eNB_br = wakeup_prach_eNB_br;
    RC.ru[ru_id]->eNB_top             = eNB_top;
978
  }
979
980

  LOG_I(PHY,"%s() Exitting\n", __FUNCTION__);
981
}
982

983
void init_eNB(int single_thread_flag,int wait_for_sync) {
984
  
985
  int CC_id;
986
  int inst;
987
  PHY_VARS_eNB *eNB;
knopp's avatar
knopp committed
988

989
990
  LOG_I(PHY,"[lte-softmodem.c] eNB structure about to allocated\n");

991
  if (RC.eNB == NULL) RC.eNB = (PHY_VARS_eNB***) malloc(RC.nb_L1_inst*sizeof(PHY_VARS_eNB **));
992
  LOG_I(PHY,"[lte-softmodem.c] eNB structure RC.eNB allocated\n");
993
  for (inst=0;inst<RC.nb_L1_inst;inst++) {
knopp's avatar
knopp committed
994
    if (RC.eNB[inst] == NULL) RC.eNB[inst] = (PHY_VARS_eNB**) malloc(RC.nb_CC[inst]*sizeof(PHY_VARS_eNB *));
995
    for (CC_id=0;CC_id<RC.nb_L1_CC[inst];CC_id++) {
996
997
      if (RC.eNB[inst][CC_id] == NULL) RC.eNB[inst][CC_id] = (PHY_VARS_eNB*) malloc(sizeof(PHY_VARS_eNB));
      eNB                     = RC.eNB[inst][CC_id]; 
998
      eNB->abstraction_flag   = 0;
knopp's avatar
knopp committed
999
      eNB->single_thread_flag = single_thread_flag;
1000

1001

laurent's avatar
small2    
laurent committed
1002
#ifndef OCP_FRAMEWORK
1003
      LOG_I(PHY,"Initializing eNB %d CC_id %d\n",inst,CC_id);
laurent's avatar
small2    
laurent committed
1004
#endif
knopp's avatar
knopp committed
1005
1006


1007
1008
      eNB->td                   = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data;
      eNB->te                   = dlsch_encoding;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding;
1009

1010
      
1011
      LOG_I(PHY,"Registering with MAC interface module\n");
1012
1013
1014
1015
1016
1017
1018
1019
      AssertFatal((eNB->if_inst         = IF_Module_init(inst))!=NULL,"Cannot register interface");
      eNB->if_inst->schedule_response   = schedule_response;
      eNB->if_inst->PHY_config_req      = phy_config_request;
      memset((void*)&eNB->UL_INFO,0,sizeof(eNB->UL_INFO));
      memset((void*)&eNB->Sched_INFO,0,sizeof(eNB->Sched_INFO));
      LOG_I(PHY,"Setting indication lists\n");
      eNB->UL_INFO.rx_ind.rx_pdu_list   = eNB->rx_pdu_list;
      eNB->UL_INFO.crc_ind.crc_pdu_list = eNB->crc_pdu_list;
1020
1021
1022
1023
      eNB->UL_INFO.sr_ind.sr_pdu_list = eNB->sr_pdu_list;
      eNB->UL_INFO.harq_ind.harq_pdu_list = eNB->harq_pdu_list;
      eNB->UL_INFO.cqi_ind.cqi_pdu_list = eNB->cqi_pdu_list;
      eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list;
knopp's avatar
knopp committed
1024
1025
    }

1026
  }
1027