Commit 2c230f83 authored by rdoost's avatar rdoost

working tdd/fdd at 5 and 10 Mhz

parent 36d3e624
...@@ -2017,7 +2017,7 @@ void prach_procedures(PHY_VARS_eNB *eNB) { ...@@ -2017,7 +2017,7 @@ void prach_procedures(PHY_VARS_eNB *eNB) {
eNB->UE_stats[(uint32_t)UE_id].UE_timing_offset = preamble_delay_list[preamble_max]&0x1FFF; //limit to 13 (=11+2) bits eNB->UE_stats[(uint32_t)UE_id].UE_timing_offset = preamble_delay_list[preamble_max]&0x1FFF; //limit to 13 (=11+2) bits
eNB->UE_stats[(uint32_t)UE_id].sector = 0; eNB->UE_stats[(uint32_t)UE_id].sector = 0;
LOG_I(PHY,"[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure (UE_id %d) with preamble %d, energy %d.%d dB, delay %d\n", LOG_D(PHY,"[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure (UE_id %d) with preamble %d, energy %d.%d dB, delay %d\n",
eNB->Mod_id, eNB->Mod_id,
eNB->CC_id, eNB->CC_id,
frame, frame,
...@@ -3042,7 +3042,7 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const ...@@ -3042,7 +3042,7 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
#endif #endif
stop_meas(&eNB->ulsch_decoding_stats); stop_meas(&eNB->ulsch_decoding_stats);
LOG_G(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n", LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n",
eNB->Mod_id,harq_pid, eNB->Mod_id,harq_pid,
frame,subframe, frame,subframe,
eNB->ulsch[i]->rnti, eNB->ulsch[i]->rnti,
......
...@@ -125,7 +125,7 @@ skb_p->mark = rb_idP; ...@@ -125,7 +125,7 @@ skb_p->mark = rb_idP;
skb_p->ip_summed = CHECKSUM_UNNECESSARY; skb_p->ip_summed = CHECKSUM_UNNECESSARY;
ipv_p = (struct ipversion*)((void*)&(skb_p->data[hard_header_len])); ipv_p = (ipversion_t *)((void*)&(skb_p->data[hard_header_len]));
switch (ipv_p->version) { switch (ipv_p->version) {
......
...@@ -243,7 +243,12 @@ int ue_ip_hard_start_xmit(struct sk_buff *skb_pP, struct net_device *dev_pP) ...@@ -243,7 +243,12 @@ int ue_ip_hard_start_xmit(struct sk_buff *skb_pP, struct net_device *dev_pP)
// End debug information // End debug information
netif_stop_queue(dev_pP); netif_stop_queue(dev_pP);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
netif_trans_update(dev_pP);
#else
dev_pP->trans_start = jiffies; dev_pP->trans_start = jiffies;
#endif
#ifdef OAI_DRV_DEBUG_DEVICE #ifdef OAI_DRV_DEBUG_DEVICE
printk("[UE_IP_DRV][%s] step 1\n", __FUNCTION__); printk("[UE_IP_DRV][%s] step 1\n", __FUNCTION__);
#endif #endif
...@@ -315,7 +320,11 @@ void ue_ip_tx_timeout(struct net_device *dev_pP) ...@@ -315,7 +320,11 @@ void ue_ip_tx_timeout(struct net_device *dev_pP)
printk("[UE_IP_DRV][%s] begin\n", __FUNCTION__); printk("[UE_IP_DRV][%s] begin\n", __FUNCTION__);
// (ue_ip_priv_t *)(dev_pP->priv_p)->stats.tx_errors++; // (ue_ip_priv_t *)(dev_pP->priv_p)->stats.tx_errors++;
(priv_p->stats).tx_errors++; (priv_p->stats).tx_errors++;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
netif_trans_update(dev_pP);
#else
dev_pP->trans_start = jiffies; dev_pP->trans_start = jiffies;
#endif
netif_wake_queue(dev_pP); netif_wake_queue(dev_pP);
printk("[UE_IP_DRV][%s] transmit timed out %s\n", __FUNCTION__,dev_pP->name); printk("[UE_IP_DRV][%s] transmit timed out %s\n", __FUNCTION__,dev_pP->name);
} }
......
...@@ -20,26 +20,26 @@ ...@@ -20,26 +20,26 @@
#include <limits> #include <limits>
#include "UTIL/LOG/log_extern.h" #include "UTIL/LOG/log_extern.h"
#include "common_lib.h" #include "common_lib.h"
#include <chrono>
#define SAMPLE_RATE_DOWN 1 #define SAMPLE_RATE_DOWN 1
/*! \brief Iris Configuration */ /*! \brief Iris Configuration */
typedef struct typedef struct {
{
// -------------------------------- // --------------------------------
// variables for Iris configuration // variables for Iris configuration
// -------------------------------- // --------------------------------
//! Iris device pointer //! Iris device pointer
std::vector<SoapySDR::Device*> iris; std::vector<SoapySDR::Device *> iris;
int device_num; int device_num;
int rx_num_channels; int rx_num_channels;
int tx_num_channels; int tx_num_channels;
//create a send streamer and a receive streamer //create a send streamer and a receive streamer
//! Iris TX Stream //! Iris TX Stream
std::vector<SoapySDR::Stream*> txStream; std::vector<SoapySDR::Stream *> txStream;
//! Iris RX Stream //! Iris RX Stream
std::vector<SoapySDR::Stream*> rxStream; std::vector<SoapySDR::Stream *> rxStream;
//! Sampling rate //! Sampling rate
double sample_rate; double sample_rate;
...@@ -73,20 +73,18 @@ typedef struct ...@@ -73,20 +73,18 @@ typedef struct
/*! \brief Called to start the Iris lime transceiver. Return 0 if OK, < 0 if error /*! \brief Called to start the Iris lime transceiver. Return 0 if OK, < 0 if error
@param device pointer to the device structure specific to the RF hardware target @param device pointer to the device structure specific to the RF hardware target
*/ */
static int trx_iris_start(openair0_device *device) static int trx_iris_start(openair0_device *device) {
{ iris_state_t *s = (iris_state_t *) device->priv;
iris_state_t *s = (iris_state_t*)device->priv;
long long timeNs = s->iris[0]->getHardwareTime("") + 500000; long long timeNs = s->iris[0]->getHardwareTime("") + 500000;
int flags = 0; int flags = 0;
//flags |= SOAPY_SDR_HAS_TIME; //flags |= SOAPY_SDR_HAS_TIME;
int r; int r;
for (r = 0; r < s->device_num; r++) for (r = 0; r < s->device_num; r++) {
{
int ret = s->iris[r]->activateStream(s->rxStream[r], flags, timeNs, 0); int ret = s->iris[r]->activateStream(s->rxStream[r], flags, timeNs, 0);
int ret2 = s->iris[r]->activateStream(s->txStream[r]); int ret2 = s->iris[r]->activateStream(s->txStream[r]);
if (ret < 0 | ret2 < 0) if (ret < 0 | ret2 < 0)
return - 1; return -1;
} }
return 0; return 0;
} }
...@@ -94,28 +92,25 @@ static int trx_iris_start(openair0_device *device) ...@@ -94,28 +92,25 @@ static int trx_iris_start(openair0_device *device)
/*! \brief Stop Iris /*! \brief Stop Iris
* \param card refers to the hardware index to use * \param card refers to the hardware index to use
*/ */
int trx_iris_stop(openair0_device* device) { int trx_iris_stop(openair0_device *device) {
iris_state_t *s = (iris_state_t*)device->priv; iris_state_t *s = (iris_state_t *) device->priv;
int r; int r;
for (r = 0; r < s->device_num; r++) for (r = 0; r < s->device_num; r++) {
{
s->iris[r]->deactivateStream(s->txStream[r]); s->iris[r]->deactivateStream(s->txStream[r]);
s->iris[r]->deactivateStream(s->rxStream[r]); s->iris[r]->deactivateStream(s->rxStream[r]);
} }
return(0); return (0);
} }
/*! \brief Terminate operation of the Iris lime transceiver -- free all associated resources /*! \brief Terminate operation of the Iris lime transceiver -- free all associated resources
* \param device the hardware to use * \param device the hardware to use
*/ */
static void trx_iris_end(openair0_device *device) static void trx_iris_end(openair0_device *device) {
{ LOG_I(HW, "Closing Iris device.\n");
LOG_I(HW,"Closing Iris device.\n");
trx_iris_stop(device); trx_iris_stop(device);
iris_state_t *s = (iris_state_t*)device->priv; iris_state_t *s = (iris_state_t *) device->priv;
int r; int r;
for (r = 0; r < s->device_num; r++) for (r = 0; r < s->device_num; r++) {
{
s->iris[r]->closeStream(s->txStream[r]); s->iris[r]->closeStream(s->txStream[r]);
s->iris[r]->closeStream(s->rxStream[r]); s->iris[r]->closeStream(s->rxStream[r]);
SoapySDR::Device::unmake(s->iris[r]); SoapySDR::Device::unmake(s->iris[r]);
...@@ -130,70 +125,65 @@ static void trx_iris_end(openair0_device *device) ...@@ -130,70 +125,65 @@ static void trx_iris_end(openair0_device *device)
@param antenna_id index of the antenna if the device has multiple anteannas @param antenna_id index of the antenna if the device has multiple anteannas
@param flags flags must be set to TRUE if timestamp parameter needs to be applied @param flags flags must be set to TRUE if timestamp parameter needs to be applied
*/ */
static int trx_iris_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags)
{
static long long int loop=0; static int
static long time_min=0, time_max=0, time_avg=0; trx_iris_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) {
using namespace std::chrono;
static long long int loop = 0;
static long time_min = 0, time_max = 0, time_avg = 0;
struct timespec tp_start, tp_end; struct timespec tp_start, tp_end;
long time_diff; long time_diff;
int ret=0, ret_i=0; int ret = 0, ret_i = 0;
int flag = 0; int flag = 0;
iris_state_t *s = (iris_state_t*)device->priv;
iris_state_t *s = (iris_state_t *) device->priv;
clock_gettime(CLOCK_MONOTONIC_RAW, &tp_start); clock_gettime(CLOCK_MONOTONIC_RAW, &tp_start);
// This hack was added by cws to help keep packets flowing
if (flags == 8) {
long long tempHack = s->iris[0]->getHardwareTime("");
return nsamps;
}
if (flags) if (flags)
flag |= SOAPY_SDR_HAS_TIME; flag |= SOAPY_SDR_HAS_TIME;
if (flags == 2 || flags == 1) { // start of burst if (flags == 2 || flags == 1) { // start of burst
}else if (flags == 3 || flags == 4){ } else if (flags == 3 || flags == 4) {
flag |= SOAPY_SDR_END_BURST; flag |= SOAPY_SDR_END_BURST;
} }
long long timeNs = SoapySDR::ticksToTimeNs(timestamp, s->sample_rate / SAMPLE_RATE_DOWN);
long long timeNs = SoapySDR::ticksToTimeNs(timestamp, s->sample_rate/SAMPLE_RATE_DOWN);
uint32_t *samps[2]; //= (uint32_t **)buff; uint32_t *samps[2]; //= (uint32_t **)buff;
int r; int r;
int m = s->tx_num_channels; int m = s->tx_num_channels;
for (r = 0; r < s->device_num; r++) for (r = 0; r < s->device_num; r++) {
{
int samples_sent = 0; int samples_sent = 0;
samps[0] = (uint32_t *)buff[m*r]; samps[0] = (uint32_t *) buff[m * r];
if (cc % 2 == 0) if (cc % 2 == 0)
samps[1] = (uint32_t *)buff[m*r+1]; //cws: it seems another thread can clobber these, so we need to save them locally. samps[1] = (uint32_t *) buff[m * r +
while (samples_sent < nsamps) 1]; //cws: it seems another thread can clobber these, so we need to save them locally.
{
ret = s->iris[r]->writeStream(s->txStream[r], (void **)samps, (size_t)(nsamps - samples_sent), flag, timeNs, 1000000); //printf("\nHardware time before write: %lld, tx_time_stamp: %lld\n", s->iris[0]->getHardwareTime(""), timeNs);
if (ret < 0) { ret = s->iris[r]->writeStream(s->txStream[r], (void **) samps, (size_t)(nsamps), flag, timeNs, 1000000);
if (ret < 0)
printf("Unable to write stream!\n"); printf("Unable to write stream!\n");
break; else
} samples_sent = ret;
flag = 0;
samples_sent += ret;
samps[0] += ret; if (samples_sent != nsamps)
if (cc % 2 == 0) printf("[xmit] tx samples %d != %d\n", samples_sent, nsamps);
samps[1] += ret;
}
if (samples_sent != nsamps) {
printf("[xmit] tx samples %d != %d\n",samples_sent,nsamps);
}
} }
/*
flag = 0;
size_t channel = 0;
ret = s->iris->readStreamStatus(s->txStream, channel, flag, timeNs, 0);
if (ret == SOAPY_SDR_TIME_ERROR)
printf("[xmit] Time Error in tx stream!\n");
else if (ret == SOAPY_SDR_UNDERFLOW)
printf("[xmit] Underflow occured!\n");
else if (ret == SOAPY_SDR_TIMEOUT)
printf("[xmit] Timeout occured!\n");
else if (ret == SOAPY_SDR_STREAM_ERROR)
printf("[xmit] Stream (tx) error occured!\n");
*/
return nsamps; return nsamps;
} }
...@@ -208,35 +198,30 @@ static int trx_iris_write(openair0_device *device, openair0_timestamp timestamp, ...@@ -208,35 +198,30 @@ static int trx_iris_write(openair0_device *device, openair0_timestamp timestamp,
* \param antenna_id Index of antenna for which to receive samples * \param antenna_id Index of antenna for which to receive samples
* \returns the number of sample read * \returns the number of sample read
*/ */
static int trx_iris_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) static int trx_iris_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) {
{
int ret = 0; int ret = 0;
static long long nextTime; static long long nextTime;
static bool nextTimeValid = false; static bool nextTimeValid = false;
iris_state_t *s = (iris_state_t*)device->priv; iris_state_t *s = (iris_state_t *) device->priv;
bool time_set = false; bool time_set = false;
long long timeNs = 0; long long timeNs = 0;
int flags; int flags;
int samples_received; int samples_received;
uint32_t *samps[2]; //= (uint32_t **)buff; uint32_t *samps[2]; //= (uint32_t **)buff;
//printf("Reading %d samples from Iris...\n", nsamps);
//fflush(stdout);
int r; int r;
int m = s->rx_num_channels; int m = s->rx_num_channels;
for (r = 0; r < s->device_num; r++) for (r = 0; r < s->device_num; r++) {
{
flags = 0; flags = 0;
samples_received = 0; samples_received = 0;
samps[0] = (uint32_t *)buff[m*r]; samps[0] = (uint32_t *) buff[m * r];
if (cc % 2 == 0) if (cc % 2 == 0)
samps[1] = (uint32_t *)buff[m*r+1]; samps[1] = (uint32_t *) buff[m * r + 1];
//uint32_t *samps[2] = {(uint32_t *)buff[2*r], (uint32_t *)buff[2*r+1]}; //cws: it seems another thread can clobber these, so we need to save them locally.
while (samples_received < nsamps)
{
flags = 0; flags = 0;
ret = s->iris[r]->readStream(s->rxStream[r], (void **)samps, (size_t)(nsamps-samples_received), flags, timeNs, 1000000); ret = s->iris[r]->readStream(s->rxStream[r], (void **) samps, (size_t)(nsamps - samples_received), flags,
if (ret < 0) timeNs, 1000000);
{ if (ret < 0) {
if (ret == SOAPY_SDR_TIME_ERROR) if (ret == SOAPY_SDR_TIME_ERROR)
printf("[recv] Time Error in tx stream!\n"); printf("[recv] Time Error in tx stream!\n");
else if (ret == SOAPY_SDR_OVERFLOW | (flags & SOAPY_SDR_END_ABRUPT)) else if (ret == SOAPY_SDR_OVERFLOW | (flags & SOAPY_SDR_END_ABRUPT))
...@@ -248,19 +233,15 @@ static int trx_iris_read(openair0_device *device, openair0_timestamp *ptimestamp ...@@ -248,19 +233,15 @@ static int trx_iris_read(openair0_device *device, openair0_timestamp *ptimestamp
else if (ret == SOAPY_SDR_CORRUPTION) else if (ret == SOAPY_SDR_CORRUPTION)
printf("[recv] Bad packet occured!\n"); printf("[recv] Bad packet occured!\n");
break; break;
} } else
samples_received = ret;
samples_received += ret;
samps[0] += ret; if (r == 0) {
if (cc % 2 == 0)
samps[1] += ret;
if (r == 0)
{
if (samples_received == ret) // first batch if (samples_received == ret) // first batch
{ {
if (flags & SOAPY_SDR_HAS_TIME) if (flags & SOAPY_SDR_HAS_TIME) {
{ s->rx_timestamp = SoapySDR::timeNsToTicks(timeNs, s->sample_rate / SAMPLE_RATE_DOWN);
s->rx_timestamp = SoapySDR::timeNsToTicks(timeNs, s->sample_rate/SAMPLE_RATE_DOWN);
*ptimestamp = s->rx_timestamp; *ptimestamp = s->rx_timestamp;
nextTime = timeNs; nextTime = timeNs;
nextTimeValid = true; nextTimeValid = true;
...@@ -269,23 +250,29 @@ static int trx_iris_read(openair0_device *device, openair0_timestamp *ptimestamp ...@@ -269,23 +250,29 @@ static int trx_iris_read(openair0_device *device, openair0_timestamp *ptimestamp
} }
} }
} }
if (r == 0) {
if (samples_received == nsamps) {
if (flags & SOAPY_SDR_HAS_TIME) {
s->rx_timestamp = SoapySDR::timeNsToTicks(nextTime, s->sample_rate / SAMPLE_RATE_DOWN);
*ptimestamp = s->rx_timestamp;
nextTime = timeNs;
nextTimeValid = true;
time_set = true;
} }
if (r == 0) } else if (samples_received < nsamps)
{ printf("[recv] received %d samples out of %d\n", samples_received, nsamps);
if (samples_received < nsamps)
printf("[recv] received %d samples out of %d\n",samples_received,nsamps);
s->rx_count += samples_received; s->rx_count += samples_received;
if (s->sample_rate != 0 && nextTimeValid) if (s->sample_rate != 0 && nextTimeValid) {
{ if (!time_set) {
if (!time_set) s->rx_timestamp = SoapySDR::timeNsToTicks(nextTime, s->sample_rate / SAMPLE_RATE_DOWN);
{
s->rx_timestamp = SoapySDR::timeNsToTicks(nextTime, s->sample_rate/SAMPLE_RATE_DOWN);
*ptimestamp = s->rx_timestamp; *ptimestamp = s->rx_timestamp;
//printf("2) time set %llu, nextTime will be %llu \n", *ptimestamp, nextTime); //printf("2) time set %llu, nextTime will be %llu \n", *ptimestamp, nextTime);
} }
nextTime += SoapySDR::ticksToTimeNs(samples_received, s->sample_rate/SAMPLE_RATE_DOWN); nextTime += SoapySDR::ticksToTimeNs(samples_received, s->sample_rate / SAMPLE_RATE_DOWN);
} }
} }
} }
...@@ -295,9 +282,8 @@ static int trx_iris_read(openair0_device *device, openair0_timestamp *ptimestamp ...@@ -295,9 +282,8 @@ static int trx_iris_read(openair0_device *device, openair0_timestamp *ptimestamp
/*! \brief Get current timestamp of Iris /*! \brief Get current timestamp of Iris
* \param device the hardware to use * \param device the hardware to use
*/ */
openair0_timestamp get_iris_time(openair0_device *device) openair0_timestamp get_iris_time(openair0_device *device) {
{ iris_state_t *s = (iris_state_t *) device->priv;
iris_state_t *s = (iris_state_t*)device->priv;
return SoapySDR::timeNsToTicks(s->iris[0]->getHardwareTime(""), s->sample_rate); return SoapySDR::timeNsToTicks(s->iris[0]->getHardwareTime(""), s->sample_rate);
} }
...@@ -305,61 +291,58 @@ openair0_timestamp get_iris_time(openair0_device *device) ...@@ -305,61 +291,58 @@ openair0_timestamp get_iris_time(openair0_device *device)
* \param a first variable * \param a first variable
* \param b second variable * \param b second variable
*/ */
static bool is_equal(double a, double b) static bool is_equal(double a, double b) {
{ return std::fabs(a - b) < std::numeric_limits<double>::epsilon();
return std::fabs(a-b) < std::numeric_limits<double>::epsilon();
} }
void *set_freq_thread(void *arg) { void *set_freq_thread(void *arg) {
openair0_device *device=(openair0_device *)arg; openair0_device *device = (openair0_device *) arg;
iris_state_t *s = (iris_state_t*)device->priv; iris_state_t *s = (iris_state_t *) device->priv;
int r, i; int r, i;
printf("Setting Iris TX Freq %f, RX Freq %f\n",device->openair0_cfg[0].tx_freq[0],device->openair0_cfg[0].rx_freq[0]); printf("Setting Iris TX Freq %f, RX Freq %f\n", device->openair0_cfg[0].tx_freq[0],
device->openair0_cfg[0].rx_freq[0]);
// add check for the number of channels in the cfg // add check for the number of channels in the cfg
for (r = 0; r < s->device_num; r++) for (r = 0; r < s->device_num; r++) {
{ for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) {
for(i=0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) {
if (i < s->rx_num_channels) if (i < s->rx_num_channels)
s->iris[r]->setFrequency(SOAPY_SDR_RX, i, "RF", device->openair0_cfg[0].rx_freq[i]); s->iris[r]->setFrequency(SOAPY_SDR_RX, i, "RF", device->openair0_cfg[0].rx_freq[i]);
} }
for(i=0; i < s->iris[r]->getNumChannels(SOAPY_SDR_TX); i++) { for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_TX); i++) {
if (i < s->tx_num_channels) if (i < s->tx_num_channels)
s->iris[r]->setFrequency(SOAPY_SDR_TX, i, "RF", device->openair0_cfg[0].tx_freq[i]); s->iris[r]->setFrequency(SOAPY_SDR_TX, i, "RF", device->openair0_cfg[0].tx_freq[i]);
} }
} }
} }
/*! \brief Set frequencies (TX/RX) /*! \brief Set frequencies (TX/RX)
* \param device the hardware to use * \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application * \param openair0_cfg RF frontend parameters set by application
* \param dummy dummy variable not used * \param dummy dummy variable not used
* \returns 0 in success * \returns 0 in success
*/ */
int trx_iris_set_freq(openair0_device* device, openair0_config_t *openair0_cfg, int dont_block) int trx_iris_set_freq(openair0_device *device, openair0_config_t *openair0_cfg, int dont_block) {
{ iris_state_t *s = (iris_state_t *) device->priv;
iris_state_t *s = (iris_state_t*)device->priv;
pthread_t f_thread; pthread_t f_thread;
if (dont_block) if (dont_block)
pthread_create(&f_thread, NULL, set_freq_thread, (void*)device); pthread_create(&f_thread, NULL, set_freq_thread, (void *) device);
else else {
{
int r, i; int r, i;
for (r = 0; r < s->device_num; r++) for (r = 0; r < s->device_num; r++) {
{ printf("Setting Iris TX Freq %f, RX Freq %f\n", openair0_cfg[0].tx_freq[0], openair0_cfg[0].rx_freq[0]);
printf("Setting Iris TX Freq %f, RX Freq %f\n",openair0_cfg[0].tx_freq[0],openair0_cfg[0].rx_freq[0]); for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) {
for(i=0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) {
if (i < s->rx_num_channels) { if (i < s->rx_num_channels) {
s->iris[r]->setFrequency(SOAPY_SDR_RX, i, "RF", openair0_cfg[0].rx_freq[i]); s->iris[r]->setFrequency(SOAPY_SDR_RX, i, "RF", openair0_cfg[0].rx_freq[i]);
} }
} }
for(i=0; i < s->iris[r]->getNumChannels(SOAPY_SDR_TX); i++) { for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_TX); i++) {
if (i < s->tx_num_channels) { if (i < s->tx_num_channels) {
s->iris[r]->setFrequency(SOAPY_SDR_TX, i, "RF", openair0_cfg[0].tx_freq[i]); s->iris[r]->setFrequency(SOAPY_SDR_TX, i, "RF", openair0_cfg[0].tx_freq[i]);
} }
} }
} }
} }
return(0); return (0);
} }
...@@ -368,29 +351,28 @@ int trx_iris_set_freq(openair0_device* device, openair0_config_t *openair0_cfg, ...@@ -368,29 +351,28 @@ int trx_iris_set_freq(openair0_device* device, openair0_config_t *openair0_cfg,
* \param openair0_cfg RF frontend parameters set by application * \param openair0_cfg RF frontend parameters set by application
* \returns 0 in success * \returns 0 in success
*/ */
int trx_iris_set_gains(openair0_device* device, int trx_iris_set_gains(openair0_device *device,
openair0_config_t *openair0_cfg) { openair0_config_t *openair0_cfg) {
iris_state_t *s = (iris_state_t*)device->priv; iris_state_t *s = (iris_state_t *) device->priv;
int r; int r;
for (r = 0; r < s->device_num; r++) for (r = 0; r < s->device_num; r++) {
{
s->iris[r]->setGain(SOAPY_SDR_RX, 0, openair0_cfg[0].rx_gain[0]); s->iris[r]->setGain(SOAPY_SDR_RX, 0, openair0_cfg[0].rx_gain[0]);
s->iris[r]->setGain(SOAPY_SDR_TX, 0, openair0_cfg[0].tx_gain[0]); s->iris[r]->setGain(SOAPY_SDR_TX, 0, openair0_cfg[0].tx_gain[0]);
s->iris[r]->setGain(SOAPY_SDR_RX, 1, openair0_cfg[0].rx_gain[1]); s->iris[r]->setGain(SOAPY_SDR_RX, 1, openair0_cfg[0].rx_gain[1]);
s->iris[r]->setGain(SOAPY_SDR_TX, 1, openair0_cfg[0].tx_gain[1]); s->iris[r]->setGain(SOAPY_SDR_TX, 1, openair0_cfg[0].tx_gain[1]);
} }
return(0); return (0);
} }
/*! \brief Iris RX calibration table */ /*! \brief Iris RX calibration table */
rx_gain_calib_table_t calib_table_iris[] = { rx_gain_calib_table_t calib_table_iris[] = {
{3500000000.0,83}, {3500000000.0, 83},
{2660000000.0,83}, {2660000000.0, 83},
{2580000000.0,83}, {2580000000.0, 83},
{2300000000.0,83}, {2300000000.0, 83},
{1880000000.0,83}, {1880000000.0, 83},
{816000000.0,83}, {816000000.0, 83},
{-1,0}}; {-1, 0}};
/*! \brief Set RX gain offset /*! \brief Set RX gain offset
...@@ -398,61 +380,60 @@ rx_gain_calib_table_t calib_table_iris[] = { ...@@ -398,61 +380,60 @@ rx_gain_calib_table_t calib_table_iris[] = {
* \param chain_index RF chain to apply settings to * \param chain_index RF chain to apply settings to
* \returns 0 in success * \returns 0 in success
*/ */
void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index,int bw_gain_adjust) { void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index, int bw_gain_adjust) {
int i=0; int i = 0;
// loop through calibration table to find best adjustment factor for RX frequency // loop through calibration table to find best adjustment factor for RX frequency
double min_diff = 6e9,diff,gain_adj=0.0; double min_diff = 6e9, diff, gain_adj = 0.0;
if (bw_gain_adjust==1) { if (bw_gain_adjust == 1) {
switch ((int)openair0_cfg[0].sample_rate) { switch ((int) openair0_cfg[0].sample_rate) {
case 30720000: case 30720000:
break; break;
case 23040000: case 23040000:
gain_adj=1.25; gain_adj = 1.25;
break; break;
case 15360000: case 15360000:
gain_adj=3.0; gain_adj = 3.0;
break; break;
case 7680000: case 7680000:
gain_adj=6.0; gain_adj = 6.0;
break; break;
case 3840000: case 3840000:
gain_adj=9.0; gain_adj = 9.0;
break; break;
case 1920000: case 1920000:
gain_adj=12.0; gain_adj = 12.0;
break; break;
default: default:
printf("unknown sampling rate %d\n",(int)openair0_cfg[0].sample_rate); printf("unknown sampling rate %d\n", (int) openair0_cfg[0].sample_rate);
exit(-1); exit(-1);
break; break;
} }
} }
if (openair0_cfg[0].gain_calib_val == 0){ if (openair0_cfg[0].gain_calib_val == 0) {
while (openair0_cfg->rx_gain_calib_table[i].freq>0) { while (openair0_cfg->rx_gain_calib_table[i].freq > 0) {
diff = fabs(openair0_cfg->rx_freq[chain_index] - openair0_cfg->rx_gain_calib_table[i].freq); diff = fabs(openair0_cfg->rx_freq[chain_index] - openair0_cfg->rx_gain_calib_table[i].freq);
printf("cal %d: freq %f, offset %f, diff %f\n", printf("cal %d: freq %f, offset %f, diff %f\n",
i, i,
openair0_cfg->rx_gain_calib_table[i].freq, openair0_cfg->rx_gain_calib_table[i].freq,
openair0_cfg->rx_gain_calib_table[i].offset,diff); openair0_cfg->rx_gain_calib_table[i].offset, diff);
if (min_diff > diff) { if (min_diff > diff) {
min_diff = diff; min_diff = diff;
openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg->rx_gain_calib_table[i].offset+gain_adj; openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg->rx_gain_calib_table[i].offset + gain_adj;
} }
i++; i++;
} }
} } else
else openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg[0].gain_calib_val + gain_adj;
openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg[0].gain_calib_val+gain_adj;
} }
/*! \brief print the Iris statistics /*! \brief print the Iris statistics
* \param device the hardware to use * \param device the hardware to use
* \returns 0 on success * \returns 0 on success
*/ */
int trx_iris_get_stats(openair0_device* device) { int trx_iris_get_stats(openair0_device *device) {
return(0); return (0);
} }
...@@ -460,82 +441,90 @@ int trx_iris_get_stats(openair0_device* device) { ...@@ -460,82 +441,90 @@ int trx_iris_get_stats(openair0_device* device) {
* \param device the hardware to use * \param device the hardware to use
* \returns 0 on success * \returns 0 on success
*/ */
int trx_iris_reset_stats(openair0_device* device) { int trx_iris_reset_stats(openair0_device *device) {
return(0); return (0);
} }
extern "C" { extern "C" {
/*! \brief Initialize Openair Iris target. It returns 0 if OK /*! \brief Initialize Openair Iris target. It returns 0 if OK
* \param device the hardware to use * \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application * \param openair0_cfg RF frontend parameters set by application
*/ */
int device_init(openair0_device* device, openair0_config_t *openair0_cfg) { int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
size_t i,r,card; size_t i, r, card;
int bw_gain_adjust=0; int bw_gain_adjust = 0;
openair0_cfg[0].rx_gain_calib_table = calib_table_iris; openair0_cfg[0].rx_gain_calib_table = calib_table_iris;
iris_state_t *s = (iris_state_t*)malloc(sizeof(iris_state_t)); iris_state_t *s = (iris_state_t *) malloc(sizeof(iris_state_t));
memset(s, 0, sizeof(iris_state_t)); memset(s, 0, sizeof(iris_state_t));
std::string devFE("DEV");
std::string cbrsFE("CBRS");
std::string wireFormat("WIRE");
// Initialize Iris device // Initialize Iris device
device->openair0_cfg = openair0_cfg; device->openair0_cfg = openair0_cfg;
SoapySDR::Kwargs args; SoapySDR::Kwargs args;
for (card = 0; card < MAX_CARDS; card++) printf("\nMAX_CARDS: %d\n", MAX_CARDS);
{ for (card = 0; card < 1; card++) {
char* remote_addr = device->openair0_cfg[card].remote_addr; char *remote_addr = device->openair0_cfg[card].remote_addr;
if (remote_addr == NULL) {printf("Opened %d cards...\n", card);break;} if (remote_addr == NULL) {
char* drvtype = strtok(remote_addr, ","); printf("Opened %lu cards...\n", card);
break;
}
char *drvtype = strtok(remote_addr, ",");
char *srl = strtok(NULL, ","); char *srl = strtok(NULL, ",");
while (srl != NULL) while (srl != NULL) {
{ LOG_I(HW, "Attempting to open Iris device\n");//, srl);
LOG_I(HW,"Attempting to open Iris device: %s\n", srl); args["driver"] = "iris";//drvtype;
args["driver"] = drvtype; args["serial"] = srl; //Ali: Debugging...was "serial"
args["serial"] = srl;
s->iris.push_back(SoapySDR::Device::make(args)); s->iris.push_back(SoapySDR::Device::make(args));
srl = strtok(NULL, ","); srl = strtok(NULL, ",");
} }
//openair0_cfg[0].iq_txshift = 4;//if radio needs OAI to shift left the tx samples for preserving bit precision openair0_cfg[0].iq_txshift = 4;//if radio needs OAI to shift left the tx samples for preserving bit precision
openair0_cfg[0].iq_rxrescale = 15;
} }
s->device_num = s->iris.size(); s->device_num = s->iris.size();
device->type=IRIS_DEV; device->type = IRIS_DEV;
switch ((int)openair0_cfg[0].sample_rate) { switch ((int) openair0_cfg[0].sample_rate) {
case 30720000: case 30720000:
//openair0_cfg[0].samples_per_packet = 1024; //openair0_cfg[0].samples_per_packet = 1024;
//openair0_cfg[0].tx_sample_advance = 115; openair0_cfg[0].tx_sample_advance = 115;
openair0_cfg[0].tx_bw = 20e6; openair0_cfg[0].tx_bw = 20e6;
openair0_cfg[0].rx_bw = 20e6; openair0_cfg[0].rx_bw = 20e6;
break; break;
case 23040000: case 23040000:
//openair0_cfg[0].samples_per_packet = 1024; //openair0_cfg[0].samples_per_packet = 1024;
//openair0_cfg[0].tx_sample_advance = 113; openair0_cfg[0].tx_sample_advance = 113;
openair0_cfg[0].tx_bw = 15e6; openair0_cfg[0].tx_bw = 15e6;
openair0_cfg[0].rx_bw = 15e6; openair0_cfg[0].rx_bw = 15e6;
break; break;
case 15360000: case 15360000:
//openair0_cfg[0].samples_per_packet = 1024; //openair0_cfg[0].samples_per_packet = 1024;
//openair0_cfg[0].tx_sample_advance = 103; openair0_cfg[0].tx_sample_advance = 60;
openair0_cfg[0].tx_bw = 10e6; openair0_cfg[0].tx_bw = 10e6;
openair0_cfg[0].rx_bw = 10e6; openair0_cfg[0].rx_bw = 10e6;
break; break;
case 7680000: case 7680000:
//openair0_cfg[0].samples_per_packet = 1024; //openair0_cfg[0].samples_per_packet = 1024;
//openair0_cfg[0].tx_sample_advance = 80; openair0_cfg[0].tx_sample_advance = 30;
openair0_cfg[0].tx_bw = 30e6; openair0_cfg[0].tx_bw = 5e6;
openair0_cfg[0].rx_bw = 30e6; openair0_cfg[0].rx_bw = 5e6;
break; break;
case 1920000: case 1920000:
//openair0_cfg[0].samples_per_packet = 1024; //openair0_cfg[0].samples_per_packet = 1024;
//openair0_cfg[0].tx_sample_advance = 40; openair0_cfg[0].tx_sample_advance = 40;
openair0_cfg[0].tx_bw = 5e6; openair0_cfg[0].tx_bw = 1.4e6;
openair0_cfg[0].rx_bw = 5e6; openair0_cfg[0].rx_bw = 1.4e6;
break; break;
default: default:
printf("Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); printf("Error: unknown sampling rate %f\n", openair0_cfg[0].sample_rate);
exit(-1); exit(-1);
break; break;
} }
...@@ -545,101 +534,232 @@ extern "C" { ...@@ -545,101 +534,232 @@ extern "C" {
s->tx_num_channels = openair0_cfg[0].tx_num_channels; s->tx_num_channels = openair0_cfg[0].tx_num_channels;
if ((s->rx_num_channels == 1 || s->rx_num_channels == 2) && (s->tx_num_channels == 1 || s->tx_num_channels == 2)) if ((s->rx_num_channels == 1 || s->rx_num_channels == 2) && (s->tx_num_channels == 1 || s->tx_num_channels == 2))
printf("Enabling %d rx and %d tx channel(s) on each device...\n", s->rx_num_channels, s->tx_num_channels); printf("Enabling %d rx and %d tx channel(s) on each device...\n", s->rx_num_channels, s->tx_num_channels);
else else {
{
printf("Invalid rx or tx number of channels (%d, %d)\n", s->rx_num_channels, s->tx_num_channels); printf("Invalid rx or tx number of channels (%d, %d)\n", s->rx_num_channels, s->tx_num_channels);
exit(-1); exit(-1);
} }
for (r = 0; r < s->device_num; r++) for (r = 0; r < s->device_num; r++) {
{ switch ((int) openair0_cfg[0].sample_rate) {
s->iris[r]->setMasterClockRate(8*openair0_cfg[0].sample_rate); // sample*8=clock_rate for Soapy case 1920000:
s->iris[r]->setMasterClockRate(256 * openair0_cfg[0].sample_rate);
break;
case 3840000:
s->iris[r]->setMasterClockRate(128 * openair0_cfg[0].sample_rate);
break;
case 7680000:
s->iris[r]->setMasterClockRate(64 * openair0_cfg[0].sample_rate);
break;
case 15360000:
s->iris[r]->setMasterClockRate(32 * openair0_cfg[0].sample_rate);
break;
case 30720000:
s->iris[r]->setMasterClockRate(16 * openair0_cfg[0].sample_rate);
break;
default:
printf("Error: unknown sampling rate %f\n", openair0_cfg[0].sample_rate);
exit(-1);
break;
}
// display Iris settings // display Iris settings
printf("Actual master clock: %fMHz...\n", (s->iris[r]->getMasterClockRate()/1e6)); printf("Actual master clock: %fMHz...\n", (s->iris[r]->getMasterClockRate() / 1e6));
/* Setting TX/RX BW after streamers are created due to iris calibration issue */ /* Setting TX/RX BW after streamers are created due to iris calibration issue */
for(i = 0; i < s->tx_num_channels; i++) { for (i = 0; i < s->tx_num_channels; i++) {
if (i < s->iris[r]->getNumChannels(SOAPY_SDR_TX) ) { if (i < s->iris[r]->getNumChannels(SOAPY_SDR_TX)) {
if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0)
s->iris[r]->setBandwidth(SOAPY_SDR_TX, i, 30e6);
else
s->iris[r]->setBandwidth(SOAPY_SDR_TX, i, openair0_cfg[0].tx_bw); s->iris[r]->setBandwidth(SOAPY_SDR_TX, i, openair0_cfg[0].tx_bw);
printf("Setting tx bandwidth on channel %lu/%lu: BW %f (readback %f)\n",i,s->iris[r]->getNumChannels(SOAPY_SDR_TX),openair0_cfg[0].tx_bw/1e6,s->iris[r]->getBandwidth(SOAPY_SDR_TX, i)/1e6);
printf("Setting tx bandwidth on channel %lu/%lu: BW %f (readback %f)\n", i,
s->iris[r]->getNumChannels(SOAPY_SDR_TX), openair0_cfg[0].tx_bw / 1e6,
s->iris[r]->getBandwidth(SOAPY_SDR_TX, i) / 1e6);
} }
} }
for(i = 0; i < s->rx_num_channels; i++) { for (i = 0; i < s->rx_num_channels; i++) {
if (i < s->iris[r]->getNumChannels(SOAPY_SDR_RX)) { if (i < s->iris[r]->getNumChannels(SOAPY_SDR_RX)) {
if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0)
s->iris[r]->setBandwidth(SOAPY_SDR_TX, i, 30e6);
else
s->iris[r]->setBandwidth(SOAPY_SDR_RX, i, openair0_cfg[0].rx_bw); s->iris[r]->setBandwidth(SOAPY_SDR_RX, i, openair0_cfg[0].rx_bw);
printf("Setting rx bandwidth on channel %lu/%lu : BW %f (readback %f)\n",i,s->iris[r]->getNumChannels(SOAPY_SDR_RX),openair0_cfg[0].rx_bw/1e6,s->iris[r]->getBandwidth(SOAPY_SDR_RX, i)/1e6); printf("Setting rx bandwidth on channel %lu/%lu : BW %f (readback %f)\n", i,
s->iris[r]->getNumChannels(SOAPY_SDR_RX), openair0_cfg[0].rx_bw / 1e6,
s->iris[r]->getBandwidth(SOAPY_SDR_RX, i) / 1e6);
} }
} }
for(i=0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) { for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) {
if (i < s->rx_num_channels) { if (i < s->rx_num_channels) {
s->iris[r]->setSampleRate(SOAPY_SDR_RX, i, openair0_cfg[0].sample_rate/SAMPLE_RATE_DOWN); s->iris[r]->setSampleRate(SOAPY_SDR_RX, i, openair0_cfg[0].sample_rate / SAMPLE_RATE_DOWN);
s->iris[r]->setFrequency(SOAPY_SDR_RX, i, "RF", openair0_cfg[0].rx_freq[i]); s->iris[r]->setFrequency(SOAPY_SDR_RX, i, "RF", openair0_cfg[0].rx_freq[i]);
set_rx_gain_offset(&openair0_cfg[0],i,bw_gain_adjust); set_rx_gain_offset(&openair0_cfg[0], i, bw_gain_adjust);
s->iris[r]->setGain(SOAPY_SDR_RX, i, openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i]); //s->iris[r]->setGain(SOAPY_SDR_RX, i, openair0_cfg[0].rx_gain[i] - openair0_cfg[0].rx_gain_offset[i]);
if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) {
s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA", openair0_cfg[0].rx_gain[i] - openair0_cfg[0].rx_gain_offset[i]);
//s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA", 0);
s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA1", 30);
s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA2", 17);
s->iris[r]->setGain(SOAPY_SDR_RX, i, "TIA", 0);
s->iris[r]->setGain(SOAPY_SDR_RX, i, "PGA", 0);
s->iris[r]->setGain(SOAPY_SDR_RX, i, "ATTN", 0);
} else {
s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA", openair0_cfg[0].rx_gain[i] - openair0_cfg[0].rx_gain_offset[i]); // [0,30]
s->iris[r]->setGain(SOAPY_SDR_RX, i, "TIA", 0); // [0,12,6]
s->iris[r]->setGain(SOAPY_SDR_RX, i, "PGA", 0); // [-12,19,1]
//s->iris[r]->setGain(SOAPY_SDR_RX, i, 50); // [-12,19,1]
}
if (openair0_cfg[0].duplex_mode == 1) //duplex_mode_TDD
s->iris[r]->setAntenna(SOAPY_SDR_RX, i, "TRX");
else
s->iris[r]->setAntenna(SOAPY_SDR_RX, i, "RX");
if (openair0_cfg[0].duplex_mode == 1 ) //duplex_mode_TDD
s->iris[r]->setAntenna(SOAPY_SDR_RX, i, s->iris[r]->listAntennas(SOAPY_SDR_RX, i)[0]);
s->iris[r]->setDCOffsetMode(SOAPY_SDR_RX, i, true); // move somewhere else s->iris[r]->setDCOffsetMode(SOAPY_SDR_RX, i, true); // move somewhere else
} }
} }
for(i=0; i < s->iris[r]->getNumChannels(SOAPY_SDR_TX); i++) { for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_TX); i++) {
if (i < s->tx_num_channels) { if (i < s->tx_num_channels) {
s->iris[r]->setSampleRate(SOAPY_SDR_TX, i, openair0_cfg[0].sample_rate/SAMPLE_RATE_DOWN); s->iris[r]->setSampleRate(SOAPY_SDR_TX, i, openair0_cfg[0].sample_rate / SAMPLE_RATE_DOWN);
s->iris[r]->setFrequency(SOAPY_SDR_TX, i, "RF", openair0_cfg[0].tx_freq[i]); s->iris[r]->setFrequency(SOAPY_SDR_TX, i, "RF", openair0_cfg[0].tx_freq[i]);
s->iris[r]->setGain(SOAPY_SDR_TX, i, openair0_cfg[0].tx_gain[i]);
if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) == 0) {
s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", openair0_cfg[0].tx_gain[i]);
//s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", 52);
s->iris[r]->setGain(SOAPY_SDR_TX, i, "IAMP", 0);
//s->iris[r]->writeSetting("TX_ENABLE_DELAY", "0");
//s->iris[r]->writeSetting("TX_DISABLE_DELAY", "100");
} else {
s->iris[r]->setGain(SOAPY_SDR_TX, i, "ATTN", 0); // [-18, 0, 6] dB
s->iris[r]->setGain(SOAPY_SDR_TX, i, "IAMP", 0); // [-12, 12, 1] dB
s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", openair0_cfg[0].tx_gain[i]);
//s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", 35); // [0, 52, 1] dB
s->iris[r]->setGain(SOAPY_SDR_TX, i, "PA1", 9); // 17 ??? dB
s->iris[r]->setGain(SOAPY_SDR_TX, i, "PA2", 0); // [0, 17, 17] dB
s->iris[r]->setGain(SOAPY_SDR_TX, i, "PA3", 20); // 33 ??? dB
s->iris[r]->writeSetting("TX_ENABLE_DELAY", "0");
s->iris[r]->writeSetting("TX_DISABLE_DELAY", "100");
}
// if (openair0_cfg[0].duplex_mode == 0) {
// printf("\nFDD: Enable TX antenna override\n");
// s->iris[r]->writeSetting(SOAPY_SDR_TX, i, "TX_ENB_OVERRIDE",
// "true"); // From Josh: forces tx switching to be on always transmit regardless of bursts
// }
}
}
for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) {
if (i < s->rx_num_channels) {
if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) {
printf("\nUsing SKLK calibration...\n");
s->iris[r]->writeSetting(SOAPY_SDR_RX, i, "CALIBRATE", "SKLK");
} else {
s->iris[r]->writeSetting(SOAPY_SDR_RX, i, "CALIBRATE", "");
printf("\nUsing LMS calibration...\n");
}
}
}
for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_TX); i++) {
if (i < s->tx_num_channels) {
if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) {
printf("\nUsing SKLK calibration...\n");
s->iris[r]->writeSetting(SOAPY_SDR_TX, i, "CALIBRATE", "SKLK");
} else {
printf("\nUsing LMS calibration...\n");
s->iris[r]->writeSetting(SOAPY_SDR_TX, i, "CALIBRATE", "");
}
}
}
for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) {
if (openair0_cfg[0].duplex_mode == 0) {
printf("\nFDD: Setting receive antenna to %s\n", s->iris[r]->listAntennas(SOAPY_SDR_RX, i)[1].c_str());
if (i < s->rx_num_channels)
s->iris[r]->setAntenna(SOAPY_SDR_RX, i, "RX");
} else {
printf("\nTDD: Setting receive antenna to %s\n", s->iris[r]->listAntennas(SOAPY_SDR_RX, i)[0].c_str());
if (i < s->rx_num_channels)
s->iris[r]->setAntenna(SOAPY_SDR_RX, i, "TRX");
} }
} }
//s->iris[r]->writeSetting("TX_SW_DELAY", std::to_string(
// -openair0_cfg[0].tx_sample_advance)); //should offset switching to compensate for RF path (Lime) delay -- this will eventually be automated
// create tx & rx streamer // create tx & rx streamer
//const SoapySDR::Kwargs &arg = SoapySDR::Kwargs(); //const SoapySDR::Kwargs &arg = SoapySDR::Kwargs();
std::vector<size_t> channels; std::map <std::string, std::string> rxStreamArgs;
rxStreamArgs["WIRE"] = SOAPY_SDR_CS16;
std::vector <size_t> channels;
for (i = 0; i < s->rx_num_channels; i++) for (i = 0; i < s->rx_num_channels; i++)
if (i < s->iris[r]->getNumChannels(SOAPY_SDR_RX)) if (i < s->iris[r]->getNumChannels(SOAPY_SDR_RX))
channels.push_back(i); channels.push_back(i);
s->rxStream.push_back(s->iris[r]->setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, channels)); //, arg)); s->rxStream.push_back(s->iris[r]->setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, channels));//, rxStreamArgs));
std::vector<size_t> tx_channels={}; std::vector <size_t> tx_channels = {};
for (i = 0; i < s->tx_num_channels; i++) for (i = 0; i < s->tx_num_channels; i++)
if (i < s->iris[r]->getNumChannels(SOAPY_SDR_TX)) if (i < s->iris[r]->getNumChannels(SOAPY_SDR_TX))
tx_channels.push_back(i); tx_channels.push_back(i);
s->txStream.push_back(s->iris[r]->setupStream(SOAPY_SDR_TX, SOAPY_SDR_CS16, tx_channels)); //, arg)); s->txStream.push_back(s->iris[r]->setupStream(SOAPY_SDR_TX, SOAPY_SDR_CS16, tx_channels)); //, arg));
//s->iris[r]->setHardwareTime(0, ""); //s->iris[r]->setHardwareTime(0, "");
std::cout << "Front end detected: " << s->iris[r]->getHardwareInfo()["frontend"] << "\n";
for (i = 0; i < s->rx_num_channels; i++) { for (i = 0; i < s->rx_num_channels; i++) {
if (i < s->iris[r]->getNumChannels(SOAPY_SDR_RX)) { if (i < s->iris[r]->getNumChannels(SOAPY_SDR_RX)) {
printf("RX Channel %lu\n",i); printf("RX Channel %lu\n", i);
printf("Actual RX sample rate: %fMSps...\n", (s->iris[r]->getSampleRate(SOAPY_SDR_RX, i)/1e6) ); printf("Actual RX sample rate: %fMSps...\n", (s->iris[r]->getSampleRate(SOAPY_SDR_RX, i) / 1e6));
printf("Actual RX frequency: %fGHz...\n", (s->iris[r]->getFrequency(SOAPY_SDR_RX, i)/1e9) ); printf("Actual RX frequency: %fGHz...\n", (s->iris[r]->getFrequency(SOAPY_SDR_RX, i) / 1e9));
printf("Actual RX gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i)) ); printf("Actual RX gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i)));
printf("Actual RX LNA gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "LNA")) ); printf("Actual RX LNA gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "LNA")));
printf("Actual RX PGA gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "PGA")) ); printf("Actual RX PGA gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "PGA")));
printf("Actual RX TIA gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "TIA")) ); printf("Actual RX TIA gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "TIA")));
printf("Actual RX bandwidth: %fM...\n", (s->iris[r]->getBandwidth(SOAPY_SDR_RX, i)/1e6) ); if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) {
printf("Actual RX antenna: %s...\n", (s->iris[r]->getAntenna(SOAPY_SDR_RX, i).c_str()) ); printf("Actual RX LNA1 gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "LNA1")));
printf("Actual RX LNA2 gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "LNA2")));
}
printf("Actual RX bandwidth: %fM...\n", (s->iris[r]->getBandwidth(SOAPY_SDR_RX, i) / 1e6));
printf("Actual RX antenna: %s...\n", (s->iris[r]->getAntenna(SOAPY_SDR_RX, i).c_str()));
} }
} }
for (i=0;i < s->tx_num_channels;i++) { for (i = 0; i < s->tx_num_channels; i++) {
if (i < s->iris[r]->getNumChannels(SOAPY_SDR_TX)) { if (i < s->iris[r]->getNumChannels(SOAPY_SDR_TX)) {
printf("TX Channel %lu\n",i); printf("TX Channel %lu\n", i);
printf("Actual TX sample rate: %fMSps...\n", (s->iris[r]->getSampleRate(SOAPY_SDR_TX, i)/1e6) ); printf("Actual TX sample rate: %fMSps...\n", (s->iris[r]->getSampleRate(SOAPY_SDR_TX, i) / 1e6));
printf("Actual TX frequency: %fGHz...\n", (s->iris[r]->getFrequency(SOAPY_SDR_TX, i)/1e9) ); printf("Actual TX frequency: %fGHz...\n", (s->iris[r]->getFrequency(SOAPY_SDR_TX, i) / 1e9));
printf("Actual TX gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i)) ); printf("Actual TX gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i)));
printf("Actual TX PAD gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i, "PAD")) ); printf("Actual TX PAD gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i, "PAD")));
printf("Actual TX bandwidth: %fM...\n", (s->iris[r]->getBandwidth(SOAPY_SDR_TX, i)/1e6) ); printf("Actual TX IAMP gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i, "IAMP")));
printf("Actual TX antenna: %s...\n", (s->iris[r]->getAntenna(SOAPY_SDR_TX, i).c_str()) ); if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) {
printf("Actual TX PA1 gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i, "PA1")));
printf("Actual TX PA2 gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i, "PA2")));
printf("Actual TX PA3 gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i, "PA3")));
}
printf("Actual TX bandwidth: %fM...\n", (s->iris[r]->getBandwidth(SOAPY_SDR_TX, i) / 1e6));
printf("Actual TX antenna: %s...\n", (s->iris[r]->getAntenna(SOAPY_SDR_TX, i).c_str()));
} }
} }
} }
s->iris[0]->writeSetting("SYNC_DELAYS",""); s->iris[0]->writeSetting("SYNC_DELAYS", "");
for (r = 0; r < s->device_num; r++) for (r = 0; r < s->device_num; r++)
s->iris[r]->setHardwareTime(0, "TRIGGER"); s->iris[r]->setHardwareTime(0, "TRIGGER");
s->iris[0]->writeSetting("TRIGGER_GEN",""); s->iris[0]->writeSetting("TRIGGER_GEN", "");
for (r = 0; r < s->device_num; r++) for (r = 0; r < s->device_num; r++)
printf("Device timestamp: %f...\n", (s->iris[r]->getHardwareTime("TRIG")/1e9) ); printf("Device timestamp: %f...\n", (s->iris[r]->getHardwareTime("TRIGGER") / 1e9));
device->priv = s; device->priv = s;
device->trx_start_func = trx_iris_start; device->trx_start_func = trx_iris_start;
...@@ -656,16 +776,16 @@ extern "C" { ...@@ -656,16 +776,16 @@ extern "C" {
s->sample_rate = openair0_cfg[0].sample_rate; s->sample_rate = openair0_cfg[0].sample_rate;
// TODO: // TODO:
// init tx_forward_nsamps based iris_time_offset ex // init tx_forward_nsamps based iris_time_offset ex
if(is_equal(s->sample_rate, (double)30.72e6)) if (is_equal(s->sample_rate, (double) 30.72e6))
s->tx_forward_nsamps = 176; s->tx_forward_nsamps = 176;
if(is_equal(s->sample_rate, (double)15.36e6)) if (is_equal(s->sample_rate, (double) 15.36e6))
s->tx_forward_nsamps = 90; s->tx_forward_nsamps = 90;
if(is_equal(s->sample_rate, (double)7.68e6)) if (is_equal(s->sample_rate, (double) 7.68e6))
s->tx_forward_nsamps = 50; s->tx_forward_nsamps = 50;
LOG_I(HW,"Finished initializing %d Iris device(s).\n", s->device_num); LOG_I(HW, "Finished initializing %d Iris device(s).\n", s->device_num);
fflush(stdout); fflush(stdout);
return 0; return 0;
} }
} }
/*@}*/ /*@}*/
...@@ -33,14 +33,14 @@ eNBs = ...@@ -33,14 +33,14 @@ eNBs =
eutra_band = 38; eutra_band = 38;
downlink_frequency = 2580000000L; downlink_frequency = 2580000000L;
uplink_frequency_offset = 0; uplink_frequency_offset = 0;
Nid_cell = 57; Nid_cell = 10;
N_RB_DL = 25; N_RB_DL = 100;
Nid_cell_mbsfn = 0; Nid_cell_mbsfn = 0;
nb_antenna_ports = 1; nb_antenna_ports = 1;
nb_antennas_tx = 1; nb_antennas_tx = 1;
nb_antennas_rx = 1; nb_antennas_rx = 1;
tx_gain = 52; tx_gain = 52; # [ ~50 for DEV-FE, ~30 for CBRS-FE ]
rx_gain = 110; rx_gain = 115; # [ ~115 for DEV-FE, ~90 fir CBRS-FE ]
prach_root = 0; prach_root = 0;
prach_config_index = 0; prach_config_index = 0;
prach_high_speed = "DISABLE"; prach_high_speed = "DISABLE";
...@@ -50,7 +50,7 @@ eNBs = ...@@ -50,7 +50,7 @@ eNBs =
pucch_nRB_CQI = 1; pucch_nRB_CQI = 1;
pucch_nCS_AN = 0; pucch_nCS_AN = 0;
pucch_n1_AN = 32; pucch_n1_AN = 32;
pdsch_referenceSignalPower = -60; pdsch_referenceSignalPower = -30;
pdsch_p_b = 0; pdsch_p_b = 0;
pusch_n_SB = 1; pusch_n_SB = 1;
pusch_enable64QAM = "DISABLE"; pusch_enable64QAM = "DISABLE";
...@@ -68,7 +68,7 @@ eNBs = ...@@ -68,7 +68,7 @@ eNBs =
srs_ackNackST =; srs_ackNackST =;
srs_MaxUpPts =;*/ srs_MaxUpPts =;*/
pusch_p0_Nominal = -90; pusch_p0_Nominal = -70;
pusch_alpha = "AL1"; pusch_alpha = "AL1";
pucch_p0_Nominal = -96; pucch_p0_Nominal = -96;
msg3_delta_Preamble = 6; msg3_delta_Preamble = 6;
...@@ -137,7 +137,7 @@ eNBs = ...@@ -137,7 +137,7 @@ eNBs =
////////// MME parameters: ////////// MME parameters:
mme_ip_address = ( { ipv4 = "10.224.20.11"; mme_ip_address = ( { ipv4 = "127.0.0.20";
ipv6 = "fe80::6a6:9555:ded:fafa/64"; ipv6 = "fe80::6a6:9555:ded:fafa/64";
active = "yes"; active = "yes";
preference = "ipv4"; preference = "ipv4";
...@@ -145,16 +145,16 @@ eNBs = ...@@ -145,16 +145,16 @@ eNBs =
); );
rrh_gw_config = ({ rrh_gw_config = ({
local_if_name = "eth0"; local_if_name = "eno1";
remote_address = "iris,0205"; remote_address = "iris,100.0.0.101";
local_address = "10.224.20.40"; local_address = "10.0.0.108";
local_port = 50000; #for raw option local port must be the same to remote local_port = 50000; #for raw option local port must be the same to remote
remote_port = 50000; remote_port = 50000;
rrh_gw_active = "yes"; rrh_gw_active = "yes";
tr_preference = "raw"; tr_preference = "raw";
rf_preference = "iris030"; rf_preference = "iris030";
iq_txshift = 4; iq_txshift = 4;
tx_sample_advance = -40; tx_sample_advance = 60;
tx_scheduling_advance = 9; tx_scheduling_advance = 9;
if_compression = "alaw"; if_compression = "alaw";
} }
...@@ -162,16 +162,10 @@ rrh_gw_config = ({ ...@@ -162,16 +162,10 @@ rrh_gw_config = ({
NETWORK_INTERFACES : NETWORK_INTERFACES :
{ {
#ENB_INTERFACE_NAME_FOR_S1_MME = "eth1"; ENB_INTERFACE_NAME_FOR_S1_MME = "lo";
#ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.146/24"; ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.10/8";
#ENB_INTERFACE_NAME_FOR_S1U = "eth1"; ENB_INTERFACE_NAME_FOR_S1U = "lo";
#ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.146/24"; ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.10/8";
#ENB_PORT_FOR_S1U = 2152; # Spec 2152
ENB_INTERFACE_NAME_FOR_S1_MME = "enp1s0f0";
ENB_IPV4_ADDRESS_FOR_S1_MME = "10.224.20.35/26";
ENB_INTERFACE_NAME_FOR_S1U = "enp1s0f0";
ENB_IPV4_ADDRESS_FOR_S1U = "10.224.20.35/26";
ENB_PORT_FOR_S1U = 2152; # Spec 2152 ENB_PORT_FOR_S1U = 2152; # Spec 2152
}; };
...@@ -180,9 +174,9 @@ rrh_gw_config = ({ ...@@ -180,9 +174,9 @@ rrh_gw_config = ({
global_log_level ="info"; global_log_level ="info";
global_log_verbosity ="medium"; global_log_verbosity ="medium";
hw_log_level ="info"; hw_log_level ="info";
hw_log_verbosity ="medium"; hw_log_verbosity ="high";
phy_log_level ="info"; phy_log_level ="info";
phy_log_verbosity ="medium"; phy_log_verbosity ="high";
mac_log_level ="info"; mac_log_level ="info";
mac_log_verbosity ="high"; mac_log_verbosity ="high";
rlc_log_level ="info"; rlc_log_level ="info";
......
...@@ -17,7 +17,7 @@ eNBs = ...@@ -17,7 +17,7 @@ eNBs =
mobile_country_code = "208"; mobile_country_code = "208";
mobile_network_code = "94"; mobile_network_code = "92";
////////// Physical parameters: ////////// Physical parameters:
...@@ -39,7 +39,7 @@ eNBs = ...@@ -39,7 +39,7 @@ eNBs =
nb_antenna_ports = 1; nb_antenna_ports = 1;
nb_antennas_tx = 1; nb_antennas_tx = 1;
nb_antennas_rx = 1; nb_antennas_rx = 1;
tx_gain = 90; tx_gain = 110;
rx_gain = 125; rx_gain = 125;
prach_root = 0; prach_root = 0;
prach_config_index = 0; prach_config_index = 0;
...@@ -137,20 +137,36 @@ eNBs = ...@@ -137,20 +137,36 @@ eNBs =
////////// MME parameters: ////////// MME parameters:
mme_ip_address = ( { ipv4 = "192.168.12.70"; mme_ip_address = ( { ipv4 = "127.0.0.20";
ipv6 = "192:168:30::17"; ipv6 = "192:168:30::17";
active = "yes"; active = "yes";
preference = "ipv4"; preference = "ipv4";
} }
); );
rrh_gw_config = ({
local_if_name = "eno1";
remote_address = "iris,RF3C000052";
local_address = "10.0.0.108";
local_port = 50000; #for raw option local port must be the same to remote
remote_port = 50000;
rrh_gw_active = "yes";
tr_preference = "raw";
rf_preference = "iris030";
iq_txshift = 4;
tx_sample_advance = -40;
tx_scheduling_advance = 9;
if_compression = "alaw";
}
);
NETWORK_INTERFACES : NETWORK_INTERFACES :
{ {
ENB_INTERFACE_NAME_FOR_S1_MME = "eth1"; ENB_INTERFACE_NAME_FOR_S1_MME = "lo";
ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.146/24"; ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.10/8";
ENB_INTERFACE_NAME_FOR_S1U = "eth1"; ENB_INTERFACE_NAME_FOR_S1U = "lo";
ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.146/24"; ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.10/8";
ENB_PORT_FOR_S1U = 2152; # Spec 2152 ENB_PORT_FOR_S1U = 2152; # Spec 2152
}; };
...@@ -159,9 +175,9 @@ eNBs = ...@@ -159,9 +175,9 @@ eNBs =
global_log_level ="info"; global_log_level ="info";
global_log_verbosity ="medium"; global_log_verbosity ="medium";
hw_log_level ="info"; hw_log_level ="info";
hw_log_verbosity ="medium"; hw_log_verbosity ="high";
phy_log_level ="info"; phy_log_level ="info";
phy_log_verbosity ="medium"; phy_log_verbosity ="high";
mac_log_level ="info"; mac_log_level ="info";
mac_log_verbosity ="high"; mac_log_verbosity ="high";
rlc_log_level ="info"; rlc_log_level ="info";
......
...@@ -23,6 +23,11 @@ eNBs = ...@@ -23,6 +23,11 @@ eNBs =
component_carriers = ( component_carriers = (
{ {
node_function = "eNodeB_3GPP";
node_timing = "synch_to_ext_device";
node_synch_ref = 0;
frame_type = "FDD"; frame_type = "FDD";
tdd_config = 3; tdd_config = 3;
tdd_config_s = 0; tdd_config_s = 0;
...@@ -33,9 +38,10 @@ eNBs = ...@@ -33,9 +38,10 @@ eNBs =
Nid_cell = 0; Nid_cell = 0;
N_RB_DL = 25; N_RB_DL = 25;
Nid_cell_mbsfn = 0; Nid_cell_mbsfn = 0;
nb_antenna_ports = 1;
nb_antennas_tx = 1; nb_antennas_tx = 1;
nb_antennas_rx = 1; nb_antennas_rx = 1;
tx_gain = 90; tx_gain = 110;
rx_gain = 115; rx_gain = 115;
prach_root = 0; prach_root = 0;
prach_config_index = 0; prach_config_index = 0;
...@@ -97,6 +103,7 @@ eNBs = ...@@ -97,6 +103,7 @@ eNBs =
ue_TimersAndConstants_t311 = 10000; ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20; ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1; ue_TimersAndConstants_n311 = 1;
ue_TransmissionMode = 1;
} }
); );
...@@ -132,20 +139,41 @@ eNBs = ...@@ -132,20 +139,41 @@ eNBs =
}; };
////////// MME parameters: ////////// MME parameters:
mme_ip_address = ( { ipv4 = "192.168.13.11"; mme_ip_address = ( { ipv4 = "127.0.0.20";
ipv6 = "192:168:30::17"; ipv6 = "192:168:30::17";
active = "yes"; active = "yes";
preference = "ipv4"; preference = "ipv4";
} }
); );
rrh_gw_config = ({
local_if_name = "eno1";
remote_address = "iris,RF3C000052";
local_address = "10.0.0.108";
local_port = 50000; #for raw option local port must be the same to remote
remote_port = 50000;
rrh_gw_active = "yes";
tr_preference = "raw";
rf_preference = "iris030";
iq_txshift = 4;
tx_sample_advance = -40;
tx_scheduling_advance = 9;
if_compression = "alaw";
}
);
NETWORK_INTERFACES : NETWORK_INTERFACES :
{ {
ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; ENB_INTERFACE_NAME_FOR_S1_MME = "lo";
ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.13.10/24"; ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.10/8";
ENB_INTERFACE_NAME_FOR_S1U = "eth0"; ENB_INTERFACE_NAME_FOR_S1U = "lo";
ENB_IPV4_ADDRESS_FOR_S1U = "192.168.13.10/24"; ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.10/8";
ENB_PORT_FOR_S1U = 2152; # Spec 2152 ENB_PORT_FOR_S1U = 2152; # Spec 2152
}; };
......
...@@ -39,8 +39,8 @@ eNBs = ...@@ -39,8 +39,8 @@ eNBs =
nb_antenna_ports = 1; nb_antenna_ports = 1;
nb_antennas_tx = 1; nb_antennas_tx = 1;
nb_antennas_rx = 1; nb_antennas_rx = 1;
tx_gain = 52; tx_gain = 52; # [~50 for DEV-FE, ~30 for CBRS-FE]
rx_gain = 110; rx_gain = 115; # [115 for DEV-FE, 90 for CBRS-FE]
prach_root = 0; prach_root = 0;
prach_config_index = 0; prach_config_index = 0;
prach_high_speed = "DISABLE"; prach_high_speed = "DISABLE";
...@@ -137,7 +137,7 @@ eNBs = ...@@ -137,7 +137,7 @@ eNBs =
////////// MME parameters: ////////// MME parameters:
mme_ip_address = ( { ipv4 = "10.224.20.11"; mme_ip_address = ( { ipv4 = "127.0.0.20";
ipv6 = "fe80::6a6:9555:ded:fafa"; ipv6 = "fe80::6a6:9555:ded:fafa";
active = "yes"; active = "yes";
preference = "ipv4"; preference = "ipv4";
...@@ -145,9 +145,9 @@ eNBs = ...@@ -145,9 +145,9 @@ eNBs =
); );
rrh_gw_config = ({ rrh_gw_config = ({
local_if_name = "eth0"; local_if_name = "eno1";
remote_address = "iris,0205"; remote_address = "iris,RF3C000052";
local_address = "10.224.20.47" local_address = "100.0.0.108"
local_port = 50000; #for raw option local port must be the same to remote local_port = 50000; #for raw option local port must be the same to remote
remote_port = 50000; remote_port = 50000;
rrh_gw_active = "yes"; rrh_gw_active = "yes";
...@@ -161,10 +161,10 @@ rrh_gw_config = ({ ...@@ -161,10 +161,10 @@ rrh_gw_config = ({
NETWORK_INTERFACES : NETWORK_INTERFACES :
{ {
ENB_INTERFACE_NAME_FOR_S1_MME = "enp1s0f0"; ENB_INTERFACE_NAME_FOR_S1_MME = "lo";
ENB_IPV4_ADDRESS_FOR_S1_MME = "10.224.20.35/26"; ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.10/8";
ENB_INTERFACE_NAME_FOR_S1U = "enp1s0f0"; ENB_INTERFACE_NAME_FOR_S1U = "lo";
ENB_IPV4_ADDRESS_FOR_S1U = "10.224.20.35/26"; ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.10/8";
ENB_PORT_FOR_S1U = 2152; # Spec 2152 ENB_PORT_FOR_S1U = 2152; # Spec 2152
#ENB_INTERFACE_NAME_FOR_S1_MME = "enp1s0f0"; #ENB_INTERFACE_NAME_FOR_S1_MME = "enp1s0f0";
...@@ -183,7 +183,7 @@ rrh_gw_config = ({ ...@@ -183,7 +183,7 @@ rrh_gw_config = ({
phy_log_level ="info"; phy_log_level ="info";
phy_log_verbosity ="medium"; phy_log_verbosity ="medium";
mac_log_level ="info"; mac_log_level ="info";
mac_log_verbosity ="high"; mac_log_verbosity ="medium";
rlc_log_level ="info"; rlc_log_level ="info";
rlc_log_verbosity ="medium"; rlc_log_verbosity ="medium";
pdcp_log_level ="info"; pdcp_log_level ="info";
......
...@@ -17,7 +17,7 @@ eNBs = ...@@ -17,7 +17,7 @@ eNBs =
mobile_country_code = "208"; mobile_country_code = "208";
mobile_network_code = "94"; mobile_network_code = "92";
////////// Physical parameters: ////////// Physical parameters:
...@@ -33,13 +33,13 @@ eNBs = ...@@ -33,13 +33,13 @@ eNBs =
eutra_band = 7; eutra_band = 7;
downlink_frequency = 2660000000L; downlink_frequency = 2660000000L;
uplink_frequency_offset = -120000000; uplink_frequency_offset = -120000000;
Nid_cell = 0; Nid_cell = 66;
N_RB_DL = 25; N_RB_DL = 25;
Nid_cell_mbsfn = 0; Nid_cell_mbsfn = 0;
nb_antenna_ports = 1; nb_antenna_ports = 1;
nb_antennas_tx = 1; nb_antennas_tx = 1;
nb_antennas_rx = 1; nb_antennas_rx = 1;
tx_gain = 90; tx_gain = 110;
rx_gain = 125; rx_gain = 125;
prach_root = 0; prach_root = 0;
prach_config_index = 0; prach_config_index = 0;
...@@ -137,20 +137,40 @@ eNBs = ...@@ -137,20 +137,40 @@ eNBs =
////////// MME parameters: ////////// MME parameters:
mme_ip_address = ( { ipv4 = "192.168.12.70"; mme_ip_address = ( { ipv4 = "127.0.0.20";
ipv6 = "192:168:30::17"; ipv6 = "192:168:30::17";
active = "yes"; active = "yes";
preference = "ipv4"; preference = "ipv4";
} }
); );
rrh_gw_config = ({
local_if_name = "eno1";
remote_address = "iris,RF3C000052";
local_address = "10.0.0.108";
local_port = 50000; #for raw option local port must be the same to remote
remote_port = 50000;
rrh_gw_active = "yes";
tr_preference = "raw";
rf_preference = "iris030";
iq_txshift = 4;
tx_sample_advance = -40;
tx_scheduling_advance = 9;
if_compression = "alaw";
}
);
NETWORK_INTERFACES : NETWORK_INTERFACES :
{ {
ENB_INTERFACE_NAME_FOR_S1_MME = "eth1"; ENB_INTERFACE_NAME_FOR_S1_MME = "lo";
ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.146/24"; ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.10/8";
ENB_INTERFACE_NAME_FOR_S1U = "eth1"; ENB_INTERFACE_NAME_FOR_S1U = "lo";
ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.146/24"; ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.10/8";
ENB_PORT_FOR_S1U = 2152; # Spec 2152 ENB_PORT_FOR_S1U = 2152; # Spec 2152
}; };
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
* \warning * \warning
*/ */
#define _GNU_SOURCE #define _GNU_SOURCE
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
...@@ -53,6 +54,7 @@ ...@@ -53,6 +54,7 @@
#include "PHY/types.h" #include "PHY/types.h"
#include "PHY/defs.h" #include "PHY/defs.h"
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all #undef MALLOC //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 //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
...@@ -79,6 +81,7 @@ ...@@ -79,6 +81,7 @@
#include "PHY/TOOLS/smbv.h" #include "PHY/TOOLS/smbv.h"
unsigned short config_frames[4] = {2,9,11,13}; unsigned short config_frames[4] = {2,9,11,13};
#endif #endif
#include "UTIL/LOG/log_extern.h" #include "UTIL/LOG/log_extern.h"
#include "UTIL/OTG/otg_tx.h" #include "UTIL/OTG/otg_tx.h"
#include "UTIL/OTG/otg_externs.h" #include "UTIL/OTG/otg_externs.h"
...@@ -89,7 +92,9 @@ unsigned short config_frames[4] = {2,9,11,13}; ...@@ -89,7 +92,9 @@ unsigned short config_frames[4] = {2,9,11,13};
//#include "PHY/TOOLS/time_meas.h" //#include "PHY/TOOLS/time_meas.h"
#ifndef OPENAIR2 #ifndef OPENAIR2
#include "UTIL/OTG/otg_extern.h" #include "UTIL/OTG/otg_extern.h"
#endif #endif
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
...@@ -141,7 +146,7 @@ time_stats_t softmodem_stats_rx_sf; // total rx time ...@@ -141,7 +146,7 @@ time_stats_t softmodem_stats_rx_sf; // total rx time
uint8_t seqno; //sequence number uint8_t seqno; //sequence number
static int time_offset[4] = {0,0,0,0}; static int time_offset[4] = {0, 0, 0, 0};
/* mutex, cond and variable to serialize phy proc TX calls /* mutex, cond and variable to serialize phy proc TX calls
* (this mechanism may be relaxed in the future for better * (this mechanism may be relaxed in the future for better
...@@ -155,9 +160,10 @@ static struct { ...@@ -155,9 +160,10 @@ static struct {
extern double cpuf; extern double cpuf;
void exit_fun(const char* s); void exit_fun(const char *s);
void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[], int nb_inst, eth_params_t *, int);
void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst,eth_params_t *,int);
void stop_eNB(int nb_inst); void stop_eNB(int nb_inst);
...@@ -221,20 +227,20 @@ static inline void thread_top_init(char *thread_name, ...@@ -221,20 +227,20 @@ static inline void thread_top_init(char *thread_name,
/* 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) {
...@@ -248,12 +254,13 @@ static inline void thread_top_init(char *thread_name, ...@@ -248,12 +254,13 @@ static inline void thread_top_init(char *thread_name,
exit_fun("Error getting thread priority"); exit_fun("Error getting thread priority");
} }
LOG_I(HW, "[SCHED][eNB] %s started on CPU %d TID %ld, sched_policy = %s , priority = %d, CPU Affinity=%s \n",thread_name,sched_getcpu(),gettid(), LOG_I(HW, "[SCHED][eNB] %s started on CPU %d TID %ld, sched_policy = %s , priority = %d, CPU Affinity=%s \n",
thread_name, 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
...@@ -263,37 +270,36 @@ static inline void thread_top_init(char *thread_name, ...@@ -263,37 +270,36 @@ static inline void thread_top_init(char *thread_name,
static inline void wait_sync(char *thread_name) { static inline void wait_sync(char *thread_name) {
printf( "waiting for sync (%s)\n",thread_name); printf("waiting for sync (%s)\n", thread_name);
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 (%s)\n", thread_name); printf("got sync (%s)\n", thread_name); fflush(stdout);
} }
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; unsigned int aa, slot_offset;
//int dummy_tx_b[7680*4] __attribute__((aligned(32))); //int dummy_tx_b[7680*4] __attribute__((aligned(32)));
int i, tx_offset; int i, tx_offset;
//int slot_sizeF = (phy_vars_eNB->frame_parms.ofdm_symbol_size)* ((phy_vars_eNB->frame_parms.Ncp==1) ? 6 : 7); //int slot_sizeF = (phy_vars_eNB->frame_parms.ofdm_symbol_size)* ((phy_vars_eNB->frame_parms.Ncp==1) ? 6 : 7);
int len; int len;
//int slot_offset_F = (subframe<<1)*slot_sizeF; //int slot_offset_F = (subframe<<1)*slot_sizeF;
slot_offset = subframe*phy_vars_eNB->frame_parms.samples_per_tti; slot_offset = subframe * phy_vars_eNB->frame_parms.samples_per_tti;
if ((subframe_select(&phy_vars_eNB->frame_parms,subframe)==SF_DL)|| if ((subframe_select(&phy_vars_eNB->frame_parms, subframe) == SF_DL) ||
((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);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_OFDM_MODULATION,1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_OFDM_MODULATION, 1);
/*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++) {
...@@ -326,18 +332,18 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) ...@@ -326,18 +332,18 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
}*/ }*/
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++) {
do_OFDM_mod_symbol(&phy_vars_eNB->common_vars, do_OFDM_mod_symbol(&phy_vars_eNB->common_vars,
0, 0,
subframe<<1, subframe << 1,
&phy_vars_eNB->frame_parms, &phy_vars_eNB->frame_parms,
aa); aa);
// 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) {
do_OFDM_mod_symbol(&phy_vars_eNB->common_vars, do_OFDM_mod_symbol(&phy_vars_eNB->common_vars,
0, 0,
1+(subframe<<1), 1 + (subframe << 1),
&phy_vars_eNB->frame_parms, &phy_vars_eNB->frame_parms,
aa); aa);
} }
...@@ -359,13 +365,13 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) ...@@ -359,13 +365,13 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
thread_pool_join(phy_vars_eNB->pool); thread_pool_join(phy_vars_eNB->pool);
} }
*/ */
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_OFDM_MODULATION,0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_OFDM_MODULATION, 0);
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 S-subframe generate first slot only // if S-subframe generate first slot only
if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_S) if (subframe_select(&phy_vars_eNB->frame_parms, subframe) == SF_S)
len = phy_vars_eNB->frame_parms.samples_per_tti>>1; len = phy_vars_eNB->frame_parms.samples_per_tti >> 1;
else else
len = phy_vars_eNB->frame_parms.samples_per_tti; len = phy_vars_eNB->frame_parms.samples_per_tti;
/* /*
...@@ -375,45 +381,49 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) ...@@ -375,45 +381,49 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
dummy_tx_b[i+2] = 0xff00; dummy_tx_b[i+2] = 0xff00;
dummy_tx_b[i+3] = 0xff000000; dummy_tx_b[i+3] = 0xff000000;
}*/ }*/
for (i=0; i<len; i++) { for (i = 0; i < len; i++) {
tx_offset = (int)slot_offset+time_offset[aa%4]+i; tx_offset = (int) slot_offset + time_offset[aa % 4] + i;
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;
/* ((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[0] = ((short*)dummy_tx_b)[2*i]<<openair0_cfg[0].iq_txshift; /* ((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[0] = ((short*)dummy_tx_b)[2*i]<<openair0_cfg[0].iq_txshift;
((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[1] = ((short*)dummy_tx_b)[2*i+1]<<openair0_cfg[0].iq_txshift; */ ((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[1] = ((short*)dummy_tx_b)[2*i+1]<<openair0_cfg[0].iq_txshift; */
((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[0] = ((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[0]<<openair0_cfg[0].iq_txshift; ((short *) &phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[0] =
((short *) &phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[0]
<< openair0_cfg[0].iq_txshift;
((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[1] = ((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[1]<<openair0_cfg[0].iq_txshift; ((short *) &phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[1] =
((short *) &phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[1]
<< openair0_cfg[0].iq_txshift;
} }
// 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) {
for (i=0; i<len; i++) { for (i = 0; i < len; i++) {
phy_vars_eNB->common_vars.txdata[0][aa][tx_offset++] = 0x00010001; phy_vars_eNB->common_vars.txdata[0][aa][tx_offset++] = 0x00010001;
} }
} }
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%4]+i-phy_vars_eNB->N_TA_offset; tx_offset = (int) slot_offset + time_offset[aa % 4] + i - phy_vars_eNB->N_TA_offset;
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;
} }
...@@ -423,18 +433,18 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) ...@@ -423,18 +433,18 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
} }
void tx_fh_if5(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { void tx_fh_if5(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, proc->timestamp_tx&0xffffffff ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, proc->timestamp_tx & 0xffffffff);
send_IF5(eNB, proc->timestamp_tx, proc->subframe_tx, &seqno, IF5_RRH_GW_DL); send_IF5(eNB, proc->timestamp_tx, proc->subframe_tx, &seqno, IF5_RRH_GW_DL);
} }
void tx_fh_if5_mobipass(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { void tx_fh_if5_mobipass(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, proc->timestamp_tx&0xffffffff ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, proc->timestamp_tx & 0xffffffff);
send_IF5(eNB, proc->timestamp_tx, proc->subframe_tx, &seqno, IF5_MOBIPASS); send_IF5(eNB, proc->timestamp_tx, proc->subframe_tx, &seqno, IF5_MOBIPASS);
} }
void tx_fh_if4p5(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { void tx_fh_if4p5(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc) {
send_IF4p5(eNB,proc->frame_tx, proc->subframe_tx, IF4p5_PDLFFT, 0); send_IF4p5(eNB, proc->frame_tx, proc->subframe_tx, IF4p5_PDLFFT, 0);
} }
void proc_tx_high0(PHY_VARS_eNB *eNB, void proc_tx_high0(PHY_VARS_eNB *eNB,
...@@ -444,10 +454,11 @@ void proc_tx_high0(PHY_VARS_eNB *eNB, ...@@ -444,10 +454,11 @@ void proc_tx_high0(PHY_VARS_eNB *eNB,
int offset = proc == &eNB->proc.proc_rxtx[0] ? 0 : 1; int offset = proc == &eNB->proc.proc_rxtx[0] ? 0 : 1;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB+offset, proc->frame_tx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB + offset, proc->frame_tx);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB+offset, proc->subframe_tx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB + offset,
proc->subframe_tx);
phy_procedures_eNB_TX(eNB,proc,r_type,rn,1); phy_procedures_eNB_TX(eNB, proc, r_type, rn, 1);
/* 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) {
...@@ -471,10 +482,10 @@ void proc_tx_high(PHY_VARS_eNB *eNB, ...@@ -471,10 +482,10 @@ void proc_tx_high(PHY_VARS_eNB *eNB,
// do PHY high // do PHY high
proc_tx_high0(eNB,proc,r_type,rn); proc_tx_high0(eNB, proc, r_type, rn);
// if TX fronthaul go ahead // if TX fronthaul go ahead
if (eNB->tx_fh) eNB->tx_fh(eNB,proc); if (eNB->tx_fh) eNB->tx_fh(eNB, proc);
} }
...@@ -485,11 +496,11 @@ void proc_tx_full(PHY_VARS_eNB *eNB, ...@@ -485,11 +496,11 @@ void proc_tx_full(PHY_VARS_eNB *eNB,
// do PHY high // do PHY high
proc_tx_high0(eNB,proc,r_type,rn); proc_tx_high0(eNB, proc, r_type, rn);
// do OFDM modulation // do OFDM modulation
do_OFDM_mod_rt(proc->subframe_tx,eNB); do_OFDM_mod_rt(proc->subframe_tx, eNB);
// if TX fronthaul go ahead // if TX fronthaul go ahead
if (eNB->tx_fh) eNB->tx_fh(eNB,proc); if (eNB->tx_fh) eNB->tx_fh(eNB, proc);
/* /*
if (proc->frame_tx>1000) { if (proc->frame_tx>1000) {
...@@ -509,34 +520,36 @@ void proc_tx_rru_if4p5(PHY_VARS_eNB *eNB, ...@@ -509,34 +520,36 @@ void proc_tx_rru_if4p5(PHY_VARS_eNB *eNB,
relaying_type_t r_type, relaying_type_t r_type,
PHY_VARS_RN *rn) { PHY_VARS_RN *rn) {
uint32_t symbol_number=0; uint32_t symbol_number = 0;
uint32_t symbol_mask, symbol_mask_full; uint32_t symbol_mask, symbol_mask_full;
uint16_t packet_type; uint16_t packet_type;
int offset = proc == &eNB->proc.proc_rxtx[0] ? 0 : 1; int offset = proc == &eNB->proc.proc_rxtx[0] ? 0 : 1;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB+offset, proc->frame_tx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB + offset, proc->frame_tx);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB+offset, proc->subframe_tx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB + offset,
proc->subframe_tx);
/// **** recv_IF4 of txdataF from RCC **** /// /// **** recv_IF4 of txdataF from RCC **** ///
symbol_number = 0; symbol_number = 0;
symbol_mask = 0; symbol_mask = 0;
symbol_mask_full = (1<<eNB->frame_parms.symbols_per_tti)-1; symbol_mask_full = (1 << eNB->frame_parms.symbols_per_tti) - 1;
do { do {
recv_IF4p5(eNB, &proc->frame_tx, &proc->subframe_tx, &packet_type, &symbol_number); recv_IF4p5(eNB, &proc->frame_tx, &proc->subframe_tx, &packet_type, &symbol_number);
symbol_mask = symbol_mask | (1<<symbol_number); symbol_mask = symbol_mask | (1 << symbol_number);
} while (symbol_mask != symbol_mask_full); } while (symbol_mask != symbol_mask_full);
do_OFDM_mod_rt(proc->subframe_tx, eNB); do_OFDM_mod_rt(proc->subframe_tx, eNB);
} }
void proc_tx_rru_if5(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { void proc_tx_rru_if5(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc) {
int offset = proc == &eNB->proc.proc_rxtx[0] ? 0 : 1; int offset = proc == &eNB->proc.proc_rxtx[0] ? 0 : 1;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB+offset, proc->frame_tx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB + offset, proc->frame_tx);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB+offset, proc->subframe_tx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB + offset,
proc->subframe_tx);
/// **** recv_IF5 of txdata from BBU **** /// /// **** recv_IF5 of txdata from BBU **** ///
recv_IF5(eNB, &proc->timestamp_tx, proc->subframe_tx, IF5_RRH_GW_DL); recv_IF5(eNB, &proc->timestamp_tx, proc->subframe_tx, IF5_RRH_GW_DL);
} }
...@@ -545,13 +558,13 @@ int wait_CCs(eNB_rxtx_proc_t *proc) { ...@@ -545,13 +558,13 @@ int wait_CCs(eNB_rxtx_proc_t *proc) {
struct timespec wait; struct timespec wait;
wait.tv_sec=0; wait.tv_sec = 0;
wait.tv_nsec=5000000L; wait.tv_nsec = 5000000L;
if (pthread_mutex_timedlock(&sync_phy_proc.mutex_phy_proc_tx,&wait) != 0) { if (pthread_mutex_timedlock(&sync_phy_proc.mutex_phy_proc_tx, &wait) != 0) {
LOG_E(PHY, "[SCHED][eNB] error locking PHY proc mutex for eNB TX\n"); LOG_E(PHY, "[SCHED][eNB] error locking PHY proc mutex for eNB TX\n");
exit_fun("nothing to add"); exit_fun("nothing to add");
return(-1); return (-1);
} }
// wait for our turn or oai_exit // wait for our turn or oai_exit
...@@ -563,27 +576,28 @@ int wait_CCs(eNB_rxtx_proc_t *proc) { ...@@ -563,27 +576,28 @@ int wait_CCs(eNB_rxtx_proc_t *proc) {
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\n"); LOG_E(PHY, "[SCHED][eNB] error unlocking PHY proc mutex for eNB TX\n");
exit_fun("nothing to add"); exit_fun("nothing to add");
return(-1); return (-1);
} }
return(0); return (0);
} }
static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_name) { static inline int rxtx(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, char *thread_name) {
start_meas(&softmodem_stats_rxtx_sf); start_meas(&softmodem_stats_rxtx_sf);
// **************************************** // ****************************************
// TDD workaround for EXMIMO card // TDD workaround for EXMIMO card
if ((eNB->rfdevice.openair0_cfg->duplex_mode == duplex_mode_TDD_workaround) && (eNB->frame_parms.frame_type == TDD) && subframe_select(&eNB->frame_parms,proc->subframe_rx)==SF_UL) { if ((eNB->rfdevice.openair0_cfg->duplex_mode == duplex_mode_TDD_workaround) &&
remove_1_4_fs(eNB,proc->subframe_rx<<1); (eNB->frame_parms.frame_type == TDD) && subframe_select(&eNB->frame_parms, proc->subframe_rx) == SF_UL) {
remove_1_4_fs(eNB,1+(proc->subframe_rx<<1)); remove_1_4_fs(eNB, proc->subframe_rx << 1);
remove_1_4_fs(eNB, 1 + (proc->subframe_rx << 1));
} }
// Common RX procedures subframe n // Common RX procedures subframe n
phy_procedures_eNB_common_RX(eNB); phy_procedures_eNB_common_RX(eNB);
// UE-specific RX processing for subframe n // UE-specific RX processing for subframe n
if (eNB->proc_uespec_rx) eNB->proc_uespec_rx(eNB, proc, no_relay ); if (eNB->proc_uespec_rx) eNB->proc_uespec_rx(eNB, proc, no_relay);
// ***************************************** // *****************************************
// TX processing for subframe n+4 // TX processing for subframe n+4
...@@ -592,15 +606,15 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam ...@@ -592,15 +606,15 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam
// ***************************************** // *****************************************
//if (wait_CCs(proc)<0) return(-1); //if (wait_CCs(proc)<0) return(-1);
if (oai_exit) return(-1); if (oai_exit) return (-1);
if (eNB->proc_tx) eNB->proc_tx(eNB, proc, no_relay, NULL ); if (eNB->proc_tx) eNB->proc_tx(eNB, proc, no_relay, NULL);
if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) return(-1); if (release_thread(&proc->mutex_rxtx, &proc->instance_cnt_rxtx, thread_name) < 0) return (-1);
stop_meas( &softmodem_stats_rxtx_sf ); stop_meas(&softmodem_stats_rxtx_sf);
return(0); return (0);
} }
/*! /*!
...@@ -608,11 +622,11 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam ...@@ -608,11 +622,11 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam
* \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;
PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id]; PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id];
char thread_name[100]; char thread_name[100];
...@@ -622,27 +636,28 @@ static void* eNB_thread_rxtx( void* param ) { ...@@ -622,27 +636,28 @@ static void* eNB_thread_rxtx( void* param ) {
eNB_thread_rxtx_status = 0; eNB_thread_rxtx_status = 0;
sprintf(thread_name,"RXn_TXnp4_%d\n",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1); sprintf(thread_name, "RXn_TXnp4_%d\n", &eNB->proc.proc_rxtx[0] == proc ? 0 : 1);
thread_top_init(thread_name,1,850000L,1000000L,2000000L); thread_top_init(thread_name, 1, 850000L, 1000000L, 2000000L);
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 (wait_on_condition(&proc->mutex_rxtx,&proc->cond_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break; if (wait_on_condition(&proc->mutex_rxtx, &proc->cond_rxtx, &proc->instance_cnt_rxtx, thread_name) < 0) break;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 1 );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0 + (proc->subframe_rx & 1),
1);
if (oai_exit) break; if (oai_exit) break;
if (rxtx(eNB,proc,thread_name) < 0) break; if (rxtx(eNB, proc, thread_name) < 0) break;
} // 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);
printf( "Exiting eNB thread RXn_TXnp4\n"); printf("Exiting eNB thread RXn_TXnp4\n");
eNB_thread_rxtx_status = 0; eNB_thread_rxtx_status = 0;
return &eNB_thread_rxtx_status; return &eNB_thread_rxtx_status;
...@@ -669,46 +684,45 @@ static void wait_system_ready (char *message, volatile int *start_flag) { ...@@ -669,46 +684,45 @@ static void wait_system_ready (char *message, volatile int *start_flag) {
// asynchronous UL with IF4p5 (RCC,RAU,eNodeB_BBU) // asynchronous UL with IF4p5 (RCC,RAU,eNodeB_BBU)
void fh_if5_asynch_UL(PHY_VARS_eNB *eNB,int *frame,int *subframe) { void fh_if5_asynch_UL(PHY_VARS_eNB *eNB, int *frame, int *subframe) {
eNB_proc_t *proc = &eNB->proc; eNB_proc_t *proc = &eNB->proc;
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
recv_IF5(eNB, &proc->timestamp_rx, *subframe, IF5_RRH_GW_UL); recv_IF5(eNB, &proc->timestamp_rx, *subframe, IF5_RRH_GW_UL);
proc->subframe_rx = (proc->timestamp_rx/fp->samples_per_tti)%10; proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti) % 10;
proc->frame_rx = (proc->timestamp_rx/(10*fp->samples_per_tti))&1023; proc->frame_rx = (proc->timestamp_rx / (10 * fp->samples_per_tti)) & 1023;
if (proc->first_rx != 0) { if (proc->first_rx != 0) {
proc->first_rx = 0; proc->first_rx = 0;
*subframe = proc->subframe_rx; *subframe = proc->subframe_rx;
*frame = proc->frame_rx; *frame = proc->frame_rx;
} } else {
else {
if (proc->subframe_rx != *subframe) { if (proc->subframe_rx != *subframe) {
LOG_E(PHY,"subframe_rx %d is not what we expect %d\n",proc->subframe_rx,*subframe); LOG_E(PHY, "subframe_rx %d is not what we expect %d\n", proc->subframe_rx, *subframe);
exit_fun("Exiting"); exit_fun("Exiting");
} }
if (proc->frame_rx != *frame) { if (proc->frame_rx != *frame) {
LOG_E(PHY,"subframe_rx %d is not what we expect %d\n",proc->frame_rx,*frame); LOG_E(PHY, "subframe_rx %d is not what we expect %d\n", proc->frame_rx, *frame);
exit_fun("Exiting"); exit_fun("Exiting");
} }
} }
} // eNodeB_3GPP_BBU } // eNodeB_3GPP_BBU
// asynchronous UL with IF4p5 (RCC,RAU,eNodeB_BBU) // asynchronous UL with IF4p5 (RCC,RAU,eNodeB_BBU)
void fh_if4p5_asynch_UL(PHY_VARS_eNB *eNB,int *frame,int *subframe) { void fh_if4p5_asynch_UL(PHY_VARS_eNB *eNB, int *frame, int *subframe) {
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
eNB_proc_t *proc = &eNB->proc; eNB_proc_t *proc = &eNB->proc;
uint16_t packet_type; uint16_t packet_type;
uint32_t symbol_number,symbol_mask,symbol_mask_full,prach_rx; uint32_t symbol_number, symbol_mask, symbol_mask_full, prach_rx;
symbol_number = 0; symbol_number = 0;
symbol_mask = 0; symbol_mask = 0;
symbol_mask_full = (1<<fp->symbols_per_tti)-1; symbol_mask_full = (1 << fp->symbols_per_tti) - 1;
prach_rx = 0; prach_rx = 0;
do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!! do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!!
...@@ -717,71 +731,69 @@ void fh_if4p5_asynch_UL(PHY_VARS_eNB *eNB,int *frame,int *subframe) { ...@@ -717,71 +731,69 @@ void fh_if4p5_asynch_UL(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
*frame = proc->frame_rx; *frame = proc->frame_rx;
*subframe = proc->subframe_rx; *subframe = proc->subframe_rx;
proc->first_rx = 0; proc->first_rx = 0;
} } else {
else {
if (proc->frame_rx != *frame) { if (proc->frame_rx != *frame) {
LOG_E(PHY,"frame_rx %d is not what we expect %d\n",proc->frame_rx,*frame); LOG_E(PHY, "frame_rx %d is not what we expect %d\n", proc->frame_rx, *frame);
exit_fun("Exiting"); exit_fun("Exiting");
} }
if (proc->subframe_rx != *subframe) { if (proc->subframe_rx != *subframe) {
LOG_E(PHY,"subframe_rx %d is not what we expect %d\n",proc->subframe_rx,*subframe); LOG_E(PHY, "subframe_rx %d is not what we expect %d\n", proc->subframe_rx, *subframe);
exit_fun("Exiting"); exit_fun("Exiting");
} }
} }
if (packet_type == IF4p5_PULFFT) { if (packet_type == IF4p5_PULFFT) {
symbol_mask = symbol_mask | (1<<symbol_number); symbol_mask = symbol_mask | (1 << symbol_number);
prach_rx = (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>0) ? 1 : 0; prach_rx = (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx) > 0) ? 1 : 0;
} else if (packet_type == IF4p5_PRACH) { } else if (packet_type == IF4p5_PRACH) {
prach_rx = 0; prach_rx = 0;
} }
} while( (symbol_mask != symbol_mask_full) || (prach_rx == 1)); } while ((symbol_mask != symbol_mask_full) || (prach_rx == 1));
} }
void fh_if5_asynch_DL(PHY_VARS_eNB *eNB,int *frame,int *subframe) { void fh_if5_asynch_DL(PHY_VARS_eNB *eNB, int *frame, int *subframe) {
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
eNB_proc_t *proc = &eNB->proc; eNB_proc_t *proc = &eNB->proc;
int subframe_tx,frame_tx; int subframe_tx, frame_tx;
openair0_timestamp timestamp_tx; openair0_timestamp timestamp_tx;
recv_IF5(eNB, &timestamp_tx, *subframe, IF5_RRH_GW_DL); recv_IF5(eNB, &timestamp_tx, *subframe, IF5_RRH_GW_DL);
// printf("Received subframe %d (TS %llu) from RCC\n",subframe_tx,timestamp_tx); // printf("Received subframe %d (TS %llu) from RCC\n",subframe_tx,timestamp_tx);
subframe_tx = (timestamp_tx/fp->samples_per_tti)%10; subframe_tx = (timestamp_tx / fp->samples_per_tti) % 10;
frame_tx = (timestamp_tx/(fp->samples_per_tti*10))&1023; frame_tx = (timestamp_tx / (fp->samples_per_tti * 10)) & 1023;
if (proc->first_tx != 0) { if (proc->first_tx != 0) {
*subframe = subframe_tx; *subframe = subframe_tx;
*frame = frame_tx; *frame = frame_tx;
proc->first_tx = 0; proc->first_tx = 0;
} } else {
else {
if (subframe_tx != *subframe) { if (subframe_tx != *subframe) {
LOG_E(PHY,"subframe_tx %d is not what we expect %d\n",subframe_tx,*subframe); LOG_E(PHY, "subframe_tx %d is not what we expect %d\n", subframe_tx, *subframe);
exit_fun("Exiting"); exit_fun("Exiting");
} }
if (frame_tx != *frame) { if (frame_tx != *frame) {
LOG_E(PHY,"frame_tx %d is not what we expect %d\n",frame_tx,*frame); LOG_E(PHY, "frame_tx %d is not what we expect %d\n", frame_tx, *frame);
exit_fun("Exiting"); exit_fun("Exiting");
} }
} }
} }
void fh_if4p5_asynch_DL(PHY_VARS_eNB *eNB,int *frame,int *subframe) { void fh_if4p5_asynch_DL(PHY_VARS_eNB *eNB, int *frame, int *subframe) {
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
eNB_proc_t *proc = &eNB->proc; eNB_proc_t *proc = &eNB->proc;
uint16_t packet_type; uint16_t packet_type;
uint32_t symbol_number,symbol_mask,symbol_mask_full; uint32_t symbol_number, symbol_mask, symbol_mask_full;
int subframe_tx,frame_tx; int subframe_tx, frame_tx;
symbol_number = 0; symbol_number = 0;
symbol_mask = 0; symbol_mask = 0;
symbol_mask_full = (1<<fp->symbols_per_tti)-1; symbol_mask_full = (1 << fp->symbols_per_tti) - 1;
do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!! do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!!
recv_IF4p5(eNB, &frame_tx, &subframe_tx, &packet_type, &symbol_number); recv_IF4p5(eNB, &frame_tx, &subframe_tx, &packet_type, &symbol_number);
...@@ -789,22 +801,20 @@ void fh_if4p5_asynch_DL(PHY_VARS_eNB *eNB,int *frame,int *subframe) { ...@@ -789,22 +801,20 @@ void fh_if4p5_asynch_DL(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
*frame = frame_tx; *frame = frame_tx;
*subframe = subframe_tx; *subframe = subframe_tx;
proc->first_tx = 0; proc->first_tx = 0;
} } else {
else {
if (frame_tx != *frame) { if (frame_tx != *frame) {
LOG_E(PHY,"frame_tx %d is not what we expect %d\n",frame_tx,*frame); LOG_E(PHY, "frame_tx %d is not what we expect %d\n", frame_tx, *frame);
exit_fun("Exiting"); exit_fun("Exiting");
} }
if (subframe_tx != *subframe) { if (subframe_tx != *subframe) {
LOG_E(PHY,"subframe_tx %d is not what we expect %d\n",subframe_tx,*subframe); LOG_E(PHY, "subframe_tx %d is not what we expect %d\n", subframe_tx, *subframe);
exit_fun("Exiting"); exit_fun("Exiting");
} }
} }
if (packet_type == IF4p5_PDLFFT) { if (packet_type == IF4p5_PDLFFT) {
symbol_mask = symbol_mask | (1<<symbol_number); symbol_mask = symbol_mask | (1 << symbol_number);
} } else {
else { LOG_E(PHY, "Illegal IF4p5 packet type (should only be IF4p5_PDLFFT%d\n", packet_type);
LOG_E(PHY,"Illegal IF4p5 packet type (should only be IF4p5_PDLFFT%d\n",packet_type);
exit_fun("Exiting"); exit_fun("Exiting");
} }
} while (symbol_mask != symbol_mask_full); } while (symbol_mask != symbol_mask_full);
...@@ -818,100 +828,110 @@ void fh_if4p5_asynch_DL(PHY_VARS_eNB *eNB,int *frame,int *subframe) { ...@@ -818,100 +828,110 @@ void fh_if4p5_asynch_DL(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
* \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_asynch_rxtx( void* param ) { static void *eNB_thread_asynch_rxtx(void *param) {
static int eNB_thread_asynch_rxtx_status; static int eNB_thread_asynch_rxtx_status;
eNB_proc_t *proc = (eNB_proc_t*)param; eNB_proc_t *proc = (eNB_proc_t *) param;
PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id]; PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id];
int subframe = 0, frame = 0;
int subframe=0, frame=0; thread_top_init("thread_asynch", 1, 870000L, 1000000L, 1000000L);
thread_top_init("thread_asynch",1,870000L,1000000L,1000000L);
// wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe
wait_sync("thread_asynch"); wait_sync("thread_asynch");
// wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe
printf( "waiting for devices (eNB_thread_asynch_rx)\n"); printf("waiting for devices (eNB_thread_asynch_rx)\n");
wait_on_condition(&proc->mutex_asynch_rxtx,&proc->cond_asynch_rxtx,&proc->instance_cnt_asynch_rxtx,"thread_asynch"); wait_on_condition(&proc->mutex_asynch_rxtx, &proc->cond_asynch_rxtx, &proc->instance_cnt_asynch_rxtx,
"thread_asynch");
printf( "devices ok (eNB_thread_asynch_rx)\n"); printf("devices ok (eNB_thread_asynch_rx)\n");
while (!oai_exit) { while (!oai_exit) {
if (oai_exit) break; if (oai_exit) break;
if (subframe==9) { if (subframe == 9) {
subframe=0; subframe = 0;
frame++; frame++;
frame&=1023; frame &= 1023;
} else { } else {
subframe++; subframe++;
} }
if (eNB->fh_asynch) eNB->fh_asynch(eNB,&frame,&subframe); if (eNB->fh_asynch) eNB->fh_asynch(eNB, &frame, &subframe);
else AssertFatal(1==0, "Unknown eNB->node_function %d",eNB->node_function); else AssertFatal(1 == 0, "Unknown eNB->node_function %d", eNB->node_function);
} }
eNB_thread_asynch_rxtx_status=0; eNB_thread_asynch_rxtx_status = 0;
return(&eNB_thread_asynch_rxtx_status); return (&eNB_thread_asynch_rxtx_status);
} }
void rx_rf(PHY_VARS_eNB *eNB, int *frame, int *subframe) {
void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
eNB_proc_t *proc = &eNB->proc; eNB_proc_t *proc = &eNB->proc;
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
void *rxp[fp->nb_antennas_rx],*txp[fp->nb_antennas_tx]; void *rxp[fp->nb_antennas_rx], *txp[fp->nb_antennas_tx];
unsigned int rxs,txs; unsigned int rxs, txs;
int i; int i;
int flag = 1; int flag = 1;
int tx_sfoffset = 3;//(eNB->single_thread_flag == 1) ? 3 : 3; int tx_sfoffset = 3;//(eNB->single_thread_flag == 1) ? 3 : 3;
//lte_subframe_t TXSF_type = subframe_select(fp,(proc->subframe_rx+tx_sfoffset)%10); lte_subframe_t TXSF_type = subframe_select(fp, (proc->subframe_rx + tx_sfoffset) % 10);
//if (proc->first_rx==0 && TXSF_type != SF_UL) { //if (proc->first_rx==0 && TXSF_type != SF_UL) {
if (proc->first_rx==0) { if (proc->first_rx == 0) {
// Transmit TX buffer based on timestamp from RX // Transmit TX buffer based on timestamp from RX
// printf("trx_write -> USRP TS %llu (sf %d)\n", (proc->timestamp_rx+(3*fp->samples_per_tti)),(proc->subframe_rx+2)%10); // printf("trx_write -> USRP TS %llu (sf %d)\n", (proc->timestamp_rx+(3*fp->samples_per_tti)),(proc->subframe_rx+2)%10);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_rx+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance)&0xffffffff ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); (proc->timestamp_rx + (tx_sfoffset * fp->samples_per_tti) -
openair0_cfg[0].tx_sample_advance) & 0xffffffff);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1);
// prepare tx buffer pointers // prepare tx buffer pointers
for (i=0; i<fp->nb_antennas_tx; i++) for (i = 0; i < fp->nb_antennas_tx; i++)
txp[i] = (void*)&eNB->common_vars.txdata[0][i][((proc->subframe_rx+tx_sfoffset)%10)*fp->samples_per_tti]; txp[i] = (void *) &eNB->common_vars.txdata[0][i][((proc->subframe_rx + tx_sfoffset) % 10) *
//lte_subframe_t SFnext_type = subframe_select(fp,(proc->subframe_rx+tx_sfoffset+1)%10); fp->samples_per_tti];
//if (SFnext_type == SF_UL) flag = 3; lte_subframe_t SFnext_type = subframe_select(fp, (proc->subframe_rx + tx_sfoffset + 1) % 10);
if (SFnext_type == SF_UL) flag = 3;
if (TXSF_type != SF_UL) {
txs = eNB->rfdevice.trx_write_func(&eNB->rfdevice, txs = eNB->rfdevice.trx_write_func(&eNB->rfdevice,
proc->timestamp_rx+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance, proc->timestamp_rx + (tx_sfoffset * fp->samples_per_tti) -
openair0_cfg[0].tx_sample_advance,
txp, txp,
fp->samples_per_tti, fp->samples_per_tti,
fp->nb_antennas_tx, fp->nb_antennas_tx,
flag); flag);
} else {
txs = eNB->rfdevice.trx_write_func(&eNB->rfdevice,
proc->timestamp_rx + (tx_sfoffset * fp->samples_per_tti) -
openair0_cfg[0].tx_sample_advance,
txp,
fp->samples_per_tti,
fp->nb_antennas_tx,
8);
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);
if (txs != fp->samples_per_tti) { if (txs != fp->samples_per_tti) {
LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, fp->samples_per_tti); LOG_E(PHY, "TX : Timeout (sent %d/%d)\n", txs, fp->samples_per_tti);
exit_fun( "problem transmitting samples" ); exit_fun("problem transmitting samples");
} }
} }
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 = eNB->rfdevice.trx_read_func(&eNB->rfdevice, rxs = eNB->rfdevice.trx_read_func(&eNB->rfdevice,
&(proc->timestamp_rx), &(proc->timestamp_rx),
...@@ -919,21 +939,25 @@ void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) { ...@@ -919,21 +939,25 @@ void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
fp->samples_per_tti, fp->samples_per_tti,
fp->nb_antennas_rx); fp->nb_antennas_rx);
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);
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;
proc->timestamp_tx = proc->timestamp_rx+(4*fp->samples_per_tti); proc->timestamp_tx = proc->timestamp_rx + (4 * fp->samples_per_tti);
// printf("trx_read <- USRP TS %llu (sf %d, first_rx %d)\n", proc->timestamp_rx,proc->subframe_rx,proc->first_rx); // printf("trx_read <- USRP TS %llu (sf %d, first_rx %d)\n", proc->timestamp_rx,proc->subframe_rx,proc->first_rx);
if (proc->first_rx == 0) { if (proc->first_rx == 0) {
if (proc->subframe_rx != *subframe){ if (proc->subframe_rx != *subframe) {
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,*subframe); LOG_E(PHY,
"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",
proc->subframe_rx, *subframe);
exit_fun("Exiting"); exit_fun("Exiting");
} }
if (proc->frame_rx != *frame) { if (proc->frame_rx != *frame) {
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,*frame); LOG_E(PHY,
"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",
proc->frame_rx, *frame);
exit_fun("Exiting"); exit_fun("Exiting");
} }
} else { } else {
...@@ -944,33 +968,36 @@ void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) { ...@@ -944,33 +968,36 @@ void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
//printf("timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",proc->timestamp_rx,proc->frame_rx,frame,proc->subframe_rx,subframe); //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 ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx & 0xffffffff);
if (rxs != fp->samples_per_tti) if (rxs != fp->samples_per_tti)
exit_fun( "problem receiving samples" ); exit_fun("problem receiving samples");
} }
void rx_fh_if5(PHY_VARS_eNB *eNB,int *frame, int *subframe) { void rx_fh_if5(PHY_VARS_eNB *eNB, int *frame, int *subframe) {
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
eNB_proc_t *proc = &eNB->proc; eNB_proc_t *proc = &eNB->proc;
recv_IF5(eNB, &proc->timestamp_rx, *subframe, IF5_RRH_GW_UL); recv_IF5(eNB, &proc->timestamp_rx, *subframe, IF5_RRH_GW_UL);
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) { if (proc->first_rx == 0) {
if (proc->subframe_rx != *subframe){ if (proc->subframe_rx != *subframe) {
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,subframe); LOG_E(PHY,
"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",
proc->subframe_rx, subframe);
exit_fun("Exiting"); exit_fun("Exiting");
} }
if (proc->frame_rx != *frame) { if (proc->frame_rx != *frame) {
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,frame); LOG_E(PHY,
"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",
proc->frame_rx, frame);
exit_fun("Exiting"); exit_fun("Exiting");
} }
} else { } else {
...@@ -979,12 +1006,12 @@ void rx_fh_if5(PHY_VARS_eNB *eNB,int *frame, int *subframe) { ...@@ -979,12 +1006,12 @@ void rx_fh_if5(PHY_VARS_eNB *eNB,int *frame, int *subframe) {
*subframe = proc->subframe_rx; *subframe = proc->subframe_rx;
} }
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_TRX_TS, proc->timestamp_rx & 0xffffffff);
} }
void rx_fh_if4p5(PHY_VARS_eNB *eNB,int *frame,int *subframe) { void rx_fh_if4p5(PHY_VARS_eNB *eNB, int *frame, int *subframe) {
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
eNB_proc_t *proc = &eNB->proc; eNB_proc_t *proc = &eNB->proc;
...@@ -992,37 +1019,41 @@ void rx_fh_if4p5(PHY_VARS_eNB *eNB,int *frame,int *subframe) { ...@@ -992,37 +1019,41 @@ void rx_fh_if4p5(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
int prach_rx; int prach_rx;
uint16_t packet_type; uint16_t packet_type;
uint32_t symbol_number=0; uint32_t symbol_number = 0;
uint32_t symbol_mask, symbol_mask_full; uint32_t symbol_mask, symbol_mask_full;
symbol_mask = 0; symbol_mask = 0;
symbol_mask_full = (1<<fp->symbols_per_tti)-1; symbol_mask_full = (1 << fp->symbols_per_tti) - 1;
prach_rx = 0; prach_rx = 0;
do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!! do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!!
recv_IF4p5(eNB, &proc->frame_rx, &proc->subframe_rx, &packet_type, &symbol_number); recv_IF4p5(eNB, &proc->frame_rx, &proc->subframe_rx, &packet_type, &symbol_number);
if (packet_type == IF4p5_PULFFT) { if (packet_type == IF4p5_PULFFT) {
symbol_mask = symbol_mask | (1<<symbol_number); symbol_mask = symbol_mask | (1 << symbol_number);
prach_rx = (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>0) ? 1 : 0; prach_rx = (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx) > 0) ? 1 : 0;
} else if (packet_type == IF4p5_PRACH) { } else if (packet_type == IF4p5_PRACH) {
prach_rx = 0; prach_rx = 0;
} }
} while( (symbol_mask != symbol_mask_full) || (prach_rx == 1)); } while ((symbol_mask != symbol_mask_full) || (prach_rx == 1));
//caculate timestamp_rx, timestamp_tx based on frame and subframe //caculate timestamp_rx, timestamp_tx based on frame and subframe
proc->timestamp_rx = ((proc->frame_rx * 10) + proc->subframe_rx ) * fp->samples_per_tti ; proc->timestamp_rx = ((proc->frame_rx * 10) + proc->subframe_rx) * fp->samples_per_tti;
proc->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti); proc->timestamp_tx = proc->timestamp_rx + (4 * fp->samples_per_tti);
if (proc->first_rx == 0) { if (proc->first_rx == 0) {
if (proc->subframe_rx != *subframe){ if (proc->subframe_rx != *subframe) {
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,*subframe); LOG_E(PHY,
"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",
proc->subframe_rx, *subframe);
exit_fun("Exiting"); exit_fun("Exiting");
} }
if (proc->frame_rx != *frame) { if (proc->frame_rx != *frame) {
LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,*frame); LOG_E(PHY,
"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",
proc->frame_rx, *frame);
exit_fun("Exiting"); exit_fun("Exiting");
} }
} else { } else {
...@@ -1031,48 +1062,50 @@ void rx_fh_if4p5(PHY_VARS_eNB *eNB,int *frame,int *subframe) { ...@@ -1031,48 +1062,50 @@ void rx_fh_if4p5(PHY_VARS_eNB *eNB,int *frame,int *subframe) {
*subframe = proc->subframe_rx; *subframe = proc->subframe_rx;
} }
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_TRX_TS, proc->timestamp_rx & 0xffffffff);
} }
void rx_fh_slave(PHY_VARS_eNB *eNB,int *frame,int *subframe) { void rx_fh_slave(PHY_VARS_eNB *eNB, int *frame, int *subframe) {
// This case is for synchronization to another thread // This case is for synchronization to another thread
// it just waits for an external event. The actual rx_fh is handle by the asynchronous RX thread // it just waits for an external event. The actual rx_fh is handle by the asynchronous RX thread
eNB_proc_t *proc=&eNB->proc; eNB_proc_t *proc = &eNB->proc;
if (wait_on_condition(&proc->mutex_FH,&proc->cond_FH,&proc->instance_cnt_FH,"rx_fh_slave") < 0) if (wait_on_condition(&proc->mutex_FH, &proc->cond_FH, &proc->instance_cnt_FH, "rx_fh_slave") < 0)
return; return;
release_thread(&proc->mutex_FH,&proc->instance_cnt_FH,"rx_fh_slave"); release_thread(&proc->mutex_FH, &proc->instance_cnt_FH, "rx_fh_slave");
} }
int wakeup_rxtx(eNB_proc_t *proc,eNB_rxtx_proc_t *proc_rxtx,LTE_DL_FRAME_PARMS *fp) { int wakeup_rxtx(eNB_proc_t *proc, eNB_rxtx_proc_t *proc_rxtx, LTE_DL_FRAME_PARMS *fp) {
int i; int i;
struct timespec wait; struct timespec wait;
wait.tv_sec=0; wait.tv_sec = 0;
wait.tv_nsec=5000000L; wait.tv_nsec = 5000000L;
/* accept some delay in processing - up to 5ms */ /* accept some delay in processing - up to 5ms */
for (i = 0; i < 10 && proc_rxtx->instance_cnt_rxtx == 0; i++) { for (i = 0; i < 10 && proc_rxtx->instance_cnt_rxtx == 0; i++) {
LOG_W( PHY,"[eNB] Frame %d, eNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", proc_rxtx->frame_tx, proc_rxtx->instance_cnt_rxtx); LOG_W(PHY, "[eNB] Frame %d, eNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", proc_rxtx->frame_tx,
proc_rxtx->instance_cnt_rxtx);
usleep(500); usleep(500);
} }
if (proc_rxtx->instance_cnt_rxtx == 0) { if (proc_rxtx->instance_cnt_rxtx == 0) {
exit_fun( "TX thread busy" ); exit_fun("TX thread busy");
return(-1); return (-1);
} }
// wake up TX for subframe n+4 // wake up TX for subframe n+4
// lock the TX mutex and make sure the thread is ready // lock the TX mutex and make sure the thread is ready
if (pthread_mutex_timedlock(&proc_rxtx->mutex_rxtx,&wait) != 0) { if (pthread_mutex_timedlock(&proc_rxtx->mutex_rxtx, &wait) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", proc_rxtx->subframe_rx&1,proc_rxtx->instance_cnt_rxtx ); LOG_E(PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", proc_rxtx->subframe_rx & 1,
exit_fun( "error locking mutex_rxtx" ); proc_rxtx->instance_cnt_rxtx);
return(-1); exit_fun("error locking mutex_rxtx");
return (-1);
} }
++proc_rxtx->instance_cnt_rxtx; ++proc_rxtx->instance_cnt_rxtx;
...@@ -1083,22 +1116,22 @@ int wakeup_rxtx(eNB_proc_t *proc,eNB_rxtx_proc_t *proc_rxtx,LTE_DL_FRAME_PARMS * ...@@ -1083,22 +1116,22 @@ int wakeup_rxtx(eNB_proc_t *proc,eNB_rxtx_proc_t *proc_rxtx,LTE_DL_FRAME_PARMS *
// The last (TS_rx mod samples_per_frame) was n*samples_per_tti, // The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
// we want to generate subframe (n+4), so TS_tx = TX_rx+4*samples_per_tti, // we want to generate subframe (n+4), so TS_tx = TX_rx+4*samples_per_tti,
// and proc->subframe_tx = proc->subframe_rx+4 // and proc->subframe_tx = proc->subframe_rx+4
proc_rxtx->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti); proc_rxtx->timestamp_tx = proc->timestamp_rx + (4 * fp->samples_per_tti);
proc_rxtx->frame_rx = proc->frame_rx; proc_rxtx->frame_rx = proc->frame_rx;
proc_rxtx->subframe_rx = proc->subframe_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->frame_tx = (proc_rxtx->subframe_rx > 5) ? (proc_rxtx->frame_rx + 1) & 1023 : proc_rxtx->frame_rx;
proc_rxtx->subframe_tx = (proc_rxtx->subframe_rx + 4)%10; proc_rxtx->subframe_tx = (proc_rxtx->subframe_rx + 4) % 10;
// the thread can now be woken up // the thread 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");
return(-1); return (-1);
} }
pthread_mutex_unlock( &proc_rxtx->mutex_rxtx ); pthread_mutex_unlock(&proc_rxtx->mutex_rxtx);
return(0); return (0);
} }
void wakeup_slaves(eNB_proc_t *proc) { void wakeup_slaves(eNB_proc_t *proc) {
...@@ -1106,16 +1139,17 @@ void wakeup_slaves(eNB_proc_t *proc) { ...@@ -1106,16 +1139,17 @@ void wakeup_slaves(eNB_proc_t *proc) {
int i; int i;
struct timespec wait; struct timespec wait;
wait.tv_sec=0; wait.tv_sec = 0;
wait.tv_nsec=5000000L; wait.tv_nsec = 5000000L;
for (i=0;i<proc->num_slaves;i++) { for (i = 0; i < proc->num_slaves; i++) {
eNB_proc_t *slave_proc = proc->slave_proc[i]; eNB_proc_t *slave_proc = proc->slave_proc[i];
// wake up slave FH thread // wake up slave FH thread
// lock the FH mutex and make sure the thread is ready // lock the FH mutex and make sure the thread is ready
if (pthread_mutex_timedlock(&slave_proc->mutex_FH,&wait) != 0) { if (pthread_mutex_timedlock(&slave_proc->mutex_FH, &wait) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB CCid %d slave CCid %d (IC %d)\n",proc->CC_id,slave_proc->CC_id); LOG_E(PHY, "[eNB] ERROR pthread_mutex_lock for eNB CCid %d slave CCid %d (IC %d)\n", proc->CC_id,
exit_fun( "error locking mutex_rxtx" ); slave_proc->CC_id);
exit_fun("error locking mutex_rxtx");
break; break;
} }
...@@ -1125,18 +1159,20 @@ void wakeup_slaves(eNB_proc_t *proc) { ...@@ -1125,18 +1159,20 @@ void wakeup_slaves(eNB_proc_t *proc) {
slave_proc->timestamp_rx = proc->timestamp_rx; slave_proc->timestamp_rx = proc->timestamp_rx;
slave_proc->timestamp_tx = proc->timestamp_tx; slave_proc->timestamp_tx = proc->timestamp_tx;
pthread_mutex_unlock( &slave_proc->mutex_FH ); pthread_mutex_unlock(&slave_proc->mutex_FH);
if (cnt_slave == 0) { if (cnt_slave == 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(&slave_proc->cond_FH) != 0) { if (pthread_cond_signal(&slave_proc->cond_FH) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB CCid %d, slave CCid %d\n",proc->CC_id,slave_proc->CC_id); LOG_E(PHY, "[eNB] ERROR pthread_cond_signal for eNB CCid %d, slave CCid %d\n", proc->CC_id,
exit_fun( "ERROR pthread_cond_signal" ); slave_proc->CC_id);
exit_fun("ERROR pthread_cond_signal");
break; break;
} }
} else { } else {
LOG_W( PHY,"[eNB] Frame %d, slave CC_id %d thread busy!! (cnt_FH %i)\n",slave_proc->frame_rx,slave_proc->CC_id, cnt_slave); LOG_W(PHY, "[eNB] Frame %d, slave CC_id %d thread busy!! (cnt_FH %i)\n", slave_proc->frame_rx,
exit_fun( "FH thread busy" ); slave_proc->CC_id, cnt_slave);
exit_fun("FH thread busy");
break; break;
} }
} }
...@@ -1150,20 +1186,20 @@ void wakeup_slaves(eNB_proc_t *proc) { ...@@ -1150,20 +1186,20 @@ void wakeup_slaves(eNB_proc_t *proc) {
* \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_FH( void* param ) { static void *eNB_thread_FH(void *param) {
static int eNB_thread_FH_status; static int eNB_thread_FH_status;
eNB_proc_t *proc = (eNB_proc_t*)param; eNB_proc_t *proc = (eNB_proc_t *) param;
PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id]; PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id];
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
int subframe=0, frame=0; int subframe = 0, frame = 0;
// set default return value // set default return value
eNB_thread_FH_status = 0; eNB_thread_FH_status = 0;
thread_top_init("eNB_thread_FH",0,870000,1000000,1000000); thread_top_init("eNB_thread_FH", 0, 870000, 1000000, 1000000);
wait_sync("eNB_thread_FH"); wait_sync("eNB_thread_FH");
...@@ -1175,16 +1211,16 @@ static void* eNB_thread_FH( void* param ) { ...@@ -1175,16 +1211,16 @@ static void* eNB_thread_FH( void* param ) {
// Start IF device if any // Start IF device if any
if (eNB->start_if) if (eNB->start_if)
if (eNB->start_if(eNB) != 0) if (eNB->start_if(eNB) != 0)
LOG_E(HW,"Could not start the IF device\n"); LOG_E(HW, "Could not start the IF device\n");
// Start RF device if any // Start RF device if any
if (eNB->start_rf) if (eNB->start_rf)
if (eNB->start_rf(eNB) != 0) if (eNB->start_rf(eNB) != 0)
LOG_E(HW,"Could not start the RF device\n"); LOG_E(HW, "Could not start the RF device\n");
// wakeup asnych_rxtx thread because the devices are ready at this point // wakeup asnych_rxtx thread because the devices are ready at this point
pthread_mutex_lock(&proc->mutex_asynch_rxtx); pthread_mutex_lock(&proc->mutex_asynch_rxtx);
proc->instance_cnt_asynch_rxtx=0; proc->instance_cnt_asynch_rxtx = 0;
pthread_mutex_unlock(&proc->mutex_asynch_rxtx); pthread_mutex_unlock(&proc->mutex_asynch_rxtx);
pthread_cond_signal(&proc->cond_asynch_rxtx); pthread_cond_signal(&proc->cond_asynch_rxtx);
...@@ -1193,18 +1229,18 @@ static void* eNB_thread_FH( void* param ) { ...@@ -1193,18 +1229,18 @@ static void* eNB_thread_FH( void* param ) {
// these are local subframe/frame counters to check that we are in synch with the fronthaul timing. // these are local subframe/frame counters to check that we are in synch with the fronthaul timing.
// They are set on the first rx/tx in the underly FH routines. // They are set on the first rx/tx in the underly FH routines.
if (subframe==9) { if (subframe == 9) {
subframe=0; subframe = 0;
frame++; frame++;
frame&=1023; frame &= 1023;
} else { } else {
subframe++; subframe++;
} }
// synchronization on FH interface, acquire signals/data and block // synchronization on FH interface, acquire signals/data and block
if (eNB->rx_fh) eNB->rx_fh(eNB,&frame,&subframe); if (eNB->rx_fh) eNB->rx_fh(eNB, &frame, &subframe);
else AssertFatal(1==0, "No fronthaul interface : eNB->node_function %d",eNB->node_function); else AssertFatal(1 == 0, "No fronthaul interface : eNB->node_function %d", eNB->node_function);
T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx)); T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
...@@ -1214,15 +1250,15 @@ static void* eNB_thread_FH( void* param ) { ...@@ -1214,15 +1250,15 @@ static void* eNB_thread_FH( void* param ) {
// wake up RXn_TXnp4 thread for the subframe // wake up RXn_TXnp4 thread for the subframe
// choose even or odd thread for RXn-TXnp4 processing // choose even or odd thread for RXn-TXnp4 processing
if (wakeup_rxtx(proc,&proc->proc_rxtx[proc->subframe_rx&1],fp) < 0) if (wakeup_rxtx(proc, &proc->proc_rxtx[proc->subframe_rx & 1], fp) < 0)
break; break;
// artifical sleep for very slow fronthaul // artifical sleep for very slow fronthaul
if (eNB->frame_parms.N_RB_DL==6) if (eNB->frame_parms.N_RB_DL == 6)
rt_sleep_ns(800000LL); rt_sleep_ns(800000LL);
} }
printf( "Exiting FH thread \n"); printf("Exiting FH thread \n");
eNB_thread_FH_status = 0; eNB_thread_FH_status = 0;
return &eNB_thread_FH_status; return &eNB_thread_FH_status;
...@@ -1234,48 +1270,50 @@ static void* eNB_thread_FH( void* param ) { ...@@ -1234,48 +1270,50 @@ static void* eNB_thread_FH( void* param ) {
* \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;
PHY_VARS_eNB *eNB= PHY_vars_eNB_g[0][proc->CC_id]; PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id];
// set default return value // set default return value
eNB_thread_prach_status = 0; eNB_thread_prach_status = 0;
thread_top_init("eNB_thread_prach",1,500000L,1000000L,20000000L); thread_top_init("eNB_thread_prach", 1, 500000L, 1000000L, 20000000L);
while (!oai_exit) { while (!oai_exit) {
if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break; if (wait_on_condition(&proc->mutex_prach, &proc->cond_prach, &proc->instance_cnt_prach, "eNB_prach_thread") <
0)
break;
if (oai_exit) break; if (oai_exit) break;
prach_procedures(eNB); prach_procedures(eNB);
if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break; if (release_thread(&proc->mutex_prach, &proc->instance_cnt_prach, "eNB_prach_thread") < 0) break;
} }
printf( "Exiting eNB thread PRACH\n"); printf("Exiting eNB thread PRACH\n");
eNB_thread_prach_status = 0; eNB_thread_prach_status = 0;
return &eNB_thread_prach_status; return &eNB_thread_prach_status;
} }
static void* eNB_thread_single( void* param ) { static void *eNB_thread_single(void *param) {
static int eNB_thread_single_status; static int eNB_thread_single_status;
eNB_proc_t *proc = (eNB_proc_t*)param; eNB_proc_t *proc = (eNB_proc_t *) param;
eNB_rxtx_proc_t *proc_rxtx = &proc->proc_rxtx[0]; eNB_rxtx_proc_t *proc_rxtx = &proc->proc_rxtx[0];
PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id]; PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id];
int subframe=0, frame=0; int subframe = 0, frame = 0;
// set default return value // set default return value
eNB_thread_single_status = 0; eNB_thread_single_status = 0;
thread_top_init("eNB_thread_single",0,870000,1000000,1000000); thread_top_init("eNB_thread_single", 0, 870000, 1000000, 1000000);
wait_sync("eNB_thread_single"); wait_sync("eNB_thread_single");
...@@ -1287,16 +1325,16 @@ static void* eNB_thread_single( void* param ) { ...@@ -1287,16 +1325,16 @@ static void* eNB_thread_single( void* param ) {
// Start IF device if any // Start IF device if any
if (eNB->start_if) if (eNB->start_if)
if (eNB->start_if(eNB) != 0) if (eNB->start_if(eNB) != 0)
LOG_E(HW,"Could not start the IF device\n"); LOG_E(HW, "Could not start the IF device\n");
// Start RF device if any // Start RF device if any
if (eNB->start_rf) if (eNB->start_rf)
if (eNB->start_rf(eNB) != 0) if (eNB->start_rf(eNB) != 0)
LOG_E(HW,"Could not start the RF device\n"); LOG_E(HW, "Could not start the RF device\n");
// wakeup asnych_rxtx thread because the devices are ready at this point // wakeup asnych_rxtx thread because the devices are ready at this point
pthread_mutex_lock(&proc->mutex_asynch_rxtx); pthread_mutex_lock(&proc->mutex_asynch_rxtx);
proc->instance_cnt_asynch_rxtx=0; proc->instance_cnt_asynch_rxtx = 0;
pthread_mutex_unlock(&proc->mutex_asynch_rxtx); pthread_mutex_unlock(&proc->mutex_asynch_rxtx);
pthread_cond_signal(&proc->cond_asynch_rxtx); pthread_cond_signal(&proc->cond_asynch_rxtx);
...@@ -1305,37 +1343,37 @@ static void* eNB_thread_single( void* param ) { ...@@ -1305,37 +1343,37 @@ static void* eNB_thread_single( void* param ) {
// these are local subframe/frame counters to check that we are in synch with the fronthaul timing. // these are local subframe/frame counters to check that we are in synch with the fronthaul timing.
// They are set on the first rx/tx in the underly FH routines. // They are set on the first rx/tx in the underly FH routines.
if (subframe==9) { if (subframe == 9) {
subframe=0; subframe = 0;
frame++; frame++;
frame&=1023; frame &= 1023;
} else { } else {
subframe++; subframe++;
} }
LOG_D(PHY,"eNB Fronthaul thread, frame %d, subframe %d\n",frame,subframe); LOG_D(PHY, "eNB Fronthaul thread, frame %d, subframe %d\n", frame, subframe);
// synchronization on FH interface, acquire signals/data and block // synchronization on FH interface, acquire signals/data and block
if (eNB->rx_fh) eNB->rx_fh(eNB,&frame,&subframe); if (eNB->rx_fh) eNB->rx_fh(eNB, &frame, &subframe);
else AssertFatal(1==0, "No fronthaul interface : eNB->node_function %d",eNB->node_function); else AssertFatal(1 == 0, "No fronthaul interface : eNB->node_function %d", eNB->node_function);
T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx)); T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
proc_rxtx->subframe_rx = proc->subframe_rx; proc_rxtx->subframe_rx = proc->subframe_rx;
proc_rxtx->frame_rx = proc->frame_rx; proc_rxtx->frame_rx = proc->frame_rx;
proc_rxtx->subframe_tx = (proc->subframe_rx+4)%10; proc_rxtx->subframe_tx = (proc->subframe_rx + 4) % 10;
proc_rxtx->frame_tx = (proc->subframe_rx < 6) ? proc->frame_rx : (proc->frame_rx+1)&1023; proc_rxtx->frame_tx = (proc->subframe_rx < 6) ? proc->frame_rx : (proc->frame_rx + 1) & 1023;
proc_rxtx->timestamp_tx = proc->timestamp_tx; proc_rxtx->timestamp_tx = proc->timestamp_tx;
// At this point, all information for subframe has been received on FH interface // At this point, all information for subframe has been received on FH interface
// If this proc is to provide synchronization, do so // If this proc is to provide synchronization, do so
wakeup_slaves(proc); wakeup_slaves(proc);
if (rxtx(eNB,proc_rxtx,"eNB_thread_single") < 0) break; if (rxtx(eNB, proc_rxtx, "eNB_thread_single") < 0) break;
} }
printf( "Exiting eNB_single thread \n"); printf("Exiting eNB_single thread \n");
eNB_thread_single_status = 0; eNB_thread_single_status = 0;
return &eNB_thread_single_status; return &eNB_thread_single_status;
...@@ -1343,22 +1381,25 @@ static void* eNB_thread_single( void* param ) { ...@@ -1343,22 +1381,25 @@ static void* eNB_thread_single( void* param ) {
} }
extern void init_fep_thread(PHY_VARS_eNB *, pthread_attr_t *); extern void init_fep_thread(PHY_VARS_eNB *, pthread_attr_t *);
extern void init_td_thread(PHY_VARS_eNB *, pthread_attr_t *); extern void init_td_thread(PHY_VARS_eNB *, pthread_attr_t *);
extern void init_te_thread(PHY_VARS_eNB *, pthread_attr_t *); extern void init_te_thread(PHY_VARS_eNB *, pthread_attr_t *);
void init_eNB_proc(int inst) { void init_eNB_proc(int inst) {
int i=0; int i = 0;
int CC_id; int CC_id;
PHY_VARS_eNB *eNB; PHY_VARS_eNB *eNB;
eNB_proc_t *proc; eNB_proc_t *proc;
eNB_rxtx_proc_t *proc_rxtx; eNB_rxtx_proc_t *proc_rxtx;
pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_FH=NULL,*attr_prach=NULL,*attr_asynch=NULL,*attr_single=NULL,*attr_fep=NULL,*attr_td=NULL,*attr_te; pthread_attr_t *attr0 = NULL, *attr1 = NULL, *attr_FH = NULL, *attr_prach = NULL, *attr_asynch = NULL, *attr_single = NULL, *attr_fep = NULL, *attr_td = NULL, *attr_te;
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[inst][CC_id]; eNB = PHY_vars_eNB_g[inst][CC_id];
#ifndef OCP_FRAMEWORK #ifndef OCP_FRAMEWORK
LOG_I(PHY,"Initializing eNB %d CC_id %d (%s,%s),\n",inst,CC_id,eNB_functions[eNB->node_function],eNB_timing[eNB->node_timing]); LOG_I(PHY, "Initializing eNB %d CC_id %d (%s,%s),\n", inst, CC_id, eNB_functions[eNB->node_function],
eNB_timing[eNB->node_timing]);
#endif #endif
proc = &eNB->proc; proc = &eNB->proc;
...@@ -1370,30 +1411,30 @@ void init_eNB_proc(int inst) { ...@@ -1370,30 +1411,30 @@ void init_eNB_proc(int inst) {
proc->instance_cnt_asynch_rxtx = -1; proc->instance_cnt_asynch_rxtx = -1;
proc->CC_id = CC_id; proc->CC_id = CC_id;
proc->first_rx=1; proc->first_rx = 1;
proc->first_tx=1; proc->first_tx = 1;
pthread_mutex_init( &proc_rxtx[0].mutex_rxtx, NULL); pthread_mutex_init(&proc_rxtx[0].mutex_rxtx, NULL);
pthread_mutex_init( &proc_rxtx[1].mutex_rxtx, NULL); pthread_mutex_init(&proc_rxtx[1].mutex_rxtx, NULL);
pthread_cond_init( &proc_rxtx[0].cond_rxtx, NULL); pthread_cond_init(&proc_rxtx[0].cond_rxtx, NULL);
pthread_cond_init( &proc_rxtx[1].cond_rxtx, NULL); pthread_cond_init(&proc_rxtx[1].cond_rxtx, NULL);
pthread_mutex_init( &proc->mutex_prach, NULL); pthread_mutex_init(&proc->mutex_prach, NULL);
pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL); pthread_mutex_init(&proc->mutex_asynch_rxtx, NULL);
pthread_cond_init( &proc->cond_prach, NULL); pthread_cond_init(&proc->cond_prach, NULL);
pthread_cond_init( &proc->cond_FH, NULL); pthread_cond_init(&proc->cond_FH, NULL);
pthread_cond_init( &proc->cond_asynch_rxtx, NULL); pthread_cond_init(&proc->cond_asynch_rxtx, NULL);
pthread_attr_init( &proc->attr_FH); pthread_attr_init(&proc->attr_FH);
pthread_attr_init( &proc->attr_prach); pthread_attr_init(&proc->attr_prach);
pthread_attr_init( &proc->attr_asynch_rxtx); pthread_attr_init(&proc->attr_asynch_rxtx);
pthread_attr_init( &proc->attr_single); pthread_attr_init(&proc->attr_single);
pthread_attr_init( &proc->attr_fep); pthread_attr_init(&proc->attr_fep);
pthread_attr_init( &proc->attr_td); pthread_attr_init(&proc->attr_td);
pthread_attr_init( &proc->attr_te); pthread_attr_init(&proc->attr_te);
pthread_attr_init( &proc_rxtx[0].attr_rxtx); pthread_attr_init(&proc_rxtx[0].attr_rxtx);
pthread_attr_init( &proc_rxtx[1].attr_rxtx); pthread_attr_init(&proc_rxtx[1].attr_rxtx);
#ifndef DEADLINE_SCHEDULER #ifndef DEADLINE_SCHEDULER
attr0 = &proc_rxtx[0].attr_rxtx; attr0 = &proc_rxtx[0].attr_rxtx;
attr1 = &proc_rxtx[1].attr_rxtx; attr1 = &proc_rxtx[1].attr_rxtx;
...@@ -1406,51 +1447,49 @@ void init_eNB_proc(int inst) { ...@@ -1406,51 +1447,49 @@ void init_eNB_proc(int inst) {
attr_te = &proc->attr_te; attr_te = &proc->attr_te;
#endif #endif
if (eNB->single_thread_flag==0) { if (eNB->single_thread_flag == 0) {
pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, &proc_rxtx[0] ); pthread_create(&proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, &proc_rxtx[0]);
pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, eNB_thread_rxtx, &proc_rxtx[1] ); pthread_create(&proc_rxtx[1].pthread_rxtx, attr1, eNB_thread_rxtx, &proc_rxtx[1]);
pthread_create( &proc->pthread_FH, attr_FH, eNB_thread_FH, &eNB->proc ); pthread_create(&proc->pthread_FH, attr_FH, eNB_thread_FH, &eNB->proc);
} } else {
else {
pthread_create(&proc->pthread_single, attr_single, eNB_thread_single, &eNB->proc); pthread_create(&proc->pthread_single, attr_single, eNB_thread_single, &eNB->proc);
init_fep_thread(eNB,attr_fep); init_fep_thread(eNB, attr_fep);
init_td_thread(eNB,attr_td); init_td_thread(eNB, attr_td);
init_te_thread(eNB,attr_te); init_te_thread(eNB, attr_te);
} }
pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, &eNB->proc ); pthread_create(&proc->pthread_prach, attr_prach, eNB_thread_prach, &eNB->proc);
if ((eNB->node_timing == synch_to_other) || if ((eNB->node_timing == synch_to_other) ||
(eNB->node_function == NGFI_RRU_IF5) || (eNB->node_function == NGFI_RRU_IF5) ||
(eNB->node_function == NGFI_RRU_IF4p5)) (eNB->node_function == NGFI_RRU_IF4p5))
pthread_create( &proc->pthread_asynch_rxtx, attr_asynch, eNB_thread_asynch_rxtx, &eNB->proc ); pthread_create(&proc->pthread_asynch_rxtx, attr_asynch, eNB_thread_asynch_rxtx, &eNB->proc);
char name[16]; char name[16];
if (eNB->single_thread_flag == 0) { if (eNB->single_thread_flag == 0) {
snprintf( name, sizeof(name), "RXTX0 %d", i ); snprintf(name, sizeof(name), "RXTX0 %d", i);
pthread_setname_np( proc_rxtx[0].pthread_rxtx, name ); pthread_setname_np(proc_rxtx[0].pthread_rxtx, name);
snprintf( name, sizeof(name), "RXTX1 %d", i ); snprintf(name, sizeof(name), "RXTX1 %d", i);
pthread_setname_np( proc_rxtx[1].pthread_rxtx, name ); pthread_setname_np(proc_rxtx[1].pthread_rxtx, name);
snprintf( name, sizeof(name), "FH %d", i ); snprintf(name, sizeof(name), "FH %d", i);
pthread_setname_np( proc->pthread_FH, name ); pthread_setname_np(proc->pthread_FH, name);
} } else {
else { snprintf(name, sizeof(name), " %d", i);
snprintf( name, sizeof(name), " %d", i ); pthread_setname_np(proc->pthread_single, name);
pthread_setname_np( proc->pthread_single, name );
} }
} }
//for multiple CCs: setup master and slaves //for multiple CCs: setup master and slaves
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[inst][CC_id]; eNB = PHY_vars_eNB_g[inst][CC_id];
if (eNB->node_timing == synch_to_ext_device) { //master if (eNB->node_timing == synch_to_ext_device) { //master
eNB->proc.num_slaves = MAX_NUM_CCs-1; eNB->proc.num_slaves = MAX_NUM_CCs - 1;
eNB->proc.slave_proc = (eNB_proc_t**)malloc(eNB->proc.num_slaves*sizeof(eNB_proc_t*)); eNB->proc.slave_proc = (eNB_proc_t **) malloc(eNB->proc.num_slaves * sizeof(eNB_proc_t * ));
for (i=0; i< eNB->proc.num_slaves; i++) { for (i = 0; i < eNB->proc.num_slaves; i++) {
if (i < CC_id) eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i]->proc); if (i < CC_id) eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i]->proc);
if (i >= CC_id) eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i+1]->proc); if (i >= CC_id) eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i + 1]->proc);
} }
} }
} }
...@@ -1463,7 +1502,6 @@ void init_eNB_proc(int inst) { ...@@ -1463,7 +1502,6 @@ void init_eNB_proc(int inst) {
} }
/*! /*!
* \brief Terminate eNB TX and RX threads. * \brief Terminate eNB TX and RX threads.
*/ */
...@@ -1473,8 +1511,8 @@ void kill_eNB_proc(int inst) { ...@@ -1473,8 +1511,8 @@ void kill_eNB_proc(int inst) {
PHY_VARS_eNB *eNB; PHY_VARS_eNB *eNB;
eNB_proc_t *proc; eNB_proc_t *proc;
eNB_rxtx_proc_t *proc_rxtx; eNB_rxtx_proc_t *proc_rxtx;
for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
eNB=PHY_vars_eNB_g[inst][CC_id]; eNB = PHY_vars_eNB_g[inst][CC_id];
proc = &eNB->proc; proc = &eNB->proc;
proc_rxtx = &proc->proc_rxtx[0]; proc_rxtx = &proc->proc_rxtx[0];
...@@ -1487,25 +1525,25 @@ void kill_eNB_proc(int inst) { ...@@ -1487,25 +1525,25 @@ void kill_eNB_proc(int inst) {
proc_rxtx[1].instance_cnt_rxtx = 0; // FIXME data race! proc_rxtx[1].instance_cnt_rxtx = 0; // FIXME data race!
proc->instance_cnt_prach = 0; proc->instance_cnt_prach = 0;
proc->instance_cnt_FH = 0; proc->instance_cnt_FH = 0;
pthread_cond_signal( &proc_rxtx[0].cond_rxtx ); pthread_cond_signal(&proc_rxtx[0].cond_rxtx);
pthread_cond_signal( &proc_rxtx[1].cond_rxtx ); pthread_cond_signal(&proc_rxtx[1].cond_rxtx);
pthread_cond_signal( &proc->cond_prach ); pthread_cond_signal(&proc->cond_prach);
pthread_cond_signal( &proc->cond_FH ); pthread_cond_signal(&proc->cond_FH);
pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx); pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx);
pthread_join( proc->pthread_FH, (void**)&status ); pthread_join(proc->pthread_FH, (void **) &status);
pthread_mutex_destroy( &proc->mutex_FH ); pthread_mutex_destroy(&proc->mutex_FH);
pthread_cond_destroy( &proc->cond_FH ); pthread_cond_destroy(&proc->cond_FH);
pthread_join( proc->pthread_prach, (void**)&status ); pthread_join(proc->pthread_prach, (void **) &status);
pthread_mutex_destroy( &proc->mutex_prach ); pthread_mutex_destroy(&proc->mutex_prach);
pthread_cond_destroy( &proc->cond_prach ); pthread_cond_destroy(&proc->cond_prach);
int i; int i;
for (i=0;i<2;i++) { for (i = 0; i < 2; i++) {
pthread_join( proc_rxtx[i].pthread_rxtx, (void**)&status ); pthread_join(proc_rxtx[i].pthread_rxtx, (void **) &status);
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);
} }
} }
} }
...@@ -1517,20 +1555,20 @@ void kill_eNB_proc(int inst) { ...@@ -1517,20 +1555,20 @@ void kill_eNB_proc(int inst) {
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) { int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg) {
int i,j; int i, j;
int CC_id,card,ant; int CC_id, card, ant;
//uint16_t N_TA_offset = 0; //uint16_t N_TA_offset = 0;
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);
printf("setup_eNB_buffers: frame_parms = %p\n",frame_parms); printf("setup_eNB_buffers: frame_parms = %p\n", frame_parms);
} else { } else {
printf("phy_vars_eNB[%d] not initialized\n", CC_id); printf("phy_vars_eNB[%d] not initialized\n", CC_id);
return(-1); return (-1);
} }
/* /*
...@@ -1548,36 +1586,41 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c ...@@ -1548,36 +1586,41 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
if (openair0_cfg[CC_id].mmapped_dma == 1) { if (openair0_cfg[CC_id].mmapped_dma == 1) {
// replace RX signal buffers with mmaped HW versions // replace RX signal buffers with mmaped HW versions
for (i=0; i<frame_parms->nb_antennas_rx; i++) { for (i = 0; i < frame_parms->nb_antennas_rx; i++) {
card = i/4; card = i / 4;
ant = i%4; ant = i % 4;
printf("Mapping eNB CC_id %d, rx_ant %d, on card %d, chain %d\n",CC_id,i,phy_vars_eNB[CC_id]->rf_map.card+card, phy_vars_eNB[CC_id]->rf_map.chain+ant); printf("Mapping eNB CC_id %d, rx_ant %d, on card %d, chain %d\n", CC_id, i,
phy_vars_eNB[CC_id]->rf_map.card + card, phy_vars_eNB[CC_id]->rf_map.chain + ant);
free(phy_vars_eNB[CC_id]->common_vars.rxdata[0][i]); free(phy_vars_eNB[CC_id]->common_vars.rxdata[0][i]);
phy_vars_eNB[CC_id]->common_vars.rxdata[0][i] = openair0_cfg[phy_vars_eNB[CC_id]->rf_map.card+card].rxbase[phy_vars_eNB[CC_id]->rf_map.chain+ant]; phy_vars_eNB[CC_id]->common_vars.rxdata[0][i] = openair0_cfg[phy_vars_eNB[CC_id]->rf_map.card +
card].rxbase[
phy_vars_eNB[CC_id]->rf_map.chain + ant];
printf("rxdata[%d] @ %p\n",i,phy_vars_eNB[CC_id]->common_vars.rxdata[0][i]); printf("rxdata[%d] @ %p\n", i, phy_vars_eNB[CC_id]->common_vars.rxdata[0][i]);
for (j=0; j<16; j++) { for (j = 0; j < 16; j++) {
printf("rxbuffer %d: %x\n",j,phy_vars_eNB[CC_id]->common_vars.rxdata[0][i][j]); printf("rxbuffer %d: %x\n", j, phy_vars_eNB[CC_id]->common_vars.rxdata[0][i][j]);
phy_vars_eNB[CC_id]->common_vars.rxdata[0][i][j] = 16-j; phy_vars_eNB[CC_id]->common_vars.rxdata[0][i][j] = 16 - j;
} }
} }
for (i=0; i<frame_parms->nb_antennas_tx; i++) { for (i = 0; i < frame_parms->nb_antennas_tx; i++) {
card = i/4; card = i / 4;
ant = i%4; ant = i % 4;
printf("Mapping eNB CC_id %d, tx_ant %d, on card %d, chain %d\n",CC_id,i,phy_vars_eNB[CC_id]->rf_map.card+card, phy_vars_eNB[CC_id]->rf_map.chain+ant); printf("Mapping eNB CC_id %d, tx_ant %d, on card %d, chain %d\n", CC_id, i,
phy_vars_eNB[CC_id]->rf_map.card + card, phy_vars_eNB[CC_id]->rf_map.chain + ant);
free(phy_vars_eNB[CC_id]->common_vars.txdata[0][i]); free(phy_vars_eNB[CC_id]->common_vars.txdata[0][i]);
phy_vars_eNB[CC_id]->common_vars.txdata[0][i] = openair0_cfg[phy_vars_eNB[CC_id]->rf_map.card+card].txbase[phy_vars_eNB[CC_id]->rf_map.chain+ant]; phy_vars_eNB[CC_id]->common_vars.txdata[0][i] = openair0_cfg[phy_vars_eNB[CC_id]->rf_map.card +
card].txbase[
phy_vars_eNB[CC_id]->rf_map.chain + ant];
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]);
for (j=0; j<16; j++) { for (j = 0; j < 16; j++) {
printf("txbuffer %d: %x\n",j,phy_vars_eNB[CC_id]->common_vars.txdata[0][i][j]); printf("txbuffer %d: %x\n", j, phy_vars_eNB[CC_id]->common_vars.txdata[0][i][j]);
phy_vars_eNB[CC_id]->common_vars.txdata[0][i][j] = 16-j; phy_vars_eNB[CC_id]->common_vars.txdata[0][i][j] = 16 - j;
}
} }
} }
else { // not memory-mapped DMA } else { // not memory-mapped DMA
//nothing to do, everything already allocated in lte_init //nothing to do, everything already allocated in lte_init
/* /*
rxdata = (int32_t**)malloc16(frame_parms->nb_antennas_rx*sizeof(int32_t*)); rxdata = (int32_t**)malloc16(frame_parms->nb_antennas_rx*sizeof(int32_t*));
...@@ -1602,7 +1645,7 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c ...@@ -1602,7 +1645,7 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
} }
} }
return(0); return (0);
} }
...@@ -1612,7 +1655,7 @@ void reset_opp_meas(void) { ...@@ -1612,7 +1655,7 @@ void reset_opp_meas(void) {
reset_meas(&softmodem_stats_mt); reset_meas(&softmodem_stats_mt);
reset_meas(&softmodem_stats_hw); reset_meas(&softmodem_stats_hw);
for (sfn=0; sfn < 10; sfn++) { for (sfn = 0; sfn < 10; sfn++) {
reset_meas(&softmodem_stats_rxtx_sf); reset_meas(&softmodem_stats_rxtx_sf);
reset_meas(&softmodem_stats_rx_sf); reset_meas(&softmodem_stats_rx_sf);
} }
...@@ -1621,45 +1664,50 @@ void reset_opp_meas(void) { ...@@ -1621,45 +1664,50 @@ void reset_opp_meas(void) {
void print_opp_meas(void) { void print_opp_meas(void) {
int sfn=0; int sfn = 0;
print_meas(&softmodem_stats_mt, "Main ENB Thread", NULL, NULL); print_meas(&softmodem_stats_mt, "Main ENB Thread", NULL, NULL);
print_meas(&softmodem_stats_hw, "HW Acquisation", NULL, NULL); print_meas(&softmodem_stats_hw, "HW Acquisation", NULL, NULL);
for (sfn=0; sfn < 10; sfn++) { for (sfn = 0; sfn < 10; sfn++) {
print_meas(&softmodem_stats_rxtx_sf,"[eNB][total_phy_proc_rxtx]",NULL, NULL); print_meas(&softmodem_stats_rxtx_sf, "[eNB][total_phy_proc_rxtx]", NULL, NULL);
print_meas(&softmodem_stats_rx_sf,"[eNB][total_phy_proc_rx]",NULL,NULL); print_meas(&softmodem_stats_rx_sf, "[eNB][total_phy_proc_rx]", NULL, NULL);
} }
} }
int start_if(PHY_VARS_eNB *eNB) { int start_if(PHY_VARS_eNB *eNB) {
return(eNB->ifdevice.trx_start_func(&eNB->ifdevice)); return (eNB->ifdevice.trx_start_func(&eNB->ifdevice));
} }
int start_rf(PHY_VARS_eNB *eNB) { int start_rf(PHY_VARS_eNB *eNB) {
return(eNB->rfdevice.trx_start_func(&eNB->rfdevice)); return (eNB->rfdevice.trx_start_func(&eNB->rfdevice));
} }
extern void eNB_fep_rru_if5(PHY_VARS_eNB *eNB); extern void eNB_fep_rru_if5(PHY_VARS_eNB *eNB);
extern void eNB_fep_full(PHY_VARS_eNB *eNB); extern void eNB_fep_full(PHY_VARS_eNB *eNB);
extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB); extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB);
extern void do_prach(PHY_VARS_eNB *eNB); extern void do_prach(PHY_VARS_eNB *eNB);
void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst,eth_params_t *eth_params,int single_thread_flag) { void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[], int nb_inst, eth_params_t *eth_params,
int single_thread_flag) {
int CC_id; int CC_id;
int inst; int inst;
PHY_VARS_eNB *eNB; PHY_VARS_eNB *eNB;
int ret; int ret;
for (inst=0;inst<nb_inst;inst++) { for (inst = 0; inst < nb_inst; inst++) {
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[inst][CC_id]; eNB = PHY_vars_eNB_g[inst][CC_id];
eNB->node_function = node_function[CC_id]; eNB->node_function = node_function[CC_id];
eNB->node_timing = node_timing[CC_id]; eNB->node_timing = node_timing[CC_id];
eNB->abstraction_flag = 0; eNB->abstraction_flag = 0;
eNB->single_thread_flag = single_thread_flag; eNB->single_thread_flag = single_thread_flag;
#ifndef OCP_FRAMEWORK #ifndef OCP_FRAMEWORK
LOG_I(PHY,"Initializing eNB %d CC_id %d : (%s,%s)\n",inst,CC_id,eNB_functions[node_function[CC_id]],eNB_timing[node_timing[CC_id]]); LOG_I(PHY, "Initializing eNB %d CC_id %d : (%s,%s)\n", inst, CC_id, eNB_functions[node_function[CC_id]],
eNB_timing[node_timing[CC_id]]);
#endif #endif
switch (node_function[CC_id]) { switch (node_function[CC_id]) {
...@@ -1676,15 +1724,15 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst ...@@ -1676,15 +1724,15 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
eNB->start_if = start_if; eNB->start_if = start_if;
eNB->fh_asynch = fh_if5_asynch_DL; eNB->fh_asynch = fh_if5_asynch_DL;
ret = openair0_device_load(&eNB->rfdevice, &openair0_cfg[CC_id]); ret = openair0_device_load(&eNB->rfdevice, &openair0_cfg[CC_id]);
if (ret<0) { if (ret < 0) {
printf("Exiting, cannot initialize rf device\n"); printf("Exiting, cannot initialize rf device\n");
exit(-1); exit(-1);
} }
eNB->rfdevice.host_type = RRH_HOST; eNB->rfdevice.host_type = RRH_HOST;
eNB->ifdevice.host_type = RRH_HOST; eNB->ifdevice.host_type = RRH_HOST;
ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params+CC_id)); ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params + CC_id));
printf("openair0_transport_init returns %d for CC_id %d\n",ret,CC_id); printf("openair0_transport_init returns %d for CC_id %d\n", ret, CC_id);
if (ret<0) { if (ret < 0) {
printf("Exiting, cannot initialize transport protocol\n"); printf("Exiting, cannot initialize transport protocol\n");
exit(-1); exit(-1);
} }
...@@ -1702,15 +1750,15 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst ...@@ -1702,15 +1750,15 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
eNB->start_rf = start_rf; eNB->start_rf = start_rf;
eNB->start_if = start_if; eNB->start_if = start_if;
ret = openair0_device_load(&eNB->rfdevice, &openair0_cfg[CC_id]); ret = openair0_device_load(&eNB->rfdevice, &openair0_cfg[CC_id]);
if (ret<0) { if (ret < 0) {
printf("Exiting, cannot initialize rf device\n"); printf("Exiting, cannot initialize rf device\n");
exit(-1); exit(-1);
} }
eNB->rfdevice.host_type = RRH_HOST; eNB->rfdevice.host_type = RRH_HOST;
eNB->ifdevice.host_type = RRH_HOST; eNB->ifdevice.host_type = RRH_HOST;
ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params+CC_id)); ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params + CC_id));
printf("openair0_transport_init returns %d for CC_id %d\n",ret,CC_id); printf("openair0_transport_init returns %d for CC_id %d\n", ret, CC_id);
if (ret<0) { if (ret < 0) {
printf("Exiting, cannot initialize transport protocol\n"); printf("Exiting, cannot initialize transport protocol\n");
exit(-1); exit(-1);
} }
...@@ -1731,7 +1779,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst ...@@ -1731,7 +1779,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
eNB->start_if = NULL; eNB->start_if = NULL;
eNB->fh_asynch = NULL; eNB->fh_asynch = NULL;
ret = openair0_device_load(&eNB->rfdevice, &openair0_cfg[CC_id]); ret = openair0_device_load(&eNB->rfdevice, &openair0_cfg[CC_id]);
if (ret<0) { if (ret < 0) {
printf("Exiting, cannot initialize rf device\n"); printf("Exiting, cannot initialize rf device\n");
exit(-1); exit(-1);
} }
...@@ -1750,8 +1798,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst ...@@ -1750,8 +1798,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
eNB->rx_fh = rx_fh_slave; eNB->rx_fh = rx_fh_slave;
eNB->fh_asynch = fh_if5_asynch_UL; eNB->fh_asynch = fh_if5_asynch_UL;
} } else {
else {
eNB->tx_fh = tx_fh_if5; eNB->tx_fh = tx_fh_if5;
eNB->rx_fh = rx_fh_if5; eNB->rx_fh = rx_fh_if5;
eNB->fh_asynch = NULL; eNB->fh_asynch = NULL;
...@@ -1763,9 +1810,9 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst ...@@ -1763,9 +1810,9 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
eNB->ifdevice.host_type = BBU_HOST; eNB->ifdevice.host_type = BBU_HOST;
ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params+CC_id)); ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params + CC_id));
printf("openair0_transport_init returns %d for CC_id %d\n",ret,CC_id); printf("openair0_transport_init returns %d for CC_id %d\n", ret, CC_id);
if (ret<0) { if (ret < 0) {
printf("Exiting, cannot initialize transport protocol\n"); printf("Exiting, cannot initialize transport protocol\n");
exit(-1); exit(-1);
} }
...@@ -1784,9 +1831,9 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst ...@@ -1784,9 +1831,9 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
eNB->fh_asynch = (eNB->node_timing == synch_to_other) ? fh_if4p5_asynch_UL : NULL; eNB->fh_asynch = (eNB->node_timing == synch_to_other) ? fh_if4p5_asynch_UL : NULL;
eNB->rfdevice.host_type = BBU_HOST; eNB->rfdevice.host_type = BBU_HOST;
eNB->ifdevice.host_type = BBU_HOST; eNB->ifdevice.host_type = BBU_HOST;
ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params+CC_id)); ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params + CC_id));
printf("openair0_transport_init returns %d for CC_id %d\n",ret,CC_id); printf("openair0_transport_init returns %d for CC_id %d\n", ret, CC_id);
if (ret<0) { if (ret < 0) {
printf("Exiting, cannot initialize transport protocol\n"); printf("Exiting, cannot initialize transport protocol\n");
exit(-1); exit(-1);
} }
...@@ -1809,9 +1856,9 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst ...@@ -1809,9 +1856,9 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
eNB->rfdevice.host_type = BBU_HOST; eNB->rfdevice.host_type = BBU_HOST;
eNB->ifdevice.host_type = BBU_HOST; eNB->ifdevice.host_type = BBU_HOST;
ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params+CC_id)); ret = openair0_transport_load(&eNB->ifdevice, &openair0_cfg[CC_id], (eth_params + CC_id));
printf("openair0_transport_init returns %d for CC_id %d\n",ret,CC_id); printf("openair0_transport_init returns %d for CC_id %d\n", ret, CC_id);
if (ret<0) { if (ret < 0) {
printf("Exiting, cannot initialize transport protocol\n"); printf("Exiting, cannot initialize transport protocol\n");
exit(-1); exit(-1);
} }
...@@ -1821,7 +1868,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst ...@@ -1821,7 +1868,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
} }
} }
if (setup_eNB_buffers(PHY_vars_eNB_g[inst],&openair0_cfg[0])!=0) { if (setup_eNB_buffers(PHY_vars_eNB_g[inst], &openair0_cfg[0]) != 0) {
printf("Exiting, cannot initialize eNodeB Buffers\n"); printf("Exiting, cannot initialize eNodeB Buffers\n");
exit(-1); exit(-1);
} }
...@@ -1830,7 +1877,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst ...@@ -1830,7 +1877,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
} }
sleep(1); sleep(1);
LOG_D(HW,"[lte-softmodem.c] eNB threads created\n"); LOG_D(HW, "[lte-softmodem.c] eNB threads created\n");
} }
...@@ -1838,8 +1885,8 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst ...@@ -1838,8 +1885,8 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst
void stop_eNB(int nb_inst) { void stop_eNB(int nb_inst) {
for (int inst=0;inst<nb_inst;inst++) { for (int inst = 0; inst < nb_inst; inst++) {
printf("Killing eNB %d processing threads\n",inst); printf("Killing eNB %d processing threads\n", inst);
kill_eNB_proc(inst); kill_eNB_proc(inst);
} }
} }
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