nr-gnb.c 18.2 KB
Newer Older
laurent's avatar
laurent committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

/*! \file lte-enb.c
 * \brief Top-level threads for gNodeB
 * \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
 */

#define _GNU_SOURCE
#include <pthread.h>

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

#include "assertions.h"
Laurent's avatar
Laurent committed
39 40
#include <common/utils/LOG/log.h>
#include <common/utils/system.h>
laurent's avatar
laurent committed
41 42 43 44 45 46 47 48 49

#include "PHY/types.h"

#include "PHY/INIT/phy_init.h"

#include "PHY/defs_gNB.h"
#include "SCHED/sched_eNB.h"
#include "SCHED_NR/sched_nr.h"
#include "SCHED_NR/fapi_nr_l1.h"
cig's avatar
cig committed
50
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
51
#include "PHY/MODULATION/nr_modulation.h"
laurent's avatar
laurent committed
52 53 54 55 56 57 58 59 60 61 62 63 64

#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

#include "PHY/LTE_TRANSPORT/if4_tools.h"
#include "PHY/LTE_TRANSPORT/if5_tools.h"

#include "PHY/phy_extern.h"

65
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
laurent's avatar
laurent committed
66 67 68 69 70 71 72 73 74
#include "RRC/LTE/rrc_extern.h"
#include "PHY_INTERFACE/phy_interface.h"
#include "common/utils/LOG/log_extern.h"
#include "UTIL/OTG/otg_tx.h"
#include "UTIL/OTG/otg_externs.h"
#include "UTIL/MATH/oml.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
#include "enb_config.h"
75
#include "gnb_paramdef.h"
laurent's avatar
laurent committed
76 77 78 79 80 81


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

82 83
#include "s1ap_eNB.h"
#include "SIMULATION/ETH_TRANSPORT/proto.h"
84
#include <executables/softmodem-common.h>
laurent's avatar
laurent committed
85 86

#include "T.h"
Mahesh's avatar
Mahesh committed
87
#include "nfapi/oai_integration/vendor_ext.h"
Laurent THOMAS's avatar
Laurent THOMAS committed
88
#include <nfapi/oai_integration/nfapi_pnf.h>
laurent's avatar
laurent committed
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
//#define DEBUG_THREADS 1

//#define USRP_DEBUG 1
// Fix per CC openair rf/if device update
// extern openair0_device openair0;


//pthread_t                       main_gNB_thread;

time_stats_t softmodem_stats_mt; // main thread
time_stats_t softmodem_stats_hw; //  hw acquisition
time_stats_t softmodem_stats_rxtx_sf; // total tx time
time_stats_t nfapi_meas; // total tx time
time_stats_t softmodem_stats_rx_sf; // total rx time


105
#include "executables/thread-common.h"
laurent's avatar
laurent committed
106 107 108 109 110 111


//#define TICK_TO_US(ts) (ts.diff)
#define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials)


112
void tx_func(void *param) {
laurent's avatar
laurent committed
113

114 115 116 117
  processingData_L1_t *info = (processingData_L1_t *) param;
  PHY_VARS_gNB *gNB = info->gNB;
  int frame_tx = info->frame_tx;
  int slot_tx = info->slot_tx;
laurent's avatar
laurent committed
118

119 120 121 122 123 124 125 126 127 128 129 130 131
  phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1);

  // start FH TX processing
  notifiedFIFO_elt_t *res; 
  res = pullTpool(gNB->resp_RU_tx, gNB->threadPool);
  processingData_RU_t *syncMsg = (processingData_RU_t *)NotifiedFifoData(res);
  syncMsg->frame_tx = frame_tx;
  syncMsg->slot_tx = slot_tx;
  syncMsg->timestamp_tx = info->timestamp_tx;
  syncMsg->ru = gNB->RU_list[0];
  res->key = slot_tx;
  pushTpool(gNB->threadPool, res);
}
laurent's avatar
laurent committed
132

133
void rx_func(void *param) {
134

135 136 137 138 139 140
  processingData_L1_t *info = (processingData_L1_t *) param;
  PHY_VARS_gNB *gNB = info->gNB;
  int frame_rx = info->frame_rx;
  int slot_rx = info->slot_rx;
  int frame_tx = info->frame_tx;
  int slot_tx = info->slot_tx;
141
  sl_ahead = sf_ahead*gNB->frame_parms.slots_per_subframe;
142 143
  nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;

laurent's avatar
laurent committed
144 145 146
  start_meas(&softmodem_stats_rxtx_sf);

  // *******************************************************************
147
  // NFAPI not yet supported for NR - this code has to be revised
148
  if (NFAPI_MODE == NFAPI_MODE_PNF) {
laurent's avatar
laurent committed
149 150 151 152 153
    // I am a PNF and I need to let nFAPI know that we have a (sub)frame tick
    //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);
MaheshK1995's avatar
MaheshK1995 committed
154 155
    // oai_subframe_ind(frame_rx, slot_rx);
    oai_slot_ind(frame_rx, slot_rx);
laurent's avatar
laurent committed
156 157
    stop_meas(&nfapi_meas);

158
    /*if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus||
laurent's avatar
laurent committed
159 160
        gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs ||
        gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs ||
161
        gNB->UL_INFO.rach_ind.number_of_pdus ||
laurent's avatar
laurent committed
162 163
        gNB->UL_INFO.cqi_ind.number_of_cqis
       ) {
164
      LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d rach_pdus:%0d.%d:%d cqis:%d] RX:%04d%d TX:%04d%d \n",
laurent's avatar
laurent committed
165 166 167
            NFAPI_SFNSF2DEC(gNB->UL_INFO.rx_ind.sfn_sf),   gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus,
            NFAPI_SFNSF2DEC(gNB->UL_INFO.harq_ind.sfn_sf), gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs,
            NFAPI_SFNSF2DEC(gNB->UL_INFO.crc_ind.sfn_sf),  gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs,
168
            gNB->UL_INFO.rach_ind.sfn, gNB->UL_INFO.rach_ind.slot,gNB->UL_INFO.rach_ind.number_of_pdus,
laurent's avatar
laurent committed
169
            gNB->UL_INFO.cqi_ind.number_of_cqis,
170 171
            frame_rx, slot_rx,
            frame_tx, slot_tx);
172
    }*/
laurent's avatar
laurent committed
173 174
  }
  // ****************************************
175

176
  T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(frame_tx), T_INT(slot_tx));
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 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
  /* hack to remove UEs */
  extern int rnti_to_remove[10];
  extern volatile int rnti_to_remove_count;
  extern pthread_mutex_t rnti_to_remove_mutex;
  if (pthread_mutex_lock(&rnti_to_remove_mutex)) exit(1);
  int up_removed = 0;
  int down_removed = 0;
  int pucch_removed = 0;
  for (int i = 0; i < rnti_to_remove_count; i++) {
    LOG_W(PHY, "to remove rnti %d\n", rnti_to_remove[i]);
    void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch);
    void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch);
    int j;
    for (j = 0; j < NUMBER_OF_NR_ULSCH_MAX; j++)
      if (gNB->ulsch[j][0]->rnti == rnti_to_remove[i]) {
        gNB->ulsch[j][0]->rnti = 0;
        gNB->ulsch[j][0]->harq_mask = 0;
        //clean_gNB_ulsch(gNB->ulsch[j][0]);
        int h;
        for (h = 0; h < NR_MAX_ULSCH_HARQ_PROCESSES; h++) {
          gNB->ulsch[j][0]->harq_processes[h]->status = SCH_IDLE;
          gNB->ulsch[j][0]->harq_processes[h]->round  = 0;
          gNB->ulsch[j][0]->harq_processes[h]->handled = 0;
        }
        up_removed++;
      }
    for (j = 0; j < NUMBER_OF_NR_DLSCH_MAX; j++)
      if (gNB->dlsch[j][0]->rnti == rnti_to_remove[i]) {
        gNB->dlsch[j][0]->rnti = 0;
        gNB->dlsch[j][0]->harq_mask = 0;
        //clean_gNB_dlsch(gNB->dlsch[j][0]);
        down_removed++;
      }
    for (j = 0; j < NUMBER_OF_NR_PUCCH_MAX; j++)
      if (gNB->pucch[j]->active > 0 &&
          gNB->pucch[j]->pucch_pdu.rnti == rnti_to_remove[i]) {
        gNB->pucch[j]->active = 0;
        gNB->pucch[j]->pucch_pdu.rnti = 0;
        pucch_removed++;
      }
#if 0
    for (j = 0; j < NUMBER_OF_NR_PDCCH_MAX; j++)
      gNB->pdcch_pdu[j].frame = -1;
    for (j = 0; j < NUMBER_OF_NR_PDCCH_MAX; j++)
      gNB->ul_pdcch_pdu[j].frame = -1;
    for (j = 0; j < NUMBER_OF_NR_PRACH_MAX; j++)
      gNB->prach_vars.list[j].frame = -1;
#endif
  }
  if (rnti_to_remove_count) LOG_W(PHY, "to remove rnti_to_remove_count=%d, up_removed=%d down_removed=%d pucch_removed=%d\n", rnti_to_remove_count, up_removed, down_removed, pucch_removed);
  rnti_to_remove_count = 0;
  if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1);

231
  // Call the scheduler
Khalid Ahmed's avatar
Khalid Ahmed committed
232

laurent's avatar
laurent committed
233
  pthread_mutex_lock(&gNB->UL_INFO_mutex);
234 235
  gNB->UL_INFO.frame     = frame_rx;
  gNB->UL_INFO.slot      = slot_rx;
laurent's avatar
laurent committed
236 237 238 239
  gNB->UL_INFO.module_id = gNB->Mod_id;
  gNB->UL_INFO.CC_id     = gNB->CC_id;
  gNB->if_inst->NR_UL_indication(&gNB->UL_INFO);
  pthread_mutex_unlock(&gNB->UL_INFO_mutex);
240 241 242 243 244
  
  // RX processing
  int tx_slot_type         = nr_slot_select(cfg,frame_tx,slot_tx);
  int rx_slot_type         = nr_slot_select(cfg,frame_rx,slot_rx);

245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
  notifiedFIFO_elt_t *res;

  if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) {
    res = pullTpool(gNB->resp_L1_tx, gNB->threadPool);
    processingData_L1_t *syncMsg = (processingData_L1_t *)NotifiedFifoData(res);
    syncMsg->gNB = gNB;
    syncMsg->frame_rx = frame_rx;
    syncMsg->slot_rx = slot_rx;
    syncMsg->frame_tx = frame_tx;
    syncMsg->slot_tx = slot_tx;
    syncMsg->timestamp_tx = info->timestamp_tx;
    res->key = slot_tx;
    pushTpool(gNB->threadPool, res);
  }

260 261 262
  if (rx_slot_type == NR_UPLINK_SLOT || rx_slot_type == NR_MIXED_SLOT) {
    // UE-specific RX processing for subframe n
    // TODO: check if this is correct for PARALLEL_RU_L1_TRX_SPLIT
263 264

    // Do PRACH RU processing
265
    L1_nr_prach_procedures(gNB,frame_rx,slot_rx);
266

267
    //apply the rx signal rotation here
268 269 270 271 272 273 274 275
    for (int aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) {
      apply_nr_rotation_ul(&gNB->frame_parms,
                           gNB->common_vars.rxdataF[aa],
                           slot_rx,
                           0,
                           gNB->frame_parms.Ncp==EXTENDED?12:14,
                           gNB->frame_parms.ofdm_symbol_size);
    }
276 277 278
    phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx);
  }

279
  stop_meas( &softmodem_stats_rxtx_sf );
280
  LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx);
laurent's avatar
laurent committed
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321

