Commit 17322170 authored by David Price's avatar David Price

Merged RU-RAU-split as of 18 Oct

parents 1ec934f9 599ba826
......@@ -13,6 +13,16 @@ containing lines:
SUBSYSTEM=="tty", ENV{ID_VENDOR_ID}=="1a8d", ENV{ID_MODEL_ID}=="100d", ENV{ID_SERIAL_SHORT}=="357473040068155", ENV{ID_USB_INTERFACE_NUM}=="00", SYMLINK+="bandrich.data", MODE="0666"
SUBSYSTEM=="tty", ENV{ID_VENDOR_ID}=="1a8d", ENV{ID_MODEL_ID}=="100d", ENV{ID_SERIAL_SHORT}=="357473040068155", ENV{ID_USB_INTERFACE_NUM}=="02", SYMLINK+="bandrich.control", MODE="0666"
To avoid NetworkManager to play with the bandrich, add also the line:
ENV{ID_VENDOR_ID}=="1a8d", ENV{ID_MM_DEVICE_IGNORE}="1"
Maybe also add; , ENV{ID_MM_DEVICE_IGNORE}="1"
to the two other lines.
Then run: udevadm control --reload-rules
And: service network-manager restart
Change vendor_id/model_id/serial/interface num to match yours.
Use lsusb -v to find values.
......
......@@ -36,7 +36,7 @@ static void get_message(int s)
int is_on;
if (read(s, &t, 1) != 1) QUIT("get_message fails");
printf("got mess %d\n", t);
printf("T tracer: got mess %d\n", t);
switch (t) {
case 0:
/* toggle all those IDs */
......
......@@ -63,7 +63,7 @@ static int get_connection(char *addr, int port)
socklen_t alen;
int s, t;
printf("waiting for connection on %s:%d\n", addr, port);
printf("T tracer: waiting for connection on %s:%d\n", addr, port);
s = socket(AF_INET, SOCK_STREAM, 0);
if (s == -1) { perror("socket"); exit(1); }
......@@ -82,7 +82,7 @@ static int get_connection(char *addr, int port)
if (t == -1) { perror("accept"); exit(1); }
close(s);
printf("connected\n");
printf("T tracer: connected\n");
return t;
}
......@@ -150,7 +150,7 @@ process:
while (size) {
int l = write(f->socket_remote, b, size);
if (l <= 0) {
printf("forward error\n");
printf("T tracer: forward error\n");
close(f->socket_remote);
f->socket_remote = -1;
break;
......@@ -268,7 +268,7 @@ static void *forwarder(int port, int s)
f->memusage = 0;
f->last_warning_memusage = 0;
printf("waiting for remote tracer on port %d\n", port);
printf("T tracer: waiting for remote tracer on port %d\n", port);
f->remote_port = port;
f->socket_remote = get_connection("0.0.0.0", port);
......@@ -305,7 +305,7 @@ static void forward(void *_forwarder, char *buf, int size)
if (f->memusage > f->last_warning_memusage &&
f->memusage - f->last_warning_memusage > 100000000) {
f->last_warning_memusage += 100000000;
printf("WARNING: memory usage is over %"PRIu64"MB\n",
printf("T tracer: WARNING: memory usage is over %"PRIu64"MB\n",
f->last_warning_memusage / 1000000);
} else
if (f->memusage < f->last_warning_memusage &&
......
......@@ -36,7 +36,8 @@ void reset_ue_ids(void)
int ue_id_from_rnti(void *_priv, int rnti)
{
rnti = 0; /* HACK, to be removed */
if (rnti < 0) rnti = 65534; /* HACK, to be removed */
if (rnti < 0 || rnti > 65535) { printf("bad rnti %d\n", rnti); exit(1); }
/* rnti not seen yet? give it a new ue_id */
if (ue_id[rnti] == -1) {
......@@ -93,6 +94,7 @@ typedef struct {
enb_gui *e;
int ue; /* what UE is displayed in the UE specific views */
void *database;
int nb_rb;
} enb_data;
void is_on_changed(void *_d)
......@@ -120,27 +122,6 @@ connection_dies:
if (pthread_mutex_unlock(&d->lock)) abort();
}
void usage(void)
{
printf(
"options:\n"
" -d <database file> this option is mandatory\n"
" -on <GROUP or ID> turn log ON for given GROUP or ID\n"
" -off <GROUP or ID> turn log OFF for given GROUP or ID\n"
" -ON turn all logs ON\n"
" -OFF turn all logs OFF\n"
" note: you may pass several -on/-off/-ON/-OFF,\n"
" they will be processed in order\n"
" by default, all is off\n"
" -ip <host> connect to given IP address (default %s)\n"
" -p <port> connect to given port (default %d)\n"
" -debug-gui activate GUI debug logs\n",
DEFAULT_REMOTE_IP,
DEFAULT_REMOTE_PORT
);
exit(1);
}
static void *gui_thread(void *_g)
{
gui *g = _g;
......@@ -313,14 +294,14 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database,
input_signal_plot = new_xy_plot(g, 256, 55, "input signal", 20);
widget_add_child(g, line, input_signal_plot, -1);
xy_plot_set_range(g, input_signal_plot, 0, 7680*10, 20, 70);
xy_plot_set_range(g, input_signal_plot, 0, 7680*10 * ed->nb_rb/25, 20, 70);
input_signal_log = new_framelog(h, database,
"ENB_PHY_INPUT_SIGNAL", "subframe", "rxdata");
/* a skip value of 10 means to process 1 frame over 10, that is
* more or less 10 frames per second
*/
framelog_set_skip(input_signal_log, 10);
input_signal_view = new_view_xy(7680*10, 10,
input_signal_view = new_view_xy(7680*10 * ed->nb_rb/25, 10,
g, input_signal_plot, new_color(g, "#0c0c72"), XY_LOOP_MODE);
logger_add_view(input_signal_log, input_signal_view);
......@@ -660,6 +641,28 @@ void view_add_log(view *v, char *log, event_handler *h, void *database,
on_off(database, log, is_on, 1);
}
void usage(void)
{
printf(
"options:\n"
" -d <database file> this option is mandatory\n"
" -rb <RBs> setup for this number of RBs (default 25)\n"
" -on <GROUP or ID> turn log ON for given GROUP or ID\n"
" -off <GROUP or ID> turn log OFF for given GROUP or ID\n"
" -ON turn all logs ON\n"
" -OFF turn all logs OFF\n"
" note: you may pass several -on/-off/-ON/-OFF,\n"
" they will be processed in order\n"
" by default, all is off\n"
" -ip <host> connect to given IP address (default %s)\n"
" -p <port> connect to given port (default %d)\n"
" -debug-gui activate GUI debug logs\n",
DEFAULT_REMOTE_IP,
DEFAULT_REMOTE_PORT
);
exit(1);
}
int main(int n, char **v)
{
extern int volatile gui_logd;
......@@ -680,6 +683,8 @@ int main(int n, char **v)
reset_ue_ids();
enb_data.nb_rb = 25;
/* write on a socket fails if the other end is closed and we get SIGPIPE */
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) abort();
......@@ -690,6 +695,8 @@ int main(int n, char **v)
if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage();
if (!strcmp(v[i], "-d"))
{ if (i > n-2) usage(); database_filename = v[++i]; continue; }
if (!strcmp(v[i], "-rb"))
{ if (i > n-2) usage(); enb_data.nb_rb = atoi(v[++i]); continue; }
if (!strcmp(v[i], "-ip")) { if (i > n-2) usage(); ip = v[++i]; continue; }
if (!strcmp(v[i], "-p"))
{ if (i > n-2) usage(); port = atoi(v[++i]); continue; }
......@@ -705,6 +712,11 @@ int main(int n, char **v)
usage();
}
switch (enb_data.nb_rb) {
case 25: case 50: case 100: break;
default: printf("ERROR, bad value for -rb (%d)\n", enb_data.nb_rb); exit(1);
}
if (database_filename == NULL) {
printf("ERROR: provide a database file (-d)\n");
exit(1);
......
......@@ -12,7 +12,9 @@ void usage(void)
"usage: [options] <file> <frame> <subframe>\n"
"options:\n"
" -d <database file> this option is mandatory\n"
" -o <output file> this option is mandatory\n"
" -v verbose\n"
" -c <number of subframes> default to 1\n"
);
exit(1);
}
......@@ -25,15 +27,23 @@ int main(int n, char **v)
int input_event_id;
database_event_format f;
char *file = NULL;
char *output_file = NULL;
FILE *out;
int fd;
int frame = -1, subframe = -1;
int frame_arg, subframe_arg, buffer_arg;
int verbose = 0;
int number_of_subframes = 1;
int processed_subframes = 0;
for (i = 1; i < n; i++) {
if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage();
if (!strcmp(v[i], "-d"))
{ if (i > n-2) usage(); database_filename = v[++i]; continue; }
if (!strcmp(v[i], "-o"))
{ if (i > n-2) usage(); output_file = v[++i]; continue; }
if (!strcmp(v[i], "-c"))
{ if (i > n-2) usage(); number_of_subframes = atoi(v[++i]); continue; }
if (!strcmp(v[i], "-v")) { verbose = 1; continue; }
if (file == NULL) { file = v[i]; continue; }
if (frame == -1) { frame = atoi(v[i]); continue; }
......@@ -47,6 +57,19 @@ int main(int n, char **v)
exit(1);
}
if (number_of_subframes < 1) {
printf("bad value for option -c, must be at least 1 and is %d\n",
number_of_subframes);
exit(1);
}
if (output_file == NULL) {
printf("gimme -o <output file>, thanks\n");
exit(1);
}
out = fopen(output_file, "w"); if(out==NULL){perror(output_file);exit(1);}
database = parse_database(database_filename);
load_config_file(database_filename);
......@@ -99,11 +122,22 @@ short *x = e.e[buffer_arg].b;
x[i] *= 14;
}
#endif
fwrite(e.e[buffer_arg].b, e.e[buffer_arg].bsize, 1, stdout);
fflush(stdout);
return 0;
if (fwrite(e.e[buffer_arg].b, e.e[buffer_arg].bsize, 1, out) != 1)
{ perror(output_file); exit(1); }
processed_subframes++;
number_of_subframes--;
if (!number_of_subframes) {
if (fclose(out)) perror(output_file);
printf("%d subframes dumped\n", processed_subframes);
return 0;
}
subframe++;
if (subframe == 10) { subframe = 0; frame=(frame+1)%1024; }
}
printf("frame %d subframe %d not found\n", frame, subframe);
printf("%d subframes dumped\n", processed_subframes);
fclose(out);
return 0;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -267,33 +267,28 @@ int32_t temp_in_ifft_0[2048*2] __attribute__((aligned(32)));
#endif
}
// Convert to time domain for visualization
memset(temp_in_ifft_0,0,frame_parms->ofdm_symbol_size*sizeof(int32_t));
for(i=0; i<Msc_RS; i++)
((int32_t*)temp_in_ifft_0)[i] = ul_ch_estimates[aa][symbol_offset+i];
switch(frame_parms->N_RB_DL) {
case 6:
idft128((int16_t*) temp_in_ifft_0,
(int16_t*) ul_ch_estimates_time[aa],
1);
break;
case 25:
idft512((int16_t*) temp_in_ifft_0,
(int16_t*) ul_ch_estimates_time[aa],
1);
break;
case 50:
idft1024((int16_t*) temp_in_ifft_0,
(int16_t*) ul_ch_estimates_time[aa],
1);
break;
case 100:
idft2048((int16_t*) temp_in_ifft_0,
(int16_t*) ul_ch_estimates_time[aa],
1);
......
......@@ -2262,11 +2262,18 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
y[0] = &yseq0[0];
y[1] = &yseq1[0];
#if 0
// reset all bits to <NIL>, here we set <NIL> elements as 2
// memset(e, 2, DCI_BITS_MAX);
// here we interpret NIL as a random QPSK sequence. That makes power estimation easier.
for (i=0; i<DCI_BITS_MAX; i++)
e[i]=taus()&1;
#endif
/* clear all bits, the above code may generate too much false detections
* (not sure about this, to be checked somehow)
*/
memset(e, 0, DCI_BITS_MAX);
e_ptr = e;
......
......@@ -835,11 +835,13 @@ int8_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type)
LOG_D(PHY,"searching for rnti %x : UE index %d=> harq_mask %x, rnti %x, first_free_index %d\n",
rnti,i,eNB->dlsch[i][0]->harq_mask,eNB->dlsch[i][0]->rnti,first_free_index);
if ((eNB->dlsch[i][0]->harq_mask >0) &&
(eNB->dlsch[i][0]->rnti==rnti)) return(i);
(eNB->dlsch[i][0]->rnti==rnti)) return i;
else if ((eNB->dlsch[i][0]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i;
}
if (type == SEARCH_EXIST) return(-1);
else return(first_free_index);
if (type == SEARCH_EXIST) return -1;
if (first_free_index != -1)
eNB->dlsch[first_free_index][0]->rnti = 0;
return first_free_index;
}
int8_t find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type)
......@@ -849,13 +851,15 @@ int8_t find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type)
AssertFatal(eNB!=NULL,"eNB is null\n");
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
AssertFatal(eNB->ulsch[i]!=NULL,"eNB->dlsch[%d] is null\n",i);
AssertFatal(eNB->ulsch[i]!=NULL,"eNB->ulsch[%d] is null\n",i);
if ((eNB->ulsch[i]->harq_mask >0) &&
(eNB->ulsch[i]->rnti==rnti)) return(i);
(eNB->ulsch[i]->rnti==rnti)) return i;
else if ((eNB->ulsch[i]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i;
}
if (type == SEARCH_EXIST) return(-1);
else return(first_free_index);
if (type == SEARCH_EXIST) return -1;
if (first_free_index != -1)
eNB->ulsch[first_free_index]->rnti = 0;
return first_free_index;
}
......@@ -929,7 +933,6 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci
dlsch0_harq->round=0;
}
else { // process is inactive, so activate and set round to 0
dlsch0->harq_mask |= (1<<rel8->harq_process);
dlsch0_harq->round=0;
}
dlsch0_harq->ndi = rel8->new_data_indicator_1;
......@@ -937,8 +940,8 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci
dlsch0->active = 1;
if (rel8->rnti_type == 2)
dlsch0_harq->round = 0;
LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) \n",rel8->harq_process,dlsch0->harq_mask,dlsch0_harq->round,
dlsch0_harq->ndi,rel8->new_data_indicator_1);
LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n",rel8->harq_process,dlsch0->harq_mask,dlsch0_harq->round,
dlsch0_harq->ndi,rel8->new_data_indicator_1, rel8->rnti_type);
switch (rel8->dci_format) {
......@@ -1127,6 +1130,8 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) \n",rel8->harq_
if (dlsch0_harq->round == 0)
dlsch0_harq->status = ACTIVE;
dlsch0->harq_mask |= (1<<rel8->harq_process);
if (rel8->rnti_type == 1) LOG_I(PHY,"DCI 1A: round %d, mcs %d, rballoc %x,rv %d, rnti %x\n",dlsch0_harq->round,rel8->mcs_1,rel8->resource_block_coding,rel8->redundancy_version_1,rel8->rnti);
break;
......@@ -1288,6 +1293,7 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) \n",rel8->harq_
LOG_D(PHY,"DCI: Set harq_ids[%d] to %d (%p)\n",subframe,rel8->harq_process,dlsch0);
dlsch0->harq_ids[subframe] = rel8->harq_process;
dlsch0->harq_mask |= (1<<rel8->harq_process);
dlsch0->rnti = rel8->rnti;
......@@ -2283,11 +2289,6 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d
void fill_dci0(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,
nfapi_hi_dci0_dci_pdu *pdu)
{
uint8_t UE_id;
AssertFatal((UE_id=find_ulsch(pdu->dci_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0,
"No existing UE ULSCH for rnti %x\n",pdu->dci_pdu_rel8.rnti);
LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
uint32_t cqi_req = pdu->dci_pdu_rel8.cqi_csi_request;
......@@ -2447,17 +2448,15 @@ void fill_dci0(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,
}
}
void fill_ulsch(PHY_VARS_eNB *eNB,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame,int subframe) {
void fill_ulsch(PHY_VARS_eNB *eNB,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame,int subframe)
{
uint8_t harq_pid;
uint8_t UE_id;
boolean_t new_ulsch = (find_ulsch(ulsch_pdu->ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST)==-1) ? TRUE : FALSE;
AssertFatal((UE_id=find_ulsch(ulsch_pdu->ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0,
"No existing/free UE ULSCH for rnti %x\n",ulsch_pdu->ulsch_pdu_rel8.rnti);
boolean_t new_ulsch = (find_ulsch(ulsch_pdu->ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST)==-1) ? TRUE : FALSE;
LTE_eNB_ULSCH_t *ulsch=eNB->ulsch[UE_id];
LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
......@@ -2465,6 +2464,7 @@ void fill_ulsch(PHY_VARS_eNB *eNB,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame
harq_pid = ulsch_pdu->ulsch_pdu_rel8.harq_process_number;
ulsch->harq_mask |= 1 << harq_pid;
ulsch->harq_processes[harq_pid]->frame = frame;
ulsch->harq_processes[harq_pid]->subframe = subframe;
......@@ -2500,12 +2500,10 @@ void fill_ulsch(PHY_VARS_eNB *eNB,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame
else if(ulsch->harq_processes[harq_pid]->n_DMRS == 7)
ulsch->harq_processes[harq_pid]->n_DMRS2 = 9;
LOG_D(PHY,"[eNB %d][PUSCH %d] Programming PUSCH with n_DMRS2 %d (cshift %d) for Frame %d, Subframe %d\n",
eNB->Mod_id,harq_pid,ulsch->harq_processes[harq_pid]->n_DMRS2,ulsch->harq_processes[harq_pid]->n_DMRS,
frame,subframe);
ulsch->harq_processes[harq_pid]->rvidx = ulsch_pdu->ulsch_pdu_rel8.redundancy_version;
ulsch->harq_processes[harq_pid]->Qm = ulsch_pdu->ulsch_pdu_rel8.modulation_type;
// Set O_ACK to 0 by default, will be set of DLSCH is scheduled and needs to be
......@@ -2531,8 +2529,10 @@ void fill_ulsch(PHY_VARS_eNB *eNB,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame
else ulsch->harq_processes[harq_pid]->round++;
ulsch->rnti = ulsch_pdu->ulsch_pdu_rel8.rnti;
LOG_D(PHY,"Filling ULSCH %x (new_ulsch %d) for Frame %d, Subframe %d : harq_pid %d, first_rb %d, nb_rb %d, rvidx %d, Qm %d, TBS %d, round %d \n",
ulsch->rnti, new_ulsch,
LOG_D(PHY,"Filling ULSCH %x (UE_id %d) (new_ulsch %d) for Frame %d, Subframe %d : harq_pid %d, first_rb %d, nb_rb %d, rvidx %d, Qm %d, TBS %d, round %d \n",
ulsch->rnti,
UE_id,
new_ulsch,
frame,
subframe,
harq_pid,
......@@ -2542,12 +2542,8 @@ void fill_ulsch(PHY_VARS_eNB *eNB,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame
ulsch->harq_processes[harq_pid]->Qm,
ulsch->harq_processes[harq_pid]->TBS,
ulsch->harq_processes[harq_pid]->round);
}
int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci)
{
switch (dci->format) {
......@@ -6420,12 +6416,11 @@ uint8_t ul_subframe2pdcch_alloc_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t
return(9);
else
return((n+6)%10);
}
uint32_t pdcch_alloc2ul_frame(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t n)
{
uint32_t ul_frame = 255;
uint32_t ul_frame;
if ((frame_parms->frame_type == TDD) &&
(frame_parms->tdd_config == 1) &&
......@@ -6443,8 +6438,7 @@ uint32_t pdcch_alloc2ul_frame(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, ui
ul_frame = (frame+(n>=6 ? 1 : 0));
LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n", frame, n, ul_frame);
return ul_frame;
return ul_frame % 1024;
}
int32_t pmi_convert_rank1_from_rank2(uint16_t pmi_alloc, int tpmi, int nb_rb)
......
......@@ -151,18 +151,19 @@ unsigned char subframe2_ul_harq(LTE_DL_FRAME_PARMS *frame_parms,unsigned char su
return(0);
}
uint8_t phich_frame2_pusch_frame(LTE_DL_FRAME_PARMS *frame_parms,frame_t frame,uint8_t subframe)
int phich_frame2_pusch_frame(LTE_DL_FRAME_PARMS *frame_parms, int frame, int subframe)
{
uint8_t pusch_frame = 255;
int pusch_frame;
if (frame_parms->frame_type == FDD) {
pusch_frame = ((subframe<4) ? (frame - 1) : frame);
pusch_frame = subframe<4 ? frame + 1024 - 1 : frame;
} else {
// Note this is not true, but it doesn't matter, the frame number is irrelevant for TDD!
pusch_frame = (frame);
}
LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n", frame, subframe, pusch_frame);
return pusch_frame;
return pusch_frame % 1024;
}
uint8_t phich_subframe2_pusch_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe)
......
......@@ -1950,7 +1950,7 @@ uint8_t phich_subframe2_pusch_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t s
@param subframe Subframe of received/transmitted PHICH
@returns frame of PUSCH transmission
*/
uint8_t phich_frame2_pusch_frame(LTE_DL_FRAME_PARMS *frame_parms,frame_t frame,uint8_t subframe);
int phich_frame2_pusch_frame(LTE_DL_FRAME_PARMS *frame_parms, int frame, int subframe);
void print_CQI(void *o,UCI_format_t uci_format,uint8_t eNB_id,int N_RB_DL);
......
......@@ -2420,7 +2420,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
if (fmt==pucch_format1b)
*(1+payload) = (stat_im<0) ? 1 : 2;
} else { // insufficient energy on PUCCH so NAK
LOG_D(PHY,"PUCCH 1a/b: subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d\n",subframe,sigma2_dB,dB_fixed(stat_max),pucch1_thres);
LOG_I(PHY,"PUCCH 1a/b: subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d\n",subframe,sigma2_dB,dB_fixed(stat_max),pucch1_thres);
*payload = 4; // DTX
((int16_t*)&eNB->pucch1ab_stats[UE_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe])])[0] = (int16_t)(stat_re);
((int16_t*)&eNB->pucch1ab_stats[UE_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe])])[1] = (int16_t)(stat_im);
......
......@@ -1164,16 +1164,21 @@ void rx_ulsch(PHY_VARS_eNB *eNB,
l/(frame_parms->symbols_per_tti/2));
}
int correction_factor = 1;
int deltaMCS=1;
int MPR_times_Ks;
if (deltaMCS==1) {
// Note we're using TBS instead of sumKr, since didn't run segmentation yet!
MPR_times_Ks = 5*ulsch[UE_id]->harq_processes[harq_pid]->TBS/(ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12*4*ulsch[UE_id]->harq_processes[harq_pid]->Nsymb_pusch);
if (MPR_times_Ks > 0) correction_factor = (1<<MPR_times_Ks) - 1;
}
for (i=0; i<frame_parms->nb_antennas_rx; i++) {
pusch_vars->ulsch_power[i] = signal_energy_nodc(pusch_vars->drs_ch_estimates[i],
ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12);
ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12)/correction_factor;
//printf("%4.4d.%d power harq_pid %d rb %2.2d TBS %2.2d (MPR_times_Ks %d correction %d) power %d dBtimes10\n", proc->frame_rx, proc->subframe_rx, harq_pid, ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, ulsch[UE_id]->harq_processes[harq_pid]->TBS,MPR_times_Ks,correction_factor,dB_fixed_times10(pusch_vars->ulsch_power[i]));
#ifdef LOCALIZATION
pusch_vars->subcarrier_power = (int32_t *)malloc(ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12*sizeof(int32_t));
pusch_vars->active_subcarrier = subcarrier_energy(pusch_vars->drs_ch_estimates[i],
ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12, pusch_vars->subcarrier_power, rx_power_correction);
#endif
}
......
......@@ -33,47 +33,29 @@ This section deals with basic functions for OFDM Modulation.
#include "UTIL/LOG/log.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
//static short temp2[2048*4] __attribute__((aligned(16)));
//#define DEBUG_OFDM_MOD
void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRAME_PARMS *frame_parms)
{
uint8_t i;
int short_offset=0;
if ((2*nsymb) < frame_parms->symbols_per_tti)
short_offset = 1;
// printf("nsymb %d\n",nsymb);
for (i=0; i<((short_offset)+2*nsymb/frame_parms->symbols_per_tti); i++) {
#ifdef DEBUG_OFDM_MOD
printf("slot i %d (txdata offset %d, txoutput %p)\n",i,(i*(frame_parms->samples_per_tti>>1)),
txdata+(i*(frame_parms->samples_per_tti>>1)));
#endif
PHY_ofdm_mod(txdataF+(i*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti>>1), // input
txdata+(i*frame_parms->samples_per_tti>>1), // output
frame_parms->ofdm_symbol_size,
1, // number of symbols
frame_parms->nb_prefix_samples0, // number of prefix samples
CYCLIC_PREFIX);
#ifdef DEBUG_OFDM_MOD
printf("slot i %d (txdata offset %d)\n",i,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0+(i*frame_parms->samples_per_tti>>1));
#endif
PHY_ofdm_mod(txdataF+frame_parms->ofdm_symbol_size+(i*frame_parms->ofdm_symbol_size*(frame_parms->symbols_per_tti>>1)), // input
txdata+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0+(i*(frame_parms->samples_per_tti>>1)), // output
frame_parms->ofdm_symbol_size,
(short_offset==1) ? 1 :(frame_parms->symbols_per_tti>>1)-1,//6, // number of symbols
frame_parms->nb_prefix_samples, // number of prefix samples
CYCLIC_PREFIX);
PHY_ofdm_mod(txdataF, // input
txdata, // output
frame_parms->ofdm_symbol_size,
1, // number of symbols
frame_parms->nb_prefix_samples0, // number of prefix samples
CYCLIC_PREFIX);
PHY_ofdm_mod(txdataF+frame_parms->ofdm_symbol_size, // input
txdata+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0, // output
frame_parms->ofdm_symbol_size,
nsymb-1,
frame_parms->nb_prefix_samples, // number of prefix samples
CYCLIC_PREFIX);
}
}
void PHY_ofdm_mod(int *input, /// pointer to complex input
......@@ -85,7 +67,7 @@ void PHY_ofdm_mod(int *input, /// pointer to complex input
)
{
static short temp[2048*4] __attribute__((aligned(32)));
short temp[2048*4] __attribute__((aligned(32)));
unsigned short i,j;
short k;
......@@ -165,9 +147,10 @@ void PHY_ofdm_mod(int *input, /// pointer to complex input
if (fftsize==128)
#endif
{
for (j=0; j<fftsize ; j++) {
/*for (j=0; j<fftsize ; j++) {
output_ptr[j] = temp_ptr[j];
}
}*/
memcpy((void*)output_ptr,(void*)temp_ptr,fftsize<<2);
}
j=fftsize;
......
......@@ -83,9 +83,8 @@ void print_meas(time_stats_t *ts, const char* name, time_stats_t * total_exec_ti
//printf("%20s: total: %10.3f ms, average: %10.3f us (%10d trials)\n", name, ts->diff/cpu_freq_GHz/1000000.0, ts->diff/ts->trials/cpu_freq_GHz/1000.0, ts->trials);
if ((total_exec_time == NULL) || (sf_exec_time== NULL)) {
fprintf(stderr, "%25s: %15.3f ms ; %15.3f us; %15d;\n",
fprintf(stderr, "%25s: %15.3f us; %15d;\n",
name,
(ts->diff/cpu_freq_GHz/1000000.0),
(ts->diff/ts->trials/cpu_freq_GHz/1000.0),
ts->trials);
} else {
......
......@@ -330,6 +330,8 @@ typedef struct RU_proc_t_s {
int instance_cnt_asynch_rxtx;
/// \internal This variable is protected by \ref mutex_fep
int instance_cnt_fep;
/// \internal This variable is protected by \ref mutex_fep
int instance_cnt_feptx;
/// pthread structure for RU FH processing thread
pthread_t pthread_FH;
/// pthread structure for RU prach processing thread
......@@ -340,8 +342,10 @@ typedef struct RU_proc_t_s {
#endif
/// pthread struct for RU synch thread
pthread_t pthread_synch;
/// pthread struct for RU RX FEP thread
/// pthread struct for RU RX FEP worker thread
pthread_t pthread_fep;
/// pthread struct for RU RX FEPTX worker thread
pthread_t pthread_feptx;
/// pthread structure for asychronous RX/TX processing thread
pthread_t pthread_asynch_rxtx;
/// flag to indicate first RX acquisition
......@@ -360,8 +364,10 @@ typedef struct RU_proc_t_s {
pthread_attr_t attr_synch;
/// pthread attributes for asynchronous RX thread
pthread_attr_t attr_asynch_rxtx;
/// pthread attributes for parallel fep thread
/// pthread attributes for worker fep thread
pthread_attr_t attr_fep;
/// pthread attributes for worker feptx thread
pthread_attr_t attr_feptx;
/// scheduling parameters for RU FH thread
struct sched_param sched_param_FH;
/// scheduling parameters for RU prach thread
......@@ -388,6 +394,8 @@ typedef struct RU_proc_t_s {
pthread_cond_t cond_asynch_rxtx;
/// condition varaible for RU RX FEP thread
pthread_cond_t cond_fep;
/// condition varaible for RU RX FEPTX thread
pthread_cond_t cond_feptx;
/// condition variable for eNB signal
pthread_cond_t cond_eNBs;
/// mutex for RU FH
......@@ -404,8 +412,10 @@ typedef struct RU_proc_t_s {
pthread_mutex_t mutex_eNBs;
/// mutex for asynch RX/TX thread
pthread_mutex_t mutex_asynch_rxtx;
/// mutex for fep RX
/// mutex for fep RX worker thread
pthread_mutex_t mutex_fep;
/// mutex for fep TX worker thread
pthread_mutex_t mutex_feptx;
/// symbol mask for IF4p5 reception per subframe
uint32_t symbol_mask[10];
/// number of slave threads
......@@ -740,6 +750,8 @@ typedef struct RU_t_s{
void (*eNB_top)(struct PHY_VARS_eNB_s *eNB, int frame_rx, int subframe_rx, char *string);
/// Timing statistics
time_stats_t ofdm_demod_stats;
/// Timing statistics (TX)
time_stats_t ofdm_mod_stats;
/// RX and TX buffers for precoder output
RU_COMMON common;
/// beamforming weight vectors per eNB
......@@ -755,6 +767,8 @@ typedef struct RU_t_s{
openair0_timestamp ts_offset;
/// process scheduling variables
RU_proc_t proc;
/// stats thread pthread descriptor
pthread_t ru_stats_thread;
} RU_t;
......
......@@ -594,14 +594,13 @@ void schedule_response(Sched_Rsp_t *Sched_INFO)
ul_subframe = pdcch_alloc2ul_subframe(fp,subframe);
ul_frame = pdcch_alloc2ul_frame(fp,frame,subframe);
// DJP - subframe assert will fail - not sure why yet
// DJP - subframe assert will fail - not sure why yet
// DJP - AssertFatal(proc->subframe_tx == subframe, "Current subframe %d != NFAPI subframe %d\n",proc->subframe_tx,subframe);
// DJP - AssertFatal(proc->subframe_tx == subframe, "Current frame %d != NFAPI frame %d\n",proc->frame_tx,frame);
uint8_t number_dci = DL_req->dl_config_request_body.number_dci;
uint8_t number_pdcch_ofdm_symbols = DL_req->dl_config_request_body.number_pdcch_ofdm_symbols;
uint8_t number_dl_pdu = DL_req->dl_config_request_body.number_pdu;
uint8_t number_hi_dci0_pdu = HI_DCI0_req->hi_dci0_request_body.number_of_dci+HI_DCI0_req->hi_dci0_request_body.number_of_hi;
uint8_t number_ul_pdu = UL_req->ul_config_request_body.number_of_pdus;
......
......@@ -924,7 +924,7 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
frame,subframe,
pucch_b0b1[0][0],metric[0]);
uci->stat = metric[0];
fill_uci_harq_indication(eNB,uci,frame,subframe,pucch_b0b1[0],0,0xffff);
}
......@@ -995,6 +995,7 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
else if (pucch_b0b1[1][0] != 1 && pucch_b0b1[1][1] != 1) { // 0 ACKs, or at least one DL assignment missed
harq_ack[0] = 0;
}
uci->stat = metric[0];
fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,2,0xffff); // special_bundling mode
}
else if ((uci->tdd_bundling == 0) && (uci->num_pucch_resources==2)){ // multiplexing + no SR, implement Table 10.1.3-5 (Rel14) for multiplexing with M=2
......@@ -1036,6 +1037,7 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
}
}
}
uci->stat = max(metric[0],metric[1]);
fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode
} //else if ((uci->tdd_bundling == 0) && (res==2))
else if ((uci->tdd_bundling == 0) && (uci->num_pucch_resources==3)){ // multiplexing + no SR, implement Table 10.1.3-6 (Rel14) for multiplexing with M=3
......@@ -1116,8 +1118,9 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
tdd_multiplexing_mask = 0x4;
}
}
}
uci->stat = max_metric;
fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode
}
} //else if ((uci->tdd_bundling == 0) && (res==3))
else if ((uci->tdd_bundling == 0) && (uci->num_pucch_resources==4)){ // multiplexing + no SR, implement Table 10.1.3-7 (Rel14) for multiplexing with M=4
if (pucch_b0b1[0][0] == 4 ||
......@@ -1253,11 +1256,13 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
}
}
}
uci->stat = max_metric;
fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode
} // else if ((uci->tdd_bundling == 0) && (res==4))
else { // bundling
harq_ack[0] = pucch_b0b1[0][0];
harq_ack[1] = pucch_b0b1[0][1];
uci->stat = metric[0];
fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,0,0xffff); // special_bundling mode
}
......@@ -1291,8 +1296,8 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
}
}
void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
{
uint32_t ret=0,i;
uint32_t harq_pid;
uint8_t nPRS;
......@@ -1306,10 +1311,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
if (fp->frame_type == FDD) harq_pid = ((10*frame) + subframe)&7;
else harq_pid = subframe%10;
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
ulsch = eNB->ulsch[i];
ulsch_harq = ulsch->harq_processes[harq_pid];
if (ulsch->rnti>0) LOG_D(PHY,"Frame %d, subframe %d: PUSCH procedures, harq_pid %d, UE %d/%x\n",
......@@ -1322,9 +1324,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
(ulsch_harq->subframe == subframe) &&
(ulsch_harq->handled == 0)) {
// UE has ULSCH scheduling
for (int rb=0;
rb<=ulsch_harq->nb_rb;
rb++) {
......@@ -1332,7 +1332,6 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
eNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31));
}
LOG_D(PHY,"[eNB %d] frame %d, subframe %d: Scheduling ULSCH Reception for UE %d \n",
eNB->Mod_id,
frame,
......@@ -1364,13 +1363,10 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
start_meas(&eNB->ulsch_demodulation_stats);
rx_ulsch(eNB,proc,
i);
rx_ulsch(eNB,proc, i);
stop_meas(&eNB->ulsch_demodulation_stats);
start_meas(&eNB->ulsch_decoding_stats);
ret = ulsch_decoding(eNB,proc,
......@@ -1379,8 +1375,6 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
ulsch_harq->V_UL_DAI,
ulsch_harq->nb_rb>20 ? 1 : 0);
stop_meas(&eNB->ulsch_decoding_stats);
LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d ulsch_harq->cqi_crc_status:%d ackBits:%d\n",
......@@ -1397,19 +1391,15 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
ulsch_harq->cqi_crc_status,
ulsch_harq->O_ACK);
//compute the expected ULSCH RX power (for the stats)
ulsch_harq->delta_TF = get_hundred_times_delta_IF_eNB(eNB,i,harq_pid, 0); // 0 means bw_factor is not considered
if (ulsch_harq->cqi_crc_status == 1) {
#ifdef DEBUG_PHY_PROC
//if (((frame%10) == 0) || (frame < 50))
print_CQI(ulsch_harq->o,ulsch_harq->uci_format,0,fp->N_RB_DL);
#endif
fill_ulsch_cqi_indication(eNB,frame,subframe,
ulsch_harq,
ulsch->rnti);
......@@ -1429,10 +1419,13 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
ulsch->Mlimit,
ulsch_harq->o_ACK[0],
ulsch_harq->o_ACK[1]);
/*if (dB_fixed_times10(eNB->pusch_vars[i]->ulsch_power[0]) > 300) {
dump_ulsch(eNB,frame,subframe,i); exit(-1);
if (ulsch_harq->round >= 3) {
ulsch_harq->status = SCH_IDLE;
ulsch_harq->handled = 0;
ulsch->harq_mask &= ~(1 << harq_pid);
ulsch_harq->round = 0;
}
*/
#if defined(MESSAGE_CHART_GENERATOR_PHY)
MSC_LOG_RX_DISCARDED_MESSAGE(
MSC_PHY_ENB,MSC_PHY_UE,
......@@ -1444,15 +1437,22 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
);
#endif
/* Mark the HARQ process to release it later if max transmission reached
* (see below).
* MAC does not send the max transmission count, we have to deal with it
* locally in PHY.
*/
ulsch_harq->handled = 1;
} // ulsch in error
else {
fill_crc_indication(eNB,i,frame,subframe,0); // indicate ACK to MAC
fill_rx_indication(eNB,i,frame,subframe); // indicate SDU to MAC
ulsch_harq->status = SCH_IDLE;
ulsch->harq_mask &= ~(1 << harq_pid);
T(T_ENB_PHY_ULSCH_UE_ACK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(ulsch->rnti),
T_INT(harq_pid));
ulsch_harq->status = SCH_IDLE;
#if defined(MESSAGE_CHART_GENERATOR_PHY)
MSC_LOG_RX_MESSAGE(
......@@ -1475,9 +1475,6 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
LOG_T(PHY,"\n");
#endif
#endif
} // ulsch not in error
if (ulsch_harq->O_ACK>0) fill_ulsch_harq_indication(eNB,ulsch_harq,ulsch->rnti,frame,subframe,ulsch->bundling);
......@@ -1492,12 +1489,9 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
ulsch_harq->o_ACK[1],
eNB->UE_stats[i].ulsch_errors[harq_pid],
eNB->UE_stats[i].ulsch_decoding_attempts[harq_pid][0]);
ulsch_harq->handled = 1;
} // if ((ulsch) &&
// (ulsch->rnti>0) &&
// (ulsch_harq->status == ACTIVE))
else if ((ulsch) &&
(ulsch->rnti>0) &&
(ulsch_harq->status == ACTIVE) &&
......@@ -1506,10 +1500,11 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
(ulsch_harq->handled == 1)) {
// this harq process is stale, kill it, this 1024 frames later (10s), consider reducing that
ulsch_harq->status = SCH_IDLE;
ulsch->harq_mask = 0;
LOG_W(PHY,"Removing stale ULSCH config for UE %x\n",ulsch->rnti);
ulsch_harq->handled = 0;
ulsch->harq_mask &= ~(1 << harq_pid);
LOG_W(PHY,"Removing stale ULSCH config for UE %x harq_pid %d (harq_mask is now 0x%2.2x)\n",
ulsch->rnti, harq_pid, ulsch->harq_mask);
}
} // for (i=0; i<NUMBER_OF_UE_MAX; i++) {
}
......@@ -1548,12 +1543,8 @@ void init_te_thread(PHY_VARS_eNB *eNB,pthread_attr_t *attr_te) {
}
void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe) {
void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe)
{
nfapi_rx_indication_pdu_t *pdu;
int timing_advance_update;
......@@ -1580,50 +1571,36 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe) {
sync_pos = lte_est_timing_advance_pusch(eNB,UE_id);
timing_advance_update = sync_pos - eNB->frame_parms.nb_prefix_samples/4; //to check
// if (timing_advance_update > 10) { dump_ulsch(eNB,frame,subframe,UE_id); exit(-1);}
// if (timing_advance_update < -10) { dump_ulsch(eNB,frame,subframe,UE_id); exit(-1);}
switch (eNB->frame_parms.N_RB_DL) {
case 6:
pdu->rx_indication_rel8.timing_advance = timing_advance_update;
break;
case 15:
pdu->rx_indication_rel8.timing_advance = timing_advance_update/2;
break;
case 25:
pdu->rx_indication_rel8.timing_advance = timing_advance_update/4;
break;
case 50:
pdu->rx_indication_rel8.timing_advance = timing_advance_update/8;
break;
case 75:
pdu->rx_indication_rel8.timing_advance = timing_advance_update/12;
break;
case 100:
pdu->rx_indication_rel8.timing_advance = timing_advance_update/16;
break;
case 6: /* nothing to do */ break;
case 15: timing_advance_update /= 2; break;
case 25: timing_advance_update /= 4; break;
case 50: timing_advance_update /= 8; break;
case 75: timing_advance_update /= 12; break;
case 100: timing_advance_update /= 16; break;
default: abort();
}
// put timing advance command in 0..63 range
pdu->rx_indication_rel8.timing_advance += 31;
if (pdu->rx_indication_rel8.timing_advance < 0) pdu->rx_indication_rel8.timing_advance = 0;
if (pdu->rx_indication_rel8.timing_advance > 63) pdu->rx_indication_rel8.timing_advance = 63;
timing_advance_update += 31;
if (timing_advance_update < 0) timing_advance_update = 0;
if (timing_advance_update > 63) timing_advance_update = 63;
pdu->rx_indication_rel8.timing_advance = timing_advance_update;
// estimate UL_CQI for MAC (from antenna port 0 only)
int SNRtimes10 = dB_fixed_times10(eNB->pusch_vars[UE_id]->ulsch_power[0]) - 200;//(10*eNB->measurements.n0_power_dB[0]);
if (SNRtimes10 < -640) pdu->rx_indication_rel8.ul_cqi=0;
else if (SNRtimes10 > 635) pdu->rx_indication_rel8.ul_cqi=255;
else pdu->rx_indication_rel8.ul_cqi=(640+SNRtimes10)/5;
LOG_D(PHY,"[PUSCH %d] Filling RX_indication with SNR %d (%d), timing_advance %d (update %d)\n",
harq_pid,SNRtimes10,pdu->rx_indication_rel8.ul_cqi,pdu->rx_indication_rel8.timing_advance,
timing_advance_update);
eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus++;
pthread_mutex_unlock(&eNB->UL_INFO_mutex);
}
void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subframe,uint16_t mask) {
......@@ -1820,6 +1797,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
uint16_t tdd_multiplexing_mask) {
int UE_id=find_dlsch(uci->rnti,eNB,SEARCH_EXIST);
AssertFatal(UE_id>=0,"UE_id doesn't exist\n");
pthread_mutex_lock(&eNB->UL_INFO_mutex);
......@@ -1832,6 +1810,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
// estimate UL_CQI for MAC (from antenna port 0 only)
int SNRtimes10 = dB_fixed_times10(uci->stat) - 200;//(10*eNB->measurements.n0_power_dB[0]);
if (SNRtimes10 < -100) LOG_I(PHY,"uci->stat %d \n",uci->stat);
if (SNRtimes10 < -640) pdu->ul_cqi_information.ul_cqi=0;
else if (SNRtimes10 > 635) pdu->ul_cqi_information.ul_cqi=255;
......
......@@ -54,10 +54,160 @@
#include <time.h>
#include "targets/RT/USER/rt_wrapper.h"
// RU OFDM Modulator, used in IF4p5 RRU, RCC/RAU with IF5, eNodeB
extern openair0_config_t openair0_cfg[MAX_CARDS];
extern int oai_exit;
void feptx0(RU_t *ru,int slot) {
LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
//int dummy_tx_b[7680*2] __attribute__((aligned(32)));
unsigned int aa,slot_offset;
int i,tx_offset;
int slot_sizeF = (fp->ofdm_symbol_size)*
((fp->Ncp==1) ? 6 : 7);
int subframe = ru->proc.subframe_tx;
slot_offset = subframe*fp->samples_per_tti + (slot*(fp->samples_per_tti>>1));
// LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot);
for (aa=0; aa<ru->nb_tx; aa++) {
if (fp->Ncp == EXTENDED) PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot*slot_sizeF],
(int*)&ru->common.txdata[aa][slot_offset],
fp->ofdm_symbol_size,
6,
fp->nb_prefix_samples,
CYCLIC_PREFIX);
else normal_prefix_mod(&ru->common.txdataF_BF[aa][slot*slot_sizeF],
(int*)&ru->common.txdata[aa][slot_offset],
7,
fp);
/*
len = fp->samples_per_tti>>1;
if ((slot_offset+len)>(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti)) {
tx_offset = (int)slot_offset;
txdata = (int16_t*)&ru->common.txdata[aa][tx_offset];
len2 = -tx_offset+LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti;
for (i=0; i<(len2<<1); i++) {
txdata[i] = ((int16_t*)dummy_tx_b)[i];
}
txdata = (int16_t*)&ru->common.txdata[aa][0];
for (j=0; i<(len<<1); i++,j++) {
txdata[j++] = ((int16_t*)dummy_tx_b)[i];
}
}
else {
tx_offset = (int)slot_offset;
txdata = (int16_t*)&ru->common.txdata[aa][tx_offset];
memcpy((void*)txdata,(void*)dummy_tx_b,len<<2);
}
*/
// TDD: turn on tx switch N_TA_offset before by setting buffer in these samples to 0
if ((slot == 0) &&
(fp->frame_type == TDD) &&
((fp->tdd_config==0) ||
(fp->tdd_config==1) ||
(fp->tdd_config==2) ||
(fp->tdd_config==6)) &&
((subframe==0) || (subframe==5))) {
for (i=0; i<ru->N_TA_offset; i++) {
tx_offset = (int)slot_offset+i-ru->N_TA_offset/2;
if (tx_offset<0)
tx_offset += LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti;
if (tx_offset>=(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti))
tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti;
ru->common.txdata[aa][tx_offset] = 0x00000000;
}
}
}
}
static void *feptx_thread(void *param) {
RU_t *ru = (RU_t *)param;
RU_proc_t *proc = &ru->proc;
thread_top_init("feptx_thread",0,870000,1000000,1000000);
while (!oai_exit) {
if (wait_on_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"feptx thread")<0) break;
feptx0(ru,1);
if (release_thread(&proc->mutex_feptx,&proc->instance_cnt_feptx,"feptx thread")<0) break;
if (pthread_cond_signal(&proc->cond_feptx) != 0) {
printf("[eNB] ERROR pthread_cond_signal for feptx thread exit\n");
exit_fun( "ERROR pthread_cond_signal" );
return NULL;
}
}
return(NULL);
}
void feptx_ofdm_2thread(RU_t *ru) {
LTE_DL_FRAME_PARMS *fp=&ru->frame_parms;
RU_proc_t *proc = &ru->proc;
struct timespec wait;
int subframe = ru->proc.subframe_tx;
wait.tv_sec=0;
wait.tv_nsec=5000000L;
start_meas(&ru->ofdm_mod_stats);
if (subframe_select(fp,subframe) == SF_UL) return;
if (subframe_select(fp,subframe)==SF_DL) {
// If this is not an S-subframe
if (pthread_mutex_timedlock(&proc->mutex_feptx,&wait) != 0) {
printf("[RU] ERROR pthread_mutex_lock for feptx thread (IC %d)\n", proc->instance_cnt_feptx);
exit_fun( "error locking mutex_feptx" );
return;
}
if (proc->instance_cnt_feptx==0) {
printf("[RU] FEPtx thread busy\n");
exit_fun("FEPtx thread busy");
pthread_mutex_unlock( &proc->mutex_feptx );
return;
}
++proc->instance_cnt_feptx;
if (pthread_cond_signal(&proc->cond_feptx) != 0) {
printf("[RU] ERROR pthread_cond_signal for feptx thread\n");
exit_fun( "ERROR pthread_cond_signal" );
return;
}
pthread_mutex_unlock( &proc->mutex_feptx );
}
// call first slot in this thread
feptx0(ru,0);
wait_on_busy_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"feptx thread");
stop_meas(&ru->ofdm_mod_stats);
}
void feptx_ofdm(RU_t *ru) {
LTE_DL_FRAME_PARMS *fp=&ru->frame_parms;
......@@ -83,6 +233,8 @@ void feptx_ofdm(RU_t *ru) {
((subframe_select(fp,subframe)==SF_S))) {
// LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot);
start_meas(&ru->ofdm_mod_stats);
for (aa=0; aa<ru->nb_tx; aa++) {
if (fp->Ncp == EXTENDED) {
PHY_ofdm_mod(&ru->common.txdataF_BF[aa][0],
......@@ -167,11 +319,12 @@ void feptx_ofdm(RU_t *ru) {
}
}
*/
if ((((fp->tdd_config==0) ||
if ((fp->frame_type == TDD) &&
((fp->tdd_config==0) ||
(fp->tdd_config==1) ||
(fp->tdd_config==2) ||
(fp->tdd_config==6)) &&
(subframe==0)) || (subframe==5)) {
((subframe==0) || (subframe==5))) {
// 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,ru->N_TA_offset,slot_offset);
for (i=0; i<ru->N_TA_offset; i++) {
......@@ -185,11 +338,10 @@ void feptx_ofdm(RU_t *ru) {
ru->common.txdata[aa][tx_offset] = 0x00000000;
}
}
#if 0
stop_meas(&ru->ofdm_mod_stats);
LOG_D(PHY,"feptx_ofdm (TXPATH): frame %d, subframe %d: txp (time %p) %d dB, txp (freq) %d dB\n",
ru->proc.frame_tx,subframe,txdata,dB_fixed(signal_energy((int32_t*)txdata,fp->samples_per_tti)),
dB_fixed(signal_energy_nodc(ru->common.txdataF_BF[aa],2*slot_sizeF)));
#endif
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 0 );
......@@ -246,11 +398,6 @@ void feptx_prec(RU_t *ru) {
}
}
typedef struct {
RU_t *ru;
int slot;
} fep_task;
void fep0(RU_t *ru,int slot) {
RU_proc_t *proc = &ru->proc;
......@@ -271,12 +418,13 @@ void fep0(RU_t *ru,int slot) {
extern int oai_exit;
static void *fep_thread(void *param) {
RU_t *ru = (RU_t *)param;
RU_proc_t *proc = &ru->proc;
thread_top_init("fep_thread",0,870000,1000000,1000000);
while (!oai_exit) {
if (wait_on_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"fep thread")<0) break;
......@@ -295,6 +443,20 @@ static void *fep_thread(void *param) {
return(NULL);
}
void init_feptx_thread(RU_t *ru,pthread_attr_t *attr_feptx) {
RU_proc_t *proc = &ru->proc;
proc->instance_cnt_feptx = -1;
pthread_mutex_init( &proc->mutex_feptx, NULL);
pthread_cond_init( &proc->cond_feptx, NULL);
pthread_create(&proc->pthread_feptx, attr_feptx, feptx_thread, (void*)ru);
}
void init_fep_thread(RU_t *ru,pthread_attr_t *attr_fep) {
RU_proc_t *proc = &ru->proc;
......
......@@ -850,7 +850,7 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
if (UE_id == -1)
LOG_E(MAC,"%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, __LINE__, __FUNCTION__);
else
config_dedicated(Mod_idP, CC_idP, UE_RNTI(Mod_idP, UE_id), physicalConfigDedicated);
UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated=physicalConfigDedicated;
}
......
......@@ -806,7 +806,6 @@ typedef struct {
unsigned char rballoc_sub_UE[MAX_NUM_CCs][N_RBG_MAX];
uint16_t ta_timer;
int16_t ta_update;
uint8_t ul_cqi;
uint16_t ul_consecutive_errors;
int32_t context_active_timer;
int32_t cqi_req_timer;
......
......@@ -113,6 +113,9 @@ void schedule_SRS(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
ul_req = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body;
// drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet
if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED) continue;
AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",UE_id);
if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL) {
......@@ -168,6 +171,9 @@ void schedule_CSI(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
ul_req = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body;
// drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet
if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED) continue;
AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",UE_id);
if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig) {
......@@ -491,10 +497,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame
CC_id = UE_PCCID(module_idP, i);
if ((frameP==0)&&(subframeP==0)) {
LOG_D(MAC,"UE rnti %x : %s, PHR %d dB CQI %d\n", rnti,
LOG_I(MAC,"UE rnti %x : %s, PHR %d dB DL CQI %d PUSCH SNR %d PUCCH SNR %d\n", rnti,
UE_list->UE_sched_ctrl[i].ul_out_of_sync==0 ? "in synch" : "out of sync",
UE_list->UE_template[CC_id][i].phr_info,
UE_list->UE_sched_ctrl[i].dl_cqi[CC_id]);
UE_list->UE_sched_ctrl[i].dl_cqi[CC_id],
(UE_list->UE_sched_ctrl[i].pusch_snr[CC_id]-128)/2,
(UE_list->UE_sched_ctrl[i].pucch1_snr[CC_id]-128)/2);
}
RC.eNB[module_idP][CC_id]->pusch_stats_bsr[i][(frameP*10)+subframeP]=-63;
......
......@@ -460,7 +460,7 @@ void generate_Msg2(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
{
if ((RA_template->Msg2_frame == frameP) && (RA_template->Msg2_subframe == subframeP)) {
LOG_I(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generating RAR DCI, RA_active %d format 1A (%d,%d))\n",
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generating RAR DCI, RA_active %d format 1A (%d,%d))\n",
module_idP, CC_idP, frameP, subframeP,
RA_template->RA_active,
RA_template->RA_dci_fmt1,
......@@ -847,7 +847,7 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
(unsigned short*)&rrc_sdu_length, //
&lcid, // sdu_lcid
255, // no drx
0, // no timing advance
31, // no timing advance
RA_template->cont_res_id, // contention res id
msg4_padding, // no padding
msg4_post_padding);
......@@ -970,7 +970,7 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
1, // ndi
0, // rv
0); // vrb_flag
LOG_I(MAC,"Frame %d, subframe %d: Msg4 DCI pdu_num %d (rnti %x,rnti_type %d,harq_pid %d, resource_block_coding (%p) %d\n",
LOG_D(MAC,"Frame %d, subframe %d: Msg4 DCI pdu_num %d (rnti %x,rnti_type %d,harq_pid %d, resource_block_coding (%p) %d\n",
frameP,
subframeP,
dl_req->number_pdu,
......@@ -1024,7 +1024,7 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
(unsigned short*)&rrc_sdu_length, //
&lcid, // sdu_lcid
255, // no drx
0, // no timing advance
31, // no timing advance
RA_template->cont_res_id, // contention res id
msg4_padding, // no padding
msg4_post_padding);
......@@ -1058,7 +1058,7 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
(cc->p_eNB==1 ) ? 1 : 2, // transmission mode
1, // num_bf_prb_per_subband
1); // num_bf_vector
LOG_I(MAC,"Filled DLSCH config, pdu number %d, non-dci pdu_index %d\n",dl_req->number_pdu,eNB->pdu_index[CC_idP]);
LOG_D(MAC,"Filled DLSCH config, pdu number %d, non-dci pdu_index %d\n",dl_req->number_pdu,eNB->pdu_index[CC_idP]);
// DL request
eNB->TX_req[CC_idP].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_idP].tx_request_body,
......@@ -1195,7 +1195,7 @@ void check_Msg4_retransmission(module_id_t module_idP,int CC_idP,frame_t frameP,
dl_req->number_pdu++;
dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
LOG_I(MAC,"msg4 retransmission for rnti %x (round %d) fsf %d/%d\n", RA_template->rnti, round, frameP, subframeP);
LOG_D(MAC,"msg4 retransmission for rnti %x (round %d) fsf %d/%d\n", RA_template->rnti, round, frameP, subframeP);
// DLSCH Config
fill_nfapi_dlsch_config(eNB,
dl_req,
......@@ -1277,7 +1277,7 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
if (RA_template->RA_active == TRUE) {
LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA %d is active (generate RAR %d, generate_Msg4 %d, wait_ack_Msg4 %d, rnti %x)\n",
LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA %d is active (generate RAR %d, generate_Msg4 %d, wait_ack_Msg4 %d, rnti %x)\n",
module_idP,frameP,subframeP,CC_id,i,RA_template->generate_rar,RA_template->generate_Msg4,RA_template->wait_ack_Msg4, RA_template->rnti);
if (RA_template->generate_rar == 1) generate_Msg2(module_idP,CC_id,frameP,subframeP,RA_template);
......
......@@ -169,7 +169,7 @@ generate_dlsch_header(
last_size=1;
}
if (timing_advance_cmd != 0) {
if (timing_advance_cmd != 31) {
if (first_element>0) {
mac_header_ptr->E = 1;
mac_header_ptr++;
......@@ -457,6 +457,7 @@ schedule_ue_spec(
nfapi_dl_config_request_body_t *dl_req;
nfapi_dl_config_request_pdu_t *dl_config_pdu;
int tdd_sfa;
int ta_update;
#if 0
if (UE_list->head==-1) {
......@@ -749,7 +750,7 @@ schedule_ue_spec(
UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]);
}
if (!CCE_allocation_infeasible(module_idP,CC_id,0,subframeP,
if (!CCE_allocation_infeasible(module_idP,CC_id,1,subframeP,
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,
rnti)) {
dl_req->number_dci++;
......@@ -821,7 +822,18 @@ schedule_ue_spec(
// check first for RLC data on DCCH
// add the length for all the control elements (timing adv, drx, etc) : header + payload
ta_len = (ue_sched_ctl->ta_update!=0) ? 2 : 0;
if (ue_sched_ctl->ta_timer == 0) {
ta_update = ue_sched_ctl->ta_update;
/* if we send TA then set timer to not send it for a while */
if (ta_update != 31)
ue_sched_ctl->ta_timer = 20;
/* reset ta_update */
ue_sched_ctl->ta_update = 31;
} else {
ta_update = 31;
}
ta_len = (ta_update != 31) ? 2 : 0;
header_len_dcch = 2; // 2 bytes DCCH SDU subheader
......@@ -1099,17 +1111,17 @@ schedule_ue_spec(
sdu_lengths, //
sdu_lcids,
255, // no drx
ue_sched_ctl->ta_update, // timing advance
ta_update, // timing advance
NULL, // contention res id
padding,
post_padding);
//#ifdef DEBUG_eNB_SCHEDULER
if (ue_sched_ctl->ta_update) {
if (ta_update != 31) {
LOG_D(MAC,
"[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_dcch %d, header_dtch %d\n",
module_idP,frameP, UE_id, CC_id, sdu_length_total,num_sdus,sdu_lengths[0],sdu_lcids[0],offset,
ue_sched_ctl->ta_update,padding,post_padding,mcs,TBS,nb_rb,header_len_dcch,header_len_dtch);
ta_update,padding,post_padding,mcs,TBS,nb_rb,header_len_dcch,header_len_dtch);
}
//#endif
#ifdef DEBUG_eNB_SCHEDULER
......@@ -1121,6 +1133,7 @@ schedule_ue_spec(
LOG_T(MAC,"\n");
#endif
// cycle through SDUs and place in dlsch_buffer
memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset],dlsch_buffer,sdu_length_total);
// memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]);
......@@ -1173,8 +1186,9 @@ schedule_ue_spec(
// this is the normalized RX power
eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
/* TODO: fix how we deal with power, unit is not dBm, it's special from nfapi */
normalized_rx_power = ue_sched_ctl->pucch1_snr[CC_id];
target_rx_power = 20;
target_rx_power = 208;
// this assumes accumulated tpc
// make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out
......@@ -1187,10 +1201,10 @@ schedule_ue_spec(
UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame=frameP;
UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe=subframeP;
if (normalized_rx_power>(target_rx_power+1)) {
if (normalized_rx_power>(target_rx_power+4)) {
tpc = 0; //-1
tpc_accumulated--;
} else if (normalized_rx_power<(target_rx_power-1)) {
} else if (normalized_rx_power<(target_rx_power-4)) {
tpc = 2; //+1
tpc_accumulated++;
} else {
......
......@@ -597,8 +597,8 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra
sdu_lengths,
sdu_lcids,
255, // no drx
0, // no timing advance
NULL, // no contention res id
31, // no timing advance
NULL, // no contention res id
padding,
post_padding);
......
......@@ -1739,6 +1739,8 @@ int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP,int harq_pidP
memset((void*)&UE_list->UE_sched_ctrl[UE_id],0,sizeof(UE_sched_ctrl));
memset((void*)&UE_list->eNB_UE_stats[cc_idP][UE_id],0,sizeof(eNB_UE_STATS));
UE_list->UE_sched_ctrl[UE_id].ta_update = 31;
for (j=0; j<8; j++) {
UE_list->UE_template[cc_idP][UE_id].oldNDI[j] = (j==0)?1:0; // 1 because first transmission is with format1A (Msg4) for harq_pid 0
UE_list->UE_template[cc_idP][UE_id].oldNDI_UL[j] = (j==harq_pidP)?0:1; // 1st transmission is with Msg3;
......@@ -2825,7 +2827,7 @@ try_again:
} // for i = 0 ... num_UL_DCIs
for (i=0;i<DL_req->number_pdu;i++) {
// allocate DL common DCIs first
// allocate DL UE specific DCIs
if ((dl_config_pdu[i].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE)&&
(dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type==1)) {
LOG_D(MAC,"Trying to allocate DL UE-SPECIFIC DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n",
......@@ -3573,6 +3575,10 @@ void cqi_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, sub_frame_t
{
int UE_id = find_UE_id(mod_idP, rntiP);
UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
if (UE_id == -1) {
LOG_W(MAC, "cqi_indication: UE %x not found\n", rntiP);
return;
}
UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
if (UE_id >= 0) {
......@@ -3615,10 +3621,13 @@ void SR_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, sub_frame_t
if (mac_eNB_get_rrc_status(mod_idP,UE_RNTI(mod_idP,UE_id)) < RRC_CONNECTED)
LOG_D(MAC,"[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d on CC_id %d\n",mod_idP,rntiP,frameP,subframeP, UE_id,cc_idP);
#if 0
UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
/* for the moment don't use ul_cqi from SR, value is too different from harq */
sched_ctl->pucch1_snr[cc_idP] = ul_cqi;
sched_ctl->pucch1_cqi_update[cc_idP] = 1;
#endif
UE_list->UE_template[cc_idP][UE_id].ul_SR = 1;
UE_list->UE_template[cc_idP][UE_id].ul_active = TRUE;
......@@ -3655,6 +3664,10 @@ void harq_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, sub_frame_
uint8_t ul_cqi = harq_pdu->ul_cqi_information.ul_cqi;
uint8_t channel = harq_pdu->ul_cqi_information.channel;
int UE_id = find_UE_id(mod_idP, rnti);
if (UE_id == -1) {
LOG_W(MAC, "harq_indication: UE %x not found\n", rnti);
return;
}
UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP];
......
......@@ -73,9 +73,8 @@ void rx_sdu(const module_id_t enb_mod_idP,
uint8_t *sduP,
const uint16_t sdu_lenP,
const uint16_t timing_advance,
const uint8_t ul_cqi) {
const uint8_t ul_cqi)
{
unsigned char rx_ces[MAX_NUM_CE],num_ce,num_sdu,i,*payload_ptr;
unsigned char rx_lcids[NB_RB_MAX];
unsigned short rx_lengths[NB_RB_MAX];
......@@ -105,9 +104,7 @@ void rx_sdu(const module_id_t enb_mod_idP,
enb_mod_idP, frameP, rntiP, sdu_lenP);
}
if (UE_id!=-1) {
LOG_D(MAC,"[eNB %d][PUSCH %d] CC_id %d Received ULSCH sdu(%p) round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n",enb_mod_idP,harq_pid,CC_idP,sduP,UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid],
rntiP,UE_id,ul_cqi);
......@@ -117,8 +114,10 @@ void rx_sdu(const module_id_t enb_mod_idP,
UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0;
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0;
UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= (~(1<<harq_pid));
/* don't take into account TA if timer is running */
if (UE_list->UE_sched_ctrl[UE_id].ta_timer == 0)
UE_list->UE_sched_ctrl[UE_id].ta_update = timing_advance;
UE_list->UE_sched_ctrl[UE_id].ul_cqi = ul_cqi;
UE_list->UE_sched_ctrl[UE_id].pusch_snr[CC_idP] = ul_cqi;
UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors = 0;
first_rb = UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid];
......@@ -220,6 +219,8 @@ void rx_sdu(const module_id_t enb_mod_idP,
UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync=0;
mac_eNB_rrc_ul_in_sync(enb_mod_idP,CC_idP,frameP,subframeP,(((uint16_t)payload_ptr[0])<<8) + payload_ptr[1]);
}
printf("TODO: deal with CRNTI\n");
abort();
}
crnti_rx=1;
payload_ptr+=2;
......@@ -597,10 +598,8 @@ void rx_sdu(const module_id_t enb_mod_idP,
stop_meas(&eNB->rx_ulsch_sdu);
}
uint32_t bytes_to_bsr_index(int32_t nbytes)
{
uint32_t i=0;
if (nbytes<0) {
......@@ -617,13 +616,11 @@ uint32_t bytes_to_bsr_index(int32_t nbytes)
void add_ue_ulsch_info(module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframeP, UE_ULSCH_STATUS status)
{
eNB_ulsch_info[module_idP][CC_id][UE_id].rnti = UE_RNTI(module_idP,UE_id);
eNB_ulsch_info[module_idP][CC_id][UE_id].subframe = subframeP;
eNB_ulsch_info[module_idP][CC_id][UE_id].status = status;
eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++;
}
unsigned char *parse_ulsch_header(unsigned char *mac_header,
......@@ -634,7 +631,6 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header,
unsigned short *rx_lengths,
unsigned short tb_length)
{
unsigned char not_done=1,num_ces=0,num_sdus=0,lcid,num_sdu_cnt;
unsigned char *mac_header_ptr = mac_header;
unsigned short length, ce_len=0;
......@@ -725,12 +721,8 @@ void set_msg3_subframe(module_id_t Mod_id,
void schedule_ulsch(module_id_t module_idP,
frame_t frameP,
sub_frame_t subframeP) {
sub_frame_t subframeP)
{
uint16_t first_rb[MAX_NUM_CCs],i;
int CC_id;
eNB_MAC_INST *eNB=RC.mac[module_idP];
......@@ -738,7 +730,6 @@ void schedule_ulsch(module_id_t module_idP,
start_meas(&eNB->schedule_ulsch);
int sched_subframe = (subframeP+4)%10;
cc = &eNB->common_channels[0];
......@@ -831,18 +822,14 @@ void schedule_ulsch(module_id_t module_idP,
schedule_ulsch_rnti(module_idP, frameP, subframeP, sched_subframe,first_rb);
stop_meas(&eNB->schedule_ulsch);
}
void schedule_ulsch_rnti(module_id_t module_idP,
frame_t frameP,
sub_frame_t subframeP,
unsigned char sched_subframeP,
uint16_t *first_rb)
{
int UE_id;
uint8_t aggregation = 2;
rnti_t rnti = -1;
......@@ -873,8 +860,6 @@ void schedule_ulsch_rnti(module_id_t module_idP,
//nfapi_ul_config_request_pdu_t *ul_config_pdu;
nfapi_ul_config_request_body_t *ul_req_tmp = &eNB->UL_req_tmp[CC_id][sched_subframeP].ul_config_request_body;
//ul_config_pdu = &ul_req_tmp->ul_config_pdu_list[0];
......@@ -955,7 +940,7 @@ abort();
format0);
*/
if (CCE_allocation_infeasible(module_idP,CC_id,2,subframeP,aggregation,rnti)) {
if (CCE_allocation_infeasible(module_idP,CC_id,1,subframeP,aggregation,rnti)) {
LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: not enough nCCE\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id);
continue; // break;
}
......@@ -967,8 +952,6 @@ abort();
continue;
}
// if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel
UE_template = &UE_list->UE_template[CC_id][UE_id];
......@@ -1002,13 +985,12 @@ abort();
else
cqi_req = 0;
//power control
//compute the expected ULSCH RX power (for the stats)
// this is the normalized RX power and this should be constant (regardless of mcs
normalized_rx_power = UE_sched_ctrl->pusch_snr[CC_id];
target_rx_power = 20;
target_rx_power = 178;
// this assumes accumulated tpc
// make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out
......@@ -1018,10 +1000,10 @@ abort();
{
UE_template->pusch_tpc_tx_frame=frameP;
UE_template->pusch_tpc_tx_subframe=subframeP;
if (normalized_rx_power>(target_rx_power+1)) {
if (normalized_rx_power>(target_rx_power+4)) {
tpc = 0; //-1
tpc_accumulated--;
} else if (normalized_rx_power<(target_rx_power-1)) {
} else if (normalized_rx_power<(target_rx_power-4)) {
tpc = 2; //+1
tpc_accumulated++;
} else {
......@@ -1030,7 +1012,7 @@ abort();
} else {
tpc = 1; //0
}
tpc = 1;
//tpc = 1;
if (tpc!=1) {
LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n",
module_idP,frameP,subframeP,harq_pid,tpc,
......@@ -1118,7 +1100,6 @@ abort();
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request = cqi_req;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = UE_template->DAI_ul[sched_subframeP];
eNB->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_dci++;
LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n",
......@@ -1159,8 +1140,6 @@ abort();
ul_req_tmp->number_of_pdus++;
eNB->ul_handle++;
add_ue_ulsch_info(module_idP,
CC_id,
UE_id,
......@@ -1169,10 +1148,8 @@ abort();
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP,CC_id,frameP,subframeP,UE_id);
// increment first rb for next UE allocation
first_rb[CC_id]+=rb_table[rb_table_index];
}
else { // round > 0 => retransmission
T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP),
......@@ -1265,4 +1242,3 @@ abort();
} // loop over UE_id
} // loop of CC_id
}
......@@ -894,6 +894,8 @@ void dlsch_scheduler_pre_processor_reset (int module_idP,
LOG_D(MAC,"Running preprocessor for UE %d (%x)\n",UE_id,rnti);
// initialize harq_pid and round
if (ue_sched_ctl->ta_timer) ue_sched_ctl->ta_timer--;
/*
eNB_UE_stats *eNB_UE_stats;
......
......@@ -48,6 +48,8 @@
#include "SIMULATION/TOOLS/defs.h" // for taus
extern UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
int8_t get_DELTA_PREAMBLE(module_id_t module_idP,int CC_id)
{
......
......@@ -91,6 +91,8 @@ extern Packet_OTG_List_t *otg_pdcp_buffer;
# include "gtpv1u_eNB_task.h"
#endif
extern int gtpv1u_new_data_req( uint8_t enb_module_idP, rnti_t ue_rntiP, uint8_t rab_idP, uint8_t *buffer_pP, uint32_t buf_lenP, uint32_t buf_offsetP);
/* Prevent de-queueing the same PDCP SDU from the queue twice
* by multiple threads. This has happened in TDD when thread-odd
* is flushing a PDCP SDU after UE_RX() processing; whereas
......
......@@ -254,13 +254,15 @@ static void dump_ul(UL_IND_t *u)
A("XXXX harq_ind %d\n", u->harq_ind.number_of_harqs);
for (i = 0; i < u->harq_ind.number_of_harqs; i++) {
nfapi_harq_indication_pdu_t *v = &u->harq_ind.harq_pdu_list[i];
A("XXXX harq ind %d\n", i);
A("XXXX rnti %d\n", v->rx_ue_information.rnti);
A("XXXX tb1 %d tb2 %d\n", v->harq_indication_fdd_rel8.harq_tb1,
v->harq_indication_fdd_rel8.harq_tb2);
A("XXXX number_of_ack_nack %d\n",
v->harq_indication_fdd_rel9.number_of_ack_nack);
A("XXXX harq[0] = %d\n", v->harq_indication_fdd_rel9.harq_tb_n[0]);
A("XXXX ul_cqi %d channel %d\n", v->ul_cqi_information.ul_cqi,
A("XXXX harq[0] = %d\n",
v->harq_indication_fdd_rel9.harq_tb_n[0]);
A("XXXX harq ul_cqi %d channel %d\n", v->ul_cqi_information.ul_cqi,
v->ul_cqi_information.channel);
}
......@@ -269,10 +271,23 @@ static void dump_ul(UL_IND_t *u)
A("XXXX sr_ind %d\n", u->sr_ind.number_of_srs);
A("XXXX cqi_ind %d\n", u->cqi_ind.number_of_cqis);
for (i = 0; i < u->cqi_ind.number_of_cqis; i++) {
nfapi_cqi_indication_pdu_t *v = &u->cqi_ind.cqi_pdu_list[i];
A("XXXX cqi ind %d\n", i);
A("XXXX cqi ul_cqi %d channel %d\n", v->ul_cqi_information.ul_cqi,
v->ul_cqi_information.channel);
}
A("XXXX rach_ind %d\n", u->rach_ind.number_of_preambles);
A("XXXX rx_ind %d\n", u->rx_ind.rx_indication_body.number_of_pdus);
for (i = 0; i < u->rx_ind.rx_indication_body.number_of_pdus; i++) {
nfapi_rx_indication_pdu_t *v = &u->rx_ind.rx_indication_body.rx_pdu_list[i];
A("XXXX rx ind %d\n", i);
A("XXXX timing_advance %d\n",
v->rx_indication_rel8.timing_advance);
A("XXXX rx ul_cqi %d\n", v->rx_indication_rel8.ul_cqi);
}
LOG_I(PHY, "XXXX UL\nXXXX UL\n%s", s);
}
......@@ -321,6 +336,18 @@ static char *UL_PDU_TYPE(int x)
return "UNKNOWN";
}
static char *HI_DCI0_PDU_TYPE(int x)
{
switch (x) {
case NFAPI_HI_DCI0_HI_PDU_TYPE: return "NFAPI_HI_DCI0_HI_PDU_TYPE";
case NFAPI_HI_DCI0_DCI_PDU_TYPE: return "NFAPI_HI_DCI0_DCI_PDU_TYPE";
case NFAPI_HI_DCI0_EPDCCH_DCI_PDU_TYPE: return "NFAPI_HI_DCI0_EPDCCH_DCI_PDU_TYPE";
case NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE: return "NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE";
case NFAPI_HI_DCI0_NPDCCH_DCI_PDU_TYPE: return "NFAPI_HI_DCI0_NPDCCH_DCI_PDU_TYPE";
}
return "UNKNOWN";
}
static void dump_dl(Sched_Rsp_t *d)
{
int i;
......@@ -360,10 +387,63 @@ static void dump_dl(Sched_Rsp_t *d)
A("XXXX rnti type %d\n", q->rnti_type);
A("XXXX xmit pow %d\n", q->transmission_power);
break;
}
case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE: {
nfapi_dl_config_dlsch_pdu_rel8_t *q =
&p[i].dlsch_pdu.dlsch_pdu_rel8;
A("XXXX pdu_index %d\n", q->pdu_index);
A("XXXX rnti %d\n", q->rnti);
A("XXXX rv %d\n", q->redundancy_version);
A("XXXX mcs %d\n", q->modulation);
A("XXXX pa %d\n", q->pa);
break;
}}
}
}
if (d->HI_DCI0_req != NULL) {
nfapi_hi_dci0_request_body_t *v=&d->HI_DCI0_req->hi_dci0_request_body;
A("XXXX up HI_DCI0_req sfnsf %d (%d.%d)\n", d->HI_DCI0_req->sfn_sf,
d->HI_DCI0_req->sfn_sf/16, d->HI_DCI0_req->sfn_sf%16);
A("XXXX up sfnsf %d\n", v->sfnsf);
A("XXXX up DCIs %d\n", v->number_of_dci);
A("XXXX up HIs %d\n", v->number_of_hi);
for (i = 0; i < v->number_of_dci + v->number_of_hi; i++) {
nfapi_hi_dci0_request_pdu_t *p = &v->hi_dci0_pdu_list[i];
A("XXXX up pdu %d\n", i);
A("XXXX up type %d %s\n",p->pdu_type,HI_DCI0_PDU_TYPE(p->pdu_type));
if (p->pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) {
nfapi_hi_dci0_dci_pdu_rel8_t *q = &p->dci_pdu.dci_pdu_rel8;
A("XXXX up dci_format %d\n", q->dci_format);
A("XXXX up cce_index %d\n", q->cce_index);
A("XXXX up aggregation_level %d\n", q->aggregation_level);
A("XXXX up rnti %d\n", q->rnti);
A("XXXX up rb start %d\n", q->resource_block_start);
A("XXXX up # rb %d\n", q->number_of_resource_block);
A("XXXX up mcs_1 %d\n", q->mcs_1);
A("XXXX up cshift_2_for_drms %d\n", q->cyclic_shift_2_for_drms);
A("XXXX up freq hop enabled %d\n", q->frequency_hopping_enabled_flag);
A("XXXX up fre hop bits %d\n", q->frequency_hopping_bits);
A("XXXX up NDI_1 %d\n", q->new_data_indication_1);
A("XXXX up tx_antenna_seleciton %d\n", q->ue_tx_antenna_seleciton);
A("XXXX up tpc %d\n", q->tpc);
A("XXXX up cqi_csi_request %d\n", q->cqi_csi_request);
A("XXXX up ul_index %d\n", q->ul_index);
A("XXXX up dl_assignment_index %d\n", q->dl_assignment_index);
A("XXXX up tpc_bitmap %d\n", q->tpc_bitmap);
A("XXXX up transmission_power %d\n", q->transmission_power);
}
if (p->pdu_type == NFAPI_HI_DCI0_HI_PDU_TYPE) {
nfapi_hi_dci0_hi_pdu_rel8_t *q = &p->hi_pdu.hi_pdu_rel8;
A("XXXX up rb start %d\n", q->resource_block_start);
A("XXXX up cs2_drms %d\n", q->cyclic_shift_2_for_drms);
A("XXXX up ack %d\n", q->hi_value);
A("XXXX up i_phich %d\n", q->i_phich);
A("XXXX up power %d\n", q->transmission_power);
}
}
}
if (d->UL_req != NULL) {
nfapi_ul_config_request_body_t *v=&d->UL_req->ul_config_request_body;
A("XXXX UL_req sfnsf %d (%d.%d)\n", d->UL_req->sfn_sf,
......
......@@ -1408,6 +1408,22 @@ int setup_RU_buffers(RU_t *ru) {
return(0);
}
static void* ru_stats_thread(void* param) {
RU_t *ru = (RU_t*)param;
wait_sync("ru_stats_thread");
while (!oai_exit) {
sleep(1);
if (opp_enabled == 1) {
if (ru->feprx) print_meas(&ru->ofdm_demod_stats,"feprx",NULL,NULL);
if (ru->feptx_ofdm) print_meas(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL);
}
}
return(NULL);
}
static void* ru_thread( void* param ) {
static int ru_thread_status;
......@@ -1557,7 +1573,6 @@ static void* ru_thread( void* param ) {
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
if (ru->fh_north_out) ru->fh_north_out(ru);
if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 0 );
}
......@@ -1659,9 +1674,12 @@ int start_rf(RU_t *ru) {
}
extern void fep_full(RU_t *ru);
extern void fep_full_2thread(RU_t *ru);
extern void ru_fep_full_2thread(RU_t *ru);
extern void feptx_ofdm(RU_t *ru);
extern void feptx_ofdm_2thread(RU_t *ru);
extern void feptx_prec(RU_t *ru);
extern void init_fep_thread(RU_t *ru,pthread_attr_t *attr);
extern void init_feptx_thread(RU_t *ru,pthread_attr_t *attr);
void init_RU_proc(RU_t *ru) {
......@@ -1752,8 +1770,11 @@ void init_RU_proc(RU_t *ru) {
pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void*)ru );
}
if (get_nprocs()>=2) {
if (ru->feprx) init_fep_thread(ru,NULL);
if (ru->feptx_ofdm) init_feptx_thread(ru,NULL);
}
if (opp_enabled == 1) pthread_create(&ru->ru_stats_thread,NULL,ru_stats_thread,(void*)ru);
}
......@@ -2029,8 +2050,8 @@ LOG_E(PHY,"ru->if_south:%d\n", ru->if_south);
ru->fh_north_out = fh_if4p5_north_out; // send_IF4p5 on reception
ru->fh_south_out = tx_rf; // send output to RF
ru->fh_north_asynch_in = fh_if4p5_north_asynch_in; // TX packets come asynchronously
ru->feprx = fep_full; // RX DFTs
ru->feptx_ofdm = feptx_ofdm; // this is fep with idft only (no precoding in RRU)
ru->feprx = (get_nprocs()<=4) ? fep_full :ru_fep_full_2thread; // RX DFTs
ru->feptx_ofdm = (get_nprocs()<=4) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft only (no precoding in RRU)
ru->feptx_prec = NULL;
ru->start_if = start_if; // need to start the if interface for if4p5
ru->ifdevice.host_type = RRU_HOST;
......@@ -2047,8 +2068,8 @@ LOG_E(PHY,"ru->if_south:%d\n", ru->if_south);
}
else if (ru->function == eNodeB_3GPP) {
ru->do_prach = 0; // no prach processing in RU
ru->feprx = fep_full; // RX DFTs
ru->feptx_ofdm = feptx_ofdm; // this is fep with idft and precoding
ru->feprx = (get_nprocs()<=2) ? fep_full : ru_fep_full_2thread; // RX DFTs
ru->feptx_ofdm = (get_nprocs()<=2) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft and precoding
ru->feptx_prec = feptx_prec; // this is fep with idft and precoding
ru->fh_north_in = NULL; // no incoming fronthaul from north
ru->fh_north_out = NULL; // no outgoing fronthaul to north
......@@ -2076,9 +2097,9 @@ LOG_E(PHY,"ru->if_south:%d\n", ru->if_south);
case REMOTE_IF5: // the remote unit is IF5 RRU
ru->do_prach = 0;
ru->feprx = fep_full; // this is frequency-shift + DFTs
ru->feprx = (get_nprocs()<=2) ? fep_full : fep_full; // this is frequency-shift + DFTs
ru->feptx_prec = feptx_prec; // need to do transmit Precoding + IDFTs
ru->feptx_ofdm = feptx_ofdm; // need to do transmit Precoding + IDFTs
ru->feptx_ofdm = (get_nprocs()<=2) ? feptx_ofdm : feptx_ofdm_2thread; // need to do transmit Precoding + IDFTs
if (ru->if_timing == synch_to_other) {
ru->fh_south_in = fh_slave_south_in; // synchronize to master
ru->fh_south_out = fh_if5_mobipass_south_out; // use send_IF5 for mobipass
......
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