lte-enb.c 45.6 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 (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
extern PARALLEL_CONF_t get_thread_parallel_conf(void);
extern WORKER_CONF_t   get_thread_worker_conf(void);
154

155 156 157 158 159 160
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
161

162

163
static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name) {
Raymond Knopp's avatar
Raymond Knopp committed
164
  start_meas(&softmodem_stats_rxtx_sf);
165
  //L1_rxtx_proc_t *L1_proc_tx = &eNB->proc.L1_proc_tx;
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 203 204
  // *******************************************************************

  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
205 206
  // ****************************************
  // Common RX procedures subframe n
207

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

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

  release_UE_in_freeList(eNB->Mod_id);

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

  pthread_mutex_lock(&eNB->UL_INFO_mutex);
227

228 229 230 231
  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;
232

233
  eNB->if_inst->UL_indication(&eNB->UL_INFO);
234

235
  pthread_mutex_unlock(&eNB->UL_INFO_mutex);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
236 237
  /* this conflict resolution may be totally wrong, to be tested */
  /* CONFLICT RESOLUTION: BEGIN */
238
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER , 0 );
239
  if(oai_exit) return(-1);
240
  if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD){
Wang Tsu-Han's avatar
Wang Tsu-Han committed
241
#ifndef PHY_TX_THREAD
242
    phy_procedures_eNB_TX(eNB, proc, 1);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
243
#endif
244
  }