#if 0
  LOG_D(PHY, "rxtx:%lld nfapi:%lld phy:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ",
        softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now,
        TICK_TO_US(gNB->phy_proc),
        TICK_TO_US(gNB->phy_proc_tx),
        TICK_TO_US(gNB->phy_proc_rx),
        TICK_TO_US(gNB->rx_prach),
        TICK_TO_US(gNB->ofdm_mod_stats),
        softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now);
  LOG_D(PHY,
        "dlsch[enc:%lld mod:%lld scr:%lld rm:%lld t:%lld i:%lld] rx_dft:%lld ",
        TICK_TO_US(gNB->dlsch_encoding_stats),
        TICK_TO_US(gNB->dlsch_modulation_stats),
        TICK_TO_US(gNB->dlsch_scrambling_stats),
        TICK_TO_US(gNB->dlsch_rate_matching_stats),
        TICK_TO_US(gNB->dlsch_turbo_encoding_stats),
        TICK_TO_US(gNB->dlsch_interleaving_stats),
        TICK_TO_US(gNB->rx_dft_stats));
  LOG_D(PHY," ulsch[ch:%lld freq:%lld dec:%lld demod:%lld ru:%lld ",
        TICK_TO_US(gNB->ulsch_channel_estimation_stats),
        TICK_TO_US(gNB->ulsch_freq_offset_estimation_stats),
        TICK_TO_US(gNB->ulsch_decoding_stats),
        TICK_TO_US(gNB->ulsch_demodulation_stats),
        TICK_TO_US(gNB->ulsch_rate_unmatching_stats));
  LOG_D(PHY, "td:%lld dei:%lld dem:%lld llr:%lld tci:%lld ",
        TICK_TO_US(gNB->ulsch_turbo_decoding_stats),
        TICK_TO_US(gNB->ulsch_deinterleaving_stats),
        TICK_TO_US(gNB->ulsch_demultiplexing_stats),
        TICK_TO_US(gNB->ulsch_llr_stats),
        TICK_TO_US(gNB->ulsch_tc_init_stats));
  LOG_D(PHY, "tca:%lld tcb:%lld tcg:%lld tce:%lld l1:%lld l2:%lld]\n\n",
        TICK_TO_US(gNB->ulsch_tc_alpha_stats),
        TICK_TO_US(gNB->ulsch_tc_beta_stats),
        TICK_TO_US(gNB->ulsch_tc_gamma_stats),
        TICK_TO_US(gNB->ulsch_tc_ext_stats),
        TICK_TO_US(gNB->ulsch_tc_intl1_stats),
        TICK_TO_US(gNB->ulsch_tc_intl2_stats)
       );
#endif
}
laurent's avatar
laurent committed
322
static void *process_stats_thread(void *param) {
323

laurent's avatar
laurent committed
324
  PHY_VARS_gNB *gNB  = (PHY_VARS_gNB *)param;
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341

  reset_meas(&gNB->dlsch_encoding_stats);
  reset_meas(&gNB->dlsch_scrambling_stats);
  reset_meas(&gNB->dlsch_modulation_stats);

  wait_sync("process_stats_thread");

  while(!oai_exit)
  {
    sleep(1);
    print_meas(&gNB->dlsch_encoding_stats, "pdsch_encoding", NULL, NULL);
    print_meas(&gNB->dlsch_scrambling_stats, "pdsch_scrambling", NULL, NULL);
    print_meas(&gNB->dlsch_modulation_stats, "pdsch_modulation", NULL, NULL);
  }
  return(NULL);
}

Sakthivel Velumani's avatar
Sakthivel Velumani committed
342
void init_gNB_Tpool(int inst) {
laurent's avatar
laurent committed
343
  PHY_VARS_gNB *gNB;
344
  gNB = RC.gNB[inst];
345
  gNB_L1_proc_t *proc = &gNB->proc;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
346

Sakthivel Velumani's avatar
Sakthivel Velumani committed
347
  // ULSCH decoding threadpool
Sakthivel Velumani's avatar
Sakthivel Velumani committed
348
  gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
349
  int numCPU = sysconf(_SC_NPROCESSORS_ONLN);
350
  int threadCnt = min(numCPU, gNB->pusch_proc_threads);
351
  char ul_pool[80];
352
  sprintf(ul_pool,"-1");
353
  int s_offset = 0;
354
  for (int icpu=1; icpu<threadCnt; icpu++) {
355 356
    sprintf(ul_pool+2+s_offset,",-1");
    s_offset += 3;
357
  }
358
  initTpool(ul_pool, gNB->threadPool, true);
359 360
  // ULSCH decoder result FIFO
  gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
Sakthivel Velumani's avatar
Sakthivel Velumani committed
361
  initNotifiedFIFO(gNB->respDecode);
laurent's avatar
laurent committed
362

363
  // L1 RX result FIFO 
Sakthivel Velumani's avatar
Sakthivel Velumani committed
364 365 366
  gNB->resp_L1 = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
  initNotifiedFIFO(gNB->resp_L1);

367
  // L1 TX result FIFO 
Sakthivel Velumani's avatar
Sakthivel Velumani committed
368 369 370
  gNB->resp_L1_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
  initNotifiedFIFO(gNB->resp_L1_tx);

371
  // RU TX result FIFO 
Sakthivel Velumani's avatar
Sakthivel Velumani committed
372 373
  gNB->resp_RU_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
  initNotifiedFIFO(gNB->resp_RU_tx);
374 375 376

  // Stats measurement thread
  if(opp_enabled == 1) threadCreate(&proc->L1_stats_thread, process_stats_thread,(void *)gNB, "time_meas", -1, OAI_PRIORITY_RT_LOW);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
377
}
laurent's avatar
laurent committed
378 379 380 381 382 383 384 385


