Commit d9501248 authored by knopp's avatar knopp
Browse files

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

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

Conflicts:
	targets/RT/USER/lte-softmodem.c
parents 89a9be9b b804f1e4
......@@ -963,7 +963,7 @@ set(PHY_SRC
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/print_stats.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/initial_sync.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if4_tools.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if5_mobipass_tools.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if5_tools.c
${OPENAIR1_DIR}/PHY/MODULATION/ofdm_mod.c
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep.c
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_mbsfn.c
......
......@@ -296,9 +296,6 @@ function main() {
if [ "$HW" = "None" -a "$TP" = "None" ] ; then
echo_fatal "Define a local radio head (e.g. -w EXMIMO) or a transport protocol (e.g. -t ETHERNET) to communicate with a remote radio head!"
fi
if [ "$HW" != "None" -a "$TP" != "None" ] ; then
echo_fatal "Currently eNB can not support simultaniously local and remote radio heads!!"
fi
if [ "$HW" = "None" ] ; then
echo_info "No radio head has been selected (HW set to $HW)"
fi
......
......@@ -29,65 +29,58 @@
/*! \file PHY/LTE_TRANSPORT/if4_tools.c
* \brief
* \author Fredrik Skretteberg, Tobias Schuster, Mauricio Gunther, S. Sandeep Kumar, Raymond Knopp
* \author S. Sandeep Kumar, Raymond Knopp
* \date 2016
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr
* \email: ee13b1025@iith.ac.in, knopp@eurecom.fr
* \note
* \warning
*/
#include <stdint.h>
#include "PHY/defs.h"
#include "PHY/LTE_TRANSPORT/if4_tools.h"
#include "PHY/TOOLS/ALAW/alaw_lut.h"
#include "PHY/TOOLS/alaw_lut.h"
#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
// --- Careful to handle buffer memory --- RAW/UDP modes --- PRACH variables and data
void send_IF4(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type, int k) {
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
int32_t **txdataF = eNB->common_vars.txdataF[0];
int32_t **rxdataF = eNB->common_vars.rxdataF[0];
int16_t **rxsigF = eNB->prach_vars.rxsigF;
void *tx_buffer = eNB->ifbuffer.tx;
uint16_t symbol_id=0, element_id=0;
uint16_t db_fulllength, db_halflength;
int slotoffsetF=0, blockoffsetF=0;
void *tx_buffer=NULL;
int16_t *data_block=NULL;
uint16_t *data_block=NULL, *i=NULL;
if (packet_type == IF4_PDLFFT) {
db_fulllength = 12*fp->N_RB_DL;
db_halflength = (db_fulllength)>>1;
slotoffsetF = (subframe)*(fp->ofdm_symbol_size)*((fp->Ncp==1) ? 12 : 14) + 1;
blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength;
blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength - 1;
tx_buffer = malloc(MAC_HEADER_SIZE_BYTES + sizeof_IF4_header_t + db_fulllength*sizeof(int16_t));
IF4_header_t *dl_header = (IF4_header_t *)(tx_buffer + MAC_HEADER_SIZE_BYTES);
data_block = (int16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4_header_t);
data_block = (uint16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4_header_t);
gen_IF4_dl_header(dl_header, frame, subframe);
for (symbol_id=0; symbol_id<fp->symbols_per_tti; symbol_id++) {
// Do compression of the two parts and generate data blocks
for (element_id=0; element_id<db_halflength; element_id++) {
data_block[element_id] = lin2alaw[ (txdataF[0][blockoffsetF+element_id] & 0xffff) + 32768 ];
data_block[element_id] |= lin2alaw[ (txdataF[0][blockoffsetF+element_id]>>16) + 32768 ]<<8;
data_block[element_id+db_halflength] = lin2alaw[ (txdataF[0][slotoffsetF+element_id] & 0xffff) + 32768 ];
data_block[element_id+db_halflength] |= lin2alaw[ (txdataF[0][slotoffsetF+element_id]>>16) + 32768 ]<<8;
i = (uint16_t*) &txdataF[0][blockoffsetF+element_id];
data_block[element_id] = ((uint16_t) lin2alaw[*i]) | (lin2alaw[*(i+1)]<<8);
i = (uint16_t*) &txdataF[0][slotoffsetF+element_id];
data_block[element_id+db_halflength] = ((uint16_t) lin2alaw[*i]) | (lin2alaw[*(i+1)]<<8);
}
// Update information in generated packet
dl_header->frame_status &= ~(0x000f<<26);
dl_header->frame_status |= (symbol_id&0x000f)<<26;
// Write the packet to the fronthaul
if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice,
symbol_id,
&tx_buffer,
......@@ -104,29 +97,26 @@ void send_IF4(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type,
db_fulllength = 12*fp->N_RB_UL;
db_halflength = (db_fulllength)>>1;
slotoffsetF = (subframe)*(fp->ofdm_symbol_size)*((fp->Ncp==1) ? 12 : 14) + 1;
blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength;
blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength - 1;
tx_buffer = malloc(MAC_HEADER_SIZE_BYTES + sizeof_IF4_header_t + db_fulllength*sizeof(int16_t));
IF4_header_t *ul_header = (IF4_header_t *)(tx_buffer + MAC_HEADER_SIZE_BYTES);
data_block = (int16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4_header_t);
data_block = (uint16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4_header_t);
gen_IF4_ul_header(ul_header, frame, subframe);
for (symbol_id=0; symbol_id<fp->symbols_per_tti; symbol_id++) {
// Do compression of the two parts and generate data blocks - rxdataF
for (element_id=0; element_id<db_halflength; element_id++) {
data_block[element_id] = lin2alaw[ (rxdataF[0][blockoffsetF+element_id] & 0xffff) + 32768 ];
data_block[element_id] |= lin2alaw[ (rxdataF[0][blockoffsetF+element_id]>>16) + 32768 ]<<8;
data_block[element_id+db_halflength] = lin2alaw[ (rxdataF[0][slotoffsetF+element_id] & 0xffff) + 32768 ];
data_block[element_id+db_halflength] |= lin2alaw[ (rxdataF[0][slotoffsetF+element_id]>>16) + 32768 ]<<8;
i = (uint16_t*) &rxdataF[0][blockoffsetF+element_id];
data_block[element_id] = ((uint16_t) lin2alaw[*i]) | (lin2alaw[*(i+1)]<<8);
i = (uint16_t*) &rxdataF[0][slotoffsetF+element_id];
data_block[element_id+db_halflength] = ((uint16_t) lin2alaw[*i]) | (lin2alaw[*(i+1)]<<8);
}
// Update information in generated packet
ul_header->frame_status &= ~(0x000f<<26);
ul_header->frame_status |= (symbol_id&0x000f)<<26;
// Write the packet(s) to the fronthaul
if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice,
symbol_id,
&tx_buffer,
......@@ -143,22 +133,15 @@ void send_IF4(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type,
// FIX: hard coded prach samples length
db_fulllength = 839*2;
tx_buffer = malloc(MAC_HEADER_SIZE_BYTES + sizeof_IF4_header_t + db_fulllength*sizeof(int16_t));
IF4_header_t *prach_header = (IF4_header_t *)(tx_buffer + MAC_HEADER_SIZE_BYTES);
data_block = (int16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4_header_t);
data_block = (uint16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4_header_t);
gen_IF4_prach_header(prach_header, frame, subframe);
// Generate uncompressed data blocks
memcpy(data_block, (rxsigF[0]+k), db_fulllength*sizeof(int16_t));
//for (element_id=0; element_id<db_fulllength; element_id++) {
// data_block[element_id] = rxsigF[0][prachoffsetF];
// data_block[element_id] |= rxsigF[0][prachoffsetF+1]<<16;
// prachoffsetF += 2;
//}
// Write the packet to the fronthaul
memcpy((int16_t*)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF4_header_t),
(&rxsigF[0][0]+k),
db_fulllength*sizeof(int16_t));
if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice,
symbol_id,
&tx_buffer,
......@@ -171,7 +154,6 @@ void send_IF4(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type,
AssertFatal(1==0, "send_IF4 - Unknown packet_type %x", packet_type);
}
free(tx_buffer);
return;
}
......@@ -181,6 +163,7 @@ void recv_IF4(PHY_VARS_eNB *eNB, int *frame, int *subframe, uint16_t *packet_typ
int32_t **txdataF = eNB->common_vars.txdataF[0];
int32_t **rxdataF = eNB->common_vars.rxdataF[0];
int16_t **rxsigF = eNB->prach_vars.rxsigF;
void *rx_buffer = eNB->ifbuffer.rx;
uint16_t element_id;
uint16_t db_fulllength, db_halflength;
......@@ -193,11 +176,9 @@ void recv_IF4(PHY_VARS_eNB *eNB, int *frame, int *subframe, uint16_t *packet_typ
}
db_halflength = db_fulllength>>1;
void *rx_buffer=NULL;
IF4_header_t *packet_header=NULL;
int16_t *data_block=NULL;
uint16_t *data_block=NULL, *i=NULL;
// Read packet(s) from the fronthaul
if (eNB->ifdevice.trx_read_func(&eNB->ifdevice,
(int64_t*) packet_type,
&rx_buffer,
......@@ -207,104 +188,100 @@ void recv_IF4(PHY_VARS_eNB *eNB, int *frame, int *subframe, uint16_t *packet_typ
}
packet_header = (IF4_header_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES);
data_block = (int16_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES+sizeof_IF4_header_t);
data_block = (uint16_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES+sizeof_IF4_header_t);
*frame = ((packet_header->frame_status)>>6)&0xffff;
*subframe = ((packet_header->frame_status)>>22)&0x000f;
if (*packet_type == IF4_PDLFFT) {
// Calculate from received packet
slotoffsetF = (*subframe)*(fp->ofdm_symbol_size)*((fp->Ncp==1) ? 12 : 14) + 1;
blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength;
// Do decompression of the two parts and generate txdataF
*symbol_number = ((packet_header->frame_status)>>26)&0x000f;
slotoffsetF = (*symbol_number)*(fp->ofdm_symbol_size) + (*subframe)*(fp->ofdm_symbol_size)*((fp->Ncp==1) ? 12 : 14) + 1;
blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength - 1;
for (element_id=0; element_id<db_halflength; element_id++) {
txdataF[0][blockoffsetF+element_id] = alaw2lin[ (data_block[element_id] & 0xff) ];
txdataF[0][blockoffsetF+element_id] |= alaw2lin[ (data_block[element_id]>>8) ]<<16;
i = (uint16_t*) &txdataF[0][blockoffsetF+element_id];
*i = alaw2lin[ (data_block[element_id] & 0xff) ];
*(i+1) = alaw2lin[ (data_block[element_id]>>8) ];
txdataF[0][slotoffsetF+element_id] = alaw2lin[ (data_block[element_id+db_halflength] & 0xff) ];
txdataF[0][slotoffsetF+element_id] |= alaw2lin[ (data_block[element_id+db_halflength]>>8) ]<<16;
i = (uint16_t*) &txdataF[0][slotoffsetF+element_id];
*i = alaw2lin[ (data_block[element_id+db_halflength] & 0xff) ];
*(i+1) = alaw2lin[ (data_block[element_id+db_halflength]>>8) ];
}
// Find and return symbol_number
*symbol_number = ((packet_header->frame_status)>>26)&0x000f;
} else if (*packet_type == IF4_PULFFT) {
// Calculate from received packet
slotoffsetF = (*subframe)*(fp->ofdm_symbol_size)*((fp->Ncp==1) ? 12 : 14) + 1;
blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength;
*symbol_number = ((packet_header->frame_status)>>26)&0x000f;
slotoffsetF = (*symbol_number)*(fp->ofdm_symbol_size) + (*subframe)*(fp->ofdm_symbol_size)*((fp->Ncp==1) ? 12 : 14) + 1;
blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength - 1;
// Do decompression of the two parts and generate rxdataF
for (element_id=0; element_id<db_halflength; element_id++) {
rxdataF[0][blockoffsetF+element_id] = alaw2lin[ (data_block[element_id] & 0xff) ];
rxdataF[0][blockoffsetF+element_id] |= alaw2lin[ (data_block[element_id]>>8) ]<<16;
i = (uint16_t*) &rxdataF[0][blockoffsetF+element_id];
*i = alaw2lin[ (data_block[element_id] & 0xff) ];
*(i+1) = alaw2lin[ (data_block[element_id]>>8) ];
rxdataF[0][slotoffsetF+element_id] = alaw2lin[ (data_block[element_id+db_halflength] & 0xff) ];
rxdataF[0][slotoffsetF+element_id] |= alaw2lin[ (data_block[element_id+db_halflength]>>8) ]<<16;
i = (uint16_t*) &rxdataF[0][slotoffsetF+element_id];
*i = alaw2lin[ (data_block[element_id+db_halflength] & 0xff) ];
*(i+1) = alaw2lin[ (data_block[element_id+db_halflength]>>8) ];
}
// Find and return symbol_number
*symbol_number = ((packet_header->frame_status)>>26)&0x000f;
} else if (*packet_type == IF4_PRACH) {
// FIX: hard coded prach samples length
db_fulllength = 839*2;
// Generate uncompressed data blocks
memcpy((rxsigF[0]+slotoffsetF), data_block, db_fulllength*sizeof(int16_t));
memcpy((&rxsigF[0][0]),
(int16_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES+sizeof_IF4_header_t),
db_fulllength*sizeof(int16_t));
} else {
AssertFatal(1==0, "recv_IF4 - Unknown packet_type %x", *packet_type);
}
free(rx_buffer);
return;
}
void gen_IF4_dl_header(IF4_header_t *dl_packet, int frame, int subframe) {
// Set Type and Sub-Type
dl_packet->type = IF4_PACKET_TYPE;
dl_packet->sub_type = IF4_PDLFFT;
// Reset frame status
dl_packet->rsvd = 0;
// Set frame status
dl_packet->frame_status = 0;
dl_packet->frame_status |= (frame&0xffff)<<6;
dl_packet->frame_status |= (subframe&0x000f)<<22;
}
void gen_IF4_ul_header(IF4_header_t *ul_packet, int frame, int subframe) {
// Set Type and Sub-Type
ul_packet->type = IF4_PACKET_TYPE;
ul_packet->sub_type = IF4_PULFFT;
// Leave reserved as it is
ul_packet->rsvd = 0;
// Set frame status
ul_packet->frame_status = 0;
ul_packet->frame_status |= (frame&0xffff)<<6;
ul_packet->frame_status |= (subframe&0x000f)<<22;
}
void gen_IF4_prach_header(IF4_header_t *prach_packet, int frame, int subframe) {
// Set Type and Sub-Type
prach_packet->type = IF4_PACKET_TYPE;
prach_packet->sub_type = IF4_PRACH;
// Leave reserved as it is
prach_packet->rsvd = 0;
// Set LTE Prach configuration
prach_packet->frame_status = 0;
prach_packet->frame_status |= (frame&0xffff)<<6;
prach_packet->frame_status |= (subframe&0x000f)<<22;
}
void malloc_IF4_buffer(PHY_VARS_eNB *eNB) {
// Keep the size large enough
eNB->ifbuffer.tx = malloc(RAW_IF4_PRACH_SIZE_BYTES);
eNB->ifbuffer.rx = malloc(RAW_IF4_PRACH_SIZE_BYTES);
}
......@@ -38,7 +38,6 @@
* \warning
*/
#include <stdint.h>
#include "PHY/defs.h"
/// Macro for IF4 packet type
......@@ -57,7 +56,7 @@ struct IF4_header {
/// Frame Status
uint32_t frame_status;
};
} __attribute__ ((__packed__));
typedef struct IF4_header IF4_header_t;
#define sizeof_IF4_header_t 12
......@@ -71,3 +70,5 @@ void gen_IF4_prach_header(IF4_header_t*, int, int);
void send_IF4(PHY_VARS_eNB*, int, int, uint16_t, int);
void recv_IF4(PHY_VARS_eNB*, int*, int*, uint16_t*, uint32_t*);
void malloc_IF4_buffer(PHY_VARS_eNB*);
#include <stdint.h>
#include "PHY/defs.h"
#include "PHY/LTE_TRANSPORT/if5_mobipass_tools.h"
#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
uint8_t send_IF5(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, uint8_t init_seq) {
uint8_t seqno=init_seq;
void *txp[2];
void *tx_buffer=NULL;
__m128i *data_block=NULL,*main_data_block=NULL;
__m128i *txp128;
__m128i t0, t1;
uint16_t packet_id=0, i;
uint16_t db_fulllength = 640;
tx_buffer = memalign(16, MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t));
IF5_mobipass_header_t *header = (IF5_mobipass_header_t *)(tx_buffer + MAC_HEADER_SIZE_BYTES);
data_block = (__m128i *)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + 4);
main_data_block = data_block;
header->flags = 0;
header->fifo_status = 0;
header->ack = 0;
header->seqno = seqno;
header->rsvd = 0;
txp[0] = (void*)&eNB->common_vars.txdata[0][0][proc->subframe_tx*eNB->frame_parms.samples_per_tti];
txp128 = (__m128i *) txp[0];
for (packet_id=0; packet_id<(7680*2)/640; packet_id++) {
header->time_stamp = proc->timestamp_tx + packet_id*640;
data_block = main_data_block;
for (i=0; i<db_fulllength>>3; i+=2) {
t0 = _mm_srli_epi16(*txp128++, 4);
t1 = _mm_srli_epi16(*txp128++, 4);
*data_block++ = _mm_packs_epi16(t0, t1);
}
// Write the packet to the fronthaul
if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice,
packet_id,
&tx_buffer,
db_fulllength,
1,
IF5_MOBIPASS)) < 0) {
perror("ETHERNET write for IF5_MOBIPASS\n");
}
header->seqno += 1;
}
seqno = header->seqno;
free(tx_buffer);
return(seqno);
}
#include <stdint.h>
#include "PHY/defs.h"
#define IF5_MOBIPASS 0x0050
struct IF5_mobipass_header {
/// Type
uint16_t flags;
/// Sub-Type
uint16_t fifo_status;
/// Reserved
uint8_t seqno;
uint8_t ack;
uint32_t rsvd;
/// Frame Status
uint32_t time_stamp;
} __attribute__ ((__packed__));
typedef struct IF5_mobipass_header IF5_mobipass_header_t;
#define sizeof_IF5_mobipass_header_t 14
uint8_t send_IF5(PHY_VARS_eNB*, eNB_rxtx_proc_t*, uint8_t);
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file PHY/LTE_TRANSPORT/if5_tools.c
* \brief
* \author S. Sandeep Kumar, Raymond Knopp
* \date 2016
* \version 0.1
* \company Eurecom
* \email: ee13b1025@iith.ac.in, knopp@eurecom.fr
* \note
* \warning
*/
#include "PHY/defs.h"
#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe, uint8_t *seqno, uint16_t packet_type) {
LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
void *txp[fp->nb_antennas_tx], *rxp[fp->nb_antennas_rx];
void *tx_buffer=NULL;
uint16_t packet_id=0, i=0;
if (packet_type == IF5_RRH_GW_DL) {
unsigned int spp_eth = eNB->ifdevice.openair0_cfg->samples_per_packet;
unsigned int spsf = eNB->ifdevice.openair0_cfg->samples_per_frame/10;
for (i=0; i < fp->nb_antennas_tx; i++)
txp[i] = (void*)&eNB->common_vars.txdata[0][i][subframe*fp->samples_per_tti];
for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
for (i=0; i < fp->nb_antennas_tx; i++)
txp[i] += packet_id*spp_eth;
eNB->ifdevice.trx_write_func(&eNB->ifdevice,
(proc_timestamp + packet_id*spp_eth),
txp,
spp_eth,
fp->nb_antennas_tx,
0);
}
} else if (packet_type == IF5_RRH_GW_UL) {
unsigned int spp_eth = eNB->ifdevice.openair0_cfg->samples_per_packet;
unsigned int spsf = eNB->ifdevice.openair0_cfg->samples_per_frame/10;
for (i=0; i < fp->nb_antennas_rx; i++)
rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti];
for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) {
for (i=0; i < fp->nb_antennas_rx; i++)
rxp[i] += packet_id*spp_eth;
eNB->ifdevice.trx_write_func(&eNB->ifdevice,
(proc_timestamp + packet_id*spp_eth),
rxp,
spp_eth,
fp->nb_antennas_rx,
0);
}
} else if (packet_type == IF5_MOBIPASS) {
uint16_t db_fulllength=640;
__m128i *data_block=NULL, *data_block_head=NULL;
__m128i *txp128;
__m128i t0, t1;
tx_buffer = memalign(16, MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t));
IF5_mobipass_header_t *header = (IF5_mobipass_header_t *)(tx_buffer + MAC_HEADER_SIZE_BYTES);
data_block_head = (__m128i *)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + 4);
header->flags = 0;
header->fifo_status = 0;
header->seqno = *seqno;
header->ack = 0;
header->word0 = 0;
txp[0] = (void*)&eNB->common_vars.txdata[0][0][subframe*eNB->frame_parms.samples_per_tti];
txp128 = (__m128i *) txp[0];
for (packet_id=0; packet_id<(fp->samples_per_tti*2)/db_fulllength; packet_id++) {
header->time_stamp = proc_timestamp + packet_id*db_fulllength;
data_block = data_block_head;
for (i=0; i<db_fulllength>>3; i+=2) {
t0 = _mm_srli_epi16(*txp128++, 4);
t1 = _mm_srli_epi16(*txp128++, 4);
*data_block++ = _mm_packs_epi16(t0, t1);
}
// Write the packet to the fronthaul
if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice,
packet_id,
&tx_buffer,
db_fulllength,
1,
IF5_MOBIPASS)) < 0) {
perror("ETHERNET write for IF5_MOBIPASS\n");
}