Merge remote-tracking branch 'origin/develop' into develop-nos1-fixes

Conflicts:
	openair1/SCHED/fapi_l1.c
	openair1/SCHED/phy_procedures_lte_eNb.c
	openair2/LAYER2/MAC/config.c
This commit is contained in:
Raymond Knopp
2018-01-16 03:55:37 -08:00
127 changed files with 70174 additions and 1477 deletions
+12 -10
View File
@@ -283,12 +283,11 @@ int64_t wrap_ts = 0;
unsigned int u_sf_mode = 0; // 1=record, 2=replay
unsigned int u_sf_record = 0; // record mode
unsigned int u_sf_replay = 0; // replay mode
char u_sf_filename[1024]; // subframes file path
char u_sf_filename[1024] = ""; // subframes file path
unsigned int u_sf_max = DEF_NB_SF; // max number of recorded subframes
unsigned int u_sf_loops = DEF_SF_NB_LOOP; // number of loops in replay mode
unsigned int u_sf_read_delay = DEF_SF_DELAY_READ; // read delay in replay mode
unsigned int u_sf_write_delay = DEF_SF_DELAY_WRITE; // write delay in replay mode
char *tmp_filename[1]; // use an array of pointer (libconfig does not seems to work with char array yet)
char config_opt_sf_file[] = CONFIG_OPT_SF_FILE;
char config_def_sf_file[] = DEF_SF_FILE;
@@ -420,10 +419,10 @@ static void trx_usrp_end(openair0_device *device) {
/*! \brief Called to send samples to the USRP RF target
@param device pointer to the device structure specific to the RF hardware target
@param timestamp The timestamp at whicch the first sample MUST be sent
@param timestamp The timestamp at which the first sample MUST be sent
@param buff Buffer which holds the samples
@param nsamps number of samples to be sent
@param antenna_id index of the antenna if the device has multiple anteannas
@param antenna_id index of the antenna if the device has multiple antennas
@param flags flags must be set to TRUE if timestamp parameter needs to be applied
*/
static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) {
@@ -837,7 +836,7 @@ int trx_usrp_recplay_config_init(paramdef_t *usrp_recplay_params) {
memcpy(usrp_recplay_params[0].optname, config_opt_sf_file, strlen(config_opt_sf_file));
usrp_recplay_params[0].helpstr = config_hlp_sf_file;
usrp_recplay_params[0].paramflags=PARAMFLAG_NOFREE;
usrp_recplay_params[0].strptr=(char **)&tmp_filename[0];
usrp_recplay_params[0].strptr=(char **)&u_sf_filename;
usrp_recplay_params[0].defstrval = NULL;
usrp_recplay_params[0].type=TYPE_STRING;
usrp_recplay_params[0].numelt=sizeof(u_sf_filename);
@@ -912,16 +911,13 @@ extern "C" {
// end to check
memset(usrp_recplay_params, 0, 7*sizeof(paramdef_t));
memset(&u_sf_filename[0], 0, 1024);
tmp_filename[0] = u_sf_filename;
if (trx_usrp_recplay_config_init(usrp_recplay_params) != 0) {
std::cerr << "USRP device record/replay mode configuration error exiting" << std::endl;
return -1;
}
config_process_cmdline(usrp_recplay_params,sizeof(usrp_recplay_params)/sizeof(paramdef_t),NULL);
if (strlen(tmp_filename[0]) != 0) {
(void) strcpy(u_sf_filename, tmp_filename[0]);
} else {
if (strlen(u_sf_filename) == 0) {
(void) strcpy(u_sf_filename, DEF_SF_FILE);
}
@@ -1012,9 +1008,13 @@ extern "C" {
//s->usrp->set_master_clock_rate(usrp_master_clock);
openair0_cfg[0].rx_gain_calib_table = calib_table_x310;
#if defined(USRP_REC_PLAY)
std::cerr << "-- Using calibration table: calib_table_x310" << std::endl; // Bell Labs info
#endif
#endif
LOG_I(PHY,"%s() sample_rate:%u\n", __FUNCTION__, (int)openair0_cfg[0].sample_rate);
switch ((int)openair0_cfg[0].sample_rate) {
case 30720000:
// from usrp_time_offset
@@ -1157,6 +1157,8 @@ extern "C" {
s->usrp->set_tx_rate(openair0_cfg[0].sample_rate,i);
s->usrp->set_tx_freq(openair0_cfg[0].tx_freq[i],i);
s->usrp->set_tx_gain(gain_range_tx.stop()-openair0_cfg[0].tx_gain[i],i);
LOG_I(PHY,"USRP TX_GAIN:%3.2lf gain_range:%3.2lf tx_gain:%3.2lf\n", gain_range_tx.stop()-openair0_cfg[0].tx_gain[i], gain_range_tx.stop(), openair0_cfg[0].tx_gain[i]);
}
}
+2
View File
@@ -42,6 +42,8 @@
int create_tasks(uint32_t enb_nb, uint32_t ue_nb)
{
LOG_D(ENB_APP, "%s(enb_nb:%d ue_nb:%d)\n", __FUNCTION__, enb_nb, ue_nb);
itti_wait_ready(1);
if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) {
LOG_E(PDCP, "Create task for L2L1 failed\n");
@@ -1,3 +1,20 @@
log_config = {
global_log_level ="debug";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="low";
mac_log_level ="info";
mac_log_verbosity ="medium";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
};
L1s = (
{
num_cc = 1;
@@ -6,9 +23,9 @@ L1s = (
remote_n_address = "127.0.0.2";
local_n_address = "127.0.0.1";
local_n_portc = 50000;
remote_n_portc = 50000;
local_n_portd = 50001;
remote_n_portd = 50001;
remote_n_portc = 50001;
local_n_portd = 50010;
remote_n_portd = 50011;
}
);
@@ -156,8 +156,25 @@ eNBs =
ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.5/24";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
log_config :
MACRLCs = (
{
num_cc = 1;
local_s_if_name = "lo";
remote_s_address = "127.0.0.1";
local_s_address = "127.0.0.2";
local_s_portc = 50001;
remote_s_portc = 50000;
local_s_portd = 50011;
remote_s_portd = 50010;
tr_s_preference = "nfapi";
tr_n_preference = "local_RRC";
}
);
log_config =
{
global_log_level ="info";
global_log_verbosity ="medium";
@@ -174,21 +191,3 @@ eNBs =
rrc_log_level ="info";
rrc_log_verbosity ="medium";
};
}
);
MACRLCs = (
{
num_cc = 1;
local_s_if_name = "lo";
remote_s_address = "127.0.0.1";
local_s_address = "127.0.0.2";
local_s_portc = 50000;
remote_s_portc = 50000;
local_s_portd = 50001;
remote_s_portd = 50001;
tr_s_preference = "nfapi";
tr_n_preference = "local_RRC";
}
);
+188 -38
View File
@@ -121,11 +121,14 @@ extern int transmission_mode;
extern int oaisim_flag;
uint16_t sf_ahead=4;
//pthread_t main_eNB_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
/* mutex, cond and variable to serialize phy proc TX calls
@@ -151,48 +154,147 @@ void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe);
void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe);
#endif
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)
static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_name) {
static double cpu_freq_GHz = 0.0;
if (cpu_freq_GHz == 0.0)
cpu_freq_GHz = get_cpu_freq_GHz();
start_meas(&softmodem_stats_rxtx_sf);
// *******************************************************************
if (nfapi_mode == 1) {
// I am a PNF and I need to let nFAPI know that we have a (sub)frame tick
uint16_t frame = proc->frame_rx;
uint16_t subframe = proc->subframe_rx;
//add_subframe(&frame, &subframe, 4);
//oai_subframe_ind(proc->frame_tx, proc->subframe_tx);
//LOG_D(PHY, "oai_subframe_ind(frame:%u, subframe:%d) - NOT CALLED ********\n", frame, subframe);
start_meas(&nfapi_meas);
oai_subframe_ind(frame, subframe);
stop_meas(&nfapi_meas);
if (eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus||
eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs ||
eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs ||
eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles ||
eNB->UL_INFO.cqi_ind.number_of_cqis
) {
LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d preambles:%05d:%d cqis:%d] RX:%04d%d TX:%04d%d num_pdcch_symbols:%d\n",
NFAPI_SFNSF2DEC(eNB->UL_INFO.rx_ind.sfn_sf), eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus,
NFAPI_SFNSF2DEC(eNB->UL_INFO.harq_ind.sfn_sf), eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs,
NFAPI_SFNSF2DEC(eNB->UL_INFO.crc_ind.sfn_sf), eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs,
NFAPI_SFNSF2DEC(eNB->UL_INFO.rach_ind.sfn_sf), eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles,
eNB->UL_INFO.cqi_ind.number_of_cqis,
proc->frame_rx, proc->subframe_rx,
proc->frame_tx, proc->subframe_tx, eNB->pdcch_vars[proc->subframe_tx&1].num_pdcch_symbols);
}
}
if (nfapi_mode == 1 && eNB->pdcch_vars[proc->subframe_tx&1].num_pdcch_symbols == 0) {
LOG_E(PHY, "eNB->pdcch_vars[proc->subframe_tx&1].num_pdcch_symbols == 0");
return 0;
}
// ****************************************
// Common RX procedures subframe n
T(T_ENB_PHY_DL_TICK, T_INT(eNB->Mod_id), T_INT(proc->frame_tx), T_INT(proc->subframe_tx));
// if this is IF5 or 3GPP_eNB
if (eNB->RU_list[0]->function < NGFI_RAU_IF4p5) {
if (eNB && eNB->RU_list && eNB->RU_list[0] && eNB->RU_list[0]->function < NGFI_RAU_IF4p5) {
wakeup_prach_eNB(eNB,NULL,proc->frame_rx,proc->subframe_rx);
#ifdef Rel14
wakeup_prach_eNB_br(eNB,NULL,proc->frame_rx,proc->subframe_rx);
#endif
}
// UE-specific RX processing for subframe n
phy_procedures_eNB_uespec_RX(eNB, proc, no_relay );
if (nfapi_mode == 0 || nfapi_mode == 1) {
phy_procedures_eNB_uespec_RX(eNB, proc, no_relay );
}
pthread_mutex_lock(&eNB->UL_INFO_mutex);
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);
pthread_mutex_unlock(&eNB->UL_INFO_mutex);
// *****************************************
// TX processing for subframe n+4
// TX processing for subframe n+sf_ahead
// 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)
// *****************************************
//if (wait_CCs(proc)<0) return(-1);
if (oai_exit) return(-1);
phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1);
if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) return(-1);
stop_meas( &softmodem_stats_rxtx_sf );
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);
#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(eNB->phy_proc),
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),
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(eNB->dlsch_encoding_stats),
TICK_TO_US(eNB->dlsch_modulation_stats),
TICK_TO_US(eNB->dlsch_scrambling_stats),
TICK_TO_US(eNB->dlsch_rate_matching_stats),
TICK_TO_US(eNB->dlsch_turbo_encoding_stats),
TICK_TO_US(eNB->dlsch_interleaving_stats),
TICK_TO_US(eNB->rx_dft_stats));
LOG_D(PHY," ulsch[ch:%lld freq:%lld dec:%lld demod:%lld ru:%lld ",
TICK_TO_US(eNB->ulsch_channel_estimation_stats),
TICK_TO_US(eNB->ulsch_freq_offset_estimation_stats),
TICK_TO_US(eNB->ulsch_decoding_stats),
TICK_TO_US(eNB->ulsch_demodulation_stats),
TICK_TO_US(eNB->ulsch_rate_unmatching_stats));
LOG_D(PHY, "td:%lld dei:%lld dem:%lld llr:%lld tci:%lld ",
TICK_TO_US(eNB->ulsch_turbo_decoding_stats),
TICK_TO_US(eNB->ulsch_deinterleaving_stats),
TICK_TO_US(eNB->ulsch_demultiplexing_stats),
TICK_TO_US(eNB->ulsch_llr_stats),
TICK_TO_US(eNB->ulsch_tc_init_stats));
LOG_D(PHY, "tca:%lld tcb:%lld tcg:%lld tce:%lld l1:%lld l2:%lld]\n\n",
TICK_TO_US(eNB->ulsch_tc_alpha_stats),
TICK_TO_US(eNB->ulsch_tc_beta_stats),
TICK_TO_US(eNB->ulsch_tc_gamma_stats),
TICK_TO_US(eNB->ulsch_tc_ext_stats),
TICK_TO_US(eNB->ulsch_tc_intl1_stats),
TICK_TO_US(eNB->ulsch_tc_intl2_stats)
);
#endif
return(0);
}
@@ -218,7 +320,7 @@ static void* eNB_thread_rxtx( void* param ) {
eNB_thread_rxtx_status = 0;
sprintf(thread_name,"RXn_TXnp4_%d\n",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1);
sprintf(thread_name,"RXn_TXnp4_%d",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1);
thread_top_init(thread_name,1,850000L,1000000L,2000000L);
while (!oai_exit) {
@@ -228,13 +330,16 @@ static void* eNB_thread_rxtx( void* param ) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 1 );
if (oai_exit) break;
if (eNB->CC_id==0)
{
if (rxtx(eNB,proc,thread_name) < 0) break;
}
if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break;
} // while !oai_exit
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
@@ -278,21 +383,16 @@ void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string)
proc->subframe_rx = subframe_rx;
if (!oai_exit) {
LOG_D(PHY,"eNB_top in %p (proc %p, CC_id %d), frame %d, subframe %d, instance_cnt_prach %d\n",
(void*)pthread_self(), proc, eNB->CC_id, proc->frame_rx,proc->subframe_rx,proc->instance_cnt_prach);
T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
proc_rxtx->subframe_rx = proc->subframe_rx;
proc_rxtx->frame_rx = proc->frame_rx;
proc_rxtx->subframe_tx = (proc->subframe_rx+4)%10;
proc_rxtx->frame_tx = (proc->subframe_rx>5) ? (1+proc->frame_rx)&1023 : proc->frame_rx;
proc_rxtx->subframe_tx = (proc->subframe_rx+sf_ahead)%10;
proc_rxtx->frame_tx = (proc->subframe_rx>(9-sf_ahead)) ? (1+proc->frame_rx)&1023 : proc->frame_rx;
proc->frame_tx = proc_rxtx->frame_tx;
proc_rxtx->timestamp_tx = proc->timestamp_tx;
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);
LOG_D(PHY,"eNB_top out %p (proc %p, CC_id %d), frame %d, subframe %d, instance_cnt_prach %d\n",
(void*)pthread_self(), proc, eNB->CC_id, proc->frame_rx,proc->subframe_rx,proc->instance_cnt_prach);
}
}
@@ -318,6 +418,7 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {
}
}
if (proc->RU_mask != (1<<eNB->num_RU)-1) { // not all RUs have provided their information so return
LOG_E(PHY,"Not all RUs have provided their info\n");
pthread_mutex_unlock(&proc->mutex_RU);
return(0);
}
@@ -334,7 +435,7 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {
/* accept some delay in processing - up to 5ms */
for (i = 0; i < 10 && proc_rxtx->instance_cnt_rxtx == 0; i++) {
LOG_W( PHY,"[eNB] Frame %d, eNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", proc_rxtx->frame_tx, proc_rxtx->instance_cnt_rxtx);
LOG_W( PHY,"[eNB] Frame %d Subframe %d, eNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", proc_rxtx->frame_tx, proc_rxtx->subframe_tx, proc_rxtx->instance_cnt_rxtx);
usleep(500);
}
if (proc_rxtx->instance_cnt_rxtx == 0) {
@@ -342,7 +443,7 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {
return(-1);
}
// wake up TX for subframe n+4
// wake up TX for subframe n+sf_ahead
// lock the TX mutex and make sure the thread is ready
if (pthread_mutex_timedlock(&proc_rxtx->mutex_rxtx,&wait) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", proc_rxtx->subframe_rx&1,proc_rxtx->instance_cnt_rxtx );
@@ -356,14 +457,14 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {
// TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
// transmitted timestamp of the next TX slot (first).
// The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
// we want to generate subframe (n+4), so TS_tx = TX_rx+4*samples_per_tti,
// and proc->subframe_tx = proc->subframe_rx+4
proc_rxtx->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti);
// 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
proc_rxtx->timestamp_tx = proc->timestamp_rx + (sf_ahead*fp->samples_per_tti);
proc_rxtx->frame_rx = proc->frame_rx;
proc_rxtx->subframe_rx = proc->subframe_rx;
proc_rxtx->frame_tx = (proc_rxtx->subframe_rx > 5) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx;
proc_rxtx->subframe_tx = (proc_rxtx->subframe_rx + 4)%10;
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;
// the thread can now be woken up
if (pthread_cond_signal(&proc_rxtx->cond_rxtx) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n");
@@ -593,10 +694,12 @@ void init_eNB_proc(int inst) {
pthread_attr_t *attr_prach_br=NULL;
#endif
LOG_I(PHY,"%s(inst:%d) RC.nb_CC[inst]:%d \n",__FUNCTION__,inst,RC.nb_CC[inst]);
for (CC_id=0; CC_id<RC.nb_CC[inst]; CC_id++) {
eNB = RC.eNB[inst][CC_id];
#ifndef OCP_FRAMEWORK
LOG_I(PHY,"Initializing eNB processes %d CC_id %d \n",inst,CC_id);
LOG_I(PHY,"Initializing eNB processes instance:%d CC_id %d \n",inst,CC_id);
#endif
proc = &eNB->proc;
@@ -652,6 +755,8 @@ void init_eNB_proc(int inst) {
// attr_te = &proc->attr_te;
#endif
LOG_I(PHY,"eNB->single_thread_flag:%d\n", eNB->single_thread_flag);
if (eNB->single_thread_flag==0) {
pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, &proc_rxtx[0] );
pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, eNB_thread_rxtx, &proc_rxtx[1] );
@@ -787,6 +892,8 @@ void init_transport(PHY_VARS_eNB *eNB) {
int j;
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
LOG_I(PHY, "Initialise transport\n");
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i);
for (j=0; j<2; j++) {
@@ -795,8 +902,8 @@ void init_transport(PHY_VARS_eNB *eNB) {
LOG_E(PHY,"Can't get eNB dlsch structures for UE %d \n", i);
exit(-1);
} else {
LOG_D(PHY,"dlsch[%d][%d] => %p\n",i,j,eNB->dlsch[i][j]);
eNB->dlsch[i][j]->rnti=0;
LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,eNB->dlsch[i][j], eNB->dlsch[i][j]->rnti);
}
}
@@ -849,20 +956,33 @@ void init_eNB_afterRU(void) {
int inst,CC_id,ru_id,i,aa;
PHY_VARS_eNB *eNB;
LOG_I(PHY,"%s() RC.nb_inst:%d\n", __FUNCTION__, RC.nb_inst);
for (inst=0;inst<RC.nb_inst;inst++) {
LOG_I(PHY,"RC.nb_CC[inst]:%d\n", RC.nb_CC[inst]);
for (CC_id=0;CC_id<RC.nb_CC[inst];CC_id++) {
LOG_I(PHY,"RC.nb_CC[inst:%d][CC_id:%d]:%p\n", inst, CC_id, RC.eNB[inst][CC_id]);
eNB = RC.eNB[inst][CC_id];
phy_init_lte_eNB(eNB,0,0);
// map antennas and PRACH signals to eNB RX
AssertFatal(eNB->num_RU>0,"Number of RU attached to eNB %d is zero\n",eNB->Mod_id);
if (0) AssertFatal(eNB->num_RU>0,"Number of RU attached to eNB %d is zero\n",eNB->Mod_id);
LOG_I(PHY,"Mapping RX ports from %d RUs to eNB %d\n",eNB->num_RU,eNB->Mod_id);
eNB->frame_parms.nb_antennas_rx = 0;
LOG_I(PHY,"Overwriting eNB->prach_vars.rxsigF[0]:%p\n", eNB->prach_vars.rxsigF[0]);
eNB->prach_vars.rxsigF[0] = (int16_t**)malloc16(64*sizeof(int16_t*));
#ifdef Rel14
for (int ce_level=0;ce_level<4;ce_level++)
eNB->prach_vars_br.rxsigF[ce_level] = (int16_t**)malloc16(64*sizeof(int16_t*));
for (int ce_level=0;ce_level<4;ce_level++) {
LOG_I(PHY,"Overwriting eNB->prach_vars_br.rxsigF.rxsigF[0]:%p\n", eNB->prach_vars_br.rxsigF[ce_level]);
eNB->prach_vars_br.rxsigF[ce_level] = (int16_t**)malloc16(64*sizeof(int16_t*));
}
#endif
LOG_I(PHY,"eNB->num_RU:%d\n", eNB->num_RU);
for (ru_id=0,aa=0;ru_id<eNB->num_RU;ru_id++) {
eNB->frame_parms.nb_antennas_rx += eNB->RU_list[ru_id]->nb_rx;
@@ -884,6 +1004,36 @@ void init_eNB_afterRU(void) {
eNB->common_vars.rxdataF[aa] = eNB->RU_list[ru_id]->common.rxdataF[i];
}
}
/* TODO: review this code, there is something wrong.
* In monolithic mode, we come here with nb_antennas_rx == 0
* (not tested in other modes).
*/
if (eNB->frame_parms.nb_antennas_rx < 1)
{
LOG_I(PHY, "%s() ************* DJP ***** eNB->frame_parms.nb_antennas_rx:%d - GOING TO HARD CODE TO 1", __FUNCTION__, eNB->frame_parms.nb_antennas_rx);
eNB->frame_parms.nb_antennas_rx = 1;
}
else
{
//LOG_I(PHY," Delete code\n");
}
if (eNB->frame_parms.nb_antennas_tx < 1)
{
LOG_I(PHY, "%s() ************* DJP ***** eNB->frame_parms.nb_antennas_tx:%d - GOING TO HARD CODE TO 1", __FUNCTION__, eNB->frame_parms.nb_antennas_tx);
eNB->frame_parms.nb_antennas_tx = 1;
}
else
{
//LOG_I(PHY," Delete code\n");
}
AssertFatal(eNB->frame_parms.nb_antennas_rx >0,
"inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,eNB->frame_parms.nb_antennas_rx);
LOG_I(PHY,"inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,eNB->frame_parms.nb_antennas_rx);
@@ -911,7 +1061,10 @@ void init_eNB(int single_thread_flag,int wait_for_sync) {
int inst;
PHY_VARS_eNB *eNB;
LOG_I(PHY,"[lte-softmodem.c] eNB structure about to allocated RC.nb_L1_inst:%d RC.nb_L1_CC[0]:%d\n",RC.nb_L1_inst,RC.nb_L1_CC[0]);
if (RC.eNB == NULL) RC.eNB = (PHY_VARS_eNB***) malloc(RC.nb_L1_inst*sizeof(PHY_VARS_eNB **));
LOG_I(PHY,"[lte-softmodem.c] eNB structure RC.eNB allocated\n");
for (inst=0;inst<RC.nb_L1_inst;inst++) {
if (RC.eNB[inst] == NULL) RC.eNB[inst] = (PHY_VARS_eNB**) malloc(RC.nb_CC[inst]*sizeof(PHY_VARS_eNB *));
for (CC_id=0;CC_id<RC.nb_L1_CC[inst];CC_id++) {
@@ -921,6 +1074,7 @@ void init_eNB(int single_thread_flag,int wait_for_sync) {
eNB->single_thread_flag = single_thread_flag;
LOG_I(PHY,"Initializing eNB %d CC_id %d single_thread_flag:%d\n",inst,CC_id,single_thread_flag);
#ifndef OCP_FRAMEWORK
LOG_I(PHY,"Initializing eNB %d CC_id %d\n",inst,CC_id);
#endif
@@ -937,10 +1091,10 @@ void init_eNB(int single_thread_flag,int wait_for_sync) {
memset((void*)&eNB->UL_INFO,0,sizeof(eNB->UL_INFO));
memset((void*)&eNB->Sched_INFO,0,sizeof(eNB->Sched_INFO));
LOG_I(PHY,"Setting indication lists\n");
eNB->UL_INFO.rx_ind.rx_pdu_list = eNB->rx_pdu_list;
eNB->UL_INFO.crc_ind.crc_pdu_list = eNB->crc_pdu_list;
eNB->UL_INFO.sr_ind.sr_pdu_list = eNB->sr_pdu_list;
eNB->UL_INFO.harq_ind.harq_pdu_list = eNB->harq_pdu_list;
eNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = eNB->rx_pdu_list;
eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = eNB->crc_pdu_list;
eNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = eNB->sr_pdu_list;
eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list;
eNB->UL_INFO.cqi_ind.cqi_pdu_list = eNB->cqi_pdu_list;
eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list;
eNB->prach_energy_counter = 0;
@@ -948,11 +1102,7 @@ void init_eNB(int single_thread_flag,int wait_for_sync) {
}
LOG_I(PHY,"[lte-softmodem.c] eNB structure allocated\n");
}
+105 -57
View File
@@ -129,6 +129,7 @@ int attach_rru(RU_t *ru);
int connect_rau(RU_t *ru);
extern uint16_t sf_ahead;
/*************************************************************/
/* Functions to attach and configure RRU */
@@ -388,8 +389,8 @@ void fh_if4p5_south_in(RU_t *ru,int *frame,int *subframe) {
proc->frame_rx = f;
proc->timestamp_rx = ((proc->frame_rx * 10) + proc->subframe_rx ) * fp->samples_per_tti ;
// proc->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti);
proc->subframe_tx = (sf+4)%10;
proc->frame_tx = (sf>5) ? (f+1)&1023 : f;
proc->subframe_tx = (sf+sf_ahead)%10;
proc->frame_tx = (sf>(9-sf_ahead)) ? (f+1)&1023 : f;
if (proc->first_rx == 0) {
if (proc->subframe_rx != *subframe){
@@ -591,6 +592,7 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *subframe) {
uint32_t symbol_number,symbol_mask,symbol_mask_full;
int subframe_tx,frame_tx;
LOG_D(PHY, "%s(ru:%p frame, subframe)\n", __FUNCTION__, ru);
symbol_number = 0;
symbol_mask = 0;
symbol_mask_full = ((subframe_select(fp,*subframe) == SF_S) ? (1<<fp->dl_symbols_in_S_subframe) : (1<<fp->symbols_per_tti))-1;
@@ -668,6 +670,7 @@ void fh_if4p5_north_out(RU_t *ru) {
stop_meas(&ru->tx_fhaul);
}
void rx_rf(RU_t *ru,int *frame,int *subframe) {
RU_proc_t *proc = &ru->proc;
@@ -679,7 +682,7 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
for (i=0; i<ru->nb_rx; i++)
rxp[i] = (void*)&ru->common.rxdata[i][*subframe*fp->samples_per_tti];
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 );
old_ts = proc->timestamp_rx;
@@ -694,8 +697,9 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
proc->timestamp_rx = ts-ru->ts_offset;
AssertFatal(rxs == fp->samples_per_tti,
"rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_tti,rxs);
//AssertFatal(rxs == fp->samples_per_tti,
//"rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_tti,rxs);
if (rxs != fp->samples_per_tti) LOG_E(PHY, "rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_tti,rxs);
if (proc->first_rx == 1) {
ru->ts_offset = proc->timestamp_rx;
@@ -713,9 +717,9 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10;
// synchronize first reception to frame 0 subframe 0
proc->timestamp_tx = proc->timestamp_rx+(4*fp->samples_per_tti);
proc->subframe_tx = (proc->subframe_rx+4)%10;
proc->frame_tx = (proc->subframe_rx>5) ? (proc->frame_rx+1)&1023 : proc->frame_rx;
proc->timestamp_tx = proc->timestamp_rx+(sf_ahead*fp->samples_per_tti);
proc->subframe_tx = (proc->subframe_rx+sf_ahead)%10;
proc->frame_tx = (proc->subframe_rx>(9-sf_ahead)) ? (proc->frame_rx+1)&1023 : proc->frame_rx;
LOG_D(PHY,"RU %d/%d TS %llu (off %d), frame %d, subframe %d\n",
ru->idx,
@@ -752,10 +756,10 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff );
if (rxs != fp->samples_per_tti)
exit_fun( "problem receiving samples" );
{
//exit_fun( "problem receiving samples" );
LOG_E(PHY, "problem receiving samples");
}
}
@@ -778,7 +782,6 @@ void tx_rf(RU_t *ru) {
if ((SF_type == SF_DL) ||
(SF_type == SF_S)) {
int siglen=fp->samples_per_tti,flags=1;
if (SF_type == SF_S) {
@@ -945,22 +948,24 @@ static void* ru_thread_prach( void* param ) {
thread_top_init("ru_thread_prach",1,500000L,1000000L,20000000L);
while (RC.ru_mask>0) {
usleep(1e6);
LOG_I(PHY,"%s() RACH waiting for RU to be configured\n", __FUNCTION__);
}
LOG_I(PHY,"%s() RU configured - RACH processing thread running\n", __FUNCTION__);
while (!oai_exit) {
if (oai_exit) break;
if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 );
rx_prach(NULL,
ru,
NULL,
NULL,
NULL,
proc->frame_prach,
0
prach_procedures(
ru->eNB_list[0]
#ifdef Rel14
,0
,0
#endif
);
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 );
if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break;
}
@@ -1110,21 +1115,29 @@ void wakeup_eNBs(RU_t *ru) {
int i;
PHY_VARS_eNB **eNB_list = ru->eNB_list;
LOG_D(PHY,"wakeup_eNBs (num %d) for RU %d\n",ru->num_eNB,ru->idx);
LOG_D(PHY,"wakeup_eNBs (num %d) for RU %d ru->eNB_top:%p\n",ru->num_eNB,ru->idx, ru->eNB_top);
if (ru->num_eNB==1) {
if (ru->num_eNB==1 && ru->eNB_top!=0) {
// call eNB function directly
char string[20];
sprintf(string,"Incoming RU %d",ru->idx);
LOG_D(PHY,"RU %d Waking up eNB\n",ru->idx);
LOG_D(PHY,"RU %d Call eNB_top\n",ru->idx);
ru->eNB_top(eNB_list[0],ru->proc.frame_rx,ru->proc.subframe_rx,string);
}
else {
LOG_D(PHY,"ru->num_eNB:%d\n", ru->num_eNB);
for (i=0;i<ru->num_eNB;i++)
if (ru->wakeup_rxtx(eNB_list[i],ru) < 0)
{
LOG_D(PHY,"ru->wakeup_rxtx:%p\n", ru->wakeup_rxtx);
if (ru->wakeup_rxtx!=0 && ru->wakeup_rxtx(eNB_list[i],ru) < 0)
{
LOG_E(PHY,"could not wakeup eNB rxtx process for subframe %d\n", ru->proc.subframe_rx);
}
}
}
}
@@ -1145,6 +1158,10 @@ static inline int wakeup_prach_ru(RU_t *ru) {
ru->proc.frame_prach = ru->proc.frame_rx;
ru->proc.subframe_prach = ru->proc.subframe_rx;
// DJP - think prach_procedures() is looking at eNB frame_prach
ru->eNB_list[0]->proc.frame_prach = ru->proc.frame_rx;
ru->eNB_list[0]->proc.subframe_prach = ru->proc.subframe_rx;
LOG_D(PHY,"RU %d: waking up PRACH thread\n",ru->idx);
// the thread can now be woken up
AssertFatal(pthread_cond_signal(&ru->proc.cond_prach) == 0, "ERROR pthread_cond_signal for RU prach thread\n");
@@ -1371,7 +1388,6 @@ static void* ru_thread( void* param ) {
init_frame_parms(&ru->frame_parms,1);
phy_init_RU(ru);
ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg);
}
if (setup_RU_buffers(ru)!=0) {
@@ -1427,23 +1443,29 @@ static void* ru_thread( void* param ) {
subframe++;
}
LOG_D(PHY,"RU thread (proc %p), frame %d (%p), subframe %d (%p)\n",
proc, frame,&frame,subframe,&subframe);
// synchronization on input FH interface, acquire signals/data and block
if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&subframe);
else AssertFatal(1==0, "No fronthaul interface at south port");
LOG_D(PHY,"AFTER fh_south_in - SFN/SF:%d%d RU->proc[RX:%d%d TX:%d%d] RC.eNB[0][0]:[RX:%d%d TX(SFN):%d]\n",
frame,subframe,
proc->frame_rx,proc->subframe_rx,
proc->frame_tx,proc->subframe_tx,
RC.eNB[0][0]->proc.frame_rx,RC.eNB[0][0]->proc.subframe_rx,
RC.eNB[0][0]->proc.frame_tx);
LOG_D(PHY,"RU thread (do_prach %d, is_prach_subframe %d), received frame %d, subframe %d\n",
ru->do_prach,
is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx),
proc->frame_rx,proc->subframe_rx);
LOG_D(PHY,"RU thread (do_prach %d, is_prach_subframe %d), received frame %d, subframe %d\n",
ru->do_prach,
is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx),
proc->frame_rx,proc->subframe_rx);
if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)==1)) wakeup_prach_ru(ru);
if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)==1)) {
wakeup_prach_ru(ru);
}
#ifdef Rel14
else if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>1)) wakeup_prach_ru_br(ru);
else if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>1)) {
wakeup_prach_ru_br(ru);
}
#endif
// adjust for timing offset between RU
@@ -1460,7 +1482,7 @@ static void* ru_thread( void* param ) {
// wakeup all eNB processes waiting for this RU
if (ru->num_eNB>0) wakeup_eNBs(ru);
// wait until eNBs are finished subframe RX n and TX n+4
// wait until eNBs are finished subframe RX n and TX n+sf_ahead
wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread");
@@ -1473,7 +1495,6 @@ static void* ru_thread( void* param ) {
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
if (ru->fh_north_out) ru->fh_north_out(ru);
}
@@ -1663,6 +1684,10 @@ void init_RU_proc(RU_t *ru) {
pthread_setname_np( proc->pthread_FH, name );
}
else if (ru->function == eNodeB_3GPP && ru->if_south == LOCAL_RF) { // DJP - need something else to distinguish between monolithic and PNF
LOG_I(PHY,"%s() DJP - added creation of pthread_prach\n", __FUNCTION__);
pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void*)ru );
}
if (get_nprocs()>=2) {
if (ru->feprx) init_fep_thread(ru,NULL);
@@ -1672,10 +1697,6 @@ void init_RU_proc(RU_t *ru) {
}
int check_capabilities(RU_t *ru,RRU_capabilities_t *cap) {
FH_fmt_options_t fmt = cap->FH_fmt;
@@ -1878,10 +1899,13 @@ void init_RU(char *rf_config_file) {
RCconfig_RU();
LOG_I(PHY,"number of L1 instances %d, number of RU %d, number of CPU cores %d\n",RC.nb_L1_inst,RC.nb_RU,get_nprocs());
for (i=0;i<RC.nb_L1_inst;i++)
for (CC_id=0;CC_id<RC.nb_CC[i];CC_id++) RC.eNB[i][CC_id]->num_RU=0;
if (RC.nb_CC != 0)
for (i=0;i<RC.nb_L1_inst;i++)
for (CC_id=0;CC_id<RC.nb_CC[i];CC_id++) RC.eNB[i][CC_id]->num_RU=0;
LOG_D(PHY,"Process RUs RC.nb_RU:%d\n",RC.nb_RU);
for (ru_id=0;ru_id<RC.nb_RU;ru_id++) {
LOG_D(PHY,"Process RC.ru[%d]\n",ru_id);
ru = RC.ru[ru_id];
ru->rf_config_file = rf_config_file;
ru->idx = ru_id;
@@ -1889,24 +1913,47 @@ void init_RU(char *rf_config_file) {
// use eNB_list[0] as a reference for RU frame parameters
// NOTE: multiple CC_id are not handled here yet!
LOG_D(PHY, "%s() RC.ru[%d].num_eNB:%d ru->eNB_list[0]:%p RC.eNB[0][0]:%p rf_config_file:%s\n", __FUNCTION__, ru_id, ru->num_eNB, ru->eNB_list[0], RC.eNB[0][0], ru->rf_config_file);
if (ru->eNB_list[0] == 0)
{
LOG_E(PHY,"%s() DJP - ru->eNB_list ru->num_eNB are not initialized - so do it manually\n", __FUNCTION__);
ru->eNB_list[0] = RC.eNB[0][0];
ru->num_eNB=1;
//
// DJP - feptx_prec() / feptx_ofdm() parses the eNB_list (based on num_eNB) and copies the txdata_F to txdata in RU
//
}
else
{
LOG_E(PHY,"DJP - delete code above this %s:%d\n", __FILE__, __LINE__);
}
eNB0 = ru->eNB_list[0];
if ((ru->function != NGFI_RRU_IF5) && (ru->function != NGFI_RRU_IF4p5))
AssertFatal(eNB0!=NULL,"eNB0 is null!\n");
LOG_D(PHY, "RU FUnction:%d ru->if_south:%d\n", ru->function, ru->if_south);
LOG_D(PHY, "eNB0:%p\n", eNB0);
if (eNB0)
{
if ((ru->function != NGFI_RRU_IF5) && (ru->function != NGFI_RRU_IF4p5))
AssertFatal(eNB0!=NULL,"eNB0 is null!\n");
if (eNB0) {
LOG_I(PHY,"Copying frame parms from eNB %d to ru %d\n",eNB0->Mod_id,ru->idx);
memcpy((void*)&ru->frame_parms,(void*)&eNB0->frame_parms,sizeof(LTE_DL_FRAME_PARMS));
if (eNB0) {
LOG_I(PHY,"Copying frame parms from eNB %d to ru %d\n",eNB0->Mod_id,ru->idx);
memcpy((void*)&ru->frame_parms,(void*)&eNB0->frame_parms,sizeof(LTE_DL_FRAME_PARMS));
// attach all RU to all eNBs in its list/
for (i=0;i<ru->num_eNB;i++) {
eNB0 = ru->eNB_list[i];
eNB0->RU_list[eNB0->num_RU++] = ru;
// attach all RU to all eNBs in its list/
LOG_D(PHY,"ru->num_eNB:%d eNB0->num_RU:%d\n", ru->num_eNB, eNB0->num_RU);
for (i=0;i<ru->num_eNB;i++) {
eNB0 = ru->eNB_list[i];
eNB0->RU_list[eNB0->num_RU++] = ru;
}
}
}
// LOG_I(PHY,"Initializing RRU descriptor %d : (%s,%s,%d)\n",ru_id,ru_if_types[ru->if_south],eNB_timing[ru->if_timing],ru->function);
LOG_D(PHY,"ru->if_south:%d\n", ru->if_south);
switch (ru->if_south) {
case LOCAL_RF: // this is an RU with integrated RF (RRU, eNB)
if (ru->function == NGFI_RRU_IF5) { // IF5 RRU
@@ -1985,7 +2032,8 @@ void init_RU(char *rf_config_file) {
if (setup_RU_buffers(ru)!=0) {
printf("Exiting, cannot initialize RU Buffers\n");
exit(-1);
}*/
}
*/
break;
case REMOTE_IF5: // the remote unit is IF5 RRU
+108 -18
View File
@@ -101,7 +101,6 @@ unsigned short config_frames[4] = {2,9,11,13};
#endif
#include "lte-softmodem.h"
#ifdef XFORMS
// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0)
// at eNB 0, an UL scope for every UE
@@ -113,9 +112,16 @@ unsigned char scope_enb_num_ue = 2;
static pthread_t forms_thread; //xforms
#endif //XFORMS
pthread_cond_t nfapi_sync_cond;
pthread_mutex_t nfapi_sync_mutex;
int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
uint8_t nfapi_mode = 0; // Default to monolithic mode
pthread_cond_t sync_cond;
pthread_mutex_t sync_mutex;
int sync_var=-1; //!< protected by mutex \ref sync_mutex.
int config_sync_var=-1;
uint16_t runtime_phy_rx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100]
uint16_t runtime_phy_tx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100]
@@ -205,6 +211,12 @@ uint64_t num_missed_slots=0; // counter for the number of missed slots
extern void reset_opp_meas(void);
extern void print_opp_meas(void);
extern PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms,
uint8_t UE_id,
uint8_t abstraction_flag);
extern void init_eNB_afterRU(void);
int transmission_mode=1;
@@ -839,7 +851,7 @@ void init_openair0() {
void wait_RUs(void) {
LOG_I(PHY,"Waiting for RUs to be configured ...\n");
LOG_I(PHY,"Waiting for RUs to be configured ... RC.ru_mask:%02lx\n", RC.ru_mask);
// wait for all RUs to be configured over fronthaul
pthread_mutex_lock(&RC.ru_mutex);
@@ -848,6 +860,7 @@ void wait_RUs(void) {
while (RC.ru_mask>0) {
pthread_cond_wait(&RC.ru_cond,&RC.ru_mutex);
printf("RC.ru_mask:%02lx\n", RC.ru_mask);
}
LOG_I(PHY,"RUs configured\n");
@@ -860,19 +873,37 @@ void wait_eNBs(void) {
while (waiting==1) {
printf("Waiting for eNB L1 instances to all get configured ... sleeping 500ms (nb_L1_inst %d)\n",RC.nb_L1_inst);
usleep(500000);
printf("Waiting for eNB L1 instances to all get configured ... sleeping 50ms (nb_L1_inst %d)\n",RC.nb_L1_inst);
usleep(50*1000);
waiting=0;
for (i=0;i<RC.nb_L1_inst;i++)
for (j=0;j<RC.nb_L1_CC[i];j++)
for (i=0;i<RC.nb_L1_inst;i++) {
printf("RC.nb_L1_CC[%d]:%d\n", i, RC.nb_L1_CC[i]);
for (j=0;j<RC.nb_L1_CC[i];j++) {
if (RC.eNB[i][j]->configured==0) {
waiting=1;
break;
}
}
}
}
}
printf("eNB L1 are configured\n");
}
static inline void wait_nfapi_init(char *thread_name) {
printf( "waiting for NFAPI PNF connection and population of global structure (%s)\n",thread_name);
pthread_mutex_lock( &nfapi_sync_mutex );
while (nfapi_sync_var<0)
pthread_cond_wait( &nfapi_sync_cond, &nfapi_sync_mutex );
pthread_mutex_unlock(&nfapi_sync_mutex);
printf( "NFAPI: got sync (%s)\n", thread_name);
}
int main( int argc, char **argv )
{
int i;
@@ -974,6 +1005,7 @@ int main( int argc, char **argv )
log_set_instance_type (LOG_INSTANCE_ENB);
}
printf("ITTI init\n");
itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file);
// initialize mscgen log after ITTI
@@ -993,6 +1025,7 @@ int main( int argc, char **argv )
}
#ifdef PDCP_USE_NETLINK
printf("PDCP netlink\n");
netlink_init();
#if defined(PDCP_USE_NETLINK_QUEUES)
pdcp_netlink_init();
@@ -1026,6 +1059,7 @@ int main( int argc, char **argv )
printf("Before CC \n");
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
@@ -1090,6 +1124,7 @@ int main( int argc, char **argv )
}
printf("Runtime table\n");
fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx);
cpuf=get_cpu_freq_GHz();
@@ -1097,6 +1132,7 @@ int main( int argc, char **argv )
#ifndef DEADLINE_SCHEDULER
printf("NO deadline scheduler\n");
/* Currently we set affinity for UHD to CPU 0 for eNB/UE and only if number of CPUS >2 */
cpu_set_t cpuset;
@@ -1162,6 +1198,8 @@ int main( int argc, char **argv )
#ifdef XFORMS
int UE_id;
printf("XFORMS\n");
if (do_forms==1) {
fl_initialize (&argc, argv, NULL, 0, 0);
@@ -1217,7 +1255,36 @@ int main( int argc, char **argv )
#endif
rt_sleep_ns(10*100000000ULL);
if (nfapi_mode) {
printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n");
pthread_cond_init(&sync_cond,NULL);
pthread_mutex_init(&sync_mutex, NULL);
}
const char *nfapi_mode_str = "<UNKNOWN>";
switch(nfapi_mode) {
case 0:
nfapi_mode_str = "MONOLITHIC";
break;
case 1:
nfapi_mode_str = "PNF";
break;
case 2:
nfapi_mode_str = "VNF";
break;
default:
nfapi_mode_str = "<UNKNOWN NFAPI MODE>";
break;
}
printf("NFAPI MODE:%s\n", nfapi_mode_str);
if (nfapi_mode==2) // VNF
wait_nfapi_init("main?");
printf("START MAIN THREADS\n");
// start the main threads
if (UE_flag == 1) {
@@ -1238,15 +1305,18 @@ int main( int argc, char **argv )
}
else {
number_of_cards = 1;
printf("RC.nb_L1_inst:%d\n", RC.nb_L1_inst);
if (RC.nb_L1_inst > 0) {
printf("Initializing eNB threads\n");
printf("Initializing eNB threads single_thread_flag:%d wait_for_sync:%d\n", single_thread_flag,wait_for_sync);
init_eNB(single_thread_flag,wait_for_sync);
// for (inst=0;inst<RC.nb_L1_inst;inst++)
// for (CC_id=0;CC_id<RC.nb_L1_CC[inst];CC_id++) phy_init_lte_eNB(RC.eNB[inst][CC_id],0,0);
}
printf("wait_eNBs()\n");
wait_eNBs();
printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU);
if (RC.nb_RU >0) {
printf("Initializing RU threads\n");
init_RU(rf_config_file);
@@ -1256,10 +1326,30 @@ int main( int argc, char **argv )
}
}
config_sync_var=0;
if (nfapi_mode==1) { // PNF
wait_nfapi_init("main?");
}
printf("wait RUs\n");
wait_RUs();
printf("ALL RUs READY!\n");
printf("RC.nb_RU:%d\n", RC.nb_RU);
// once all RUs are ready intiailize the rest of the eNBs ((dependence on final RU parameters after configuration)
init_eNB_afterRU();
printf("ALL RUs ready - init eNBs\n");
if (nfapi_mode != 1 && nfapi_mode != 2)
{
printf("Not NFAPI mode - call init_eNB_afterRU()\n");
init_eNB_afterRU();
}
else
{
printf("NFAPI mode - DO NOT call init_eNB_afterRU()\n");
}
printf("ALL RUs ready - ALL eNBs ready\n");
}
@@ -1293,38 +1383,35 @@ int main( int argc, char **argv )
//p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX;
} else {
printf("eNB mode\n");
}
printf("Sending sync to all threads\n");
pthread_mutex_lock(&sync_mutex);
sync_var=0;
pthread_cond_broadcast(&sync_cond);
pthread_mutex_unlock(&sync_mutex);
printf("About to call end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__);
end_configmodule();
printf("Called end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__);
// wait for end of program
printf("TYPE <CTRL-C> TO TERMINATE\n");
//getchar();
#if defined(ENABLE_ITTI)
printf("Entering ITTI signals handler\n");
itti_wait_tasks_end();
printf("Returned from ITTI signal handler\n");
oai_exit=1;
printf("oai_exit=%d\n",oai_exit);
#else
while (oai_exit==0)
rt_sleep_ns(100000000ULL);
printf("Terminating application - oai_exit=%d\n",oai_exit);
#endif
@@ -1367,6 +1454,9 @@ int main( int argc, char **argv )
pthread_cond_destroy(&sync_cond);
pthread_mutex_destroy(&sync_mutex);
pthread_cond_destroy(&nfapi_sync_cond);
pthread_mutex_destroy(&nfapi_sync_mutex);
// *** Handle per CC_id openair0
+54
View File
@@ -0,0 +1,54 @@
[*]
[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI
[*] Tue Jul 25 20:26:12 2017
[*]
[dumpfile] "/tmp/openair_dump_eNB.vcd"
[dumpfile_mtime] "Tue Jul 25 20:11:55 2017"
[dumpfile_size] 19201475
[savefile] "/home/papillon/openairinterface5g/targets/RT/USER/eNB_usrp.gtkw"
[timestart] 29023604000
[size] 1236 578
[pos] 309 0
*-20.793451 29026062100 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[sst_width] 386
[signals_width] 262
[sst_expanded] 1
[sst_vpaned_height] 146
@28
functions.trx_read
functions.trx_write
@24
variables.trx_ts[63:0]
variables.trx_tst[63:0]
@25
variables.frame_number_RX0_RU[63:0]
variables.subframe_number_RX0_RU[63:0]
@25
variables.frame_number_TX0_RU[63:0]
variables.subframe_number_TX0_RU[63:0]
@24
functions.phy_procedures_ru_feprx0
functions.phy_procedures_ru_feprx1
functions.phy_procedures_eNb_rx_uespec0
functions.phy_procedures_eNb_tx0
functions.eNB_thread_rxtx1
functions.phy_enb_prach_rx
functions.phy_enb_rs_tx
functions.phy_enb_pdcch_tx
functions.nfapi_subframe
functions.generate_pcfich
functions.generate_dci0
functions.pdcch_scrambling
functions.pdcch_modulation
functions.pdcch_interleaving
functions.pdcch_tx
functions.generate_dlsch
functions.generate_phich
functions.udp_enb_task
functions.phy_procedures_ru_feptx_ofdm0
functions.phy_procedures_ru_feptx_ofdm1
functions.phy_procedures_ru_feptx_prec0
functions.phy_procedures_ru_feptx_prec1
functions.phy_enb_prach_rx
[pattern_trace] 1
[pattern_trace] 0
+2
View File
@@ -345,6 +345,8 @@ void thread_top_init(char *thread_name,
exit_fun("Error getting thread priority");
}
pthread_setname_np(pthread_self(), thread_name);
LOG_I(HW, "[SCHED][eNB] %s started on CPU %d, sched_policy = %s , priority = %d, CPU Affinity=%s \n",thread_name,sched_getcpu(),
(policy == SCHED_FIFO) ? "SCHED_FIFO" :
(policy == SCHED_RR) ? "SCHED_RR" :