benetel 4g: support two antennas
This commit is contained in:
@@ -163,8 +163,8 @@ int trx_benetel_ctlrecv(openair0_device *device, void *msg, ssize_t msg_len)
|
|||||||
cap->FH_fmt = OAI_IF4p5_only;
|
cap->FH_fmt = OAI_IF4p5_only;
|
||||||
cap->num_bands = 1;
|
cap->num_bands = 1;
|
||||||
cap->band_list[0] = 7;
|
cap->band_list[0] = 7;
|
||||||
cap->nb_rx[0] = 1;
|
cap->nb_rx[0] = device->openair0_cfg->rx_num_channels;
|
||||||
cap->nb_tx[0] = 1;
|
cap->nb_tx[0] = device->openair0_cfg->tx_num_channels;
|
||||||
cap->max_pdschReferenceSignalPower[0] = -27;
|
cap->max_pdschReferenceSignalPower[0] = -27;
|
||||||
cap->max_rxgain[0] = 90;
|
cap->max_rxgain[0] = 90;
|
||||||
|
|
||||||
@@ -194,11 +194,12 @@ void benetel_fh_if4p5_south_in(RU_t *ru,
|
|||||||
LTE_DL_FRAME_PARMS *fp;
|
LTE_DL_FRAME_PARMS *fp;
|
||||||
int symbol;
|
int symbol;
|
||||||
int32_t *rxdata;
|
int32_t *rxdata;
|
||||||
int antenna = 0;
|
int antenna;
|
||||||
|
|
||||||
lock_ul_buffer(&s->buffers, *subframe);
|
lock_ul_buffer(&s->buffers, *subframe);
|
||||||
next:
|
next:
|
||||||
while (!(s->buffers.ul_busy[*subframe] == 0x3fff ||
|
while (!((s->buffers.ul_busy[0][*subframe] == 0x3fff &&
|
||||||
|
s->buffers.ul_busy[1][*subframe] == 0x3fff) ||
|
||||||
s->buffers.prach_busy[*subframe] == 1))
|
s->buffers.prach_busy[*subframe] == 1))
|
||||||
wait_ul_buffer(&s->buffers, *subframe);
|
wait_ul_buffer(&s->buffers, *subframe);
|
||||||
if (s->buffers.prach_busy[*subframe] == 1) {
|
if (s->buffers.prach_busy[*subframe] == 1) {
|
||||||
@@ -217,24 +218,27 @@ next:
|
|||||||
|
|
||||||
eNB = eNB_list[0];
|
eNB = eNB_list[0];
|
||||||
fp = &eNB->frame_parms;
|
fp = &eNB->frame_parms;
|
||||||
for (symbol = 0; symbol < 14; symbol++) {
|
for (antenna = 0; antenna < ru->nb_rx; antenna++) {
|
||||||
int i;
|
for (symbol = 0; symbol < 14; symbol++) {
|
||||||
uint16_t *p = (uint16_t *)(&s->buffers.ul[*subframe][symbol*1200*4]);
|
int i;
|
||||||
for (i = 0; i < 1200*2; i++) {
|
uint16_t *p = (uint16_t *)(&s->buffers.ul[antenna][*subframe][symbol*1200*4]);
|
||||||
p[i] = htons(p[i]);
|
for (i = 0; i < 1200*2; i++) {
|
||||||
}
|
p[i] = htons(p[i]);
|
||||||
rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size];
|
}
|
||||||
|
rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size];
|
||||||
#if 1
|
#if 1
|
||||||
memcpy(rxdata + 2048 - 600,
|
memcpy(rxdata + 2048 - 600,
|
||||||
&s->buffers.ul[*subframe][symbol*1200*4],
|
&s->buffers.ul[antenna][*subframe][symbol*1200*4],
|
||||||
600 * 4);
|
600 * 4);
|
||||||
memcpy(rxdata,
|
memcpy(rxdata,
|
||||||
&s->buffers.ul[*subframe][symbol*1200*4] + 600*4,
|
&s->buffers.ul[antenna][*subframe][symbol*1200*4] + 600*4,
|
||||||
600 * 4);
|
600 * 4);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s->buffers.ul_busy[*subframe] = 0;
|
s->buffers.ul_busy[0][*subframe] = 0;
|
||||||
|
s->buffers.ul_busy[1][*subframe] = 0;
|
||||||
signal_ul_buffer(&s->buffers, *subframe);
|
signal_ul_buffer(&s->buffers, *subframe);
|
||||||
unlock_ul_buffer(&s->buffers, *subframe);
|
unlock_ul_buffer(&s->buffers, *subframe);
|
||||||
|
|
||||||
@@ -272,45 +276,49 @@ void benetel_fh_if4p5_south_out(RU_t *ru,
|
|||||||
LTE_DL_FRAME_PARMS *fp;
|
LTE_DL_FRAME_PARMS *fp;
|
||||||
int symbol;
|
int symbol;
|
||||||
int32_t *txdata;
|
int32_t *txdata;
|
||||||
int aa = 0;
|
int aa;
|
||||||
|
|
||||||
//printf("BENETEL: %s (f.sf %d.%d ts %ld)\n", __FUNCTION__, frame, subframe, timestamp);
|
//printf("BENETEL: %s (f.sf %d.%d ts %ld)\n", __FUNCTION__, frame, subframe, timestamp);
|
||||||
|
|
||||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
|
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
|
||||||
|
|
||||||
lock_dl_buffer(&s->buffers, subframe);
|
lock_dl_buffer(&s->buffers, subframe);
|
||||||
if (s->buffers.dl_busy[subframe]) {
|
if (s->buffers.dl_busy[0][subframe] ||
|
||||||
|
s->buffers.dl_busy[1][subframe]) {
|
||||||
printf("%s: fatal: DL buffer busy for subframe %d\n", __FUNCTION__, subframe);
|
printf("%s: fatal: DL buffer busy for subframe %d\n", __FUNCTION__, subframe);
|
||||||
unlock_dl_buffer(&s->buffers, subframe);
|
unlock_dl_buffer(&s->buffers, subframe);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
eNB = eNB_list[0];
|
eNB = eNB_list[0];
|
||||||
fp = &eNB->frame_parms;
|
fp = &eNB->frame_parms;
|
||||||
if (ru->num_eNB != 1 || ru->nb_tx != 1 || fp->ofdm_symbol_size != 2048 ||
|
if (ru->num_eNB != 1 || fp->ofdm_symbol_size != 2048 ||
|
||||||
fp->Ncp != NORMAL || fp->symbols_per_tti != 14) {
|
fp->Ncp != NORMAL || fp->symbols_per_tti != 14) {
|
||||||
printf("%s:%d:%s: unsupported configuration\n",
|
printf("%s:%d:%s: unsupported configuration\n",
|
||||||
__FILE__, __LINE__, __FUNCTION__);
|
__FILE__, __LINE__, __FUNCTION__);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (symbol = 0; symbol < 14; symbol++) {
|
for (aa = 0; aa < ru->nb_tx; aa++) {
|
||||||
txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size];
|
for (symbol = 0; symbol < 14; symbol++) {
|
||||||
|
txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size];
|
||||||
#if 1
|
#if 1
|
||||||
memcpy(&s->buffers.dl[subframe][symbol*1200*4],
|
memcpy(&s->buffers.dl[aa][subframe][symbol*1200*4],
|
||||||
txdata + 2048 - 600,
|
txdata + 2048 - 600,
|
||||||
600 * 4);
|
600 * 4);
|
||||||
memcpy(&s->buffers.dl[subframe][symbol*1200*4] + 600*4,
|
memcpy(&s->buffers.dl[aa][subframe][symbol*1200*4] + 600*4,
|
||||||
txdata + 1,
|
txdata + 1,
|
||||||
600 * 4);
|
600 * 4);
|
||||||
#endif
|
#endif
|
||||||
int i;
|
int i;
|
||||||
uint16_t *p = (uint16_t *)(&s->buffers.dl[subframe][symbol*1200*4]);
|
uint16_t *p = (uint16_t *)(&s->buffers.dl[aa][subframe][symbol*1200*4]);
|
||||||
for (i = 0; i < 1200*2; i++) {
|
for (i = 0; i < 1200*2; i++) {
|
||||||
p[i] = htons(p[i]);
|
p[i] = htons(p[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s->buffers.dl_busy[subframe] = 0x3fff;
|
s->buffers.dl_busy[0][subframe] = 0x3fff;
|
||||||
|
s->buffers.dl_busy[1][subframe] = 0x3fff;
|
||||||
unlock_dl_buffer(&s->buffers, subframe);
|
unlock_dl_buffer(&s->buffers, subframe);
|
||||||
|
|
||||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_IF4P5_SOUTH_OUT_RU+ru->idx, ru->proc.frame_tx);
|
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_IF4P5_SOUTH_OUT_RU+ru->idx, ru->proc.frame_tx);
|
||||||
|
|||||||
@@ -233,19 +233,20 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && ANT_NUM == 0x00) {
|
if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce) {
|
||||||
p.frame = FRAME;
|
p.frame = FRAME;
|
||||||
p.subframe = SUBFRAME >> 4;
|
p.subframe = SUBFRAME >> 4;
|
||||||
p.slot = 0; /* unused */
|
p.slot = 0; /* unused */
|
||||||
p.symbol = SYMBOL;
|
p.symbol = SYMBOL;
|
||||||
p.antenna = 0;
|
p.antenna = ANT_NUM;
|
||||||
memcpy(p.iq, IQ_ptr, 4800);
|
memcpy(p.iq, IQ_ptr, 4800);
|
||||||
store_ul(bs, &p);
|
store_ul(bs, &p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// U-PLANE UL ANT_0 PROCESSING
|
// U-PLANE UL PROCESSING
|
||||||
if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && ANT_NUM == 0x00 && dl_start == 1)
|
if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && dl_start == 1)
|
||||||
{
|
{
|
||||||
|
int a = ANT_NUM;
|
||||||
int tx_frame = FRAME;
|
int tx_frame = FRAME;
|
||||||
int tx_subframe = SUBFRAME >> 4;
|
int tx_subframe = SUBFRAME >> 4;
|
||||||
int tx_symbol = SYMBOL + 5;
|
int tx_symbol = SYMBOL + 5;
|
||||||
@@ -266,33 +267,20 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs)
|
|||||||
SUBFRAME = tx_subframe << 4;
|
SUBFRAME = tx_subframe << 4;
|
||||||
SYMBOL = tx_symbol;
|
SYMBOL = tx_symbol;
|
||||||
|
|
||||||
/* antenna 0 - send actual DL data (if available) */
|
/* send actual DL data (if available) */
|
||||||
lock_dl_buffer(bs->buffers, tx_subframe);
|
lock_dl_buffer(bs->buffers, tx_subframe);
|
||||||
if (!(bs->buffers->dl_busy[tx_subframe] & (1 << tx_symbol))) {
|
if (!(bs->buffers->dl_busy[a][tx_subframe] & (1 << tx_symbol))) {
|
||||||
printf("%s: warning, DL underflow (sf.symbol %d.%d)\n", __FUNCTION__,
|
printf("%s: warning, DL underflow (antenna %d sf.symbol %d.%d)\n",
|
||||||
|
__FUNCTION__,
|
||||||
|
a,
|
||||||
tx_subframe, tx_symbol);
|
tx_subframe, tx_symbol);
|
||||||
memset(IQ_ptr, 0, 1200 * 4);
|
memset(IQ_ptr, 0, 1200 * 4);
|
||||||
} else {
|
} else {
|
||||||
memcpy(IQ_ptr, bs->buffers->dl[tx_subframe] + tx_symbol * 1200*4,
|
memcpy(IQ_ptr, bs->buffers->dl[a][tx_subframe] + tx_symbol * 1200*4,
|
||||||
1200*4);
|
1200*4);
|
||||||
}
|
}
|
||||||
bs->buffers->dl_busy[tx_subframe] &= ~(1 << tx_symbol);
|
bs->buffers->dl_busy[a][tx_subframe] &= ~(1 << tx_symbol);
|
||||||
unlock_dl_buffer(bs->buffers, tx_subframe);
|
unlock_dl_buffer(bs->buffers, tx_subframe);
|
||||||
|
|
||||||
// fill DL Data for ant 0 with 0 value
|
|
||||||
// memset(IQ_ptr, 0, 4800);
|
|
||||||
}
|
|
||||||
|
|
||||||
// U-PLANE UL ANT_1 PROCESSING
|
|
||||||
else if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && ANT_NUM == 0x01 && dl_start == 1)
|
|
||||||
{
|
|
||||||
|
|
||||||
// ANT_NUM = 0x01;
|
|
||||||
SYMBOL = (SYMBOL + 5) % 14;
|
|
||||||
PAYLOAD_2 = 0xc8;
|
|
||||||
|
|
||||||
// fill DL Data for ant 1 with 0 value
|
|
||||||
memset(IQ_ptr, 0, 4800);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// U-PLANE PRACH PROCESSING
|
// U-PLANE PRACH PROCESSING
|
||||||
|
|||||||
@@ -27,37 +27,36 @@
|
|||||||
|
|
||||||
void store_ul(benetel_t *bs, ul_packet_t *ul)
|
void store_ul(benetel_t *bs, ul_packet_t *ul)
|
||||||
{
|
{
|
||||||
/* only antenna 0 for the moment */
|
int a = ul->antenna;
|
||||||
if (ul->antenna != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (ul->subframe != bs->next_subframe ||
|
if (ul->subframe != bs->next_subframe[a] ||
|
||||||
ul->symbol != bs->next_symbol) {
|
ul->symbol != bs->next_symbol[a]) {
|
||||||
printf("%s: fatal, expected frame.sf.symbol %d.%d.%d, got %d.%d.%d\n",
|
printf("%s: fatal, antenna %d expected frame.sf.symbol %d.%d.%d, got %d.%d.%d\n",
|
||||||
__FUNCTION__,
|
__FUNCTION__,
|
||||||
bs->expected_benetel_frame, bs->next_subframe, bs->next_symbol,
|
a,
|
||||||
|
bs->expected_benetel_frame[a], bs->next_subframe[a], bs->next_symbol[a],
|
||||||
ul->frame, ul->subframe, ul->symbol);
|
ul->frame, ul->subframe, ul->symbol);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock_ul_buffer(bs->buffers, bs->next_subframe);
|
lock_ul_buffer(bs->buffers, bs->next_subframe[a]);
|
||||||
if (bs->buffers->ul_busy[bs->next_subframe] & (1 << bs->next_symbol)) {
|
if (bs->buffers->ul_busy[a][bs->next_subframe[a]] & (1 << bs->next_symbol[a])) {
|
||||||
printf("%s: warning, UL overflow (sf.symbol %d.%d)\n", __FUNCTION__,
|
printf("%s: warning, UL overflow (sf.symbol %d.%d)\n", __FUNCTION__,
|
||||||
bs->next_subframe, bs->next_symbol);
|
bs->next_subframe[a], bs->next_symbol[a]);
|
||||||
}
|
}
|
||||||
memcpy(bs->buffers->ul[bs->next_subframe] + bs->next_symbol * 1200*4,
|
memcpy(bs->buffers->ul[a][bs->next_subframe[a]] + bs->next_symbol[a] * 1200*4,
|
||||||
ul->iq, 1200*4);
|
ul->iq, 1200*4);
|
||||||
bs->buffers->ul_busy[bs->next_subframe] |= (1 << bs->next_symbol);
|
bs->buffers->ul_busy[a][bs->next_subframe[a]] |= (1 << bs->next_symbol[a]);
|
||||||
signal_ul_buffer(bs->buffers, bs->next_subframe);
|
signal_ul_buffer(bs->buffers, bs->next_subframe[a]);
|
||||||
unlock_ul_buffer(bs->buffers, bs->next_subframe);
|
unlock_ul_buffer(bs->buffers, bs->next_subframe[a]);
|
||||||
|
|
||||||
bs->next_symbol++;
|
bs->next_symbol[a]++;
|
||||||
if (bs->next_symbol == 14) {
|
if (bs->next_symbol[a] == 14) {
|
||||||
bs->next_symbol = 0;
|
bs->next_symbol[a] = 0;
|
||||||
bs->next_subframe = (bs->next_subframe + 1) % 10;
|
bs->next_subframe[a] = (bs->next_subframe[a] + 1) % 10;
|
||||||
if (bs->next_subframe == 0) {
|
if (bs->next_subframe[a] == 0) {
|
||||||
bs->expected_benetel_frame++;
|
bs->expected_benetel_frame[a]++;
|
||||||
bs->expected_benetel_frame &= 255;
|
bs->expected_benetel_frame[a] &= 255;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,9 +26,10 @@
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
shared_buffers *buffers;
|
shared_buffers *buffers;
|
||||||
int next_subframe;
|
/* [2] is for two antennas */
|
||||||
int next_symbol;
|
int next_subframe[2];
|
||||||
int expected_benetel_frame;
|
int next_symbol[2];
|
||||||
|
int expected_benetel_frame[2];
|
||||||
char *dpdk_main_command_line;
|
char *dpdk_main_command_line;
|
||||||
} benetel_t;
|
} benetel_t;
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,8 @@ void *benetel_start_dpdk(char *ifname, shared_buffers *buffers, char *dpdk_main_
|
|||||||
|
|
||||||
bs->buffers = buffers;
|
bs->buffers = buffers;
|
||||||
|
|
||||||
bs->expected_benetel_frame = 255;
|
bs->expected_benetel_frame[0] = 255;
|
||||||
|
bs->expected_benetel_frame[1] = 255;
|
||||||
|
|
||||||
bs->dpdk_main_command_line = dpdk_main_command_line;
|
bs->dpdk_main_command_line = dpdk_main_command_line;
|
||||||
|
|
||||||
|
|||||||
@@ -44,9 +44,12 @@ void init_buffers(shared_buffers *s)
|
|||||||
/* in FDD the eNB's first transmitted DL subframe is 4 but the device
|
/* in FDD the eNB's first transmitted DL subframe is 4 but the device
|
||||||
* needs to have subframes 1, 2 and 3 ready. Let's pretend there are ready.
|
* needs to have subframes 1, 2 and 3 ready. Let's pretend there are ready.
|
||||||
*/
|
*/
|
||||||
s->dl_busy[1] = 0x3fff;
|
s->dl_busy[0][1] = 0x3fff;
|
||||||
s->dl_busy[2] = 0x3fff;
|
s->dl_busy[0][2] = 0x3fff;
|
||||||
s->dl_busy[3] = 0x3fff;
|
s->dl_busy[0][3] = 0x3fff;
|
||||||
|
s->dl_busy[1][1] = 0x3fff;
|
||||||
|
s->dl_busy[1][2] = 0x3fff;
|
||||||
|
s->dl_busy[1][3] = 0x3fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lock_dl_buffer(shared_buffers *s, int subframe)
|
void lock_dl_buffer(shared_buffers *s, int subframe)
|
||||||
|
|||||||
@@ -26,10 +26,11 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned char dl[10][14*1200*4];
|
/* [2] is for two antennas */
|
||||||
unsigned char ul[10][14*1200*4];
|
unsigned char dl[2][10][14*1200*4];
|
||||||
uint16_t dl_busy[10];
|
unsigned char ul[2][10][14*1200*4];
|
||||||
uint16_t ul_busy[10];
|
uint16_t dl_busy[2][10];
|
||||||
|
uint16_t ul_busy[2][10];
|
||||||
|
|
||||||
pthread_mutex_t m_ul[10];
|
pthread_mutex_t m_ul[10];
|
||||||
pthread_cond_t c_ul[10];
|
pthread_cond_t c_ul[10];
|
||||||
|
|||||||
Reference in New Issue
Block a user