Commit 21aff80b authored by Raymond Knopp's avatar Raymond Knopp

Merge branch 'enhancement-10-harmony' of...

Merge branch 'enhancement-10-harmony' of https://gitlab.eurecom.fr/oai/openairinterface5g into enhancement-10-harmony

Conflicts:
	targets/RT/USER/lte-enb.c
parents f91457d8 5541cafd
...@@ -138,7 +138,7 @@ else (CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7l") ...@@ -138,7 +138,7 @@ else (CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7l")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -mavx2") set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -mavx2")
endif() endif()
if (CPUINFO MATCHES "sse4_1") if (CPUINFO MATCHES "sse4_1")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -msse4.1 -mavx2") set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -msse4.1")
endif() endif()
if (CPUINFO MATCHES "ssse3") if (CPUINFO MATCHES "ssse3")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -mssse3") set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -mssse3")
...@@ -960,6 +960,7 @@ add_boolean_option(OAI_NW_DRIVER_USE_NETLINK True "????") ...@@ -960,6 +960,7 @@ add_boolean_option(OAI_NW_DRIVER_USE_NETLINK True "????")
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/rar_tools.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/rar_tools.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/print_stats.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/print_stats.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/initial_sync.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/initial_sync.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if4_tools.c
${OPENAIR1_DIR}/PHY/MODULATION/ofdm_mod.c ${OPENAIR1_DIR}/PHY/MODULATION/ofdm_mod.c
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep.c ${OPENAIR1_DIR}/PHY/MODULATION/slot_fep.c
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_mbsfn.c ${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_mbsfn.c
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
/*! \file PHY/LTE_TRANSPORT/if4_tools.c /*! \file PHY/LTE_TRANSPORT/if4_tools.c
* \brief * \brief
* \author Mauricio Gunther, S. Sandeep Kumar, Raymond Knopp * \author Fredrik Skretteberg, Tobias Schuster, Mauricio Gunther, S. Sandeep Kumar, Raymond Knopp
* \date 2016 * \date 2016
* \version 0.1 * \version 0.1
* \company Eurecom * \company Eurecom
...@@ -38,109 +38,137 @@ ...@@ -38,109 +38,137 @@
* \warning * \warning
*/ */
#ifndef USER_MODE
#include "if4_tools.h"
#include <stdint.h> #include <stdint.h>
#else
#include "PHY/defs.h"
#include "PHY/LTE_TRANSPORT/if4_tools.h" #include "PHY/LTE_TRANSPORT/if4_tools.h"
#endif #include "PHY/TOOLS/ALAW/alaw_lut.h"
// Get device information // Get device information
void send_IF4(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc) { void send_IF4(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, uint16_t packet_type) {
int frame = proc->frame_tx; LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
int subframe = proc->subframe_tx; int32_t **txdataF = eNB->common_vars.txdataF[0];
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
uint16_t symbol_id, element_id;
uint16_t i; uint16_t db_fulllength = 12*fp->N_RB_DL;
uint16_t db_halflength = db_fulllength>>1;
float_t data_block_length = 1200*(fp->ofdm_symbol_size/2048); int slotoffsetF = (proc->subframe_tx)*(fp->ofdm_symbol_size)*((fp->Ncp==1) ? 12 : 14) + 1;
uint16_t *data_block = (uint16_t*)malloc(data_block_length*sizeof(uint16_t)); int blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength;
int16_t *data_block = (int16_t*)malloc(db_fulllength*sizeof(int16_t));
// Caller: RCC - DL *** handle RRU case - UL and PRACH *** // Caller: RCC - DL *** handle RRU case - UL and PRACH ***
if (eNB->node_function == NGFI_RCC_IF4) { if (packet_type == IF4_PDLFFT) {
IF4_dl_packet_t *dl_packet = (IF4_dl_packet_t*)malloc(sizeof_IF4_dl_packet_t); IF4_dl_packet_t *dl_packet = (IF4_dl_packet_t*)malloc(sizeof_IF4_dl_packet_t);
gen_IF4_dl_packet(dl_packet, proc); gen_IF4_dl_packet(dl_packet, proc);
dl_packet->data_block = data_block; dl_packet->data_block = data_block;
for(i=0; i<fp->symbols_per_tti; i++) { for (symbol_id=0; symbol_id<fp->symbols_per_tti; symbol_id++) {
//Do compression of the two parts and generate data blocks printf("\n Send IF4 for frame %d, subframe %d and symbol %d\n", proc->frame_tx, proc->subframe_tx, symbol_id);
//symbol = eNB->common_vars.txdataF[0][0 /*antenna number*/][subframe*fp->ofdm_symbol_size*(fp->symbols_per_tti)] // Do compression of the two parts and generate data blocks
//data_block[j] = Atan(symbol[fp->ofmd_symbol_size - NrOfNonZeroValues + j -1])<<16 + Atan(symbol[fp->ofmd_symbol_size - NrOfNonZeroValues + j]); for (element_id=0; element_id<db_halflength; element_id++) {
//data_block[j+NrOfNonZeroValues] = Atan(subframe[i][j+1])<<16 + Atan(subframe[i][j+2]); data_block[element_id] = lin2alaw[ (txdataF[0][blockoffsetF+element_id] & 0xffff) + 32768 ];
data_block[element_id] |= lin2alaw[ (txdataF[0][blockoffsetF+element_id]>>16) + 32768 ]<<8;
data_block[element_id+db_halflength] = lin2alaw[ (txdataF[0][slotoffsetF+element_id] & 0xffff) + 32768 ];
data_block[element_id+db_halflength] |= lin2alaw[ (txdataF[0][slotoffsetF+element_id]>>16) + 32768 ]<<8;
}
// Update information in generated packet // Update information in generated packet
dl_packet->frame_status.sym_num = i; dl_packet->frame_status.sym_num = symbol_id;
// Write the packet(s) to the fronthaul // Write the packet(s) to the fronthaul
//if ((bytes_sent = dev->eth_dev.trx_write_func (&dev->eth_dev, // if ((bytes_sent = eNB->ifdevice.trx_write_func(&eNB->ifdevice,
// timestamp_rx, // (proc->timestamp_tx-eNB->ifdevice.openair0_cfg.tx_sample_advance),
// rx_eNB, // dl_packet,
// spp_eth, // eNB->frame_parms.samples_per_tti,
// dev->eth_dev.openair0_cfg->rx_num_channels, // eNB->frame_parms.nb_antennas_tx,
// 0)) < 0) { // 0)) < 0) {
// perror("RCC : ETHERNET write"); // perror("RCC : ETHERNET write");
//} //}
slotoffsetF += fp->ofdm_symbol_size;
blockoffsetF += fp->ofdm_symbol_size;
} }
}else { } else if (packet_type == IF4_PULFFT) {
IF4_ul_packet_t *ul_packet = (IF4_ul_packet_t*)malloc(sizeof_IF4_ul_packet_t); IF4_ul_packet_t *ul_packet = (IF4_ul_packet_t*)malloc(sizeof_IF4_ul_packet_t);
gen_IF4_ul_packet(ul_packet, proc); gen_IF4_ul_packet(ul_packet, proc);
ul_packet->data_block = data_block; ul_packet->data_block = data_block;
for(i=0; i<fp->symbols_per_tti; i++) { for (symbol_id=0; symbol_id<fp->symbols_per_tti; symbol_id++) {
//Do compression of the two parts and generate data blocks
//symbol = eNB->common_vars.txdataF[0][0 /*antenna number*/][subframe*fp->ofdm_symbol_size*(fp->symbols_per_tti)] // Do compression of the two parts and generate data blocks - rxdataF
//data_block[j] = Atan(symbol[fp->ofmd_symbol_size - NrOfNonZeroValues + j -1])<<16 + Atan(symbol[fp->ofmd_symbol_size - NrOfNonZeroValues + j]); for (element_id=0; element_id<db_halflength; element_id++) {
//data_block[j+NrOfNonZeroValues] = Atan(subframe[i][j+1])<<16 + Atan(subframe[i][j+2]); //data_block[element_id] = lin2alaw[ (rxdataF[0][blockoffsetF+element_id] & 0xffff) + 32768 ];
//data_block[element_id] |= lin2alaw[ (rxdataF[0][blockoffsetF+element_id]>>16) + 32768 ]<<8;
//data_block[element_id+db_halflength] = lin2alaw[ (txdataF[0][slotoffsetF+element_id] & 0xffff) + 32768 ];
//data_block[element_id+db_halflength] |= lin2alaw[ (txdataF[0][slotoffsetF+element_id]>>16) + 32768 ]<<8;
}
// Update information in generated packet // Update information in generated packet
ul_packet->frame_status.sym_num = i; ul_packet->frame_status.sym_num = symbol_id;
// Write the packet(s) to the fronthaul // Write the packet(s) to the fronthaul
slotoffsetF += fp->ofdm_symbol_size;
blockoffsetF += fp->ofdm_symbol_size;
} }
} } else if (packet_type == IF4_PRACH) {
} else {
AssertFatal(1==0, "send_IF4 - Unknown packet_type %x", packet_type);
}
return;
} }
void recv_IF4(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc) { void recv_IF4(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, uint16_t *packet_type, uint32_t *symbol_number) {
// Caller: RRU - DL *** handle RCC case - UL and PRACH *** *packet_type = 0;
int16_t *data_block=NULL;
if (eNB->node_function == NGFI_RRU_IF4) {
// Read packet(s) from the fronthaul
// for(i=0; i<fp->symbols_per_tti; i++) {
// if (dev->eth_dev.trx_read_func (&dev->eth_dev,
// timestamp_rx,
// rx_eNB,
// spp_eth,
// dev->eth_dev.openair0_cfg->rx_num_channels
// ) < 0) {
// perror("RRU : ETHERNET read");
// }
// printf("\n Recv IF4 for frame %d, subframe %d and symbol %d\n", proc->frame_tx, proc->subframe_tx, symbol_id);
//*packet_type = ;
if (*packet_type == IF4_PDLFFT) {
for(i=0; i<fp->symbols_per_tti; i++) {
// Read packet(s) from the fronthaul
if (dev->eth_dev.trx_read_func (&dev->eth_dev,
timestamp_rx,
rx_eNB,
spp_eth,
dev->eth_dev.openair0_cfg->rx_num_channels
) < 0) {
perror("RRU : ETHERNET read");
}
// Apply reverse processing - decompression // Apply reverse processing - decompression
// txAlawtolinear( Datablock ) // txAlawtolinear( Datablock )
// Generate and return the OFDM symbols (txdataF) // Generate and return the OFDM symbols (txdataF)
txDataF // txDataF
}
}else {
} } else if (*packet_type == IF4_PULFFT) {
} else if (*packet_type == IF4_PRACH) {
} else {
AssertFatal(1==0, "recv_IF4 - Unknown packet_type %x", *packet_type);
}
return;
} }
void gen_IF4_dl_packet(IF4_dl_packet_t *dl_packet, eNB_rxtx_proc_t *proc) { void gen_IF4_dl_packet(IF4_dl_packet_t *dl_packet, eNB_rxtx_proc_t *proc) {
// Set Type and Sub-Type // Set Type and Sub-Type
dl_packet->type = 0x080A; dl_packet->type = IF4_PACKET_TYPE;
dl_packet->sub_type = IF4_PDLFFT; dl_packet->sub_type = IF4_PDLFFT;
// Leave reserved as it is // Leave reserved as it is
...@@ -160,7 +188,7 @@ void gen_IF4_dl_packet(IF4_dl_packet_t *dl_packet, eNB_rxtx_proc_t *proc) { ...@@ -160,7 +188,7 @@ void gen_IF4_dl_packet(IF4_dl_packet_t *dl_packet, eNB_rxtx_proc_t *proc) {
void gen_IF4_ul_packet(IF4_ul_packet_t *ul_packet, eNB_rxtx_proc_t *proc) { void gen_IF4_ul_packet(IF4_ul_packet_t *ul_packet, eNB_rxtx_proc_t *proc) {
// Set Type and Sub-Type // Set Type and Sub-Type
ul_packet->type = 0x080A; ul_packet->type = IF4_PACKET_TYPE;
ul_packet->sub_type = IF4_PULFFT; ul_packet->sub_type = IF4_PULFFT;
// Leave reserved as it is // Leave reserved as it is
...@@ -184,7 +212,7 @@ void gen_IF4_ul_packet(IF4_ul_packet_t *ul_packet, eNB_rxtx_proc_t *proc) { ...@@ -184,7 +212,7 @@ void gen_IF4_ul_packet(IF4_ul_packet_t *ul_packet, eNB_rxtx_proc_t *proc) {
void gen_IF4_prach_packet(IF4_prach_packet_t *prach_packet, eNB_rxtx_proc_t *proc) { void gen_IF4_prach_packet(IF4_prach_packet_t *prach_packet, eNB_rxtx_proc_t *proc) {
// Set Type and Sub-Type // Set Type and Sub-Type
prach_packet->type = 0x080A; prach_packet->type = IF4_PACKET_TYPE;
prach_packet->sub_type = IF4_PRACH; prach_packet->sub_type = IF4_PRACH;
// Leave reserved as it is // Leave reserved as it is
......
...@@ -38,6 +38,10 @@ ...@@ -38,6 +38,10 @@
* \warning * \warning
*/ */
#include <stdint.h>
/// Macro for IF4 packet type
#define IF4_PACKET_TYPE 0x080A
#define IF4_PULFFT 0x0019 #define IF4_PULFFT 0x0019
#define IF4_PDLFFT 0x0020 #define IF4_PDLFFT 0x0020
#define IF4_PRACH 0x0021 #define IF4_PRACH 0x0021
...@@ -103,7 +107,7 @@ struct IF4_dl_packet { ...@@ -103,7 +107,7 @@ struct IF4_dl_packet {
/// Frame Status /// Frame Status
IF4_frame_status_t frame_status; IF4_frame_status_t frame_status;
/// Data Blocks /// Data Blocks
uint16_t *data_block; int16_t *data_block;
/// Frame Check Sequence /// Frame Check Sequence
uint32_t fcs; uint32_t fcs;
}; };
...@@ -141,7 +145,7 @@ struct IF4_ul_packet { ...@@ -141,7 +145,7 @@ struct IF4_ul_packet {
/// Gain 7 /// Gain 7
IF4_gain_t gain7; IF4_gain_t gain7;
/// Data Blocks /// Data Blocks
uint16_t *data_block; int16_t *data_block;
/// Frame Check Sequence /// Frame Check Sequence
uint32_t fcs; uint32_t fcs;
}; };
...@@ -163,7 +167,7 @@ struct IF4_prach_packet { ...@@ -163,7 +167,7 @@ struct IF4_prach_packet {
/// LTE Prach Configuration /// LTE Prach Configuration
IF4_lte_prach_conf_t prach_conf; IF4_lte_prach_conf_t prach_conf;
/// Prach Data Block (one antenna) /// Prach Data Block (one antenna)
uint16_t *data_block; int16_t *data_block;
/// Frame Check Sequence /// Frame Check Sequence
uint32_t fcs; uint32_t fcs;
}; };
...@@ -177,6 +181,6 @@ void gen_IF4_ul_packet(IF4_ul_packet_t*, eNB_rxtx_proc_t*); ...@@ -177,6 +181,6 @@ void gen_IF4_ul_packet(IF4_ul_packet_t*, eNB_rxtx_proc_t*);
void gen_IF4_prach_packet(IF4_prach_packet_t*, eNB_rxtx_proc_t*); void gen_IF4_prach_packet(IF4_prach_packet_t*, eNB_rxtx_proc_t*);
void send_IF4(PHY_VARS_eNB*, eNB_rxtx_proc_t*); void send_IF4(PHY_VARS_eNB*, eNB_rxtx_proc_t*, uint16_t);
void recv_IF4(PHY_VARS_eNB*, eNB_rxtx_proc_t*, int*, int*); void recv_IF4(PHY_VARS_eNB*, eNB_rxtx_proc_t*, uint16_t*, uint32_t*);
...@@ -1269,16 +1269,19 @@ void rx_prach(PHY_VARS_eNB *eNB, ...@@ -1269,16 +1269,19 @@ void rx_prach(PHY_VARS_eNB *eNB,
} }
if (eNB->node_function == NGFI_RRU_IF4) { if (eNB->node_function == NGFI_RRU_IF4) {
//send prachF to RCC /// **** send_IF4 of prachF to RCC **** ///
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 1 );
// send_IF4();
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 0 );
return; return;
} }
// in case of RCC and prach received rx_thread wakes up prach // in case of RCC and prach received rx_thread wakes up prach
//else if (eNB->node_function == NGFI_RCC_IF4) { //else if (eNB->node_function == NGFI_RCC_IF4) {
//wait for prachF from RRU and continue with PRACH processing // wait for prachF from RRU and continue with PRACH processing
//} //}
// here onwards is for eNodeB_3GPP or NGFI_RCC_IF4 // here onwards is for eNodeB_3GPP or NGFI_RCC_IF4
preamble_offset_old = 99; preamble_offset_old = 99;
......
...@@ -139,6 +139,8 @@ static inline void* malloc16_clear( size_t size ) ...@@ -139,6 +139,8 @@ static inline void* malloc16_clear( size_t size )
#include "PHY/LTE_TRANSPORT/defs.h" #include "PHY/LTE_TRANSPORT/defs.h"
#include <pthread.h> #include <pthread.h>
#include "targets/ARCH/COMMON/common_lib.h"
#define NUM_DCI_MAX 32 #define NUM_DCI_MAX 32
#define NUMBER_OF_eNB_SECTORS_MAX 3 #define NUMBER_OF_eNB_SECTORS_MAX 3
...@@ -456,6 +458,11 @@ typedef struct PHY_VARS_eNB_s { ...@@ -456,6 +458,11 @@ typedef struct PHY_VARS_eNB_s {
SLIST_HEAD(ral_thresholds_gen_poll_enb_s, ral_threshold_phy_t) ral_thresholds_gen_polled[RAL_LINK_PARAM_GEN_MAX]; SLIST_HEAD(ral_thresholds_gen_poll_enb_s, ral_threshold_phy_t) ral_thresholds_gen_polled[RAL_LINK_PARAM_GEN_MAX];
SLIST_HEAD(ral_thresholds_lte_poll_enb_s, ral_threshold_phy_t) ral_thresholds_lte_polled[RAL_LINK_PARAM_LTE_MAX]; SLIST_HEAD(ral_thresholds_lte_poll_enb_s, ral_threshold_phy_t) ral_thresholds_lte_polled[RAL_LINK_PARAM_LTE_MAX];
#endif #endif
/// RF and Interface devices per CC
openair0_device rfdevice;
openair0_device ifdevice;
// *** Handle spatially distributed MIMO antenna ports
} PHY_VARS_eNB; } PHY_VARS_eNB;
......
...@@ -44,6 +44,8 @@ ...@@ -44,6 +44,8 @@
#include "SCHED/defs.h" #include "SCHED/defs.h"
#include "SCHED/extern.h" #include "SCHED/extern.h"
#include "PHY/LTE_TRANSPORT/if4_tools.h"
#ifdef EMOS #ifdef EMOS
#include "SCHED/phy_procedures_emos.h" #include "SCHED/phy_procedures_emos.h"
#endif #endif
...@@ -59,6 +61,8 @@ ...@@ -59,6 +61,8 @@
#include "assertions.h" #include "assertions.h"
#include "msc.h" #include "msc.h"
#include <time.h>
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
# include "intertask_interface.h" # include "intertask_interface.h"
#endif #endif
...@@ -73,7 +77,8 @@ void exit_fun(const char* s); ...@@ -73,7 +77,8 @@ void exit_fun(const char* s);
extern int exit_openair; extern int exit_openair;
extern openair0_device openair0; // Fix per CC openair rf/if device update
// extern openair0_device openair0;
unsigned char dlsch_input_buffer[2700] __attribute__ ((aligned(32))); unsigned char dlsch_input_buffer[2700] __attribute__ ((aligned(32)));
int eNB_sync_buffer0[640*6] __attribute__ ((aligned(32))); int eNB_sync_buffer0[640*6] __attribute__ ((aligned(32)));
...@@ -1429,24 +1434,6 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, ...@@ -1429,24 +1434,6 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
#endif #endif
// Clean up split point *** RRU only function to recv and do_OFDM_mod ***
if (eNB->node_function == eNodeB_3GPP) {
// Add above to IF4 split
// do_OFDM_mod
}else if (eNB->node_function == NGFI_RCC_IF4) {
//send_IF4(eNB,subframe<<1);
//send_IF4(eNB,(subframe<<1)+1);
}else if (eNB->node_function == NGFI_RRU_IF4) { // => acquisition from RCC (IF4)
// get frame/subframe information from IF4 interface
//recv_IF4(eNB,subframe<<1);
//recv_IF4(eNB,1+(subframe<<1));
//do_OFDM_mod
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX,0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX,0);
stop_meas(&eNB->phy_proc_tx); stop_meas(&eNB->phy_proc_tx);
...@@ -2488,7 +2475,6 @@ void cba_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq_p ...@@ -2488,7 +2475,6 @@ void cba_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq_p
} }
void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_flag) { void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_flag) {
int i,l; int i,l;
...@@ -2498,160 +2484,198 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_fl ...@@ -2498,160 +2484,198 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_fl
eNB_proc_t *proc = &eNB->proc; eNB_proc_t *proc = &eNB->proc;
int subframe = proc->subframe_rx; int subframe = proc->subframe_rx;
int frame = proc->frame_rx; int frame = proc->frame_rx;
int symbol_number, symbol_mask, symbol_mask_full, prach_rx, packet_type;
int prach_rx;
uint16_t packet_type;
uint32_t symbol_number;
uint32_t symbol_mask, symbol_mask_full;
struct timespec time_req, time_rem;
time_req.tv_sec = 0;
time_req.tv_nsec = 300000;
if (subframe==9) { if (subframe==9) {
subframe=0; subframe=0;
frame++; frame++;
frame&=1023; frame&=1023;
} else {
subframe++;
} }
else subframe++;
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_COMMON_RX,1); // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_COMMON_RX,1);
start_meas(&eNB->phy_proc_rx); start_meas(&eNB->phy_proc_rx);
#ifdef DEBUG_PHY_PROC #ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_RX(%d)\n",eNB->Mod_id,frame, subframe); LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_RX(%d)\n",eNB->Mod_id,frame, subframe);
#endif #endif
if (abstraction_flag==0) { // grab signal in chunks of 500 us (1 slot) if (abstraction_flag==0) { // grab signal in chunks of 500 us (1 slot)
if ((eNB->node_function == NGFI_RRU_IF4) ||
if ((eNB->node_function == NGFI_RRU_IF4) || (eNB->node_function == eNodeB_3GPP)) { // acquisition from RF and front-end processing
(eNB->node_function == eNodeB_3GPP)) { // acquisition from RF and front-end processing
for (i=0; i<fp->nb_antennas_rx; i++) for (i=0; i<fp->nb_antennas_rx; i++)
rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti]; rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti];
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 );
rxs = openair0.trx_read_func(&openair0, rxs = eNB->rfdevice.trx_read_func(&eNB->rfdevice,
&proc->timestamp_rx, &proc->timestamp_rx,
rxp, rxp,
fp->samples_per_tti, fp->samples_per_tti,
fp->nb_antennas_rx); fp->nb_antennas_rx);
proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023;
proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10;
if (proc->first_rx == 0) {
AssertFatal(proc->subframe_rx == subframe, "Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)",proc->subframe_rx,subframe); if (proc->first_rx == 0) {
AssertFatal(proc->frame_rx == frame, "Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)",proc->frame_rx,frame); AssertFatal(proc->subframe_rx == subframe, "Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)",proc->subframe_rx,subframe);
} AssertFatal(proc->frame_rx == frame, "Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)",proc->frame_rx,frame);
else } else {
proc->first_rx = 0; proc->first_rx = 0;
}
// printf("timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",proc->timestamp_rx,proc->frame_rx,frame,proc->subframe_rx,subframe);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); //printf("timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",proc->timestamp_rx,proc->frame_rx,frame,proc->subframe_rx,subframe);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB, frame );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX_ENB, subframe );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB, frame );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX_ENB, subframe );
if (rxs != fp->samples_per_tti) if (rxs != fp->samples_per_tti)
exit_fun( "problem receiving samples" ); exit_fun( "problem receiving samples" );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
// now do common RX processing for first slot in subframe // now do common RX processing for first slot in subframe
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_SLOT_FEP,1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_SLOT_FEP,1);
remove_7_5_kHz(eNB,subframe<<1); remove_7_5_kHz(eNB,subframe<<1);
remove_7_5_kHz(eNB,1+(subframe<<1)); remove_7_5_kHz(eNB,1+(subframe<<1));
for (l=0; l<fp->symbols_per_tti/2; l++) { for (l=0; l<fp->symbols_per_tti/2; l++) {
slot_fep_ul(fp, slot_fep_ul(fp,
&eNB->common_vars, &eNB->common_vars,
l, l,
subframe<<1, subframe<<1,
0, 0,
0 0
); );
slot_fep_ul(fp, slot_fep_ul(fp,
&eNB->common_vars, &eNB->common_vars,
l, l,
1+(subframe<<1), 1+(subframe<<1),
0, 0,
0 0
); );
} }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_SLOT_FEP,0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_SLOT_FEP,0);
if (eNB->node_function == NGFI_RRU_IF4) { if (eNB->node_function == NGFI_RRU_IF4 && is_prach_subframe(fp, frame, subframe)<=0) {
//send_IF4(eNB,subframe<<1);
//send_IF4(eNB,(subframe<<1)+1);
}
/// **** send_IF4 of rxdataF to RCC (no prach now) **** ///
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 1 );
// send_IF4();
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 0 );
} }
else if (eNB->node_function == NGFI_RCC_IF4) { // => acquisition from RRU (IF4)
// get frame/subframe information from IF4 interface
// timed loop (200 us)
//symbol_mask = 0;
//symbol_mask_full = (1<<fp->symbols_per_tti)-1;
//if (is_prach_subframe(fp,frame,subframe)>0)
//prach_rx = 0;
//else
//prach_rx = 1;
//do {
//recv_IF4(eNB, proc, &packet_type, &symbol_number);
//if (is_prach_subframe(fp,frame,subframe)>0 && packet_type == PRACH) {
//// wake up prach_rx
//prach_rx = 1;
//}
//if (packet_type == IF4_PULFFT)
//symbol_mask = symbol_mask | (1<<symbol_number);
//} while( (symbol_mask != symbol_mask_full) || (prach_rx == 0));
//recv_IF4(eNB,subframe<<1);
//recv_IF4(eNB,1+(subframe<<1));
// Tobi aka mr monaco: ETH
}
else { // should not get here
AssertFatal(1==0, "Unknown eNB->node_function %d",eNB->node_function);
}
// check if we have to detect PRACH first
if (is_prach_subframe(fp,frame,subframe)>0) {
// wake up thread for PRACH RX
if (pthread_mutex_lock(&proc->mutex_prach) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB PRACH thread %d (IC %d)\n", proc->instance_cnt_prach );
exit_fun( "error locking mutex_prach" );
return;
}
int cnt_prach = ++proc->instance_cnt_prach;
// set timing for prach thread
proc->frame_prach = frame;
proc->subframe_prach = subframe;
pthread_mutex_unlock( &proc->mutex_prach ); /// **** send_IF4 of prach to RCC **** /// done in prach thread (below)
// check if we have to detect PRACH first
if (cnt_prach == 0) { if (is_prach_subframe(fp,frame,subframe)>0) {
// the thread was presumably waiting where it should and can now be woken up // wake up thread for PRACH RX
if (pthread_cond_signal(&proc->cond_prach) != 0) { if (pthread_mutex_lock(&proc->mutex_prach) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB PRACH thread %d\n", proc->thread_index); LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB PRACH thread %d (IC %d)\n", proc->instance_cnt_prach );
exit_fun( "ERROR pthread_cond_signal" ); exit_fun( "error locking mutex_prach" );
return; return;
} }
} else {
LOG_W( PHY,"[eNB] Frame %d, eNB PRACH thread busy!!\n", frame); int cnt_prach = ++proc->instance_cnt_prach;
exit_fun( "PRACH thread busy" ); // set timing for prach thread
return; proc->frame_prach = frame;
proc->subframe_prach = subframe;
pthread_mutex_unlock( &proc->mutex_prach );
if (cnt_prach == 0) {
// the thread was presumably waiting where it should and can now be woken up
if (pthread_cond_signal(&proc->cond_prach) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB PRACH thread %d\n", proc->thread_index);
exit_fun( "ERROR pthread_cond_signal" );
return;
}
} else {
LOG_W( PHY,"[eNB] Frame %d, eNB PRACH thread busy!!\n", frame);
exit_fun( "PRACH thread busy" );
return;
}
} }
} else if (eNB->node_function == NGFI_RCC_IF4) {
/// **** recv_IF4 of rxdataF from RRU **** ///
/// **** recv_IF4 of prachF from RRU **** ///
// get frame/subframe information from IF4 interface
// timed loop (200 us)
symbol_mask = 0;
symbol_mask_full = (1<<fp->symbols_per_tti)-1;
prach_rx = 0;
// Block from loop while testing
symbol_mask = symbol_mask_full;
nanosleep(&time_req, &time_rem);
do {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 1 );
//recv_IF4(eNB, proc, &packet_type, &symbol_number);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 0 );
if (packet_type == IF4_PULFFT) {
symbol_mask = symbol_mask | (1<<symbol_number);
} else if (is_prach_subframe(fp,frame,subframe)>0 && packet_type == PRACH) {
// wake up thread for PRACH RX
prach_rx = 1;
if (pthread_mutex_lock(&proc->mutex_prach) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB PRACH thread %d (IC %d)\n", proc->instance_cnt_prach );
exit_fun( "error locking mutex_prach" );
return;
}
int cnt_prach = ++proc->instance_cnt_prach;
// set timing for prach thread
proc->frame_prach = frame;
proc->subframe_prach = subframe;
pthread_mutex_unlock( &proc->mutex_prach );
if (cnt_prach == 0) {
// the thread was presumably waiting where it should and can now be woken up
if (pthread_cond_signal(&proc->cond_prach) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB PRACH thread %d\n", proc->thread_index);
exit_fun( "ERROR pthread_cond_signal" );
return;
}
} else {
LOG_W( PHY,"[eNB] Frame %d, eNB PRACH thread busy!!\n", frame);
exit_fun( "PRACH thread busy" );
return;
}
}
} while( (symbol_mask != symbol_mask_full) && (prach_rx == 0));
// Tobi aka mr monaco: ETH
} else { // should not get here
AssertFatal(1==0, "Unknown eNB->node_function %d",eNB->node_function);
} }
}
else { // grab transport channel information from network interface } else { // grab transport channel information from network interface
} }
} }
void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const uint8_t abstraction_flag,const relaying_type_t r_type) void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const uint8_t abstraction_flag,const relaying_type_t r_type)
{ {
//RX processing for ue-specific resources (i //RX processing for ue-specific resources (i
......
...@@ -329,7 +329,11 @@ const char* eurecomFunctionsNames[] = { ...@@ -329,7 +329,11 @@ const char* eurecomFunctionsNames[] = {
"itti_dump_enqueue_message", "itti_dump_enqueue_message",
"itti_dump_enqueue_message_malloc", "itti_dump_enqueue_message_malloc",
"itti_relay_thread", "itti_relay_thread",
"test" "test",
/* IF4 signals */
"send_if4",
"recv_if4"
}; };
struct vcd_module_s vcd_modules[VCD_SIGNAL_DUMPER_MODULE_END] = { struct vcd_module_s vcd_modules[VCD_SIGNAL_DUMPER_MODULE_END] = {
......
...@@ -307,6 +307,11 @@ typedef enum { ...@@ -307,6 +307,11 @@ typedef enum {
VCD_SIGNAL_DUMPER_FUNCTIONS_ITTI_DUMP_ENQUEUE_MESSAGE_MALLOC, VCD_SIGNAL_DUMPER_FUNCTIONS_ITTI_DUMP_ENQUEUE_MESSAGE_MALLOC,
VCD_SIGNAL_DUMPER_FUNCTIONS_ITTI_RELAY_THREAD, VCD_SIGNAL_DUMPER_FUNCTIONS_ITTI_RELAY_THREAD,
VCD_SIGNAL_DUMPER_FUNCTIONS_TEST, VCD_SIGNAL_DUMPER_FUNCTIONS_TEST,
/* IF4 signals */
VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4,
VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4,
VCD_SIGNAL_DUMPER_FUNCTIONS_LAST, VCD_SIGNAL_DUMPER_FUNCTIONS_LAST,
VCD_SIGNAL_DUMPER_FUNCTIONS_END = VCD_SIGNAL_DUMPER_FUNCTIONS_LAST, VCD_SIGNAL_DUMPER_FUNCTIONS_END = VCD_SIGNAL_DUMPER_FUNCTIONS_LAST,
} vcd_signal_dump_functions; } vcd_signal_dump_functions;
......
...@@ -68,6 +68,8 @@ ...@@ -68,6 +68,8 @@
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
#include "PHY/LTE_TRANSPORT/if4_tools.h"
#include "PHY/extern.h" #include "PHY/extern.h"
#include "SCHED/extern.h" #include "SCHED/extern.h"
#include "LAYER2/MAC/extern.h" #include "LAYER2/MAC/extern.h"
...@@ -106,10 +108,6 @@ unsigned short config_frames[4] = {2,9,11,13}; ...@@ -106,10 +108,6 @@ unsigned short config_frames[4] = {2,9,11,13};
# endif # endif
#endif #endif
//#define DEBUG_THREADS 1 //#define DEBUG_THREADS 1
//#define USRP_DEBUG 1 //#define USRP_DEBUG 1
...@@ -120,8 +118,8 @@ struct timing_info_t { ...@@ -120,8 +118,8 @@ struct timing_info_t {
unsigned int n_samples; unsigned int n_samples;
} timing_info; } timing_info;
// Fix per CC openair rf/if device update
extern openair0_device openair0; // extern openair0_device openair0;
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
extern volatile int start_eNB; extern volatile int start_eNB;
...@@ -156,15 +154,14 @@ static struct { ...@@ -156,15 +154,14 @@ static struct {
volatile uint8_t phy_proc_CC_id; volatile uint8_t phy_proc_CC_id;
} sync_phy_proc; } sync_phy_proc;
void exit_fun(const char* s); void exit_fun(const char* s);
void init_eNB(eNB_func_t node_function); void init_eNB(eNB_func_t node_function);
void stop_eNB(void); void stop_eNB(void);
void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
{
void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) {
unsigned int aa,slot_offset, slot_offset_F; unsigned int aa,slot_offset, slot_offset_F;
int dummy_tx_b[7680*4] __attribute__((aligned(32))); int dummy_tx_b[7680*4] __attribute__((aligned(32)));
int i,j, tx_offset; int i,j, tx_offset;
...@@ -181,7 +178,6 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) ...@@ -181,7 +178,6 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
((subframe_select(&phy_vars_eNB->frame_parms,subframe)==SF_S))) { ((subframe_select(&phy_vars_eNB->frame_parms,subframe)==SF_S))) {
// LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot); // LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot);
for (aa=0; aa<phy_vars_eNB->frame_parms.nb_antennas_tx; aa++) { for (aa=0; aa<phy_vars_eNB->frame_parms.nb_antennas_tx; aa++) {
if (phy_vars_eNB->frame_parms.Ncp == EXTENDED) { if (phy_vars_eNB->frame_parms.Ncp == EXTENDED) {
PHY_ofdm_mod(&phy_vars_eNB->common_vars.txdataF[0][aa][slot_offset_F], PHY_ofdm_mod(&phy_vars_eNB->common_vars.txdataF[0][aa][slot_offset_F],
...@@ -202,7 +198,7 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) ...@@ -202,7 +198,7 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
7, 7,
&(phy_vars_eNB->frame_parms)); &(phy_vars_eNB->frame_parms));
// if S-subframe generate first slot only // if S-subframe generate first slot only
if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_DL) if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_DL)
normal_prefix_mod(&phy_vars_eNB->common_vars.txdataF[0][aa][slot_offset_F+slot_sizeF], normal_prefix_mod(&phy_vars_eNB->common_vars.txdataF[0][aa][slot_offset_F+slot_sizeF],
dummy_tx_b+(phy_vars_eNB->frame_parms.samples_per_tti>>1), dummy_tx_b+(phy_vars_eNB->frame_parms.samples_per_tti>>1),
7, 7,
...@@ -235,9 +231,8 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) ...@@ -235,9 +231,8 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
txdata[j++] = ((int16_t*)dummy_tx_b)[i]<<openair0_cfg[0].iq_txshift; txdata[j++] = ((int16_t*)dummy_tx_b)[i]<<openair0_cfg[0].iq_txshift;
} }
} }
} }
else if ((slot_offset+time_offset[aa]+len)>(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti)) { else if ((slot_offset+time_offset[aa]+len)>(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti)) {
tx_offset = (int)slot_offset+time_offset[aa]; tx_offset = (int)slot_offset+time_offset[aa];
txdata = (int16_t*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset]; txdata = (int16_t*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset];
len2 = -tx_offset+LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti; len2 = -tx_offset+LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti;
...@@ -258,7 +253,6 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) ...@@ -258,7 +253,6 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
} }
} }
// if S-subframe switch to RX in second subframe // if S-subframe switch to RX in second subframe
/* /*
if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_S) { if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_S) {
...@@ -268,34 +262,35 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) ...@@ -268,34 +262,35 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
} }
*/ */
if ((((phy_vars_eNB->frame_parms.tdd_config==0) || if ((((phy_vars_eNB->frame_parms.tdd_config==0) ||
(phy_vars_eNB->frame_parms.tdd_config==1) || (phy_vars_eNB->frame_parms.tdd_config==1) ||
(phy_vars_eNB->frame_parms.tdd_config==2) || (phy_vars_eNB->frame_parms.tdd_config==2) ||
(phy_vars_eNB->frame_parms.tdd_config==6)) && (phy_vars_eNB->frame_parms.tdd_config==6)) &&
(subframe==0)) || (subframe==5)) { (subframe==0)) || (subframe==5)) {
// turn on tx switch N_TA_offset before // turn on tx switch N_TA_offset before
//LOG_D(HW,"subframe %d, time to switch to tx (N_TA_offset %d, slot_offset %d) \n",subframe,phy_vars_eNB->N_TA_offset,slot_offset); //LOG_D(HW,"subframe %d, time to switch to tx (N_TA_offset %d, slot_offset %d) \n",subframe,phy_vars_eNB->N_TA_offset,slot_offset);
for (i=0; i<phy_vars_eNB->N_TA_offset; i++) { for (i=0; i<phy_vars_eNB->N_TA_offset; i++) {
tx_offset = (int)slot_offset+time_offset[aa]+i-phy_vars_eNB->N_TA_offset/2; tx_offset = (int)slot_offset+time_offset[aa]+i-phy_vars_eNB->N_TA_offset/2;
if (tx_offset<0) if (tx_offset<0)
tx_offset += LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti; tx_offset += LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti;
if (tx_offset>=(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti)) if (tx_offset>=(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti))
tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti; tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti;
phy_vars_eNB->common_vars.txdata[0][aa][tx_offset] = 0x00000000; phy_vars_eNB->common_vars.txdata[0][aa][tx_offset] = 0x00000000;
} }
} }
} }
} }
} }
/*! /*!
* \brief The RX UE-specific and TX thread of eNB. * \brief The RX UE-specific and TX thread of eNB.
* \param param is a \ref eNB_proc_t structure which contains the info what to process. * \param param is a \ref eNB_proc_t structure which contains the info what to process.
* \returns a pointer to an int. The storage is not on the heap and must not be freed. * \returns a pointer to an int. The storage is not on the heap and must not be freed.
*/ */
static void* eNB_thread_rxtx( void* param ) static void* eNB_thread_rxtx( void* param ) {
{
static int eNB_thread_rxtx_status; static int eNB_thread_rxtx_status;
eNB_rxtx_proc_t *proc = (eNB_rxtx_proc_t*)param; eNB_rxtx_proc_t *proc = (eNB_rxtx_proc_t*)param;
...@@ -364,56 +359,47 @@ static void* eNB_thread_rxtx( void* param ) ...@@ -364,56 +359,47 @@ static void* eNB_thread_rxtx( void* param )
#endif //CPU_AFFINITY #endif //CPU_AFFINITY
/* Check the actual affinity mask assigned to the thread */ /* Check the actual affinity mask assigned to the thread */
s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
if (s != 0) if (s != 0) {
{
perror( "pthread_getaffinity_np"); perror( "pthread_getaffinity_np");
exit_fun("Error getting processor affinity "); exit_fun("Error getting processor affinity ");
} }
memset(cpu_affinity,0,sizeof(cpu_affinity)); memset(cpu_affinity,0,sizeof(cpu_affinity));
for (j = 0; j < CPU_SETSIZE; j++) for (j = 0; j < CPU_SETSIZE; j++)
if (CPU_ISSET(j, &cpuset)) if (CPU_ISSET(j, &cpuset)) {
{ char temp[1024];
char temp[1024]; sprintf (temp, " CPU_%d", j);
sprintf (temp, " CPU_%d", j); strcat(cpu_affinity, temp);
strcat(cpu_affinity, temp); }
}
memset(&sparam, 0 , sizeof (sparam)); memset(&sparam, 0, sizeof(sparam));
sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-1;
policy = SCHED_FIFO ; policy = SCHED_FIFO ;
s = pthread_setschedparam(pthread_self(), policy, &sparam); s = pthread_setschedparam(pthread_self(), policy, &sparam);
if (s != 0) if (s != 0) {
{ perror("pthread_setschedparam : ");
perror("pthread_setschedparam : "); exit_fun("Error setting thread priority");
exit_fun("Error setting thread priority"); }
}
s = pthread_getschedparam(pthread_self(), &policy, &sparam); s = pthread_getschedparam(pthread_self(), &policy, &sparam);
if (s != 0) if (s != 0) {
{ perror("pthread_getschedparam : ");
perror("pthread_getschedparam : "); exit_fun("Error getting thread priority");
exit_fun("Error getting thread priority"); }
}
LOG_I( HW, "[SCHED][eNB] TX thread started on CPU %d TID %ld, sched_policy = %s , priority = %d, CPU Affinity=%s \n",sched_getcpu(),gettid(), LOG_I(HW, "[SCHED][eNB] TX thread started on CPU %d TID %ld, sched_policy = %s , priority = %d, CPU Affinity=%s \n",sched_getcpu(),gettid(),
(policy == SCHED_FIFO) ? "SCHED_FIFO" : (policy == SCHED_FIFO) ? "SCHED_FIFO" :
(policy == SCHED_RR) ? "SCHED_RR" : (policy == SCHED_RR) ? "SCHED_RR" :
(policy == SCHED_OTHER) ? "SCHED_OTHER" : (policy == SCHED_OTHER) ? "SCHED_OTHER" :
"???", "???",
sparam.sched_priority, cpu_affinity ); sparam.sched_priority, cpu_affinity );
#endif //LOW_LATENCY #endif //LOW_LATENCY
mlockall(MCL_CURRENT | MCL_FUTURE); mlockall(MCL_CURRENT | MCL_FUTURE);
while (!oai_exit) { while (!oai_exit) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) {
...@@ -461,6 +447,7 @@ static void* eNB_thread_rxtx( void* param ) ...@@ -461,6 +447,7 @@ static void* eNB_thread_rxtx( void* param )
exit_fun("nothing to add"); exit_fun("nothing to add");
break; break;
} }
// wait for our turn or oai_exit // wait for our turn or oai_exit
while (sync_phy_proc.phy_proc_CC_id != proc->CC_id && !oai_exit) { while (sync_phy_proc.phy_proc_CC_id != proc->CC_id && !oai_exit) {
pthread_cond_wait(&sync_phy_proc.cond_phy_proc_tx, pthread_cond_wait(&sync_phy_proc.cond_phy_proc_tx,
...@@ -472,72 +459,86 @@ static void* eNB_thread_rxtx( void* param ) ...@@ -472,72 +459,86 @@ static void* eNB_thread_rxtx( void* param )
exit_fun("nothing to add"); exit_fun("nothing to add");
} }
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_ENB, proc->frame_tx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_ENB, proc->frame_tx );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX_ENB, proc->subframe_tx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX_ENB, proc->subframe_tx );
if (oai_exit)
break; if (oai_exit) break;
if (PHY_vars_eNB_g[0][proc->CC_id]->node_function != NGFI_RRU_IF4) { if (PHY_vars_eNB_g[0][proc->CC_id]->node_function != NGFI_RRU_IF4) {
phy_procedures_eNB_TX(PHY_vars_eNB_g[0][proc->CC_id], proc, 0, no_relay, NULL ); phy_procedures_eNB_TX(PHY_vars_eNB_g[0][proc->CC_id], proc, 0, no_relay, NULL );
/* we're done, let the next one proceed */ /* we're done, let the next one proceed */
if (pthread_mutex_lock(&sync_phy_proc.mutex_phy_proc_tx) != 0) { if (pthread_mutex_lock(&sync_phy_proc.mutex_phy_proc_tx) != 0) {
LOG_E(PHY, "[SCHED][eNB] error locking PHY proc mutex for eNB TX proc\n"); LOG_E(PHY, "[SCHED][eNB] error locking PHY proc mutex for eNB TX proc\n");
exit_fun("nothing to add"); exit_fun("nothing to add");
break; break;
} }
sync_phy_proc.phy_proc_CC_id++; sync_phy_proc.phy_proc_CC_id++;
sync_phy_proc.phy_proc_CC_id %= MAX_NUM_CCs; sync_phy_proc.phy_proc_CC_id %= MAX_NUM_CCs;
pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx); pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx);
if (pthread_mutex_unlock(&sync_phy_proc.mutex_phy_proc_tx) != 0) { if (pthread_mutex_unlock(&sync_phy_proc.mutex_phy_proc_tx) != 0) {
LOG_E(PHY, "[SCHED][eNB] error unlocking PHY proc mutex for eNB TX proc\n"); LOG_E(PHY, "[SCHED][eNB] error unlocking PHY proc mutex for eNB TX proc\n");
exit_fun("nothing to add"); exit_fun("nothing to add");
break; break;
} }
} else {
/// **** recv_IF4 of txdataF from RCC **** ///
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 1 );
//recv_IF4(eNB, proc, packet_type, symbol_number);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 0 );
} }
} }
// eNodeB_3GPP and RRU create txdata and write to RF device
if (PHY_vars_eNB_g[0][proc->CC_id]->node_function != NGFI_RCC_IF4) { if (PHY_vars_eNB_g[0][proc->CC_id]->node_function != NGFI_RCC_IF4) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_SFGEN , 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_SFGEN , 1 );
do_OFDM_mod_rt( proc->subframe_tx, PHY_vars_eNB_g[0][proc->CC_id] ); do_OFDM_mod_rt( proc->subframe_tx, PHY_vars_eNB_g[0][proc->CC_id] );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_SFGEN , 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_SFGEN , 0 );
/*
short *txdata = (short*)&PHY_vars_eNB_g[0][proc->CC_id]->common_vars.txdata[0][0][proc->subframe_tx*PHY_vars_eNB_g[0][proc->CC_id]->frame_parms.samples_per_tti]; /*
int i; short *txdata = (short*)&PHY_vars_eNB_g[0][proc->CC_id]->common_vars.txdata[0][0][proc->subframe_tx*PHY_vars_eNB_g[0][proc->CC_id]->frame_parms.samples_per_tti];
for (i=0;i<PHY_vars_eNB_g[0][proc->CC_id]->frame_parms.samples_per_tti*2;i+=8) { int i;
txdata[i] = 2047; for (i=0;i<PHY_vars_eNB_g[0][proc->CC_id]->frame_parms.samples_per_tti*2;i+=8) {
txdata[i+1] = 0; txdata[i] = 2047;
txdata[i+2] = 0; txdata[i+1] = 0;
txdata[i+3] = 2047; txdata[i+2] = 0;
txdata[i+4] = -2047; txdata[i+3] = 2047;
txdata[i+5] = 0; txdata[i+4] = -2047;
txdata[i+6] = 0; txdata[i+5] = 0;
txdata[i+7] = -2047; } txdata[i+6] = 0;
*/ txdata[i+7] = -2047; }
*/
// Transmit TX buffer based on timestamp from RX // Transmit TX buffer based on timestamp from RX
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
// prepare tx buffer pointers // prepare tx buffer pointers
int i; int i;
for (i=0; i<PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_tx; i++) for (i=0; i<PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_tx; i++)
txp[i] = (void*)&PHY_vars_eNB_g[0][0]->common_vars.txdata[0][i][proc->subframe_tx*PHY_vars_eNB_g[0][0]->frame_parms.samples_per_tti]; txp[i] = (void*)&PHY_vars_eNB_g[0][0]->common_vars.txdata[0][i][proc->subframe_tx*PHY_vars_eNB_g[0][0]->frame_parms.samples_per_tti];
// if symb_written < spp ==> error // if symb_written < spp ==> error
openair0.trx_write_func(&openair0, PHY_vars_eNB_g[0][proc->CC_id]->rfdevice.trx_write_func(&PHY_vars_eNB_g[0][proc->CC_id]->rfdevice,
(proc->timestamp_tx-openair0_cfg[0].tx_sample_advance), (proc->timestamp_tx-openair0_cfg[0].tx_sample_advance),
txp, txp,
PHY_vars_eNB_g[0][0]->frame_parms.samples_per_tti, PHY_vars_eNB_g[0][0]->frame_parms.samples_per_tti,
PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_tx, PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_tx,
1); 1);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_tx-openair0_cfg[0].tx_sample_advance)&0xffffffff ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_tx-openair0_cfg[0].tx_sample_advance)&0xffffffff );
} else {
/// **** send_IF4 of txdataF to RRU **** ///
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 1 );
//send_IF4(PHY_vars_eNB_g[0][proc->CC_id], proc, 0);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 0 );
} }
if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) {
...@@ -555,19 +556,17 @@ static void* eNB_thread_rxtx( void* param ) ...@@ -555,19 +556,17 @@ static void* eNB_thread_rxtx( void* param )
} }
stop_meas( &softmodem_stats_rxtx_sf ); stop_meas( &softmodem_stats_rxtx_sf );
#ifdef DEADLINE_SCHEDULER #ifdef DEADLINE_SCHEDULER
if (opp_enabled){ if (opp_enabled){
if(softmodem_stats_rxtx_sf.diff_now/(cpuf) > attr.sched_runtime){ if(softmodem_stats_rxtx_sf.diff_now/(cpuf) > attr.sched_runtime){
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RUNTIME_TX_ENB, (softmodem_stats_rxtx_sf.diff_now/cpuf - attr.sched_runtime)/1000000.0); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RUNTIME_TX_ENB, (softmodem_stats_rxtx_sf.diff_now/cpuf - attr.sched_runtime)/1000000.0);
}
} }
#endif #endif
print_meas_now(&softmodem_stats_rxtx_sf,"eNB_TX_SF",tx_time_file);
print_meas_now(&softmodem_stats_rxtx_sf,"eNB_TX_SF",tx_time_file);
} }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
...@@ -579,13 +578,11 @@ static void* eNB_thread_rxtx( void* param ) ...@@ -579,13 +578,11 @@ static void* eNB_thread_rxtx( void* param )
} }
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
static void wait_system_ready (char *message, volatile int *start_flag) /* Wait for eNB application initialization to be complete (eNB registration to MME) */
static void wait_system_ready (char *message, volatile int *start_flag) {
/* Wait for eNB application initialization to be complete (eNB registration to MME) */
{
static char *indicator[] = {". ", ".. ", "... ", ".... ", ".....", static char *indicator[] = {". ", ".. ", "... ", ".... ", ".....",
" ....", " ...", " ..", " .", " " " ....", " ...", " ..", " .", " "};
};
int i = 0; int i = 0;
while ((!oai_exit) && (*start_flag == 0)) { while ((!oai_exit) && (*start_flag == 0)) {
...@@ -597,16 +594,16 @@ static void wait_system_ready (char *message, volatile int *start_flag) ...@@ -597,16 +594,16 @@ static void wait_system_ready (char *message, volatile int *start_flag)
LOG_D(EMU,"\n"); LOG_D(EMU,"\n");
} }
#endif #endif
/*! /*!
* \brief The RX common thread of eNB. * \brief The RX common thread of eNB.
* \param param is a \ref eNB_proc_t structure which contains the info what to process. * \param param is a \ref eNB_proc_t structure which contains the info what to process.
* \returns a pointer to an int. The storage is not on the heap and must not be freed. * \returns a pointer to an int. The storage is not on the heap and must not be freed.
*/ */
static void* eNB_thread_rx_common( void* param ) static void* eNB_thread_rx_common( void* param ) {
{
static int eNB_thread_rx_status; static int eNB_thread_rx_status;
eNB_proc_t *proc = (eNB_proc_t*)param; eNB_proc_t *proc = (eNB_proc_t*)param;
...@@ -617,7 +614,7 @@ static void* eNB_thread_rx_common( void* param ) ...@@ -617,7 +614,7 @@ static void* eNB_thread_rx_common( void* param )
char rx_time_name[101]; char rx_time_name[101];
//int i; //int i;
if (opp_enabled == 1){ if (opp_enabled == 1) {
snprintf(rx_time_name, 100,"/tmp/%s_rx_time_thread_sf", "eNB"); snprintf(rx_time_name, 100,"/tmp/%s_rx_time_thread_sf", "eNB");
rx_time_file = fopen(rx_time_name,"w"); rx_time_file = fopen(rx_time_name,"w");
} }
...@@ -662,14 +659,12 @@ static void* eNB_thread_rx_common( void* param ) ...@@ -662,14 +659,12 @@ static void* eNB_thread_rx_common( void* param )
/* Set CPU Affinity only if number of CPUs >2 */ /* Set CPU Affinity only if number of CPUs >2 */
CPU_ZERO(&cpuset); CPU_ZERO(&cpuset);
#ifdef CPU_AFFINITY #ifdef CPU_AFFINITY
if (get_nprocs() >2) if (get_nprocs() >2) {
{
for (j = 1; j < get_nprocs(); j++) for (j = 1; j < get_nprocs(); j++)
CPU_SET(j, &cpuset); CPU_SET(j, &cpuset);
s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
if (s != 0) if (s != 0) {
{
perror( "pthread_setaffinity_np"); perror( "pthread_setaffinity_np");
exit_fun (" Error setting processor affinity :"); exit_fun (" Error setting processor affinity :");
} }
...@@ -678,44 +673,38 @@ static void* eNB_thread_rx_common( void* param ) ...@@ -678,44 +673,38 @@ static void* eNB_thread_rx_common( void* param )
/* Check the actual affinity mask assigned to the thread */ /* Check the actual affinity mask assigned to the thread */
s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
if (s != 0) if (s != 0) {
{ perror ("pthread_getaffinity_np");
perror ("pthread_getaffinity_np"); exit_fun (" Error getting processor affinity :");
exit_fun (" Error getting processor affinity :");
} }
memset(cpu_affinity,0, sizeof(cpu_affinity)); memset(cpu_affinity,0, sizeof(cpu_affinity));
for (j = 0; j < CPU_SETSIZE; j++) for (j = 0; j < CPU_SETSIZE; j++)
if (CPU_ISSET(j, &cpuset)) if (CPU_ISSET(j, &cpuset)) {
{ char temp[1024];
char temp[1024]; sprintf (temp, " CPU_%d", j);
sprintf (temp, " CPU_%d", j); strcat(cpu_affinity, temp);
strcat(cpu_affinity, temp); }
}
memset(&sparam, 0 , sizeof (sparam)); memset(&sparam, 0 , sizeof (sparam));
sparam.sched_priority = sched_get_priority_max(SCHED_FIFO); sparam.sched_priority = sched_get_priority_max(SCHED_FIFO);
policy = SCHED_FIFO ; policy = SCHED_FIFO ;
s = pthread_setschedparam(pthread_self(), policy, &sparam); s = pthread_setschedparam(pthread_self(), policy, &sparam);
if (s != 0) if (s != 0) {
{ perror("pthread_setschedparam : ");
perror("pthread_setschedparam : "); exit_fun("Error setting thread priority");
exit_fun("Error setting thread priority"); }
}
memset(&sparam, 0 , sizeof (sparam)); memset(&sparam, 0 , sizeof (sparam));
s = pthread_getschedparam(pthread_self(), &policy, &sparam); s = pthread_getschedparam(pthread_self(), &policy, &sparam);
if (s != 0) if (s != 0) {
{ perror("pthread_getschedparam");
perror("pthread_getschedparam"); exit_fun("Error getting thread priority");
exit_fun("Error getting thread priority"); }
}
LOG_I( HW, "[SCHED][eNB] RX thread started on CPU %d TID %ld, sched_policy = %s, priority = %d, CPU Affinity = %s\n", sched_getcpu(),gettid(), LOG_I(HW, "[SCHED][eNB] RX thread started on CPU %d TID %ld, sched_policy = %s, priority = %d, CPU Affinity = %s\n", sched_getcpu(),gettid(),
(policy == SCHED_FIFO) ? "SCHED_FIFO" : (policy == SCHED_FIFO) ? "SCHED_FIFO" :
(policy == SCHED_RR) ? "SCHED_RR" : (policy == SCHED_RR) ? "SCHED_RR" :
(policy == SCHED_OTHER) ? "SCHED_OTHER" : (policy == SCHED_OTHER) ? "SCHED_OTHER" :
...@@ -725,115 +714,122 @@ static void* eNB_thread_rx_common( void* param ) ...@@ -725,115 +714,122 @@ static void* eNB_thread_rx_common( void* param )
#endif // DEADLINE_SCHEDULER #endif // DEADLINE_SCHEDULER
mlockall(MCL_CURRENT | MCL_FUTURE);
mlockall(MCL_CURRENT | MCL_FUTURE);
// wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe of TX and RX threads // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe of TX and RX threads
printf( "waiting for sync (eNB_thread_rx_common)\n"); printf( "waiting for sync (eNB_thread_rx_common)\n");
pthread_mutex_lock( &sync_mutex ); pthread_mutex_lock( &sync_mutex );
while (sync_var<0) while (sync_var<0)
pthread_cond_wait( &sync_cond, &sync_mutex ); pthread_cond_wait( &sync_cond, &sync_mutex );
pthread_mutex_unlock(&sync_mutex); pthread_mutex_unlock(&sync_mutex);
printf( "got sync (eNB_thread)\n" ); printf( "got sync (eNB_thread)\n" );
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB); wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB);
#endif #endif
if (openair0.trx_start_func(&openair0) != 0 )
LOG_E(HW,"Could not start the device\n"); // Start RF device for this CC
// This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices if (eNB->node_function != NGFI_RCC_IF4) {
while (!oai_exit) { if (eNB->rfdevice.trx_start_func(&eNB->rfdevice) != 0 )
LOG_E(HW,"Could not start the RF device\n");
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RX, 0 );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON, 0 ); // Start IF device for this CC
start_meas( &softmodem_stats_rx_sf ); if (eNB->node_function != eNodeB_3GPP) {
if (eNB->ifdevice.trx_start_func(&eNB->ifdevice) != 0 )
LOG_E(HW,"Could not start the IF device\n");
}
// This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices
while (!oai_exit) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RX, 0 );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON, 0 );
start_meas( &softmodem_stats_rx_sf );
if (oai_exit) break; if (oai_exit) break;
if ((((fp->frame_type == TDD )&&(subframe_select(fp,proc->subframe_rx)==SF_UL)) || if ((((fp->frame_type == TDD )&&(subframe_select(fp,proc->subframe_rx)==SF_UL)) ||
(fp->frame_type == FDD))) { (fp->frame_type == FDD))) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON, 1 );
// this spawns the prach inside and updates the frame and subframe counters // this spawns the prach inside and updates the frame and subframe counters
phy_procedures_eNB_common_RX(eNB, 0); phy_procedures_eNB_common_RX(eNB, 0);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON, 0 );
}
// choose even or odd thread for RXn-TXnp4 processing
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON, 0 ); eNB_rxtx_proc_t *proc_rxtx = &proc->proc_rxtx[proc->subframe_rx&1];
}
// wake up TX for subframe n+4
// choose even or odd thread for RXn-TXnp4 processing // lock the TX mutex and make sure the thread is ready
eNB_rxtx_proc_t *proc_rxtx = &proc->proc_rxtx[proc->subframe_rx&1]; if (pthread_mutex_lock(&proc_rxtx->mutex_rxtx) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX thread %d (IC %d)\n", proc_rxtx->instance_cnt_rxtx );
// wake up TX for subframe n+4 exit_fun( "error locking mutex_rxtx" );
// lock the TX mutex and make sure the thread is ready break;
if (pthread_mutex_lock(&proc_rxtx->mutex_rxtx) != 0) { }
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX thread %d (IC %d)\n", proc_rxtx->instance_cnt_rxtx ); int cnt_rxtx = ++proc_rxtx->instance_cnt_rxtx;
exit_fun( "error locking mutex_rxtx" ); // We have just received and processed the common part of a subframe, say n.
break; // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
} // transmitted timestamp of the next TX slot (first).
int cnt_rxtx = ++proc_rxtx->instance_cnt_rxtx; // The last (TS_rx mod samples_pexr_frame) was n*samples_per_tti,
// We have just received and processed the common part of a subframe, say n. // we want to generate subframe (n+3), so TS_tx = TX_rx+3*samples_per_tti,
// TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired // and proc->subframe_tx = proc->subframe_rx+3
// transmitted timestamp of the next TX slot (first). proc_rxtx->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti);
// The last (TS_rx mod samples_pexr_frame) was n*samples_per_tti, proc_rxtx->frame_rx = proc->frame_rx;
// we want to generate subframe (n+3), so TS_tx = TX_rx+3*samples_per_tti, proc_rxtx->subframe_rx = proc->subframe_rx;
// and proc->subframe_tx = proc->subframe_rx+3 proc_rxtx->frame_tx = (proc_rxtx->subframe_rx > 5) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx;
proc_rxtx->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti); proc_rxtx->subframe_tx = (proc_rxtx->subframe_rx + 4)%10;
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;
pthread_mutex_unlock( &proc_rxtx->mutex_rxtx ); pthread_mutex_unlock( &proc_rxtx->mutex_rxtx );
if (cnt_rxtx == 0){ if (cnt_rxtx == 0) {
// the thread was presumably waiting where it should and can now be woken up // the thread was presumably waiting where it should and can now be woken up
if (pthread_cond_signal(&proc_rxtx->cond_rxtx) != 0) { if (pthread_cond_signal(&proc_rxtx->cond_rxtx) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n"); LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n");
exit_fun( "ERROR pthread_cond_signal" ); exit_fun( "ERROR pthread_cond_signal" );
break; break;
} }
} else { } else {
LOG_W( PHY,"[eNB] Frame %d, eNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", proc_rxtx->frame_tx, cnt_rxtx ); LOG_W( PHY,"[eNB] Frame %d, eNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", proc_rxtx->frame_tx, cnt_rxtx );
exit_fun( "TX thread busy" ); exit_fun( "TX thread busy" );
break; break;
} }
stop_meas( &softmodem_stats_rxtx_sf );
stop_meas( &softmodem_stats_rxtx_sf );
#ifdef DEADLINE_SCHEDULER #ifdef DEADLINE_SCHEDULER
if (opp_enabled){ if (opp_enabled){
if(softmodem_stats_rxtx_sf.diff_now/(cpuf) > attr.sched_runtime){ if(softmodem_stats_rxtx_sf.diff_now/(cpuf) > attr.sched_runtime){
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RUNTIME_RXTX_ENB, (softmodem_stats_rxtx_sf.diff_now/cpuf - attr.sched_runtime)/1000000.0); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RUNTIME_RXTX_ENB, (softmodem_stats_rxtx_sf.diff_now/cpuf - attr.sched_runtime)/1000000.0);
} }
} }
#endif // DEADLINE_SCHEDULER #endif // DEADLINE_SCHEDULER
print_meas_now(&softmodem_stats_rx_sf,"eNB_RX_SF", rx_time_file); print_meas_now(&softmodem_stats_rx_sf,"eNB_RX_SF", rx_time_file);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
print_meas_now(&softmodem_stats_rx_sf,"eNB_RX_SF", rx_time_file);
} VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
}
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
printf( "Exiting eNB thread RXn-TXnp4\n"); printf( "Exiting eNB thread RXn-TXnp4\n");
#endif #endif
eNB_thread_rx_status = 0; eNB_thread_rx_status = 0;
return &eNB_thread_rx_status; return &eNB_thread_rx_status;
} }
/*! /*!
* \brief The prach receive thread of eNB. * \brief The prach receive thread of eNB.
* \param param is a \ref eNB_proc_t structure which contains the info what to process. * \param param is a \ref eNB_proc_t structure which contains the info what to process.
* \returns a pointer to an int. The storage is not on the heap and must not be freed. * \returns a pointer to an int. The storage is not on the heap and must not be freed.
*/ */
static void* eNB_thread_prach( void* param ) static void* eNB_thread_prach( void* param ) {
{
static int eNB_thread_prach_status; static int eNB_thread_prach_status;
eNB_proc_t *proc = (eNB_proc_t*)param; eNB_proc_t *proc = (eNB_proc_t*)param;
...@@ -842,7 +838,6 @@ static void* eNB_thread_prach( void* param ) ...@@ -842,7 +838,6 @@ static void* eNB_thread_prach( void* param )
eNB_thread_prach_status = 0; eNB_thread_prach_status = 0;
MSC_START_USE(); MSC_START_USE();
#ifdef DEADLINE_SCHEDULER #ifdef DEADLINE_SCHEDULER
struct sched_attr attr; struct sched_attr attr;
...@@ -880,113 +875,102 @@ static void* eNB_thread_prach( void* param ) ...@@ -880,113 +875,102 @@ static void* eNB_thread_prach( void* param )
/* Set CPU Affinity only if number of CPUs >2 */ /* Set CPU Affinity only if number of CPUs >2 */
CPU_ZERO(&cpuset); CPU_ZERO(&cpuset);
#ifdef CPU_AFFINITY #ifdef CPU_AFFINITY
if (get_nprocs() >2) if (get_nprocs() >2) {
{
for (j = 1; j < get_nprocs(); j++) for (j = 1; j < get_nprocs(); j++)
CPU_SET(j, &cpuset); CPU_SET(j, &cpuset);
s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
if (s != 0) if (s != 0) {
{
perror( "pthread_setaffinity_np"); perror( "pthread_setaffinity_np");
exit_fun (" Error setting processor affinity :"); exit_fun (" Error setting processor affinity :");
} }
} }
#endif //CPU_AFFINITY #endif //CPU_AFFINITY
/* Check the actual affinity mask assigned to the thread */
/* Check the actual affinity mask assigned to the thread */
s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
if (s != 0) if (s != 0) {
{ perror ("pthread_getaffinity_np");
perror ("pthread_getaffinity_np"); exit_fun (" Error getting processor affinity :");
exit_fun (" Error getting processor affinity :");
} }
memset(cpu_affinity,0, sizeof(cpu_affinity)); memset(cpu_affinity,0, sizeof(cpu_affinity));
for (j = 0; j < CPU_SETSIZE; j++) for (j = 0; j < CPU_SETSIZE; j++)
if (CPU_ISSET(j, &cpuset)) if (CPU_ISSET(j, &cpuset)) {
{ char temp[1024];
char temp[1024]; sprintf (temp, " CPU_%d", j);
sprintf (temp, " CPU_%d", j); strcat(cpu_affinity, temp);
strcat(cpu_affinity, temp); }
}
memset(&sparam, 0 , sizeof (sparam)); memset(&sparam, 0 , sizeof (sparam));
sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-2; sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-2;
policy = SCHED_FIFO ; policy = SCHED_FIFO ;
s = pthread_setschedparam(pthread_self(), policy, &sparam); s = pthread_setschedparam(pthread_self(), policy, &sparam);
if (s != 0) if (s != 0) {
{ perror("pthread_setschedparam : ");
perror("pthread_setschedparam : "); exit_fun("Error setting thread priority");
exit_fun("Error setting thread priority"); }
}
memset(&sparam, 0 , sizeof (sparam)); memset(&sparam, 0 , sizeof (sparam));
s = pthread_getschedparam(pthread_self(), &policy, &sparam); s = pthread_getschedparam(pthread_self(), &policy, &sparam);
if (s != 0) if (s != 0) {
{ perror("pthread_getschedparam");
perror("pthread_getschedparam"); exit_fun("Error getting thread priority");
exit_fun("Error getting thread priority"); }
}
LOG_I( HW, "[SCHED][eNB] PRACH thread started on CPU %d TID %ld, sched_policy = %s, priority = %d, CPU Affinity = %s\n", sched_getcpu(),gettid(), LOG_I(HW, "[SCHED][eNB] PRACH thread started on CPU %d TID %ld, sched_policy = %s, priority = %d, CPU Affinity = %s\n", sched_getcpu(),gettid(),
(policy == SCHED_FIFO) ? "SCHED_FIFO" : (policy == SCHED_FIFO) ? "SCHED_FIFO" :
(policy == SCHED_RR) ? "SCHED_RR" : (policy == SCHED_RR) ? "SCHED_RR" :
(policy == SCHED_OTHER) ? "SCHED_OTHER" : (policy == SCHED_OTHER) ? "SCHED_OTHER" :
"???", "???",
sparam.sched_priority, cpu_affinity); sparam.sched_priority, cpu_affinity);
#endif // DEADLINE_SCHEDULER #endif // DEADLINE_SCHEDULER
mlockall(MCL_CURRENT | MCL_FUTURE); mlockall(MCL_CURRENT | MCL_FUTURE);
while (!oai_exit) { while (!oai_exit) {
if (oai_exit) break;
if (oai_exit) break;
if (pthread_mutex_lock(&proc->mutex_prach) != 0) { if (pthread_mutex_lock(&proc->mutex_prach) != 0) {
LOG_E( PHY, "[SCHED][eNB] error locking mutex for eNB PRACH\n"); LOG_E( PHY, "[SCHED][eNB] error locking mutex for eNB PRACH\n");
exit_fun( "error locking mutex" ); exit_fun( "error locking mutex" );
break; break;
} }
while (proc->instance_cnt_prach < 0) { while (proc->instance_cnt_prach < 0) {
// most of the time the thread is waiting here // most of the time the thread is waiting here
// proc->instance_cnt_prach is -1 // proc->instance_cnt_prach is -1
pthread_cond_wait( &proc->cond_prach, &proc->mutex_prach ); // this unlocks mutex_rxtx while waiting and then locks it again pthread_cond_wait( &proc->cond_prach, &proc->mutex_prach ); // this unlocks mutex_rxtx while waiting and then locks it again
} }
if (pthread_mutex_unlock(&proc->mutex_prach) != 0) { if (pthread_mutex_unlock(&proc->mutex_prach) != 0) {
LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for eNB PRACH\n"); LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for eNB PRACH\n");
exit_fun( "error unlocking mutex" ); exit_fun( "error unlocking mutex" );
break; break;
} }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,1);
prach_procedures(eNB,0); prach_procedures(eNB,0);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0);
if (pthread_mutex_lock(&proc->mutex_prach) != 0) { if (pthread_mutex_lock(&proc->mutex_prach) != 0) {
LOG_E( PHY, "[SCHED][eNB] error locking mutex for eNB PRACH proc %d\n"); LOG_E( PHY, "[SCHED][eNB] error locking mutex for eNB PRACH proc %d\n");
exit_fun( "error locking mutex" ); exit_fun( "error locking mutex" );
break; break;
} }
proc->instance_cnt_prach--;
if (pthread_mutex_unlock(&proc->mutex_prach) != 0) { proc->instance_cnt_prach--;
LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for eNB RX proc %d\n");
exit_fun( "error unlocking mutex" ); if (pthread_mutex_unlock(&proc->mutex_prach) != 0) {
break; LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for eNB RX proc %d\n");
} exit_fun( "error unlocking mutex" );
} break;
}
}
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
printf( "Exiting eNB thread PRACH\n"); printf( "Exiting eNB thread PRACH\n");
...@@ -997,10 +981,8 @@ static void* eNB_thread_prach( void* param ) ...@@ -997,10 +981,8 @@ static void* eNB_thread_prach( void* param )
} }
void init_eNB_proc(void) {
void init_eNB_proc(void)
{
int i; int i;
int CC_id; int CC_id;
PHY_VARS_eNB *eNB; PHY_VARS_eNB *eNB;
...@@ -1010,7 +992,6 @@ void init_eNB_proc(void) ...@@ -1010,7 +992,6 @@ void init_eNB_proc(void)
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
eNB = PHY_vars_eNB_g[0][CC_id]; eNB = PHY_vars_eNB_g[0][CC_id];
proc = &eNB->proc; proc = &eNB->proc;
proc_rxtx = proc->proc_rxtx; proc_rxtx = proc->proc_rxtx;
#ifndef DEADLINE_SCHEDULER #ifndef DEADLINE_SCHEDULER
...@@ -1074,7 +1055,6 @@ void init_eNB_proc(void) ...@@ -1074,7 +1055,6 @@ void init_eNB_proc(void)
pthread_setname_np( proc->pthread_rx, name ); pthread_setname_np( proc->pthread_rx, name );
} }
/* setup PHY proc TX sync mechanism */ /* setup PHY proc TX sync mechanism */
pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL); pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL);
pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL); pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL);
...@@ -1085,8 +1065,8 @@ void init_eNB_proc(void) ...@@ -1085,8 +1065,8 @@ void init_eNB_proc(void)
/*! /*!
* \brief Terminate eNB TX and RX threads. * \brief Terminate eNB TX and RX threads.
*/ */
void kill_eNB_proc(void) void kill_eNB_proc(void) {
{
int *status; int *status;
PHY_VARS_eNB *eNB; PHY_VARS_eNB *eNB;
eNB_proc_t *proc; eNB_proc_t *proc;
...@@ -1110,6 +1090,7 @@ void kill_eNB_proc(void) ...@@ -1110,6 +1090,7 @@ void kill_eNB_proc(void)
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
printf( "Joining eNB TX CC_id %d thread\n", CC_id); printf( "Joining eNB TX CC_id %d thread\n", CC_id);
#endif #endif
int result,i; int result,i;
for (i=0;i<1;i++) { for (i=0;i<1;i++) {
pthread_join( proc_rxtx[i].pthread_rxtx, (void**)&status ); pthread_join( proc_rxtx[i].pthread_rxtx, (void**)&status );
...@@ -1125,16 +1106,14 @@ void kill_eNB_proc(void) ...@@ -1125,16 +1106,14 @@ void kill_eNB_proc(void)
printf( "The thread was killed. No status available.\n" ); printf( "The thread was killed. No status available.\n" );
} }
} }
#else #else
UNUSED(result); UNUSED(result);
#endif #endif
pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx ); pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx );
pthread_cond_destroy( &proc_rxtx[i].cond_rxtx ); pthread_cond_destroy( &proc_rxtx[i].cond_rxtx );
} }
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
printf( "Killing RX CC_id %d thread\n", CC_id); printf( "Killing RX CC_id %d thread\n", CC_id);
#endif #endif
...@@ -1142,10 +1121,10 @@ void kill_eNB_proc(void) ...@@ -1142,10 +1121,10 @@ void kill_eNB_proc(void)
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
printf( "Joining eNB RX CC_id %d thread ...\n", CC_id); printf( "Joining eNB RX CC_id %d thread ...\n", CC_id);
#endif #endif
result = pthread_join( proc->pthread_rx, (void**)&status ); result = pthread_join( proc->pthread_rx, (void**)&status );
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
if (result != 0) { if (result != 0) {
printf( "Error joining thread.\n" ); printf( "Error joining thread.\n" );
} else { } else {
...@@ -1154,8 +1133,7 @@ void kill_eNB_proc(void) ...@@ -1154,8 +1133,7 @@ void kill_eNB_proc(void)
} else { } else {
printf( "The thread was killed. No status available.\n" ); printf( "The thread was killed. No status available.\n" );
} }
} }
#else #else
UNUSED(result); UNUSED(result);
#endif #endif
...@@ -1170,8 +1148,7 @@ void kill_eNB_proc(void) ...@@ -1170,8 +1148,7 @@ void kill_eNB_proc(void)
Each rf chain is is addressed by the card number and the chain on the card. The Each rf chain is is addressed by the card number and the chain on the card. The
rf_map specifies for each CC, on which rf chain the mapping should start. Multiple rf_map specifies for each CC, on which rf chain the mapping should start. Multiple
antennas are mapped to successive RF chains on the same card. */ antennas are mapped to successive RF chains on the same card. */
int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]) int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]) {
{
int i, CC_id; int i, CC_id;
...@@ -1179,7 +1156,6 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c ...@@ -1179,7 +1156,6 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
LTE_DL_FRAME_PARMS *frame_parms; LTE_DL_FRAME_PARMS *frame_parms;
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
if (phy_vars_eNB[CC_id]) { if (phy_vars_eNB[CC_id]) {
frame_parms = &(phy_vars_eNB[CC_id]->frame_parms); frame_parms = &(phy_vars_eNB[CC_id]->frame_parms);
...@@ -1198,8 +1174,6 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c ...@@ -1198,8 +1174,6 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
N_TA_offset = 624/4; N_TA_offset = 624/4;
} }
/* /*
// replace RX signal buffers with mmaped HW versions // replace RX signal buffers with mmaped HW versions
#ifdef EXMIMO #ifdef EXMIMO
...@@ -1261,8 +1235,7 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c ...@@ -1261,8 +1235,7 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
rxdata[i] = (int32_t*)(32 + malloc16(32+openair0_cfg[rf_map[CC_id].card].samples_per_frame*sizeof(int32_t))); // FIXME broken memory allocation rxdata[i] = (int32_t*)(32 + malloc16(32+openair0_cfg[rf_map[CC_id].card].samples_per_frame*sizeof(int32_t))); // FIXME broken memory allocation
phy_vars_eNB[CC_id]->common_vars.rxdata[0][i] = rxdata[i]-N_TA_offset; // N_TA offset for TDD FIXME! N_TA_offset > 16 => access of unallocated memory phy_vars_eNB[CC_id]->common_vars.rxdata[0][i] = rxdata[i]-N_TA_offset; // N_TA offset for TDD FIXME! N_TA_offset > 16 => access of unallocated memory
memset(rxdata[i], 0, openair0_cfg[rf_map[CC_id].card].samples_per_frame*sizeof(int32_t)); memset(rxdata[i], 0, openair0_cfg[rf_map[CC_id].card].samples_per_frame*sizeof(int32_t));
printf("rxdata[%d] @ %p (%p) (N_TA_OFFSET %d)\n", i, phy_vars_eNB[CC_id]->common_vars.rxdata[0][i],rxdata[i],N_TA_offset); printf("rxdata[%d] @ %p (%p) (N_TA_OFFSET %d)\n", i, phy_vars_eNB[CC_id]->common_vars.rxdata[0][i],rxdata[i],N_TA_offset);
} }
for (i=0; i<frame_parms->nb_antennas_tx; i++) { for (i=0; i<frame_parms->nb_antennas_tx; i++) {
...@@ -1271,7 +1244,6 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c ...@@ -1271,7 +1244,6 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
phy_vars_eNB[CC_id]->common_vars.txdata[0][i] = txdata[i]; phy_vars_eNB[CC_id]->common_vars.txdata[0][i] = txdata[i];
memset(txdata[i],0, openair0_cfg[rf_map[CC_id].card].samples_per_frame*sizeof(int32_t)); memset(txdata[i],0, openair0_cfg[rf_map[CC_id].card].samples_per_frame*sizeof(int32_t));
printf("txdata[%d] @ %p\n", i, phy_vars_eNB[CC_id]->common_vars.txdata[0][i]); printf("txdata[%d] @ %p\n", i, phy_vars_eNB[CC_id]->common_vars.txdata[0][i]);
} }
...@@ -1281,9 +1253,8 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c ...@@ -1281,9 +1253,8 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
} }
void reset_opp_meas(void) { void reset_opp_meas(void) {
int sfn; int sfn;
reset_meas(&softmodem_stats_mt); reset_meas(&softmodem_stats_mt);
reset_meas(&softmodem_stats_hw); reset_meas(&softmodem_stats_hw);
...@@ -1294,6 +1265,7 @@ void reset_opp_meas(void) { ...@@ -1294,6 +1265,7 @@ void reset_opp_meas(void) {
} }
} }
void print_opp_meas(void) { void print_opp_meas(void) {
int sfn=0; int sfn=0;
...@@ -1309,7 +1281,6 @@ void print_opp_meas(void) { ...@@ -1309,7 +1281,6 @@ void print_opp_meas(void) {
void init_eNB(eNB_func_t node_function) { void init_eNB(eNB_func_t node_function) {
int CC_id; int CC_id;
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++)
...@@ -1339,11 +1310,11 @@ void stop_eNB() { ...@@ -1339,11 +1310,11 @@ void stop_eNB() {
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
printf("Joining eNB_thread ..."); printf("Joining eNB_thread ...");
#endif #endif
int *eNB_thread_status_p;
int result = pthread_join( main_eNB_thread, (void**)&eNB_thread_status_p ); int *eNB_thread_status_p;
int result = pthread_join( main_eNB_thread, (void**)&eNB_thread_status_p );
#ifdef DEBUG_THREADS #ifdef DEBUG_THREADS
if (result != 0) { if (result != 0) {
printf( "\nError joining main_eNB_thread.\n" ); printf( "\nError joining main_eNB_thread.\n" );
} else { } else {
...@@ -1353,7 +1324,6 @@ void stop_eNB() { ...@@ -1353,7 +1324,6 @@ void stop_eNB() {
printf( "The thread was killed. No status available.\n"); printf( "The thread was killed. No status available.\n");
} }
} }
#else #else
UNUSED(result); UNUSED(result);
#endif // DEBUG_THREADS #endif // DEBUG_THREADS
......
...@@ -151,8 +151,6 @@ int sync_var=-1; //!< protected by mutex \ref sync_mutex. ...@@ -151,8 +151,6 @@ int sync_var=-1; //!< protected by mutex \ref sync_mutex.
static pthread_t forms_thread; //xforms static pthread_t forms_thread; //xforms
#endif #endif
openair0_device openair0;
uint16_t runtime_phy_rx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100] 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] uint16_t runtime_phy_tx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100]
...@@ -281,6 +279,9 @@ eth_params_t *eth_params; ...@@ -281,6 +279,9 @@ eth_params_t *eth_params;
openair0_config_t openair0_cfg[MAX_CARDS]; openair0_config_t openair0_cfg[MAX_CARDS];
// Change to openair_global to handle UE
openair0_device openair0;
double cpuf; double cpuf;
char uecap_xer[1024],uecap_xer_in=0; char uecap_xer[1024],uecap_xer_in=0;
...@@ -1574,14 +1575,26 @@ int main( int argc, char **argv ) ...@@ -1574,14 +1575,26 @@ int main( int argc, char **argv )
} }
LOG_I(HW, "CPU Affinity of main() function is... %s\n", cpu_affinity); LOG_I(HW, "CPU Affinity of main() function is... %s\n", cpu_affinity);
#endif #endif
openair0_cfg[0].log_level = glog_level;
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
PHY_vars_eNB_g[0][CC_id]->rfdevice.host_type = BBU_HOST;
PHY_vars_eNB_g[0][CC_id]->rfdevice.type = NONE_DEV;
PHY_vars_eNB_g[0][CC_id]->rfdevice.transp_type = NONE_TP;
PHY_vars_eNB_g[0][CC_id]->ifdevice.host_type = BBU_HOST;
PHY_vars_eNB_g[0][CC_id]->ifdevice.type = NONE_DEV;
PHY_vars_eNB_g[0][CC_id]->ifdevice.transp_type = NONE_TP;
}
/* device host type is set*/ /* device host type is set*/
openair0.host_type = BBU_HOST; openair0.host_type = BBU_HOST;
/* device type is initialized NONE_DEV (no RF device) when the RF device will be initiated device type will be set */ /* device type is initialized NONE_DEV (no RF device) when the RF device will be initiated device type will be set */
openair0.type = NONE_DEV; openair0.type = NONE_DEV;
/* transport type is initialized NONE_TP (no transport protocol) when the transport protocol will be initiated transport protocol type will be set */ /* transport type is initialized NONE_TP (no transport protocol) when the transport protocol will be initiated transport protocol type will be set */
openair0.transp_type = NONE_TP; openair0.transp_type = NONE_TP;
openair0_cfg[0].log_level = glog_level; //openair0_cfg[0].log_level = glog_level;
// Legacy BBU - RRH init // Legacy BBU - RRH init
//int returns=-1; //int returns=-1;
...@@ -1613,36 +1626,41 @@ int main( int argc, char **argv ) ...@@ -1613,36 +1626,41 @@ int main( int argc, char **argv )
//printf("Done\n"); //printf("Done\n");
int returns=-1; int returns=-1;
// Handle spatially distributed MIMO antenna ports
// Load RF device and initialize // Load RF device and initialize
if (node_function == eNodeB_3GPP || node_function == NGFI_RRU_IF4) { if (node_function != NGFI_RCC_IF4) {
if (mode!=loop_through_memory) { for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
returns=openair0_device_load(&openair0, &openair0_cfg[0]); if (mode!=loop_through_memory) {
printf("openair0_device_init returns %d\n",returns); returns=openair0_device_load(&(PHY_vars_eNB_g[0][CC_id]->rfdevice), &openair0_cfg[0]);
if (returns<0) { printf("openair0_device_init returns %d for CC_id %d\n",returns,CC_id);
printf("Exiting, cannot initialize device\n"); if (returns<0) {
exit(-1); printf("Exiting, cannot initialize device\n");
exit(-1);
}
} }
} else if (mode==loop_through_memory) {
else if (mode==loop_through_memory) { }
} }
} }
// Load transport protocol and initialize // Load transport protocol and initialize
if (node_function == NGFI_RCC_IF4 || node_function == NGFI_RRU_IF4){ if (node_function != eNodeB_3GPP){
if (mode!=loop_through_memory) { for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
returns=openair0_transport_load(&openair0, &openair0_cfg[0], eth_params); if (mode!=loop_through_memory) {
printf("openair0_transport_init returns %d\n",returns); returns=openair0_transport_load(&(PHY_vars_eNB_g[0][CC_id]->ifdevice), &openair0_cfg[0], (eth_params+CC_id));
if (returns<0) { printf("openair0_transport_init returns %d for CC_id %d\n",returns,CC_id);
printf("Exiting, cannot initialize transport protocol\n"); if (returns<0) {
exit(-1); printf("Exiting, cannot initialize transport protocol\n");
exit(-1);
}
} }
else if (mode==loop_through_memory) {
}
} }
else if (mode==loop_through_memory) { }
}
}
printf("Done\n"); printf("Done initializing RF and IF devices\n");
mac_xface = malloc(sizeof(MAC_xface)); mac_xface = malloc(sizeof(MAC_xface));
...@@ -1812,7 +1830,7 @@ int main( int argc, char **argv ) ...@@ -1812,7 +1830,7 @@ int main( int argc, char **argv )
// *** Handle per CC_id openair0
#ifndef USRP_DEBUG #ifndef USRP_DEBUG
if ((UE_flag==1) && (mode!=loop_through_memory)) if ((UE_flag==1) && (mode!=loop_through_memory))
if (openair0.trx_start_func(&openair0) != 0 ) if (openair0.trx_start_func(&openair0) != 0 )
...@@ -1882,7 +1900,7 @@ int main( int argc, char **argv ) ...@@ -1882,7 +1900,7 @@ int main( int argc, char **argv )
pthread_cond_destroy(&sync_cond); pthread_cond_destroy(&sync_cond);
pthread_mutex_destroy(&sync_mutex); pthread_mutex_destroy(&sync_mutex);
// *** Handle per CC_id openair0
openair0.trx_end_func(&openair0); openair0.trx_end_func(&openair0);
if (ouput_vcd) if (ouput_vcd)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment