To minimize migration effort, we follow the logic of legacy macro Rel10 and Rel14 used for conditional compilation of current code. In the future, they might be changed to accommodate finer software configuration, e.g. MAKE_VERSION(12,2,0) or MAKE_VERSION(13,1,0) .... etc.
354 lines
15 KiB
C
354 lines
15 KiB
C
/*
|
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership.
|
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
|
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
|
* except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.openairinterface.org/?page_id=698
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*-------------------------------------------------------------------------------
|
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
|
* contact@openairinterface.org
|
|
*/
|
|
|
|
/*! \file eNB_scheduler_dlsch.c
|
|
* \brief procedures related to eNB for the DLSCH transport channel
|
|
* \author Navid Nikaein and Raymond Knopp
|
|
* \date 2010 - 2014
|
|
* \email: navid.nikaein@eurecom.fr
|
|
* \version 1.0
|
|
* @ingroup _mac
|
|
|
|
*/
|
|
|
|
#include "assertions.h"
|
|
#include "PHY/defs_eNB.h"
|
|
#include "PHY/phy_extern.h"
|
|
#include "PHY/LTE_TRANSPORT/transport_common_proto.h"
|
|
|
|
#include "SCHED/sched_eNB.h"
|
|
|
|
#include "LAYER2/MAC/mac.h"
|
|
#include "LAYER2/MAC/mac_proto.h"
|
|
#include "LAYER2/MAC/mac_extern.h"
|
|
#include "UTIL/LOG/log.h"
|
|
#include "UTIL/LOG/vcd_signal_dumper.h"
|
|
#include "UTIL/OPT/opt.h"
|
|
#include "OCG.h"
|
|
#include "OCG_extern.h"
|
|
|
|
#include "SIMULATION/TOOLS/sim.h" // for taus
|
|
|
|
#include "T.h"
|
|
|
|
extern RAN_CONTEXT_t RC;
|
|
|
|
//------------------------------------------------------------------------------
|
|
void
|
|
schedule_ue_spec_phy_test(
|
|
module_id_t module_idP,
|
|
frame_t frameP,
|
|
sub_frame_t subframeP,
|
|
int* mbsfn_flag
|
|
)
|
|
//------------------------------------------------------------------------------
|
|
{
|
|
uint8_t CC_id;
|
|
int UE_id=0;
|
|
uint16_t N_RB_DL;
|
|
uint16_t TBS;
|
|
uint16_t nb_rb;
|
|
|
|
unsigned char harq_pid = subframeP%5;
|
|
uint16_t rnti = 0x1235;
|
|
uint32_t rb_alloc = 0x1FFFFFFF;
|
|
int32_t tpc = 1;
|
|
int32_t mcs = 28;
|
|
int32_t cqi = 15;
|
|
int32_t ndi = subframeP/5;
|
|
int32_t dai = 0;
|
|
|
|
eNB_MAC_INST *eNB = RC.mac[module_idP];
|
|
COMMON_channels_t *cc = eNB->common_channels;
|
|
nfapi_dl_config_request_body_t *dl_req;
|
|
nfapi_dl_config_request_pdu_t *dl_config_pdu;
|
|
|
|
N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth);
|
|
|
|
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
|
|
LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n",CC_id);
|
|
|
|
dl_req = &eNB->DL_req[CC_id].dl_config_request_body;
|
|
|
|
if (mbsfn_flag[CC_id]>0)
|
|
continue;
|
|
|
|
nb_rb = conv_nprb(0,rb_alloc,N_RB_DL);
|
|
//printf("////////////////////////////////////*************************nb_rb = %d\n",nb_rb);
|
|
TBS = get_TBS_DL(mcs,nb_rb);
|
|
|
|
LOG_D(PHY,"schedule_ue_spec_phy_test: subframe %d/%d: nb_rb=%d, TBS=%d, mcs=%d (rb_alloc=%x, N_RB_DL=%d)\n",frameP,subframeP,nb_rb,TBS,mcs,rb_alloc,N_RB_DL);
|
|
|
|
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
|
|
memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
|
|
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
|
|
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu));
|
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1;
|
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP,CC_id),cqi,format1);
|
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0;
|
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0;
|
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = rb_alloc;
|
|
|
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti;
|
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications
|
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power
|
|
|
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid;
|
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; // dont adjust power when retransmitting
|
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = ndi;
|
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs;
|
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0;
|
|
//deactivate second codeword
|
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0;
|
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1;
|
|
|
|
if (cc[CC_id].tdd_Config != NULL) { //TDD
|
|
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = dai;
|
|
LOG_D(MAC,"[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n",
|
|
module_idP,CC_id,harq_pid,dai,mcs);
|
|
} else {
|
|
LOG_D(MAC,"[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n",
|
|
module_idP,CC_id,harq_pid,mcs);
|
|
|
|
}
|
|
LOG_D(MAC,"Checking feasibility pdu %d (new sdu)\n",dl_req->number_pdu);
|
|
if (!CCE_allocation_infeasible(module_idP,CC_id,1,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,rnti)) {
|
|
|
|
|
|
//ue_sched_ctl->round[CC_id][harq_pid] = 0;
|
|
dl_req->number_dci++;
|
|
dl_req->number_pdu++;
|
|
|
|
// Toggle NDI for next time
|
|
/*
|
|
LOG_D(MAC,"CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n",
|
|
CC_id, frameP,subframeP,UE_id,
|
|
rnti,harq_pid,UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]);
|
|
|
|
UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]=1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid];
|
|
UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs;
|
|
UE_list->UE_template[CC_id][UE_id].oldmcs2[harq_pid] = 0;
|
|
AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated!=NULL,"physicalConfigDedicated is NULL\n");
|
|
AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated!=NULL,"physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n");
|
|
*/
|
|
|
|
|
|
|
|
fill_nfapi_dlsch_config(eNB,
|
|
dl_req,
|
|
TBS,
|
|
eNB->pdu_index[CC_id],
|
|
rnti,
|
|
0, // type 0 allocation from 7.1.6 in 36.213
|
|
0, // virtual_resource_block_assignment_flag
|
|
rb_alloc, // resource_block_coding
|
|
getQm(mcs),
|
|
0, // redundancy version
|
|
1, // transport blocks
|
|
0, // transport block to codeword swap flag
|
|
cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme
|
|
1, // number of layers
|
|
1, // number of subbands
|
|
// uint8_t codebook_index,
|
|
4, // UE category capacity
|
|
PDSCH_ConfigDedicated__p_a_dB0,
|
|
0, // delta_power_offset for TM5
|
|
0, // ngap
|
|
0, // nprb
|
|
cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode
|
|
0, //number of PRBs treated as one subband, not used here
|
|
0 // number of beamforming vectors, not used here
|
|
);
|
|
|
|
eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_id].tx_request_body,
|
|
(frameP*10)+subframeP,
|
|
TBS,
|
|
eNB->pdu_index[CC_id],
|
|
eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0]);
|
|
}
|
|
else {
|
|
LOG_W(MAC,"[eNB_scheduler_phytest] DCI allocation infeasible!\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
|
|
{
|
|
uint16_t first_rb[MAX_NUM_CCs];
|
|
int UE_id = 0;
|
|
uint8_t aggregation = 2;
|
|
rnti_t rnti = 0x1235;
|
|
uint8_t mcs = 0;
|
|
uint8_t harq_pid = 0;
|
|
uint32_t cqi_req = 0,cshift,ndi,tpc = 1;
|
|
int32_t normalized_rx_power;
|
|
int32_t target_rx_power= 178;
|
|
int CC_id = 0;
|
|
int nb_rb = 96;
|
|
eNB_MAC_INST *eNB = RC.mac[module_idP];
|
|
COMMON_channels_t *cc = eNB->common_channels;
|
|
UE_list_t *UE_list=&eNB->UE_list;
|
|
UE_TEMPLATE *UE_template;
|
|
UE_sched_ctrl *UE_sched_ctrl;
|
|
int sched_frame=frameP;
|
|
int sched_subframe = (subframeP+4)%10;
|
|
|
|
if (sched_subframe<subframeP) sched_frame++;
|
|
|
|
nfapi_hi_dci0_request_body_t *hi_dci0_req = &eNB->HI_DCI0_req[CC_id].hi_dci0_request_body;
|
|
nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu;
|
|
|
|
//nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req->ul_config_pdu_list[0];;
|
|
nfapi_ul_config_request_body_t *ul_req = &eNB->UL_req[CC_id].ul_config_request_body;
|
|
|
|
|
|
eNB->UL_req[CC_id].sfn_sf = (sched_frame<<4) + sched_subframe;
|
|
eNB->HI_DCI0_req[CC_id].sfn_sf = (frameP<<4)+subframeP;
|
|
|
|
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
|
|
//rnti = UE_RNTI(module_idP,UE_id);
|
|
//leave out first RB for PUCCH
|
|
first_rb[CC_id] = 1;
|
|
// loop over all active UEs
|
|
|
|
// if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel
|
|
|
|
UE_template = &UE_list->UE_template[CC_id][UE_id];
|
|
UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id];
|
|
harq_pid = subframe2harqpid(&cc[CC_id],sched_frame,sched_subframe);
|
|
|
|
LOG_D(MAC,"Scheduling for frame %d, subframe %d => harq_pid %d\n",sched_frame,sched_subframe,harq_pid);
|
|
|
|
RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->TBS_UL[harq_pid];
|
|
|
|
|
|
|
|
//power control
|
|
//compute the expected ULSCH RX power (for the stats)
|
|
|
|
// this is the normalized RX power and this should be constant (regardless of mcs
|
|
normalized_rx_power = UE_sched_ctrl->pusch_snr[CC_id];
|
|
|
|
// new transmission
|
|
|
|
ndi = 1-UE_template->oldNDI_UL[harq_pid];
|
|
UE_template->oldNDI_UL[harq_pid]=ndi;
|
|
UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power=normalized_rx_power;
|
|
UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power=target_rx_power;
|
|
UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1 = mcs;
|
|
UE_template->mcs_UL[harq_pid] = mcs;//cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS
|
|
UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = mcs;
|
|
// buffer_occupancy = UE_template->ul_total_buffer;
|
|
|
|
|
|
|
|
UE_template->TBS_UL[harq_pid] = get_TBS_UL(mcs,nb_rb);
|
|
UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += nb_rb;
|
|
UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = get_TBS_UL(mcs,nb_rb);
|
|
// buffer_occupancy -= TBS;
|
|
|
|
|
|
|
|
// bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB)
|
|
//store for possible retransmission
|
|
UE_template->nb_rb_ul[harq_pid] = nb_rb;
|
|
UE_template->first_rb_ul[harq_pid] = first_rb[CC_id];
|
|
|
|
UE_sched_ctrl->ul_scheduled |= (1<<harq_pid);
|
|
|
|
// adjust total UL buffer status by TBS, wait for UL sdus to do final update
|
|
//UE_template->ul_total_buffer = UE_template->TBS_UL[harq_pid];
|
|
// Cyclic shift for DM RS
|
|
cshift = 0;// values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1)
|
|
// save it for a potential retransmission
|
|
UE_template->cshift[harq_pid] = cshift;
|
|
|
|
hi_dci0_pdu = &hi_dci0_req->hi_dci0_pdu_list[eNB->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_dci+eNB->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_hi];
|
|
memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t));
|
|
hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE;
|
|
hi_dci0_pdu->pdu_size = 2+sizeof(nfapi_hi_dci0_dci_pdu);
|
|
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = NFAPI_UL_DCI_FORMAT_0;
|
|
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation;
|
|
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti;
|
|
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = 6000;
|
|
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start = first_rb[CC_id];
|
|
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.number_of_resource_block = nb_rb;
|
|
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = mcs;
|
|
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = cshift;
|
|
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag = 0;
|
|
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.new_data_indication_1 = ndi;
|
|
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc;
|
|
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request = cqi_req;
|
|
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = UE_template->DAI_ul[sched_subframe];
|
|
|
|
|
|
eNB->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_dci++;
|
|
|
|
|
|
// Add UL_config PDUs
|
|
fill_nfapi_ulsch_config_request_rel8(&ul_req->ul_config_pdu_list[ul_req->number_of_pdus],
|
|
cqi_req,
|
|
cc,
|
|
0,//UE_template->physicalConfigDedicated,
|
|
get_tmode(module_idP,CC_id,UE_id),
|
|
eNB->ul_handle,
|
|
rnti,
|
|
first_rb[CC_id], // resource_block_start
|
|
nb_rb, // number_of_resource_blocks
|
|
mcs,
|
|
cshift, // cyclic_shift_2_for_drms
|
|
0, // frequency_hopping_enabled_flag
|
|
0, // frequency_hopping_bits
|
|
ndi, // new_data_indication
|
|
0, // redundancy_version
|
|
harq_pid, // harq_process_number
|
|
0, // ul_tx_mode
|
|
0, // current_tx_nb
|
|
0, // n_srs
|
|
get_TBS_UL(mcs,nb_rb)
|
|
);
|
|
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
|
if (UE_template->rach_resource_type>0) { // This is a BL/CE UE allocation
|
|
fill_nfapi_ulsch_config_request_emtc(&ul_req->ul_config_pdu_list[ul_req->number_of_pdus],
|
|
UE_template->rach_resource_type>2 ? 2 : 1,
|
|
1, //total_number_of_repetitions
|
|
1, //repetition_number
|
|
(frameP*10)+subframeP);
|
|
}
|
|
#endif
|
|
ul_req->number_of_pdus = 1;
|
|
eNB->ul_handle++;
|
|
|
|
|
|
|
|
add_ue_ulsch_info(module_idP,
|
|
CC_id,
|
|
UE_id,
|
|
subframeP,
|
|
S_UL_SCHEDULED);
|
|
|
|
// increment first rb for next UE allocation
|
|
first_rb[CC_id]+= nb_rb;
|
|
|
|
|
|
} // loop of CC_id
|
|
}
|