Commit 90b9cbb8 authored by Laurent's avatar Laurent

remove global for frame/subframe, noS1 attach+ traffic ok, UE do not compile

parent ae25c883
......@@ -63,15 +63,19 @@ static inline void updateTimesReset(uint64_t start, Meas *M, int period, bool Ma
M->maxArray[0]=diff;
M->sum+=diff;
M->iterations++;
if ( MaxMin)
qsort(M->maxArray, 11, sizeof(uint64_t), cmpint);
else
qsort(M->maxArray, 11, sizeof(uint64_t), cmpintRev);
printMeas2(txt,M,period, MaxMin);
if (M->iterations%period == 0 ) {
bzero(M,sizeof(*M));
if (!MaxMin)
for (int i=0;i<11;i++)
for (int i=0; i<11; i++)
M->maxArray[i]=INT_MAX;
}
}
......@@ -111,10 +115,10 @@ static void fs6Dlpack(void *out, void *in, int szUnpacked) {
}
}
void prach_eNB_tosplit(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB) {
void prach_eNB_tosplit(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc) {
fs6_ul_t *header=(fs6_ul_t *) commonUDPdata(bufferZone);
if (is_prach_subframe(&eNB->frame_parms, eNB->proc.frame_prach,eNB->proc.subframe_prach)<=0)
if (is_prach_subframe(&eNB->frame_parms, proc->frame_prach,proc->subframe_prach)<=0)
return;
RU_t *ru;
......@@ -134,12 +138,13 @@ void prach_eNB_tosplit(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB) {
}
rx_prach(eNB,
proc,
eNB->RU_list[0],
header->max_preamble,
header->max_preamble_energy,
header->max_preamble_delay,
header->avg_preamble_energy,
eNB->proc.frame_prach,
proc->frame_prach,
0,
false
);
......@@ -166,20 +171,20 @@ void prach_eNB_tosplit(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB) {
return;
}
void prach_eNB_fromsplit(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB) {
void prach_eNB_fromsplit(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc) {
fs6_ul_t *header=(fs6_ul_t *) commonUDPdata(bufferZone);
uint16_t *max_preamble=header->max_preamble;
uint16_t *max_preamble_energy=header->max_preamble_energy;
uint16_t *max_preamble_delay=header->max_preamble_delay;
uint16_t *avg_preamble_energy=header->avg_preamble_energy;
int subframe=eNB->proc.subframe_prach;
int frame=eNB->proc.frame_prach;
int subframe=proc->subframe_prach;
int frame=proc->frame_prach;
// Fixme: not clear why we call twice with "br" and without
int br_flag=0;
if (br_flag==1) {
int prach_mask;
prach_mask = is_prach_subframe (&eNB->frame_parms, eNB->proc.frame_prach_br, eNB->proc.subframe_prach_br);
prach_mask = is_prach_subframe (&eNB->frame_parms, proc->frame_prach_br, proc->subframe_prach_br);
eNB->UL_INFO.rach_ind_br.rach_indication_body.preamble_list = eNB->preamble_list_br;
int ind = 0;
int ce_level = 0;
......@@ -563,10 +568,10 @@ void fill_rx_indication_from_split(uint8_t *bufferZone, PHY_VARS_eNB *eNB,int UE
pthread_mutex_unlock(&eNB->UL_INFO_mutex);
}
void pusch_procedures_fromsplit(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB, ul_propagation_t *ul_propa) {
void pusch_procedures_fromsplit(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, ul_propagation_t *ul_propa) {
//LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
const int subframe = eNB->proc.subframe_rx;
const int frame = eNB->proc.frame_rx;
const int subframe = proc->subframe_rx;
const int frame = proc->frame_rx;
uint32_t harq_pid;
uint32_t harq_pid0 = subframe2harq_pid(&eNB->frame_parms,frame,subframe);
......@@ -750,8 +755,8 @@ void recvFs6Ul(uint8_t *bufferZone, int nbBlocks, PHY_VARS_eNB *eNB, ul_propagat
sizeof(ulsch_harq->o_ACK));
memcpy(ulsch_harq->o,hULUE(bufPtr)->o, sizeof(ulsch_harq->o));
ul_propa[hULUE(bufPtr)->UE_id].ta=hULUE(bufPtr)->ta;
LOG_D(PHY,"Received ulsch data for: rnti:%x, fsf: %d/%d, cqi_crc_status %d O_ACK: %di, segment: %di, seglen: %d \n",
ulsch->rnti, eNB->proc.frame_rx, eNB->proc.subframe_rx, ulsch_harq->cqi_crc_status, ulsch_harq->O_ACK,hULUE(bufPtr)->segment, hULUE(bufPtr)->segLen);
LOG_D(PHY,"Received ulsch data for: rnti:%x, cqi_crc_status %d O_ACK: %di, segment: %di, seglen: %d \n",
ulsch->rnti, ulsch_harq->cqi_crc_status, ulsch_harq->O_ACK,hULUE(bufPtr)->segment, hULUE(bufPtr)->segLen);
} else if ( type == fs6ULcch ) {
int nb_uci=hULUEuci(bufPtr)->nb_active_ue;
fs6_ul_uespec_uci_element_t *tmp=(fs6_ul_uespec_uci_element_t *)(hULUEuci(bufPtr)+1);
......@@ -783,18 +788,18 @@ void recvFs6Ul(uint8_t *bufferZone, int nbBlocks, PHY_VARS_eNB *eNB, ul_propagat
}
}
void phy_procedures_eNB_uespec_RX_fromsplit(uint8_t *bufferZone, int nbBlocks,PHY_VARS_eNB *eNB) {
void phy_procedures_eNB_uespec_RX_fromsplit(uint8_t *bufferZone, int nbBlocks,PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc) {
// The configuration arrived in Dl, so we can extract the UL data
ul_propagation_t ul_propa[NUMBER_OF_UE_MAX];
recvFs6Ul(bufferZone, nbBlocks, eNB, ul_propa);
// dirty memory allocation in OAI...
for (int i = 0; i < NUMBER_OF_UCI_VARS_MAX; i++)
if ( eNB->uci_vars[i].frame == eNB->proc.frame_rx &&
eNB->uci_vars[i].subframe == eNB->proc.subframe_rx )
if ( eNB->uci_vars[i].frame == proc->frame_rx &&
eNB->uci_vars[i].subframe == proc->subframe_rx )
eNB->uci_vars[i].active=0;
pusch_procedures_fromsplit(bufferZone, nbBlocks, eNB, ul_propa);
pusch_procedures_fromsplit(bufferZone, nbBlocks, eNB, proc, ul_propa);
}
void rcvFs6DL(uint8_t *bufferZone, int nbBlocks, PHY_VARS_eNB *eNB, int frame, int subframe) {
......@@ -1379,6 +1384,9 @@ void phy_procedures_eNB_TX_tosplit(uint8_t *bufferZone, PHY_VARS_eNB *eNB, L1_rx
}
void DL_du_fs6(RU_t *ru) {
static uint64_t lastTS;
L1_rxtx_proc_t L1_proc;
for (int i=0; i<ru->num_eNB; i++) {
initBufferZone(bufferZone);
initStaticTime(begingWait);
......@@ -1388,40 +1396,36 @@ void DL_du_fs6(RU_t *ru) {
updateTimesReset(begingWait, &fullLoop, 1000, false, "DU wait CU");
if (nb_blocks > 0) {
L1_proc_t *L1_proc = &ru->eNB_list[i]->proc;
if ( L1_proc->timestamp_tx != hUDP(bufferZone)->timestamp) {
if ( lastTS+ru->eNB_list[i]->frame_parms.samples_per_tti != hUDP(bufferZone)->timestamp) {
LOG_E(HW,"Missed a subframe: expecting: %lu, received %lu\n",
L1_proc->timestamp_tx,
lastTS+ru->eNB_list[i]->frame_parms.samples_per_tti,
hUDP(bufferZone)->timestamp);
}
setAllfromTS(hUDP(bufferZone)->timestamp - sf_ahead*ru->eNB_list[i]->frame_parms.samples_per_tti);
phy_procedures_eNB_TX_fromsplit( bufferZone, nb_blocks, ru->eNB_list[i], &ru->eNB_list[i]->proc.L1_proc, 1);
lastTS=hUDP(bufferZone)->timestamp;
setAllfromTS(hUDP(bufferZone)->timestamp - sf_ahead*ru->eNB_list[i]->frame_parms.samples_per_tti, &L1_proc);
phy_procedures_eNB_TX_fromsplit( bufferZone, nb_blocks, ru->eNB_list[i], &L1_proc, 1);
} else
LOG_E(PHY,"DL not received for subframe\n");
}
feptx_prec(ru);
feptx_ofdm(ru);
tx_rf(ru);
feptx_prec(ru, &L1_proc);
feptx_ofdm(ru, &L1_proc);
tx_rf(ru, &L1_proc);
}
void UL_du_fs6(RU_t *ru, int frame, int subframe) {
RU_proc_t *ru_proc=&ru->proc;
void UL_du_fs6(RU_t *ru, L1_rxtx_proc_t *proc, int frame, int subframe) {
initStaticTime(begingWait);
initRefTimes(fullLoop);
pickStaticTime(begingWait);
rx_rf(ru);
rx_rf(ru, proc);
updateTimesReset(begingWait, &fullLoop, 1000, false, "DU wait USRP");
setAllfromTS(ru_proc->timestamp_rx);
setAllfromTS(proc->timestamp_rx, proc);
// front end processing: convert from time domain to frequency domain
// fills rxdataF buffer
fep_full(ru);
fep_full(ru, proc);
// Fixme: datamodel issue
PHY_VARS_eNB *eNB = RC.eNB[0][0];
L1_proc_t *proc = &eNB->proc;
if (NFAPI_MODE==NFAPI_MODE_PNF) {
// I am a PNF and I need to let nFAPI know that we have a (sub)frame tick
......@@ -1431,11 +1435,11 @@ void UL_du_fs6(RU_t *ru, int frame, int subframe) {
}
initBufferZone(bufferZone);
hUDP(bufferZone)->timestamp=ru->proc.timestamp_rx;
prach_eNB_tosplit(bufferZone, FS6_BUF_SIZE, eNB);
hUDP(bufferZone)->timestamp=proc->timestamp_rx;
prach_eNB_tosplit(bufferZone, FS6_BUF_SIZE, eNB, proc );
if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) {
phy_procedures_eNB_uespec_RX_tosplit(bufferZone, FS6_BUF_SIZE, eNB, &proc->L1_proc );
phy_procedures_eNB_uespec_RX_tosplit(bufferZone, FS6_BUF_SIZE, eNB, proc );
}
if (hUDP(bufferZone)->nbBlocks==0) {
......@@ -1449,20 +1453,19 @@ void UL_du_fs6(RU_t *ru, int frame, int subframe) {
}
}
void DL_cu_fs6(RU_t *ru) {
void DL_cu_fs6(RU_t *ru, L1_rxtx_proc_t *proc) {
// Fixme: datamodel issue
PHY_VARS_eNB *eNB = RC.eNB[0][0];
L1_proc_t *proc = &eNB->proc;
pthread_mutex_lock(&eNB->UL_INFO_mutex);
eNB->UL_INFO.frame = proc->frame_rx;
eNB->UL_INFO.subframe = proc->subframe_rx;
eNB->UL_INFO.module_id = eNB->Mod_id;
eNB->UL_INFO.CC_id = eNB->CC_id;
eNB->if_inst->UL_indication(&eNB->UL_INFO);
eNB->if_inst->UL_indication(&eNB->UL_INFO, proc);
pthread_mutex_unlock(&eNB->UL_INFO_mutex);
initBufferZone(bufferZone);
phy_procedures_eNB_TX_tosplit(bufferZone, eNB, &proc->L1_proc, 1, bufferZone, FS6_BUF_SIZE);
hUDP(bufferZone)->timestamp=proc->L1_proc.timestamp_tx;
phy_procedures_eNB_TX_tosplit(bufferZone, eNB, proc, 1, bufferZone, FS6_BUF_SIZE);
hUDP(bufferZone)->timestamp=proc->timestamp_tx;
if (hUDP(bufferZone)->nbBlocks==0) {
hUDP(bufferZone)->nbBlocks=1; // We have to send the signaling, even is there is no user plan data (no UE)
......@@ -1473,7 +1476,7 @@ void DL_cu_fs6(RU_t *ru) {
sendSubFrame(&sockFS6, bufferZone, sizeof(fs6_dl_t), CTsentCUv0 );
}
void UL_cu_fs6(RU_t *ru, uint64_t *TS) {
void UL_cu_fs6(RU_t *ru, L1_rxtx_proc_t *proc, uint64_t *TS) {
initBufferZone(bufferZone);
initStaticTime(begingWait);
initRefTimes(fullLoop);
......@@ -1494,23 +1497,22 @@ void UL_cu_fs6(RU_t *ru, uint64_t *TS) {
*TS=hUDP(bufferZone)->timestamp;
}
setAllfromTS(hUDP(bufferZone)->timestamp);
setAllfromTS(hUDP(bufferZone)->timestamp, proc);
PHY_VARS_eNB *eNB = RC.eNB[0][0];
if (is_prach_subframe(&eNB->frame_parms, eNB->proc.frame_prach,eNB->proc.subframe_prach)>0)
prach_eNB_fromsplit(bufferZone, sizeof(bufferZone), eNB);
if (is_prach_subframe(&eNB->frame_parms, proc->frame_prach,proc->subframe_prach)>0)
prach_eNB_fromsplit(bufferZone, sizeof(bufferZone), eNB, proc);
release_UE_in_freeList(eNB->Mod_id);
if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) {
phy_procedures_eNB_uespec_RX_fromsplit(bufferZone, nb_blocks, eNB);
phy_procedures_eNB_uespec_RX_fromsplit(bufferZone, nb_blocks, eNB, proc);
}
}
void *cu_fs6(void *arg) {
setbuf(stdout, NULL);
setbuf(stderr, NULL);
RU_t *ru = (RU_t *)arg;
//RU_proc_t *proc = &ru->proc;
fill_rf_config(ru,ru->rf_config_file);
......@@ -1531,26 +1533,29 @@ void *cu_fs6(void *arg) {
initRefTimes(waitDUAndProcessingUL);
initRefTimes(makeSendDL);
initRefTimes(fullLoop);
L1_rxtx_proc_t L1proc;
while(1) {
timeStamp+=ru->frame_parms.samples_per_tti;
updateTimesReset(begingWait, &fullLoop, 1000, true, "CU for full SubFrame (must be less 1ms)");
pickStaticTime(begingWait);
updateTimesReset(begingWait, &waitDUAndProcessingUL, 1000, true,"CU Time in wait Rx + Ul processing");
UL_cu_fs6(ru, &timeStamp);
UL_cu_fs6(ru, &L1proc, &timeStamp);
pickStaticTime(begingWait2);
DL_cu_fs6(ru);
DL_cu_fs6(ru, &L1proc);
updateTimesReset(begingWait2, &makeSendDL, 1000, true,"CU Time in DL build+send");
}
return NULL;
}
void *DlDu(void *arg) {
return NULL;
}
void *du_fs6(void *arg) {
setbuf(stdout, NULL);
setbuf(stderr, NULL);
RU_t *ru = (RU_t *)arg;
//RU_proc_t *proc = &ru->proc;
fill_rf_config(ru,ru->rf_config_file);
......@@ -1573,17 +1578,19 @@ void *du_fs6(void *arg) {
else LOG_I(PHY,"RU %d rf device ready\n",ru->idx);
} else LOG_I(PHY,"RU %d no rf device\n",ru->idx);
//threadCreate(&t, dutxfs6, (void *)ru, "DlDu", -1, OAI_PRIORITY_RT_MAX);
initStaticTime(begingWait);
initStaticTime(begingWait2);
initRefTimes(waitRxAndProcessingUL);
initRefTimes(makeSendDL);
initRefTimes(fullLoop);
L1_rxtx_proc_t L1proc;
while(1) {
L1_proc_t *proc = &ru->eNB_list[0]->proc;
L1_rxtx_proc_t *proc = &L1proc;
updateTimesReset(begingWait, &fullLoop, 1000, true,"DU for full SubFrame (must be less 1ms)");
pickStaticTime(begingWait);
UL_du_fs6(ru, proc->frame_rx,proc->subframe_rx);
UL_du_fs6(ru, proc, proc->frame_rx,proc->subframe_rx);
updateTimesReset(begingWait, &waitRxAndProcessingUL, 1000, true,"DU Time in wait Rx + Ul processing");
pickStaticTime(begingWait2);
DL_du_fs6(ru);
......
......@@ -30,11 +30,6 @@ static int DEFENBS[] = {0};
#include <executables/split_headers.h>
extern uint16_t sf_ahead;
extern void oai_subframe_ind(uint16_t sfn, uint16_t sf);
extern void fep_full(RU_t *ru);
extern void feptx_ofdm(RU_t *ru);
extern void feptx_prec(RU_t *ru);
extern void phy_init_RU(RU_t *);
static void *ru_thread( void *param );
void kill_RU_proc(RU_t *ru) {
......@@ -48,29 +43,11 @@ void reset_opp_meas(void) {
// Fixme: there are many mistakes in the datamodel and in redondant variables
// TDD is also mode complex
void setAllfromTS(uint64_t TS) {
for (int i=0; i <RC.nb_RU; i++) {
LTE_DL_FRAME_PARMS *fp=&RC.ru[i]->frame_parms;
RU_proc_t *proc =&RC.ru[i]->proc;
uint64_t TStx=TS+(sf_ahead)*fp->samples_per_tti;
uint64_t TSrach=TS;//-fp->samples_per_tti;
proc->timestamp_rx= TS;
proc->timestamp_tx= TStx;
proc->subframe_rx= (TS / fp->samples_per_tti)%10;
proc->subframe_tx= (TStx / fp->samples_per_tti)%10;
proc->subframe_prach=(TSrach / fp->samples_per_tti)%10;
proc->subframe_prach_br=proc->subframe_prach;
proc->frame_rx= (TS / (fp->samples_per_tti*10))&1023;
proc->frame_prach= (TSrach / (fp->samples_per_tti*10))&1023;
proc->frame_prach_br=(TSrach / (fp->samples_per_tti*10))&1023;
proc->frame_tx= (TStx / (fp->samples_per_tti*10))&1023;
}
void setAllfromTS(uint64_t TS, L1_rxtx_proc_t *proc) {
for (int i=0; i < RC.nb_inst; i++) {
for (int j=0; j<RC.nb_CC[i]; j++) {
LTE_DL_FRAME_PARMS *fp=&RC.eNB[i][j]->frame_parms;
L1_proc_t *proc =&RC.eNB[i][j]->proc;
L1_rxtx_proc_t *proc1=&RC.eNB[i][j]->proc.L1_proc;
uint64_t TStx=TS+(sf_ahead)*fp->samples_per_tti;
uint64_t TSrach=TS;//-fp->samples_per_tti;
proc->timestamp_rx= TS;
......@@ -82,11 +59,7 @@ void setAllfromTS(uint64_t TS) {
proc->frame_prach= (TSrach / (fp->samples_per_tti*10))&1023;
proc->frame_prach_br=(TSrach / (fp->samples_per_tti*10))&1023;
proc->frame_tx= (TStx / (fp->samples_per_tti*10))&1023;
proc1->timestamp_tx= TStx;
proc1->subframe_rx= (TS / fp->samples_per_tti)%10;
proc1->subframe_tx= (TStx / fp->samples_per_tti)%10;
proc1->frame_rx= (TS / (fp->samples_per_tti*10))&1023;
proc1->frame_tx= (TStx / (fp->samples_per_tti*10))&1023;
proc->subframe_tx= (TStx / fp->samples_per_tti)%10;
}
}
......@@ -98,24 +71,10 @@ void init_eNB_proc(int inst) {
/*int i=0;*/
int CC_id;
PHY_VARS_eNB *eNB;
L1_proc_t *proc;
L1_rxtx_proc_t *L1_proc;
for (CC_id=0; CC_id<RC.nb_CC[inst]; CC_id++) {
eNB = RC.eNB[inst][CC_id];
proc = &eNB->proc;
L1_proc = &proc->L1_proc;
L1_proc->instance_cnt = -1;
L1_proc->instance_cnt_RUs = 0;
proc->instance_cnt_prach = -1;
proc->instance_cnt_synch = -1;
proc->CC_id = CC_id;
proc->first_rx =1;
proc->first_tx =1;
pthread_mutex_init( &eNB->UL_INFO_mutex, NULL);
pthread_mutex_init( &L1_proc->mutex, NULL);
pthread_cond_init( &L1_proc->cond, NULL);
pthread_mutex_init( &proc->mutex_RU,NULL);
}
//for multiple CCs: setup master and slaves
......@@ -124,8 +83,8 @@ void init_eNB_proc(int inst) {
eNB = PHY_vars_eNB_g[inst][CC_id];
if (eNB->node_timing == synch_to_ext_device) { //master
eNB->proc.num_slaves = MAX_NUM_CCs-1;
eNB->proc.slave_proc = (L1_proc_t**)malloc(eNB->proc.num_slaves*sizeof(L1_proc_t*));
proc->num_slaves = MAX_NUM_CCs-1;
proc->slave_proc = (L1_proc_t**)malloc(proc->num_slaves*sizeof(L1_proc_t*));
for (i=0; i< eNB->proc.num_slaves; i++) {
if (i < CC_id) eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i]->proc);
......@@ -137,19 +96,6 @@ void init_eNB_proc(int inst) {
}
void init_RU_proc(RU_t *ru) {
int i=0;
RU_proc_t *proc;
proc = &ru->proc;
memset((void *)proc,0,sizeof(RU_proc_t));
proc->ru = ru;
proc->instance_cnt_synch = -1;
proc->instance_cnt_eNBs = -1;
proc->first_rx = 1;
proc->first_tx = 1;
proc->num_slaves = 0;
proc->frame_tx_unwrap = 0;
for (i=0; i<10; i++) proc->symbol_mask[i]=0;
pthread_t t;
char *fs6=getenv("fs6");
......@@ -469,7 +415,7 @@ void init_precoding_weights(PHY_VARS_eNB *eNB) {
}
}
void prach_procedures_ocp(PHY_VARS_eNB *eNB, int br_flag) {
void prach_procedures_ocp(PHY_VARS_eNB *eNB, L1_rxtx_proc_t * proc, int br_flag) {
uint16_t max_preamble[4],max_preamble_energy[4],max_preamble_delay[4],avg_preamble_energy[4];
RU_t *ru;
int aa=0;
......@@ -490,12 +436,13 @@ void prach_procedures_ocp(PHY_VARS_eNB *eNB, int br_flag) {
// run PRACH detection for CE-level 0 only for now when br_flag is set
rx_prach(eNB,
proc,
eNB->RU_list[0],
&max_preamble[0],
&max_preamble_energy[0],
&max_preamble_delay[0],
&avg_preamble_energy[0],
eNB->proc.frame_prach,
proc->frame_prach,
0
,br_flag
);
......@@ -508,7 +455,7 @@ void prach_procedures_ocp(PHY_VARS_eNB *eNB, int br_flag) {
if (br_flag==1) {
int prach_mask;
prach_mask = is_prach_subframe (&eNB->frame_parms, eNB->proc.frame_prach_br, eNB->proc.subframe_prach_br);
prach_mask = is_prach_subframe (&eNB->frame_parms, proc->frame_prach_br, proc->subframe_prach_br);
eNB->UL_INFO.rach_ind_br.rach_indication_body.preamble_list = eNB->preamble_list_br;
int ind = 0;
int ce_level = 0;
......@@ -528,7 +475,7 @@ void prach_procedures_ocp(PHY_VARS_eNB *eNB, int br_flag) {
eNB->preamble_list_br[ind].preamble_rel8.timing_advance = max_preamble_delay[ind]; //
eNB->preamble_list_br[ind].preamble_rel8.preamble = max_preamble[ind];
// note: fid is implicitly 0 here, this is the rule for eMTC RA-RNTI from 36.321, Section 5.1.4
eNB->preamble_list_br[ind].preamble_rel8.rnti = 1 + eNB->proc.subframe_prach + (60*(eNB->prach_vars_br.first_frame[ce_level] % 40));
eNB->preamble_list_br[ind].preamble_rel8.rnti = 1 + proc->subframe_prach + (60*(eNB->prach_vars_br.first_frame[ce_level] % 40));
eNB->preamble_list_br[ind].instance_length = 0; //don't know exactly what this is
eNB->preamble_list_br[ind].preamble_rel13.rach_resource_type = 1 + ce_level; // CE Level
LOG_I (PHY, "Filling NFAPI indication for RACH %d CELevel %d (mask %x) : TA %d, Preamble %d, rnti %x, rach_resource_type %d\n",
......@@ -549,8 +496,8 @@ void prach_procedures_ocp(PHY_VARS_eNB *eNB, int br_flag) {
LOG_I(PHY,"[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n",
eNB->Mod_id,
eNB->CC_id,
eNB->proc.frame_prach,
eNB->proc.subframe_prach,
proc->frame_prach,
proc->subframe_prach,
max_preamble[0],
max_preamble_energy[0]/10,
max_preamble_energy[0]%10,
......@@ -560,11 +507,11 @@ void prach_procedures_ocp(PHY_VARS_eNB *eNB, int br_flag) {
eNB->UL_INFO.rach_ind.rach_indication_body.preamble_list = &eNB->preamble_list[0];
eNB->UL_INFO.rach_ind.rach_indication_body.tl.tag = NFAPI_RACH_INDICATION_BODY_TAG;
eNB->UL_INFO.rach_ind.header.message_id = NFAPI_RACH_INDICATION;
eNB->UL_INFO.rach_ind.sfn_sf = eNB->proc.frame_prach<<4 | eNB->proc.subframe_prach;
eNB->UL_INFO.rach_ind.sfn_sf = proc->frame_prach<<4 | proc->subframe_prach;
eNB->preamble_list[0].preamble_rel8.tl.tag = NFAPI_PREAMBLE_REL8_TAG;
eNB->preamble_list[0].preamble_rel8.timing_advance = max_preamble_delay[0];
eNB->preamble_list[0].preamble_rel8.preamble = max_preamble[0];
eNB->preamble_list[0].preamble_rel8.rnti = 1+eNB->proc.subframe_prach; // note: fid is implicitly 0 here
eNB->preamble_list[0].preamble_rel8.rnti = 1+proc->subframe_prach; // note: fid is implicitly 0 here
eNB->preamble_list[0].preamble_rel13.rach_resource_type = 0;
eNB->preamble_list[0].instance_length = 0; //don't know exactly what this is
......@@ -589,11 +536,11 @@ void prach_procedures_ocp(PHY_VARS_eNB *eNB, int br_flag) {
}
} // else br_flag
void prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) {
void prach_eNB(PHY_VARS_eNB *eNB, L1_rxtx_proc_t * proc, int frame,int subframe) {
// check if we have to detect PRACH first
if (is_prach_subframe(&eNB->frame_parms, frame,subframe)>0) {
prach_procedures_ocp(eNB, 0);
prach_procedures_ocp(eNB, 1);
prach_procedures_ocp(eNB, proc, 0);
prach_procedures_ocp(eNB, proc, 1);
}
}
......@@ -609,7 +556,7 @@ static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name
AssertFatal( !(NFAPI_MODE==NFAPI_MODE_PNF &&
eNB->pdcch_vars[proc->subframe_tx&1].num_pdcch_symbols == 0), "");
prach_eNB(eNB,NULL,proc->frame_rx,proc->subframe_rx);
prach_eNB(eNB,proc,proc->frame_rx,proc->subframe_rx);
release_UE_in_freeList(eNB->Mod_id);
// UE-specific RX processing for subframe n
......@@ -622,41 +569,38 @@ static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name
eNB->UL_INFO.subframe = proc->subframe_rx;
eNB->UL_INFO.module_id = eNB->Mod_id;
eNB->UL_INFO.CC_id = eNB->CC_id;
eNB->if_inst->UL_indication(&eNB->UL_INFO);
eNB->if_inst->UL_indication(&eNB->UL_INFO, proc);
pthread_mutex_unlock(&eNB->UL_INFO_mutex);
phy_procedures_eNB_TX(eNB, proc, 1);
return(0);
}
void eNB_top(PHY_VARS_eNB *eNB, int dummy1, int dummy2, char *string,RU_t *ru) {
L1_proc_t *proc = &eNB->proc;
L1_rxtx_proc_t *L1_proc = &proc->L1_proc;
void eNB_top(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, int dummy1, int dummy2, char *string,RU_t *ru) {
if (!oai_exit) {
if (rxtx(eNB,L1_proc,string) < 0)
if (rxtx(eNB,proc,string) < 0)
LOG_E(PHY,"eNB %d CC_id %d failed during execution\n",eNB->Mod_id,eNB->CC_id);
}
}
void rx_rf(RU_t *ru) {
RU_proc_t *proc = &ru->proc;
void rx_rf(RU_t *ru, L1_rxtx_proc_t *proc) {
LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
void *rxp[ru->nb_rx];
unsigned int rxs;
int i;
openair0_timestamp ts=0,old_ts=0;
openair0_timestamp ts=0, timestamp_rx;
static openair0_timestamp old_ts=0;
for (i=0; i<ru->nb_rx; i++)
//receive in the next slot
rxp[i] = (void *)&ru->common.rxdata[i][((ru->proc.subframe_rx+1)%10)*fp->samples_per_tti];
rxp[i] = (void *)&ru->common.rxdata[i][((proc->subframe_rx+1)%10)*fp->samples_per_tti];
old_ts = proc->timestamp_rx;
rxs = ru->rfdevice.trx_read_func(&ru->rfdevice,
&ts,
rxp,
fp->samples_per_tti,
ru->nb_rx);
proc->timestamp_rx = ts-ru->ts_offset;
timestamp_rx = ts-ru->ts_offset;
// AssertFatal(rxs == fp->samples_per_tti,
// "rx_rf: Asked for %d samples, got %d from SDR\n",fp->samples_per_tti,rxs);
......@@ -670,23 +614,16 @@ void rx_rf(RU_t *ru) {
#endif
}
if (proc->first_rx == 1) {
//ru->ts_offset = proc->timestamp_rx;
//proc->timestamp_rx = 0;
proc->first_rx = false;
} else {
if (proc->timestamp_rx - old_ts != fp->samples_per_tti) {
LOG_E(HW,"impossible shift in rx stream, rx: %ld, previous rx distance: %ld, should be %d\n", proc->timestamp_rx, proc->timestamp_rx - old_ts, fp->samples_per_tti);
if (timestamp_rx - old_ts != fp->samples_per_tti) {
LOG_E(HW,"impossible shift in rx stream, rx: %ld, previous rx distance: %ld, should be %d\n", timestamp_rx, proc->timestamp_rx - old_ts, fp->samples_per_tti);
//ru->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_tti);
//proc->timestamp_rx = ts-ru->ts_offset;
}
}
setAllfromTS(proc->timestamp_rx);
old_ts=timestamp_rx;
setAllfromTS(timestamp_rx, proc);
}
void tx_rf(RU_t *ru) {
RU_proc_t *proc = &ru->proc;
void tx_rf(RU_t *ru, L1_rxtx_proc_t *proc) {
LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
void *txp[ru->nb_tx];
int i;
......@@ -740,8 +677,8 @@ void tx_rf(RU_t *ru) {
siglen+sf_extension,
ru->nb_tx,
flags);
LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n",ru->idx,
(long long unsigned int)proc->timestamp_tx,proc->frame_tx,proc->frame_tx_unwrap,proc->subframe_tx);
LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, subframe %d\n",ru->idx,
(long long unsigned int)proc->timestamp_tx,proc->frame_tx,proc->subframe_tx);
}
}
......@@ -749,6 +686,8 @@ static void *ru_thread( void *param ) {
setbuf(stdout, NULL);
setbuf(stderr, NULL);
RU_t *ru = (RU_t *)param;
L1_rxtx_proc_t L1proc;
L1_rxtx_proc_t * proc=&L1proc;
if (ru->if_south == LOCAL_RF) { // configure RF parameters only
fill_rf_config(ru,ru->rf_config_file);
......@@ -771,11 +710,11 @@ static void *ru_thread( void *param ) {
// This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices
while (!oai_exit) {
// synchronization on input FH interface, acquire signals/data and block
rx_rf(ru);
rx_rf(ru, proc);
// do RX front-end processing (frequency-shift, dft) if needed
if (ru->feprx)
ru->feprx(ru);
ru->feprx(ru, proc);
// At this point, all information for subframe has been received on FH interface
// If this proc is to provide synchronization, do so
......@@ -784,20 +723,20 @@ static void *ru_thread( void *param ) {
for (int i=0; i<ru->num_eNB; i++) {
char string[20];
sprintf(string,"Incoming RU %d",ru->idx);
ru->eNB_top(ru->eNB_list[i],ru->proc.frame_rx,ru->proc.subframe_rx,string,ru);
ru->eNB_top(ru->eNB_list[i],proc, proc->frame_rx,proc->subframe_rx,string,ru);
}
// do TX front-end processing if needed (precoding and/or IDFTs)
if (ru->feptx_prec)
ru->feptx_prec(ru);
ru->feptx_prec(ru, proc);
// do OFDM if needed
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm))
ru->feptx_ofdm(ru);
ru->feptx_ofdm(ru, proc);
// do outgoing fronthaul (south) if needed
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out))
ru->fh_south_out(ru);
ru->fh_south_out(ru, proc);
}
LOG_W(PHY,"Exiting ru_thread \n");
......
......@@ -229,15 +229,15 @@ static inline void *commonUDPdata(uint8_t *ptr) {
return (void *) (((commonUDP_t *)ptr)+1);
}
void setAllfromTS(uint64_t TS);
void setAllfromTS(uint64_t TS, L1_rxtx_proc_t *proc);
void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB,LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask,
uint16_t rnti, int32_t stat);
void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset);
void *cu_fs6(void *arg);
void *du_fs6(void *arg);
void fill_rf_config(RU_t *ru, char *rf_config_file);
void rx_rf(RU_t *ru);
void tx_rf(RU_t *ru);
void rx_rf(RU_t *ru, L1_rxtx_proc_t *proc);
void tx_rf(RU_t *ru, L1_rxtx_proc_t *proc);
void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe);
void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc);
bool dlsch_procedures(PHY_VARS_eNB *eNB,
......@@ -256,9 +256,9 @@ void uci_procedures(PHY_VARS_eNB *eNB,
// mistakes in main OAI
void phy_init_RU(RU_t *);
void feptx_prec(RU_t *);
void feptx_ofdm(RU_t *);
void feptx_prec(RU_t *, L1_rxtx_proc_t *proc);
void feptx_ofdm(RU_t *, L1_rxtx_proc_t *proc);
void oai_subframe_ind(uint16_t sfn, uint16_t sf);
void fep_full(RU_t *ru);
void fep_full(RU_t *ru, L1_rxtx_proc_t *proc);
extern uint16_t sf_ahead;
#endif
......@@ -692,13 +692,12 @@ void pnf_phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t *header) {
free(header);
}
int pnf_phy_hi_dci0_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_hi_dci0_request_t *req) {
int pnf_phy_hi_dci0_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_hi_dci0_request_t *req) {
if (req->hi_dci0_request_body.number_of_dci == 0 && req->hi_dci0_request_body.number_of_hi == 0)
LOG_D(PHY,"[PNF] HI_DCI0_REQUEST SFN/SF:%05d dci:%d hi:%d\n", NFAPI_SFNSF2DEC(req->sfn_sf), req->hi_dci0_request_body.number_of_dci, req->hi_dci0_request_body.number_of_hi);
//phy_info* phy = (phy_info*)(pnf_p7->user_data);
struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
L1_rxtx_proc_t *proc = &eNB->proc.L1_proc;
for (int i=0; i<req->hi_dci0_request_body.number_of_dci + req->hi_dci0_request_body.number_of_hi; i++) {
//LOG_D(PHY,"[PNF] HI_DCI0_REQ sfn_sf:%d PDU[%d]\n", NFAPI_SFNSF2DEC(req->sfn_sf), i);
......@@ -719,7 +718,7 @@ int pnf_phy_hi_dci0_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_hi_dci0_request_t *
return 0;
}
int pnf_phy_dl_config_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_dl_config_request_t *req) {
int pnf_phy_dl_config_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_dl_config_request_t *req) {
if (RC.ru == 0) {
return -1;
}
......@@ -740,7 +739,6 @@ int pnf_phy_dl_config_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_dl_config_request
int sfn = NFAPI_SFNSF2SFN(req->sfn_sf);
int sf = NFAPI_SFNSF2SF(req->sfn_sf);
struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
L1_rxtx_proc_t *proc = &eNB->proc.L1_proc;
nfapi_dl_config_request_pdu_t *dl_config_pdu_list = req->dl_config_request_body.dl_config_pdu_list;
LTE_eNB_PDCCH *pdcch_vars = &eNB->pdcch_vars[sf&1];
pdcch_vars->num_pdcch_symbols = req->dl_config_request_body.number_pdcch_ofdm_symbols;
......@@ -797,7 +795,7 @@ int pnf_phy_dl_config_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_dl_config_request
uint8_t *dlsch_sdu = tx_pdus[UE_id][harq_pid];
memcpy(dlsch_sdu, tx_pdu->segments[0].segment_data, tx_pdu->segments[0].segment_length);
//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() DLSCH:pdu_index:%d handle_nfapi_dlsch_pdu(eNB, proc_rxtx, dlsch_pdu, transport_blocks:%d sdu:%p) eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols:%d\n", __FUNCTION__, rel8_pdu->pdu_index, rel8_pdu->transport_blocks, dlsch_sdu, eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols);
handle_nfapi_dlsch_pdu( eNB, sfn,sf, &eNB->proc.L1_proc, &dl_config_pdu_list[i], rel8_pdu->transport_blocks-1, dlsch_sdu);
handle_nfapi_dlsch_pdu( eNB, sfn,sf, proc, &dl_config_pdu_list[i], rel8_pdu->transport_blocks-1, dlsch_sdu);
} else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() DLSCH NULL TX PDU SFN/SF:%d PDU_INDEX:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), rel8_pdu->pdu_index);
}
......@@ -837,7 +835,7 @@ int pnf_phy_tx_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_tx_request_t *req) {
return 0;
}
int pnf_phy_ul_config_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_ul_config_request_t *req) {
int pnf_phy_ul_config_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_ul_config_request_t *req) {
if (0)LOG_D(PHY,"[PNF] UL_CONFIG_REQ %s() sfn_sf:%d pdu:%d rach_prach_frequency_resources:%d srs_present:%u\n",
__FUNCTION__,
NFAPI_SFNSF2DEC(req->sfn_sf),
......@@ -866,7 +864,6 @@ int pnf_phy_ul_config_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_ul_config_request
uint16_t curr_sfn = NFAPI_SFNSF2SFN(req->sfn_sf);
uint16_t curr_sf = NFAPI_SFNSF2SF(req->sfn_sf);
struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
L1_rxtx_proc_t *proc = &eNB->proc.L1_proc;
nfapi_ul_config_request_pdu_t *ul_config_pdu_list = req->ul_config_request_body.ul_config_pdu_list;
for (int i=0; i<req->ul_config_request_body.number_of_pdus; i++) {
......
......@@ -321,9 +321,8 @@ int pnf_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_config_
return 0;
}
int wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf) {
L1_proc_t *proc=&eNB->proc;
L1_rxtx_proc_t *L1_proc= (sf&1)? &proc->L1_proc : &proc->L1_proc_tx;
int wake_eNB_rxtx(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, uint16_t sfn, uint16_t sf) {
L1_rxtx_proc_t *L1_proc= proc;
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
//printf("%s(eNB:%p, sfn:%d, sf:%d)\n", __FUNCTION__, eNB, sfn, sf);
//int i;
......@@ -398,7 +397,7 @@ int phy_sync_indication(struct nfapi_vnf_p7_config *config, uint8_t sync) {
return(0);
}
int phy_subframe_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uint16_t sfn_sf) {
int phy_subframe_indication(L1_rxtx_proc_t * proc, struct nfapi_vnf_p7_config *config, uint16_t phy_id, uint16_t sfn_sf) {
static uint8_t first_time = 1;
if (first_time) {
......@@ -410,7 +409,7 @@ int phy_subframe_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id,
uint16_t sfn = NFAPI_SFNSF2SFN(sfn_sf);
uint16_t sf = NFAPI_SFNSF2SF(sfn_sf);
//LOG_D(PHY,"[VNF] subframe indication sfn_sf:%d sfn:%d sf:%d\n", sfn_sf, sfn, sf);
wake_eNB_rxtx(RC.eNB[0][0], sfn, sf);
wake_eNB_rxtx(RC.eNB[0][0], proc, sfn, sf);
} else {
printf("[VNF] %s() RC.eNB:%p\n", __FUNCTION__, RC.eNB);
......
......@@ -148,7 +148,7 @@ int lte_est_timing_advance_pusch(PHY_VARS_eNB *eNB,module_id_t UE_id)
max_pos = max_pos-frame_parms->ofdm_symbol_size;
//#ifdef DEBUG_PHY
LOG_D(PHY,"frame %d: max_pos = %d, sync_pos=%d\n",eNB->proc.frame_rx,max_pos,sync_pos);
LOG_D(PHY,"max_pos = %d, sync_pos=%d\n",max_pos,sync_pos);
//#endif //DEBUG_PHY
return max_pos - sync_pos;
......
......@@ -54,7 +54,7 @@ int32_t lte_ul_channel_estimation(PHY_VARS_eNB *eNB,
int32_t **rxdataF_ext = (eNB!=NULL) ? pusch_vars->rxdataF_ext : calibration->rxdataF_ext;
int subframe = (eNB!=NULL) ? proc->subframe_rx : ru->proc.subframe_rx;
int subframe = proc->subframe_rx;
uint8_t harq_pid;
int16_t delta_phase = 0;
......
......@@ -328,231 +328,7 @@ int dlsch_encoding_2threads0(te_params *tep) {
extern int oai_exit;
void *te_thread(void *param) {
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
thread_top_init("te_thread",1,200000,250000,500000);
pthread_setname_np( pthread_self(),"te processing");
LOG_I(PHY,"thread te created id=%ld\n", syscall(__NR_gettid));
te_params *tep = (te_params *)param;
//wait_sync("te_thread");
while (!oai_exit) {
if (wait_on_condition(&tep->mutex_te,&tep->cond_te,&tep->instance_cnt_te,"te thread")<0) break;
if(oai_exit) break;
dlsch_encoding_2threads0(tep);
if (release_thread(&tep->mutex_te,&tep->instance_cnt_te,"te thread")<0) break;
if (pthread_cond_signal(&tep->cond_te) != 0) {
printf("[eNB] ERROR pthread_cond_signal for te thread exit\n");
exit_fun( "ERROR pthread_cond_signal" );
return(NULL);
}
/*if(opp_enabled == 1 && te_wakeup_stats0->p_time>50*3000){
print_meas_now(te_wakeup_stats0,"coding_wakeup",stderr);
printf("te_thread0 delay for waking up in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx);
}*/
}
return(NULL);
}
int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
unsigned char *a,
uint8_t num_pdcch_symbols,
LTE_eNB_DLSCH_t *dlsch,
int frame,
uint8_t subframe,
time_stats_t *rm_stats,
time_stats_t *te_stats,
time_stats_t *te_wait_stats,
time_stats_t *te_main_stats,
time_stats_t *te_wakeup_stats0,
time_stats_t *te_wakeup_stats1,
time_stats_t *i_stats,
int worker_num) {
//start_meas(&eNB->dlsch_turbo_encoding_preperation_stats);
LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
L1_proc_t *proc = &eNB->proc;
unsigned int G;
unsigned int crc=1;
unsigned char harq_pid = dlsch->harq_ids[frame%2][subframe];
if((harq_pid < 0) || (harq_pid >= dlsch->Mdlharq)) {
LOG_E(PHY,"dlsch_encoding_2threads illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__);
return(-1);
}
unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb;
unsigned int A;
unsigned char mod_order;
unsigned int Kr=0,Kr_bytes,r,r_offset=0;
// unsigned short m=dlsch->harq_processes[harq_pid]->mcs;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);
A = dlsch->harq_processes[harq_pid]->TBS; //6228
mod_order = dlsch->harq_processes[harq_pid]->Qm;
G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,
dlsch->harq_processes[harq_pid]->mimo_mode==TM7?7:0);
if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet
start_meas(&eNB->dlsch_turbo_encoding_preperation_stats);
// Add 24-bit crc (polynomial A) to payload
crc = crc24a(a,
A)>>8;
stop_meas(&eNB->dlsch_turbo_encoding_preperation_stats);
a[A>>3] = ((uint8_t *)&crc)[2];
a[1+(A>>3)] = ((uint8_t *)&crc)[1];
a[2+(A>>3)] = ((uint8_t *)&crc)[0];
dlsch->harq_processes[harq_pid]->B = A+24;
memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4);
//stop_meas(&eNB->dlsch_turbo_encoding_preperation_stats);
start_meas(&eNB->dlsch_turbo_encoding_segmentation_stats);
if (lte_segmentation(dlsch->harq_processes[harq_pid]->b,
dlsch->harq_processes[harq_pid]->c,
dlsch->harq_processes[harq_pid]->B,
&dlsch->harq_processes[harq_pid]->C,
&dlsch->harq_processes[harq_pid]->Cplus,
&dlsch->harq_processes[harq_pid]->Cminus,
&dlsch->harq_processes[harq_pid]->Kplus,
&dlsch->harq_processes[harq_pid]->Kminus,
&dlsch->harq_processes[harq_pid]->F)<0)
return(-1);
stop_meas(&eNB->dlsch_turbo_encoding_segmentation_stats);
start_meas(&eNB->dlsch_turbo_encoding_signal_stats);
for(int i=0; i<worker_num; i++) {
proc->tep[i].eNB = eNB;
proc->tep[i].dlsch = dlsch;
proc->tep[i].G = G;
proc->tep[i].harq_pid = harq_pid;
proc->tep[i].total_worker = worker_num;
proc->tep[i].current_worker = i;
pthread_mutex_lock( &proc->tep[i].mutex_te );
if (proc->tep[i].instance_cnt_te==0) {
printf("[eNB] TE thread busy\n");
exit_fun("TE thread busy");
pthread_mutex_unlock( &proc->tep[i].mutex_te );
return(-1);
}
++proc->tep[i].instance_cnt_te;
// wakeup worker to do segments
if (pthread_cond_signal(&proc->tep[i].cond_te) != 0) {
printf("[eNB] ERROR pthread_cond_signal for te thread %d exit\n",i);
exit_fun( "ERROR pthread_cond_signal" );
return (-1);
}
pthread_mutex_unlock( &proc->tep[i].mutex_te );
}
stop_meas(&eNB->dlsch_turbo_encoding_signal_stats);
start_meas(te_main_stats);
for (r=(dlsch->harq_processes[harq_pid]->C/(worker_num+1))*worker_num; r<dlsch->harq_processes[harq_pid]->C; r++) {
if (r<dlsch->harq_processes[harq_pid]->Cminus)
Kr = dlsch->harq_processes[harq_pid]->Kminus;
else
Kr = dlsch->harq_processes[harq_pid]->Kplus;
Kr_bytes = Kr>>3;
start_meas(te_stats);
encoder(dlsch->harq_processes[harq_pid]->c[r],
Kr>>3,
&dlsch->harq_processes[harq_pid]->d[r][96],
(r==0) ? dlsch->harq_processes[harq_pid]->F : 0
);
stop_meas(te_stats);
start_meas(i_stats);
dlsch->harq_processes[harq_pid]->RTC[r] =
sub_block_interleaving_turbo(4+(Kr_bytes*8),
&dlsch->harq_processes[harq_pid]->d[r][96],
dlsch->harq_processes[harq_pid]->w[r]);
stop_meas(i_stats);
}
} else {
for(int i=0; i<worker_num; i++) {
proc->tep[i].eNB = eNB;
proc->tep[i].dlsch = dlsch;
proc->tep[i].G = G;
proc->tep[i].total_worker = worker_num;
proc->tep[i].current_worker = i;
if (pthread_cond_signal(&proc->tep[i].cond_te) != 0) {
printf("[eNB] ERROR pthread_cond_signal for te thread exit\n");
exit_fun( "ERROR pthread_cond_signal" );
return (-1);
}
}
}
// Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
// outputs for each code segment, see Section 5.1.5 p.20
for (r=0,r_offset=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
// get information for E for the segments that are handled by the worker thread
if (r<(dlsch->harq_processes[harq_pid]->C/(worker_num+1))*worker_num) {
int Nl=dlsch->harq_processes[harq_pid]->Nl;
int Qm=dlsch->harq_processes[harq_pid]->Qm;
int C = dlsch->harq_processes[harq_pid]->C;
int Gp = G/Nl/Qm;
int GpmodC = Gp%C;
if (r < (C-(GpmodC)))
r_offset += Nl*Qm * (Gp/C);
else
r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));
} else {
start_meas(rm_stats);
r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
G, //G
dlsch->harq_processes[harq_pid]->w[r],
dlsch->harq_processes[harq_pid]->e+r_offset,
dlsch->harq_processes[harq_pid]->C, // C
dlsch->Nsoft, // Nsoft,
dlsch->Mdlharq,
dlsch->Kmimo,
dlsch->harq_processes[harq_pid]->rvidx,
dlsch->harq_processes[harq_pid]->Qm,
dlsch->harq_processes[harq_pid]->Nl,
r,
nb_rb);
// m); // r
stop_meas(rm_stats);
}
}
stop_meas(te_main_stats);
start_meas(te_wait_stats);
if(worker_num == 1) {
wait_on_busy_condition(&proc->tep[0].mutex_te,&proc->tep[0].cond_te,&proc->tep[0].instance_cnt_te,"te thread 0");
} else if(worker_num == 2) {
wait_on_busy_condition(&proc->tep[0].mutex_te,&proc->tep[0].cond_te,&proc->tep[0].instance_cnt_te,"te thread 0");
wait_on_busy_condition(&proc->tep[1].mutex_te,&proc->tep[1].cond_te,&proc->tep[1].instance_cnt_te,"te thread 1");
} else {
wait_on_busy_condition(&proc->tep[0].mutex_te,&proc->tep[0].cond_te,&proc->tep[0].instance_cnt_te,"te thread 0");
wait_on_busy_condition(&proc->tep[1].mutex_te,&proc->tep[1].cond_te,&proc->tep[1].instance_cnt_te,"te thread 1");
wait_on_busy_condition(&proc->tep[2].mutex_te,&proc->tep[2].cond_te,&proc->tep[2].instance_cnt_te,"te thread 2");
}
stop_meas(te_wait_stats);
/*if(opp_enabled == 1 && te_wait_stats->p_time>100*3000){
print_meas_now(te_wait_stats,"coding_wait",stderr);
printf("coding delay in wait on codition in frame_rx: %d \n",proc->frame_rx);
}*/
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
return(0);
}
int dlsch_encoding_all(PHY_VARS_eNB *eNB,
unsigned char *a,
uint8_t num_pdcch_symbols,
......@@ -589,68 +365,6 @@ int dlsch_encoding_all(PHY_VARS_eNB *eNB,
}
}
if(get_thread_worker_conf() == WORKER_ENABLE) {
if(C >= 8) { //one main three worker
encoding_return =
dlsch_encoding_2threads(eNB,
a,
num_pdcch_symbols,
dlsch,
frame,
subframe,
rm_stats,
te_stats,
te_wait_stats,
te_main_stats,
te_wakeup_stats0,
te_wakeup_stats1,
i_stats,
3);
} else if(C >= 6) { //one main two worker
encoding_return =
dlsch_encoding_2threads(eNB,
a,
num_pdcch_symbols,
dlsch,
frame,
subframe,
rm_stats,
te_stats,
te_wait_stats,
te_main_stats,
te_wakeup_stats0,
te_wakeup_stats1,
i_stats,
2);
} else if(C >= 4) { //one main one worker
encoding_return =
dlsch_encoding_2threads(eNB,
a,
num_pdcch_symbols,
dlsch,
frame,
subframe,
rm_stats,
te_stats,
te_wait_stats,
te_main_stats,
te_wakeup_stats0,
te_wakeup_stats1,
i_stats,
1);
} else {
encoding_return =
dlsch_encoding(eNB,
a,
num_pdcch_symbols,
dlsch,
frame,
subframe,
rm_stats,
te_stats,
i_stats);
}
} else {
encoding_return =
dlsch_encoding(eNB,
a,
......@@ -661,7 +375,6 @@ int dlsch_encoding_all(PHY_VARS_eNB *eNB,
rm_stats,
te_stats,
i_stats);
}
return encoding_return;
}
......
......@@ -308,7 +308,7 @@ void send_IF5(RU_t *ru, openair0_timestamp proc_timestamp, int subframe, uint8_t
}
void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16_t packet_type) {
void recv_IF5(RU_t *ru, L1_rxtx_proc_t *proc, openair0_timestamp *proc_timestamp, int subframe, uint16_t packet_type) {
LTE_DL_FRAME_PARMS *fp=&ru->frame_parms;
int32_t *txp[fp->nb_antennas_tx], *rxp[fp->nb_antennas_rx];
......@@ -505,7 +505,6 @@ void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16
rxp[0] = (void*)&ru->common.rxdata[0][subframe*ru->frame_parms.samples_per_tti];
rxp128 = (__m128i *) (rxp[0]);
RU_proc_t *proc = &ru->proc;
/*
// while(packet_id<fp->samples_per_tti/db_fulllength) {
data_block = data_block_head;
......@@ -569,13 +568,13 @@ void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16
subframe_skip++;
offset_cnt = header->seqno;
} else {
if ((offset_cnt != header->seqno) && (start_flag == 0) && (proc->first_rx > 3)){
if ((offset_cnt != header->seqno) && (start_flag == 0) ){
#ifdef DEBUG_UL_MOBIPASS
LOG_D(PHY,"[Mobipass] Reset sequence number, offset_cnt:%d, header->seqno:%d, packet_id:%d\n", offset_cnt, header->seqno, packet_id);
#endif
reset_flag=1;
}
if ((reset_flag == 1) && (proc->first_rx > 3 ) && (start_flag == 0) && (packet_id == 0)) {
if ((reset_flag == 1) && (start_flag == 0) && (packet_id == 0)) {
packet_id = 1;
reset_flag = 0;
}
......
......@@ -61,7 +61,8 @@ typedef struct IF5_mobipass_header IF5_mobipass_header_t;
void send_IF5(RU_t *, openair0_timestamp, int, uint8_t*, uint16_t);
void recv_IF5(RU_t *, openair0_timestamp*, int, uint16_t);
void recv_IF5(RU_t *ru, L1_rxtx_proc_t *proc, openair0_timestamp *proc_timestamp, int subframe, uint16_t packet_type);
void malloc_IF5_buffer(RU_t *ru);
......
......@@ -38,12 +38,15 @@
#include "SCHED/sched_eNB.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "prach_extern.h"
#include <openair1/PHY/LTE_TRANSPORT/transport_proto.h>
#include <executables/split_headers.h>
#if (LTE_RRC_VERSION < MAKE_VERSION(14, 0, 0))
#define rx_prach0 rx_prach
#endif
void rx_prach0(PHY_VARS_eNB *eNB,
L1_rxtx_proc_t *proc,
RU_t *ru,
uint16_t *max_preamble,
uint16_t *max_preamble_energy,
......@@ -147,13 +150,13 @@ void rx_prach0(PHY_VARS_eNB *eNB,
if (br_flag == 1) {
prach_ifftp = eNB->prach_vars_br.prach_ifft[ce_level];
subframe = eNB->proc.subframe_prach_br;
subframe = proc->subframe_prach_br;
prachF = eNB->prach_vars_br.prachF;
rxsigF = eNB->prach_vars_br.rxsigF[ce_level];
if (LOG_DEBUGFLAG(PRACH)){
if (((eNB->proc.frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (eNB) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d, rootSequenceIndex %d, repetition number %d,numRepetitionsPrePreambleAttempt %d\n",
br_flag,ce_level,eNB->proc.frame_prach,subframe,
if (((proc->frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (eNB) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d, rootSequenceIndex %d, repetition number %d,numRepetitionsPrePreambleAttempt %d\n",
br_flag,ce_level,proc->frame_prach,subframe,
fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level],
prach_ConfigIndex,rootSequenceIndex,
eNB->prach_vars_br.repetition_number[ce_level],
......@@ -163,34 +166,30 @@ void rx_prach0(PHY_VARS_eNB *eNB,
#endif
{
prach_ifftp = eNB->prach_vars.prach_ifft[0];
subframe = eNB->proc.subframe_prach;
subframe = proc->subframe_prach;
prachF = eNB->prach_vars.prachF;
rxsigF = eNB->prach_vars.rxsigF[0];
if (LOG_DEBUGFLAG(PRACH)){
if (((eNB->proc.frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (eNB) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d , rootSequenceIndex %d\n", subframe,fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset,prach_ConfigIndex,rootSequenceIndex);
if (((proc->frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (eNB) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d , rootSequenceIndex %d\n", subframe,fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset,prach_ConfigIndex,rootSequenceIndex);
}
}
} else {
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
if (br_flag == 1) {
subframe = ru->proc.subframe_prach_br;
subframe = proc->subframe_prach_br;
rxsigF = ru->prach_rxsigF_br[ce_level];
if (LOG_DEBUGFLAG(PRACH)) {
if (((ru->proc.frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (RU) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n",
br_flag,ce_level,ru->proc.frame_prach,subframe,fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level],prach_ConfigIndex);
if (((proc->frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (RU) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n",
br_flag,ce_level,proc->frame_prach,subframe,fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level],prach_ConfigIndex);
}
} else
#endif
{
subframe = ru->proc.subframe_prach;
subframe = proc->subframe_prach;
rxsigF = ru->prach_rxsigF;
if (LOG_DEBUGFLAG(PRACH)) {
if (((ru->proc.frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (RU) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n",
subframe,fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset,prach_ConfigIndex);
}
}
}
......@@ -218,8 +217,8 @@ void rx_prach0(PHY_VARS_eNB *eNB,
if (prach[0]!= NULL) LOG_M("prach_rx","prach_rx",prach[0],fp->samples_per_tti,1,1);
LOG_I(PHY,"RU %d, br_flag %d ce_level %d frame %d subframe %d per_tti:%d prach:%p (energy %d) TA:%d %s rxdata:%p index:%d\n",
ru->idx,br_flag,ce_level,ru->proc.frame_prach,subframe,fp->samples_per_tti,
LOG_I(PHY,"RU %d, br_flag %d ce_level %d subframe %d per_tti:%d prach:%p (energy %d) TA:%d %s rxdata:%p index:%d\n",
ru->idx,br_flag,ce_level,subframe,fp->samples_per_tti,
prach[aa],dbEn0,ru->N_TA_offset,buffer,ru->common.rxdata[aa],
(subframe*fp->samples_per_tti)-ru->N_TA_offset);
}
......@@ -424,16 +423,16 @@ void rx_prach0(PHY_VARS_eNB *eNB,
if ((eNB==NULL) && ru->function == NGFI_RRU_IF4p5) {
/// **** send_IF4 of rxsigF to RAU **** ///
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
if (br_flag == 1) send_IF4p5(ru, ru->proc.frame_prach, ru->proc.subframe_prach, IF4p5_PRACH+1+ce_level);
if (br_flag == 1) send_IF4p5(ru, proc->frame_prach, proc->subframe_prach, IF4p5_PRACH+1+ce_level);
else
#endif
send_IF4p5(ru, ru->proc.frame_prach, ru->proc.subframe_prach, IF4p5_PRACH);
send_IF4p5(ru, proc->frame_prach, proc->subframe_prach, IF4p5_PRACH);
return;
} else if (eNB!=NULL) {
if ( LOG_DEBUGFLAG(PRACH)) {
int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
if ((en > 60)&&(br_flag==1)) LOG_I(PHY,"PRACH (br_flag %d,ce_level %d, n_ra_prb %d, k %d): Frame %d, Subframe %d => %d dB\n",br_flag,ce_level,n_ra_prb,k,eNB->proc.frame_rx,eNB->proc.subframe_rx,en);
if ((en > 60)&&(br_flag==1)) LOG_I(PHY,"PRACH (br_flag %d,ce_level %d, n_ra_prb %d, k %d): Frame %d, Subframe %d => %d dB\n",br_flag,ce_level,n_ra_prb,k,proc->frame_rx,proc->subframe_rx,en);
}
}
......@@ -475,7 +474,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
if (LOG_DEBUGFLAG(PRACH)) {
int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
if (en>60) LOG_I(PHY,"frame %d, subframe %d : Trying preamble %d (br_flag %d)\n",ru->proc.frame_prach,subframe,preamble_index,br_flag);
if (en>60) LOG_I(PHY,"frame %d, subframe %d : Trying preamble %d (br_flag %d)\n",proc->frame_prach,subframe,preamble_index,br_flag);
}
if (restricted_set == 0) {
......@@ -561,7 +560,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
if (en>60) LOG_I(PHY,"frame %d, subframe %d : preamble index %d: offset %d, preamble shift %d (br_flag %d, en %d)\n",
ru->proc.frame_prach,subframe,preamble_index,preamble_offset,preamble_shift,br_flag,en);
proc->frame_prach,subframe,preamble_index,preamble_offset,preamble_shift,br_flag,en);
}
log2_ifft_size = 10;
......@@ -643,7 +642,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
if (LOG_DEBUGFLAG(PRACH)) {
int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840));
if (en>60) LOG_I(PHY,"frame %d, subframe %d: Checking for peak in time-domain (br_flag %d, en %d)\n",ru->proc.frame_prach,subframe,br_flag,en);
if (en>60) LOG_I(PHY,"frame %d, subframe %d: Checking for peak in time-domain (br_flag %d, en %d)\n",proc->frame_prach,subframe,br_flag,en);
}
preamble_shift2 = ((preamble_shift==0) ? 0 : ((preamble_shift<<log2_ifft_size)/N_ZC));
......@@ -663,7 +662,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
if ((en>60) && (br_flag==1))
LOG_D(PHY,"frame %d, subframe %d : max_preamble_energy %d, max_preamble_delay %d, max_preamble %d (br_flag %d,ce_level %d, levdB %d, lev %d)\n",
ru->proc.frame_prach,subframe,
proc->frame_prach,subframe,
*max_preamble_energy,*max_preamble_delay,
*max_preamble,br_flag,ce_level,levdB,lev);
}
......@@ -707,6 +706,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
void rx_prach(PHY_VARS_eNB *eNB,
L1_rxtx_proc_t *proc,
RU_t *ru,
uint16_t *max_preamble,
uint16_t *max_preamble_energy,
......@@ -719,21 +719,21 @@ void rx_prach(PHY_VARS_eNB *eNB,
int prach_mask=0;
if (br_flag == 0) {
rx_prach0(eNB,ru,max_preamble,max_preamble_energy,max_preamble_delay,avg_preamble_energy,Nf,tdd_mapindex,0,0);
rx_prach0(eNB,proc, ru,max_preamble,max_preamble_energy,max_preamble_delay,avg_preamble_energy,Nf,tdd_mapindex,0,0);
} else { // This is procedure for eMTC, basically handling the repetitions
prach_mask = is_prach_subframe(&eNB->frame_parms,eNB->proc.frame_prach_br,eNB->proc.subframe_prach_br);
prach_mask = is_prach_subframe(&eNB->frame_parms,proc->frame_prach_br,proc->subframe_prach_br);
for (i=0; i<4; i++) {
if ((eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[i]==1) &&
((prach_mask&(1<<(i+1))) > 0)) { // check that prach CE level is active now
// if first reception in group of repetitions store frame for later (in RA-RNTI for Msg2)
if (eNB->prach_vars_br.repetition_number[i]==0) eNB->prach_vars_br.first_frame[i]=eNB->proc.frame_prach_br;
if (eNB->prach_vars_br.repetition_number[i]==0) eNB->prach_vars_br.first_frame[i]=proc->frame_prach_br;
// increment repetition number
eNB->prach_vars_br.repetition_number[i]++;
// do basic PRACH reception
rx_prach0(eNB,ru,max_preamble,max_preamble_energy,max_preamble_delay,avg_preamble_energy,Nf,tdd_mapindex,1,i);
rx_prach0(eNB,proc, ru,max_preamble,max_preamble_energy,max_preamble_delay,avg_preamble_energy,Nf,tdd_mapindex,1,i);
// if last repetition, clear counter
if (eNB->prach_vars_br.repetition_number[i] == eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[i]) {
......
......@@ -573,7 +573,9 @@ uint32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB,
@returns 0 on success
*/
void rx_prach(PHY_VARS_eNB *phy_vars_eNB,RU_t *ru,
void rx_prach(PHY_VARS_eNB *phy_vars_eNB,
L1_rxtx_proc_t *proc,
RU_t *ru,
uint16_t *max_preamble,
uint16_t *max_preamble_energy,
uint16_t *max_preamble_delay,
......
......@@ -211,324 +211,7 @@ uint8_t extract_cqi_crc(uint8_t *cqi,uint8_t CQI_LENGTH) {
return(crc);
}
int ulsch_decoding_data_2thread0(td_params *tdp) {
PHY_VARS_eNB *eNB = tdp->eNB;
int UE_id = tdp->UE_id;
int harq_pid = tdp->harq_pid;
int llr8_flag = tdp->llr8_flag;
unsigned int r,r_offset=0,Kr,Kr_bytes;
uint8_t crc_type;
int offset = 0;
int ret = 1;
int16_t dummy_w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id];
LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
int Q_m = ulsch_harq->Qm;
int G = ulsch_harq->G;
uint32_t E=0;
uint32_t Gp,GpmodC,Nl=1;
uint32_t C = ulsch_harq->C;
decoder_if_t *tc;
if (llr8_flag == 0)
tc = decoder16;
else
tc = decoder8;
// go through first half of segments to get r_offset
for (r=0; r<(ulsch_harq->C/2); r++) {
// Get Turbo interleaver parameters
if (r<ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
Kr_bytes = Kr>>3;
// This is stolen from rate-matching algorithm to get the value of E
Gp = G/Nl/Q_m;
GpmodC = Gp%C;
if (r < (C-(GpmodC)))
E = Nl*Q_m * (Gp/C);
else
E = Nl*Q_m * ((GpmodC==0?0:1) + (Gp/C));
r_offset += E;
if (r==0) {
offset = Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0);
} else {
offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0));
}
}
// go through second half of segments
for (; r<(ulsch_harq->C); r++) {
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
// Get Turbo interleaver parameters
if (r<ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
Kr_bytes = Kr>>3;
memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short));
ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8),
(uint8_t *)&dummy_w[r][0],
(r==0) ? ulsch_harq->F : 0);
if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r],
G,
ulsch_harq->w[r],
(uint8_t *) &dummy_w[r][0],
ulsch_harq->e+r_offset,
ulsch_harq->C,
NSOFT,
0, //Uplink
1,
ulsch_harq->rvidx,
(ulsch_harq->round==0)?1:0, // clear
ulsch_harq->Qm,
1,
r,
&E)==-1) {
LOG_E(PHY,"ulsch_decoding.c: Problem in rate matching\n");
return(-1);
}
r_offset += E;
sub_block_deinterleaving_turbo(4+Kr,
&ulsch_harq->d[r][96],
ulsch_harq->w[r]);
if (ulsch_harq->C == 1)
crc_type = CRC24_A;
else
crc_type = CRC24_B;
ret = tc(&ulsch_harq->d[r][96],
NULL,
ulsch_harq->c[r],
NULL,
Kr,
ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS,
crc_type,
(r==0) ? ulsch_harq->F : 0,
&eNB->ulsch_tc_init_stats,
&eNB->ulsch_tc_alpha_stats,
&eNB->ulsch_tc_beta_stats,
&eNB->ulsch_tc_gamma_stats,
&eNB->ulsch_tc_ext_stats,
&eNB->ulsch_tc_intl1_stats,
&eNB->ulsch_tc_intl2_stats);
// Reassembly of Transport block here
if (ret != (1+ulsch->max_turbo_iterations)) {
if (r<ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
Kr_bytes = Kr>>3;
memcpy(ulsch_harq->b+offset,
ulsch_harq->c[r],
Kr_bytes - ((ulsch_harq->C>1)?3:0));
offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0));
} else {
break;
}
}
return(ret);
}
extern int oai_exit;
void *td_thread(void *param) {
PHY_VARS_eNB *eNB = ((td_params *)param)->eNB;
L1_proc_t *proc = &eNB->proc;
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
thread_top_init("td_thread",1,200000,250000,500000);
pthread_setname_np( pthread_self(),"td processing");
LOG_I(PHY,"thread td created id=%ld\n", syscall(__NR_gettid));
//wait_sync("td_thread");
while (!oai_exit) {
if (wait_on_condition(&proc->mutex_td,&proc->cond_td,&proc->instance_cnt_td,"td thread")<0) break;
if(oai_exit) break;
((td_params *)param)->ret = ulsch_decoding_data_2thread0((td_params *)param);
if (release_thread(&proc->mutex_td,&proc->instance_cnt_td,"td thread")<0) break;
if (pthread_cond_signal(&proc->cond_td) != 0) {
printf("[eNB] ERROR pthread_cond_signal for td thread exit\n");
exit_fun( "ERROR pthread_cond_signal" );
return(NULL);
}
}
return(NULL);
}
int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) {
L1_proc_t *proc = &eNB->proc;
unsigned int r,r_offset=0,Kr,Kr_bytes;
uint8_t crc_type;
int offset = 0;
int ret = 1;
int16_t dummy_w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id];
LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
int G = ulsch_harq->G;
unsigned int E;
int Cby2;
decoder_if_t *tc;
struct timespec wait;
wait.tv_sec=0;
wait.tv_nsec=5000000L;
if (llr8_flag == 0)
tc = decoder16;
else
tc = decoder8;
if (ulsch_harq->C>1) { // wakeup worker if more than 1 segment
if (pthread_mutex_timedlock(&proc->mutex_td,&wait) != 0) {
printf("[eNB] ERROR pthread_mutex_lock for TD thread (IC %d)\n", proc->instance_cnt_td);
exit_fun( "error locking mutex_fep" );
return -1;
}
if (proc->instance_cnt_td==0) {
printf("[eNB] TD thread busy\n");
exit_fun("TD thread busy");
pthread_mutex_unlock( &proc->mutex_td );
return -1;
}
++proc->instance_cnt_td;
proc->tdp.eNB = eNB;
proc->tdp.UE_id = UE_id;
proc->tdp.harq_pid = harq_pid;
proc->tdp.llr8_flag = llr8_flag;
// wakeup worker to do second half segments
if (pthread_cond_signal(&proc->cond_td) != 0) {
printf("[eNB] ERROR pthread_cond_signal for td thread exit\n");
exit_fun( "ERROR pthread_cond_signal" );
return (1+ulsch->max_turbo_iterations);
}
pthread_mutex_unlock( &proc->mutex_td );
Cby2 = ulsch_harq->C/2;
} else {
Cby2 = 1;
}
// go through first half of segments in main thread
for (r=0; r<Cby2; r++) {
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
// Get Turbo interleaver parameters
if (r<ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
Kr_bytes = Kr>>3;
memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short));
ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8),
(uint8_t *)&dummy_w[r][0],
(r==0) ? ulsch_harq->F : 0);
start_meas(&eNB->ulsch_rate_unmatching_stats);
if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r],
G,
ulsch_harq->w[r],
(uint8_t *) &dummy_w[r][0],
ulsch_harq->e+r_offset,
ulsch_harq->C,
NSOFT,
0, //Uplink
1,
ulsch_harq->rvidx,
(ulsch_harq->round==0)?1:0, // clear
ulsch_harq->Qm,
1,
r,
&E)==-1) {
LOG_E(PHY,"ulsch_decoding.c: Problem in rate matching\n");
return(-1);
}
stop_meas(&eNB->ulsch_rate_unmatching_stats);
r_offset += E;
start_meas(&eNB->ulsch_deinterleaving_stats);
sub_block_deinterleaving_turbo(4+Kr,
&ulsch_harq->d[r][96],
ulsch_harq->w[r]);
stop_meas(&eNB->ulsch_deinterleaving_stats);
if (ulsch_harq->C == 1)
crc_type = CRC24_A;
else
crc_type = CRC24_B;
start_meas(&eNB->ulsch_turbo_decoding_stats);
ret = tc(&ulsch_harq->d[r][96],
NULL,
ulsch_harq->c[r],
NULL,
Kr,
ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS,
crc_type,
(r==0) ? ulsch_harq->F : 0,
&eNB->ulsch_tc_init_stats,
&eNB->ulsch_tc_alpha_stats,
&eNB->ulsch_tc_beta_stats,
&eNB->ulsch_tc_gamma_stats,
&eNB->ulsch_tc_ext_stats,
&eNB->ulsch_tc_intl1_stats,
&eNB->ulsch_tc_intl2_stats);
// Reassembly of Transport block here
if (ret != (1+ulsch->max_turbo_iterations)) {
if (r<ulsch_harq->Cminus)
Kr = ulsch_harq->Kminus;
else
Kr = ulsch_harq->Kplus;
Kr_bytes = Kr>>3;
if (r==0) {
memcpy(ulsch_harq->b,
&ulsch_harq->c[0][(ulsch_harq->F>>3)],
Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0));
offset = Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0);
} else {
memcpy(ulsch_harq->b+offset,
ulsch_harq->c[r],
Kr_bytes - ((ulsch_harq->C>1)?3:0));
offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0));
}
} else {
break;
}
stop_meas(&eNB->ulsch_turbo_decoding_stats);
//printf("/////////////////////////////////////////**************************loop for %d time in ulsch_decoding main\n",r);
}
// wait for worker to finish
wait_on_busy_condition(&proc->mutex_td,&proc->cond_td,&proc->instance_cnt_td,"td thread");
return( (ret>proc->tdp.ret) ? ret : proc->tdp.ret );
}
int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) {
unsigned int r,r_offset=0,Kr,Kr_bytes;
......
......@@ -71,219 +71,7 @@
#include <pthread.h>
#include "openair2/PHY_INTERFACE/IF_Module.h"
typedef struct RU_proc_t_s {
/// Pointer to associated RU descriptor
struct RU_t_s *ru;
/// timestamp received from HW
openair0_timestamp timestamp_rx;
/// timestamp to send to "slave rru"
openair0_timestamp timestamp_tx;
/// subframe to act upon for reception
int subframe_rx;
/// subframe to act upon for transmission
int subframe_tx;
/// subframe to act upon for reception of prach
int subframe_prach;
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
/// subframe to act upon for reception of prach BL/CE UEs
int subframe_prach_br;
#endif
/// frame to act upon for reception
int frame_rx;
/// frame to act upon for transmission
int frame_tx;
/// unwrapped frame count
int frame_tx_unwrap;
/// frame to act upon for reception of prach
int frame_prach;
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
/// frame to act upon for reception of prach
int frame_prach_br;
#endif
/// frame offset for slave RUs (to correct for frame asynchronism at startup)
int frame_offset;
/// \brief Instance count for FH processing thread.
/// \internal This variable is protected by \ref mutex_FH.
int instance_cnt_FH;
int instance_cnt_FH1;
/// \internal This variable is protected by \ref mutex_prach.
int instance_cnt_prach;
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
/// \internal This variable is protected by \ref mutex_prach.
int instance_cnt_prach_br;
#endif
/// \internal This variable is protected by \ref mutex_synch.
int instance_cnt_synch;
/// \internal This variable is protected by \ref mutex_eNBs.
int instance_cnt_eNBs;
/// \brief Instance count for rx processing thread.
/// \internal This variable is protected by \ref mutex_asynch_rxtx.
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_feptx
int instance_cnt_feptx;
/// \internal This variable is protected by \ref mutex_ru_thread
int instance_cnt_ru;
/// pthread structure for RU FH processing thread
pthread_t pthread_FH;
/// pthread structure for RU control thread
pthread_t pthread_ctrl;
/// This varible is protected by \ref mutex_emulatedRF
int instance_cnt_emulateRF;
/// pthread structure for RU FH processing thread
pthread_t pthread_FH1;
/// pthread structure for RU prach processing thread
pthread_t pthread_prach;
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
/// pthread structure for RU prach processing thread BL/CE UEs
pthread_t pthread_prach_br;
#endif
/// pthread struct for RU synch thread
pthread_t pthread_synch;
/// pthread struct for RU RX FEP worker thread
pthread_t pthread_fep;
/// pthread struct for RU TX FEP worker thread
pthread_t pthread_feptx;
/// pthread struct for emulated RF
pthread_t pthread_emulateRF;
/// pthread structure for asychronous RX/TX processing thread
pthread_t pthread_asynch_rxtx;
/// flag to indicate first RX acquisition
int first_rx;
/// flag to indicate first TX transmission
int first_tx;
/// pthread attributes for RU FH processing thread
pthread_attr_t attr_FH;
/// pthread attributes for RU control thread
pthread_attr_t attr_ctrl;
pthread_attr_t attr_FH1;
/// pthread attributes for RU prach
pthread_attr_t attr_prach;
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
/// pthread attributes for RU prach BL/CE UEs
pthread_attr_t attr_prach_br;
#endif
/// pthread attributes for RU synch thread
pthread_attr_t attr_synch;
/// pthread attributes for asynchronous RX thread
pthread_attr_t attr_asynch_rxtx;
/// pthread attributes for worker fep thread
pthread_attr_t attr_fep;
/// pthread attributes for worker feptx thread
pthread_attr_t attr_feptx;
/// pthread attributes for emulated RF
pthread_attr_t attr_emulateRF;
/// scheduling parameters for RU FH thread
struct sched_param sched_param_FH;
struct sched_param sched_param_FH1;
/// scheduling parameters for RU prach thread
struct sched_param sched_param_prach;
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
/// scheduling parameters for RU prach thread BL/CE UEs
struct sched_param sched_param_prach_br;
#endif
/// scheduling parameters for RU synch thread
struct sched_param sched_param_synch;
/// scheduling parameters for asynch_rxtx thread
struct sched_param sched_param_asynch_rxtx;
/// condition variable for RU FH thread
pthread_cond_t cond_FH;
pthread_cond_t cond_FH1;
/// condition variable for RU prach thread
pthread_cond_t cond_prach;
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
/// condition variable for RU prach thread BL/CE UEs
pthread_cond_t cond_prach_br;
#endif
/// condition variable for RU synch thread
pthread_cond_t cond_synch;
/// condition variable for asynch RX/TX thread
pthread_cond_t cond_asynch_rxtx;
/// condition variable for RU RX FEP thread
pthread_cond_t cond_fep;
/// condition variable for RU TX FEP thread
pthread_cond_t cond_feptx;
/// condition variable for emulated RF
pthread_cond_t cond_emulateRF;
/// condition variable for eNB signal
pthread_cond_t cond_eNBs;
/// condition variable for ru_thread
pthread_cond_t cond_ru_thread;
/// mutex for RU FH
pthread_mutex_t mutex_FH;
pthread_mutex_t mutex_FH1;
/// mutex for RU prach
pthread_mutex_t mutex_prach;
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
/// mutex for RU prach BL/CE UEs
pthread_mutex_t mutex_prach_br;
#endif
/// mutex for RU synch
pthread_mutex_t mutex_synch;
/// mutex for eNB signal
pthread_mutex_t mutex_eNBs;
/// mutex for asynch RX/TX thread
pthread_mutex_t mutex_asynch_rxtx;
/// mutex for fep RX worker thread
pthread_mutex_t mutex_fep;
/// mutex for fep TX worker thread
pthread_mutex_t mutex_feptx;
/// mutex for ru_thread
pthread_mutex_t mutex_ru;
/// mutex for emulated RF thread
pthread_mutex_t mutex_emulateRF;
/// symbol mask for IF4p5 reception per subframe
uint32_t symbol_mask[10];
/// time measurements for each subframe
struct timespec t[10];
/// number of slave threads
int num_slaves;
/// array of pointers to slaves
struct RU_proc_t_s **slave_proc;
#ifdef PHY_TX_THREAD
/// pthread structure for PRACH thread
pthread_t pthread_phy_tx;
pthread_mutex_t mutex_phy_tx;
pthread_cond_t cond_phy_tx;
/// \internal This variable is protected by \ref mutex_phy_tx.
int instance_cnt_phy_tx;
/// frame to act upon for transmission
int frame_phy_tx;
/// subframe to act upon for transmission
int subframe_phy_tx;
/// timestamp to send to "slave rru"
openair0_timestamp timestamp_phy_tx;
/// pthread structure for RF TX thread
pthread_t pthread_rf_tx;
pthread_mutex_t mutex_rf_tx;
pthread_cond_t cond_rf_tx;
/// \internal This variable is protected by \ref mutex_rf_tx.
int instance_cnt_rf_tx;
#endif
#if defined(PRE_SCD_THREAD)
pthread_t pthread_pre_scd;
/// condition variable for time processing thread
pthread_cond_t cond_pre_scd;
/// mutex for time thread
pthread_mutex_t mutex_pre_scd;
int instance_pre_scd;
#endif
int emulate_rf_busy;
} RU_proc_t;
typedef enum {
LOCAL_RF =0,
......@@ -312,6 +100,7 @@ typedef enum {
WAIT_RESYNCH = 3
} rru_cmd_t;
#include "openair2/PHY_INTERFACE/IF_Module.h"
typedef struct RU_t_s{
/// index of this ru
uint32_t idx;
......@@ -396,7 +185,7 @@ typedef struct RU_t_s{
/// function pointer to synchronous RX fronthaul function (RRU,3GPP_eNB)
void (*fh_south_in)(struct RU_t_s *ru,int *frame, int *subframe);
/// function pointer to synchronous TX fronthaul function
void (*fh_south_out)(struct RU_t_s *ru);
void (*fh_south_out)(struct RU_t_s *ru, L1_rxtx_proc_t * proc);
/// function pointer to synchronous RX fronthaul function (RRU)
void (*fh_north_in)(struct RU_t_s *ru,int *frame, int *subframe);
/// function pointer to synchronous RX fronthaul function (RRU)
......@@ -412,11 +201,11 @@ typedef struct RU_t_s{
/// function pointer to initialization function for radio interface
int (*start_if)(struct RU_t_s *ru,struct PHY_VARS_eNB_s *eNB);
/// function pointer to RX front-end processing routine (DFTs/prefix removal or NULL)
void (*feprx)(struct RU_t_s *ru);
void (*feprx)(struct RU_t_s *ru, L1_rxtx_proc_t * proc);
/// function pointer to TX front-end processing routine (IDFTs and prefix removal or NULL)
void (*feptx_ofdm)(struct RU_t_s *ru);
void (*feptx_ofdm)(struct RU_t_s *ru, L1_rxtx_proc_t * proc);
/// function pointer to TX front-end processing routine (PRECODING)
void (*feptx_prec)(struct RU_t_s *ru);
void (*feptx_prec)(struct RU_t_s *ru, L1_rxtx_proc_t * proc);
/// function pointer to wakeup routine in lte-enb.
int (*wakeup_rxtx)(struct PHY_VARS_eNB_s *eNB, struct RU_t_s *ru);
/// function pointer to wakeup routine in lte-enb.
......@@ -426,7 +215,7 @@ typedef struct RU_t_s{
void (*wakeup_prach_eNB_br)(struct PHY_VARS_eNB_s *eNB,struct RU_t_s *ru,int frame,int subframe);
#endif
/// function pointer to eNB entry routine
void (*eNB_top)(struct PHY_VARS_eNB_s *eNB, int frame_rx, int subframe_rx, char *string, struct RU_t_s *ru);
void (*eNB_top)(struct PHY_VARS_eNB_s *eNB, L1_rxtx_proc_t * proc, int frame_rx, int subframe_rx, char *string, struct RU_t_s *ru);
/// Timing statistics
time_stats_t ofdm_demod_stats;
/// Timing statistics (TX)
......@@ -468,7 +257,7 @@ typedef struct RU_t_s{
/// value to be passed using command
uint16_t cmdval;
/// process scheduling variables
RU_proc_t proc;
//RU_proc_t proc;
/// stats thread pthread descriptor
pthread_t ru_stats_thread;
/// OTA synchronization signal
......@@ -728,41 +517,6 @@ typedef struct {
#include "PHY/TOOLS/tools_defs.h"
#include "PHY/LTE_TRANSPORT/transport_eNB.h"
/// Context data structure for RX/TX portion of subframe processing
typedef struct {
/// Component Carrier index
uint8_t CC_id;
/// timestamp transmitted to HW
openair0_timestamp timestamp_tx;
/// subframe to act upon for transmission
int subframe_tx;
/// subframe to act upon for reception
int subframe_rx;
/// frame to act upon for transmission
int frame_tx;
/// frame to act upon for reception
int frame_rx;
/// \brief Instance count for RXn-TXnp4 processing thread.
/// \internal This variable is protected by \ref mutex_rxtx.
int instance_cnt;
/// pthread structure for RXn-TXnp4 processing thread
pthread_t pthread;
/// pthread attributes for RXn-TXnp4 processing thread
pthread_attr_t attr;
/// condition variable for tx processing thread
pthread_cond_t cond;
/// mutex for RXn-TXnp4 processing thread
pthread_mutex_t mutex;
/// scheduling parameters for RXn-TXnp4 thread
struct sched_param sched_param_rxtx;
/// \internal This variable is protected by \ref mutex_RUs.
int instance_cnt_RUs;
/// condition variable for tx processing thread
pthread_cond_t cond_RUs;
/// mutex for RXn-TXnp4 processing thread
pthread_mutex_t mutex_RUs;
} L1_rxtx_proc_t;
typedef struct {
struct PHY_VARS_eNB_s *eNB;
......@@ -793,159 +547,6 @@ typedef struct {
pthread_mutex_t mutex_te;
} te_params;
/// Context data structure for eNB subframe processing
typedef struct L1_proc_t_s {
/// Component Carrier index
uint8_t CC_id;
/// thread index
int thread_index;
/// timestamp received from HW
openair0_timestamp timestamp_rx;
/// timestamp to send to "slave rru"
openair0_timestamp timestamp_tx;
/// subframe to act upon for reception
int subframe_rx;
/// subframe to act upon for PRACH
int subframe_prach;
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
/// subframe to act upon for reception of prach BL/CE UEs
int subframe_prach_br;
#endif
/// frame to act upon for reception
int frame_rx;
/// frame to act upon for transmission
int frame_tx;
/// frame to act upon for PRACH
int frame_prach;
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
/// frame to act upon for PRACH BL/CE UEs
int frame_prach_br;
#endif
/// \internal This variable is protected by \ref mutex_td.
int instance_cnt_td;
/// \internal This variable is protected by \ref mutex_te.
int instance_cnt_te;
/// \internal This variable is protected by \ref mutex_prach.
int instance_cnt_prach;
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
/// \internal This variable is protected by \ref mutex_prach for BL/CE UEs.
int instance_cnt_prach_br;
#endif
// instance count for over-the-air eNB synchronization
int instance_cnt_synch;
/// \internal This variable is protected by \ref mutex_asynch_rxtx.
int instance_cnt_asynch_rxtx;
/// pthread structure for asychronous RX/TX processing thread
pthread_t pthread_asynch_rxtx;
/// flag to indicate first RX acquisition
int first_rx;
/// flag to indicate first TX transmission
int first_tx;
/// pthread attributes for parallel turbo-decoder thread
pthread_attr_t attr_td;
/// pthread attributes for parallel turbo-encoder thread
pthread_attr_t attr_te;
/// pthread attributes for single eNB processing thread
pthread_attr_t attr_single;
/// pthread attributes for prach processing thread
pthread_attr_t attr_prach;
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
/// pthread attributes for prach processing thread BL/CE UEs
pthread_attr_t attr_prach_br;
#endif
/// pthread attributes for asynchronous RX thread
pthread_attr_t attr_asynch_rxtx;
/// scheduling parameters for parallel turbo-decoder thread
struct sched_param sched_param_td;
/// scheduling parameters for parallel turbo-encoder thread
struct sched_param sched_param_te;
/// scheduling parameters for single eNB thread
struct sched_param sched_param_single;
/// scheduling parameters for prach thread
struct sched_param sched_param_prach;
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
/// scheduling parameters for prach thread
struct sched_param sched_param_prach_br;
#endif
/// scheduling parameters for asynch_rxtx thread
struct sched_param sched_param_asynch_rxtx;
/// pthread structure for parallel turbo-decoder thread
pthread_t pthread_td;
/// pthread structure for parallel turbo-encoder thread
pthread_t pthread_te;
/// pthread structure for PRACH thread
pthread_t pthread_prach;
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
/// pthread structure for PRACH thread BL/CE UEs
pthread_t pthread_prach_br;
#endif
/// condition variable for parallel turbo-decoder thread
pthread_cond_t cond_td;
/// condition variable for parallel turbo-encoder thread
pthread_cond_t cond_te;
/// condition variable for PRACH processing thread;
pthread_cond_t cond_prach;
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
/// condition variable for PRACH processing thread BL/CE UEs;
pthread_cond_t cond_prach_br;
#endif
/// condition variable for asynch RX/TX thread
pthread_cond_t cond_asynch_rxtx;
/// mutex for parallel turbo-decoder thread
pthread_mutex_t mutex_td;
/// mutex for parallel turbo-encoder thread
pthread_mutex_t mutex_te;
/// mutex for PRACH thread
pthread_mutex_t mutex_prach;
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
/// mutex for PRACH thread for BL/CE UEs
pthread_mutex_t mutex_prach_br;
#endif
/// mutex for asynch RX/TX thread
pthread_mutex_t mutex_asynch_rxtx;
/// mutex for RU access to eNB processing (PDSCH/PUSCH)
pthread_mutex_t mutex_RU;
/// mutex for eNB processing to access RU TX (PDSCH/PUSCH)
pthread_mutex_t mutex_RU_tx;
/// mutex for RU access to eNB processing (PRACH)
pthread_mutex_t mutex_RU_PRACH;
/// mutex for RU access to eNB processing (PRACH BR)
pthread_mutex_t mutex_RU_PRACH_br;
/// mask for RUs serving eNB (PDSCH/PUSCH)
int RU_mask[10];
/// mask for RUs serving eNB (PDSCH/PUSCH)
int RU_mask_tx;
/// time measurements for RU arrivals
struct timespec t[10];
/// Timing statistics (RU_arrivals)
time_stats_t ru_arrival_time;
/// mask for RUs serving eNB (PRACH)
int RU_mask_prach;
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
/// mask for RUs serving eNB (PRACH)
int RU_mask_prach_br;
#endif
/// parameters for turbo-decoding worker thread
td_params tdp;
/// parameters for turbo-encoding worker thread
te_params tep[3];
/// set of scheduling variables RXn-TXnp4 threads
L1_rxtx_proc_t L1_proc,L1_proc_tx;
/// stats thread pthread descriptor
pthread_t process_stats_thread;
/// for waking up tx procedure
RU_proc_t *ru_proc;
} L1_proc_t;
typedef struct {
//unsigned int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (linear)
//unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (dB)
......@@ -1007,7 +608,7 @@ typedef struct PHY_VARS_eNB_s {
module_id_t Mod_id;
uint8_t CC_id;
uint8_t configured;
L1_proc_t proc;
//L1_proc_t proc;
int single_thread_flag;
int abstraction_flag;
int num_RU;
......@@ -1257,5 +858,6 @@ typedef struct PHY_VARS_eNB_s {
} PHY_VARS_eNB;
#endif /* __PHY_DEFS_ENB__H__ */
......@@ -730,9 +730,8 @@ void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,
}
}
void schedule_response(Sched_Rsp_t *Sched_INFO) {
void schedule_response(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc) {
PHY_VARS_eNB *eNB;
L1_rxtx_proc_t *proc;
// copy data from L2 interface into L1 structures
module_id_t Mod_id = Sched_INFO->module_id;
uint8_t CC_id = Sched_INFO->CC_id;
......@@ -752,7 +751,6 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
AssertFatal(RC.eNB[Mod_id][CC_id]!=NULL,"RC.eNB[%d][%d] is null\n",Mod_id,CC_id);
eNB = RC.eNB[Mod_id][CC_id];
fp = &eNB->frame_parms;
proc = &eNB->proc.L1_proc;
/* TODO: check that following line is correct - in the meantime it is disabled */
//if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)==SF_UL)) return;
ul_subframe = pdcch_alloc2ul_subframe(fp,subframe);
......
......@@ -76,4 +76,4 @@ void handle_uci_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu
void handle_srs_pdu(PHY_VARS_eNB *eNB,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe);
void schedule_response(Sched_Rsp_t *Sched_INFO);
void schedule_response(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc);
......@@ -1360,51 +1360,8 @@ extern int oai_exit;
extern void *td_thread (void *);
void init_td_thread(PHY_VARS_eNB *eNB) {
L1_proc_t *proc = &eNB->proc;
proc->tdp.eNB = eNB;
proc->instance_cnt_td = -1;
pthread_attr_init( &proc->attr_td);
pthread_mutex_init( &proc->mutex_td, NULL);
pthread_cond_init( &proc->cond_td, NULL);
pthread_create(&proc->pthread_td, &proc->attr_td, td_thread, (void *)&proc->tdp);
}
void kill_td_thread(PHY_VARS_eNB *eNB) {
L1_proc_t *proc = &eNB->proc;
proc->instance_cnt_td = 0;
pthread_cond_signal(&proc->cond_td);
pthread_join(proc->pthread_td, NULL);
pthread_mutex_destroy( &proc->mutex_td );
pthread_cond_destroy( &proc->cond_td );
}
extern void *te_thread (void *);
void init_te_thread(PHY_VARS_eNB *eNB) {
L1_proc_t *proc = &eNB->proc;
for(int i=0; i<3 ; i++) {
proc->tep[i].eNB = eNB;
proc->tep[i].instance_cnt_te = -1;
pthread_mutex_init( &proc->tep[i].mutex_te, NULL);
pthread_cond_init( &proc->tep[i].cond_te, NULL);
pthread_attr_init( &proc->tep[i].attr_te);
LOG_I(PHY,"Creating te_thread %d\n",i);
pthread_create(&proc->tep[i].pthread_te, &proc->tep[i].attr_te, te_thread, (void *)&proc->tep[i]);
}
}
void kill_te_thread(PHY_VARS_eNB *eNB) {
L1_proc_t *proc = &eNB->proc;
for(int i=0; i<3 ; i++) {
proc->tep[i].instance_cnt_te = 0;
pthread_cond_signal(&proc->tep[i].cond_te);
pthread_join(proc->tep[i].pthread_te, NULL);
pthread_mutex_destroy( &proc->tep[i].mutex_te);
pthread_cond_destroy( &proc->tep[i].cond_te);
}
}
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;
......
......@@ -53,7 +53,8 @@
extern int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind);
void prach_procedures(PHY_VARS_eNB *eNB
void prach_procedures(PHY_VARS_eNB *eNB,
L1_rxtx_proc_t *proc
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
,
int br_flag
......@@ -65,8 +66,8 @@ void prach_procedures(PHY_VARS_eNB *eNB
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
if (br_flag==1) {
subframe = eNB->proc.subframe_prach_br;
frame = eNB->proc.frame_prach_br;
subframe = proc->subframe_prach_br;
frame = proc->frame_prach_br;
pthread_mutex_lock(&eNB->UL_INFO_mutex);
eNB->UL_INFO.rach_ind_br.rach_indication_body.number_of_preambles=0;
pthread_mutex_unlock(&eNB->UL_INFO_mutex);
......@@ -76,8 +77,8 @@ void prach_procedures(PHY_VARS_eNB *eNB
pthread_mutex_lock(&eNB->UL_INFO_mutex);
eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles=0;
pthread_mutex_unlock(&eNB->UL_INFO_mutex);
subframe = eNB->proc.subframe_prach;
frame = eNB->proc.frame_prach;
subframe = proc->subframe_prach;
frame = proc->frame_prach;
}
RU_t *ru;
......@@ -102,6 +103,7 @@ void prach_procedures(PHY_VARS_eNB *eNB
// run PRACH detection for CE-level 0 only for now when br_flag is set
rx_prach(eNB,
proc,
eNB->RU_list[0],
&max_preamble[0],
&max_preamble_energy[0],
......@@ -125,7 +127,7 @@ void prach_procedures(PHY_VARS_eNB *eNB
if (br_flag==1) {
int prach_mask;
prach_mask = is_prach_subframe (&eNB->frame_parms, eNB->proc.frame_prach_br, eNB->proc.subframe_prach_br);
prach_mask = is_prach_subframe (&eNB->frame_parms, proc->frame_prach_br, proc->subframe_prach_br);
eNB->UL_INFO.rach_ind_br.rach_indication_body.preamble_list = eNB->preamble_list_br;
int ind = 0;
int ce_level = 0;
......
......@@ -69,7 +69,7 @@ extern int oai_exit;
void feptx0(RU_t *ru,int slot) {
void feptx0(RU_t *ru, L1_rxtx_proc_t *proc, int slot) {
LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
//int dummy_tx_b[7680*2] __attribute__((aligned(32)));
......@@ -77,7 +77,7 @@ void feptx0(RU_t *ru,int slot) {
unsigned int aa,slot_offset;
int slot_sizeF = (fp->ofdm_symbol_size)*
((fp->Ncp==1) ? 6 : 7);
int subframe = ru->proc.subframe_tx;
int subframe = proc->subframe_tx;
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+slot , 1 );
......@@ -169,108 +169,7 @@ void feptx0(RU_t *ru,int slot) {
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+slot , 0);
}
static void *feptx_thread(void *param) {
RU_t *ru = (RU_t *)param;
RU_proc_t *proc = &ru->proc;
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
thread_top_init("feptx_thread",1,85000,120000,500000);
pthread_setname_np( pthread_self(),"feptx processing");
LOG_I(PHY,"thread feptx created id=%ld\n", syscall(__NR_gettid));
//CPU_SET(6, &cpuset);
//pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
//wait_sync("feptx_thread");
while (!oai_exit) {
if (wait_on_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"feptx thread")<0) break;
if (oai_exit) break;
//stop_meas(&ru->ofdm_mod_wakeup_stats);
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;
}
/*if(opp_enabled == 1 && ru->ofdm_mod_wakeup_stats.p_time>30*3000){
print_meas_now(&ru->ofdm_mod_wakeup_stats,"fep wakeup",stderr);
printf("delay in fep wakeup in frame_tx: %d subframe_rx: %d \n",proc->frame_tx,proc->subframe_tx);
}*/
}
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;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+ru->idx , 1 );
start_meas(&ru->ofdm_mod_stats);
if (subframe_select(fp,subframe) == SF_UL) return;
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 );
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;
}
//start_meas(&ru->ofdm_mod_wakeup_stats);
pthread_mutex_unlock( &proc->mutex_feptx );
}
// call first slot in this thread
feptx0(ru,0);
start_meas(&ru->ofdm_mod_wait_stats);
wait_on_busy_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"feptx thread");
stop_meas(&ru->ofdm_mod_wait_stats);
/*if(opp_enabled == 1 && ru->ofdm_mod_wait_stats.p_time>30*3000){
print_meas_now(&ru->ofdm_mod_wait_stats,"fep wakeup",stderr);
printf("delay in feptx wait on codition in frame_rx: %d subframe_rx: %d \n",proc->frame_tx,proc->subframe_tx);
}*/
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 0 );
stop_meas(&ru->ofdm_mod_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+ru->idx , 0 );
}
void feptx_ofdm(RU_t *ru) {
void feptx_ofdm(RU_t *ru, L1_rxtx_proc_t* proc) {
LTE_DL_FRAME_PARMS *fp=&ru->frame_parms;
......@@ -281,7 +180,7 @@ void feptx_ofdm(RU_t *ru) {
((fp->Ncp==1) ? 6 : 7);
int len,len2;
int16_t *txdata;
int subframe = ru->proc.subframe_tx;
int subframe = proc->subframe_tx;
// int CC_id = ru->proc.CC_id;
......@@ -402,18 +301,18 @@ void feptx_ofdm(RU_t *ru) {
// }
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)),
LOG_D(PHY,"feptx_ofdm (TXPATH): subframe %d: txp (time %p) %d dB, txp (freq) %d dB\n",
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)));
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+ru->idx , 0 );
}
void feptx_prec(RU_t *ru) {
void feptx_prec(RU_t *ru, L1_rxtx_proc_t * proc) {
int l,i,aa,p;
int subframe = ru->proc.subframe_tx;
int subframe = proc->subframe_tx;
PHY_VARS_eNB **eNB_list = ru->eNB_list,*eNB;
LTE_DL_FRAME_PARMS *fp;
......@@ -504,9 +403,8 @@ void feptx_prec(RU_t *ru) {
}
}
void fep0(RU_t *ru,int slot) {
void fep0(RU_t *ru,L1_rxtx_proc_t *proc, int slot) {
RU_proc_t *proc = &ru->proc;
LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
int l;
......@@ -524,243 +422,8 @@ void fep0(RU_t *ru,int slot) {
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+slot, 0);
}
void fep_full(RU_t *ru, L1_rxtx_proc_t *proc) {
static void *fep_thread(void *param) {
RU_t *ru = (RU_t *)param;
RU_proc_t *proc = &ru->proc;
thread_top_init("fep_thread",1,100000,120000,5000000);
pthread_setname_np( pthread_self(),"fep processing");
LOG_I(PHY,"thread fep created id=%ld\n", syscall(__NR_gettid));
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
//CPU_SET(2, &cpuset);
//pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
//wait_sync("fep_thread");
while (!oai_exit) {
if (wait_on_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"fep thread")<0) break;
if (oai_exit) break;
//stop_meas(&ru->ofdm_demod_wakeup_stats);
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX1, 1 );
fep0(ru,0);
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX1, 0 );
if (release_thread(&proc->mutex_fep,&proc->instance_cnt_fep,"fep thread")<0) break;
if (pthread_cond_signal(&proc->cond_fep) != 0) {
printf("[eNB] ERROR pthread_cond_signal for fep thread exit\n");
exit_fun( "ERROR pthread_cond_signal" );
return NULL;
}
/*if(opp_enabled == 1 && ru->ofdm_demod_wakeup_stats.p_time>30*3000){
print_meas_now(&ru->ofdm_demod_wakeup_stats,"fep wakeup",stderr);
printf("delay in fep wakeup in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx);
}*/
}
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;
proc->instance_cnt_fep = -1;
pthread_mutex_init( &proc->mutex_fep, NULL);
pthread_cond_init( &proc->cond_fep, NULL);
pthread_create(&proc->pthread_fep, attr_fep, fep_thread, (void*)ru);
}
extern void kill_fep_thread(RU_t *ru)
{
RU_proc_t *proc = &ru->proc;
pthread_mutex_lock( &proc->mutex_fep );
proc->instance_cnt_fep = 0;
pthread_cond_signal(&proc->cond_fep);
pthread_mutex_unlock( &proc->mutex_fep );
LOG_D(PHY, "Joining pthread_fep\n");
pthread_join(proc->pthread_fep, NULL);
pthread_mutex_destroy( &proc->mutex_fep );
pthread_cond_destroy( &proc->cond_fep );
}
extern void kill_feptx_thread(RU_t *ru)
{
RU_proc_t *proc = &ru->proc;
pthread_mutex_lock( &proc->mutex_feptx );
proc->instance_cnt_feptx = 0;
pthread_cond_signal(&proc->cond_feptx);
pthread_mutex_unlock( &proc->mutex_feptx );
LOG_D(PHY, "Joining pthread_feptx\n");
pthread_join(proc->pthread_feptx, NULL);
pthread_mutex_destroy( &proc->mutex_feptx );
pthread_cond_destroy( &proc->cond_feptx );
}
void ru_fep_full_2thread(RU_t *ru) {
RU_proc_t *proc = &ru->proc;
//PHY_VARS_eNB *eNB = RC.eNB[0][0];
LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
RU_CALIBRATION *calibration = &ru->calibration;
RRU_CONFIG_msg_t rru_config_msg;
int check_sync_pos;
struct timespec wait;
if (proc->subframe_rx==1){
//LOG_I(PHY,"subframe type %d, RU %d\n",subframe_select(fp,proc->subframe_rx),ru->idx);
}
else if ((fp->frame_type == TDD) && (subframe_select(fp,proc->subframe_rx) != SF_UL)) {
return;
}
//if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 );
wait.tv_sec=0;
wait.tv_nsec=5000000L;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+ru->idx, 1 );
start_meas(&ru->ofdm_demod_stats);
if (pthread_mutex_timedlock(&proc->mutex_fep,&wait) != 0) {
printf("[RU] ERROR pthread_mutex_lock for fep thread (IC %d)\n", proc->instance_cnt_fep);
exit_fun( "error locking mutex_fep" );
return;
}
if (proc->instance_cnt_fep==0) {
printf("[RU] FEP thread busy\n");
exit_fun("FEP thread busy");
pthread_mutex_unlock( &proc->mutex_fep );
return;
}
++proc->instance_cnt_fep;
if (pthread_cond_signal(&proc->cond_fep) != 0) {
printf("[RU] ERROR pthread_cond_signal for fep thread\n");
exit_fun( "ERROR pthread_cond_signal" );
return;
}
//start_meas(&ru->ofdm_demod_wakeup_stats);
pthread_mutex_unlock( &proc->mutex_fep );
// call second slot in this symbol
fep0(ru,1);
start_meas(&ru->ofdm_demod_wait_stats);
wait_on_busy_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"fep thread");
stop_meas(&ru->ofdm_demod_wait_stats);
if(opp_enabled == 1 && ru->ofdm_demod_wakeup_stats.p_time>30*3000){
print_meas_now(&ru->ofdm_demod_wakeup_stats,"fep wakeup",stderr);
printf("delay in fep wait on condition in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx);
}
if (proc->subframe_rx==1 && ru->is_slave==1/* && ru->state == RU_CHECK_SYNC*/) {
//LOG_I(PHY,"Running check synchronization procedure for frame %d\n", proc->frame_rx);
ulsch_extract_rbs_single(ru->common.rxdataF,
calibration->rxdataF_ext,
0,
fp->N_RB_DL,
3%(fp->symbols_per_tti/2),// l = symbol within slot
3/(fp->symbols_per_tti/2),// Ns = slot number
fp);
/*lte_ul_channel_estimation((PHY_VARS_eNB *)NULL,
proc,
ru->idx,
3%(fp->symbols_per_tti/2),
3/(fp->symbols_per_tti/2));
*/
lte_ul_channel_estimation_RRU(fp,
calibration->drs_ch_estimates,
calibration->drs_ch_estimates_time,
calibration->rxdataF_ext,
fp->N_RB_DL, //N_rb_alloc,
proc->frame_rx,
proc->subframe_rx,
0,//u = 0..29
0,//v = 0,1
/*eNB->ulsch[ru->idx]->cyclicShift,cyclic_shift,0..7*/0,
3,//l,
0,//interpolate,
0 /*eNB->ulsch[ru->idx]->rnti rnti or ru->ulsch[eNB_id]->rnti*/);
check_sync_pos = lte_est_timing_advance_pusch((PHY_VARS_eNB *)NULL,
ru->idx);
if (ru->state == RU_CHECK_SYNC) {
if ((check_sync_pos >= 0 && check_sync_pos<8) || (check_sync_pos < 0 && check_sync_pos>-8)) {
LOG_I(PHY,"~~~~~~~~~~~ check_sync_pos %d, frame %d, cnt %d\n",check_sync_pos,proc->frame_rx,ru->wait_check);
ru->wait_check++;
}
if (ru->wait_check==20) {
ru->state = RU_RUN;
ru->wait_check = 0;
// Send RRU_sync_ok
rru_config_msg.type = RRU_sync_ok;
rru_config_msg.len = sizeof(RRU_CONFIG_msg_t); // TODO: set to correct msg len
LOG_I(PHY,"Sending RRU_sync_ok to RAU\n");
AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1),"Failed to send msg to RAU %d\n",ru->idx);
//LOG_I(PHY,"~~~~~~~~~ RU_RUN\n");
/*LOG_M("dmrs_time.m","dmrstime",calibration->drs_ch_estimates_time[0], (fp->ofdm_symbol_size),1,1);
LOG_M("rxdataF_ext.m","rxdataFext",&calibration->rxdataF_ext[0][36*fp->N_RB_DL], 12*(fp->N_RB_DL),1,1);
LOG_M("drs_seq0.m","drsseq0",ul_ref_sigs_rx[0][0][23],600,1,1);
LOG_M("rxdata.m","rxdata",&ru->common.rxdata[0][0], fp->samples_per_tti*2,1,1);
exit(-1);*/
}
}
else if (ru->state == RU_RUN) {
// check for synchronization error
if (check_sync_pos >= 8 || check_sync_pos<=-8) {
LOG_E(PHY,"~~~~~~~~~~~~~~ check_sync_pos %d, frame %d ---> LOST SYNC-EXIT\n", check_sync_pos, proc->frame_rx);
LOG_M("rxdata.m","rxdata",&ru->common.rxdata[0][0], fp->samples_per_tti*2,1,1);
exit(-1);
}
}
else {
AssertFatal(1==0,"Should not get here\n");
}
}
stop_meas(&ru->ofdm_demod_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+ru->idx, 0 );
}
void fep_full(RU_t *ru) {
RU_proc_t *proc = &ru->proc;
int l;
LTE_DL_FRAME_PARMS *fp=&ru->frame_parms;
......@@ -791,43 +454,3 @@ void fep_full(RU_t *ru) {
}
void do_prach_ru(RU_t *ru) {
RU_proc_t *proc = &ru->proc;
LTE_DL_FRAME_PARMS *fp=&ru->frame_parms;
// check if we have to detect PRACH first
if (is_prach_subframe(fp,proc->frame_prach,proc->subframe_prach)>0) {
//accept some delay in processing - up to 5ms
int i;
for (i = 0; i < 10 && proc->instance_cnt_prach == 0; i++) {
LOG_W(PHY,"Frame %d Subframe %d, PRACH thread busy (IC %d)!!\n", proc->frame_prach,proc->subframe_prach,
proc->instance_cnt_prach);
usleep(500);
}
if (proc->instance_cnt_prach == 0) {
exit_fun( "PRACH thread busy" );
return;
}
// wake up thread for PRACH RX
if (pthread_mutex_lock(&proc->mutex_prach) != 0) {
LOG_E( PHY, "ERROR pthread_mutex_lock for PRACH thread (IC %d)\n", proc->instance_cnt_prach );
exit_fun( "error locking mutex_prach" );
return;
}
++proc->instance_cnt_prach;
// the thread can now be woken up
if (pthread_cond_signal(&proc->cond_prach) != 0) {
LOG_E( PHY, "ERROR pthread_cond_signal for PRACH thread\n");
exit_fun( "ERROR pthread_cond_signal" );
return;
}
pthread_mutex_unlock( &proc->mutex_prach );
}
}
......@@ -311,7 +311,7 @@ void get_cqipmiri_params(PHY_VARS_UE *ue,uint8_t eNB_id);
int8_t get_PHR(uint8_t Mod_id, uint8_t CC_id, uint8_t eNB_index);
void schedule_response(Sched_Rsp_t *Sched_INFO);
void schedule_response(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc);
LTE_eNB_UE_stats* get_UE_stats(uint8_t Mod_id, uint8_t CC_id,uint16_t rnti);
......
......@@ -128,7 +128,7 @@ void phy_procedures_eNB_S_RX(PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc);
@param br_flag indicator for eMTC PRACH
*/
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
void prach_procedures(PHY_VARS_eNB *eNB,
void prach_procedures(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc,
int br_flag);
#else
void prach_procedures(PHY_VARS_eNB *eNB);
......@@ -195,7 +195,7 @@ int8_t find_ue_ulsch(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB);
void schedule_response(Sched_Rsp_t *Sched_INFO);
void schedule_response(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc);
LTE_eNB_UE_stats* get_UE_stats(uint8_t Mod_id, uint8_t CC_id,uint16_t rnti);
......
......@@ -3399,7 +3399,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0));
}
LOG_D(PHY," ------ end turbo decoder for AbsSubframe %d.%d ------ \n", frame_rx, subframe_rx);
LOG_D(PHY," ------ end turbo decoder for AbsSubframe %d.%d ------ iter %d \n", frame_rx, subframe_rx,ret1);
// Check CRC for CW 0
if (ret == (1+dlsch0->max_turbo_iterations)) {
......
......@@ -693,7 +693,7 @@ static void dump_dl(Sched_Rsp_t *d) {
/* debug utility functions end */
/****************************************************************************/
void UL_indication(UL_IND_t *UL_info) {
void UL_indication(UL_IND_t *UL_info, L1_rxtx_proc_t *proc) {
AssertFatal(UL_info!=NULL,"UL_INFO is null\n");
#ifdef DUMP_FAPI
dump_ul(UL_info);
......@@ -775,7 +775,7 @@ void UL_indication(UL_IND_t *UL_info) {
"schedule_response is null (mod %d, cc %d)\n",
module_id,
CC_id);
ifi->schedule_response(sched_info);
ifi->schedule_response(sched_info, proc );
}
LOG_D(PHY,"Schedule_response: SFN_SF:%d%d dl_pdus:%d\n",sched_info->frame,sched_info->subframe,sched_info->DL_req->dl_config_request_body.number_pdu);
......
......@@ -34,6 +34,7 @@
#include <stdint.h>
#include <sched.h>
//#include "openair1/PHY/LTE_TRANSPORT/transport_eNB.h"
#include "nfapi_interface.h"
#include "platform_constants.h"
......@@ -138,11 +139,52 @@ typedef struct {
int CC_id;
nfapi_config_request_t *cfg;
}PHY_Config_t;
#include <targets/ARCH/COMMON/common_lib.h>
/// Context data structure for RX/TX portion of subframe processing
typedef struct {
/// Component Carrier index
uint8_t CC_id;
/// timestamp transmitted to HW
openair0_timestamp timestamp_tx;
openair0_timestamp timestamp_rx;
/// subframe to act upon for transmission
int subframe_tx;
/// subframe to act upon for reception
int subframe_rx;
/// frame to act upon for transmission
int frame_tx;
/// frame to act upon for reception
int frame_rx;
int frame_prach;
int subframe_prach;
int frame_prach_br;
int subframe_prach_br;
/// \brief Instance count for RXn-TXnp4 processing thread.
/// \internal This variable is protected by \ref mutex_rxtx.
int instance_cnt;
/// pthread structure for RXn-TXnp4 processing thread
pthread_t pthread;
/// pthread attributes for RXn-TXnp4 processing thread
pthread_attr_t attr;
/// condition variable for tx processing thread
pthread_cond_t cond;
/// mutex for RXn-TXnp4 processing thread
pthread_mutex_t mutex;
/// scheduling parameters for RXn-TXnp4 thread
struct sched_param sched_param_rxtx;
/// \internal This variable is protected by \ref mutex_RUs.
int instance_cnt_RUs;
/// condition variable for tx processing thread
pthread_cond_t cond_RUs;
/// mutex for RXn-TXnp4 processing thread
pthread_mutex_t mutex_RUs;
} L1_rxtx_proc_t;
typedef struct IF_Module_s{
//define the function pointer
void (*UL_indication)(UL_IND_t *UL_INFO);
void (*schedule_response)(Sched_Rsp_t *Sched_INFO);
void (*UL_indication)(UL_IND_t *UL_INFO, L1_rxtx_proc_t *proc);
void (*schedule_response)(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc);
void (*PHY_config_req)(PHY_Config_t* config_INFO);
uint32_t CC_mask;
uint16_t current_frame;
......@@ -167,7 +209,7 @@ void IF_Module_kill(int Mod_id);
/*Interface for uplink, transmitting the Preamble(list), ULSCH SDU, NAK, Tick (trigger scheduler)
*/
void UL_indication(UL_IND_t *UL_INFO);
void UL_indication(UL_IND_t *UL_INFO, L1_rxtx_proc_t *proc);
/*Interface for Downlink, transmitting the DLSCH SDU, DCI SDU*/
void Schedule_Response(Sched_Rsp_t *Sched_INFO);
......
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