diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index 703bdd2d6fde21273ea9d8bc56453df9db061f1e..6f1eb595bb61414fb25a02f45a90c91b1fb909e2 100755 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -159,8 +159,8 @@ typedef enum { typedef enum { synch_to_ext_device=0, // synch to RF or Ethernet device - synch_to_other // synch to another source (timer, other CC_id) -} eNB_timing_t; + synch_to_other // synch to another source (timer, other RU) +} RU_timing_t; typedef struct UE_SCAN_INFO_s { /// 10 best amplitudes (linear) for each pss signals @@ -226,6 +226,57 @@ typedef struct { int G; } te_params; +typedef struct pc_proc_t_s { + /// timestamp received from HW + openair0_timestamp timestamp_rx; + /// timestamp to send to "slave rru" + openair0_timestamp timestamp_tx; + /// subframe to act upon for reception + int subframe_rx; + /// frame to act upon for reception + int frame_rx; + /// \brief Instance count for FH processing thread. + /// \internal This variable is protected by \ref mutex_FH. + int instance_cnt_FH; + /// \brief Instance count for rx processing thread. + /// \internal This variable is protected by \ref mutex_asynch_rxtx. + int instance_cnt_asynch_rxtx; + /// pthread structure for FH processing thread + pthread_t pthread_FH; + /// pthread structure for eNB single processing thread + pthread_t pthread_single; + /// pthread structure for asychronous RX/TX processing thread + pthread_t pthread_asynch_rxtx; + /// flag to indicate first RX acquisition + int first_rx; + /// flag to indicate first TX transmission + int first_tx; + /// pthread attributes for FH processing thread + pthread_attr_t attr_FH; + /// pthread attributes for single eNB processing thread + pthread_attr_t attr_single; + /// pthread attributes for asynchronous RX thread + pthread_attr_t attr_asynch_rxtx; + /// scheduling parameters for FH thread + struct sched_param sched_param_FH; + /// scheduling parameters for single eNB thread + struct sched_param sched_param_single; + /// scheduling parameters for asynch_rxtx thread + struct sched_param sched_param_asynch_rxtx; + /// condition variable for FH thread + pthread_cond_t cond_FH; + /// condition variable for asynch RX/TX thread + pthread_cond_t cond_asynch_rxtx; + /// mutex for FH + pthread_mutex_t mutex_FH; + /// mutex for asynch RX/TX thread + pthread_mutex_t mutex_asynch_rxtx; + /// number of slave threads + int num_slaves; + /// array of pointers to slaves + struct pc_proc_t_s **slave_proc; +} pc_proc_t; + /// Context data structure for eNB subframe processing typedef struct eNB_proc_t_s { /// Component Carrier index @@ -412,14 +463,12 @@ typedef struct PHY_VARS_eNB_s { int abstraction_flag; openair0_timestamp ts_offset; void (*do_prach)(struct PHY_VARS_eNB_s *eNB); - void (*fep)(struct PHY_VARS_eNB_s *eNB); int (*td)(struct PHY_VARS_eNB_s *eNB,int UE_id,int harq_pid,int llr8_flag); int (*te)(struct PHY_VARS_eNB_s *,uint8_t *,uint8_t,LTE_eNB_DLSCH_t *,int,uint8_t,time_stats_t *,time_stats_t *,time_stats_t *); void (*proc_uespec_rx)(struct PHY_VARS_eNB_s *eNB,eNB_rxtx_proc_t *proc,const relaying_type_t r_type); void (*proc_tx)(struct PHY_VARS_eNB_s *eNB,eNB_rxtx_proc_t *proc,relaying_type_t r_type,PHY_VARS_RN *rn); void (*tx_fh)(struct PHY_VARS_eNB_s *eNB,eNB_rxtx_proc_t *proc); void (*rx_fh)(struct PHY_VARS_eNB_s *eNB,int *frame, int *subframe); - int (*start_rf)(struct PHY_VARS_eNB_s *eNB); int (*start_if)(struct PHY_VARS_eNB_s *eNB); void (*fh_asynch)(struct PHY_VARS_eNB_s *eNB,int *frame, int *subframe); uint8_t local_flag; @@ -612,12 +661,6 @@ typedef struct PHY_VARS_eNB_s { int32_t pusch_stats_bsr[NUMBER_OF_UE_MAX][10240]; int32_t pusch_stats_BO[NUMBER_OF_UE_MAX][10240]; - /// RF and Interface devices per CC - openair0_device rfdevice; - openair0_device ifdevice; - /// Pointer for ifdevice buffer struct - if_buffer_t ifbuffer; - } PHY_VARS_eNB; #define debug_msg if (((mac_xface->frame%100) == 0) || (mac_xface->frame < 50)) msg @@ -873,13 +916,69 @@ typedef struct { /// RF and Interface devices per CC openair0_device rfdevice; - } PHY_VARS_UE; +typedef enum { + LOCAL_RF=0, + REMOTE_IF5=1, + REMOTE_IF4p5=2, + REMOTE_IF1pp=3, + MAX_RU_IF_TYPES=4 +} RU_if_in_t; + +typedef struct { + + /// input interface + RU_if_in_t RU_if_in; + /// timing + RU_if_timing_t RU_if_timing; + /// number of RX paths on device + int nb_rx; + /// number of TX paths on device + int nb_tx; + /// Radio Unit device descriptor + openair0_device rudevice; + /// Pointer for ifdevice buffer struct + if_buffer_t ifbuffer; +} RU_desc_t; + +typedef struct PRECODER_t_s{ + /// pointer to RAN context governing this precoder + RAN_CONTEXT *RC; + /// function pointer to synchronous TX fronthaul function + void (*tx_fh)(PRECODER_t_s *pc); + /// function pointer to synchronous RX fronthaul function + void (*rx_fh)(PRECODER_t_s *pc,int *frame, int *subframe); + /// function pointer to asynchronous fronthaul interface + void (*fh_asynch)(struct PRECODER_t_s *pc,int *frame, int *subframe); + /// function pointer to initialization function for radio interface + int (*start_rf)(struct PRECODER_t_s *pc); + /// function pointer to RX front-end processing routine (DFTs/prefix removal or NULL) + void (*fep_rx)(struct PRECODER_t_s *pc); + /// function pointer to TX front-end processing routine (PRECODING and/or IDFTs and prefix removal or NULL) + void (*fep_tx)(struct PRECODER_t_s *pc); + /// RX and TX buffers for precoder output + RU_TIME ru_time; +} PRECODER_t; + +typedef struct { + /// Number of eNB instances in this node + int nb_inst; + /// Number of Component Carriers per instance in this node + int *nb_CC; + /// Number of radio units + int nb_RU; + /// eNB context variables + PHY_VARS_eNB **eNB; + /// RU descriptors + RU_desc_t *ru_desc; + /// Precoding descriptor per radio unit. This describes what each radio unit is supposed to do and contains the necessary functions for fronthaul interfaces + PRECODER_t *pc; +} RAN_CONTEXT_t; + void exit_fun(const char* s); static inline int wait_on_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) { - if (pthread_mutex_lock(mutex) != 0) { LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name); exit_fun("nothing to add"); diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h index bed2057800275dc2797ea44b391fecb43497569a..19c3936b6c38a296be21ff28c2a6fdc40dab5e66 100644 --- a/openair1/PHY/impl_defs_lte.h +++ b/openair1/PHY/impl_defs_lte.h @@ -592,150 +592,83 @@ typedef enum { TM9_10=13 } MIMO_mode_t; + typedef struct { - /// \brief Holds the transmit data in time domain. - /// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. - /// - first index: eNB id [0..2] (hard coded) - /// - second index: tx antenna [0..nb_antennas_tx[ - /// - third index: - int32_t **txdata[3]; - /// \brief holds the transmit data in the frequency domain. - /// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. - /// - first index: eNB id [0..2] (hard coded) - /// - second index: tx antenna [0..nb_antennas_tx[ - /// - third index: sample [0..] - int32_t **txdataF[3]; - /// \brief Holds the received data in time domain. - /// Should point to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. - /// - first index: sector id [0..2] (hard coded) - /// - second index: rx antenna [0..nb_antennas_rx[ - /// - third index: sample [0..] - int32_t **rxdata[3]; + + int32_t **txdataF; /// \brief Holds the last subframe of received data in time domain after removal of 7.5kHz frequency offset. - /// - first index: secotr id [0..2] (hard coded) - /// - second index: rx antenna [0..nb_antennas_rx[ - /// - third index: sample [0..samples_per_tti[ - int32_t **rxdata_7_5kHz[3]; + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: sample [0..samples_per_tti[ + int32_t **rxdata_7_5kHz; /// \brief Holds the received data in the frequency domain. - /// - first index: sector id [0..2] (hard coded) - /// - second index: rx antenna [0..nb_antennas_rx[ - /// - third index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[ - int32_t **rxdataF[3]; + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[ + int32_t **rxdataF; /// \brief Holds output of the sync correlator. - /// - first index: sector id [0..2] (hard coded) - /// - second index: sample [0..samples_per_tti*10[ + /// - first index: sample [0..samples_per_tti*10[ uint32_t *sync_corr[3]; } LTE_eNB_COMMON; +typedef struct { + /// \brief Holds the transmit data in the frequency domain. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[ + int32_t **txdata; + /// \brief Holds the receive data in the frequency domain. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[ + int32_t **rxdata; +} RU_TIME; + typedef struct { /// \brief Hold the channel estimates in frequency domain based on SRS. - /// - first index: sector id [0..2] (hard coded) - /// - second index: rx antenna id [0..nb_antennas_rx[ - /// - third index: ? [0..ofdm_symbol_size[ - int32_t **srs_ch_estimates[3]; + /// - first index: rx antenna id [0..nb_antennas_rx[ + /// - second index: ? [0..ofdm_symbol_size[ + int32_t **srs_ch_estimates; /// \brief Hold the channel estimates in time domain based on SRS. - /// - first index: sector id [0..2] (hard coded) - /// - second index: rx antenna id [0..nb_antennas_rx[ - /// - third index: ? [0..2*ofdm_symbol_size[ - int32_t **srs_ch_estimates_time[3]; + /// - first index: rx antenna id [0..nb_antennas_rx[ + /// - second index: ? [0..2*ofdm_symbol_size[ + int32_t **srs_ch_estimates_time; /// \brief Holds the SRS for channel estimation at the RX. - /// - first index: ? [0..ofdm_symbol_size[ + /// - first index: rx antenna id [0..nb_antennas_rx[ + /// - second index: ? [0..ofdm_symbol_size[ int32_t *srs; } LTE_eNB_SRS; typedef struct { /// \brief Holds the received data in the frequency domain for the allocated RBs in repeated format. - /// - first index: sector id [0..2] (hard coded) - /// - second index: rx antenna id [0..nb_antennas_rx[ - /// - third index: ? [0..2*ofdm_symbol_size[ - /// - third index (definition from phy_init_lte_eNB()): ? [0..24*N_RB_UL*frame_parms->symbols_per_tti[ - /// \warning inconsistent third index definition - int32_t **rxdataF_ext[3]; + /// - first index: rx antenna id [0..nb_antennas_rx[ + /// - second index: ? [0..2*ofdm_symbol_size[ + int32_t **rxdataF_ext; /// \brief Holds the received data in the frequency domain for the allocated RBs in normal format. - /// - first index: sector id [0..2] (hard coded) - /// - second index: rx antenna id [0..nb_antennas_rx[ - /// - third index (definition from phy_init_lte_eNB()): ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ - int32_t **rxdataF_ext2[3]; + /// - first index: rx antenna id [0..nb_antennas_rx[ + /// - second index (definition from phy_init_lte_eNB()): ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **rxdataF_ext2; /// \brief Hold the channel estimates in time domain based on DRS. - /// - first index: sector id [0..2] (hard coded) - /// - second index: rx antenna id [0..nb_antennas_rx[ - /// - third index: ? [0..4*ofdm_symbol_size[ - int32_t **drs_ch_estimates_time[3]; + /// - first index: rx antenna id [0..nb_antennas_rx[ + /// - second index: ? [0..4*ofdm_symbol_size[ + int32_t **drs_ch_estimates_time; /// \brief Hold the channel estimates in frequency domain based on DRS. - /// - first index: sector id [0..2] (hard coded) - /// - second index: rx antenna id [0..nb_antennas_rx[ - /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ - int32_t **drs_ch_estimates[3]; - /// \brief Hold the channel estimates for UE0 in case of Distributed Alamouti Scheme. - /// - first index: sector id [0..2] (hard coded) - /// - second index: rx antenna id [0..nb_antennas_rx[ - /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ - int32_t **drs_ch_estimates_0[3]; - /// \brief Hold the channel estimates for UE1 in case of Distributed Almouti Scheme. - /// - first index: sector id [0..2] (hard coded) - /// - second index: rx antenna id [0..nb_antennas_rx[ - /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ - int32_t **drs_ch_estimates_1[3]; + /// - first index: rx antenna id [0..nb_antennas_rx[ + /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **drs_ch_estimates; /// \brief Holds the compensated signal. - /// - first index: sector id [0..2] (hard coded) - /// - second index: rx antenna id [0..nb_antennas_rx[ - /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ - int32_t **rxdataF_comp[3]; - /// \brief Hold the compensated data (y)*(h0*) in case of Distributed Alamouti Scheme. - /// - first index: sector id [0..2] (hard coded) - /// - second index: rx antenna id [0..nb_antennas_rx[ - /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ - int32_t **rxdataF_comp_0[3]; - /// \brief Hold the compensated data (y*)*(h1) in case of Distributed Alamouti Scheme. - /// - first index: sector id [0..2] (hard coded) - /// - second index: rx antenna id [0..nb_antennas_rx[ - /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ - int32_t **rxdataF_comp_1[3]; - /// \brief ?. - /// - first index: sector id [0..2] (hard coded) - /// - second index: rx antenna id [0..nb_antennas_rx[ - /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ - int32_t **ul_ch_mag[3]; - /// \brief ?. - /// - first index: eNB id [0..2] (hard coded) - /// - second index: rx antenna id [0..nb_antennas_rx[ - /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ - int32_t **ul_ch_magb[3]; - /// \brief Hold the channel mag for UE0 in case of Distributed Alamouti Scheme. - /// - first index: eNB id [0..2] (hard coded) - /// - second index: rx antenna id [0..nb_antennas_rx[ - /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ - int32_t **ul_ch_mag_0[3]; - /// \brief Hold the channel magb for UE0 in case of Distributed Alamouti Scheme. - /// - first index: eNB id [0..2] (hard coded) - /// - second index: rx antenna id [0..nb_antennas_rx[ - /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ - int32_t **ul_ch_magb_0[3]; - /// \brief Hold the channel mag for UE1 in case of Distributed Alamouti Scheme. - /// - first index: eNB id [0..2] (hard coded) - /// - second index: rx antenna id [0..nb_antennas_rx[ - /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ - int32_t **ul_ch_mag_1[3]; - /// \brief Hold the channel magb for UE1 in case of Distributed Alamouti Scheme. - /// - first index: eNB id [0..2] (hard coded) - /// - second index: rx antenna id [0..nb_antennas_rx[ - /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ - int32_t **ul_ch_magb_1[3]; + /// - first index: rx antenna id [0..nb_antennas_rx[ + /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **rxdataF_comp; + /// \brief Magnitude of the UL channel estimates. Used for 2nd-bit level thresholds in LLR computation + /// - first index: rx antenna id [0..nb_antennas_rx[ + /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_mag; + /// \brief Magnitude of the UL channel estimates scaled for 3rd bit level thresholds in LLR computation + /// - first index: rx antenna id [0..nb_antennas_rx[ + /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_magb; /// measured RX power based on DRS int ulsch_power[2]; - /// measured RX power based on DRS for UE0 in case of Distributed Alamouti Scheme - int ulsch_power_0[2]; - /// measured RX power based on DRS for UE0 in case of Distributed Alamouti Scheme - int ulsch_power_1[2]; /// \brief llr values. /// - first index: ? [0..1179743] (hard coded) int16_t *llr; -#ifdef LOCALIZATION - /// number of active subcarrier for a specific UE - int32_t active_subcarrier; - /// subcarrier power in dBm - int32_t *subcarrier_power; -#endif } LTE_eNB_PUSCH; typedef struct { diff --git a/openair1/PHY/vars.h b/openair1/PHY/vars.h index e773229a28dc06a5dc289d1e739d5a42df141923..448aa192ba6e6ca589efbf4ea645ef24547e990f 100755 --- a/openair1/PHY/vars.h +++ b/openair1/PHY/vars.h @@ -141,6 +141,7 @@ double beta2_dlsch[6][MCS_COUNT] = { {2.52163, 0.83231, 0.77472, 1.36536, 1.1682 char eNB_functions[6][20]={"eNodeB_3GPP","eNodeB_3GPP_BBU","NGFI_RCC_IF4p5","NGFI_RAI_IF4p5","NGFI_RRU_IF5","NGFI_RRU_IF4p5",}; char eNB_timing[2][20]={"synch_to_ext_device","synch_to_other"}; +char ru_if_types[MAX_RU_IF_TYPES][20]={"local RF","IF5 RRU","IF4p5 RRU","IF1pp RRU"}; /// lookup table for unscrambling in RX int16_t unscrambling_lut[65536*16] __attribute__((aligned(32))); diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index fdad1e12c1ff07e1544b5271a872bc7a95d0a3da..de46d8f2f9505dd8d05b6a77dfc88abd908af1ca 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -1230,13 +1230,30 @@ static void* eNB_thread_prach( void* param ) { return &eNB_thread_prach_status; } +static void *pc_thread(void* param) { + + PRECODER *pc = (PRECODER_t*)param; + + // Start IF device if any + if (eNB->start_if) + if (eNB->start_if(eNB) != 0) + LOG_E(HW,"Could not start the IF device\n"); + + // Start RF device if any + if (eNB->start_rf) + if (eNB->start_rf(eNB) != 0) + LOG_E(HW,"Could not start the RF device\n"); + +} + + static void* eNB_thread_single( void* param ) { static int eNB_thread_single_status; eNB_proc_t *proc = (eNB_proc_t*)param; eNB_rxtx_proc_t *proc_rxtx = &proc->proc_rxtx[0]; - PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id]; + PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id]; int subframe=0, frame=0; @@ -1252,15 +1269,6 @@ static void* eNB_thread_single( void* param ) { wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB); #endif - // Start IF device if any - if (eNB->start_if) - if (eNB->start_if(eNB) != 0) - LOG_E(HW,"Could not start the IF device\n"); - - // Start RF device if any - if (eNB->start_rf) - if (eNB->start_rf(eNB) != 0) - LOG_E(HW,"Could not start the RF device\n"); // wakeup asnych_rxtx thread because the devices are ready at this point pthread_mutex_lock(&proc->mutex_asynch_rxtx); @@ -1607,6 +1615,183 @@ extern void eNB_fep_full(PHY_VARS_eNB *eNB); extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB); extern void do_prach(PHY_VARS_eNB *eNB); +void init_RU(RAN_CONTEXT *rc,RU_if_in_t ru_if_in[], RU_if_timing_t ru_if_timing[], eth_params_t *eth_params) { + + int ru_id; + + for (ru_id=0;ru_id<rc->nb_RU;ru_id++) { + ru = &rc.ru_desc[ru_id]; + ru->RU_if_in[ru_id] = ru_if_in[ru_id]; + ru->RU_if_timing = ru_if_timing[ru_id]; + LOG_I(PHY,"Initializing RRU descriptor %d : (%s,%s)\n",ru_id,ru_if_types[ru_if_in[ru_id]],eNB_timing[ru_timing[ru_id]]); + + switch (ru->RU_if_in[ru_id]) { + case REMOTE_IF5: + pc->fep = pc_fep_rru_if5; + eNB->rx_fh = rx_rf; + eNB->start_rf = start_rf; + eNB->start_if = start_if; + eNB->fh_asynch = fh_if5_asynch_DL; + ret = openair0_device_load(&eNB->rfdevice, &openair0_cfg[CC_id]); + if (ret<0) { + printf("Exiting, cannot initialize rf device\n"); + exit(-1); + } + eNB->rfdevice.host_type = RRH_HOST; + eNB->ifdevice.host_type = RRH_HOST; + ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params+CC_id)); + printf("openair0_transport_init returns %d for CC_id %d\n",ret,CC_id); + if (ret<0) { + printf("Exiting, cannot initialize transport protocol\n"); + exit(-1); + } + break; + case NGFI_RRU_IF4p5: + eNB->do_prach = do_prach; + eNB->fep = eNB_fep_full;//(single_thread_flag==1) ? eNB_fep_full_2thread : eNB_fep_full; + eNB->td = NULL; + eNB->te = NULL; + eNB->proc_uespec_rx = NULL; + eNB->proc_tx = NULL;//proc_tx_rru_if4p5; + eNB->tx_fh = NULL; + eNB->rx_fh = rx_rf; + eNB->fh_asynch = fh_if4p5_asynch_DL; + eNB->start_rf = start_rf; + eNB->start_if = start_if; + ret = openair0_device_load(&eNB->rfdevice, &openair0_cfg[CC_id]); + if (ret<0) { + printf("Exiting, cannot initialize rf device\n"); + exit(-1); + } + eNB->rfdevice.host_type = RRH_HOST; + eNB->ifdevice.host_type = RRH_HOST; + ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params+CC_id)); + printf("openair0_transport_init returns %d for CC_id %d\n",ret,CC_id); + if (ret<0) { + printf("Exiting, cannot initialize transport protocol\n"); + exit(-1); + } + + malloc_IF4p5_buffer(eNB); + + break; + case eNodeB_3GPP: + eNB->do_prach = do_prach; + eNB->fep = eNB_fep_full;//(single_thread_flag==1) ? eNB_fep_full_2thread : eNB_fep_full; + eNB->td = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; + eNB->te = dlsch_encoding;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding; + eNB->proc_uespec_rx = phy_procedures_eNB_uespec_RX; + eNB->proc_tx = proc_tx_full; + eNB->tx_fh = NULL; + eNB->rx_fh = rx_rf; + eNB->start_rf = start_rf; + eNB->start_if = NULL; + eNB->fh_asynch = NULL; + ret = openair0_device_load(&eNB->rfdevice, &openair0_cfg[CC_id]); + if (ret<0) { + printf("Exiting, cannot initialize rf device\n"); + exit(-1); + } + eNB->rfdevice.host_type = BBU_HOST; + eNB->ifdevice.host_type = BBU_HOST; + break; + case eNodeB_3GPP_BBU: + eNB->do_prach = do_prach; + eNB->fep = eNB_fep_full;//(single_thread_flag==1) ? eNB_fep_full_2thread : eNB_fep_full; + eNB->td = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; + eNB->te = dlsch_encoding;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding; + eNB->proc_uespec_rx = phy_procedures_eNB_uespec_RX; + eNB->proc_tx = proc_tx_full; + if (eNB->node_timing == synch_to_other) { + eNB->tx_fh = tx_fh_if5_mobipass; + eNB->rx_fh = rx_fh_slave; + eNB->fh_asynch = fh_if5_asynch_UL; + + } + else { + eNB->tx_fh = tx_fh_if5; + eNB->rx_fh = rx_fh_if5; + eNB->fh_asynch = NULL; + } + + eNB->start_rf = NULL; + eNB->start_if = start_if; + eNB->rfdevice.host_type = BBU_HOST; + + eNB->ifdevice.host_type = BBU_HOST; + + ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params+CC_id)); + printf("openair0_transport_init returns %d for CC_id %d\n",ret,CC_id); + if (ret<0) { + printf("Exiting, cannot initialize transport protocol\n"); + exit(-1); + } + break; + case NGFI_RCC_IF4p5: + eNB->do_prach = do_prach; + eNB->fep = NULL; + eNB->td = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; + eNB->te = dlsch_encoding;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding; + eNB->proc_uespec_rx = phy_procedures_eNB_uespec_RX; + eNB->proc_tx = proc_tx_high; + eNB->tx_fh = tx_fh_if4p5; + eNB->rx_fh = rx_fh_if4p5; + eNB->start_rf = NULL; + eNB->start_if = start_if; + eNB->fh_asynch = (eNB->node_timing == synch_to_other) ? fh_if4p5_asynch_UL : NULL; + eNB->rfdevice.host_type = BBU_HOST; + eNB->ifdevice.host_type = BBU_HOST; + ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params+CC_id)); + printf("openair0_transport_init returns %d for CC_id %d\n",ret,CC_id); + if (ret<0) { + printf("Exiting, cannot initialize transport protocol\n"); + exit(-1); + } + malloc_IF4p5_buffer(eNB); + + break; + case NGFI_RAU_IF4p5: + eNB->do_prach = do_prach; + eNB->fep = NULL; + + eNB->td = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; + eNB->te = dlsch_encoding;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding; + eNB->proc_uespec_rx = phy_procedures_eNB_uespec_RX; + eNB->proc_tx = proc_tx_high; + eNB->tx_fh = tx_fh_if4p5; + eNB->rx_fh = rx_fh_if4p5; + eNB->fh_asynch = (eNB->node_timing == synch_to_other) ? fh_if4p5_asynch_UL : NULL; + eNB->start_rf = NULL; + eNB->start_if = start_if; + + eNB->rfdevice.host_type = BBU_HOST; + eNB->ifdevice.host_type = BBU_HOST; + ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params+CC_id)); + printf("openair0_transport_init returns %d for CC_id %d\n",ret,CC_id); + if (ret<0) { + printf("Exiting, cannot initialize transport protocol\n"); + exit(-1); + } + break; + malloc_IF4p5_buffer(eNB); + + } + } + + if (setup_eNB_buffers(PHY_vars_eNB_g[inst],&openair0_cfg[CC_id])!=0) { + printf("Exiting, cannot initialize eNodeB Buffers\n"); + exit(-1); + } + + init_eNB_proc(inst); + } + + sleep(1); + LOG_D(HW,"[lte-softmodem.c] eNB threads created\n"); + + +} + void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst,eth_params_t *eth_params,int single_thread_flag) { int CC_id;