diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index fce45df6c8..6648223c00 100644 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -434,6 +434,8 @@ typedef struct RU_proc_t_s { pthread_mutex_t mutex_ru; /// symbol mask for IF4p5 reception per subframe uint32_t symbol_mask[10]; + /// time measurements for each subframe + struct timespec t[10]; /// number of slave threads int num_slaves; /// array of pointers to slaves @@ -715,6 +717,8 @@ typedef struct RU_t_s{ int rx_offset; /// flag to indicate the RU is a slave to another source int is_slave; + /// flag to indicate if the RU has a control channel + int has_ctrl_prt; /// counter to delay start of processing of RU until HW settles int wait_cnt; /// Total gain of receive chain diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index e036909e17..5f25212099 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -1264,7 +1264,12 @@ void do_ru_synch(RU_t *ru) { LOG_I(PHY,"Exiting synch routine\n"); } +int check_sync(RU_t *ru, RU_t *ru_master, int subframe){ + if (fabs(ru_master->proc.t[subframe].tv_nsec - ru->proc.t[subframe].tv_nsec) > 500000) + return 0; + return 1; +} void wakeup_eNBs(RU_t *ru) { @@ -1285,11 +1290,13 @@ void wakeup_eNBs(RU_t *ru) { pthread_mutex_lock(&proc->mutex_RU); LOG_I(PHY,"Frame %d, Subframe %d: RU %d done (wait_cnt %d),RU_mask[%d] %x\n", ru->proc.frame_rx,ru->proc.subframe_rx,ru->idx,ru->wait_cnt,ru->proc.subframe_rx,proc->RU_mask[ru->proc.subframe_rx]); - + + clock_gettime(CLOCK_MONOTONIC,&ru->proc.t[ru->proc.subframe_rx]); + if (proc->RU_mask[ru->proc.subframe_rx] == 0){ - clock_gettime(CLOCK_MONOTONIC,&proc->t[ru->proc.subframe_rx]); + //clock_gettime(CLOCK_MONOTONIC,&proc->t[ru->proc.subframe_rx]); + proc->t[ru->proc.subframe_rx] = ru->proc.t[ru->proc.subframe_rx]; //start_meas(&proc->ru_arrival_time); - LOG_D(PHY,"RU %d starting timer for frame %d subframe %d\n",ru->idx, ru->proc.frame_rx,ru->proc.subframe_rx); } for (i=0;inum_RU;i++) { @@ -1297,12 +1304,22 @@ void wakeup_eNBs(RU_t *ru) { if (ru == eNB->RU_list[i]) { // AssertFatal((proc->RU_mask&(1<Mod_id,ru->proc.frame_rx,ru->proc.subframe_rx,ru->idx,eNB->num_RU,proc->RU_mask); proc->RU_mask[ru->proc.subframe_rx] |= (1<RU_list[i]->state == RU_SYNC || eNB->RU_list[i]->wait_cnt > 0){ + }else if (eNB->RU_list[i]->state == RU_SYNC){ proc->RU_mask[ru->proc.subframe_rx] |= (1<is_slave == 0 && ( (proc->RU_mask[ru->proc.subframe_rx]&(1<RU_list[i]->state == RU_RUN) { // This is master & the RRU has already been received + if (check_sync(eNB->RU_list[i],eNB->RU_list[0],ru->proc.subframe_rx) == 0) + LOG_E(PHY,"RU %d is not SYNC, subframe %d, time %f this is master\n", eNB->RU_list[i]->idx, ru->proc.subframe_rx, fabs(eNB->RU_list[i]->proc.t[ru->proc.subframe_rx].tv_nsec - eNB->RU_list[0]->proc.t[ru->proc.subframe_rx].tv_nsec)); + }else if (ru->is_slave == 1 && ru->state == RU_RUN && ( (proc->RU_mask[ru->proc.subframe_rx]&(1<<0)) == 1)){ // master already received. TODO: we assume that RU0 is master. + if (check_sync(ru,eNB->RU_list[0],ru->proc.subframe_rx) == 0) + LOG_E(PHY,"RU %d is not SYNC time, subframe %d, time %f\n", ru->idx, ru->proc.subframe_rx, fabs(ru->proc.t[ru->proc.subframe_rx].tv_nsec - eNB->RU_list[0]->proc.t[ru->proc.subframe_rx].tv_nsec)); + + } } - clock_gettime(CLOCK_MONOTONIC,&t); - LOG_I(PHY,"RU mask is now %x, time is %lu\n",proc->RU_mask[ru->proc.subframe_rx], t.tv_nsec - proc->t[ru->proc.subframe_rx].tv_nsec); + //clock_gettime(CLOCK_MONOTONIC,&t); + //LOG_I(PHY,"RU mask is now %x, time is %lu\n",proc->RU_mask[ru->proc.subframe_rx], t.tv_nsec - proc->t[ru->proc.subframe_rx].tv_nsec); + if (proc->RU_mask[ru->proc.subframe_rx] == (1<num_RU)-1) { LOG_D(PHY,"Reseting mask frame %d, subframe %d, this is RU %d\n",ru->proc.frame_rx, ru->proc.subframe_rx, ru->idx); @@ -1316,7 +1333,8 @@ void wakeup_eNBs(RU_t *ru) { pthread_mutex_unlock(&proc->mutex_RU); LOG_D(PHY,"wakeup eNB top for for subframe %d\n", ru->proc.subframe_rx); - ru->eNB_top(eNB_list[0],ru->proc.frame_rx,ru->proc.subframe_rx,string); + if (ru->wait_cnt == 0) + ru->eNB_top(eNB_list[0],ru->proc.frame_rx,ru->proc.subframe_rx,string); } else { // multiple eNB case for later @@ -1593,7 +1611,7 @@ static void* ru_thread_control( void* param ) { &rru_config_msg, msg_len))<0) { LOG_D(PHY,"Waiting msg for RU %d\n", ru->idx); - } + else { switch(rru_config_msg.type) @@ -1823,7 +1841,9 @@ static void* ru_thread( void* param ) { int subframe =9; int frame =1023; int resynch_done = 0; - + PHY_VARS_eNB **eNB_list = ru->eNB_list; + PHY_VARS_eNB *eNB=eNB_list[0]; + eNB_proc_t *eNBproc = &eNB->proc; // set default return value @@ -1831,6 +1851,36 @@ static void* ru_thread( void* param ) { LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,eNB_functions[ru->function],eNB_timing[ru->if_timing]); + if (ru->has_ctrl_prt == 0){ + // There is no control port: start everything here + + if (ru->if_south == LOCAL_RF){ + fill_rf_config(ru,ru->rf_config_file); + init_frame_parms(&ru->frame_parms,1); + ru->frame_parms.nb_antennas_rx = ru->nb_rx; + phy_init_RU(ru); + + + ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); + } + if (setup_RU_buffers(ru)!=0) { + printf("Exiting, cannot initialize RU Buffers\n"); + exit(-1); + } + pthread_mutex_lock(&RC.ru_mutex); + RC.ru_mask &= ~(1<idx); + pthread_cond_signal(&RC.ru_cond); + pthread_mutex_unlock(&RC.ru_mutex); + } + pthread_mutex_lock(&RC.ru_mutex); + RC.ru_mask &= ~(1<idx); + pthread_cond_signal(&RC.ru_cond); + pthread_mutex_unlock(&RC.ru_mutex); + + ru->state = RU_RUN; + + } + while (!oai_exit) { @@ -1838,9 +1888,9 @@ static void* ru_thread( void* param ) { else ru->wait_cnt = 0; // wait to be woken up - if (ru->function!=eNodeB_3GPP) { + if (ru->function!=eNodeB_3GPP && ru->has_ctrl_prt == 1) { if (wait_on_condition(&ru->proc.mutex_ru,&ru->proc.cond_ru_thread,&ru->proc.instance_cnt_ru,"ru_thread")<0) break; - } + else wait_sync("ru_thread"); if (ru->is_slave == 0) AssertFatal(ru->state == RU_RUN,"ru-%d state = %s != RU_RUN\n",ru->idx,ru_states[ru->state]); @@ -1903,8 +1953,11 @@ static void* ru_thread( void* param ) { if (ru->fh_south_in && ru->state == RU_RUN ) ru->fh_south_in(ru,&frame,&subframe); else AssertFatal(1==0, "No fronthaul interface at south port"); + if (ru->wait_cnt > 0) { + ru->wait_cnt--; + LOG_I(PHY,"RU thread %d, frame %d, subframe %d, wait_cnt %d \n",ru->idx, frame, subframe, ru->wait_cnt); @@ -1919,8 +1972,10 @@ static void* ru_thread( void* param ) { AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1),"Failed to send msg to RAU\n"); resynch_done=1; } + wakeup_eNBs(ru); } - if (ru->wait_cnt == 0) { + + else { LOG_D(PHY,"RU thread %d, frame %d, subframe %d \n", ru->idx,frame,subframe); @@ -2809,6 +2864,8 @@ void RCconfig_RU(void) { RC.ru[j]->num_eNB = 0; for (i=0;inum_eNB;i++) RC.ru[j]->eNB_list[i] = RC.eNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]][0]; + RC.ru[j]->has_ctrl_prt = 1; + if (strcmp(*(RUParamList.paramarray[j][RU_LOCAL_RF_IDX].strptr), "yes") == 0) { if ( !(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX)) ) { @@ -2821,30 +2878,43 @@ void RCconfig_RU(void) { RC.ru[j]->eth_params.local_if_name = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr)); RC.ru[j]->eth_params.my_addr = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr)); RC.ru[j]->eth_params.remote_addr = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr)); - RC.ru[j]->eth_params.my_portc = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr); - RC.ru[j]->eth_params.remote_portc = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr); RC.ru[j]->eth_params.my_portd = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr); RC.ru[j]->eth_params.remote_portd = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr); + + + // Check if control port set + if (!(config_isparamset(RUParamList.paramarray[j],RU_REMOTE_PORTC_IDX)) ){ + RC.ru[j]->eth_params.my_portc = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr); + RC.ru[j]->eth_params.remote_portc = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr); + + RC.ru[j]->has_ctrl_prt = 0; + } + + if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) { RC.ru[j]->if_south = LOCAL_RF; RC.ru[j]->function = NGFI_RRU_IF5; RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE; + printf("Setting function for RU %d to NGFI_RRU_IF5 (udp)\n",j); } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) { RC.ru[j]->if_south = LOCAL_RF; RC.ru[j]->function = NGFI_RRU_IF5; RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE; + printf("Setting function for RU %d to NGFI_RRU_IF5 (raw)\n",j); } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) { RC.ru[j]->if_south = LOCAL_RF; RC.ru[j]->function = NGFI_RRU_IF4p5; RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE; + printf("Setting function for RU %d to NGFI_RRU_IF4p5 (udp)\n",j); } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) { RC.ru[j]->if_south = LOCAL_RF; RC.ru[j]->function = NGFI_RRU_IF4p5; RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; + printf("Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n",j); } printf("RU %d is_slave=%s\n",j,*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr));