lte-enb.c 45.5 KB
Newer Older
1 2 3 4 5
/*
 * 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
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7 8 9 10 11 12 13 14 15 16 17 18 19 20
 * 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

Raymond Knopp's avatar
Raymond Knopp committed
33 34
#define _GNU_SOURCE
#include <pthread.h>
35

36

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

39 40
#include "rt_wrapper.h"

41
#include "assertions.h"
42

43 44 45

#include "PHY/types.h"

46 47 48 49 50 51
#include "PHY/INIT/phy_init.h"

#include "PHY/defs_eNB.h"
#include "SCHED/sched_eNB.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"

52 53 54 55 56 57 58
#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

59
#include "PHY/LTE_TRANSPORT/if4_tools.h"
60
#include "PHY/LTE_TRANSPORT/if5_tools.h"
61

62 63 64 65 66 67 68 69
#include "PHY/phy_extern.h"


#include "LAYER2/MAC/mac.h"
#include "LAYER2/MAC/mac_extern.h"
#include "LAYER2/MAC/mac_proto.h"
#include "RRC/LTE/rrc_extern.h"
#include "PHY_INTERFACE/phy_interface.h"
70
#include "common/utils/LOG/log.h"
71 72 73
#include "UTIL/OTG/otg_tx.h"
#include "UTIL/OTG/otg_externs.h"
#include "UTIL/MATH/oml.h"
74
#include "common/utils/LOG/vcd_signal_dumper.h"
75 76
#include "UTIL/OPT/opt.h"
#include "enb_config.h"
77

78 79 80 81 82 83 84 85 86 87 88 89 90 91

#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
Rohit Gupta committed
92 93
#include "T.h"

94 95 96 97 98 99 100 101 102 103
//#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;

104 105
// Fix per CC openair rf/if device update
// extern openair0_device openair0;
106

107

108 109 110 111 112 113
#if defined(ENABLE_ITTI)
extern volatile int             start_eNB;
extern volatile int             start_UE;
#endif
extern volatile int                    oai_exit;

Cedric Roux's avatar
Cedric Roux committed
114
extern int transmission_mode;
115

116 117
extern int oaisim_flag;

118 119 120
//uint16_t sf_ahead=4;
extern uint16_t sf_ahead;

121

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
126
time_stats_t softmodem_stats_rxtx_sf; // total tx time
127
time_stats_t nfapi_meas; // total tx time
128
time_stats_t softmodem_stats_rx_sf; // total rx time
129 130 131 132 133 134 135 136 137

/* 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;
138
} sync_phy_proc;
139

140 141
extern double cpuf;

142

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

Wang Tsu-Han's avatar
Wang Tsu-Han committed
146
int wakeup_tx(PHY_VARS_eNB *eNB);
147
int wakeup_txfh(L1_rxtx_proc_t *proc,PHY_VARS_eNB *eNB);
148
void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe);
149
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
150 151
void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe);
#endif
152

153 154 155 156 157 158
extern uint8_t nfapi_mode;
extern void oai_subframe_ind(uint16_t sfn, uint16_t sf);
extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset);

//#define TICK_TO_US(ts) (ts.diff)
#define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials)
Raymond Knopp's avatar
Raymond Knopp committed
159

160

161
static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name) {
Raymond Knopp's avatar
Raymond Knopp committed
162
  start_meas(&softmodem_stats_rxtx_sf);
163
  //L1_rxtx_proc_t *L1_proc_tx = &eNB->proc.L1_proc_tx;
164

165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
  // *******************************************************************

  if (nfapi_mode == 1) {

    // I am a PNF and I need to let nFAPI know that we have a (sub)frame tick
    uint16_t frame = proc->frame_rx;
    uint16_t subframe = proc->subframe_rx;

    //add_subframe(&frame, &subframe, 4);

    //oai_subframe_ind(proc->frame_tx, proc->subframe_tx);
    //LOG_D(PHY, "oai_subframe_ind(frame:%u, subframe:%d) - NOT CALLED ********\n", frame, subframe);
    start_meas(&nfapi_meas);
    oai_subframe_ind(frame, subframe);
    stop_meas(&nfapi_meas);

    if (eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus||
        eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs ||
        eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs ||
        eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles ||
        eNB->UL_INFO.cqi_ind.number_of_cqis
       ) {
      LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d preambles:%05d:%d cqis:%d] RX:%04d%d TX:%04d%d num_pdcch_symbols:%d\n", 
          NFAPI_SFNSF2DEC(eNB->UL_INFO.rx_ind.sfn_sf),   eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus, 
          NFAPI_SFNSF2DEC(eNB->UL_INFO.harq_ind.sfn_sf), eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs, 
          NFAPI_SFNSF2DEC(eNB->UL_INFO.crc_ind.sfn_sf),  eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs, 
          NFAPI_SFNSF2DEC(eNB->UL_INFO.rach_ind.sfn_sf), eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles,
          eNB->UL_INFO.cqi_ind.number_of_cqis, 
          proc->frame_rx, proc->subframe_rx, 
      proc->frame_tx, proc->subframe_tx, eNB->pdcch_vars[proc->subframe_tx&1].num_pdcch_symbols);
    }
  }

  if (nfapi_mode == 1 && eNB->pdcch_vars[proc->subframe_tx&1].num_pdcch_symbols == 0) {
    LOG_E(PHY, "eNB->pdcch_vars[proc->subframe_tx&1].num_pdcch_symbols == 0");
    return 0;
  }

Raymond Knopp's avatar
Raymond Knopp committed
203 204
  // ****************************************
  // Common RX procedures subframe n
205

Cedric Roux's avatar
Cedric Roux committed
206 207
  T(T_ENB_PHY_DL_TICK, T_INT(eNB->Mod_id), T_INT(proc->frame_tx), T_INT(proc->subframe_tx));

208
  // if this is IF5 or 3GPP_eNB
209
  if (eNB && eNB->RU_list && eNB->RU_list[0] && eNB->RU_list[0]->function < NGFI_RAU_IF4p5) {
210
    wakeup_prach_eNB(eNB,NULL,proc->frame_rx,proc->subframe_rx);
211
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
212 213 214
    wakeup_prach_eNB_br(eNB,NULL,proc->frame_rx,proc->subframe_rx);
#endif
  }
Wang Tsu-Han's avatar
Wang Tsu-Han committed
215 216 217

  release_UE_in_freeList(eNB->Mod_id);

Raymond Knopp's avatar
Raymond Knopp committed
218
  // UE-specific RX processing for subframe n
219
  if (nfapi_mode == 0 || nfapi_mode == 1) {
220
    phy_procedures_eNB_uespec_RX(eNB, proc);
221
  }
222
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER , 1 );
223 224

  pthread_mutex_lock(&eNB->UL_INFO_mutex);
225

226 227 228 229
  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;
230

231
  eNB->if_inst->UL_indication(&eNB->UL_INFO);
232

233
  pthread_mutex_unlock(&eNB->UL_INFO_mutex);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
234 235
  /* this conflict resolution may be totally wrong, to be tested */
  /* CONFLICT RESOLUTION: BEGIN */
236
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER , 0 );
237
  if(oai_exit) return(-1);
238
  if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD){
Wang Tsu-Han's avatar
Wang Tsu-Han committed
239
#ifndef PHY_TX_THREAD
240
    phy_procedures_eNB_TX(eNB, proc, 1);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
241
#endif
242
  }
Wang Tsu-Han's avatar
Wang Tsu-Han committed
243 244 245
  /* CONFLICT RESOLUTION: what about this release_thread call, has it to be done? if yes, where? */
  //if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) return(-1);
  /* CONFLICT RESOLUTION: END */
Raymond Knopp's avatar
Raymond Knopp committed
246 247

  stop_meas( &softmodem_stats_rxtx_sf );
248 249 250

  LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, proc->frame_rx, proc->subframe_rx, proc->frame_tx, proc->subframe_tx);

251
  LOG_D(PHY, "rxtx:%lld nfapi:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ",
laurent's avatar
laurent committed
252
      softmodem_stats_rxtx_sf.p_time, nfapi_meas.p_time,
253 254 255
      TICK_TO_US(eNB->phy_proc_tx),
      TICK_TO_US(eNB->phy_proc_rx),
      TICK_TO_US(eNB->rx_prach),
Wang Tsu-Han's avatar
Wang Tsu-Han committed
256 257
      TICK_TO_US(eNB->ofdm_mod_stats)
      );
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
  LOG_D(PHY,
    "dlsch[enc:%lld mod:%lld scr:%lld rm:%lld t:%lld i:%lld] rx_dft:%lld ",
      TICK_TO_US(eNB->dlsch_encoding_stats),
      TICK_TO_US(eNB->dlsch_modulation_stats),
      TICK_TO_US(eNB->dlsch_scrambling_stats),
      TICK_TO_US(eNB->dlsch_rate_matching_stats),
      TICK_TO_US(eNB->dlsch_turbo_encoding_stats),
      TICK_TO_US(eNB->dlsch_interleaving_stats),
      TICK_TO_US(eNB->rx_dft_stats));

  LOG_D(PHY," ulsch[ch:%lld freq:%lld dec:%lld demod:%lld ru:%lld ",
      TICK_TO_US(eNB->ulsch_channel_estimation_stats),
      TICK_TO_US(eNB->ulsch_freq_offset_estimation_stats),
      TICK_TO_US(eNB->ulsch_decoding_stats),
      TICK_TO_US(eNB->ulsch_demodulation_stats),
      TICK_TO_US(eNB->ulsch_rate_unmatching_stats));

  LOG_D(PHY, "td:%lld dei:%lld dem:%lld llr:%lld tci:%lld ",
      TICK_TO_US(eNB->ulsch_turbo_decoding_stats),
      TICK_TO_US(eNB->ulsch_deinterleaving_stats),
      TICK_TO_US(eNB->ulsch_demultiplexing_stats),
      TICK_TO_US(eNB->ulsch_llr_stats),
      TICK_TO_US(eNB->ulsch_tc_init_stats));
  LOG_D(PHY, "tca:%lld tcb:%lld tcg:%lld tce:%lld l1:%lld l2:%lld]\n\n", 
      TICK_TO_US(eNB->ulsch_tc_alpha_stats),
      TICK_TO_US(eNB->ulsch_tc_beta_stats),
      TICK_TO_US(eNB->ulsch_tc_gamma_stats),
      TICK_TO_US(eNB->ulsch_tc_ext_stats),
      TICK_TO_US(eNB->ulsch_tc_intl1_stats),
      TICK_TO_US(eNB->ulsch_tc_intl2_stats)
      );
Raymond Knopp's avatar
Raymond Knopp committed
289 290 291 292
  
  return(0);
}

293

Wang Tsu-Han's avatar
Wang Tsu-Han committed
294
static void* L1_thread_tx(void* param) {
295

296 297
  L1_proc_t *eNB_proc  = (L1_proc_t*)param;
  L1_rxtx_proc_t *proc = &eNB_proc->L1_proc_tx;
298 299 300
  PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id];
  
  char thread_name[100];
Wang Tsu-Han's avatar
Wang Tsu-Han committed
301
  sprintf(thread_name,"TXnp4_%d\n",&eNB->proc.L1_proc == proc ? 0 : 1);
302
  thread_top_init(thread_name,1,470000,500000,500000);
303
  
304
  //wait_sync("tx_thread");
Eurecom's avatar
Eurecom committed
305
  
306
  while (!oai_exit) {
307
    
308

Wang Tsu-Han's avatar
Wang Tsu-Han committed
309
    if (wait_on_condition(&proc->mutex,&proc->cond,&proc->instance_cnt,thread_name)<0) break;
310 311 312 313 314 315
    if (oai_exit) break;    
    // *****************************************
    // 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)
    // *****************************************
316 317 318 319
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX1_ENB,proc->subframe_tx);
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX1_ENB,proc->subframe_rx);
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_ENB,proc->frame_tx);
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_ENB,proc->frame_rx);
320
    
321
    phy_procedures_eNB_TX(eNB, proc, 1);
322

Wang Tsu-Han's avatar
Wang Tsu-Han committed
323
    pthread_mutex_lock( &proc->mutex );
324
    proc->instance_cnt = -1;
325
    // the thread can now be woken up
Wang Tsu-Han's avatar
Wang Tsu-Han committed
326
    if (pthread_cond_signal(&proc->cond) != 0) {
327 328 329
      LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
      exit_fun( "ERROR pthread_cond_signal" );
    }
Wang Tsu-Han's avatar
Wang Tsu-Han committed
330
    pthread_mutex_unlock( &proc->mutex );
Wang Tsu-Han's avatar
Wang Tsu-Han committed
331
    wakeup_txfh(proc,eNB);
332 333 334 335 336
  }

  return 0;
}

337
/*!
338
 * \brief The RX UE-specific and TX thread of eNB.
339
 * \param param is a \ref L1_proc_t structure which contains the info what to process.
340 341
 * \returns a pointer to an int. The storage is not on the heap and must not be freed.
 */
342

Wang Tsu-Han's avatar
Wang Tsu-Han committed
343
static void* L1_thread( void* param ) {
344

345
  static int eNB_thread_rxtx_status;
346 347
  //L1_proc_t *eNB_proc  = (L1_proc_t*)param;
  L1_rxtx_proc_t *proc;
348 349 350

  // Working
  if(nfapi_mode ==2){
351
	  proc = (L1_rxtx_proc_t*)param;
352 353
  }
  else{
354
	  L1_proc_t *eNB_proc  = (L1_proc_t*)param;
Wang Tsu-Han's avatar
Wang Tsu-Han committed
355
	  proc = &eNB_proc->L1_proc;
356 357 358
  }


359
  PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id];
360

Raymond Knopp's avatar
Raymond Knopp committed
361 362
  char thread_name[100];

363 364
  cpu_set_t cpuset;
  CPU_ZERO(&cpuset);
365

366
  // set default return value
367
  eNB_thread_rxtx_status = 0;
368 369


Wang Tsu-Han's avatar
Wang Tsu-Han committed
370
  sprintf(thread_name,"RXn_TXnp4_%d\n",&eNB->proc.L1_proc == proc ? 0 : 1);
371 372 373
  thread_top_init(thread_name,1,470000,500000,500000);
  pthread_setname_np( pthread_self(),"rxtx processing");
  LOG_I(PHY,"thread rxtx created id=%ld\n", syscall(__NR_gettid));
374

375

376

377
  while (!oai_exit) {
378 379
    
    
380
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
381
    T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
382

Wang Tsu-Han's avatar
Wang Tsu-Han committed
383
    if (wait_on_condition(&proc->mutex,&proc->cond,&proc->instance_cnt,thread_name)<0) break;
384

385
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_CPUID_ENB_THREAD_RXTX,sched_getcpu());
386
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 1 );
387 388 389 390 391 392
   
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB,proc->subframe_tx);
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_ENB,proc->subframe_rx);
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB,proc->frame_tx);
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_ENB,proc->frame_rx);
 
393

394 395
    if (oai_exit) break;

396
    if (eNB->CC_id==0)
397
    {
398
      if (rxtx(eNB,proc,thread_name) < 0) break;
399
    }
400

401
    if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT)              phy_procedures_eNB_TX(eNB, proc, 1);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
402
    if (release_thread(&proc->mutex,&proc->instance_cnt,thread_name)<0) break;
Wang Tsu-Han's avatar
Wang Tsu-Han committed
403
    if (nfapi_mode!=2){
Wang Tsu-Han's avatar
Wang Tsu-Han committed
404
    	if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)      wakeup_tx(eNB);
405
    	else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT)     wakeup_txfh(proc,eNB);
406
    }
407

Raymond Knopp's avatar
Raymond Knopp committed
408
  } // while !oai_exit
409

410
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
411

412
  LOG_D(PHY, " *** Exiting eNB thread RXn_TXnp4\n");
413

414 415
  eNB_thread_rxtx_status = 0;
  return &eNB_thread_rxtx_status;
416 417
}

