lte-enb.c 46.3 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
Cedric Roux's avatar
Cedric Roux committed
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

knopp's avatar
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

#ifndef OPENAIR2
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
80
  #include "UTIL/OTG/otg_extern.h"
81 82 83
#endif

#if defined(ENABLE_ITTI)
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
84 85 86 87 88 89
  #if defined(ENABLE_USE_MME)
    #include "s1ap_eNB.h"
    #ifdef PDCP_USE_NETLINK
      #include "SIMULATION/ETH_TRANSPORT/proto.h"
    #endif
  #endif
90 91
#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

knopp's avatar
knopp committed
107

108
#if defined(ENABLE_ITTI)
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
109 110
  extern volatile int             start_eNB;
  extern volatile int             start_UE;
111 112 113
#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
knopp's avatar
knopp committed
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

146
int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
147
int wakeup_txfh(eNB_rxtx_proc_t *proc,RU_proc_t *ru_proc);
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))
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
150
  void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe);
151
#endif
Wang Tsu-Han's avatar
Wang Tsu-Han committed
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)
knopp's avatar
knopp committed
161

162

knopp's avatar
knopp committed
163 164
static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_name) {
  start_meas(&softmodem_stats_rxtx_sf);
165

166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
  // *******************************************************************

  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
       ) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
185 186 187 188 189 190 191 192
      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);
193 194 195 196 197 198 199 200
    }
  }

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

knopp's avatar
knopp committed
201 202
  // ****************************************
  // Common RX procedures subframe n
Cedric Roux's avatar
Cedric Roux committed
203 204
  T(T_ENB_PHY_DL_TICK, T_INT(eNB->Mod_id), T_INT(proc->frame_tx), T_INT(proc->subframe_tx));

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

  release_UE_in_freeList(eNB->Mod_id);

knopp's avatar
knopp committed
215
  // UE-specific RX processing for subframe n
216
  if (nfapi_mode == 0 || nfapi_mode == 1) {
217
    phy_procedures_eNB_uespec_RX(eNB, proc);
218
  }
219

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
220 221 222
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, 1 );

  if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
WANG Tsu-Han's avatar
WANG Tsu-Han committed
223 224 225 226
    if(wait_on_condition(&proc[1].mutex_rxtx,&proc[1].cond_rxtx,&proc[1].pipe_ready,"wakeup_tx")<0) {
      LOG_E(PHY,"Frame %d, subframe %d: TX1 not ready\n",proc[1].frame_rx,proc[1].subframe_rx);
      return(-1);
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
227

WANG Tsu-Han's avatar
WANG Tsu-Han committed
228
    if (release_thread(&proc[1].mutex_rxtx,&proc[1].pipe_ready,"wakeup_tx")<0)  return(-1);
229 230
  }

231
  pthread_mutex_lock(&eNB->UL_INFO_mutex);
232 233 234 235 236
  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;
  eNB->if_inst->UL_indication(&eNB->UL_INFO);
237
  pthread_mutex_unlock(&eNB->UL_INFO_mutex);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
238 239
  /* this conflict resolution may be totally wrong, to be tested */
  /* CONFLICT RESOLUTION: BEGIN */
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
240 241
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, 0 );

242
  if(oai_exit) return(-1);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
243 244

  if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) {
Wang Tsu-Han's avatar
Wang Tsu-Han committed
245
#ifndef PHY_TX_THREAD
246
    phy_procedures_eNB_TX(eNB, proc, 1);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
247
#endif
248
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
249

Wang Tsu-Han's avatar
Wang Tsu-Han committed
250 251 252
  /* 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 */
knopp's avatar
knopp committed
253
  stop_meas( &softmodem_stats_rxtx_sf );
254
  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);
255
  LOG_D(PHY, "rxtx:%lld nfapi:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ",
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
256 257 258 259 260 261
        softmodem_stats_rxtx_sf.p_time, nfapi_meas.p_time,
        TICK_TO_US(eNB->phy_proc_tx),
        TICK_TO_US(eNB->phy_proc_rx),
        TICK_TO_US(eNB->rx_prach),
        TICK_TO_US(eNB->ofdm_mod_stats)
       );
262
  LOG_D(PHY,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
263 264 265 266 267 268 269 270
        "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));
271
  LOG_D(PHY," ulsch[ch:%lld freq:%lld dec:%lld demod:%lld ru:%lld ",
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
272 273 274 275 276
        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));
277
  LOG_D(PHY, "td:%lld dei:%lld dem:%lld llr:%lld tci:%lld ",
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
278 279 280 281 282 283 284 285 286 287 288 289 290
        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)
       );
knopp's avatar
knopp committed
291 292 293
  return(0);
}

294

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
295 296
static void *tx_thread(void *param) {
  eNB_proc_t *eNB_proc  = (eNB_proc_t *)param;
297 298 299
  eNB_rxtx_proc_t *proc = &eNB_proc->proc_rxtx[1];
  PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id];
  char thread_name[100];
300
  sprintf(thread_name,"TXnp4_%d\n",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
301
  thread_top_init(thread_name,1,470000,500000,500000);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
302

303
  //wait_sync("tx_thread");
304

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
305
  while (!oai_exit) {
306
    if (wait_on_condition(&proc->mutex_rxtx,&proc->cond_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
307 308 309

    if (oai_exit) break;

310 311 312 313 314
    // *****************************************
    // 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)
    // *****************************************
315 316 317 318
    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);
319
    phy_procedures_eNB_TX(eNB, proc, 1);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
320

321
    if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
322

323 324
    pthread_mutex_lock( &proc->mutex_rxtx );
    proc->pipe_ready++;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
325

326 327 328 329 330
    // the thread can now be woken up
    if (pthread_cond_signal(&proc->cond_rxtx) != 0) {
      LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
      exit_fun( "ERROR pthread_cond_signal" );
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
331

332
    pthread_mutex_unlock( &proc->mutex_rxtx );
Wang Tsu-Han's avatar
Wang Tsu-Han committed
333
    wakeup_txfh(proc,eNB_proc->ru_proc);
334 335 336 337 338
  }

  return 0;
}

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

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
345
static void *eNB_thread_rxtx( void *param ) {
knopp's avatar
knopp committed
346
  static int eNB_thread_rxtx_status;
347 348 349 350
  //eNB_proc_t *eNB_proc  = (eNB_proc_t*)param;
  eNB_rxtx_proc_t *proc;

  // Working
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
351 352 353 354 355
  if(nfapi_mode ==2) {
    proc = (eNB_rxtx_proc_t *)param;
  } else {
    eNB_proc_t *eNB_proc  = (eNB_proc_t *)param;
    proc = &eNB_proc->proc_rxtx[0];
356 357
  }

358
  PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id];
359
  //RU_proc_t *ru_proc = NULL;
knopp's avatar
knopp committed
360
  char thread_name[100];
361 362
  cpu_set_t cpuset;
  CPU_ZERO(&cpuset);
363
  // set default return value
knopp's avatar
knopp committed
364
  eNB_thread_rxtx_status = 0;
knopp's avatar
knopp committed
365
  sprintf(thread_name,"RXn_TXnp4_%d\n",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
366 367 368
  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));
369 370

  while (!oai_exit) {
knopp's avatar
knopp committed
371
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
372
    T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
373

knopp's avatar
knopp committed
374
    if (wait_on_condition(&proc->mutex_rxtx,&proc->cond_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break;
375

376
    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_CPUID_ENB_THREAD_RXTX,sched_getcpu());
knopp's avatar
knopp committed
377
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 1 );
378 379 380 381
    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);
382

383 384
    if (oai_exit) break;

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
385
    if (eNB->CC_id==0) {
386
      if (rxtx(eNB,proc,thread_name) < 0) break;
387
    }
388 389

    if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
390

391 392
    pthread_mutex_lock( &proc->mutex_rxtx );
    proc->pipe_ready++;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
393

394 395 396 397 398
    // the thread can now be woken up
    if (pthread_cond_signal(&proc->cond_rxtx) != 0) {
      LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
      exit_fun( "ERROR pthread_cond_signal" );
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
399

400
    pthread_mutex_unlock( &proc->mutex_rxtx );
401

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
402 403 404 405 406 407 408
    if (nfapi_mode!=2) {
      if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)      wakeup_tx(eNB,eNB->proc.ru_proc);
      else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) {
        phy_procedures_eNB_TX(eNB, proc, 1);
        wakeup_txfh(proc,eNB->proc.ru_proc);
      }
    }
knopp's avatar
knopp committed
409
  } // while !oai_exit
410

knopp's avatar
knopp committed
411
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
412
  LOG_D(PHY, " *** Exiting eNB thread RXn_TXnp4\n");
knopp's avatar
knopp committed
413 414
  eNB_thread_rxtx_status = 0;
  return &eNB_thread_rxtx_status;
415 416
}

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
417
void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t *ru) {
418 419
  eNB_proc_t *proc           = &eNB->proc;
  eNB_rxtx_proc_t *proc_rxtx = &proc->proc_rxtx[0];
knopp's avatar
knopp committed
420 421
  LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
  RU_proc_t *ru_proc=&ru->proc;
422 423
  proc->frame_rx    = frame_rx;
  proc->subframe_rx = subframe_rx;
knopp's avatar
knopp committed
424

Cedric Roux's avatar
Cedric Roux committed
425
  if (!oai_exit) {
426
    T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
knopp's avatar
knopp committed
427 428 429 430 431
    proc_rxtx->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_tti);
    proc_rxtx->frame_rx     = ru_proc->frame_rx;
    proc_rxtx->subframe_rx  = ru_proc->subframe_rx;
    proc_rxtx->frame_tx     = (proc_rxtx->subframe_rx > (9-sf_ahead)) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx;
    proc_rxtx->subframe_tx  = (proc_rxtx->subframe_rx + sf_ahead)%10;
knopp's avatar
knopp committed
432

433
    if (rxtx(eNB,proc_rxtx,string) < 0) LOG_E(PHY,"eNB %d CC_id %d failed during execution\n",eNB->Mod_id,eNB->CC_id);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
434

knopp's avatar
knopp committed
435 436 437
    ru_proc->timestamp_tx = proc_rxtx->timestamp_tx;
    ru_proc->subframe_tx  = proc_rxtx->subframe_tx;
    ru_proc->frame_tx     = proc_rxtx->frame_tx;
438
  }
knopp's avatar
knopp committed
439 440
}

Wang Tsu-Han's avatar
Wang Tsu-Han committed
441
int wakeup_txfh(eNB_rxtx_proc_t *proc,RU_proc_t *ru_proc) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
442 443 444
  if(ru_proc == NULL)
    return(0);

445 446 447
  struct timespec wait;
  wait.tv_sec=0;
  wait.tv_nsec=5000000L;
Wang Tsu-Han's avatar
Wang Tsu-Han committed
448

449 450 451
  if(wait_on_condition(&ru_proc->mutex_eNBs,&ru_proc->cond_eNBs,&ru_proc->ru_tx_ready,"wakeup_txfh")<0) {
    LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", ru_proc->frame_tx, ru_proc->subframe_tx);
    return(-1);
452
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
453

454
  if (release_thread(&ru_proc->mutex_eNBs,&ru_proc->ru_tx_ready,"wakeup_txfh")<0) return(-1);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
455

456
  if (ru_proc->instance_cnt_eNBs == 0) {
Wang Tsu-Han's avatar
Wang Tsu-Han committed
457
    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);
458 459
    return(-1);
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
460

461 462 463 464 465 466
  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);
  }

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
467 468 469 470 471
  ++ru_proc->instance_cnt_eNBs;
  ru_proc->timestamp_tx = proc->timestamp_tx;
  ru_proc->subframe_tx  = proc->subframe_tx;
  ru_proc->frame_tx     = proc->frame_tx;

472 473 474 475 476 477 478
  // 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);
  }

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
479
  pthread_mutex_unlock( &ru_proc->mutex_eNBs );
480 481 482
  return(0);
}

483 484
int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc) {
  eNB_proc_t *proc=&eNB->proc;
485 486
  eNB_rxtx_proc_t *proc_rxtx1=&proc->proc_rxtx[1];//*proc_rxtx=&proc->proc_rxtx[proc->frame_rx&1];
  eNB_rxtx_proc_t *proc_rxtx0=&proc->proc_rxtx[0];
487 488 489
  struct timespec wait;
  wait.tv_sec=0;
  wait.tv_nsec=5000000L;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
490

491 492
  if (proc_rxtx1->instance_cnt_rxtx == 0) {
    LOG_E(PHY,"Frame %d, subframe %d: TX1 thread busy, dropping\n",proc_rxtx1->frame_rx,proc_rxtx1->subframe_rx);
493 494
    return(-1);
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
495

496 497
  if (pthread_mutex_timedlock(&proc_rxtx1->mutex_rxtx,&wait) != 0) {
    LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", proc_rxtx1->subframe_rx&1,proc_rxtx1->instance_cnt_rxtx );
498
    exit_fun( "error locking mutex_tx" );
499 500 501
    return(-1);
  }

502 503 504 505 506 507
  ++proc_rxtx1->instance_cnt_rxtx;
  proc_rxtx1->subframe_rx   = proc_rxtx0->subframe_rx;
  proc_rxtx1->frame_rx      = proc_rxtx0->frame_rx;
  proc_rxtx1->subframe_tx   = proc_rxtx0->subframe_tx;
  proc_rxtx1->frame_tx      = proc_rxtx0->frame_tx;
  proc_rxtx1->timestamp_tx  = proc_rxtx0->timestamp_tx;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
508

509
  // the thread can now be woken up
510
  if (pthread_cond_signal(&proc_rxtx1->cond_rxtx) != 0) {
511
    LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
512 513 514 515
    exit_fun( "ERROR pthread_cond_signal" );
    return(-1);
  }

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
516
  pthread_mutex_unlock( &proc_rxtx1->mutex_rxtx );
517 518
  return(0);
}
knopp's avatar
knopp committed
519

520 521
int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {
  eNB_proc_t *proc=&eNB->proc;
522
  RU_proc_t *ru_proc=&ru->proc;
Wang Tsu-Han's avatar
Wang Tsu-Han committed
523
  eNB_rxtx_proc_t *proc_rxtx0=&proc->proc_rxtx[0];
Wang Tsu-Han's avatar
Wang Tsu-Han committed
524
  //eNB_rxtx_proc_t *proc_rxtx1=&proc->proc_rxtx[1];
525
  LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
526 527
  int i;
  struct timespec wait;
528
  pthread_mutex_lock(&proc->mutex_RU);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
529 530

  for (i=0; i<eNB->num_RU; i++) {
531 532
    if (ru == eNB->RU_list[i]) {
      if ((proc->RU_mask&(1<<i)) > 0)
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
533 534 535
        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);

536 537 538
      proc->RU_mask |= (1<<i);
    }
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
539

540
  if (proc->RU_mask != (1<<eNB->num_RU)-1) {  // not all RUs have provided their information so return
541
    LOG_E(PHY,"Not all RUs have provided their info\n");
542 543
    pthread_mutex_unlock(&proc->mutex_RU);
    return(0);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
544
  } else { // all RUs have provided their information so continue on and wakeup eNB processing
545 546 547 548
    proc->RU_mask = 0;
    pthread_mutex_unlock(&proc->mutex_RU);
  }

549 550
  wait.tv_sec=0;
  wait.tv_nsec=5000000L;
551 552 553 554

  if(wait_on_condition(&proc_rxtx0->mutex_rxtx,&proc_rxtx0->cond_rxtx,&proc_rxtx0->pipe_ready,"wakeup_rxtx")<0) {
    LOG_E(PHY,"Frame %d, subframe %d: RXTX0 not ready\n",proc_rxtx0->frame_rx,proc_rxtx0->subframe_rx);
    return(-1);
555
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
556

557
  if (release_thread(&proc_rxtx0->mutex_rxtx,&proc_rxtx0->pipe_ready,"wakeup_rxtx")<0) return(-1);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
558

559 560
  if (proc_rxtx0->instance_cnt_rxtx == 0) {
    LOG_E(PHY,"Frame %d, subframe %d: RXTX0 thread busy, dropping\n",proc_rxtx0->frame_rx,proc_rxtx0->subframe_rx);
561 562 563
    return(-1);
  }

Cedric Roux's avatar
Cedric Roux committed
564
  // wake up TX for subframe n+sf_ahead
565
  // lock the TX mutex and make sure the thread is ready
566 567
  if (pthread_mutex_timedlock(&proc_rxtx0->mutex_rxtx,&wait) != 0) {
    LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", proc_rxtx0->subframe_rx&1,proc_rxtx0->instance_cnt_rxtx );
568 569 570
    exit_fun( "error locking mutex_rxtx" );
    return(-1);
  }
571

572
  ++proc_rxtx0->instance_cnt_rxtx;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
573 574
  // 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
575
  // transmitted timestamp of the next TX slot (first).
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
576
  // The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
577 578
  // 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
579 580 581 582 583
  proc_rxtx0->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_tti);
  proc_rxtx0->frame_rx     = ru_proc->frame_rx;
  proc_rxtx0->subframe_rx  = ru_proc->subframe_rx;
  proc_rxtx0->frame_tx     = (proc_rxtx0->subframe_rx > (9-sf_ahead)) ? (proc_rxtx0->frame_rx+1)&1023 : proc_rxtx0->frame_rx;
  proc_rxtx0->subframe_tx  = (proc_rxtx0->subframe_rx + sf_ahead)%10;
584

585
  // the thread can now be woken up
586
  if (pthread_cond_signal(&proc_rxtx0->cond_rxtx) != 0) {
587 588 589 590 591
    LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n");
    exit_fun( "ERROR pthread_cond_signal" );
    return(-1);
  }

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
592
  pthread_mutex_unlock( &proc_rxtx0->mutex_rxtx );
593 594 595
  return(0);
}

596
void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) {
knopp's avatar
knopp committed
597 598
  eNB_proc_t *proc = &eNB->proc;
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
599
  int i;
knopp's avatar
knopp committed
600

601 602
  if (ru!=NULL) {
    pthread_mutex_lock(&proc->mutex_RU_PRACH);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
603 604

    for (i=0; i<eNB->num_RU; i++) {
605
      if (ru == eNB->RU_list[i]) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
606 607 608 609 610 611 612
        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);

        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",
                eNB->Mod_id,frame,subframe,ru->idx,eNB->num_RU,proc->RU_mask_prach);

        proc->RU_mask_prach |= (1<<i);
613 614
      }
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
615

616 617
    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);
knopp's avatar
knopp committed
618
      return;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
619
    } else { // all RUs have provided their information so continue on and wakeup eNB processing
620 621 622 623
      proc->RU_mask_prach = 0;
      pthread_mutex_unlock(&proc->mutex_RU_PRACH);
    }
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
624

knopp's avatar
knopp committed
625
  // check if we have to detect PRACH first
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
626
  if (is_prach_subframe(fp,frame,subframe)>0) {
627
    LOG_D(PHY,"Triggering prach processing, frame %d, subframe %d\n",frame,subframe);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
628

knopp's avatar
knopp committed
629
    if (proc->instance_cnt_prach == 0) {
630
      LOG_W(PHY,"[eNB] Frame %d Subframe %d, dropping PRACH\n", frame,subframe);
knopp's avatar
knopp committed
631 632
      return;
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
633

knopp's avatar
knopp committed
634 635 636 637 638 639
    // 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;
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
640

knopp's avatar
knopp committed
641 642
    ++proc->instance_cnt_prach;
    // set timing for prach thread
643 644
    proc->frame_prach = frame;
    proc->subframe_prach = subframe;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
645

knopp's avatar
knopp committed
646 647 648 649 650 651
    // 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;
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
652

knopp's avatar
knopp committed
653 654 655 656
    pthread_mutex_unlock( &proc->mutex_prach );
  }
}

657
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
658 659 660 661 662 663 664
void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) {
  eNB_proc_t *proc = &eNB->proc;
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
  int i;

  if (ru!=NULL) {
    pthread_mutex_lock(&proc->mutex_RU_PRACH_br);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
665 666

    for (i=0; i<eNB->num_RU; i++) {
667
      if (ru == eNB->RU_list[i]) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
668 669 670 671 672 673 674
        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);

        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);
675 676
      }
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
677

678 679
    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);
knopp's avatar
knopp committed
680
      return;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
681
    } else { // all RUs have provided their information so continue on and wakeup eNB processing
682 683 684 685
      proc->RU_mask_prach_br = 0;
      pthread_mutex_unlock(&proc->mutex_RU_PRACH_br);
    }
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
686

687
  // check if we have to detect PRACH first
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
688
  if (is_prach_subframe(fp,frame,subframe)>0) {
689
    LOG_D(PHY,"Triggering prach br processing, frame %d, subframe %d\n",frame,subframe);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
690

691 692 693
    if (proc->instance_cnt_prach_br == 0) {
      LOG_W(PHY,"[eNB] Frame %d Subframe %d, dropping PRACH BR\n", frame,subframe);
      return;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
694
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
695

696 697 698 699 700 701
    // 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;
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
702

703 704 705 706
    ++proc->instance_cnt_prach_br;
    // set timing for prach thread
    proc->frame_prach_br = frame;
    proc->subframe_prach_br = subframe;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
707

708 709 710 711 712 713
    // 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;
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
714

715 716 717 718
    pthread_mutex_unlock( &proc->mutex_prach_br );
  }
}
#endif
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
719 720


721 722 723 724 725 726 727 728 729 730 731 732
/*!
 * \brief The prach receive thread of eNB.
 * \param param is a \ref eNB_proc_t structure which contains the info what to process.
 * \returns a pointer to an int. The storage is not on the heap and must not be freed.
 */
static void *eNB_thread_prach( void *param ) {
  static int eNB_thread_prach_status;
  PHY_VARS_eNB *eNB= (PHY_VARS_eNB *)param;
  eNB_proc_t *proc = &eNB->proc;
  // set default return value
  eNB_thread_prach_status = 0;
  thread_top_init("eNB_thread_prach",1,500000,1000000,20000000);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
733

734
  //wait_sync("eNB_thread_prach");
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
735

736 737
  while (!oai_exit) {
    if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
738

739
    if (oai_exit) break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
740

741 742 743 744 745 746
    LOG_D(PHY,"Running eNB prach procedures\n");
    prach_procedures(eNB
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                     ,0
#endif
                    );
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
747

748 749
    if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break;
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
750

751 752 753 754
  LOG_I(PHY, "Exiting eNB thread PRACH\n");
  eNB_thread_prach_status = 0;
  return &eNB_thread_prach_status;
}
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
755

756 757 758 759 760 761 762 763 764 765 766 767 768
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
/*!
 * \brief The prach receive thread of eNB for BL/CE UEs.
 * \param param is a \ref eNB_proc_t structure which contains the info what to process.
 * \returns a pointer to an int. The storage is not on the heap and must not be freed.
 */
static void *eNB_thread_prach_br( void *param ) {
  static int eNB_thread_prach_status;
  PHY_VARS_eNB *eNB= (PHY_VARS_eNB *)param;
  eNB_proc_t *proc = &eNB->proc;
  // set default return value
  eNB_thread_prach_status = 0;
  thread_top_init("eNB_thread_prach_br",1,500000,1000000,20000000);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
769

770 771
  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;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
772

773
    if (oai_exit) break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
774

775 776
    LOG_D(PHY,"Running eNB prach procedures for BL/CE UEs\n");
    prach_procedures(eNB,1);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
777

778 779
    if (release_thread(&proc->mutex_prach_br,&proc->instance_cnt_prach_br,"eNB_prach_thread_br") < 0) break;
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
780

781 782 783 784
  LOG_I(PHY, "Exiting eNB thread PRACH BR\n");
  eNB_thread_prach_status = 0;
  return &eNB_thread_prach_status;
}
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
785

786
#endif
787 788


789

790 791 792 793
extern void init_td_thread(PHY_VARS_eNB *);
extern void init_te_thread(PHY_VARS_eNB *);
extern void kill_td_thread(PHY_VARS_eNB *);
extern void kill_te_thread(PHY_VARS_eNB *);
794

795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816
static void *process_stats_thread(void *param) {
  PHY_VARS_eNB     *eNB      = (PHY_VARS_eNB *)param;
  wait_sync("process_stats_thread");

  while (!oai_exit) {
    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);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
817
      }
818

819 820
      print_meas(&eNB->dlsch_modulation_stats,"dlsch_modulation",NULL,NULL);
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
821
  }
822 823 824 825 826 827 828 829 830 831 832 833

  return(NULL);
}


void init_eNB_proc(int inst) {
  /*int i=0;*/
  int CC_id;
  PHY_VARS_eNB *eNB;
  eNB_proc_t *proc;
  eNB_rxtx_proc_t *proc_rxtx;
  pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_prach=NULL;
834
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
835
  pthread_attr_t *attr_prach_br=NULL;
836
#endif
837
  LOG_I(PHY,"%s(inst:%d) RC.nb_CC[inst]:%d \n",__FUNCTION__,inst,RC.nb_CC[inst]);
knopp's avatar
knopp committed
838

839 840
  for (CC_id=0; CC_id<RC.nb_CC[inst]; CC_id++) {
    eNB = RC.eNB[inst][CC_id];
laurent's avatar
laurent committed
841
#ifndef OCP_FRAMEWORK
842
    LOG_I(PHY,"Initializing eNB processes instance:%d CC_id %d \n",inst,CC_id);
laurent's avatar
laurent committed
843
#endif
844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872
    proc = &eNB->proc;
    proc_rxtx                      = proc->proc_rxtx;
    proc_rxtx[0].instance_cnt_rxtx = -1;
    proc_rxtx[1].instance_cnt_rxtx = -1;
    proc_rxtx[0].pipe_ready        = 0;
    proc_rxtx[1].pipe_ready        = 0;
    proc->instance_cnt_prach       = -1;
    proc->instance_cnt_asynch_rxtx = -1;
    proc->instance_cnt_synch       = -1;
    proc->CC_id                    = CC_id;
    proc->first_rx=1;
    proc->first_tx=1;
    proc->RU_mask=0;
    proc->RU_mask_prach=0;
    pthread_mutex_init( &eNB->UL_INFO_mutex, NULL);
    pthread_mutex_init( &proc_rxtx[0].mutex_rxtx, NULL);
    pthread_mutex_init( &proc_rxtx[1].mutex_rxtx, NULL);
    pthread_cond_init( &proc_rxtx[0].cond_rxtx, NULL);
    pthread_cond_init( &proc_rxtx[1].cond_rxtx, NULL);
    pthread_mutex_init( &proc->mutex_prach, NULL);
    pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL);
    pthread_mutex_init( &proc->mutex_RU,NULL);
    pthread_mutex_init( &proc->mutex_RU_PRACH,NULL);
    pthread_cond_init( &proc->cond_prach, NULL);
    pthread_cond_init( &proc->cond_asynch_rxtx, NULL);
    pthread_attr_init( &proc->attr_prach);
    pthread_attr_init( &proc->attr_asynch_rxtx);
    pthread_attr_init( &proc_rxtx[0].attr_rxtx);
    pthread_attr_init( &proc_rxtx[1].attr_rxtx);
873
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
874 875 876 877 878 879
    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);
880
#endif
881
#ifndef DEADLINE_SCHEDULER
882 883 884
    attr0       = &proc_rxtx[0].attr_rxtx;
    attr1       = &proc_rxtx[1].attr_rxtx;
    attr_prach  = &proc->attr_prach;
885
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
886
    attr_prach_br  = &proc->attr_prach_br;
887
#endif
888 889
    //    attr_td     = &proc->attr_td;
    //    attr_te     = &proc->attr_te;
knopp's avatar
knopp committed
890
#endif
Wang Tsu-Han's avatar
Wang Tsu-Han committed
891

892 893 894 895
    if(get_thread_worker_conf() == WORKER_ENABLE) {
      init_te_thread(eNB);
      init_td_thread(eNB);
    }
knopp's avatar
knopp committed
896

897
    LOG_I(PHY,"eNB->single_thread_flag:%d\n", eNB->single_thread_flag);
knopp's avatar
knopp committed
898

899 900 901 902
    if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && nfapi_mode!=2) {
      pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, proc );
      pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, tx_thread, proc);
    }
903

904
    pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, eNB );
905
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
906
    pthread_create( &proc->pthread_prach_br, attr_prach_br, eNB_thread_prach_br, eNB );
907
#endif
908 909 910 911 912 913 914 915 916 917
    /*char name[16];
    if (eNB->single_thread_flag==0) {
      snprintf( name, sizeof(name), "RXTX0 %d", i );
      pthread_setname_np( proc_rxtx[0].pthread_rxtx, name );
      snprintf( name, sizeof(name), "RXTX1 %d", i );
      pthread_setname_np( proc_rxtx[1].pthread_rxtx, name );
    }*/
    AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach);

    if (opp_enabled == 1) pthread_create(&proc->process_stats_thread,NULL,process_stats_thread,(void *)eNB);
918
  }
919

920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941
  //for multiple CCs: setup master and slaves
  /*
     for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
     eNB = PHY_vars_eNB_g[inst][CC_id];

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

     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);
     }
     }
     }
  */
  /* 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;
}

Raymond Knopp's avatar
Raymond Knopp committed
942

943

944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984
/*!
 * \brief Terminate eNB TX and RX threads.
 */
void kill_eNB_proc(int inst) {
  int *status;
  PHY_VARS_eNB *eNB;
  eNB_proc_t *proc;
  eNB_rxtx_proc_t *proc_rxtx;
  int i;

  for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
    eNB=RC.eNB[inst][CC_id];
    proc = &eNB->proc;
    proc_rxtx = &proc->proc_rxtx[0];

    if(get_thread_worker_conf() == WORKER_ENABLE) {
      kill_td_thread(eNB);
      kill_te_thread(eNB);
    }

    LOG_I(PHY, "Killing TX CC_id %d inst %d\n", CC_id, inst );

    for (i=0; i<2; i++) {
      pthread_mutex_lock(&proc_rxtx[i].mutex_rxtx);
      proc_rxtx[i].instance_cnt_rxtx = 0;
      proc_rxtx[i].pipe_ready = 0;
      pthread_cond_signal(&proc_rxtx[i].cond_rxtx);
      pthread_mutex_unlock(&proc_rxtx[i].mutex_rxtx);
    }

    pthread_mutex_lock(&proc->mutex_prach);
    proc->instance_cnt_prach = 0;
    pthread_cond_signal( &proc->cond_prach );
    pthread_mutex_unlock(&proc->mutex_prach);
    pthread_cond_signal( &proc->cond_asynch_rxtx );
    pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx);
    LOG_D(PHY, "joining pthread_prach\n");
    pthread_join( proc->pthread_prach, (void **)&status );
    LOG_I(PHY, "Destroying prach mutex/cond\n");
    pthread_mutex_destroy( &proc->mutex_prach );
    pthread_cond_destroy( &proc->cond_prach );
985
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
986 987 988 989 990
    proc->instance_cnt_prach_br = 0;
    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
991
#endif
992 993 994 995 996 997 998 999 1000 1001
    LOG_I(PHY, "Destroying UL_INFO mutex\n");
    pthread_mutex_destroy(&eNB->UL_INFO_mutex);

    for (i=0; i<2; i++) {
      LOG_I(PHY, "Joining rxtx[%d] mutex/cond\n",i);
      pthread_join( proc_rxtx[i].pthread_rxtx, (void **)&status );
      LOG_I(PHY, "Destroying rxtx[%d] mutex/cond\n",i);
      pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx );
      pthread_cond_destroy( &proc_rxtx[i].cond_rxtx );
    }
Robert Schmidt's avatar
Robert Schmidt committed
1002

1003 1004 1005 1006
    pthread_attr_destroy(&proc->attr_prach);
    pthread_attr_destroy(&proc->attr_asynch_rxtx);
    pthread_attr_destroy(&proc_rxtx[0].attr_rxtx);
    pthread_attr_destroy(&proc_rxtx[1].attr_rxtx);
1007
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1008 1009
    pthread_mutex_destroy(&proc->mutex_RU_PRACH_br);
    pthread_attr_destroy(&proc->attr_prach_br);
Robert Schmidt's avatar
Robert Schmidt committed
1010
#endif
1011
  }
1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024
}




void reset_opp_meas(void) {
  int sfn;
  reset_meas(&softmodem_stats_mt);
  reset_meas(&softmodem_stats_hw);

  for (sfn=0; sfn < 10; sfn++) {
    reset_meas(&softmodem_stats_rxtx_sf);
    reset_meas(&softmodem_stats_rx_sf);
1025
  }
1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036
}


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++) {
    print_meas(&softmodem_stats_rxtx_sf,"[eNB][total_phy_proc_rxtx]",NULL, NULL);
    print_meas(&softmodem_stats_rx_sf,"[eNB][total_phy_proc_rx]",NULL,NULL);
1037
  }
1038
}
1039

1040 1041 1042
void free_transport(PHY_VARS_eNB *eNB) {
  int i;
  int j;
1043

1044 1045
  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
    LOG_D(PHY, "Freeing Transport Channel Buffers for DLSCH, UE %d\n",i);
1046

1047
    for (j=0; j<2; j++) free_eNB_dlsch(eNB->dlsch[i][j]);
1048

1049 1050
    LOG_D(PHY, "Freeing Transport Channel Buffer for ULSCH, UE %d\n",i);
    free_eNB_ulsch(eNB->ulsch[1+i]);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1051
  }
1052

1053 1054 1055 1056 1057 1058 1059 1060 1061