diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index d9b8f9b31996cd3b0ef8ddf6b3f89376a7597b9d..a8c0ab8506185edb88774a02bd9f2470463476ab 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -809,12 +809,16 @@ typedef struct eNB_proc_t_s { pthread_mutex_t mutex_asynch_rxtx; /// mutex for RU access to eNB processing (PDSCH/PUSCH) pthread_mutex_t mutex_RU; + /// mutex for eNB processing to access RU TX (PDSCH/PUSCH) + pthread_mutex_t mutex_RU_tx; /// mutex for RU access to eNB processing (PRACH) pthread_mutex_t mutex_RU_PRACH; /// mutex for RU access to eNB processing (PRACH BR) pthread_mutex_t mutex_RU_PRACH_br; /// mask for RUs serving eNB (PDSCH/PUSCH) int RU_mask; + /// mask for RUs serving eNB (PDSCH/PUSCH) + int RU_mask_tx; /// mask for RUs serving eNB (PRACH) int RU_mask_prach; #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) @@ -829,8 +833,6 @@ typedef struct eNB_proc_t_s { eNB_rxtx_proc_t L1_proc,L1_proc_tx; /// stats thread pthread descriptor pthread_t process_stats_thread; - /// for waking up tx procedure - RU_proc_t *ru_proc; } eNB_proc_t; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf index 60b47c5c493e62a245dbbcb8d50a5267a21b9ed8..728492ee835aaf2607ea6aefd09eb5a7be2cc880 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf @@ -15,7 +15,7 @@ eNBs = // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = 1; - plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); tr_s_preference = "local_mac" @@ -138,7 +138,7 @@ eNBs = ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.12.26"; + mme_ip_address = ( { ipv4 = "192.168.12.148"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -187,7 +187,7 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 116; eNB_instances = [0]; - + sdr_addrs = "type=x300"; } ); diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index f8d5a351be301f4486595d1621ef3658514fc7bf..271572060c88c640656dffde5414e1c078537ea1 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -143,8 +143,8 @@ extern double cpuf; void init_eNB(int,int); void stop_eNB(int nb_inst); -int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc); -int wakeup_txfh(eNB_rxtx_proc_t *proc,RU_proc_t *ru_proc); +int wakeup_tx(PHY_VARS_eNB *eNB); +int wakeup_txfh(eNB_rxtx_proc_t *proc,PHY_VARS_eNB *eNB); void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); @@ -356,7 +356,7 @@ static void* L1_thread_tx(void* param) { exit_fun( "ERROR pthread_cond_signal" ); } pthread_mutex_unlock( &proc->mutex ); - wakeup_txfh(proc,eNB->proc.ru_proc); + wakeup_txfh(proc,eNB); } return 0; @@ -429,11 +429,11 @@ static void* L1_thread( void* param ) { if (release_thread(&proc->mutex,&proc->instance_cnt,thread_name)<0) break; if (nfapi_mode!=2){ - if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) wakeup_tx(eNB,eNB->proc.ru_proc); + if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) wakeup_tx(eNB); else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) { phy_procedures_eNB_TX(eNB, proc, 1); - wakeup_txfh(proc,eNB->proc.ru_proc); + wakeup_txfh(proc,eNB); } } @@ -473,51 +473,61 @@ void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t } } -int wakeup_txfh(eNB_rxtx_proc_t *proc,RU_proc_t *ru_proc) { - - if(ru_proc == NULL) - return(0); +int wakeup_txfh(eNB_rxtx_proc_t *proc,PHY_VARS_eNB *eNB) { + + RU_t *ru; + RU_proc_t *ru_proc; + int i; + + struct timespec wait; wait.tv_sec=0; wait.tv_nsec=5000000L; -printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~inside wakeup_txfh %d.%d IC_RU = %d\n", proc->frame_tx, proc->subframe_tx, proc->instance_cnt_RUs); +//printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~inside wakeup_txfh %d.%d IC_RU = %d\n", proc->frame_tx, proc->subframe_tx, proc->instance_cnt_RUs); if(wait_on_condition(&proc->mutex_RUs,&proc->cond_RUs,&proc->instance_cnt_RUs,"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); } + pthread_mutex_lock(&eNB->proc.mutex_RU_tx); + eNB->proc.RU_mask_tx = 0; + pthread_mutex_unlock(&eNB->proc.mutex_RU_tx); if (release_thread(&proc->mutex_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) return(-1); - - if (ru_proc->instance_cnt_eNBs == 0) { - LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->subframe_tx, proc->frame_rx, proc->subframe_rx); - return(-1); - } - if (pthread_mutex_timedlock(&ru_proc->mutex_eNBs,&wait) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", ru_proc->subframe_rx&1,ru_proc->instance_cnt_eNBs ); - exit_fun( "error locking mutex_eNB" ); - return(-1); - } - //for(num_RUs) + for(int i=0; i<eNB->num_RU; i++) + { + ru = eNB->RU_list[i]; + ru_proc = &ru->proc; + if (ru_proc->instance_cnt_eNBs == 0) { + LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->subframe_tx, proc->frame_rx, proc->subframe_rx); + return(-1); + } + if (pthread_mutex_timedlock(&ru_proc->mutex_eNBs,&wait) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", ru_proc->subframe_rx&1,ru_proc->instance_cnt_eNBs ); + exit_fun( "error locking mutex_eNB" ); + return(-1); + } + ru_proc->instance_cnt_eNBs = 0; ru_proc->timestamp_tx = proc->timestamp_tx; ru_proc->subframe_tx = proc->subframe_tx; ru_proc->frame_tx = proc->frame_tx; - // 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); - } + // 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); + } - pthread_mutex_unlock( &ru_proc->mutex_eNBs ); + pthread_mutex_unlock( &ru_proc->mutex_eNBs ); + } return(0); } -int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc) { +int wakeup_tx(PHY_VARS_eNB *eNB) { eNB_proc_t *proc=&eNB->proc; @@ -913,6 +923,7 @@ void init_eNB_proc(int inst) { proc->first_rx =1; proc->first_tx =1; + proc->RU_mask_tx = (1<<eNB->num_RU)-1; proc->RU_mask =0; proc->RU_mask_prach =0; @@ -929,6 +940,7 @@ void init_eNB_proc(int inst) { 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_tx,NULL); pthread_mutex_init( &proc->mutex_RU_PRACH,NULL); pthread_cond_init( &proc->cond_prach, NULL); diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 4bf6fd6cd44b8ca8ac541bd4ece2e54121eb7b31..42d71cfbf464cda2e6c4cc4b583e59deeed1429d 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -1273,7 +1273,6 @@ void wakeup_L1s(RU_t *ru) { for (i=0;i<ru->num_eNB;i++) { LOG_D(PHY,"ru->wakeup_rxtx:%p\n", ru->wakeup_rxtx); - eNB_list[i]->proc.ru_proc = &ru->proc; 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); @@ -1559,7 +1558,7 @@ static void* ru_thread_tx( void* param ) { // wait until eNBs are finished subframe RX n and TX n+4 wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx"); if (oai_exit) break; -printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~ru_thread_tx is waken up %d.%d having L1 %d\n", proc->frame_tx, proc->subframe_tx, ru->num_eNB); +//printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~ru_thread_tx is waken up %d.%d having L1 %d\n", proc->frame_tx, proc->subframe_tx, ru->num_eNB); // do TX front-end processing if needed (precoding and/or IDFTs) if (ru->feptx_prec) ru->feptx_prec(ru); @@ -1578,16 +1577,33 @@ printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~ru_thread_tx is waken up %d.%d having L1 %d\ eNB = ru->eNB_list[i]; eNB_proc = &eNB->proc; L1_proc = (get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)? &eNB_proc->L1_proc_tx : &eNB_proc->L1_proc; -char *L1_proc_name = (get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)? "L1_proc_tx" : "L1_proc"; -printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~ru_thread_tx signaling to eNB_list[%d] with %s IC_RU %d\n", i, L1_proc_name, L1_proc->instance_cnt_RUs); - pthread_mutex_lock( &L1_proc->mutex_RUs ); - L1_proc->instance_cnt_RUs = 0; - // the thread can now be woken up - if (pthread_cond_signal(&L1_proc->cond_RUs) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); - exit_fun( "ERROR pthread_cond_signal" ); + pthread_mutex_lock(&eNB_proc->mutex_RU_tx); + for (int j=0;j<eNB->num_RU;j++) { + if (ru == eNB->RU_list[j]) { + if ((eNB_proc->RU_mask_tx&(1<<i)) > 0) + LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information from RU tx %d (num_RU %d,mask %x) has not been served yet!\n", + eNB->Mod_id,eNB_proc->frame_rx,eNB_proc->subframe_rx,ru->idx,eNB->num_RU,eNB_proc->RU_mask_tx); + eNB_proc->RU_mask_tx |= (1<<i); + } + } + if (eNB_proc->RU_mask_tx != (1<<eNB->num_RU)-1) { // not all RUs have provided their information so return + LOG_E(PHY,"Not all RUs TX are finished\n"); + pthread_mutex_unlock(&eNB_proc->mutex_RU_tx); + continue; + } + else { // all RUs TX are finished so send the ready signal to eNB processing + eNB_proc->RU_mask_tx = 0; + pthread_mutex_unlock(&eNB_proc->mutex_RU_tx); + + pthread_mutex_lock( &L1_proc->mutex_RUs); + L1_proc->instance_cnt_RUs = 0; + // the thread can now be woken up + if (pthread_cond_signal(&L1_proc->cond_RUs) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); + exit_fun( "ERROR pthread_cond_signal" ); + } + pthread_mutex_unlock( &L1_proc->mutex_RUs ); } - pthread_mutex_unlock( &L1_proc->mutex_RUs ); } } release_thread(&proc->mutex_FH1,&proc->instance_cnt_FH1,"ru_thread_tx");