418
void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t *ru)
Cedric Roux's avatar
Cedric Roux committed
419
{
420 421
  L1_proc_t *proc           = &eNB->proc;
  L1_rxtx_proc_t *L1_proc = &proc->L1_proc;
Raymond Knopp's avatar
Raymond Knopp committed
422 423
  LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
  RU_proc_t *ru_proc=&ru->proc;
424

425 426
  proc->frame_rx    = frame_rx;
  proc->subframe_rx = subframe_rx;
Raymond Knopp's avatar
Raymond Knopp committed
427

Cedric Roux's avatar
Cedric Roux committed
428
  if (!oai_exit) {
429
    T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
Raymond Knopp's avatar
Raymond Knopp committed
430

Wang Tsu-Han's avatar
Wang Tsu-Han committed
431 432 433 434 435
    L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_tti);
    L1_proc->frame_rx     = ru_proc->frame_rx;
    L1_proc->subframe_rx  = ru_proc->subframe_rx;
    L1_proc->frame_tx     = (L1_proc->subframe_rx > (9-sf_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
    L1_proc->subframe_tx  = (L1_proc->subframe_rx + sf_ahead)%10;
Raymond Knopp's avatar
Raymond Knopp committed
436

Wang Tsu-Han's avatar
Wang Tsu-Han committed
437 438 439 440
    if (rxtx(eNB,L1_proc,string) < 0) LOG_E(PHY,"eNB %d CC_id %d failed during execution\n",eNB->Mod_id,eNB->CC_id);
    ru_proc->timestamp_tx = L1_proc->timestamp_tx;
    ru_proc->subframe_tx  = L1_proc->subframe_tx;
    ru_proc->frame_tx     = L1_proc->frame_tx;
441
  }
Raymond Knopp's avatar
Raymond Knopp committed
442 443
}

444
int wakeup_txfh(L1_rxtx_proc_t *proc,PHY_VARS_eNB *eNB) {
Wang Tsu-Han's avatar
Wang Tsu-Han committed
445 446 447 448 449

  RU_t *ru;
  RU_proc_t *ru_proc;


450 451 452
  struct timespec wait;
  wait.tv_sec=0;
  wait.tv_nsec=5000000L;
Wang Tsu-Han's avatar
Wang Tsu-Han committed
453

454
  if(wait_on_condition(&proc->mutex_RUs,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) {
Wang Tsu-Han's avatar
Wang Tsu-Han committed
455
    LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", proc->frame_tx, proc->subframe_tx);
456
    return(-1);
457
  }
Wang Tsu-Han's avatar
Wang Tsu-Han committed
458 459 460
  pthread_mutex_lock(&eNB->proc.mutex_RU_tx);
  eNB->proc.RU_mask_tx = 0;
  pthread_mutex_unlock(&eNB->proc.mutex_RU_tx);
461
  if (release_thread(&proc->mutex_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) return(-1);
462

Wang Tsu-Han's avatar
Wang Tsu-Han committed
463 464 465 466 467 468 469 470 471 472 473 474 475 476
  for(int i=0; i<eNB->num_RU; i++)
  {
    ru      = eNB->RU_list[i];
    ru_proc = &ru->proc;
    if (ru_proc->instance_cnt_eNBs == 0) {
      LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->subframe_tx, proc->frame_rx, proc->subframe_rx);
      return(-1);
    }
    if (pthread_mutex_timedlock(&ru_proc->mutex_eNBs,&wait) != 0) {
      LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", ru_proc->subframe_rx&1,ru_proc->instance_cnt_eNBs );
      exit_fun( "error locking mutex_eNB" );
      return(-1);
    }

477
    ru_proc->instance_cnt_eNBs = 0;
Wang Tsu-Han's avatar
Wang Tsu-Han committed
478 479 480
    ru_proc->timestamp_tx = proc->timestamp_tx;
    ru_proc->subframe_tx  = proc->subframe_tx;
    ru_proc->frame_tx     = proc->frame_tx;
481

482
  
Wang Tsu-Han's avatar
Wang Tsu-Han committed
483 484 485 486 487 488
    // the thread can now be woken up
    if (pthread_cond_signal(&ru_proc->cond_eNBs) != 0) {
      LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
      exit_fun( "ERROR pthread_cond_signal" );
      return(-1);
    }
489
  
Wang Tsu-Han's avatar
Wang Tsu-Han committed
490 491
    pthread_mutex_unlock( &ru_proc->mutex_eNBs );
  }
492 493 494 495

  return(0);
}

Wang Tsu-Han's avatar
Wang Tsu-Han committed
496
int wakeup_tx(PHY_VARS_eNB *eNB) {
497

498
  L1_proc_t *proc=&eNB->proc;
499

500 501
  L1_rxtx_proc_t *L1_proc_tx = &proc->L1_proc_tx;
  L1_rxtx_proc_t *L1_proc    = &proc->L1_proc;
502 503 504 505 506 507

  
  struct timespec wait;
  wait.tv_sec=0;
  wait.tv_nsec=5000000L;
  
508
  
Wang Tsu-Han's avatar
Wang Tsu-Han committed
509
  if (pthread_mutex_timedlock(&L1_proc_tx->mutex,&wait) != 0) {
510 511
    LOG_E(PHY, "[SCHED][eNB] ERROR locking mutex for eNB L1_thread_tx\n");
    exit_fun("ERROR pthread_lock");
512 513
    return(-1);
  }
514 515 516
  while(L1_proc_tx->instance_cnt == 0){
    pthread_cond_wait(&L1_proc_tx->cond,&L1_proc_tx->mutex);
  }
517

518
  L1_proc_tx->instance_cnt = 0;
519 520

  
Wang Tsu-Han's avatar
Wang Tsu-Han committed
521 522 523 524 525
  L1_proc_tx->subframe_rx   = L1_proc->subframe_rx;
  L1_proc_tx->frame_rx      = L1_proc->frame_rx;
  L1_proc_tx->subframe_tx   = L1_proc->subframe_tx;
  L1_proc_tx->frame_tx      = L1_proc->frame_tx;
  L1_proc_tx->timestamp_tx  = L1_proc->timestamp_tx;
526 527
  
  // the thread can now be woken up
Wang Tsu-Han's avatar
Wang Tsu-Han committed
528
  if (pthread_cond_signal(&L1_proc_tx->cond) != 0) {
529
    LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
530 531 532 533
    exit_fun( "ERROR pthread_cond_signal" );
    return(-1);
  }
  
Wang Tsu-Han's avatar
Wang Tsu-Han committed
534
  pthread_mutex_unlock( &L1_proc_tx->mutex);
535 536 537

  return(0);
}
Raymond Knopp's avatar
Raymond Knopp committed
538

539 540
int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {

541
  L1_proc_t *proc=&eNB->proc;
542
  RU_proc_t *ru_proc=&ru->proc;
543

544
  L1_rxtx_proc_t *L1_proc=&proc->L1_proc;
545
  
546 547

  LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
548 549 550 551

  int i;
  struct timespec wait;
  
552 553 554 555 556 557 558 559 560 561
  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
562
    LOG_E(PHY,"Not all RUs have provided their info\n");
563 564 565 566 567 568 569 570 571 572 573
    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);
  }




574 575
  wait.tv_sec=0;
  wait.tv_nsec=5000000L;
576

Wang Tsu-Han's avatar
Wang Tsu-Han committed
577 578 579
    
  if (L1_proc->instance_cnt == 0) {
    LOG_E(PHY,"Frame %d, subframe %d: RXTX0 thread busy, dropping\n",L1_proc->frame_rx,L1_proc->subframe_rx);
580 581 582
    return(-1);
  }

Cedric Roux's avatar
Cedric Roux committed
583
  // wake up TX for subframe n+sf_ahead
584
  // lock the TX mutex and make sure the thread is ready
Wang Tsu-Han's avatar
Wang Tsu-Han committed
585 586
  if (pthread_mutex_timedlock(&L1_proc->mutex,&wait) != 0) {
    LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", L1_proc->subframe_rx&1,L1_proc->instance_cnt );
587 588 589 590
    exit_fun( "error locking mutex_rxtx" );
    return(-1);
  }
  
591

Wang Tsu-Han's avatar
Wang Tsu-Han committed
592
  ++L1_proc->instance_cnt;
593 594 595 596 597
  
  // 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, 
598 599
  // we want to generate subframe (n+sf_ahead), so TS_tx = TX_rx+sf_ahead*samples_per_tti,
  // and proc->subframe_tx = proc->subframe_rx+sf_ahead
Wang Tsu-Han's avatar
Wang Tsu-Han committed
600 601 602 603 604
  L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_tti);
  L1_proc->frame_rx     = ru_proc->frame_rx;
  L1_proc->subframe_rx  = ru_proc->subframe_rx;
  L1_proc->frame_tx     = (L1_proc->subframe_rx > (9-sf_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
  L1_proc->subframe_tx  = (L1_proc->subframe_rx + sf_ahead)%10;
605

606
  // the thread can now be woken up
Wang Tsu-Han's avatar
Wang Tsu-Han committed
607
  if (pthread_cond_signal(&L1_proc->cond) != 0) {
608 609 610 611 612
    LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n");
    exit_fun( "ERROR pthread_cond_signal" );
    return(-1);
  }
  
Wang Tsu-Han's avatar
Wang Tsu-Han committed
613
  pthread_mutex_unlock( &L1_proc->mutex);
614 615 616 617

  return(0);
}

618
void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) {
619

620
  L1_proc_t *proc = &eNB->proc;
621
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
622
  int i;
623

624 625 626 627
  if (ru!=NULL) {
    pthread_mutex_lock(&proc->mutex_RU_PRACH);
    for (i=0;i<eNB->num_RU;i++) {
      if (ru == eNB->RU_list[i]) {
Raymond Knopp's avatar
Raymond Knopp committed
628
	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);
629 630
	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",
631
		eNB->Mod_id,frame,subframe,ru->idx,eNB->num_RU,proc->RU_mask_prach);
632 633 634 635 636
	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);
Raymond Knopp's avatar
Raymond Knopp committed
637
      return;
638 639 640 641 642 643 644
    }
    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);
    }
  }
    
645
  // check if we have to detect PRACH first
