Commit f3b19c04 authored by zhenghuangkun's avatar zhenghuangkun

Merge remote-tracking branch 'origin/trx_parallel_optimization' into develop

parents c0752bec 22be6eb5
......@@ -328,12 +328,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t
}
dlsch0_harq->ndi = rel8->new_data_indicator_1;
#ifdef PHY_TX_THREAD
dlsch0->active[subframe] = 1;
#else
dlsch0->active = 1;
#endif
if (rel8->rnti_type == 2)
dlsch0_harq->round = 0;
......@@ -515,11 +510,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t
dlsch0_harq->Qm = 2;
dlsch0_harq->TBS = TBStable[I_mcs][NPRB-1];
dlsch0->harq_ids[frame%2][subframe] = rel8->harq_process;
#ifdef PHY_TX_THREAD
dlsch0->active[subframe] = 1;
#else
dlsch0->active = 1;
#endif
dlsch0->rnti = rel8->rnti;
//dlsch0->harq_ids[subframe] = rel8->harq_process;
......@@ -534,11 +525,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t
case NFAPI_DL_DCI_FORMAT_1:
dci_alloc->format = format1;
#ifdef PHY_TX_THREAD
dlsch0->active[subframe] = 1;
#else
dlsch0->active = 1;
#endif
LOG_D(PHY,"SFN/SF:%04d%d proc:TX:SFN/SF:%04d%d: Programming DLSCH for Format 1 DCI, harq_pid %d\n",frame,subframe,proc->frame_tx,subframe,rel8->harq_process);
......@@ -682,11 +669,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t
dlsch0_harq->dl_power_off = 1;
#ifdef PHY_TX_THREAD
dlsch0->active[subframe] = 1;
#else
dlsch0->active = 1;
#endif
......@@ -893,32 +876,19 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t
// assume both TBs are active
dlsch0_harq->Nl = 1;
dlsch1_harq->Nl = 1;
#ifdef PHY_TX_THREAD
dlsch0->active[subframe] = 1;
dlsch1->active[subframe] = 1;
#else
dlsch0->active = 1;
dlsch1->active = 1;
#endif
dlsch0->harq_mask |= (1<<rel8->harq_process);
dlsch1->harq_mask |= (1<<rel8->harq_process);
// check if either TB is disabled (see 36-213 V11.3 Section )
if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) {
#ifdef PHY_TX_THREAD
dlsch0->active[subframe] = 0;
#else
dlsch0->active = 0;
#endif
dlsch0->harq_mask &= ~(1<<rel8->harq_process);
}
if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) {
#ifdef PHY_TX_THREAD
dlsch1->active[subframe]= 0;
#else
dlsch1->active = 0;
#endif
dlsch1->harq_mask &= ~(1<<rel8->harq_process);
}
// dlsch0_harq->dl_power_off = 0;
......@@ -929,11 +899,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t
dlsch0_harq->TBS = TBStable[get_I_TBS (dlsch0_harq->mcs)][dlsch0_harq->nb_rb - 1];
dlsch1_harq->TBS = TBStable[get_I_TBS (dlsch1_harq->mcs)][dlsch0_harq->nb_rb - 1];
#ifdef PHY_TX_THREAD
if ((dlsch0->active[subframe]==1) && (dlsch1->active[subframe]==1)) {
#else
if ((dlsch0->active==1) && (dlsch1->active==1)) {
#endif
dlsch0_harq->mimo_mode = LARGE_CDD;
dlsch1_harq->mimo_mode = LARGE_CDD;
dlsch0_harq->dl_power_off = 1;
......@@ -943,11 +909,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t
dlsch1_harq->mimo_mode = ALAMOUTI;
}
} else if (fp->nb_antenna_ports_eNB == 4) { // 4 antenna case
#ifdef PHY_TX_THREAD
if ((dlsch0->active[subframe]==1) && (dlsch1->active[subframe]==1)) {
#else
if ((dlsch0->active==1) && (dlsch1->active==1)) {
#endif
switch (rel8->precoding_information) {
case 0: // one layer per transport block
dlsch0_harq->mimo_mode = LARGE_CDD;
......@@ -987,11 +949,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t
LOG_E (PHY, "Illegal value (3) for TPMI in Format 2A DCI\n");
break;
}
#ifdef PHY_TX_THREAD
} else if (dlsch0->active[subframe] == 1) {
#else
} else if (dlsch0->active == 1) {
#endif
switch (rel8->precoding_information) {
case 0: // one layer per transport block
dlsch0_harq->mimo_mode = ALAMOUTI;
......@@ -1011,11 +969,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t
LOG_E (PHY, "Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n", rel8->precoding_information);
break;
}
#ifdef PHY_TX_THREAD
} else if (dlsch1->active[subframe] == 1) {
#else
} else if (dlsch1->active == 1) {
#endif
switch (rel8->precoding_information) {
case 0: // one layer per transport block
dlsch0_harq->mimo_mode = ALAMOUTI;
......@@ -1041,18 +995,10 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t
}
// reset HARQ process if this is the first transmission
#ifdef PHY_TX_THREAD
if ((dlsch0->active[subframe]==1) && (dlsch0_harq->round == 0))
#else
if ((dlsch0->active==1) && (dlsch0_harq->round == 0))
#endif
dlsch0_harq->status = ACTIVE;
#ifdef PHY_TX_THREAD
if ((dlsch1->active[subframe]==1) && (dlsch1_harq->round == 0))
#else
if ((dlsch1->active==1) && (dlsch1_harq->round == 0))
#endif
dlsch1_harq->status = ACTIVE;
dlsch0->rnti = rel8->rnti;
......@@ -1226,13 +1172,8 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t
printf ("RV0 = %d, RV1 = %d. MCS0 = %d, MCS1=%d\n", rel8->redundancy_version_1, rel8->redundancy_version_2, rel8->mcs_1, rel8->mcs_2);
#endif
if (TB0_active && TB1_active && rel8->transport_block_to_codeword_swap_flag==0) {
#ifdef PHY_TX_THREAD
dlsch0->active[subframe] = 1;
dlsch1->active[subframe] = 1;
#else
dlsch0->active = 1;
dlsch1->active = 1;
#endif
dlsch0->harq_mask |= (1<<rel8->harq_process);
dlsch1->harq_mask |= (1<<rel8->harq_process);
dlsch0_harq = dlsch0->harq_processes[rel8->harq_process];
......@@ -1253,13 +1194,8 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t
} else if (TB0_active && TB1_active && rel8->transport_block_to_codeword_swap_flag == 1) {
dlsch0 = eNB->dlsch[UE_id][1];
dlsch1 = eNB->dlsch[UE_id][0];
#ifdef PHY_TX_THREAD
dlsch0->active[subframe] = 1;
dlsch1->active[subframe] = 1;
#else
dlsch0->active = 1;
dlsch1->active = 1;
#endif
dlsch0->harq_mask |= (1 << rel8->harq_process);
dlsch1->harq_mask |= (1 << rel8->harq_process);
......@@ -1277,11 +1213,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t
dlsch1_harq->codeword=0;
}
else if (TB0_active && (TB1_active==0)) {
#ifdef PHY_TX_THREAD
dlsch0->active[subframe] = 1;
#else
dlsch0->active = 1;
#endif
dlsch0->harq_mask |= (1<<rel8->harq_process);
dlsch0_harq = dlsch0->harq_processes[rel8->harq_process];
dlsch0_harq->mcs = rel8->mcs_1;
......@@ -1296,11 +1228,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t
#endif
}
else if ((TB0_active==0) && TB1_active) {
#ifdef PHY_TX_THREAD
dlsch1->active[subframe] = 1;
#else
dlsch1->active = 1;
#endif
dlsch1->harq_mask |= (1<<rel8->harq_process);
dlsch1_harq = dlsch1->harq_processes[rel8->harq_process];
dlsch1_harq->mcs = rel8->mcs_2;
......@@ -1503,7 +1431,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t
#endif
//printf("DCI %d.%d rnti %d harq %d TBS %d\n", frame, subframe, rel8->rnti, rel8->harq_process, dlsch0_harq->TBS);
#if T_TRACER
if (dlsch0->active)
if (dlsch0->active[subframe])
T(T_ENB_PHY_DLSCH_UE_DCI, T_INT(0), T_INT(frame), T_INT(subframe),
T_INT(rel8->rnti), T_INT(rel8->dci_format), T_INT(rel8->harq_process),
T_INT(rel8->mcs_1), T_INT(dlsch0_harq->TBS));
......@@ -1772,7 +1700,7 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,mDCI_ALLOC_t *dc
else AssertFatal(1==0,"Don't know how to set TBS (TPC %d)\n",rel13->tpc);
LOG_D(PHY,"fill_mdci_and_dlsch : TBS = %d(%d) %p, %x\n",dlsch0_harq->TBS,dlsch0_harq->mcs,dlsch0,rel13->rnti);
}
dlsch0->active = 1;
dlsch0->active[subframe] = 1;
dlsch0->harq_mask |= (1 << rel13->harq_process);
dlsch0_harq->frame = (subframe >= 8) ? ((frame + 1) & 1023) : frame;
......
......@@ -227,14 +227,9 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch) {
if (dlsch) {
Mdlharq = dlsch->Mdlharq;
dlsch->rnti = 0;
#ifdef PHY_TX_THREAD
for (i=0; i<10; i++)
dlsch->active[i] = 0;
#else
dlsch->active = 0;
#endif
dlsch->harq_mask = 0;
for (i=0; i<20; i++)
......
......@@ -148,11 +148,7 @@ typedef struct {
/// Allocated RNTI (0 means DLSCH_t is not currently used)
uint16_t rnti;
/// Active flag for baseband transmitter processing
#ifdef PHY_TX_THREAD
uint8_t active[10];
#else
uint8_t active;
#endif
/// indicator of UE type (0 = LTE, 1,2 = Cat-M)
int ue_type;
/// HARQ process mask, indicates which processes are currently active
......
......@@ -43,6 +43,7 @@ int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req);
int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req);
int oai_nfapi_ue_release_req(nfapi_ue_release_request_t *release_req);
uint8_t dl_pdus[8][MAX_NUM_DL_PDU][9422];
void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB,
int frame, int subframe,
L1_rxtx_proc_t *proc,
......@@ -196,24 +197,13 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_pro
AssertFatal(dlsch0_harq!=NULL,"dlsch_harq is null\n");
// compute DL power control parameters
eNB->pdsch_config_dedicated[UE_id].p_a = rel8->pa;
#ifdef PHY_TX_THREAD
if (dlsch0->active[proc->subframe_tx]) {
# else
if (dlsch0->active) {
#endif
computeRhoA_eNB(rel8->pa, dlsch0,dlsch0_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB);
computeRhoB_eNB(rel8->pa,eNB->frame_parms.pdsch_config_common.p_b,eNB->frame_parms.nb_antenna_ports_eNB,dlsch0,dlsch0_harq->dl_power_off);
}
#ifdef PHY_TX_THREAD
if (dlsch1->active[proc->subframe_tx]) {
#else
if (dlsch1->active) {
#endif
computeRhoA_eNB(rel8->pa, dlsch1,dlsch1_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB);
computeRhoB_eNB(rel8->pa,eNB->frame_parms.pdsch_config_common.p_b,eNB->frame_parms.nb_antenna_ports_eNB,dlsch1,dlsch1_harq->dl_power_off);
}
......@@ -312,11 +302,7 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_pro
dlsch0_harq->rb_alloc[3] = localRIV2alloc_LUT100_3[rel8->resource_block_coding];
}
#ifdef PHY_TX_THREAD
dlsch0->active[proc->subframe_tx]= 1;
#else
dlsch0->active = 1;
#endif
dlsch0_harq->nb_rb = 6;
dlsch0_harq->vrb_type = LOCALIZED;
dlsch0_harq->rvidx = rel8->redundancy_version;
......@@ -359,7 +345,7 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_pro
rel8->length
);
#endif
dlsch0->active = 1;
dlsch0->active[proc->subframe_tx] = 1;
harq_pid = dlsch0->harq_ids[frame%2][proc->subframe_tx];
dlsch0->harq_mask |= (1<<harq_pid);
AssertFatal((harq_pid>=0) && (harq_pid<8),"subframe %d: harq_pid %d not in 0...7\n",proc->subframe_tx,harq_pid);
......@@ -369,12 +355,12 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_pro
// compute DL power control parameters
if (dlsch0->active) {
if (dlsch0->active[proc->subframe_tx]) {
computeRhoA_eNB(rel8->pa,dlsch0,dlsch0_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB);
computeRhoB_eNB(rel8->pa,eNB->frame_parms.pdsch_config_common.p_b,eNB->frame_parms.nb_antenna_ports_eNB,dlsch0,dlsch0_harq->dl_power_off);
}
if (dlsch1->active) {
if (dlsch1->active[proc->subframe_tx]) {
computeRhoA_eNB(rel8->pa, dlsch1,dlsch1_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB);
computeRhoB_eNB(rel8->pa,eNB->frame_parms.pdsch_config_common.p_b,eNB->frame_parms.nb_antenna_ports_eNB,dlsch1,dlsch1_harq->dl_power_off);
}
......@@ -867,8 +853,33 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
dlsch_pdu_rel8->transport_blocks);
if (1) { //sdu != NULL)
if (NFAPI_MODE!=NFAPI_MODE_VNF)
if (NFAPI_MODE!=NFAPI_MODE_VNF) {
if (sdu != NULL) {
LTE_eNB_PDCCH *pdcch_vars = &eNB->pdcch_vars[NFAPI_SFNSF2SF(DL_req->sfn_sf)&1];
uint8_t harq_pid_dl = 0;
uint8_t k;
for(k=0; k < pdcch_vars->num_dci;k++){
if(pdcch_vars->dci_alloc[k].rnti == dlsch_pdu_rel8->rnti){
harq_pid_dl = pdcch_vars->dci_alloc[pdcch_vars->num_dci-1].harq_pid;
break;
}
}
if(k==pdcch_vars->num_dci){
LOG_E(PHY, "schedule_response not find dl harq_pid rnti %x frame %d subframe %d\n", dlsch_pdu_rel8->rnti,NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf));
}else{
if (harq_pid_dl >=0 && harq_pid_dl < 8) {
memset(dl_pdus[harq_pid_dl][i], 0, sizeof(uint8_t)*9422);
memcpy(dl_pdus[harq_pid_dl][i], TX_req->tx_request_body.tx_pdu_list[pdu_index].segments[0].segment_data, TX_req->tx_request_body.tx_pdu_list[pdu_index].segments[0].segment_length);
handle_nfapi_dlsch_pdu(eNB,NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),proc,dl_config_pdu, dlsch_pdu_rel8->transport_blocks-1, dl_pdus[harq_pid_dl][i]);
} else {
LOG_E(PHY, "schedule_response illegal harq_pid %d\n", harq_pid_dl);
}
}
} else {
handle_nfapi_dlsch_pdu(eNB,NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),proc,dl_config_pdu, dlsch_pdu_rel8->transport_blocks-1, sdu);
}
}
} else {
dont_send=1;
LOG_E(MAC,"%s() NFAPI_DL_CONFIG_DLSCH_PDU_TYPE sdu is NULL DL_CFG:SFN/SF:%d:pdu_index:%d TX_REQ:SFN/SF:%d:pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(DL_req->sfn_sf), pdu_index,
......
......@@ -308,11 +308,7 @@ bool dlsch_procedures(PHY_VARS_eNB *eNB,
if(eNB->dlsch_encoding_stats.p_time>500*3000 && opp_enabled == 1) {
print_meas_now(&eNB->dlsch_encoding_stats,"total coding",stderr);
}
#ifdef PHY_TX_THREAD
dlsch->active[subframe] = 0;
#else
dlsch->active = 0;
#endif
dlsch_harq->round++;
LOG_D(PHY,"Generated DLSCH dlsch_harq[round:%d]\n",dlsch_harq->round);
return true;
......@@ -502,11 +498,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
dlsch1 = eNB->dlsch[(uint8_t)UE_id][1];
if ((dlsch0)&&(dlsch0->rnti>0)&&
#ifdef PHY_TX_THREAD
(dlsch0->active[subframe] == 1)
#else
(dlsch0->active == 1)
#endif
) {
// get harq_pid
harq_pid = dlsch0->harq_ids[frame%2][subframe];
......@@ -541,11 +533,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
}
}
} else if ((dlsch0)&&(dlsch0->rnti>0)&&
#ifdef PHY_TX_THREAD
(dlsch0->active[subframe] == 0)
#else
(dlsch0->active == 0)
#endif
) {
// clear subframe TX flag since UE is not scheduled for PDSCH in this subframe (so that we don't look for PUCCH later)
dlsch0->subframe_tx[subframe]=0;
......
......@@ -2131,7 +2131,7 @@ int RCconfig_gtpu(void ) {
cidr = enb_ipv4_address_for_S1U;
address = strtok(cidr, "/");
if (address) {
if (address && (RC.gtpv1u_data_g == NULL || RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up == 0)) {
MessageDef *message;
AssertFatal((message = itti_alloc_new_message(TASK_ENB_APP, GTPV1U_ENB_S1_REQ))!=NULL,"");
IPV4_STR_ADDR_TO_INT_NWBO ( address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
......
......@@ -51,10 +51,6 @@
#include "T.h"
#ifdef PHY_TX_THREAD
extern volatile int16_t phy_tx_txdataF_end;
extern int oai_exit;
#endif
extern uint16_t sfnsf_add_subframe(uint16_t frameP, uint16_t subframeP, int offset);
extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset);
......@@ -1655,17 +1651,6 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len; // 1 is for the postpadding header
}
#ifdef PHY_TX_THREAD
struct timespec time_req, time_rem;
time_req.tv_sec = 0;
time_req.tv_nsec = 10000;
while((!oai_exit)&&(phy_tx_txdataF_end == 0)) {
nanosleep(&time_req,&time_rem);
continue;
}
#endif
offset = generate_dlsch_header((unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], num_sdus, //num_sdus
sdu_lengths, //
sdu_lcids, 255, // no drx
......
......@@ -1216,7 +1216,7 @@ int gtpv1u_eNB_init(void) {
//gtpv1u_data_g.udp_data;
RC.gtpv1u_data_g->seq_num = 0;
RC.gtpv1u_data_g->restart_counter = 0;
RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up = 0;
/* Initializing GTPv1-U stack */
if ((rc = nwGtpv1uInitialize(&RC.gtpv1u_data_g->gtpv1u_stack, GTPU_STACK_ENB)) != NW_GTPV1U_OK) {
LOG_E(GTPU, "Failed to setup nwGtpv1u stack %x\n", rc);
......
......@@ -139,7 +139,7 @@ static struct {
} sync_phy_proc;
extern double cpuf;
int first_phy_tx = 1;
void init_eNB(int,int);
void stop_eNB(int nb_inst);
......@@ -450,6 +450,41 @@ static void *L1_thread( void *param ) {
return &eNB_thread_rxtx_status;
}
static void* L1_thread_rx( void* param ) {
static int eNB_thread_phy_rx_status;
L1_proc_t *eNB_proc = (L1_proc_t*)param;
L1_rxtx_proc_t* proc = &eNB_proc->L1_proc;
PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id];
char string[20];
sprintf(string,"RXnp4_1");
// set default return value
eNB_thread_phy_rx_status = 0;
thread_top_init(string,1,500000L,1000000L,20000000L);
while (!oai_exit) {
if (wait_on_condition(&proc->mutex,&proc->cond,&proc->instance_cnt,string) < 0) break;
if (oai_exit) break;
LOG_D(PHY,"Running L1 thread rx procedures\n");
if (rxtx(eNB,proc,string) < 0) LOG_E(PHY,"eNB %d CC_id %d failed during execution\n",eNB->Mod_id,eNB->CC_id);
if (release_thread(&proc->mutex,&proc->instance_cnt,string) < 0) break;
}
LOG_I(PHY, "Exiting L1 thread RX\n");
eNB_thread_phy_rx_status = 0;
return &eNB_thread_phy_rx_status;
}
void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t *ru) {
L1_proc_t *proc = &eNB->proc;
L1_rxtx_proc_t *L1_proc = &proc->L1_proc;
......@@ -544,7 +579,7 @@ int wakeup_tx(PHY_VARS_eNB *eNB, int frame_rx,int subframe_rx,int frame_tx,int s
L1_rxtx_proc_t *L1_proc = &eNB->proc.L1_proc;
L1_rxtx_proc_t *L1_proc_tx = &eNB->proc.L1_proc_tx;
RU_proc_t *ru_proc = NULL;
int ret;
LOG_D(PHY,"ENTERED wakeup_tx (IC %d)\n",L1_proc_tx->instance_cnt);
......@@ -561,12 +596,23 @@ int wakeup_tx(PHY_VARS_eNB *eNB, int frame_rx,int subframe_rx,int frame_tx,int s
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_L1_PROC_TX_IC,L1_proc_tx->instance_cnt);
L1_proc_tx->instance_cnt = 0;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_L1_PROC_TX_IC,L1_proc_tx->instance_cnt);
if(!((get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && (get_thread_worker_conf() == WORKER_ENABLE))){
L1_proc_tx->subframe_rx = subframe_rx;
L1_proc_tx->frame_rx = frame_rx;
L1_proc_tx->subframe_tx = subframe_tx;
L1_proc_tx->frame_tx = frame_tx;
L1_proc_tx->timestamp_tx = timestamp_tx;
} else {
if(eNB->RU_list[0] != NULL)
ru_proc = &eNB->RU_list[0]->proc;
if(ru_proc != NULL){
L1_proc_tx->subframe_rx = ru_proc->subframe_rx;
L1_proc_tx->frame_rx = ru_proc->frame_rx;
L1_proc_tx->subframe_tx = (ru_proc->subframe_rx+(sf_ahead-1))%10;
L1_proc_tx->frame_tx = (ru_proc->subframe_rx>(9-(sf_ahead-1))) ? (ru_proc->frame_rx+1)&1023 : ru_proc->frame_rx;
L1_proc_tx->timestamp_tx = ru_proc->timestamp_rx+((sf_ahead-1)*eNB->frame_parms.samples_per_tti);;
}
}
// the thread can now be woken up
LOG_D(PHY,"L1 RX Waking up L1 TX %d.%d\n",L1_proc->frame_tx,L1_proc->subframe_tx);
AssertFatal(pthread_cond_signal(&L1_proc_tx->cond) == 0, "ERROR pthread_cond_signal for eNB L1 thread tx\n");
......@@ -575,6 +621,36 @@ int wakeup_tx(PHY_VARS_eNB *eNB, int frame_rx,int subframe_rx,int frame_tx,int s
return(0);
}
int wakeup_rx(PHY_VARS_eNB *eNB, RU_t *ru){
L1_proc_t *proc=&eNB->proc;
RU_proc_t *ru_proc=&ru->proc;
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
L1_rxtx_proc_t *L1_proc_rx=&proc->L1_proc;
if(pthread_mutex_lock(&L1_proc_rx->mutex) != 0){
LOG_E( PHY, "[RU] ERROR pthread_mutex_lock for phy rx thread (IC %d)\n", L1_proc_rx->instance_cnt);
exit_fun( "error locking mutex_rxtx" );
}
if (L1_proc_rx->instance_cnt==-1) {
++L1_proc_rx->instance_cnt;
L1_proc_rx->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_tti);
L1_proc_rx->frame_rx = ru_proc->frame_rx;
L1_proc_rx->subframe_rx = ru_proc->subframe_rx;
L1_proc_rx->frame_tx = (ru_proc->subframe_rx > (9-sf_ahead)) ? (ru_proc->frame_rx+1)&1023 : ru_proc->frame_rx;
L1_proc_rx->subframe_tx = (ru_proc->subframe_rx + sf_ahead)%10;
// the thread can now be woken up
AssertFatal(pthread_cond_signal(&L1_proc_rx->cond) == 0, "ERROR pthread_cond_signal for L1_thread_rx thread\n");
}else{
LOG_E(PHY,"phy rx thread busy, skipping instance_cnt_phy_rx %d\n", L1_proc_rx->instance_cnt);
}
pthread_mutex_unlock( &L1_proc_rx->mutex );
return 0;
}
int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {
L1_proc_t *proc=&eNB->proc;
RU_proc_t *ru_proc=&ru->proc;
......@@ -583,7 +659,7 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {
int ret;
LOG_D(PHY,"ENTERED wakeup_rxtx, %d.%d\n",ru_proc->frame_rx,ru_proc->subframe_rx);
if(!((get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && (get_thread_worker_conf() == WORKER_ENABLE))) {
// wake up TX for subframe n+sl_ahead
// lock the TX mutex and make sure the thread is ready
AssertFatal((ret=pthread_mutex_lock(&L1_proc->mutex)) == 0,"mutex_lock returns %d\n", ret);
......@@ -623,6 +699,15 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {
}
AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"mutex_unlock return %d\n",ret);
} else {
wakeup_rx(eNB, ru);
// don't sent tx data when first time because this is no data
if(first_phy_tx == 0){
wakeup_tx(eNB, ru_proc->frame_rx, ru_proc->subframe_rx, (L1_proc->subframe_rx > (9-sf_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx, (L1_proc->subframe_rx + sf_ahead)%10, ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_tti));
} else {
first_phy_tx = 0;
}
}
return(0);
}
......@@ -930,7 +1015,7 @@ void init_eNB_proc(int inst) {
if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) && NFAPI_MODE!=NFAPI_MODE_VNF) {
pthread_create( &L1_proc->pthread, attr0, L1_thread, proc );
} else if ((get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && NFAPI_MODE!=NFAPI_MODE_VNF) {
pthread_create( &L1_proc->pthread, attr0, L1_thread, proc );
pthread_create( &L1_proc->pthread, attr0, L1_thread_rx, proc );
pthread_create( &L1_proc_tx->pthread, attr1, L1_thread_tx, proc);
} else if (NFAPI_MODE==NFAPI_MODE_VNF) { // this is neccesary in VNF or L2 FAPI simulator.
// Original Code from Fujitsu w/ old structure/field name
......
......@@ -1553,6 +1553,41 @@ void *ru_thread_tx( void *param ) {
return 0;
}
#if defined(PRE_SCD_THREAD)
int wakeup_prescd(RU_t* ru, int frame , int subframe){
new_dlsch_ue_select_tbl_in_use = dlsch_ue_select_tbl_in_use;
dlsch_ue_select_tbl_in_use = !dlsch_ue_select_tbl_in_use;
memcpy(&pre_scd_eNB_UE_stats,&RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX);
memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX);
if (pthread_mutex_lock(&ru->proc.mutex_pre_scd)!= 0) {
LOG_E( PHY, "[eNB] error locking proc mutex for eNB pre scd\n");
exit_fun("error locking mutex_time");
}
ru->proc.instance_pre_scd++;
if (ru->proc.instance_pre_scd == 0) {
if (pthread_cond_signal(&ru->proc.cond_pre_scd) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB pre scd\n" );
exit_fun( "ERROR pthread_cond_signal cond_pre_scd" );
return -1;
}
}else{
LOG_E( PHY, "[eNB] frame %d subframe %d rxtx busy instance_pre_scd %d\n",
frame,subframe,ru->proc.instance_pre_scd );
return -1;
}
if (pthread_mutex_unlock(&ru->proc.mutex_pre_scd)!= 0) {
LOG_E( PHY, "[eNB] error unlocking mutex_pre_scd mutex for eNB pre scd\n");
exit_fun("error unlocking mutex_pre_scd");
return -1;
}
return 0;
}
#endif
void *ru_thread( void *param ) {
RU_t *ru = (RU_t *)param;
RU_proc_t *proc = &ru->proc;
......@@ -1777,26 +1812,9 @@ void *ru_thread( void *param ) {
AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_eNBs))==0,"mutex_unlock returns %d\n",ret);
#if defined(PRE_SCD_THREAD)
new_dlsch_ue_select_tbl_in_use = dlsch_ue_select_tbl_in_use;
dlsch_ue_select_tbl_in_use = !dlsch_ue_select_tbl_in_use;
memcpy(&pre_scd_eNB_UE_stats,&RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX);
memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX);
AssertFatal((ret=pthread_mutex_lock(&ru->proc.mutex_pre_scd))==0,"[eNB] error locking proc mutex for eNB pre scd\n");
ru->proc.instance_pre_scd++;
if (ru->proc.instance_pre_scd == 0) {
if (pthread_cond_signal(&ru->proc.cond_pre_scd) != 0) {
LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB pre scd\n" );
exit_fun( "ERROR pthread_cond_signal cond_pre_scd" );
}
}else{
LOG_E( PHY, "[eNB] frame %d subframe %d rxtx busy instance_pre_scd %d\n",
frame,subframe,ru->proc.instance_pre_scd );
if (NFAPI_MODE == NFAPI_MONOLITHIC) {
wakeup_prescd(ru, frame, subframe);
}
AssertFatal((ret=pthread_mutex_unlock(&ru->proc.mutex_pre_scd))==0,"[eNB] error unlocking mutex_pre_scd mutex for eNB pre scd\n");
#endif
// wakeup all eNB processes waiting for this RU
if (ru->num_eNB>0) wakeup_L1s(ru);
......@@ -2208,11 +2226,13 @@ void init_RU_proc(RU_t *ru) {
pthread_create( &proc->pthread_FH, attr_FH, ru_thread, (void*)ru );
#if defined(PRE_SCD_THREAD)
if (NFAPI_MODE == NFAPI_MONOLITHIC) {
proc->instance_pre_scd = -1;
pthread_mutex_init( &proc->mutex_pre_scd, NULL);
pthread_cond_init( &proc->cond_pre_scd, NULL);
pthread_create(&proc->pthread_pre_scd, NULL, pre_scd_thread, (void *)ru);
pthread_setname_np(proc->pthread_pre_scd, "pre_scd_thread");
}
#endif
#ifdef PHY_TX_THREAD
pthread_create( &proc->pthread_phy_tx, NULL, eNB_thread_phy_tx, (void *)ru );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment