remove global for frame/subframe, noS1 attach+ traffic ok, UE do not compile
This commit is contained in:
+71
-64
@@ -45,7 +45,7 @@ static inline void printMeas2(char *txt, Meas *M, int period, bool MaxMin) {
|
||||
txt,
|
||||
M->sum/M->iterations,
|
||||
M->iterations,
|
||||
MaxMin?"max":"min",
|
||||
MaxMin?"max":"min",
|
||||
M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4], M->maxArray[5],
|
||||
M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]);
|
||||
#if T_TRACER
|
||||
@@ -63,16 +63,20 @@ 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++)
|
||||
M->maxArray[i]=INT_MAX;
|
||||
bzero(M,sizeof(*M));
|
||||
|
||||
if (!MaxMin)
|
||||
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);
|
||||
@@ -1386,42 +1394,38 @@ void DL_du_fs6(RU_t *ru) {
|
||||
pickStaticTime(begingWait);
|
||||
int nb_blocks=receiveSubFrame(&sockFS6, bufferZone, sizeof(bufferZone), CTsentCUv0 );
|
||||
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 (nb_blocks > 0) {
|
||||
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);
|
||||
|
||||
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);
|
||||
@@ -1530,27 +1532,30 @@ void *cu_fs6(void *arg) {
|
||||
initStaticTime(begingWait2);
|
||||
initRefTimes(waitDUAndProcessingUL);
|
||||
initRefTimes(makeSendDL);
|
||||
initRefTimes(fullLoop);
|
||||
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 *du_fs6(void *arg) {
|
||||
setbuf(stdout, NULL);
|
||||
setbuf(stderr, 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);
|
||||
|
||||
+41
-102
@@ -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;
|
||||
|
||||
+9
-407
@@ -71,220 +71,8 @@
|
||||
#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,
|
||||
REMOTE_IF5 =1,
|
||||
@@ -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;
|
||||
|
||||
+10
-387
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user