646
  if (is_prach_subframe(fp,frame,subframe)>0) { 
647
    LOG_D(PHY,"Triggering prach processing, frame %d, subframe %d\n",frame,subframe);
648
    if (proc->instance_cnt_prach == 0) {
649
      LOG_W(PHY,"[eNB] Frame %d Subframe %d, dropping PRACH\n", frame,subframe);
650 651 652 653 654 655 656 657 658 659 660 661
      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
662 663
    proc->frame_prach = frame;
    proc->subframe_prach = subframe;
664 665 666 667 668 669 670 671 672 673 674 675 676
    
    // 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 );
  }

}

677
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
678 679
void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) {

680
  L1_proc_t *proc = &eNB->proc;
681 682 683 684 685 686 687
  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]) {
Raymond Knopp's avatar
Raymond Knopp committed
688
	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);
689 690 691 692 693 694 695 696
	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);
Raymond Knopp's avatar
Raymond Knopp committed
697
      return;
698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737
    }
    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

Wang Tsu-Han's avatar
Wang Tsu-Han committed
738

739 740
/*!
 * \brief The prach receive thread of eNB.
741
 * \param param is a \ref L1_proc_t structure which contains the info what to process.
742 743
 * \returns a pointer to an int. The storage is not on the heap and must not be freed.
 */
744
static void* eNB_thread_prach( void* param ) {
745 746
  static int eNB_thread_prach_status;

747 748

  PHY_VARS_eNB *eNB= (PHY_VARS_eNB *)param;
749
  L1_proc_t *proc = &eNB->proc;
Raymond Knopp's avatar
Raymond Knopp committed
750

751 752 753
  // set default return value
  eNB_thread_prach_status = 0;

754
  thread_top_init("eNB_thread_prach",1,500000,1000000,20000000);
755

756
  //wait_sync("eNB_thread_prach");
757

758 759 760
  while (!oai_exit) {
    

761
    
Raymond Knopp's avatar
Raymond Knopp committed
762
    if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break;
763
    if (oai_exit) break;
764 765

    LOG_D(PHY,"Running eNB prach procedures\n");
766
    prach_procedures(eNB
767
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
768 769 770
		     ,0
#endif
		     );
771
    
Raymond Knopp's avatar
Raymond Knopp committed
772
    if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break;
773
  }
774

775
  LOG_I(PHY, "Exiting eNB thread PRACH\n");
Raymond Knopp's avatar
Raymond Knopp committed
776

777 778
  eNB_thread_prach_status = 0;
  return &eNB_thread_prach_status;
779 780
}

781
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
782 783
/*!
 * \brief The prach receive thread of eNB for BL/CE UEs.
784
 * \param param is a \ref L1_proc_t structure which contains the info what to process.
785 786 787 788 789 790 791
 * \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;
792
  L1_proc_t *proc = &eNB->proc;
793 794 795 796

  // set default return value
  eNB_thread_prach_status = 0;

797
  thread_top_init("eNB_thread_prach_br",1,500000,1000000,20000000);
798 799 800 801 802 803

  while (!oai_exit) {
    
    

    if (wait_on_condition(&proc->mutex_prach_br,&proc->cond_prach_br,&proc->instance_cnt_prach_br,"eNB_prach_thread_br") < 0) break;
804
    if (oai_exit) break;
805 806 807 808 809 810 811 812 813 814 815 816 817 818

    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
Raymond Knopp's avatar
Raymond Knopp committed
819

Raymond Knopp's avatar
Raymond Knopp committed
820

821

Wang Tsu-Han's avatar
Wang Tsu-Han committed
822
extern void init_td_thread(PHY_VARS_eNB *);
Eurecom's avatar
Eurecom committed
823
extern void init_te_thread(PHY_VARS_eNB *);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
824 825
extern void kill_td_thread(PHY_VARS_eNB *);
extern void kill_te_thread(PHY_VARS_eNB *);
826

827
static void* process_stats_thread(void* param) {
828 829 830

  PHY_VARS_eNB     *eNB      = (PHY_VARS_eNB*)param;

831
  wait_sync("process_stats_thread");
832 833

  while (!oai_exit) {
Wang Tsu-Han's avatar
Wang Tsu-Han committed
834 835
    sleep(1);
      if (opp_enabled == 1) {
laurent's avatar
laurent committed
836 837 838
	if ( eNB->ulsch_decoding_stats.trials>0) 
          print_meas(&eNB->ulsch_decoding_stats,"ulsch_decoding",NULL,NULL);
	if (eNB->dlsch_encoding_stats.trials >0) {
Wang Tsu-Han's avatar
Wang Tsu-Han committed
839 840 841 842 843 844 845 846 847 848 849 850
          print_meas(&eNB->dlsch_turbo_encoding_preperation_stats,"dlsch_coding_crc",NULL,NULL);
          print_meas(&eNB->dlsch_turbo_encoding_segmentation_stats,"dlsch_segmentation",NULL,NULL);
          print_meas(&eNB->dlsch_encoding_stats,"dlsch_encoding",NULL,NULL);
          print_meas(&eNB->dlsch_turbo_encoding_signal_stats,"coding_signal",NULL,NULL);
          print_meas(&eNB->dlsch_turbo_encoding_main_stats,"coding_main",NULL,NULL);
          print_meas(&eNB->dlsch_turbo_encoding_stats,"turbo_encoding",NULL,NULL);
          print_meas(&eNB->dlsch_interleaving_stats,"turbo_interleaving",NULL,NULL);
          print_meas(&eNB->dlsch_rate_matching_stats,"turbo_rate_matching",NULL,NULL);
          print_meas(&eNB->dlsch_turbo_encoding_waiting_stats,"coding_wait",NULL,NULL);
          print_meas(&eNB->dlsch_turbo_encoding_wakeup_stats0,"coding_worker_0",NULL,NULL);
          print_meas(&eNB->dlsch_turbo_encoding_wakeup_stats1,"coding_worker_1",NULL,NULL);
       }
851
       print_meas(&eNB->dlsch_modulation_stats,"dlsch_modulation",NULL,NULL);
852 853 854 855 856
     }
  }
  return(NULL);
}

857

858
void init_eNB_proc(int inst) {
859
  
860
  /*int i=0;*/
861
  int CC_id;
862
  PHY_VARS_eNB *eNB;
863 864
  L1_proc_t *proc;
  L1_rxtx_proc_t *L1_proc, *L1_proc_tx;
Wang Tsu-Han's avatar
Wang Tsu-Han committed
865
  pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_prach=NULL;
866
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
867 868
  pthread_attr_t *attr_prach_br=NULL;
#endif
Raymond Knopp's avatar
Raymond Knopp committed
869

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

