Commit ec6236f8 authored by Raymond.Knopp's avatar Raymond.Knopp

tests with monolithic eNB. runs fluidly. No UE stimulus yet

parent af4b4c3f
......@@ -1648,9 +1648,17 @@ int phy_init_RU(RU_t *ru) {
AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]),
"nb_antennas_rx too large");
ru->prach_rxsigF = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*));
for (j=0;j<4;j++) ru->prach_rxsigF_br[j] = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*));
for (i=0; i<ru->nb_rx; i++) {
ru->prach_rxsigF[i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) );
LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[i]);
#ifdef Rel14
for (j=0;j<4;j++) {
ru->prach_rxsigF_br[j][i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) );
LOG_D(PHY,"[INIT] prach_vars_br->rxsigF[%d] = %p\n",i,ru->prach_rxsigF_br[j][i]);
}
#endif
}
for (i=0; i<RC.nb_inst; i++) {
......@@ -1772,19 +1780,19 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
prach_vars->prachF = (int16_t*)malloc16_clear( 1024*2*sizeof(int16_t) );
// assume maximum of 64 RX antennas for PRACH receiver
prach_vars->prach_ifft = (int16_t***)malloc16_clear(4*sizeof(int32_t**));
prach_vars->prach_ifft[0] = (int16_t**)malloc16_clear(2*sizeof(int32_t*));
prach_vars->prach_ifft[0][0] = (int16_t*)malloc16_clear(1024*2*sizeof(int32_t));
prach_vars->prach_ifft[0] = (int32_t**)malloc16_clear(64*sizeof(int32_t*));
for (i=0;i<64;i++) prach_vars->prach_ifft[0][i] = (int32_t*)malloc16_clear(1024*2*sizeof(int32_t));
prach_vars->rxsigF[0] = (int16_t**)malloc16_clear(64*sizeof(int16_t*));
// PRACH BR
#ifdef Rel14
prach_vars_br->prachF = (int16_t*)malloc16_clear( 1024*2*sizeof(int32_t) );
// assume maximum of 64 RX antennas for PRACH receiver
prach_vars_br->prach_ifft = (int32_t***)malloc16_clear(4*sizeof(int32_t**));
for (int ce_level=0;ce_level<4;ce_level++) {
prach_vars_br->prach_ifft[ce_level] = (int32_t**)malloc16_clear(64*sizeof(int32_t*));
for (i=0; i<64; i++) prach_vars_br->prach_ifft[ce_level][i] = (int32_t*)malloc16_clear(1024*2*sizeof(int32_t));
prach_vars_br->prach_ifft[ce_level] = (int32_t**)malloc16_clear(64*sizeof(int32_t*));
for (i=0;i<64;i++) prach_vars_br->prach_ifft[ce_level][i] = (int32_t*)malloc16_clear(1024*2*sizeof(int32_t));
prach_vars->rxsigF[ce_level] = (int16_t**)malloc16_clear(64*sizeof(int16_t*));
}
#endif
......
......@@ -1182,13 +1182,15 @@ typedef struct {
/// first index: ? [0..1023] (hard coded)
int16_t *prachF;
/// \brief ?.
/// first index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx.
/// second index: ? [0..ofdm_symbol_size*12[
int16_t **rxsigF;
/// first index: ce_level [0..3]
/// second index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx.
/// third index: frequency-domain sample [0..ofdm_symbol_size*12[
int16_t **rxsigF[4];
/// \brief local buffer to compute prach_ifft (necessary in case of multiple CCs)
/// first index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx.
/// second index: ? [0..2047] (hard coded)
int32_t ***prach_ifft;
/// first index: ce_level [0..3] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx.
/// second index: ? [0..63] (hard coded)
/// third index: ? [0..63] (hard coded)
int32_t **prach_ifft[4];
/// repetition number
#ifdef Rel14
......
......@@ -130,6 +130,32 @@ void check_ul_failure(module_id_t module_idP,int CC_id,int UE_id,
}
void clear_nfapi_information(eNB_MAC_INST *eNB,int CC_idP,frame_t frameP,sub_frame_t subframeP);
void clear_nfapi_information(eNB_MAC_INST *eNB,int CC_idP,frame_t frameP,sub_frame_t subframeP) {
nfapi_dl_config_request_t *DL_req = &eNB->DL_req[0];
nfapi_ul_config_request_t *UL_req = &eNB->UL_req[0];
nfapi_hi_dci0_request_t *HI_DCI0_req = &eNB->HI_DCI0_req[0];
nfapi_tx_request_t *TX_req = &eNB->TX_req[0];
eNB->pdu_index[CC_idP] = 0;
DL_req[CC_idP].dl_config_request_body.number_pdcch_ofdm_symbols = 1;
DL_req[CC_idP].dl_config_request_body.number_dci = 0;
DL_req[CC_idP].dl_config_request_body.number_pdu = 0;
DL_req[CC_idP].dl_config_request_body.number_pdsch_rnti = 0;
DL_req[CC_idP].dl_config_request_body.transmission_power_pcfich = 6000;
HI_DCI0_req[CC_idP].hi_dci0_request_body.sfnsf = subframeP + (frameP<<3);
HI_DCI0_req[CC_idP].hi_dci0_request_body.number_of_dci = 0;
UL_req[CC_idP].ul_config_request_body.number_of_pdus = 0;
UL_req[CC_idP].ul_config_request_body.rach_prach_frequency_resources = 0; // ignored, handled by PHY for now
UL_req[CC_idP].ul_config_request_body.srs_present = 0; // ignored, handled by PHY for now
TX_req[CC_idP].tx_request_body.number_of_pdus = 0;
}
void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
{
......@@ -147,10 +173,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame
rnti_t rnti;
COMMON_channels_t *cc = RC.mac[module_idP]->common_channels;
nfapi_dl_config_request_t *DL_req = &RC.mac[module_idP]->DL_req[0];
nfapi_ul_config_request_t *UL_req = &RC.mac[module_idP]->UL_req[0];
nfapi_hi_dci0_request_t *HI_DCI0_req = &RC.mac[module_idP]->HI_DCI0_req[0];
nfapi_tx_request_t *TX_req = &RC.mac[module_idP]->TX_req[0];
eNB_UE_STATS *eNB_UE_stats;
#if defined(FLEXRAN_AGENT_SB_IF)
Protocol__FlexranMessage *msg;
......@@ -168,21 +191,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame
memset(cc[CC_id].vrb_map,0,100);
// clear DL/UL info for new scheduling round
clear_nfapi_information(RC.mac[module_idP],CC_id,frameP,subframeP);
RC.mac[module_idP]->pdu_index[CC_id] = 0;
DL_req[CC_id].dl_config_request_body.number_pdcch_ofdm_symbols = 1;
DL_req[CC_id].dl_config_request_body.number_dci = 0;
DL_req[CC_id].dl_config_request_body.number_pdu = 0;
DL_req[CC_id].dl_config_request_body.number_pdsch_rnti = 0;
DL_req[CC_id].dl_config_request_body.transmission_power_pcfich = 6000;
HI_DCI0_req[CC_id].hi_dci0_request_body.sfnsf = subframeP + (frameP<<3);
HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_dci = 0;
UL_req[CC_id].ul_config_request_body.number_of_pdus = 0;
UL_req[CC_id].ul_config_request_body.rach_prach_frequency_resources = 0; // ignored, handled by PHY for now
UL_req[CC_id].ul_config_request_body.srs_present = 0; // ignored, handled by PHY for now
TX_req[CC_id].tx_request_body.number_of_pdus = 0;
#if defined(Rel10) || defined(Rel14)
cc[CC_id].mcch_active =0;
#endif
......@@ -310,719 +320,18 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame
// This schedules MIB
if ((subframeP==0) && (frameP&3) == 0) schedule_mib(module_idP,frameP,subframeP);
// This schedules SI for LTE and eMTC
// This schedules SI for legacy LTE and eMTC
schedule_SI(module_idP,frameP,subframeP);
// This schedules Random-Access
schedule_RA(module_idP,frameP,subframeP,1);
// This schedules Random-Access for legacy LTE and eMTC
schedule_RA(module_idP,frameP,subframeP);
// This schedules ULSCH in subframe+
// This schedules ULSCH in subframeP+k
schedule_ulsch(module_idP,frameP,subframeP);
// This schedules DLSCH in
// This schedules DLSCH in subframeP
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
/*
switch (subframeP) {
case 0:
// FDD/TDD Schedule Downlink RA transmissions (RA response, Msg4 Contention resolution)
// Schedule ULSCH for FDD or subframeP 4 (TDD config 0,3,6)
// Schedule Normal DLSCH
LOG_D(MAC,"NFAPI: number_of_pdus %d, number_of_TX_req %d\n",
DL_req[0].dl_config_request_body.number_pdu,
TX_req[0].tx_request_body.number_of_pdus);
if (cc[0].tdd_Config == NULL) { //FDD
schedule_ulsch(module_idP,frameP,cooperation_flag,0,4);//,calibration_flag);
} else if ((cc[0].tdd_Config->subframeAssignment == 0) ||
(cc[0].tdd_Config->subframeAssignment == 3) ||
(cc[0].tdd_Config->subframeAssignment == 6)) {
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4);//,calibration_flag);
}
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
break;
case 1:
// TDD, schedule UL for subframeP 7 (TDD config 0,1) / subframeP 8 (TDD Config 6)
// FDD, schedule normal UL/DLSCH
if (cc[0].tdd_Config != NULL) { // TDD
switch (cc[0].tdd_Config->subframeAssignment) {
case 0:
case 1:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7);
#ifndef FLEXRAN_AGENT_SB_IF
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#endif
break;
case 6:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8);
#ifndef FLEXRAN_AGENT_SB_IF
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#endif
break;
default:
break;
}
} else { //FDD
schedule_ulsch(module_idP,frameP,cooperation_flag,1,5);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
}
break;
case 2:
// TDD, nothing
// FDD, normal UL/DLSCH
if (cc[0].tdd_Config == NULL) { //FDD
schedule_ulsch(module_idP,frameP,cooperation_flag,2,6);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
}
break;
case 3:
// TDD Config 2, ULSCH for subframeP 7
// TDD Config 2/5 normal DLSCH
// FDD, normal UL/DLSCH
if (cc[0].tdd_Config != NULL) {
switch (cc[0].tdd_Config->subframeAssignment) {
case 2:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7);
// no break here!
case 5:
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
break;
default:
break;
}
} else { //FDD
schedule_ulsch(module_idP,frameP,cooperation_flag,3,7);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
}
break;
case 4:
// TDD Config 1, ULSCH for subframeP 8
// TDD Config 1/2/4/5 DLSCH
// FDD UL/DLSCH
if (cc[0].tdd_Config != NULL) { // TDD
switch (cc[0].tdd_Config->subframeAssignment) {
case 1:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8);
// no break here!
case 2:
// no break here!
case 4:
// no break here!
case 5:
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
break;
default:
break;
}
} else {
if (cc[0].tdd_Config == NULL) { //FDD
schedule_ulsch(module_idP, frameP, cooperation_flag, 4, 8);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP, frameP, subframeP, mbsfn_status);
fill_DLSCH_dci(module_idP, frameP, subframeP, mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
}
}
break;
case 5:
// TDD/FDD Schedule SI
// TDD Config 0,6 ULSCH for subframes 9,3 resp.
// TDD normal DLSCH
// FDD normal UL/DLSCH
if (cc[0].tdd_Config == NULL) {
schedule_ulsch(module_idP,frameP,cooperation_flag,5,9);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP, frameP, subframeP, mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
} else if ((cc[0].tdd_Config->subframeAssignment == 0) || // TDD Config 0
(cc[0].tdd_Config->subframeAssignment == 6)) { // TDD Config 6
//schedule_ulsch(module_idP,cooperation_flag,subframeP);
#ifndef FLEXRAN_AGENT_SB_IF
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#endif
} else {
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
}
break;
case 6:
// TDD Config 0,1,6 ULSCH for subframes 2,3
// TDD Config 3,4,5 Normal DLSCH
// FDD normal ULSCH/DLSCH
if (cc[0].tdd_Config != NULL) { // TDD
switch (cc[0].tdd_Config->subframeAssignment) {
case 0:
break;
case 1:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2);
// schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
#ifndef FLEXRAN_AGENT_SB_IF
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#endif
break;
case 6:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3);
// schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
#ifndef FLEXRAN_AGENT_SB_IF
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#endif
break;
case 5:
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
break;
case 3:
case 4:
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
break;
default:
break;
}
} else { //FDD
schedule_ulsch(module_idP,frameP,cooperation_flag,6,0);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
}
break;
case 7:
// TDD Config 3,4,5 Normal DLSCH
// FDD Normal UL/DLSCH
if (cc[0].tdd_Config != NULL) { // TDD
switch (cc[0].tdd_Config->subframeAssignment) {
case 3:
case 4:
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
break;
case 5:
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
break;
default:
break;
}
} else { //FDD
schedule_ulsch(module_idP,frameP,cooperation_flag,7,1);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
}
break;
case 8:
// TDD Config 2,3,4,5 ULSCH for subframeP 2
//
// FDD Normal UL/DLSCH
if (cc[0].tdd_Config != NULL) { // TDD
switch (cc[0].tdd_Config->subframeAssignment) {
case 2:
case 3:
case 4:
case 5:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
break;
default:
break;
}
} else { //FDD
schedule_ulsch(module_idP,frameP,cooperation_flag,8,2);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
}
break;
case 9:
// TDD Config 1,3,4,6 ULSCH for subframes 3,3,3,4
if (cc[0].tdd_Config != NULL) {
switch (cc[0].tdd_Config->subframeAssignment) {
case 1:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
break;
case 3:
case 4:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
break;
case 6:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
break;
case 2:
case 5:
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
break;
default:
break;
}
} else { //FDD
schedule_ulsch(module_idP,frameP,cooperation_flag,9,3);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
}
break;
}
*/
// Allocate CCEs and Msg3 for good after scheduling is done
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
allocate_CCEs(module_idP,CC_id,subframeP,0);
......
......@@ -149,7 +149,7 @@ void check_and_add_msg3(module_id_t module_idP,frame_t frameP, sub_frame_t subfr
}
}
void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP,unsigned char Msg3_subframe)
void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
{
int CC_id;
......
......@@ -403,7 +403,7 @@ uint8_t get_Msg3harqpid(COMMON_channels_t *cc,
}
int is_UL_subframe(COMMON_channels_t *ccP,uint8_t subframeP)
int is_UL_sf(COMMON_channels_t *ccP,uint8_t subframeP)
{
// if FDD return dummy value
......
......@@ -33,22 +33,33 @@
* @{
*/
/** \fn void schedule_mib(module_id_t module_idP,frame_t frameP,sub_frame_t subframe);
\brief MIB scheduling for PBCH. This function requests the MIB from RRC and provides it to L1.
@param Mod_id Instance ID of eNB
@param frame Frame index
@param subframe Subframe number on which to act
*/
/** \fn void schedule_RA(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,uint8_t Msg3_subframe,unsigned int *nprb);
void schedule_mib(module_id_t module_idP,
frame_t frameP,
sub_frame_t subframeP);
/** \fn void schedule_RA(module_id_t module_idP,frame_t frameP,sub_frame_t subframe);
\brief First stage of Random-Access Scheduling. Loops over the RA_templates and checks if RAR, Msg3 or its retransmission are to be scheduled in the subframe. It returns the total number of PRB used for RA SDUs. For Msg3 it retrieves the L3msg from RRC and fills the appropriate buffers. For the others it just computes the number of PRBs. Each DCI uses 3 PRBs (format 1A)
for the message.
@param Mod_id Instance ID of eNB
@param frame Frame index
@param subframe Subframe number on which to act
*/
void schedule_RA(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,uint8_t Msg3_subframe);
void schedule_RA(module_id_t module_idP,frame_t frameP,sub_frame_t subframe);
/** \brief First stage of SI Scheduling. Gets a SI SDU from RRC if available and computes the MCS required to transport it as a function of the SDU length. It assumes a length less than or equal to 64 bytes (MCS 6, 3 PRBs).
@param Mod_id Instance ID of eNB
@param frame Frame index
@param subframe Subframe number on which to act
@param Msg3_subframe Subframe where Msg3 will be transmitted
*/
void schedule_SI(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP);
......
......@@ -721,31 +721,40 @@ void kill_eNB_proc(int inst) {
LOG_I(PHY, "Killing TX CC_id %d inst %d\n", CC_id, inst );
proc_rxtx[0].instance_cnt_rxtx = 0; // FIXME data race!
proc_rxtx[1].instance_cnt_rxtx = 0; // FIXME data race!
if (eNB->single_thread_flag==0) {
proc_rxtx[0].instance_cnt_rxtx = 0; // FIXME data race!
proc_rxtx[1].instance_cnt_rxtx = 0; // FIXME data race!
pthread_cond_signal( &proc_rxtx[0].cond_rxtx );
pthread_cond_signal( &proc_rxtx[1].cond_rxtx );
}
proc->instance_cnt_prach = 0;
pthread_cond_signal( &proc_rxtx[0].cond_rxtx );
pthread_cond_signal( &proc_rxtx[1].cond_rxtx );
pthread_cond_signal( &proc->cond_prach );
pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx);
pthread_join( proc->pthread_prach, (void**)&status );
LOG_I(PHY, "Destroying prach mutex/cond\n");
pthread_mutex_destroy( &proc->mutex_prach );
pthread_cond_destroy( &proc->cond_prach );
#ifdef Rel14
proc->instance_cnt_prach_br = 0;
pthread_cond_signal( &proc->cond_prach_br );
pthread_join( proc->pthread_prach_br, (void**)&status );
pthread_mutex_destroy( &proc->mutex_prach_br );
pthread_cond_destroy( &proc->cond_prach_br );
#endif
LOG_I(PHY, "Destroying UL_INFO mutex\n");
pthread_mutex_destroy(&eNB->UL_INFO_mutex);
int i;
for (i=0;i<2;i++) {
pthread_join( proc_rxtx[i].pthread_rxtx, (void**)&status );
pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx );
pthread_cond_destroy( &proc_rxtx[i].cond_rxtx );
if (eNB->single_thread_flag==0) {
for (i=0;i<2;i++) {
LOG_I(PHY, "Joining rxtx[%d] mutex/cond\n");
pthread_join( proc_rxtx[i].pthread_rxtx, (void**)&status );
LOG_I(PHY, "Destroying rxtx[%d] mutex/cond\n");
pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx );
pthread_cond_destroy( &proc_rxtx[i].cond_rxtx );
}
}
}
}
......@@ -854,8 +863,11 @@ void init_eNB_afterRU() {
AssertFatal(eNB->num_RU>0,"Number of RU attached to eNB %d is zero\n",eNB->Mod_id);
LOG_I(PHY,"Mapping RX ports from %d RUs to eNB %d\n",eNB->num_RU,eNB->Mod_id);
eNB->frame_parms.nb_antennas_rx = 0;
eNB->prach_vars.rxsigF = (int16_t*)malloc16(64*sizeof(int16_t*));
eNB->prach_vars.rxsigF[0] = (int16_t*)malloc16(64*sizeof(int16_t*));
#ifdef Rel14
for (int ce_level=0;ce_level<4;ce_level++)
eNB->prach_vars_br.rxsigF[ce_level] = (int16_t*)malloc16(64*sizeof(int16_t*));
#endif
for (ru_id=0,aa=0;ru_id<eNB->num_RU;ru_id++) {
eNB->frame_parms.nb_antennas_rx += eNB->RU_list[ru_id]->nb_rx;
......@@ -877,12 +889,6 @@ void init_eNB_afterRU() {
"inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,eNB->frame_parms.nb_antennas_rx);
LOG_I(PHY,"inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,eNB->frame_parms.nb_antennas_rx);
AssertFatal(eNB->frame_parms.nb_antennas_rx <= sizeof(eNB->prach_vars.prach_ifft) / sizeof(eNB->prach_vars.prach_ifft[0]),
"nb_antennas_rx too large");
for (i=0; i<eNB->frame_parms.nb_antennas_rx; i++) {
eNB->prach_vars.prach_ifft[i] = (int16_t*)malloc16_clear(1024*2*sizeof(int16_t));
LOG_D(PHY,"[INIT] prach_vars->prach_ifft[%d] = %p\n",i,eNB->prach_vars.prach_ifft[i]);
}
init_transport(eNB);
init_precoding_weights(RC.eNB[inst][CC_id]);
}
......
......@@ -133,6 +133,8 @@ int connect_rau(RU_t *ru);
/*************************************************************/
/* Functions to attach and configure RRU */
extern void wait_eNBs();
int attach_rru(RU_t *ru) {
ssize_t msg_len,len;
......@@ -626,7 +628,7 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *subframe) {
if ((frame_tx == 0)&&(subframe_tx == 0)) proc->frame_tx_unwrap += 1024;
proc->timestamp_tx = (((frame_tx + proc->frame_tx_unwrap) * 10) + subframe_tx) * fp->samples_per_tti;
LOG_D(PHY,"RU %d/%d TST %llu, frame %d, subframe %d\n",ru->idx,0,proc->timestamp_tx,frame_tx,subframe_tx);
LOG_D(PHY,"RU %d/%d TST %llu, frame %d, subframe %d\n",ru->idx,0,(long long unsigned int)proc->timestamp_tx,frame_tx,subframe_tx);
// dump VCD output for first RU in list
if (ru == RC.ru[0]) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame_tx );
......@@ -680,33 +682,53 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
void *rxp[ru->nb_rx];
unsigned int rxs;
int i;
openair0_timestamp ts,old_ts;
for (i=0; i<ru->nb_rx; i++)
rxp[i] = (void*)&ru->common.rxdata[i][*subframe*fp->samples_per_tti];
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 );
old_ts = proc->timestamp_rx;
rxs = ru->rfdevice.trx_read_func(&ru->rfdevice,
&(proc->timestamp_rx),
&ts,
rxp,
fp->samples_per_tti,
ru->nb_rx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
if (proc->first_rx == 1)
proc->timestamp_rx = ts-ru->ts_offset;
if (rxs != fp->samples_per_tti)
LOG_E(PHY,"rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_tti,rxs);
if (proc->first_rx == 1) {
ru->ts_offset = proc->timestamp_rx;
proc->frame_rx = ((proc->timestamp_rx-ru->ts_offset) / (fp->samples_per_tti*10))&1023;
proc->subframe_rx = ((proc->timestamp_rx-ru->ts_offset) / fp->samples_per_tti)%10;
proc->timestamp_rx = 0;
}
else {
if (proc->timestamp_rx - old_ts != fp->samples_per_tti) {
LOG_I(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_tti,ru->ts_offset);
ru->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_tti);
proc->timestamp_rx = ts-ru->ts_offset;
}
}
proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023;
proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10;
// synchronize first reception to frame 0 subframe 0
proc->timestamp_tx = proc->timestamp_rx+(4*fp->samples_per_tti);
proc->subframe_tx = (proc->subframe_rx+4)%10;
proc->frame_tx = (proc->subframe_rx>5) ? (proc->frame_rx+1)&1023 : proc->frame_rx;
LOG_D(PHY,"RU %d/%d TS %llu (off %d), frame %d, subframe %d\n",ru->idx, 0, proc->timestamp_rx,ru->ts_offset,proc->frame_rx,proc->subframe_rx);
LOG_D(PHY,"RU %d/%d TS %llu (off %d), frame %d, subframe %d\n",
ru->idx,
0,
(unsigned long long int)proc->timestamp_rx,
(int)ru->ts_offset,proc->frame_rx,proc->subframe_rx);
// dump VCD output for first RU in list
if (ru == RC.ru[0]) {
......@@ -752,30 +774,56 @@ void tx_rf(RU_t *ru) {
unsigned int txs;
int i;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_tx-ru->openair0_cfg.tx_sample_advance)&0xffffffff );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
// prepare tx buffer pointers
for (i=0; i<ru->nb_tx; i++)
txp[i] = (void*)&ru->common.txdata[i][proc->subframe_tx*fp->samples_per_tti];
txs = ru->rfdevice.trx_write_func(&ru->rfdevice,
proc->timestamp_tx-ru->openair0_cfg.tx_sample_advance,
txp,
fp->samples_per_tti,
ru->nb_tx,
1);
LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n",ru->idx,
proc->timestamp_tx,proc->frame_tx,proc->frame_tx_unwrap,proc->subframe_tx,proc);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
lte_subframe_t SF_type = subframe_select(fp,proc->subframe_tx%10);
lte_subframe_t prevSF_type = subframe_select(fp,(proc->subframe_tx+9)%10);
lte_subframe_t nextSF_type = subframe_select(fp,(proc->subframe_tx+1)%10);
if ((SF_type == SF_DL) ||
(SF_type == SF_S)) {
for (i=0; i<ru->nb_tx; i++)
txp[i] = (void*)&ru->common.txdata[i][proc->subframe_tx*fp->samples_per_tti];
int siglen=fp->samples_per_tti,flags=1;
if (SF_type == SF_S) {
siglen = fp->dl_symbols_in_S_subframe*(fp->ofdm_symbol_size+fp->nb_prefix_samples0);
flags=3; // end of burst
}
if ((fp->frame_type == TDD) &&
(SF_type == SF_DL)&&
(prevSF_type == SF_UL) &&
(nextSF_type == SF_DL))
flags = 2; // start of burst
if ((fp->frame_type == TDD) &&
(SF_type == SF_DL)&&
(prevSF_type == SF_UL) &&
(nextSF_type == SF_UL))
flags = 4; // start of burst and end of burst (only one DL SF between two UL)
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_tx-ru->openair0_cfg.tx_sample_advance)&0xffffffff );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
// prepare tx buffer pointers
txs = ru->rfdevice.trx_write_func(&ru->rfdevice,
proc->timestamp_tx+ru->ts_offset-ru->openair0_cfg.tx_sample_advance,
txp,
siglen,
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,
proc->timestamp_tx,proc->frame_tx,proc->frame_tx_unwrap,proc->subframe_tx,proc);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
if (txs != fp->samples_per_tti) {
LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, fp->samples_per_tti);
exit_fun( "problem transmitting samples" );
}
if (txs != fp->samples_per_tti) {
LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, fp->samples_per_tti);
exit_fun( "problem transmitting samples" );
}
}
}
......
......@@ -1691,8 +1691,8 @@ int main( int argc, char **argv )
if (RC.nb_L1_inst > 0) {
printf("Initializing eNB threads\n");
init_eNB(single_thread_flag,wait_for_sync);
for (inst=0;inst<RC.nb_L1_inst;inst++)
for (CC_id=0;CC_id<RC.nb_L1_CC[inst];CC_id++) phy_init_lte_eNB(RC.eNB[inst][CC_id],0,0);
// for (inst=0;inst<RC.nb_L1_inst;inst++)
// for (CC_id=0;CC_id<RC.nb_L1_CC[inst];CC_id++) phy_init_lte_eNB(RC.eNB[inst][CC_id],0,0);
}
wait_eNBs();
......
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