/*!
 * \brief Terminate gNB TX and RX threads.
 */
void kill_gNB_proc(int inst) {
  PHY_VARS_gNB *gNB;

386 387 388 389 390
  gNB=RC.gNB[inst];
  
  LOG_I(PHY, "Destroying UL_INFO mutex\n");
  pthread_mutex_destroy(&gNB->UL_INFO_mutex);
  
laurent's avatar
laurent committed
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418
}

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


void print_opp_meas(void) {
  int sfn=0;
  print_meas(&softmodem_stats_mt, "Main gNB Thread", NULL, NULL);
  print_meas(&softmodem_stats_hw, "HW Acquisation", NULL, NULL);

  for (sfn=0; sfn < 10; sfn++) {
    print_meas(&softmodem_stats_rxtx_sf,"[gNB][total_phy_proc_rxtx]",NULL, NULL);
    print_meas(&softmodem_stats_rx_sf,"[gNB][total_phy_proc_rx]",NULL,NULL);
  }
}


/// eNB kept in function name for nffapi calls, TO FIX
void init_eNB_afterRU(void) {
419
  int inst,ru_id,i,aa;
laurent's avatar
laurent committed
420 421 422 423
  PHY_VARS_gNB *gNB;
  LOG_I(PHY,"%s() RC.nb_nr_inst:%d\n", __FUNCTION__, RC.nb_nr_inst);

  for (inst=0; inst<RC.nb_nr_inst; inst++) {
424
    LOG_I(PHY,"RC.nb_nr_CC[inst:%d]:%p\n", inst, RC.gNB[inst]);
425 426
    gNB                                  =  RC.gNB[inst];
    phy_init_nr_gNB(gNB,0,0);
427

428 429
    // map antennas and PRACH signals to gNB RX
    if (0) AssertFatal(gNB->num_RU>0,"Number of RU attached to gNB %d is zero\n",gNB->Mod_id);
430

431 432
    LOG_I(PHY,"Mapping RX ports from %d RUs to gNB %d\n",gNB->num_RU,gNB->Mod_id);
    LOG_I(PHY,"gNB->num_RU:%d\n", gNB->num_RU);
433

434 435 436 437 438 439 440 441 442 443
    for (ru_id=0,aa=0; ru_id<gNB->num_RU; ru_id++) {
      AssertFatal(gNB->RU_list[ru_id]->common.rxdataF!=NULL,
		  "RU %d : common.rxdataF is NULL\n",
		  gNB->RU_list[ru_id]->idx);
      AssertFatal(gNB->RU_list[ru_id]->prach_rxsigF!=NULL,
		  "RU %d : prach_rxsigF is NULL\n",
		  gNB->RU_list[ru_id]->idx);
      
      for (i=0; i<gNB->RU_list[ru_id]->nb_rx; aa++,i++) {
	LOG_I(PHY,"Attaching RU %d antenna %d to gNB antenna %d\n",gNB->RU_list[ru_id]->idx,i,aa);
444
	gNB->prach_vars.rxsigF[aa]    =  gNB->RU_list[ru_id]->prach_rxsigF[0][i];
445 446 447
#if 0
printf("before %p\n", gNB->common_vars.rxdataF[aa]);
#endif
448
	gNB->common_vars.rxdataF[aa]     =  gNB->RU_list[ru_id]->common.rxdataF[i];
449 450 451
#if 0
printf("after %p\n", gNB->common_vars.rxdataF[aa]);
#endif
452
      }
laurent's avatar
laurent committed
453
    }
454

455 456 457 458 459
    /* TODO: review this code, there is something wrong.
     * In monolithic mode, we come here with nb_antennas_rx == 0
     * (not tested in other modes).
     */
    //init_precoding_weights(RC.gNB[inst]);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
460
    init_gNB_Tpool(inst);
laurent's avatar
laurent committed
461 462 463 464 465
  }

}

void init_gNB(int single_thread_flag,int wait_for_sync) {
466

laurent's avatar
laurent committed
467 468 469
  int inst;
  PHY_VARS_gNB *gNB;

Raymond Knopp's avatar
Raymond Knopp committed
470 471
  if (RC.gNB == NULL) {
    RC.gNB = (PHY_VARS_gNB **) malloc((1+RC.nb_nr_L1_inst)*sizeof(PHY_VARS_gNB *));
472
    LOG_I(PHY,"gNB L1 structure RC.gNB allocated @ %p\n",RC.gNB);
Raymond Knopp's avatar
Raymond Knopp committed
473
  }
laurent's avatar
laurent committed
474 475

  for (inst=0; inst<RC.nb_nr_L1_inst; inst++) {
Raymond Knopp's avatar
Raymond Knopp committed
476

477 478 479
    if (RC.gNB[inst] == NULL) {
      RC.gNB[inst] = (PHY_VARS_gNB *) malloc(sizeof(PHY_VARS_gNB));
      memset((void*)RC.gNB[inst],0,sizeof(PHY_VARS_gNB));
480
      LOG_I(PHY,"[nr-gnb.c] gNB structure RC.gNB[%d] allocated @ %p\n",inst,RC.gNB[inst]);
481
    }
482 483 484 485 486 487 488 489 490
    gNB                     = RC.gNB[inst];
    gNB->abstraction_flag   = 0;
    gNB->single_thread_flag = single_thread_flag;
    /*nr_polar_init(&gNB->nrPolar_params,
      NR_POLAR_PBCH_MESSAGE_TYPE,
      NR_POLAR_PBCH_PAYLOAD_BITS,
      NR_POLAR_PBCH_AGGREGATION_LEVEL);*/
    LOG_I(PHY,"Initializing gNB %d single_thread_flag:%d\n",inst,gNB->single_thread_flag);
    LOG_I(PHY,"Initializing gNB %d\n",inst);
491

492 493 494 495 496 497 498
    LOG_I(PHY,"Registering with MAC interface module (before %p)\n",gNB->if_inst);
    AssertFatal((gNB->if_inst         = NR_IF_Module_init(inst))!=NULL,"Cannot register interface");
    LOG_I(PHY,"Registering with MAC interface module (after %p)\n",gNB->if_inst);
    gNB->if_inst->NR_Schedule_response   = nr_schedule_response;
    gNB->if_inst->NR_PHY_config_req      = nr_phy_config_request;
    memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
    LOG_I(PHY,"Setting indication lists\n");
499

500 501 502
    gNB->UL_INFO.rx_ind.pdu_list = gNB->rx_pdu_list;
    gNB->UL_INFO.crc_ind.crc_list = gNB->crc_pdu_list;
    /*gNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = gNB->sr_pdu_list;
503 504
    gNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = gNB->harq_pdu_list;
    gNB->UL_INFO.cqi_ind.cqi_pdu_list = gNB->cqi_pdu_list;
505
    gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list;*/
506

507
    gNB->prach_energy_counter = 0;
laurent's avatar
laurent committed
508
  }
509
  
laurent's avatar
laurent committed
510

511
  LOG_I(PHY,"[nr-gnb.c] gNB structure allocated\n");
laurent's avatar
laurent committed
512 513 514 515 516 517 518 519 520
}


void stop_gNB(int nb_inst) {
  for (int inst=0; inst<nb_inst; inst++) {
    LOG_I(PHY,"Killing gNB %d processing threads\n",inst);
    kill_gNB_proc(inst);
  }
}