872
  for (CC_id=0; CC_id<RC.nb_CC[inst]; CC_id++) {
873
    eNB = RC.eNB[inst][CC_id];
laurent's avatar
laurent committed
874
#ifndef OCP_FRAMEWORK
875
    LOG_I(PHY,"Initializing eNB processes instance:%d CC_id %d \n",inst,CC_id);
laurent's avatar
laurent committed
876
#endif
877
    proc = &eNB->proc;
Raymond Knopp's avatar
Raymond Knopp committed
878

Wang Tsu-Han's avatar
Wang Tsu-Han committed
879 880 881 882
    L1_proc                        = &proc->L1_proc;
    L1_proc_tx                     = &proc->L1_proc_tx;
    L1_proc->instance_cnt          = -1;
    L1_proc_tx->instance_cnt       = -1;
883 884
    L1_proc->instance_cnt_RUs      = 0;
    L1_proc_tx->instance_cnt_RUs   = 0;
885
    proc->instance_cnt_prach       = -1;
886
    proc->instance_cnt_asynch_rxtx = -1;
Eurecom's avatar
Eurecom committed
887
    proc->instance_cnt_synch       = -1;
888
    proc->CC_id                    = CC_id;    
889

Wang Tsu-Han's avatar
Wang Tsu-Han committed
890 891
    proc->first_rx                 =1;
    proc->first_tx                 =1;
Wang Tsu-Han's avatar
Wang Tsu-Han committed
892
    proc->RU_mask_tx               = (1<<eNB->num_RU)-1;
Wang Tsu-Han's avatar
Wang Tsu-Han committed
893 894
    proc->RU_mask                  =0;
    proc->RU_mask_prach            =0;
Raymond Knopp's avatar
Raymond Knopp committed
895

896
    pthread_mutex_init( &eNB->UL_INFO_mutex, NULL);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
897 898 899 900
    pthread_mutex_init( &L1_proc->mutex, NULL);
    pthread_mutex_init( &L1_proc_tx->mutex, NULL);
    pthread_cond_init( &L1_proc->cond, NULL);
    pthread_cond_init( &L1_proc_tx->cond, NULL);
901 902 903 904
    pthread_mutex_init( &L1_proc->mutex_RUs, NULL);
    pthread_mutex_init( &L1_proc_tx->mutex_RUs, NULL);
    pthread_cond_init( &L1_proc->cond_RUs, NULL);
    pthread_cond_init( &L1_proc_tx->cond_RUs, NULL);
Raymond Knopp's avatar
Raymond Knopp committed
905 906 907

    pthread_mutex_init( &proc->mutex_prach, NULL);
    pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL);
908
    pthread_mutex_init( &proc->mutex_RU,NULL);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
909
    pthread_mutex_init( &proc->mutex_RU_tx,NULL);
910
    pthread_mutex_init( &proc->mutex_RU_PRACH,NULL);
Raymond Knopp's avatar
Raymond Knopp committed
911

912
    pthread_cond_init( &proc->cond_prach, NULL);
913
    pthread_cond_init( &proc->cond_asynch_rxtx, NULL);
914 915 916

    pthread_attr_init( &proc->attr_prach);
    pthread_attr_init( &proc->attr_asynch_rxtx);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
917 918
    pthread_attr_init( &L1_proc->attr);
    pthread_attr_init( &L1_proc_tx->attr);
919
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
920 921 922 923 924 925 926
    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
927
#ifndef DEADLINE_SCHEDULER
Wang Tsu-Han's avatar
Wang Tsu-Han committed
928 929
    attr0       = &L1_proc->attr;
    attr1       = &L1_proc_tx->attr;
Raymond Knopp's avatar
Raymond Knopp committed
930
    attr_prach  = &proc->attr_prach;
931
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
932 933 934
    attr_prach_br  = &proc->attr_prach_br;
#endif

Raymond Knopp's avatar
Raymond Knopp committed
935 936
    //    attr_td     = &proc->attr_td;
    //    attr_te     = &proc->attr_te; 
Raymond Knopp's avatar
Raymond Knopp committed
937
#endif
Wang Tsu-Han's avatar
Wang Tsu-Han committed
938

939
    if(get_thread_worker_conf() == WORKER_ENABLE)
940 941
    {
      init_te_thread(eNB);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
942
      init_td_thread(eNB);
943
    }
Raymond Knopp's avatar
Raymond Knopp committed
944 945


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

948
    if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && nfapi_mode!=2) {
Wang Tsu-Han's avatar
Wang Tsu-Han committed
949 950
      pthread_create( &L1_proc->pthread, attr0, L1_thread, proc );
      pthread_create( &L1_proc_tx->pthread, attr1, L1_thread_tx, proc);
951
    }
952
    pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, eNB );
953
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
954 955
    pthread_create( &proc->pthread_prach_br, attr_prach_br, eNB_thread_prach_br, eNB );
#endif
956 957

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

Wang Tsu-Han's avatar
Wang Tsu-Han committed
960
    if (opp_enabled == 1) pthread_create(&proc->process_stats_thread,NULL,process_stats_thread,(void*)eNB);
961

962
    
963
  }
964

965
  //for multiple CCs: setup master and slaves
966 967 968
  /* 
     for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
     eNB = PHY_vars_eNB_g[inst][CC_id];
969

970 971
     if (eNB->node_timing == synch_to_ext_device) { //master
     eNB->proc.num_slaves = MAX_NUM_CCs-1;
972
     eNB->proc.slave_proc = (L1_proc_t**)malloc(eNB->proc.num_slaves*sizeof(L1_proc_t*));
973

974 975 976 977 978 979 980
     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);
     }
     }
     }
  */
981

982 983 984 985
  /* 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;
986 987
  
  
988 989
}

990

991

992 993 994
/*!
 * \brief Terminate eNB TX and RX threads.
 */
995
void kill_eNB_proc(int inst) {
996

997
  int *status;
998
  PHY_VARS_eNB *eNB;
999 1000
  L1_proc_t *proc;
  L1_rxtx_proc_t *L1_proc, *L1_proc_tx;
1001

1002
  for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
1003
    eNB=RC.eNB[inst][CC_id];
1004
    
Wang Tsu-Han's avatar
Wang Tsu-Han committed
1005 1006 1007
    proc        = &eNB->proc;
    L1_proc     = &proc->L1_proc;
    L1_proc_tx  = &proc->L1_proc_tx;
1008

1009
    if(get_thread_worker_conf() == WORKER_ENABLE) {
1010 1011 1012
      kill_td_thread(eNB);
      kill_te_thread(eNB);
    }
1013
    LOG_I(PHY, "Killing TX CC_id %d inst %d\n", CC_id, inst );
Wang Tsu-Han's avatar
Wang Tsu-Han committed
1014

1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025
    if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && nfapi_mode!=2) {
      pthread_mutex_lock(&L1_proc->mutex);
      L1_proc->instance_cnt = 0;
      pthread_cond_signal(&L1_proc->cond);
      pthread_mutex_unlock(&L1_proc->mutex);

      pthread_mutex_lock(&L1_proc_tx->mutex);
      L1_proc_tx->instance_cnt = 0;
      pthread_cond_signal(&L1_proc_tx->cond);
      pthread_mutex_unlock(&L1_proc_tx->mutex);
    }
Wang Tsu-Han's avatar
Wang Tsu-Han committed
1026

Robert Schmidt's avatar
Robert Schmidt committed
1027
    pthread_mutex_lock(&proc->mutex_prach);
Raymond Knopp's avatar
Raymond Knopp committed
1028 1029
    proc->instance_cnt_prach = 0;
    pthread_cond_signal( &proc->cond_prach );
Robert Schmidt's avatar
Robert Schmidt committed
1030
    pthread_mutex_unlock(&proc->mutex_prach);
1031

1032
    pthread_cond_signal( &proc->cond_asynch_rxtx );
1033
    pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx);
Raymond Knopp's avatar
Raymond Knopp committed
1034

1035
    LOG_D(PHY, "joining pthread_prach\n");
1036
    pthread_join( proc->pthread_prach, (void**)&status );    
1037

1038
    LOG_I(PHY, "Destroying prach mutex/cond\n");
1039
    pthread_mutex_destroy( &proc->mutex_prach );
1040
    pthread_cond_destroy( &proc->cond_prach );
1041
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1042
    proc->instance_cnt_prach_br = 0;
1043 1044 1045 1046
    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 );
Wang Tsu-Han's avatar
Wang Tsu-Han committed
1047
#endif
1048
    LOG_I(PHY, "Destroying UL_INFO mutex\n");
1049
    pthread_mutex_destroy(&eNB->UL_INFO_mutex);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
1050 1051 1052 1053 1054 1055

    if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && nfapi_mode!=2) {
      LOG_I(PHY, "Joining L1_proc mutex/cond\n");
      pthread_join( L1_proc->pthread, (void**)&status );
      LOG_I(PHY, "Joining L1_proc_tx mutex/cond\n");
      pthread_join( L1_proc_tx->pthread, (void**)&status );
1056
    }
Wang Tsu-Han's avatar
Wang Tsu-Han committed
1057 1058 1059
    LOG_I(PHY, "Destroying L1_proc mutex/cond\n");
    pthread_mutex_destroy( &L1_proc->mutex );
    pthread_cond_destroy( &L1_proc->cond );
1060 1061
    pthread_mutex_destroy( &L1_proc->mutex_RUs );
    pthread_cond_destroy( &L1_proc->cond_RUs );
Wang Tsu-Han's avatar
Wang Tsu-Han committed
1062 1063 1064
    LOG_I(PHY, "Destroying L1_proc_tx mutex/cond\n");
    pthread_mutex_destroy( &L1_proc_tx->mutex );
    pthread_cond_destroy( &L1_proc_tx->cond );
1065 1066
    pthread_mutex_destroy( &L1_proc_tx->mutex_RUs );
    pthread_cond_destroy( &L1_proc_tx->cond_RUs );
Robert Schmidt's avatar
Robert Schmidt committed
1067 1068 1069

    pthread_attr_destroy(&proc->attr_prach);
    pthread_attr_destroy(&proc->attr_asynch_rxtx);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
1070 1071
    pthread_attr_destroy(&L1_proc->attr);
    pthread_attr_destroy(&L1_proc_tx->attr);
1072
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
Robert Schmidt's avatar
Robert Schmidt committed
1073 1074 1075 1076
    pthread_mutex_destroy(&proc->mutex_RU_PRACH_br);
    pthread_attr_destroy(&proc->attr_prach_br);
#endif

1077
  }
1078 1079
}

1080

1081 1082 1083


void reset_opp_meas(void) {
1084

1085 1086 1087 1088 1089
  int sfn;
  reset_meas(&softmodem_stats_mt);
  reset_meas(&softmodem_stats_hw);
  
  for (sfn=0; sfn < 10; sfn++) {
1090
    reset_meas(&softmodem_stats_rxtx_sf);
1091
    reset_meas(&softmodem_stats_rx_sf);
1092 1093 1094
  }
}

1095

1096 1097 1098 1099 1100 1101 1102
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++) {
1103
    print_meas(&softmodem_stats_rxtx_sf,"[eNB][total_phy_proc_rxtx]",NULL, NULL);
1104
    print_meas(&softmodem_stats_rx_sf,"[eNB][total_phy_proc_rx]",NULL,NULL);
1105 1106
  }
}
1107

1108 1109 1110 1111 1112 1113
void free_transport(PHY_VARS_eNB *eNB)
{
  int i;
  int j;

  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
1114
    LOG_D(PHY, "Freeing Transport Channel Buffers for DLSCH, UE %d\n",i);
1115 1116
    for (j=0; j<2; j++) free_eNB_dlsch(eNB->dlsch[i][j]);

1117
    LOG_D(PHY, "Freeing Transport Channel Buffer for ULSCH, UE %d\n",i);
1118 1119 1120 1121 1122
    free_eNB_ulsch(eNB->ulsch[1+i]);
  }
  free_eNB_ulsch(eNB->ulsch[0]);
}

1123
void init_transport(PHY_VARS_eNB *eNB) {
1124

1125 1126 1127
  int i;
  int j;
  LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
1128

Cedric Roux's avatar
Cedric Roux committed
1129
  LOG_I(PHY, "Initialise transport\n");
1130

1131
  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
Wang Tsu-Han's avatar
Wang Tsu-Han committed
1132
    LOG_D(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i);
1133 1134 1135 1136
    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);
1137
	exit(-1);
1138 1139
      } else {
	eNB->dlsch[i][j]->rnti=0;
1140
	LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,eNB->dlsch[i][j], eNB->dlsch[i][j]->rnti);
1141 1142
      }
    }
1143
    
Wang Tsu-Han's avatar
Wang Tsu-Han committed
1144
    LOG_D(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i);
1145 1146 1147 1148
    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");
1149 1150
      exit(-1);
    }
1151 1152 1153 1154
    
    // 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;
1155
  }
1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171
  // 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;
1172
  
1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186
  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;
    
} 
Raymond Knopp's avatar
Raymond Knopp committed
1187 1188

