diff --git a/executables/nr-ru.c b/executables/nr-ru.c index c0da88e634..72bc44bffb 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -63,7 +63,6 @@ static int DEFRUTPCORES[] = {-1,-1,-1,-1}; #include - #include "T.h" #include "nfapi_interface.h" #include @@ -74,63 +73,69 @@ static void NRRCconfig_RU(configmodule_interface_t *cfg); /*************************************************************/ /* Functions to attach and configure RRU */ -int attach_rru(RU_t *ru) { - ssize_t msg_len,len; +int attach_rru(RU_t *ru) +{ RRU_CONFIG_msg_t rru_config_msg; int received_capabilities=0; wait_gNBs(); // Wait for capabilities while (received_capabilities==0) { - memset((void *)&rru_config_msg,0,sizeof(rru_config_msg)); - rru_config_msg.type = RAU_tick; - rru_config_msg.len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE; + rru_config_msg = (RRU_CONFIG_msg_t){.type = RAU_tick, .len = sizeof(rru_config_msg.msg)}; LOG_D(PHY, "Sending RAU tick to RRU %d\n", ru->idx); AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1), "RU %d cannot access remote radio\n",ru->idx); - msg_len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_capabilities_t); - + ssize_t msg_len = rru_config_msg.len + sizeof(RRU_capabilities_t); // wait for answer with timeout - if ((len = ru->ifdevice.trx_ctlrecv_func(&ru->ifdevice, - &rru_config_msg, - msg_len))<0) { + ssize_t len = ru->ifdevice.trx_ctlrecv_func(&ru->ifdevice, &rru_config_msg, msg_len); + if (len < 0) { LOG_D(PHY, "Waiting for RRU %d\n", ru->idx); } else if (rru_config_msg.type == RRU_capabilities) { - AssertFatal(rru_config_msg.len==msg_len,"Received capabilities with incorrect length (%d!=%d)\n",(int)rru_config_msg.len,(int)msg_len); - LOG_I(PHY,"Received capabilities from RRU %d (len %d/%d, num_bands %d,max_pdschReferenceSignalPower %d, max_rxgain %d, nb_tx %d, nb_rx %d)\n",ru->idx, - (int)rru_config_msg.len,(int)msg_len, - ((RRU_capabilities_t *)&rru_config_msg.msg[0])->num_bands, - ((RRU_capabilities_t *)&rru_config_msg.msg[0])->max_pdschReferenceSignalPower[0], - ((RRU_capabilities_t *)&rru_config_msg.msg[0])->max_rxgain[0], - ((RRU_capabilities_t *)&rru_config_msg.msg[0])->nb_tx[0], - ((RRU_capabilities_t *)&rru_config_msg.msg[0])->nb_rx[0]); + AssertFatal(rru_config_msg.len == msg_len, + "Received capabilities with incorrect length (%ld!=%ld)\n", + rru_config_msg.len, + msg_len); + RRU_capabilities_t *cap = (RRU_capabilities_t *)rru_config_msg.msg; + LOG_I(PHY, + "Received capabilities from RRU %d (len %ld/%ld, num_bands %d,max_pdschReferenceSignalPower %d, max_rxgain %d, nb_tx " + "%d, nb_rx %d)\n", + ru->idx, + rru_config_msg.len, + msg_len, + cap->num_bands, + cap->max_pdschReferenceSignalPower[0], + cap->max_rxgain[0], + cap->nb_tx[0], + cap->nb_rx[0]); received_capabilities=1; } else { LOG_E(PHY,"Received incorrect message %d from RRU %d\n",rru_config_msg.type,ru->idx); } } - configure_ru(ru, (RRU_capabilities_t *)&rru_config_msg.msg[0]); + configure_ru(ru, (RRU_capabilities_t *)rru_config_msg.msg); rru_config_msg.type = RRU_config; rru_config_msg.len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_config_t); - LOG_I(PHY,"Sending Configuration to RRU %d (num_bands %d,band0 %d,txfreq %u,rxfreq %u,att_tx %d,att_rx %d,N_RB_DL %d,N_RB_UL %d,3/4FS %d, prach_FO %d, prach_CI %d)\n",ru->idx, - ((RRU_config_t *)&rru_config_msg.msg[0])->num_bands, - ((RRU_config_t *)&rru_config_msg.msg[0])->band_list[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->tx_freq[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->rx_freq[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->att_tx[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->att_rx[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->N_RB_DL[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->N_RB_UL[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->threequarter_fs[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->prach_FreqOffset[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->prach_ConfigIndex[0]); + RRU_config_t *conf = (RRU_config_t *)rru_config_msg.msg; + LOG_I(PHY, + "Sending Configuration to RRU %d (num_bands %d,band0 %d,txfreq %u,rxfreq %u,att_tx %d,att_rx %d,N_RB_DL %d,N_RB_UL " + "%d,3/4FS %d, prach_FO %d, prach_CI %d)\n", + ru->idx, + conf->num_bands, + conf->band_list[0], + conf->tx_freq[0], + conf->rx_freq[0], + conf->att_tx[0], + conf->att_rx[0], + conf->N_RB_DL[0], + conf->N_RB_UL[0], + conf->threequarter_fs[0], + conf->prach_FreqOffset[0], + conf->prach_ConfigIndex[0]); AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1), "RU %d failed send configuration to remote radio\n",ru->idx); - - if ((len = ru->ifdevice.trx_ctlrecv_func(&ru->ifdevice, - &rru_config_msg, - msg_len))<0) { + int len = ru->ifdevice.trx_ctlrecv_func(&ru->ifdevice, &rru_config_msg, sizeof(rru_config_msg.msg)); + if (len < 0) { LOG_I(PHY,"Waiting for RRU %d\n",ru->idx); } else if (rru_config_msg.type == RRU_config_ok) { LOG_I(PHY, "RRU_config_ok received\n"); @@ -142,58 +147,57 @@ int attach_rru(RU_t *ru) { } int connect_rau(RU_t *ru) { - RRU_CONFIG_msg_t rru_config_msg; - ssize_t msg_len; - int tick_received = 0; - int configuration_received = 0; - RRU_capabilities_t *cap; - int i; - int len; + RRU_CONFIG_msg_t rru_config_msg; // wait for RAU_tick + int tick_received = 0; while (tick_received == 0) { - msg_len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE; - - if ((len = ru->ifdevice.trx_ctlrecv_func(&ru->ifdevice, - &rru_config_msg, - msg_len))<0) { + ssize_t msg_len = sizeof(rru_config_msg.msg); + int len = ru->ifdevice.trx_ctlrecv_func(&ru->ifdevice, &rru_config_msg, msg_len); + if (len < 0) { LOG_I(PHY,"Waiting for RAU\n"); } else { if (rru_config_msg.type == RAU_tick) { LOG_I(PHY,"Tick received from RAU\n"); tick_received = 1; - } else LOG_E(PHY,"Received erroneous message (%d)from RAU, expected RAU_tick\n",rru_config_msg.type); + } else + LOG_E(PHY, "Received erroneous message (%d)from RAU, expected RAU_tick\n", rru_config_msg.type); } } // send capabilities rru_config_msg.type = RRU_capabilities; rru_config_msg.len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_capabilities_t); - cap = (RRU_capabilities_t *)&rru_config_msg.msg[0]; - LOG_I(PHY,"Sending Capabilities (len %d, num_bands %d,max_pdschReferenceSignalPower %d, max_rxgain %d, nb_tx %d, nb_rx %d)\n", - (int)rru_config_msg.len,ru->num_bands,ru->max_pdschReferenceSignalPower,ru->max_rxgain,ru->nb_tx,ru->nb_rx); + RRU_capabilities_t *cap = (RRU_capabilities_t *)rru_config_msg.msg; + LOG_I(PHY, + "Sending Capabilities (len %ld, num_bands %d,max_pdschReferenceSignalPower %d, max_rxgain %d, nb_tx %d, nb_rx %d)\n", + rru_config_msg.len, + ru->num_bands, + ru->max_pdschReferenceSignalPower, + ru->max_rxgain, + ru->nb_tx, + ru->nb_rx); switch (ru->function) { case NGFI_RRU_IF4p5: - cap->FH_fmt = OAI_IF4p5_only; + cap->FH_fmt = OAI_IF4p5_only; break; case NGFI_RRU_IF5: - cap->FH_fmt = OAI_IF5_only; + cap->FH_fmt = OAI_IF5_only; break; case MBP_RRU_IF5: - cap->FH_fmt = MBP_IF5; + cap->FH_fmt = MBP_IF5; break; default: - AssertFatal(1==0,"RU_function is unknown %d\n",RC.ru[0]->function); + AssertFatal(false, "RU_function is unknown %d\n", RC.ru[0]->function); break; } - cap->num_bands = ru->num_bands; - - for (i=0; inum_bands; i++) { + cap->num_bands = ru->num_bands; + for (int i = 0; i < ru->num_bands; i++) { LOG_I(PHY,"Band %d: nb_rx %d nb_tx %d pdschReferenceSignalPower %d rxgain %d\n", ru->band[i],ru->nb_rx,ru->nb_tx,ru->max_pdschReferenceSignalPower,ru->max_rxgain); cap->band_list[i] = ru->band[i]; @@ -208,25 +212,28 @@ int connect_rau(RU_t *ru) { // wait for configuration rru_config_msg.len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_config_t); + int configuration_received = 0; while (configuration_received == 0) { - if ((len = ru->ifdevice.trx_ctlrecv_func(&ru->ifdevice, - &rru_config_msg, - rru_config_msg.len))<0) { + int len = ru->ifdevice.trx_ctlrecv_func(&ru->ifdevice, &rru_config_msg, rru_config_msg.len); + if (len < 0) { LOG_I(PHY,"Waiting for configuration from RAU\n"); } else { - LOG_I(PHY,"Configuration received from RAU (num_bands %d,band0 %d,txfreq %u,rxfreq %u,att_tx %d,att_rx %d,N_RB_DL %d,N_RB_UL %d,3/4FS %d, prach_FO %d, prach_CI %d)\n", - ((RRU_config_t *)&rru_config_msg.msg[0])->num_bands, - ((RRU_config_t *)&rru_config_msg.msg[0])->band_list[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->tx_freq[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->rx_freq[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->att_tx[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->att_rx[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->N_RB_DL[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->N_RB_UL[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->threequarter_fs[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->prach_FreqOffset[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->prach_ConfigIndex[0]); - configure_rru(ru, (void *)&rru_config_msg.msg[0]); + RRU_config_t *conf = (RRU_config_t *)rru_config_msg.msg; + LOG_I(PHY, + "Configuration received from RAU (num_bands %d,band0 %d,txfreq %u,rxfreq %u,att_tx %d,att_rx %d,N_RB_DL %d,N_RB_UL " + "%d,3/4FS %d, prach_FO %d, prach_CI %d)\n", + conf->num_bands, + conf->band_list[0], + conf->tx_freq[0], + conf->rx_freq[0], + conf->att_tx[0], + conf->att_rx[0], + conf->N_RB_DL[0], + conf->N_RB_UL[0], + conf->threequarter_fs[0], + conf->prach_FreqOffset[0], + conf->prach_ConfigIndex[0]); + configure_rru(ru, (void *)rru_config_msg.msg); configuration_received = 1; } } @@ -238,15 +245,23 @@ int connect_rau(RU_t *ru) { // southbound IF5 fronthaul for 16-bit OAI format void fh_if5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) { - if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); + if (ru == RC.ru[0]) + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx & 0xffffffff); int offset = ru->nr_frame_parms->get_samples_slot_timestamp(slot,ru->nr_frame_parms,0); void *buffs[ru->nb_tx]; for (int aid = 0; aid < ru->nb_tx; aid++) buffs[aid] = (void*)&ru->common.txdata[aid][offset]; struct timespec txmeas; clock_gettime(CLOCK_MONOTONIC, &txmeas); - LOG_D(NR_PHY,"IF5 TX %d.%d, TS %llu, buffs[0] %p, buffs[1] %p ener0 %f dB, tx start %d\n",frame,slot,(unsigned long long)timestamp,buffs[0],buffs[1], - 10*log10((double)signal_energy(buffs[0],ru->nr_frame_parms->get_samples_per_slot(slot,ru->nr_frame_parms))),(int)txmeas.tv_nsec); + LOG_D(NR_PHY, + "IF5 TX %d.%d, TS %lu, buffs[0] %p, buffs[1] %p ener0 %f dB, tx start %d\n", + frame, + slot, + timestamp, + buffs[0], + buffs[1], + 10 * log10((double)signal_energy(buffs[0], ru->nr_frame_parms->get_samples_per_slot(slot, ru->nr_frame_parms))), + (int)txmeas.tv_nsec); ru->ifdevice.trx_write_func2(&ru->ifdevice, timestamp, buffs, @@ -258,13 +273,12 @@ void fh_if5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) { // southbound IF4p5 fronthaul void fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) { - nfapi_nr_config_request_scf_t *cfg = &ru->config; - - if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); + if (ru == RC.ru[0]) + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx & 0xffffffff); LOG_D(PHY,"Sending IF4p5 for frame %d subframe %d\n",ru->proc.frame_tx,ru->proc.tti_tx); - if ((nr_slot_select(cfg,ru->proc.frame_tx,ru->proc.tti_tx)&NR_DOWNLINK_SLOT) > 0) + if ((nr_slot_select(&ru->config, ru->proc.frame_tx, ru->proc.tti_tx) & NR_DOWNLINK_SLOT) > 0) send_IF4p5(ru,frame, slot, IF4p5_PDLFFT); } @@ -281,11 +295,11 @@ void fh_if5_south_in(RU_t *ru, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 1 ); start_meas(&ru->rx_fhaul); - ru->ifdevice.trx_read_func2(&ru->ifdevice,&proc->timestamp_rx,NULL,fp->get_samples_per_slot(*tti,fp)); - if (proc->first_rx == 1) ru->ts_offset = proc->timestamp_rx; - proc->frame_rx = ((proc->timestamp_rx-ru->ts_offset) / (fp->samples_per_subframe*10))&1023; - proc->tti_rx = fp->get_slot_from_timestamp(proc->timestamp_rx-ru->ts_offset,fp); - + ru->ifdevice.trx_read_func2(&ru->ifdevice, &proc->timestamp_rx, NULL, fp->get_samples_per_slot(*tti, fp)); + if (proc->first_rx == 1) + ru->ts_offset = proc->timestamp_rx; + proc->frame_rx = ((proc->timestamp_rx - ru->ts_offset) / (fp->samples_per_subframe * 10)) & 1023; + proc->tti_rx = fp->get_slot_from_timestamp(proc->timestamp_rx - ru->ts_offset, fp); if (proc->first_rx == 0) { if (proc->tti_rx != *tti) { @@ -311,8 +325,26 @@ void fh_if5_south_in(RU_t *ru, struct timespec rxmeas; clock_gettime(CLOCK_MONOTONIC, &rxmeas); double fhtime = ru->rx_fhaul.p_time/(cpu_freq_GHz*1000.0); - if (fhtime > 800) LOG_W(PHY,"IF5 %d.%d => RX %d.%d first_rx %d: time %f, rxstart %d\n",*frame,*tti,proc->frame_rx,proc->tti_rx,proc->first_rx,ru->rx_fhaul.p_time/(cpu_freq_GHz*1000.0),(int)rxmeas.tv_nsec); - else LOG_D(PHY,"IF5 %d.%d => RX %d.%d first_rx %d: time %f, rxstart %d\n",*frame,*tti,proc->frame_rx,proc->tti_rx,proc->first_rx,ru->rx_fhaul.p_time/(cpu_freq_GHz*1000.0),(int)rxmeas.tv_nsec); + if (fhtime > 800) + LOG_W(PHY, + "IF5 %d.%d => RX %d.%d first_rx %d: time %f, rxstart %ld\n", + *frame, + *tti, + proc->frame_rx, + proc->tti_rx, + proc->first_rx, + ru->rx_fhaul.p_time / (cpu_freq_GHz * 1000.0), + rxmeas.tv_nsec); + else + LOG_D(PHY, + "IF5 %d.%d => RX %d.%d first_rx %d: time %f, rxstart %ld\n", + *frame, + *tti, + proc->frame_rx, + proc->tti_rx, + proc->first_rx, + ru->rx_fhaul.p_time / (cpu_freq_GHz * 1000.0), + rxmeas.tv_nsec); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 0 ); @@ -329,21 +361,16 @@ void fh_if4p5_south_in(RU_t *ru, uint32_t symbol_number=0; uint32_t symbol_mask_full=0; - /* - if ((fp->frame_type == TDD) && (subframe_select(fp,*slot)==SF_S)) - symbol_mask_full = (1<ul_symbols_in_S_subframe)-1; - else - symbol_mask_full = (1<symbols_per_slot)-1; - - AssertFatal(proc->symbol_mask[*slot]==0,"rx_fh_if4p5: proc->symbol_mask[%d] = %x\n",*slot,proc->symbol_mask[*slot]);*/ do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!! recv_IF4p5(ru, &f, &sl, &packet_type, &symbol_number); if (packet_type == IF4p5_PULFFT) proc->symbol_mask[sl] = proc->symbol_mask[sl] | (1<first_rx==0) && (f!=*frame)) LOG_E(PHY,"rx_fh_if4p5: PULTICK received frame %d != expected %d\n",f,*frame); + if ((proc->first_rx == 0) && (f != *frame)) + LOG_E(PHY, "rx_fh_if4p5: PULTICK received frame %d != expected %d\n", f, *frame); - if ((proc->first_rx==0) && (sl!=*slot)) LOG_E(PHY,"rx_fh_if4p5: PULTICK received subframe %d != expected %d (first_rx %d)\n",sl,*slot,proc->first_rx); + if ((proc->first_rx == 0) && (sl != *slot)) + LOG_E(PHY, "rx_fh_if4p5: PULTICK received subframe %d != expected %d (first_rx %d)\n", sl, *slot, proc->first_rx); break; } else if (packet_type == IF4p5_PRACH) { @@ -359,7 +386,7 @@ void fh_if4p5_south_in(RU_t *ru, proc->timestamp_rx = (proc->frame_rx * fp->samples_per_subframe * 10) + fp->get_samples_slot_timestamp(proc->tti_rx, fp, 0); // proc->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_subframe); proc->tti_tx = (sl+ru->sl_ahead)%fp->slots_per_frame; - proc->frame_tx = (sl>(fp->slots_per_frame-1-(ru->sl_ahead))) ? (f+1)&1023 : f; + proc->frame_tx = (sl > (fp->slots_per_frame - 1 - (ru->sl_ahead))) ? (f + 1) & 1023 : f; if (proc->first_rx == 0) { if (proc->tti_rx != *slot) { @@ -394,20 +421,12 @@ void fh_if4p5_south_asynch_in(RU_t *ru,int *frame,int *slot) { NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; RU_proc_t *proc = &ru->proc; uint16_t packet_type; - uint32_t symbol_number,symbol_mask,prach_rx; - // uint32_t got_prach_info=0; - symbol_number = 0; - symbol_mask = (1<<(fp->symbols_per_slot))-1; - prach_rx = 0; + uint32_t symbol_number = 0; + uint32_t symbol_mask = (1 << fp->symbols_per_slot) - 1; + uint32_t prach_rx = 0; do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!! recv_IF4p5(ru, &proc->frame_rx, &proc->tti_rx, &packet_type, &symbol_number); - - // grab first prach information for this new subframe - /*if (got_prach_info==0) { - prach_rx = is_prach_subframe(fp, proc->frame_rx, proc->tti_rx); - got_prach_info = 1; - }*/ if (proc->first_rx != 0) { *frame = proc->frame_rx; *slot = proc->tti_rx; @@ -417,22 +436,19 @@ void fh_if4p5_south_asynch_in(RU_t *ru,int *frame,int *slot) { LOG_E(PHY,"frame_rx %d is not what we expect %d\n",proc->frame_rx,*frame); exit_fun("Exiting"); } - if (proc->tti_rx != *slot) { LOG_E(PHY,"tti_rx %d is not what we expect %d\n",proc->tti_rx,*slot); exit_fun("Exiting"); } } - if (packet_type == IF4p5_PULFFT) symbol_mask &= (~(1< 0) || (prach_rx >0)); // haven't received all PUSCH symbols and PRACH information + if (packet_type == IF4p5_PULFFT) + symbol_mask &= ~(1 << symbol_number); + else if (packet_type == IF4p5_PRACH) + prach_rx &= ~0x1; + } while (symbol_mask > 0 || prach_rx > 0); // haven't received all PUSCH symbols and PRACH information } - - - - /*************************************************************/ /* Input Fronthaul from North RRU */ @@ -459,26 +475,9 @@ void fh_if4p5_north_in(RU_t *ru,int *frame,int *slot) { } } -void fh_if5_north_asynch_in(RU_t *ru,int *frame,int *slot) { - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - RU_proc_t *proc = &ru->proc; - int tti_tx,frame_tx; - openair0_timestamp timestamp_tx = 0; +void fh_if5_north_asynch_in(RU_t *ru, int *frame, int *slot) +{ AssertFatal(1 == 0, "Shouldn't get here\n"); - frame_tx = (timestamp_tx / (fp->samples_per_subframe*10))&1023; - uint32_t idx_sf = timestamp_tx / fp->samples_per_subframe; - tti_tx = (idx_sf * fp->slots_per_subframe + (int)round((float)(timestamp_tx % fp->samples_per_subframe) / fp->samples_per_slot0))%(fp->slots_per_frame); - - if (proc->first_tx != 0) { - *slot = tti_tx; - *frame = frame_tx; - proc->first_tx = 0; - } else { - AssertFatal(tti_tx == *slot, - "tti_tx %d is not what we expect %d\n",tti_tx,*slot); - AssertFatal(frame_tx == *frame, - "frame_tx %d is not what we expect %d\n",frame_tx,*frame); - } } void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) { @@ -486,17 +485,18 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) { nfapi_nr_config_request_scf_t *cfg = &ru->config; RU_proc_t *proc = &ru->proc; uint16_t packet_type; - uint32_t symbol_number,symbol_mask,symbol_mask_full=0; + uint32_t symbol_mask_full = 0; int slot_tx,frame_tx; LOG_D(PHY, "%s(ru:%p frame, subframe)\n", __FUNCTION__, ru); - symbol_number = 0; - symbol_mask = 0; + uint32_t symbol_number = 0; + uint32_t symbol_mask = 0; // symbol_mask_full = ((subframe_select(fp,*slot) == SF_S) ? (1<dl_symbols_in_S_subframe) : (1<symbols_per_slot))-1; do { recv_IF4p5(ru, &frame_tx, &slot_tx, &packet_type, &symbol_number); - if (((nr_slot_select(cfg,frame_tx,slot_tx) & NR_DOWNLINK_SLOT) > 0) && (symbol_number == 0)) start_meas(&ru->rx_fhaul); + if (((nr_slot_select(cfg, frame_tx, slot_tx) & NR_DOWNLINK_SLOT) > 0) && (symbol_number == 0)) + start_meas(&ru->rx_fhaul); LOG_D(PHY,"slot %d (%d): frame %d, slot %d, symbol %d\n", *slot,nr_slot_select(cfg,frame_tx,*slot),frame_tx,slot_tx,symbol_number); @@ -505,7 +505,6 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) { *frame = frame_tx; *slot = slot_tx; proc->first_tx = 0; - //symbol_mask_full = ((subframe_select(fp,*slot) == SF_S) ? (1<dl_symbols_in_S_subframe) : (1<symbols_per_slot))-1; } else { AssertFatal(frame_tx == *frame, "frame_tx %d is not what we expect %d\n",frame_tx,*frame); @@ -515,18 +514,22 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) { if (packet_type == IF4p5_PDLFFT) { symbol_mask = symbol_mask | (1<0) stop_meas(&ru->rx_fhaul); + if ((nr_slot_select(cfg, frame_tx, slot_tx) & NR_DOWNLINK_SLOT) > 0) + stop_meas(&ru->rx_fhaul); proc->tti_tx = slot_tx; proc->frame_tx = frame_tx; - if ((frame_tx == 0)&&(slot_tx == 0)) proc->frame_tx_unwrap += 1024; + if (frame_tx == 0 && slot_tx == 0) + proc->frame_tx_unwrap += 1024; - proc->timestamp_tx = (((uint64_t)frame_tx + (uint64_t)proc->frame_tx_unwrap) * fp->samples_per_subframe * 10) + fp->get_samples_slot_timestamp(slot_tx, fp, 0); - LOG_D(PHY,"RU %d/%d TST %llu, frame %d, subframe %d\n",ru->idx,0,(long long unsigned int)proc->timestamp_tx,frame_tx,slot_tx); + proc->timestamp_tx = + ((uint64_t)frame_tx + proc->frame_tx_unwrap) * fp->samples_per_subframe * 10 + fp->get_samples_slot_timestamp(slot_tx, fp, 0); + LOG_D(PHY, "RU %d/%d TST %lu, frame %d, subframe %d\n", ru->idx, 0, proc->timestamp_tx, frame_tx, slot_tx); // dump VCD output for first RU in list if (ru == RC.ru[0]) { @@ -544,24 +547,15 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) { void fh_if5_north_out(RU_t *ru) { /// **** send_IF5 of rxdata to BBU **** /// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 ); - AssertFatal(1==0,"Shouldn't get here\n"); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 0 ); + AssertFatal(1 == 0, "Shouldn't get here\n"); } // RRU IF4p5 northbound interface (RX) void fh_if4p5_north_out(RU_t *ru) { RU_proc_t *proc=&ru->proc; + if (ru->idx == 0) + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_RX0_RU, proc->tti_rx); - //NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - //const int subframe = proc->tti_rx; - if (ru->idx==0) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_RX0_RU, proc->tti_rx ); - - /* - if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) { - /// **** in TDD during DL send_IF4 of ULTICK to RCC **** /// - send_IF4p5(ru, proc->frame_rx, proc->tti_rx, IF4p5_PULTICK); - return; - }*/ start_meas(&ru->tx_fhaul); send_IF4p5(ru, proc->frame_rx, proc->tti_rx, IF4p5_PULFFT); stop_meas(&ru->tx_fhaul); @@ -572,7 +566,7 @@ void *emulatedRF_thread(void *param) { int microsec = 500; // length of time to sleep, in miliseconds struct timespec req = {0}; req.tv_sec = 0; - req.tv_nsec = (numerology>0)? ((microsec * 1000L)/numerology):(microsec * 1000L)*2; + req.tv_nsec = numerology > 0 ? (microsec * 1000L) / numerology : microsec * 1000L * 2; wait_sync("emulatedRF_thread"); while(!oai_exit) { @@ -618,8 +612,6 @@ static void rx_rf(RU_t *ru, int *frame, int *slot) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); proc->timestamp_rx = ts-ru->ts_offset; - //AssertFatal(rxs == fp->samples_per_subframe, - //"rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_subframe,rxs); if (rxs != samples_per_slot) LOG_E(PHY, "rx_rf: Asked for %d samples, got %d from USRP\n", samples_per_slot, rxs); @@ -636,23 +628,26 @@ static void rx_rf(RU_t *ru, int *frame, int *slot) } } - //compute system frame number (SFN) according to O-RAN-WG4-CUS.0-v02.00 (using alpha=beta=0) - // this assumes that the USRP has been synchronized to the GPS time - // OAI uses timestamps in sample time stored in int64_t, but it will fit in double precision for many years to come. - double gps_sec = ((double) ts)/cfg->sample_rate; - //proc->frame_rx = ((int64_t) (gps_sec/0.01)) & 1023; + // compute system frame number (SFN) according to O-RAN-WG4-CUS.0-v02.00 (using alpha=beta=0) + // this assumes that the USRP has been synchronized to the GPS time + // OAI uses timestamps in sample time stored in int64_t, but it will fit in double precision for many years to come. + double gps_sec = ((double)ts) / cfg->sample_rate; // in fact the following line is the same as long as the timestamp_rx is synchronized to GPS. proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_subframe*10))&1023; proc->tti_rx = fp->get_slot_from_timestamp(proc->timestamp_rx,fp); // synchronize first reception to frame 0 subframe 0 - LOG_D(PHY,"RU %d/%d TS %ld, GPS %f, SR %f, frame %d, slot %d.%d / %d\n", + LOG_D(PHY, + "RU %d/%d TS %ld, GPS %f, SR %f, frame %d, slot %d.%d / %d\n", ru->idx, 0, - ts, //(unsigned long long int)(proc->timestamp_rx+ru->ts_offset), - gps_sec, - cfg->sample_rate, - proc->frame_rx,proc->tti_rx,proc->tti_tx,fp->slots_per_frame); + ts, + gps_sec, + cfg->sample_rate, + proc->frame_rx, + proc->tti_rx, + proc->tti_tx, + fp->slots_per_frame); // dump VCD output for first RU in list if (ru == RC.ru[0]) { @@ -662,15 +657,19 @@ static void rx_rf(RU_t *ru, int *frame, int *slot) if (proc->first_rx == 0) { if (proc->tti_rx != *slot) { - LOG_E(PHY,"Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->tti_rx %d, slot %d)\n",(long long unsigned int)proc->timestamp_rx,proc->tti_rx,*slot); + LOG_E(PHY, + "Received Timestamp (%lu) doesn't correspond to the time we think it is (proc->tti_rx %d, slot %d)\n", + proc->timestamp_rx, + proc->tti_rx, + *slot); exit_fun("Exiting"); } if (proc->frame_rx != *frame) { LOG_E(PHY, - "Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->frame_rx %d frame %d, proc->tti_rx %d, " + "Received Timestamp (%lu) doesn't correspond to the time we think it is (proc->frame_rx %d frame %d, proc->tti_rx %d, " "slot %d)\n", - (long long unsigned int)proc->timestamp_rx, + proc->timestamp_rx, proc->frame_rx, *frame, proc->tti_rx, @@ -720,6 +719,7 @@ static radio_tx_gpio_flag_t get_gpio_flags(RU_t *ru, int slot) } } break; + case RU_GPIO_CONTROL_INTERDIGITAL: { // the beam index is written in bits 8-10 of the flags // bit 11 enables the gpio programming @@ -805,9 +805,7 @@ void tx_rf(RU_t *ru, int frame,int slot, uint64_t timestamp) flags_gpio = get_gpio_flags(ru, slot); const int flags = flags_burst | (flags_gpio << 4); - - if (proc->first_tx == 1) - proc->first_tx = 0; + proc->first_tx = 0; VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS, flags); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame); @@ -828,10 +826,10 @@ void tx_rf(RU_t *ru, int frame,int slot, uint64_t timestamp) nt, flags); LOG_D(PHY, - "[TXPATH] RU %d tx_rf, writing to TS %llu, %d.%d, unwrapped_frame %d, slot %d, flags %d, siglen+sf_extension %d, " + "[TXPATH] RU %d tx_rf, writing to TS %lu, %d.%d, unwrapped_frame %d, slot %d, flags %d, siglen+sf_extension %d, " "returned %d, E %f\n", ru->idx, - (long long unsigned int)(timestamp + ru->ts_offset - sf_extension), + timestamp + ru->ts_offset - sf_extension, frame, slot, proc->frame_tx_unwrap, @@ -841,7 +839,6 @@ void tx_rf(RU_t *ru, int frame,int slot, uint64_t timestamp) txs, 10 * log10((double)signal_energy(txp[0], siglen + sf_extension))); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0); - // AssertFatal(txs == 0,"trx write function error %d\n", txs); } static void fill_rf_config(RU_t *ru, char *rf_config_file) @@ -880,12 +877,12 @@ static void fill_rf_config(RU_t *ru, char *rf_config_file) for (int i = 0; i < ru->nb_tx * ru->num_beams_period; i++) { if (ru->if_frequency == 0) { - cfg->tx_freq[i] = (double)fp->dl_CarrierFreq; + cfg->tx_freq[i] = fp->dl_CarrierFreq; } else if (ru->if_freq_offset) { - cfg->tx_freq[i] = (double)(ru->if_frequency); + cfg->tx_freq[i] = ru->if_frequency; LOG_I(PHY, "Setting IF TX frequency to %lu Hz with IF TX frequency offset %d Hz\n", ru->if_frequency, ru->if_freq_offset); } else { - cfg->tx_freq[i] = (double)ru->if_frequency; + cfg->tx_freq[i] = ru->if_frequency; } cfg->tx_gain[i] = ru->att_tx; @@ -895,12 +892,12 @@ static void fill_rf_config(RU_t *ru, char *rf_config_file) for (int i = 0; i < ru->nb_rx * ru->num_beams_period; i++) { if (ru->if_frequency == 0) { - cfg->rx_freq[i] = (double)fp->ul_CarrierFreq; + cfg->rx_freq[i] = fp->ul_CarrierFreq; } else if (ru->if_freq_offset) { - cfg->rx_freq[i] = (double)(ru->if_frequency + ru->if_freq_offset); + cfg->rx_freq[i] = ru->if_frequency + ru->if_freq_offset; LOG_I(PHY, "Setting IF RX frequency to %lu Hz with IF RX frequency offset %d Hz\n", ru->if_frequency, ru->if_freq_offset); } else { - cfg->rx_freq[i] = (double)(ru->if_frequency+fp->ul_CarrierFreq-fp->dl_CarrierFreq); + cfg->rx_freq[i] = ru->if_frequency + fp->ul_CarrierFreq - fp->dl_CarrierFreq; } cfg->rx_gain[i] = ru->max_rxgain-ru->att_rx; @@ -941,17 +938,11 @@ static void fill_split7_2_config(split7_config_t *split7, const nfapi_nr_config_ antennas are mapped to successive RF chains on the same card. */ int setup_RU_buffers(RU_t *ru) { - int card,ant; - //uint16_t N_TA_offset = 0; - NR_DL_FRAME_PARMS *fp; + if (!ru) + return (-1); + + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; nfapi_nr_config_request_scf_t *config = &ru->config; - - if (ru) { - fp = ru->nr_frame_parms; - } else { - return(-1); - } - int mu = config->ssb_config.scs_common.value; int N_RB = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value; @@ -963,8 +954,8 @@ int setup_RU_buffers(RU_t *ru) if (ru->openair0_cfg.mmapped_dma == 1) { // replace RX signal buffers with mmaped HW versions for (int i = 0; i < ru->nb_rx * ru->num_beams_period; i++) { - card = i / 4; - ant = i % 4; + int card = i / 4; + int ant = i % 4; LOG_D(PHY, "Mapping RU id %u, rx_ant %d, on card %d, chain %d\n", ru->idx, i, ru->rf_map.card + card, ru->rf_map.chain + ant); free(ru->common.rxdata[i]); ru->common.rxdata[i] = ru->openair0_cfg.rxbase[ru->rf_map.chain + ant]; @@ -975,8 +966,8 @@ int setup_RU_buffers(RU_t *ru) } for (int i = 0; i < ru->nb_tx * ru->num_beams_period; i++) { - card = i / 4; - ant = i % 4; + int card = i / 4; + int ant = i % 4; LOG_D(PHY, "Mapping RU id %u, tx_ant %d, on card %d, chain %d\n", ru->idx, i, ru->rf_map.card + card, ru->rf_map.chain + ant); free(ru->common.txdata[i]); ru->common.txdata[i] = ru->openair0_cfg.txbase[ru->rf_map.chain + ant]; @@ -985,8 +976,9 @@ int setup_RU_buffers(RU_t *ru) ru->common.txdata[i][j] = 16 - j; } } - } else { // not memory-mapped DMA - //nothing to do, everything already allocated in lte_init + } else { + // not memory-mapped DMA + // nothing to do, everything already allocated in lte_init } return(0); @@ -1007,14 +999,13 @@ void ru_tx_func(void *param) ru->feptx_prec(ru,frame_tx,slot_tx); // do OFDM with/without TX front-end processing if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) + if (ru->fh_north_asynch_in == NULL && ru->feptx_ofdm) ru->feptx_ofdm(ru, frame_tx, slot_tx); if(!emulate_rf) { // do outgoing fronthaul (south) if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) + if (ru->fh_north_asynch_in == NULL && ru->fh_south_out) ru->fh_south_out(ru, frame_tx, slot_tx, info->timestamp_tx); - if (ru->fh_north_out) ru->fh_north_out(ru); } else { @@ -1111,7 +1102,7 @@ void *ru_thread(void *param) // set default return value sprintf(threadname,"ru_thread %u",ru->idx); LOG_I(PHY,"Starting RU %d (%s,%s) on cpu %d\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing],sched_getcpu()); - memcpy((void *)&ru->config,(void *)&RC.gNB[0]->gNB_config,sizeof(ru->config)); + ru->config = RC.gNB[0]->gNB_config; nr_init_frame_parms(&ru->config, fp); nr_dump_frame_parms(fp); @@ -1136,7 +1127,6 @@ void *ru_thread(void *param) if (t != NULL) ru->fh_south_out = t; } else { - malloc_IF4p5_buffer(ru); } @@ -1156,9 +1146,10 @@ void *ru_thread(void *param) AssertFatal(ru->nr_start_if(ru,NULL) == 0, "Could not start the IF device\n"); if (ru->has_ctrl_prt > 0) { - if (ru->if_south == LOCAL_RF) ret = connect_rau(ru); - else ret = attach_rru(ru); - + if (ru->if_south == LOCAL_RF) + ret = connect_rau(ru); + else + ret = attach_rru(ru); AssertFatal(ret==0,"Cannot connect to remote radio\n"); } @@ -1204,8 +1195,8 @@ void *ru_thread(void *param) // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices struct timespec slot_start; - clock_gettime(CLOCK_MONOTONIC, &slot_start); - + clock_gettime(CLOCK_MONOTONIC, &slot_start); + while (!oai_exit) { if (slot==(fp->slots_per_frame-1)) { slot=0; @@ -1222,8 +1213,8 @@ void *ru_thread(void *param) // synchronization on input FH interface, acquire signals/data and block LOG_D(PHY,"[RU_thread] read data: frame_rx = %d, tti_rx = %d\n", frame, slot); - if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&slot); - else AssertFatal(1==0, "No fronthaul interface at south port"); + AssertFatal(ru->fh_south_in, "No fronthaul interface at south port"); + ru->fh_south_in(ru, &frame, &slot); if (initial_wait == 1 && proc->frame_rx < 300) { if (proc->frame_rx > 0 && ((proc->frame_rx % 100) == 0) && proc->tti_rx == 0) { @@ -1308,14 +1299,14 @@ void *ru_thread(void *param) } // end if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) { notifiedFIFO_elt_t *resTx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t), 0, &gNB->L1_tx_out, NULL); - processingData_L1tx_t *syncMsgTx = NotifiedFifoData(resTx); - syncMsgTx->gNB = gNB; - syncMsgTx->frame = proc->frame_tx; - syncMsgTx->slot = proc->tti_tx; - syncMsgTx->frame_rx = proc->frame_rx; - syncMsgTx->slot_rx = proc->tti_rx; - syncMsgTx->timestamp_tx = proc->timestamp_tx; resTx->key = proc->tti_tx; + processingData_L1tx_t *syncMsgTx = NotifiedFifoData(resTx); + *syncMsgTx = (processingData_L1tx_t){.gNB = gNB, + .frame = proc->frame_tx, + .slot = proc->tti_tx, + .frame_rx = proc->frame_rx, + .slot_rx = proc->tti_rx, + .timestamp_tx = proc->timestamp_tx}; pushNotifiedFIFO(&gNB->L1_tx_out, resTx); } @@ -1325,15 +1316,16 @@ void *ru_thread(void *param) int start_streaming(RU_t *ru) { LOG_I(PHY,"Starting streaming on third-party RRU\n"); - return(ru->ifdevice.thirdparty_startstreaming(&ru->ifdevice)); + return ru->ifdevice.thirdparty_startstreaming(&ru->ifdevice); } int nr_start_if(struct RU_t_s *ru, struct PHY_VARS_gNB_s *gNB) { if (ru->if_south <= REMOTE_IF5) - for (int i=0;inb_rx;i++) ru->openair0_cfg.rxbase[i] = ru->common.rxdata[i]; + for (int i = 0; i < ru->nb_rx; i++) + ru->openair0_cfg.rxbase[i] = ru->common.rxdata[i]; ru->openair0_cfg.rxsize = ru->nr_frame_parms->samples_per_subframe*10; reset_meas(&ru->ifdevice.tx_fhaul); - return(ru->ifdevice.trx_start_func(&ru->ifdevice)); + return ru->ifdevice.trx_start_func(&ru->ifdevice); } int start_rf(RU_t *ru) { @@ -1349,29 +1341,16 @@ int stop_rf(RU_t *ru) { } int start_write_thread(RU_t *ru) { - return(ru->rfdevice.trx_write_init(&ru->rfdevice)); + return ru->rfdevice.trx_write_init(&ru->rfdevice); } void init_RU_proc(RU_t *ru) { - int i=0; - RU_proc_t *proc; - proc = &ru->proc; - memset((void *)proc,0,sizeof(RU_proc_t)); - proc->ru = ru; - proc->instance_cnt_emulateRF = -1; - proc->first_rx = 1; - proc->first_tx = 1; - proc->frame_offset = 0; - proc->num_slaves = 0; - proc->frame_tx_unwrap = 0; - - for (i=0; i<10; i++) proc->symbol_mask[i]=0; - - pthread_mutex_init( &proc->mutex_emulateRF,NULL); - pthread_cond_init( &proc->cond_emulateRF, NULL); + ru->proc = (RU_proc_t){.ru = ru, .instance_cnt_emulateRF = -1, .first_rx = 1, .first_tx = 1}; + pthread_mutex_init(&ru->proc.mutex_emulateRF, NULL); + pthread_cond_init(&ru->proc.cond_emulateRF, NULL); if(emulate_rf) - threadCreate( &proc->pthread_emulateRF, emulatedRF_thread, (void *)proc, "emulateRF", -1, OAI_PRIORITY_RT ); + threadCreate(&ru->proc.pthread_emulateRF, emulatedRF_thread, (void *)&ru->proc, "emulateRF", -1, OAI_PRIORITY_RT); LOG_I(PHY, "Initialized RU proc %d (%s,%s),\n", ru->idx, NB_functions[ru->function], NB_timing[ru->if_timing]); } @@ -1395,10 +1374,10 @@ void kill_NR_RU_proc(int inst) { * mutex_fep/cond_fep. Thus, we unlocked above for pthread_FH above and do * the same for FEP thread below again (using broadcast() to ensure both * threads get the signal). This one will also destroy the mutex and cond. */ - pthread_mutex_lock(&proc->mutex_fep[0]); + pthread_mutex_lock(proc->mutex_fep); proc->instance_cnt_fep[0] = 0; - pthread_cond_broadcast(&proc->cond_fep[0]); - pthread_mutex_unlock( &proc->mutex_fep[0] ); + pthread_cond_broadcast(proc->cond_fep); + pthread_mutex_unlock(proc->mutex_fep); pthread_join(proc->pthread_FH, NULL); // everything should be stopped now, we can safely stop the RF device @@ -1417,19 +1396,15 @@ void kill_NR_RU_proc(int inst) { int check_capabilities(RU_t *ru,RRU_capabilities_t *cap) { FH_fmt_options_t fmt = cap->FH_fmt; int i; - int found_band=0; LOG_I(PHY,"RRU %d, num_bands %d, looking for band %d\n",ru->idx,cap->num_bands,ru->nr_frame_parms->nr_band); for (i=0; inum_bands; i++) { LOG_I(PHY,"band %d on RRU %d\n",cap->band_list[i],ru->idx); - - if (ru->nr_frame_parms->nr_band == cap->band_list[i]) { - found_band=1; + if (ru->nr_frame_parms->nr_band == cap->band_list[i]) break; - } } - if (found_band == 0) { + if (i == cap->num_bands) { LOG_I(PHY,"Couldn't find target NR band %d on RRU %d\n",ru->nr_frame_parms->nr_band,ru->idx); return(-1); } @@ -1441,18 +1416,18 @@ int check_capabilities(RU_t *ru,RRU_capabilities_t *cap) { break; case REMOTE_IF5: - if (fmt == OAI_IF5_only || fmt == OAI_IF5_and_IF4p5) return(0); - + if (fmt == OAI_IF5_only || fmt == OAI_IF5_and_IF4p5) + return (0); break; case REMOTE_IF4p5: - if (fmt == OAI_IF4p5_only || fmt == OAI_IF5_and_IF4p5) return(0); - + if (fmt == OAI_IF4p5_only || fmt == OAI_IF5_and_IF4p5) + return (0); break; case REMOTE_MBP_IF5: - if (fmt == MBP_IF5) return(0); - + if (fmt == MBP_IF5) + return (0); break; default: @@ -1464,46 +1439,40 @@ int check_capabilities(RU_t *ru,RRU_capabilities_t *cap) { } const char rru_format_options[4][20] = {"OAI_IF5_only", "OAI_IF4p5_only", "OAI_IF5_and_IF4p5", "MBP_IF5"}; - const char rru_formats[3][20] = {"OAI_IF5", "MBP_IF5", "OAI_IF4p5"}; const char ru_if_formats[4][20] = {"LOCAL_RF", "REMOTE_OAI_IF5", "REMOTE_MBP_IF5", "REMOTE_OAI_IF4p5"}; void configure_ru(void *ruu, void *arg) { RU_t *ru = (RU_t *)ruu; - RRU_config_t *config = (RRU_config_t *)arg; - RRU_capabilities_t *capabilities = (RRU_capabilities_t *)arg; nfapi_nr_config_request_scf_t *cfg = &ru->config; int ret; LOG_I(PHY, "Received capabilities from RRU %d\n", ru->idx); - if (capabilities->FH_fmt < MAX_FH_FMTs) LOG_I(PHY, "RU FH options %s\n",rru_format_options[capabilities->FH_fmt]); + RRU_capabilities_t *capabilities = (RRU_capabilities_t *)arg; + if (capabilities->FH_fmt < MAX_FH_FMTs) + LOG_I(PHY, "RU FH options %s\n", rru_format_options[capabilities->FH_fmt]); ret = check_capabilities(ru,capabilities); AssertFatal(ret == 0, "Cannot configure RRU %d, check_capabilities returned %d\n", ru->idx, ret); // take antenna capabilities of RRU - ru->nb_tx = capabilities->nb_tx[0]; - ru->nb_rx = capabilities->nb_rx[0]; + ru->nb_tx = capabilities->nb_tx[0]; + ru->nb_rx = capabilities->nb_rx[0]; // Pass configuration to RRU LOG_I(PHY, "Using %s fronthaul (%d), band %d \n",ru_if_formats[ru->if_south],ru->if_south,ru->nr_frame_parms->nr_band); + // wait for configuration - config->FH_fmt = ru->if_south; - config->num_bands = 1; - config->band_list[0] = ru->nr_frame_parms->nr_band; - config->tx_freq[0] = ru->nr_frame_parms->dl_CarrierFreq; - config->rx_freq[0] = ru->nr_frame_parms->ul_CarrierFreq; - //config->tdd_config[0] = ru->nr_frame_parms->tdd_config; - //config->tdd_config_S[0] = ru->nr_frame_parms->tdd_config_S; - config->att_tx[0] = ru->att_tx; - config->att_rx[0] = ru->att_rx; - config->N_RB_DL[0] = cfg->carrier_config.dl_grid_size[cfg->ssb_config.scs_common.value].value; - config->N_RB_UL[0] = cfg->carrier_config.dl_grid_size[cfg->ssb_config.scs_common.value].value; - config->threequarter_fs[0] = ru->nr_frame_parms->threequarter_fs; - /* if (ru->if_south==REMOTE_IF4p5) { - config->prach_FreqOffset[0] = ru->nr_frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset; - config->prach_ConfigIndex[0] = ru->nr_frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex; - LOG_I(PHY,"REMOTE_IF4p5: prach_FrequOffset %d, prach_ConfigIndex %d\n", - config->prach_FreqOffset[0],config->prach_ConfigIndex[0]);*/ + RRU_config_t *config = (RRU_config_t *)arg; + *config = (RRU_config_t){.FH_fmt = ru->if_south, + .num_bands = 1, + .band_list[0] = ru->nr_frame_parms->nr_band, + .tx_freq[0] = ru->nr_frame_parms->dl_CarrierFreq, + .rx_freq[0] = ru->nr_frame_parms->ul_CarrierFreq, + .att_tx[0] = ru->att_tx, + .att_rx[0] = ru->att_rx, + .N_RB_DL[0] = cfg->carrier_config.dl_grid_size[cfg->ssb_config.scs_common.value].value, + .N_RB_UL[0] = cfg->carrier_config.dl_grid_size[cfg->ssb_config.scs_common.value].value, + .threequarter_fs[0] = ru->nr_frame_parms->threequarter_fs}; nr_init_frame_parms(&ru->config, ru->nr_frame_parms); nr_phy_init_RU(ru); } @@ -1513,37 +1482,31 @@ void configure_rru(void *ruu, void *arg) RRU_config_t *config = (RRU_config_t *)arg; RU_t *ru = (RU_t *)ruu; nfapi_nr_config_request_scf_t *cfg = &ru->config; - ru->nr_frame_parms->nr_band = config->band_list[0]; - ru->nr_frame_parms->dl_CarrierFreq = config->tx_freq[0]; - ru->nr_frame_parms->ul_CarrierFreq = config->rx_freq[0]; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - if (ru->nr_frame_parms->dl_CarrierFreq == ru->nr_frame_parms->ul_CarrierFreq) { - cfg->cell_config.frame_duplex_type.value = TDD; - //ru->nr_frame_parms->tdd_config = config->tdd_config[0]; - //ru->nr_frame_parms->tdd_config_S = config->tdd_config_S[0]; + fp->nr_band = config->band_list[0]; + fp->dl_CarrierFreq = config->tx_freq[0]; + fp->ul_CarrierFreq = config->rx_freq[0]; + + if (fp->dl_CarrierFreq == fp->ul_CarrierFreq) { + cfg->cell_config.frame_duplex_type.value = TDD; } else - cfg->cell_config.frame_duplex_type.value = FDD; + cfg->cell_config.frame_duplex_type.value = FDD; - ru->att_tx = config->att_tx[0]; - ru->att_rx = config->att_rx[0]; + ru->att_tx = config->att_tx[0]; + ru->att_rx = config->att_rx[0]; int mu = cfg->ssb_config.scs_common.value; - cfg->carrier_config.dl_grid_size[mu].value = config->N_RB_DL[0]; - cfg->carrier_config.dl_grid_size[mu].value = config->N_RB_UL[0]; - ru->nr_frame_parms->threequarter_fs = config->threequarter_fs[0]; + cfg->carrier_config.dl_grid_size[mu].value = config->N_RB_DL[0]; + cfg->carrier_config.dl_grid_size[mu].value = config->N_RB_UL[0]; + fp->threequarter_fs = config->threequarter_fs[0]; - //ru->nr_frame_parms->pdsch_config_common.referenceSignalPower = ru->max_pdschReferenceSignalPower-config->att_tx[0]; if (ru->function==NGFI_RRU_IF4p5) { - ru->nr_frame_parms->att_rx = ru->att_rx; - ru->nr_frame_parms->att_tx = ru->att_tx; - /* - LOG_I(PHY,"Setting ru->function to NGFI_RRU_IF4p5, prach_FrequOffset %d, prach_ConfigIndex %d, att (%d,%d)\n", - config->prach_FreqOffset[0],config->prach_ConfigIndex[0],ru->att_tx,ru->att_rx); - ru->nr_frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset = config->prach_FreqOffset[0]; - ru->nr_frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex = config->prach_ConfigIndex[0]; */ + fp->att_rx = ru->att_rx; + fp->att_tx = ru->att_tx; } fill_rf_config(ru,ru->rf_config_file); - nr_init_frame_parms(&ru->config, ru->nr_frame_parms); + nr_init_frame_parms(&ru->config, fp); nr_phy_init_RU(ru); } @@ -1600,17 +1563,6 @@ void set_function_spec_param(RU_t *ru) ru->stop_rf = stop_rf; ru->start_write_thread = start_write_thread; // starting RF TX in different thread } - - /* - fill_rf_config(ru,rf_config_file); - init_frame_parms(&ru->frame_parms,1); - nr_phy_init_RU(ru); - - ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); - if (setup_RU_buffers(ru)!=0) { - exit(-1); - } - */ break; case REMOTE_IF5: // the remote unit is IF5 RRU @@ -1659,12 +1611,6 @@ void set_function_spec_param(RU_t *ru) void init_NR_RU(configmodule_interface_t *cfg, char *rf_config_file) { - int ru_id; - RU_t *ru; - PHY_VARS_gNB *gNB_RC; - PHY_VARS_gNB *gNB0= (PHY_VARS_gNB *)NULL; - NR_DL_FRAME_PARMS *fp = (NR_DL_FRAME_PARMS *)NULL; - int i; // create status mask RC.ru_mask = 0; pthread_mutex_init(&RC.ru_mutex,NULL); @@ -1674,9 +1620,9 @@ void init_NR_RU(configmodule_interface_t *cfg, char *rf_config_file) LOG_I(PHY,"number of L1 instances %d, number of RU %d, number of CPU cores %d\n",RC.nb_nr_L1_inst,RC.nb_RU,get_nprocs()); LOG_D(PHY,"Process RUs RC.nb_RU:%d\n",RC.nb_RU); - for (ru_id=0; ru_idrf_config_file = rf_config_file; ru->idx = ru_id; ru->ts_offset = 0; @@ -1693,23 +1639,18 @@ void init_NR_RU(configmodule_interface_t *cfg, char *rf_config_file) } } - gNB_RC = RC.gNB[0]; - gNB0 = ru->gNB_list[0]; - fp = ru->nr_frame_parms; + PHY_VARS_gNB *gNB_RC = RC.gNB[0]; + PHY_VARS_gNB *gNB0 = ru->gNB_list[0]; LOG_D(PHY, "RU FUnction:%d ru->if_south:%d\n", ru->function, ru->if_south); if (gNB0) { - if ((ru->function != NGFI_RRU_IF5) && (ru->function != NGFI_RRU_IF4p5)) - AssertFatal(gNB0, "gNB0 is null!\n"); - - if (gNB0 && gNB_RC) { + if (gNB_RC) { LOG_D(PHY, "Copying frame parms from gNB in RC to gNB %d in ru %d and frame_parms in ru\n", gNB0->Mod_id, ru->idx); - memcpy((void *)fp, &gNB_RC->frame_parms, sizeof(NR_DL_FRAME_PARMS)); - memcpy((void *)&gNB0->frame_parms, (void *)&gNB_RC->frame_parms, sizeof(NR_DL_FRAME_PARMS)); + *ru->nr_frame_parms = gNB_RC->frame_parms; + gNB0->frame_parms = gNB_RC->frame_parms; // attach all RU to all gNBs in its list/ LOG_D(PHY,"ru->num_gNB:%d gNB0->num_RU:%d\n", ru->num_gNB, gNB0->num_RU); - - for (i=0; inum_gNB; i++) { + for (int i = 0; i < ru->num_gNB; i++) { gNB0 = ru->gNB_list[i]; gNB0->RU_list[gNB0->num_RU++] = ru; } @@ -1723,22 +1664,21 @@ void init_NR_RU(configmodule_interface_t *cfg, char *rf_config_file) LOG_E(PHY, "Number of threads for gNB should be more than 1. Allocated only %d\n", threadCnt); char pool[80]; int s_offset = sprintf(pool,"%d",ru->tpcores[0]); - for (int icpu=1; icputpcores[icpu]); + for (int icpu = 1; icpu < threadCnt; icpu++) { + s_offset += sprintf(pool + s_offset, ",%d", ru->tpcores[icpu]); } LOG_I(PHY, "RU thread-pool core string %s (size %d)\n", pool, threadCnt); - ru->threadPool = (tpool_t*)malloc(sizeof(tpool_t)); + ru->threadPool = malloc(sizeof(tpool_t)); initTpool(pool, ru->threadPool, cpumeas(CPUMEAS_GETSTATE)); // FEP RX result FIFO - ru->respfeprx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); + ru->respfeprx = malloc(sizeof(notifiedFIFO_t)); initNotifiedFIFO(ru->respfeprx); // FEP TX result FIFO - ru->respfeptx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); + ru->respfeptx = malloc(sizeof(notifiedFIFO_t)); initNotifiedFIFO(ru->respfeptx); } } // for ru_id - // sleep(1); LOG_D(HW,"[nr-softmodem.c] RU threads created\n"); } @@ -1755,7 +1695,6 @@ void stop_RU(int nb_ru) { } } - /* --------------------------------------------------------*/ /* from here function to use configuration module */ static void NRRCconfig_RU(configmodule_interface_t *cfg) @@ -1764,199 +1703,199 @@ static void NRRCconfig_RU(configmodule_interface_t *cfg) paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST, NULL, 0}; config_getlist(cfg, &RUParamList, RUParams, sizeofArray(RUParams), NULL); - if (RUParamList.numelt > 0) { - RC.ru = (RU_t **)malloc(RC.nb_RU*sizeof(RU_t *)); - RC.ru_mask = (1 << RC.nb_RU) - 1; + if (RUParamList.numelt <= 0) + return; - for (int j = 0; j < RC.nb_RU; j++) { - RC.ru[j] = calloc(1, sizeof(*RC.ru[j])); - RC.ru[j]->idx = j; - RC.ru[j]->nr_frame_parms = calloc(1, sizeof(*RC.ru[j]->nr_frame_parms)); - RC.ru[j]->frame_parms = calloc(1, sizeof(*RC.ru[j]->frame_parms)); - RC.ru[j]->if_timing = synch_to_ext_device; + RC.ru = (RU_t **)malloc(RC.nb_RU * sizeof(RU_t *)); + RC.ru_mask = (1 << RC.nb_RU) - 1; - if (RC.nb_nr_L1_inst > 0) - RC.ru[j]->num_gNB = RUParamList.paramarray[j][RU_ENB_LIST_IDX].numelt; - else - RC.ru[j]->num_gNB = 0; + for (int j = 0; j < RC.nb_RU; j++) { + RU_t *ru = RC.ru[j] = calloc(1, sizeof(*RC.ru[j])); + ru->idx = j; + ru->nr_frame_parms = calloc(1, sizeof(*ru->nr_frame_parms)); + ru->frame_parms = calloc(1, sizeof(*ru->frame_parms)); + ru->if_timing = synch_to_ext_device; + paramdef_t *param = RUParamList.paramarray[j]; + if (RC.nb_nr_L1_inst > 0) + ru->num_gNB = param[RU_ENB_LIST_IDX].numelt; + else + ru->num_gNB = 0; - for (int i = 0; i < RC.ru[j]->num_gNB; i++) - RC.ru[j]->gNB_list[i] = RC.gNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]]; + for (int i = 0; i < ru->num_gNB; i++) + ru->gNB_list[i] = RC.gNB[param[RU_ENB_LIST_IDX].iptr[i]]; - if (config_isparamset(RUParamList.paramarray[j], RU_SDR_ADDRS)) { - RC.ru[j]->openair0_cfg.sdr_addrs = strdup(*(RUParamList.paramarray[j][RU_SDR_ADDRS].strptr)); - } + if (config_isparamset(param, RU_SDR_ADDRS)) { + ru->openair0_cfg.sdr_addrs = strdup(*param[RU_SDR_ADDRS].strptr); + } - if (config_isparamset(RUParamList.paramarray[j], RU_GPIO_CONTROL)) { - if (strcmp(*RUParamList.paramarray[j][RU_GPIO_CONTROL].strptr, "generic") == 0) { - RC.ru[j]->openair0_cfg.gpio_controller = RU_GPIO_CONTROL_GENERIC; - LOG_I(PHY, "RU GPIO control set as 'generic'\n"); - } else if (strcmp(*RUParamList.paramarray[j][RU_GPIO_CONTROL].strptr, "interdigital") == 0) { - RC.ru[j]->openair0_cfg.gpio_controller = RU_GPIO_CONTROL_INTERDIGITAL; - LOG_I(PHY, "RU GPIO control set as 'interdigital'\n"); - } else { - AssertFatal(false, - "bad GPIO controller in configuration file: '%s'\n", - *(RUParamList.paramarray[j][RU_GPIO_CONTROL].strptr)); - } - } else - RC.ru[j]->openair0_cfg.gpio_controller = RU_GPIO_CONTROL_NONE; - - if (config_isparamset(RUParamList.paramarray[j], RU_TX_SUBDEV)) { - RC.ru[j]->openair0_cfg.tx_subdev = strdup(*(RUParamList.paramarray[j][RU_TX_SUBDEV].strptr)); - LOG_I(PHY, "RU USRP tx subdev == %s\n", RC.ru[j]->openair0_cfg.tx_subdev); - } - - if (config_isparamset(RUParamList.paramarray[j], RU_RX_SUBDEV)) { - RC.ru[j]->openair0_cfg.rx_subdev = strdup(*(RUParamList.paramarray[j][RU_RX_SUBDEV].strptr)); - LOG_I(PHY, "RU USRP rx subdev == %s\n", RC.ru[j]->openair0_cfg.rx_subdev); - } - - if (config_isparamset(RUParamList.paramarray[j], RU_SDR_CLK_SRC)) { - if (strcmp(*(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr), "internal") == 0) { - RC.ru[j]->openair0_cfg.clock_source = internal; - LOG_I(PHY, "RU clock source set as internal\n"); - } else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr), "external") == 0) { - RC.ru[j]->openair0_cfg.clock_source = external; - LOG_I(PHY, "RU clock source set as external\n"); - } else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr), "gpsdo") == 0) { - RC.ru[j]->openair0_cfg.clock_source = gpsdo; - LOG_I(PHY, "RU clock source set as gpsdo\n"); - } else { - LOG_E(PHY, "Erroneous RU clock source in the provided configuration file: '%s'\n", *(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr)); - } + if (config_isparamset(param, RU_GPIO_CONTROL)) { + char *str = *param[RU_GPIO_CONTROL].strptr; + if (strcmp(str, "generic") == 0) { + ru->openair0_cfg.gpio_controller = RU_GPIO_CONTROL_GENERIC; + LOG_I(PHY, "RU GPIO control set as 'generic'\n"); + } else if (strcmp(str, "interdigital") == 0) { + ru->openair0_cfg.gpio_controller = RU_GPIO_CONTROL_INTERDIGITAL; + LOG_I(PHY, "RU GPIO control set as 'interdigital'\n"); } else { - LOG_D(PHY, "Setting clock source to internal\n"); - RC.ru[j]->openair0_cfg.clock_source = internal; + AssertFatal(false, "bad GPIO controller in configuration file: '%s'\n", str); } + } else + ru->openair0_cfg.gpio_controller = RU_GPIO_CONTROL_NONE; - if (config_isparamset(RUParamList.paramarray[j], RU_SDR_TME_SRC)) { - if (strcmp(*(RUParamList.paramarray[j][RU_SDR_TME_SRC].strptr), "internal") == 0) { - RC.ru[j]->openair0_cfg.time_source = internal; - LOG_I(PHY, "RU time source set as internal\n"); - } else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_TME_SRC].strptr), "external") == 0) { - RC.ru[j]->openair0_cfg.time_source = external; - LOG_I(PHY, "RU time source set as external\n"); - } else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_TME_SRC].strptr), "gpsdo") == 0) { - RC.ru[j]->openair0_cfg.time_source = gpsdo; - LOG_I(PHY, "RU time source set as gpsdo\n"); - } else { - LOG_E(PHY, "Erroneous RU time source in the provided configuration file: '%s'\n", *(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr)); - } + if (config_isparamset(param, RU_TX_SUBDEV)) { + ru->openair0_cfg.tx_subdev = strdup(*param[RU_TX_SUBDEV].strptr); + LOG_I(PHY, "RU USRP tx subdev == %s\n", ru->openair0_cfg.tx_subdev); + } + + if (config_isparamset(param, RU_RX_SUBDEV)) { + ru->openair0_cfg.rx_subdev = strdup(*param[RU_RX_SUBDEV].strptr); + LOG_I(PHY, "RU USRP rx subdev == %s\n", ru->openair0_cfg.rx_subdev); + } + + if (config_isparamset(param, RU_SDR_CLK_SRC)) { + char *str = *param[RU_SDR_CLK_SRC].strptr; + if (strcmp(str, "internal") == 0) { + ru->openair0_cfg.clock_source = internal; + LOG_I(PHY, "RU clock source set as internal\n"); + } else if (strcmp(str, "external") == 0) { + ru->openair0_cfg.clock_source = external; + LOG_I(PHY, "RU clock source set as external\n"); + } else if (strcmp(str, "gpsdo") == 0) { + ru->openair0_cfg.clock_source = gpsdo; + LOG_I(PHY, "RU clock source set as gpsdo\n"); } else { - LOG_D(PHY, "Setting time source to internal\n"); - RC.ru[j]->openair0_cfg.time_source = internal; + LOG_E(PHY, "Erroneous RU clock source in the provided configuration file: '%s'\n", str); + } + } else { + LOG_D(PHY, "Setting clock source to internal\n"); + ru->openair0_cfg.clock_source = internal; + } + + if (config_isparamset(param, RU_SDR_TME_SRC)) { + char *str = *param[RU_SDR_TME_SRC].strptr; + if (strcmp(str, "internal") == 0) { + ru->openair0_cfg.time_source = internal; + LOG_I(PHY, "RU time source set as internal\n"); + } else if (strcmp(str, "external") == 0) { + ru->openair0_cfg.time_source = external; + LOG_I(PHY, "RU time source set as external\n"); + } else if (strcmp(str, "gpsdo") == 0) { + ru->openair0_cfg.time_source = gpsdo; + LOG_I(PHY, "RU time source set as gpsdo\n"); + } else { + LOG_E(PHY, "Erroneous RU time source in the provided configuration file: '%s'\n", str); + } + } else { + LOG_D(PHY, "Setting time source to internal\n"); + ru->openair0_cfg.time_source = internal; + } + + ru->openair0_cfg.tune_offset = get_softmodem_params()->tune_offset; + + if (strcmp(*param[RU_LOCAL_RF_IDX].strptr, "yes") == 0) { + if (!config_isparamset(param, RU_LOCAL_IF_NAME_IDX)) { + ru->if_south = LOCAL_RF; + ru->function = gNodeB_3GPP; + LOG_D(PHY, "Setting function for RU %d to gNodeB_3GPP\n", j); + } else { + ru->eth_params.local_if_name = strdup(*param[RU_LOCAL_IF_NAME_IDX].strptr); + ru->eth_params.my_addr = strdup(*param[RU_LOCAL_ADDRESS_IDX].strptr); + ru->eth_params.remote_addr = strdup(*param[RU_REMOTE_ADDRESS_IDX].strptr); + ru->eth_params.my_portc = *param[RU_LOCAL_PORTC_IDX].uptr; + ru->eth_params.remote_portc = *param[RU_REMOTE_PORTC_IDX].uptr; + ru->eth_params.my_portd = *param[RU_LOCAL_PORTD_IDX].uptr; + ru->eth_params.remote_portd = *param[RU_REMOTE_PORTD_IDX].uptr; + char *str = *param[RU_TRANSPORT_PREFERENCE_IDX].strptr; + if (strcmp(str, "udp") == 0) { + ru->if_south = LOCAL_RF; + ru->function = NGFI_RRU_IF5; + ru->eth_params.transp_preference = ETH_UDP_MODE; + LOG_D(PHY, "Setting function for RU %d to NGFI_RRU_IF5 (udp)\n", j); + } else if (strcmp(str, "raw") == 0) { + ru->if_south = LOCAL_RF; + ru->function = NGFI_RRU_IF5; + ru->eth_params.transp_preference = ETH_RAW_MODE; + LOG_D(PHY, "Setting function for RU %d to NGFI_RRU_IF5 (raw)\n", j); + } else if (strcmp(str, "udp_if4p5") == 0) { + ru->if_south = LOCAL_RF; + ru->function = NGFI_RRU_IF4p5; + ru->eth_params.transp_preference = ETH_UDP_IF4p5_MODE; + LOG_D(PHY, "Setting function for RU %d to NGFI_RRU_IF4p5 (udp)\n", j); + } else if (strcmp(str, "raw_if4p5") == 0) { + ru->if_south = LOCAL_RF; + ru->function = NGFI_RRU_IF4p5; + ru->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; + LOG_D(PHY, "Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n", j); + } } - RC.ru[j]->openair0_cfg.tune_offset = get_softmodem_params()->tune_offset; + ru->max_pdschReferenceSignalPower = *param[RU_MAX_RS_EPRE_IDX].uptr; + ru->max_rxgain = *param[RU_MAX_RXGAIN_IDX].uptr; + ru->sf_extension = *param[RU_SF_EXTENSION_IDX].uptr; + } // strcmp(local_rf, "yes") == 0 + else { + char *str = *param[RU_TRANSPORT_PREFERENCE_IDX].strptr; + LOG_D(PHY, "RU %d: Transport %s\n", j, str); + ru->eth_params.local_if_name = strdup(*param[RU_LOCAL_IF_NAME_IDX].strptr); + ru->eth_params.my_addr = strdup(*param[RU_LOCAL_ADDRESS_IDX].strptr); + ru->eth_params.remote_addr = strdup(*param[RU_REMOTE_ADDRESS_IDX].strptr); + ru->eth_params.my_portc = *param[RU_LOCAL_PORTC_IDX].uptr; + ru->eth_params.remote_portc = *param[RU_REMOTE_PORTC_IDX].uptr; + ru->eth_params.my_portd = *param[RU_LOCAL_PORTD_IDX].uptr; + ru->eth_params.remote_portd = *param[RU_REMOTE_PORTD_IDX].uptr; - if (strcmp(*(RUParamList.paramarray[j][RU_LOCAL_RF_IDX].strptr), "yes") == 0) { - if (!(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX))) { - RC.ru[j]->if_south = LOCAL_RF; - RC.ru[j]->function = gNodeB_3GPP; - LOG_D(PHY, "Setting function for RU %d to gNodeB_3GPP\n", j); - } else { - 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); - - 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; - LOG_D(PHY, "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; - LOG_D(PHY, "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; - LOG_D(PHY, "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; - LOG_D(PHY, "Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n", j); - } - } - - RC.ru[j]->max_pdschReferenceSignalPower = *(RUParamList.paramarray[j][RU_MAX_RS_EPRE_IDX].uptr);; - RC.ru[j]->max_rxgain = *(RUParamList.paramarray[j][RU_MAX_RXGAIN_IDX].uptr); - RC.ru[j]->sf_extension = *(RUParamList.paramarray[j][RU_SF_EXTENSION_IDX].uptr); - } //strcmp(local_rf, "yes") == 0 - else { - LOG_D(PHY, "RU %d: Transport %s\n", j, *(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr)); - 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); - - if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) { - RC.ru[j]->if_south = REMOTE_IF5; - RC.ru[j]->function = NGFI_RAU_IF5; - RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE; - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_ecpri_if5") == 0) { - RC.ru[j]->if_south = REMOTE_IF5; - RC.ru[j]->function = NGFI_RAU_IF5; - RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF5_ECPRI_MODE; - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) { - RC.ru[j]->if_south = REMOTE_IF5; - RC.ru[j]->function = NGFI_RAU_IF5; - RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE; - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) { - RC.ru[j]->if_south = REMOTE_IF4p5; - RC.ru[j]->function = NGFI_RAU_IF4p5; - RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE; - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) { - RC.ru[j]->if_south = REMOTE_IF4p5; - RC.ru[j]->function = NGFI_RAU_IF4p5; - RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; - } - } /* strcmp(local_rf, "yes") != 0 */ - - RC.ru[j]->nb_tx = *(RUParamList.paramarray[j][RU_NB_TX_IDX].uptr); - RC.ru[j]->nb_rx = *(RUParamList.paramarray[j][RU_NB_RX_IDX].uptr); - RC.ru[j]->att_tx = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr); - RC.ru[j]->att_rx = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr); - RC.ru[j]->if_frequency = *(RUParamList.paramarray[j][RU_IF_FREQUENCY].u64ptr); - RC.ru[j]->if_freq_offset = *(RUParamList.paramarray[j][RU_IF_FREQ_OFFSET].iptr); - RC.ru[j]->sl_ahead = *(RUParamList.paramarray[j][RU_SL_AHEAD].iptr); - RC.ru[j]->num_bands = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt; - for (int i = 0; i < RC.ru[j]->num_bands; i++) - RC.ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i]; - RC.ru[j]->openair0_cfg.nr_flag = *(RUParamList.paramarray[j][RU_NR_FLAG].iptr); - RC.ru[j]->openair0_cfg.nr_band = RC.ru[j]->band[0]; - RC.ru[j]->openair0_cfg.nr_scs_for_raster = *(RUParamList.paramarray[j][RU_NR_SCS_FOR_RASTER].iptr); - LOG_D(PHY, - "[RU %d] Setting nr_flag %d, nr_band %d, nr_scs_for_raster %d\n", - j, - RC.ru[j]->openair0_cfg.nr_flag, - RC.ru[j]->openair0_cfg.nr_band, - RC.ru[j]->openair0_cfg.nr_scs_for_raster); - RC.ru[j]->openair0_cfg.rxfh_cores[0] = *(RUParamList.paramarray[j][RU_RXFH_CORE_ID].iptr); - RC.ru[j]->openair0_cfg.txfh_cores[0] = *(RUParamList.paramarray[j][RU_TXFH_CORE_ID].iptr); - RC.ru[j]->num_tpcores = *(RUParamList.paramarray[j][RU_NUM_TP_CORES].iptr); - RC.ru[j]->half_slot_parallelization = *(RUParamList.paramarray[j][RU_HALF_SLOT_PARALLELIZATION].iptr); - RC.ru[j]->ru_thread_core = *(RUParamList.paramarray[j][RU_RU_THREAD_CORE].iptr); - LOG_D(PHY, "[RU %d] Setting half-slot parallelization to %d\n", j, RC.ru[j]->half_slot_parallelization); - AssertFatal(RC.ru[j]->num_tpcores <= RUParamList.paramarray[j][RU_TP_CORES].numelt, "Number of TP cores should be <=16\n"); - for (int i = 0; i < RC.ru[j]->num_tpcores; i++) - RC.ru[j]->tpcores[i] = RUParamList.paramarray[j][RU_TP_CORES].iptr[i]; - }// j=0..num_rus - } else { - RC.nb_RU = 0; - } // setting != NULL + if (strcmp(str, "udp") == 0) { + ru->if_south = REMOTE_IF5; + ru->function = NGFI_RAU_IF5; + ru->eth_params.transp_preference = ETH_UDP_MODE; + } else if (strcmp(str, "udp_ecpri_if5") == 0) { + ru->if_south = REMOTE_IF5; + ru->function = NGFI_RAU_IF5; + ru->eth_params.transp_preference = ETH_UDP_IF5_ECPRI_MODE; + } else if (strcmp(str, "raw") == 0) { + ru->if_south = REMOTE_IF5; + ru->function = NGFI_RAU_IF5; + ru->eth_params.transp_preference = ETH_RAW_MODE; + } else if (strcmp(str, "udp_if4p5") == 0) { + ru->if_south = REMOTE_IF4p5; + ru->function = NGFI_RAU_IF4p5; + ru->eth_params.transp_preference = ETH_UDP_IF4p5_MODE; + } else if (strcmp(str, "raw_if4p5") == 0) { + ru->if_south = REMOTE_IF4p5; + ru->function = NGFI_RAU_IF4p5; + ru->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; + } + } /* strcmp(local_rf, "yes") != 0 */ + ru->nb_tx = *param[RU_NB_TX_IDX].uptr; + ru->nb_rx = *param[RU_NB_RX_IDX].uptr; + ru->att_tx = *param[RU_ATT_TX_IDX].uptr; + ru->att_rx = *param[RU_ATT_RX_IDX].uptr; + ru->if_frequency = *param[RU_IF_FREQUENCY].u64ptr; + ru->if_freq_offset = *param[RU_IF_FREQ_OFFSET].iptr; + ru->sl_ahead = *param[RU_SL_AHEAD].iptr; + ru->num_bands = param[RU_BAND_LIST_IDX].numelt; + for (int i = 0; i < ru->num_bands; i++) + ru->band[i] = param[RU_BAND_LIST_IDX].iptr[i]; + ru->openair0_cfg.nr_flag = *param[RU_NR_FLAG].iptr; + ru->openair0_cfg.nr_band = ru->band[0]; + ru->openair0_cfg.nr_scs_for_raster = *param[RU_NR_SCS_FOR_RASTER].iptr; + LOG_D(PHY, + "[RU %d] Setting nr_flag %d, nr_band %d, nr_scs_for_raster %d\n", + j, + ru->openair0_cfg.nr_flag, + ru->openair0_cfg.nr_band, + ru->openair0_cfg.nr_scs_for_raster); + ru->openair0_cfg.rxfh_cores[0] = *param[RU_RXFH_CORE_ID].iptr; + ru->openair0_cfg.txfh_cores[0] = *param[RU_TXFH_CORE_ID].iptr; + ru->num_tpcores = *param[RU_NUM_TP_CORES].iptr; + ru->half_slot_parallelization = *param[RU_HALF_SLOT_PARALLELIZATION].iptr; + ru->ru_thread_core = *param[RU_RU_THREAD_CORE].iptr; + LOG_D(PHY, "[RU %d] Setting half-slot parallelization to %d\n", j, ru->half_slot_parallelization); + AssertFatal(ru->num_tpcores <= param[RU_TP_CORES].numelt, "Number of TP cores should be <=16\n"); + for (int i = 0; i < ru->num_tpcores; i++) + ru->tpcores[i] = param[RU_TP_CORES].iptr[i]; + } // j=0..num_rus return; }