Wang Tsu-Han's avatar
Wang Tsu-Han committed
245 246 247
  /* 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
248 249

  stop_meas( &softmodem_stats_rxtx_sf );
250 251 252 253

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

  LOG_D(PHY, "rxtx:%lld nfapi:%lld phy:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ",
laurent's avatar
laurent committed
254
      softmodem_stats_rxtx_sf.p_time, nfapi_meas.p_time,
255 256 257 258
      TICK_TO_US(eNB->phy_proc),
      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
259 260
      TICK_TO_US(eNB->ofdm_mod_stats)
      );
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 289 290 291
  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
292 293 294 295
  
  return(0);
}

296

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

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

Wang Tsu-Han's avatar
Wang Tsu-Han committed
312
    if (wait_on_condition(&proc->mutex,&proc->cond,&proc->instance_cnt,thread_name)<0) break;
313 314 315 316 317 318
    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)
    // *****************************************
319 320 321 322
    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);
323
    
324
    phy_procedures_eNB_TX(eNB, proc, 1);
325

Wang Tsu-Han's avatar
Wang Tsu-Han committed
326
    pthread_mutex_lock( &proc->mutex );
327
    proc->instance_cnt = -1;
328
    // the thread can now be woken up
Wang Tsu-Han's avatar
Wang Tsu-Han committed
329
    if (pthread_cond_signal(&proc->cond) != 0) {
330 331 332
      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
333
    pthread_mutex_unlock( &proc->mutex );
Wang Tsu-Han's avatar
Wang Tsu-Han committed
334
    wakeup_txfh(proc,eNB);
335 336 337 338 339
  }

  return 0;
}

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

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

348
  static int eNB_thread_rxtx_status;
349 350
  //L1_proc_t *eNB_proc  = (L1_proc_t*)param;
  L1_rxtx_proc_t *proc;
351 352 353

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


362
  PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id];
363

Raymond Knopp's avatar
Raymond Knopp committed
364 365
  char thread_name[100];

366 367
  cpu_set_t cpuset;
  CPU_ZERO(&cpuset);
368

369
  // set default return value
370
  eNB_thread_rxtx_status = 0;
371 372


Wang Tsu-Han's avatar
Wang Tsu-Han committed
373
  sprintf(thread_name,"RXn_TXnp4_%d\n",&eNB->proc.L1_proc == proc ? 0 : 1);
374 375 376
  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));
377

378

379

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

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

388
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_CPUID_ENB_THREAD_RXTX,sched_getcpu());
389
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 1 );
390 391 392 393 394 395
   
    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);
 
396

397 398
    if (oai_exit) break;

399
    if (eNB->CC_id==0)
400
    {
401
      if (rxtx(eNB,proc,thread_name) < 0) break;
402
    }
403

404
    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
405
    if (release_thread(&proc->mutex,&proc->instance_cnt,thread_name)<0) break;
Wang Tsu-Han's avatar
Wang Tsu-Han committed
406
    if (nfapi_mode!=2){
Wang Tsu-Han's avatar
Wang Tsu-Han committed
407
    	if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)      wakeup_tx(eNB);
408
    	else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT)     wakeup_txfh(proc,eNB);
409
    }
410

Raymond Knopp's avatar
Raymond Knopp committed
411
  } // while !oai_exit
412

413
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
414

415
  LOG_D(PHY, " *** Exiting eNB thread RXn_TXnp4\n");
416

417 418
  eNB_thread_rxtx_status = 0;
  return &eNB_thread_rxtx_status;
419 420
}

421
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
422
{
423 424
  L1_proc_t *proc           = &eNB->proc;
  L1_rxtx_proc_t *L1_proc = &proc->L1_proc;
Raymond Knopp's avatar
Raymond Knopp committed
425 426
  LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
  RU_proc_t *ru_proc=&ru->proc;
427

428 429
  proc->frame_rx    = frame_rx;
  proc->subframe_rx = subframe_rx;
Raymond Knopp's avatar
Raymond Knopp committed
430

Cedric Roux's avatar
Cedric Roux committed
431
  if (!oai_exit) {
432
    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
433

Wang Tsu-Han's avatar
Wang Tsu-Han committed
434 435 436 437 438
    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
439

Wang Tsu-Han's avatar
Wang Tsu-Han committed
440 441 442 443
    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;
444
  }
Raymond Knopp's avatar
Raymond Knopp committed
445 446
}

447
int wakeup_txfh(L1_rxtx_proc_t *proc,PHY_VARS_eNB *eNB) {
Wang Tsu-Han's avatar
Wang Tsu-Han committed
448 449 450 451 452

  RU_t *ru;
  RU_proc_t *ru_proc;


453 454 455
  struct timespec wait;
  wait.tv_sec=0;
  wait.tv_nsec=5000000L;
Wang Tsu-Han's avatar
Wang Tsu-Han committed
456

457
  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
458
    LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", proc->frame_tx, proc->subframe_tx);
459
    return(-1);
460
  }
Wang Tsu-Han's avatar
Wang Tsu-Han committed
461 462 463
  pthread_mutex_lock(&eNB->proc.mutex_RU_tx);
  eNB->proc.RU_mask_tx = 0;
  pthread_mutex_unlock(&eNB->proc.mutex_RU_tx);
464
  if (release_thread(&proc->mutex_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) return(-1);
465

Wang Tsu-Han's avatar
Wang Tsu-Han committed
466 467 468 469 470 471 472 473 474 475 476 477 478 479
  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);
    }

480
    ru_proc->instance_cnt_eNBs = 0;
Wang Tsu-Han's avatar
Wang Tsu-Han committed
481 482 483
    ru_proc->timestamp_tx = proc->timestamp_tx;
    ru_proc->subframe_tx  = proc->subframe_tx;
    ru_proc->frame_tx     = proc->frame_tx;
484

485
  
Wang Tsu-Han's avatar
Wang Tsu-Han committed
486 487 488 489 490 491
    // 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);
    }
492
  
Wang Tsu-Han's avatar
Wang Tsu-Han committed
493 494
    pthread_mutex_unlock( &ru_proc->mutex_eNBs );
  }
495 496 497 498

  return(0);
}

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

501
  L1_proc_t *proc=&eNB->proc;
502

503 504
  L1_rxtx_proc_t *L1_proc_tx = &proc->L1_proc_tx;
  L1_rxtx_proc_t *L1_proc    = &proc->L1_proc;
505 506 507 508 509 510

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

521
  L1_proc_tx->instance_cnt = 0;
522 523

  
Wang Tsu-Han's avatar
Wang Tsu-Han committed
524 525 526 527 528
  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;
529 530
  
  // the thread can now be woken up
Wang Tsu-Han's avatar
Wang Tsu-Han committed
531
  if (pthread_cond_signal(&L1_proc_tx->cond) != 0) {
532
    LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
533 534 535 536
    exit_fun( "ERROR pthread_cond_signal" );
    return(-1);
  }
  
Wang Tsu-Han's avatar
Wang Tsu-Han committed
537
  pthread_mutex_unlock( &L1_proc_tx->mutex);
538 539 540

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

542 543
int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {

544
  L1_proc_t *proc=&eNB->proc;
545
  RU_proc_t *ru_proc=&ru->proc;
546

547
  L1_rxtx_proc_t *L1_proc=&proc->L1_proc;
548
  
549 550

  LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
551 552 553 554

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




577 578
  wait.tv_sec=0;
  wait.tv_nsec=5000000L;
579

Wang Tsu-Han's avatar
Wang Tsu-Han committed
580 581 582
    
  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);
583 584 585
    return(-1);
  }

Cedric Roux's avatar
Cedric Roux committed
586
  // wake up TX for subframe n+sf_ahead
587
  // lock the TX mutex and make sure the thread is ready
Wang Tsu-Han's avatar
Wang Tsu-Han committed
588 589
  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 );
590 591 592 593
    exit_fun( "error locking mutex_rxtx" );
    return(-1);
  }
  
594

Wang Tsu-Han's avatar
Wang Tsu-Han committed
595
  ++L1_proc->instance_cnt;
596 597 598 599 600
  
  // 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, 
601 602
  // 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
603 604 605 606 607
  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;
608

609
  // the thread can now be woken up
Wang Tsu-Han's avatar
Wang Tsu-Han committed
610
  if (pthread_cond_signal(&L1_proc->cond) != 0) {
611 612 613 614 615
    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
616
  pthread_mutex_unlock( &L1_proc->mutex);
617 618 619 620

  return(0);
}

621
void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) {
622

623
  L1_proc_t *proc = &eNB->proc;
624
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
625
  int i;
626

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

}

680
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
681 682
void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) {

683
  L1_proc_t *proc = &eNB->proc;
684 685 686 687 688 689 690
  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
691
	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);
692 693 694 695 696 697 698 699
	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
700
      return;
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 738 739 740
    }
    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
741

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

750 751

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

754 755 756
  // set default return value
  eNB_thread_prach_status = 0;

757
  thread_top_init("eNB_thread_prach",1,500000,1000000,20000000);
758

759
  //wait_sync("eNB_thread_prach");
760

761 762 763
  while (!oai_exit) {
    

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

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

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

780 781
  eNB_thread_prach_status = 0;
  return &eNB_thread_prach_status;
782 783
}

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

  // set default return value
  eNB_thread_prach_status = 0;

800
  thread_top_init("eNB_thread_prach_br",1,500000,1000000,20000000);
801 802 803 804 805 806

  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;
807
    if (oai_exit) break;
808 809 810 811 812 813 814 815 816 817 818 819 820 821

    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
822

Raymond Knopp's avatar
Raymond Knopp committed
823

824

Wang Tsu-Han's avatar
Wang Tsu-Han committed
825
extern void init_td_thread(PHY_VARS_eNB *);
Eurecom's avatar
Eurecom committed
826
extern void init_te_thread(PHY_VARS_eNB *);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
827 828
extern void kill_td_thread(PHY_VARS_eNB *);
extern void kill_te_thread(PHY_VARS_eNB *);
829

830
static void* process_stats_thread(void* param) {
831 832 833

  PHY_VARS_eNB     *eNB      = (PHY_VARS_eNB*)param;

834
  wait_sync("process_stats_thread");
835 836

  while (!oai_exit) {
Wang Tsu-Han's avatar
Wang Tsu-Han committed
837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853
    sleep(1);
      if (opp_enabled == 1) {
        if (eNB->td) print_meas(&eNB->ulsch_decoding_stats,"ulsch_decoding",NULL,NULL);
        if (eNB->te)
        {
          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);
       }
854
       print_meas(&eNB->dlsch_modulation_stats,"dlsch_modulation",NULL,NULL);
855 856 857 858 859
     }
  }
  return(NULL);
}

860

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

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

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

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

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

899
    pthread_mutex_init( &eNB->UL_INFO_mutex, NULL);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
900 901 902 903
    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);
904 905 906 907
    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
908 909 910

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

915
    pthread_cond_init( &proc->cond_prach, NULL);
916
    pthread_cond_init( &proc->cond_asynch_rxtx, NULL);
917 918 919

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

Raymond Knopp's avatar
Raymond Knopp committed
938 939
    //    attr_td     = &proc->attr_td;
    //    attr_te     = &proc->attr_te; 
Raymond Knopp's avatar
Raymond Knopp committed
940
#endif
Wang Tsu-Han's avatar
Wang Tsu-Han committed
941

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


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

951
    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
952 953
      pthread_create( &L1_proc->pthread, attr0, L1_thread, proc );
      pthread_create( &L1_proc_tx->pthread, attr1, L1_thread_tx, proc);
954
    }
955
    pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, eNB );
956
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
957 958
    pthread_create( &proc->pthread_prach_br, attr_prach_br, eNB_thread_prach_br, eNB );
#endif
959 960

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

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

965
    
966
  }
967

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

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

977 978 979 980 981 982 983
     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);
     }
     }
     }
  */
984

985 986 987 988
  /* 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;
989 990
  
  
991 992
}

993

994

995 996 997
/*!
 * \brief Terminate eNB TX and RX threads.
 */
998
void kill_eNB_proc(int inst) {
999

1000
  int *status;
1001
  PHY_VARS_eNB *eNB;
1002 1003
  L1_proc_t *proc;
  L1_rxtx_proc_t *L1_proc, *L1_proc_tx;
1004

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

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

1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028
    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
1029

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

1035
    pthread_cond_signal( &proc->cond_asynch_rxtx );
1036
    pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx);
Raymond Knopp's avatar
Raymond Knopp committed
1037

1038
    LOG_D(PHY, "joining pthread_prach\n");
1039
    pthread_join( proc->pthread_prach, (void**)&status );    
1040

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

    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 );
1059
    }
Wang Tsu-Han's avatar
Wang Tsu-Han committed
1060 1061 1062
    LOG_I(PHY, "Destroying L1_proc mutex/cond\n");
    pthread_mutex_destroy( &L1_proc->mutex );
    pthread_cond_destroy( &L1_proc->cond );
1063 1064
    pthread_mutex_destroy( &L1_proc->mutex_RUs );
    pthread_cond_destroy( &L1_proc->cond_RUs );
Wang Tsu-Han's avatar
Wang Tsu-Han committed
1065 1066 1067
    LOG_I(PHY, "Destroying L1_proc_tx mutex/cond\n");
    pthread_mutex_destroy( &L1_proc_tx->mutex );
    pthread_cond_destroy( &L1_proc_tx->cond );
1068 1069
    pthread_mutex_destroy( &L1_proc_tx->mutex_RUs );
    pthread_cond_destroy( &L1_proc_tx->cond_RUs );
Robert Schmidt's avatar
Robert Schmidt committed
1070 1071 1072

    pthread_attr_destroy(&proc->attr_prach);
    pthread_attr_destroy(&proc->attr_asynch_rxtx);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
1073 1074
    pthread_attr_destroy(&L1_proc->attr);
    pthread_attr_destroy(&L1_proc_tx->attr);
Robert Schmidt's avatar
Robert Schmidt committed
1075 1076 1077 1078 1079
#ifdef Rel14
    pthread_mutex_destroy(&proc->mutex_RU_PRACH_br);
    pthread_attr_destroy(&proc->attr_prach_br);
#endif

1080
  }
1081 1082
}

1083

1084 1085 1086


void reset_opp_meas(void) {
1087

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

1098

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

1111 1112 1113 1114 1115 1116
void free_transport(PHY_VARS_eNB *eNB)
{
  int i;
  int j;

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

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

1126
void init_transport(PHY_VARS_eNB *eNB) {
1127

1128 1129 1130
  int i;
  int j;
  LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
1131

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

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

void init_eNB_afterRU(void) {
1192

1193 1194
  int inst,CC_id,ru_id,i,aa;
  PHY_VARS_eNB *eNB;
1195

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

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

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

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

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

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

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

1223 1224
      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;
1225 1226 1227 1228 1229 1230 1231 1232 1233

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

1234 1235
	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
1236
	  eNB->prach_vars.rxsigF[0][aa]    =  eNB->RU_list[ru_id]->prach_rxsigF[i];
1237
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
Raymond Knopp's avatar
Raymond Knopp committed
1238 1239 1240
	  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
1241 1242 1243
	  eNB->common_vars.rxdataF[aa]     =  eNB->RU_list[ru_id]->common.rxdataF[i];
	}
      }
1244 1245 1246



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

      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
1268
        //LOG_I(PHY," Delete code\n");
1269 1270 1271 1272 1273
      }




1274 1275 1276
      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);
1277 1278

      init_transport(eNB);
Raymond Knopp's avatar
Raymond Knopp committed
1279
      //init_precoding_weights(RC.eNB[inst][CC_id]);
1280 1281 1282
    }
    init_eNB_proc(inst);
  }
1283

1284
  for (ru_id=0;ru_id<RC.nb_RU;ru_id++) {
1285 1286

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

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

1303 1304
  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]);

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

1315

1316
      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
1317
#ifndef OCP_FRAMEWORK
1318
      LOG_I(PHY,"Initializing eNB %d CC_id %d\n",inst,CC_id);
laurent's avatar
laurent committed
1319
#endif
Raymond Knopp's avatar
Raymond Knopp committed
1320 1321


1322 1323
      eNB->td                   = ulsch_decoding_data_all;
      eNB->te                   = dlsch_encoding_all;
1324

1325
      
1326
      LOG_I(PHY,"Registering with MAC interface module\n");
1327 1328 1329 1330 1331 1332
      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");
1333 1334 1335 1336
      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;
1337 1338
      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;
1339
      eNB->prach_energy_counter = 0;
1340 1341
    }

1342
  }
1343

1344
  LOG_I(PHY,"[lte-softmodem.c] eNB structure allocated\n");
1345 1346 1347
}


1348
void stop_eNB(int nb_inst) {
1349

1350
  for (int inst=0;inst<nb_inst;inst++) {
1351
    LOG_I(PHY,"Killing eNB %d processing threads\n",inst);
1352 1353
    kill_eNB_proc(inst);
  }
1354
}