void init_eNB_afterRU(void) {
1189

1190 1191
  int inst,CC_id,ru_id,i,aa;
  PHY_VARS_eNB *eNB;
1192

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

1195
  for (inst=0;inst<RC.nb_inst;inst++) {
1196
    LOG_I(PHY,"RC.nb_CC[inst]:%d\n", RC.nb_CC[inst]);
1197
    for (CC_id=0;CC_id<RC.nb_CC[inst];CC_id++) {
1198 1199 1200

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

1201 1202 1203
      eNB                                  =  RC.eNB[inst][CC_id];
      phy_init_lte_eNB(eNB,0,0);
      // map antennas and PRACH signals to eNB RX
1204
      if (0) AssertFatal(eNB->num_RU>0,"Number of RU attached to eNB %d is zero\n",eNB->Mod_id);
1205
      LOG_I(PHY,"Mapping RX ports from %d RUs to eNB %d\n",eNB->num_RU,eNB->Mod_id);
1206
      eNB->frame_parms.nb_antennas_rx       = 0;
1207

Cedric Roux's avatar
Cedric Roux committed
1208
      LOG_I(PHY,"Overwriting eNB->prach_vars.rxsigF[0]:%p\n", eNB->prach_vars.rxsigF[0]);
1209

Raymond Knopp's avatar
Raymond Knopp committed
1210
      eNB->prach_vars.rxsigF[0] = (int16_t**)malloc16(64*sizeof(int16_t*));
1211
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1212
      for (int ce_level=0;ce_level<4;ce_level++) {
Cedric Roux's avatar
Cedric Roux committed
1213
        LOG_I(PHY,"Overwriting eNB->prach_vars_br.rxsigF.rxsigF[0]:%p\n", eNB->prach_vars_br.rxsigF[ce_level]);
1214 1215
        eNB->prach_vars_br.rxsigF[ce_level] = (int16_t**)malloc16(64*sizeof(int16_t*));
      }
1216
#endif
1217 1218 1219

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

1220 1221
      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;
1222 1223 1224 1225 1226 1227 1228 1229 1230

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

1231 1232
	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);
Raymond Knopp's avatar
Raymond Knopp committed
1233
	  eNB->prach_vars.rxsigF[0][aa]    =  eNB->RU_list[ru_id]->prach_rxsigF[i];
1234
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
Raymond Knopp's avatar
Raymond Knopp committed
1235 1236 1237
	  for (int ce_level=0;ce_level<4;ce_level++)
	    eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[ru_id]->prach_rxsigF_br[ce_level][i];
#endif
1238 1239 1240
	  eNB->common_vars.rxdataF[aa]     =  eNB->RU_list[ru_id]->common.rxdataF[i];
	}
      }
1241 1242 1243



Cedric Roux's avatar
Cedric Roux committed
1244 1245 1246 1247
      /* TODO: review this code, there is something wrong.
       * In monolithic mode, we come here with nb_antennas_rx == 0
       * (not tested in other modes).
       */
1248 1249 1250 1251 1252 1253 1254
      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;
      }
      else
      {
Cedric Roux's avatar
Cedric Roux committed
1255
        //LOG_I(PHY," Delete code\n");
1256 1257 1258 1259 1260 1261 1262 1263 1264
      }

      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;
      }
      else
      {
Cedric Roux's avatar
Cedric Roux committed
1265
        //LOG_I(PHY," Delete code\n");
1266 1267 1268 1269 1270
      }




1271 1272 1273
      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);
1274 1275

      init_transport(eNB);
Raymond Knopp's avatar
Raymond Knopp committed
1276
      //init_precoding_weights(RC.eNB[inst][CC_id]);
1277 1278 1279
    }
    init_eNB_proc(inst);
  }
1280

1281
  for (ru_id=0;ru_id<RC.nb_RU;ru_id++) {
1282 1283

    AssertFatal(RC.ru[ru_id]!=NULL,"ru_id %d is null\n",ru_id);
1284
    
1285 1286
    RC.ru[ru_id]->wakeup_rxtx         = wakeup_rxtx;
    RC.ru[ru_id]->wakeup_prach_eNB    = wakeup_prach_eNB;
1287
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1288
    RC.ru[ru_id]->wakeup_prach_eNB_br = wakeup_prach_eNB_br;
1289
#endif
1290
    RC.ru[ru_id]->eNB_top             = eNB_top;
1291 1292
  }
}
1293

1294
void init_eNB(int single_thread_flag,int wait_for_sync) {
1295
  
1296
  int CC_id;
1297
  int inst;
1298
  PHY_VARS_eNB *eNB;
Raymond Knopp's avatar
Raymond Knopp committed
1299

1300 1301
  LOG_I(PHY,"[lte-softmodem.c] eNB structure about to allocated RC.nb_L1_inst:%d RC.nb_L1_CC[0]:%d\n",RC.nb_L1_inst,RC.nb_L1_CC[0]);

1302
  if (RC.eNB == NULL) RC.eNB = (PHY_VARS_eNB***) malloc(RC.nb_L1_inst*sizeof(PHY_VARS_eNB **));
1303
  LOG_I(PHY,"[lte-softmodem.c] eNB structure RC.eNB allocated\n");
1304
  for (inst=0;inst<RC.nb_L1_inst;inst++) {
1305
    if (RC.eNB[inst] == NULL) RC.eNB[inst] = (PHY_VARS_eNB**) malloc(RC.nb_CC[inst]*sizeof(PHY_VARS_eNB *));
1306
    for (CC_id=0;CC_id<RC.nb_L1_CC[inst];CC_id++) {
1307 1308
      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]; 
1309
      eNB->abstraction_flag   = 0;
Raymond Knopp's avatar
Raymond Knopp committed
1310
      eNB->single_thread_flag = single_thread_flag;
1311

1312

1313
      LOG_I(PHY,"Initializing eNB %d CC_id %d single_thread_flag:%d\n",inst,CC_id,single_thread_flag);
laurent's avatar
laurent committed
1314
#ifndef OCP_FRAMEWORK
1315
      LOG_I(PHY,"Initializing eNB %d CC_id %d\n",inst,CC_id);
laurent's avatar
laurent committed
1316
#endif
1317
      
1318
      LOG_I(PHY,"Registering with MAC interface module\n");
1319 1320 1321 1322 1323 1324
      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");
1325 1326 1327 1328
      eNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list   = eNB->rx_pdu_list;
      eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = eNB->crc_pdu_list;
      eNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = eNB->sr_pdu_list;
      eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list;
1329 1330
      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;
1331
      eNB->prach_energy_counter = 0;
1332 1333
    }

1334
  }
1335

1336
  LOG_I(PHY,"[lte-softmodem.c] eNB structure allocated\n");
1337 1338 1339
}


1340
void stop_eNB(int nb_inst) {
1341

1342
  for (int inst=0;inst<nb_inst;inst++) {
1343
    LOG_I(PHY,"Killing eNB %d processing threads\n",inst);
1344 1345
    kill_eNB_proc(inst);
  }
1346
}