From 362f584d6674aa3c6b9cd613d55f5851acaad202 Mon Sep 17 00:00:00 2001 From: Raymond Knopp <raymond.knopp@eurecom.fr> Date: Thu, 14 Sep 2017 07:15:49 -0700 Subject: [PATCH] integration of remaining nFAPI messages --- common/ran_context.h | 2 + common/utils/itti/intertask_interface.c | 6 +- openair1/PHY/INIT/lte_init.c | 432 +-- openair1/PHY/LTE_TRANSPORT/dci.c | 4 +- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 313 +- openair1/PHY/LTE_TRANSPORT/defs.h | 33 +- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 10 +- openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c | 4 +- openair1/PHY/LTE_TRANSPORT/if4_tools.c | 15 +- openair1/PHY/LTE_TRANSPORT/phich.c | 142 +- openair1/PHY/LTE_TRANSPORT/proto.h | 12 +- openair1/PHY/LTE_TRANSPORT/pucch.c | 28 +- openair1/PHY/LTE_TRANSPORT/rar_tools.c | 23 +- openair1/PHY/LTE_TRANSPORT/uci_tools.c | 55 - openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c | 55 +- .../PHY/LTE_TRANSPORT/ulsch_demodulation.c | 381 +-- openair1/PHY/TOOLS/lte_phy_scope.c | 6 +- openair1/PHY/defs.h | 11 +- openair1/PHY/impl_defs_lte.h | 18 + openair1/SCHED/phy_procedures_lte_eNb.c | 2919 ++++++++--------- openair1/SCHED/phy_procedures_lte_ue.c | 37 +- openair1/SCHED/pucch_pc.c | 3 + openair2/ENB_APP/enb_config.c | 7 +- openair2/LAYER2/MAC/config.c | 25 +- openair2/LAYER2/MAC/defs.h | 63 +- openair2/LAYER2/MAC/eNB_scheduler.c | 372 ++- openair2/LAYER2/MAC/eNB_scheduler_RA.c | 523 +-- openair2/LAYER2/MAC/eNB_scheduler_bch.c | 17 +- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 136 +- .../LAYER2/MAC/eNB_scheduler_primitives.c | 1532 ++++++++- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 130 +- openair2/LAYER2/MAC/main.c | 9 + openair2/LAYER2/MAC/pre_processor.c | 40 +- openair2/LAYER2/MAC/proto.h | 100 +- openair2/LAYER2/MAC/rar_tools.c | 56 +- openair2/PHY_INTERFACE/IF_Module.c | 74 +- openair2/PHY_INTERFACE/IF_Module.h | 16 +- openair2/RRC/LITE/L2_interface.c | 11 +- openair2/RRC/LITE/MESSAGES/asn1_msg.c | 4 +- openair2/RRC/LITE/rrc_common.c | 63 - openair2/RRC/LITE/rrc_eNB.c | 38 +- targets/COMMON/create_tasks.c | 10 +- .../CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf | 4 +- targets/RT/USER/lte-enb.c | 4 + 44 files changed, 4652 insertions(+), 3091 deletions(-) diff --git a/common/ran_context.h b/common/ran_context.h index 625e029382..4e25729c86 100644 --- a/common/ran_context.h +++ b/common/ran_context.h @@ -56,6 +56,8 @@ typedef struct { int *nb_CC; /// Number of MACRLC instances in this node int nb_macrlc_inst; + /// Number of component carriers per instance in this node + int *nb_mac_CC; /// Number of L1 instances in this node int nb_L1_inst; /// Number of Component Carriers per instance in this node diff --git a/common/utils/itti/intertask_interface.c b/common/utils/itti/intertask_interface.c index d70a6386b9..5ffb17c234 100644 --- a/common/utils/itti/intertask_interface.c +++ b/common/utils/itti/intertask_interface.c @@ -623,7 +623,7 @@ static inline void itti_receive_msg_internal_event_fd(task_id_t task_id, uint8_t read_ret = read (itti_desc.threads[thread_id].task_event_fd, &sem_counter, sizeof(sem_counter)); AssertFatal (read_ret == sizeof(sem_counter), "Read from task message FD (%d) failed (%d/%d)!\n", thread_id, (int) read_ret, (int) sizeof(sem_counter)); - + printf("sem_counter %d task %d\n", (int)sem_counter, task_id); if (lfds611_queue_dequeue (itti_desc.tasks[task_id].message_queue, (void **) &message) == 0) { /* No element in list -> this should not happen */ AssertFatal (0, "No message in queue for task %d while there are %d events and some for the messages queue!\n", task_id, epoll_ret); @@ -631,9 +631,13 @@ static inline void itti_receive_msg_internal_event_fd(task_id_t task_id, uint8_t AssertFatal(message != NULL, "Message from message queue is NULL!\n"); *received_msg = message->msg; + + printf("ITTI: message %s\n", ITTI_MSG_NAME(message->msg)); + result = itti_free (ITTI_MSG_ORIGIN_ID(*received_msg), message); AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + /* Mark that the event has been processed */ itti_desc.threads[thread_id].events[i].events &= ~EPOLLIN; return; diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index faf884429c..3a7eab5a5d 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -153,91 +153,93 @@ void phy_config_request(PHY_Config_t *phy_config) { RC.eNB[Mod_id][CC_id]->X_u); #ifdef Rel14 - fp->prach_emtc_config_common.prach_Config_enabled=1; - - fp->prach_emtc_config_common.rootSequenceIndex = cfg->emtc_config.prach_catm_root_sequence_index.value; - - fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag = cfg->emtc_config.prach_catm_high_speed_flag.value; - fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig = cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.value; - - // CE Level 3 parameters - fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[3] = cfg->emtc_config.prach_ce_level_3_enable.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[3] = cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[3] = cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.value; - AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[3]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[3], - "prach_starting_subframe_periodicity[3] < prach_numPetitionPerPreambleAttempt[3]\n"); - - - fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3] = cfg->emtc_config.prach_ce_level_3_configuration_index.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[3] = cfg->emtc_config.prach_ce_level_3_frequency_offset.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[3] = cfg->emtc_config.prach_ce_level_3_hopping_enable.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[3] = cfg->emtc_config.prach_ce_level_3_hopping_offset.value; - if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[3] == 1) - compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex, - fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3], - fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, - fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag, - fp->frame_type, - RC.eNB[Mod_id][CC_id]->X_u_br[3]); - - // CE Level 2 parameters - fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[2] = cfg->emtc_config.prach_ce_level_2_enable.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[2] = cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[2] = cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.value; - AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[2]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[2], - "prach_starting_subframe_periodicity[2] < prach_numPetitionPerPreambleAttempt[2]\n"); - fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[2] = cfg->emtc_config.prach_ce_level_2_configuration_index.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[2] = cfg->emtc_config.prach_ce_level_2_frequency_offset.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[2] = cfg->emtc_config.prach_ce_level_2_hopping_enable.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[2] = cfg->emtc_config.prach_ce_level_2_hopping_offset.value; - if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[2] == 1) - compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex, - fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3], - fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, - fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag, - fp->frame_type, - RC.eNB[Mod_id][CC_id]->X_u_br[2]); - - // CE Level 1 parameters - fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[1] = cfg->emtc_config.prach_ce_level_1_enable.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[1] = cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[1] = cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.value; - AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[1]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[1], - "prach_starting_subframe_periodicity[1] < prach_numPetitionPerPreambleAttempt[1]\n"); - - fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[1] = cfg->emtc_config.prach_ce_level_1_configuration_index.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[1] = cfg->emtc_config.prach_ce_level_1_frequency_offset.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[1] = cfg->emtc_config.prach_ce_level_1_hopping_enable.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[1] = cfg->emtc_config.prach_ce_level_1_hopping_offset.value; - if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[1] == 1) - compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex, - fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3], - fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, - fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag, - fp->frame_type, - RC.eNB[Mod_id][CC_id]->X_u_br[1]); + if (cfg->emtc_config.prach_ce_level_0_enable.value == 1) { + fp->prach_emtc_config_common.prach_Config_enabled=1; + + fp->prach_emtc_config_common.rootSequenceIndex = cfg->emtc_config.prach_catm_root_sequence_index.value; + + fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag = cfg->emtc_config.prach_catm_high_speed_flag.value; + fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig = cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.value; + + // CE Level 3 parameters + fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[3] = cfg->emtc_config.prach_ce_level_3_enable.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[3] = cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[3] = cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.value; + AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[3]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[3], + "prach_starting_subframe_periodicity[3] < prach_numPetitionPerPreambleAttempt[3]\n"); + + + fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3] = cfg->emtc_config.prach_ce_level_3_configuration_index.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[3] = cfg->emtc_config.prach_ce_level_3_frequency_offset.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[3] = cfg->emtc_config.prach_ce_level_3_hopping_enable.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[3] = cfg->emtc_config.prach_ce_level_3_hopping_offset.value; + if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[3] == 1) + compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex, + fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3], + fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, + fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag, + fp->frame_type, + RC.eNB[Mod_id][CC_id]->X_u_br[3]); + + // CE Level 2 parameters + fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[2] = cfg->emtc_config.prach_ce_level_2_enable.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[2] = cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[2] = cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.value; + AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[2]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[2], + "prach_starting_subframe_periodicity[2] < prach_numPetitionPerPreambleAttempt[2]\n"); + fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[2] = cfg->emtc_config.prach_ce_level_2_configuration_index.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[2] = cfg->emtc_config.prach_ce_level_2_frequency_offset.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[2] = cfg->emtc_config.prach_ce_level_2_hopping_enable.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[2] = cfg->emtc_config.prach_ce_level_2_hopping_offset.value; + if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[2] == 1) + compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex, + fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3], + fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, + fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag, + fp->frame_type, + RC.eNB[Mod_id][CC_id]->X_u_br[2]); + + // CE Level 1 parameters + fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[1] = cfg->emtc_config.prach_ce_level_1_enable.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[1] = cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[1] = cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.value; + AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[1]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[1], + "prach_starting_subframe_periodicity[1] < prach_numPetitionPerPreambleAttempt[1]\n"); + + fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[1] = cfg->emtc_config.prach_ce_level_1_configuration_index.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[1] = cfg->emtc_config.prach_ce_level_1_frequency_offset.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[1] = cfg->emtc_config.prach_ce_level_1_hopping_enable.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[1] = cfg->emtc_config.prach_ce_level_1_hopping_offset.value; + if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[1] == 1) + compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex, + fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3], + fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, + fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag, + fp->frame_type, + RC.eNB[Mod_id][CC_id]->X_u_br[1]); - // CE Level 0 parameters - fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0] = cfg->emtc_config.prach_ce_level_0_enable.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0] = cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0] = cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.value; - AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0], - "prach_starting_subframe_periodicity[0] %d < prach_numPetitionPerPreambleAttempt[0] %d\n", - fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0], - fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]); - AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0] > 0, - "prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]==0\n"); - fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[0] = cfg->emtc_config.prach_ce_level_0_configuration_index.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[0] = cfg->emtc_config.prach_ce_level_0_frequency_offset.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[0] = cfg->emtc_config.prach_ce_level_0_hopping_enable.value; - fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[0] = cfg->emtc_config.prach_ce_level_0_hopping_offset.value; - if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0] == 1) - compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex, - fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3], - fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, - fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag, - fp->frame_type, - RC.eNB[Mod_id][CC_id]->X_u_br[0]); + // CE Level 0 parameters + fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0] = cfg->emtc_config.prach_ce_level_0_enable.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0] = cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0] = cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.value; + AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0], + "prach_starting_subframe_periodicity[0] %d < prach_numPetitionPerPreambleAttempt[0] %d\n", + fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0], + fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]); + AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0] > 0, + "prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]==0\n"); + fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[0] = cfg->emtc_config.prach_ce_level_0_configuration_index.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[0] = cfg->emtc_config.prach_ce_level_0_frequency_offset.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[0] = cfg->emtc_config.prach_ce_level_0_hopping_enable.value; + fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[0] = cfg->emtc_config.prach_ce_level_0_hopping_offset.value; + if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0] == 1) + compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex, + fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3], + fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, + fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag, + fp->frame_type, + RC.eNB[Mod_id][CC_id]->X_u_br[0]); + } #endif @@ -264,9 +266,9 @@ void phy_config_request(PHY_Config_t *phy_config) { fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 0; fp->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0; if (cfg->uplink_reference_signal_config.uplink_rs_hopping.value == 1) - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1; + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1; if (cfg->uplink_reference_signal_config.uplink_rs_hopping.value == 2) - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 1; + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 1; LOG_I(PHY,"pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = %d\n",fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled); fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = cfg->uplink_reference_signal_config.group_assignment.value; LOG_I(PHY,"pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = %d\n",fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH); @@ -313,14 +315,14 @@ void phy_config_sib1_ue(uint8_t Mod_id,int CC_id, } /* -void phy_config_sib2_eNB(uint8_t Mod_id, - int CC_id, - RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, - ARFCN_ValueEUTRA_t *ul_CArrierFreq, - long *ul_Bandwidth, - AdditionalSpectrumEmission_t *additionalSpectrumEmission, - struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList) -{ + void phy_config_sib2_eNB(uint8_t Mod_id, + int CC_id, + RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, + ARFCN_ValueEUTRA_t *ul_CArrierFreq, + long *ul_Bandwidth, + AdditionalSpectrumEmission_t *additionalSpectrumEmission, + struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList) + { LTE_DL_FRAME_PARMS *fp = &RC.eNB[Mod_id][CC_id]->frame_parms; //LTE_eNB_UE_stats *eNB_UE_stats = RC.eNB[Mod_id][CC_id].eNB_UE_stats; @@ -347,7 +349,7 @@ void phy_config_sib2_eNB(uint8_t Mod_id, init_prach_tables(839); compute_prach_seq(&fp->prach_config_common,fp->frame_type, - RC.eNB[Mod_id][CC_id]->X_u); + RC.eNB[Mod_id][CC_id]->X_u); fp->pucch_config_common.deltaPUCCH_Shift = 1+radioResourceConfigCommon->pucch_ConfigCommon.deltaPUCCH_Shift; fp->pucch_config_common.nRB_CQI = radioResourceConfigCommon->pucch_ConfigCommon.nRB_CQI; @@ -389,15 +391,15 @@ void phy_config_sib2_eNB(uint8_t Mod_id, fp->soundingrs_ul_config_common.enabled_flag = 0; if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon.present==SoundingRS_UL_ConfigCommon_PR_setup) { - fp->soundingrs_ul_config_common.enabled_flag = 1; - fp->soundingrs_ul_config_common.srs_BandwidthConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig; - fp->soundingrs_ul_config_common.srs_SubframeConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig; - fp->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; + fp->soundingrs_ul_config_common.enabled_flag = 1; + fp->soundingrs_ul_config_common.srs_BandwidthConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig; + fp->soundingrs_ul_config_common.srs_SubframeConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig; + fp->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; - if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts) - fp->soundingrs_ul_config_common.srs_MaxUpPts = 1; - else - fp->soundingrs_ul_config_common.srs_MaxUpPts = 0; + if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts) + fp->soundingrs_ul_config_common.srs_MaxUpPts = 1; + else + fp->soundingrs_ul_config_common.srs_MaxUpPts = 0; } @@ -425,34 +427,34 @@ void phy_config_sib2_eNB(uint8_t Mod_id, // MBSFN if (mbsfn_SubframeConfigList != NULL) { - fp->num_MBSFN_config = mbsfn_SubframeConfigList->list.count; - - for (i=0; i<mbsfn_SubframeConfigList->list.count; i++) { - fp->MBSFN_config[i].radioframeAllocationPeriod = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod; - fp->MBSFN_config[i].radioframeAllocationOffset = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset; - - if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { - fp->MBSFN_config[i].fourFrames_flag = 0; - fp->MBSFN_config[i].mbsfn_SubframeConfig = mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration - LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, - fp->MBSFN_config[i].mbsfn_SubframeConfig); - } else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration - fp->MBSFN_config[i].fourFrames_flag = 1; - fp->MBSFN_config[i].mbsfn_SubframeConfig = - mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]| - (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)| - (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]<<16); - - LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, - fp->MBSFN_config[i].mbsfn_SubframeConfig); - } - } + fp->num_MBSFN_config = mbsfn_SubframeConfigList->list.count; + + for (i=0; i<mbsfn_SubframeConfigList->list.count; i++) { + fp->MBSFN_config[i].radioframeAllocationPeriod = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod; + fp->MBSFN_config[i].radioframeAllocationOffset = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset; + + if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { + fp->MBSFN_config[i].fourFrames_flag = 0; + fp->MBSFN_config[i].mbsfn_SubframeConfig = mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration + LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, + fp->MBSFN_config[i].mbsfn_SubframeConfig); + } else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration + fp->MBSFN_config[i].fourFrames_flag = 1; + fp->MBSFN_config[i].mbsfn_SubframeConfig = + mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]| + (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)| + (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]<<16); + + LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, + fp->MBSFN_config[i].mbsfn_SubframeConfig); + } + } } else - fp->num_MBSFN_config = 0; + fp->num_MBSFN_config = 0; // -} + } */ void phy_config_sib2_ue(uint8_t Mod_id,int CC_id, @@ -852,7 +854,7 @@ void phy_config_afterHO_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_id, Mobility PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti = mobilityControlInfo->newUE_Identity.buf[0]|(mobilityControlInfo->newUE_Identity.buf[1]<<8); LOG_I(PHY,"SET C-RNTI %x %x\n",PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_id]->crnti, - PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti); + PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti); } if(ho_failed) { @@ -881,67 +883,67 @@ void phy_config_meas_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index,uint8_t n } /* -void phy_config_dedicated_eNB(uint8_t Mod_id, - int CC_id, - uint16_t rnti, - struct PhysicalConfigDedicated *physicalConfigDedicated) -{ + void phy_config_dedicated_eNB(uint8_t Mod_id, + int CC_id, + uint16_t rnti, + struct PhysicalConfigDedicated *physicalConfigDedicated) + { PHY_VARS_eNB *eNB = RC.eNB[Mod_id][CC_id]; int8_t UE_id = find_ue(rnti,eNB); int i; if (UE_id == -1) { - LOG_E( PHY, "[eNB %"PRIu8"] find_ue() returns -1\n", Mod_id); - return; + LOG_E( PHY, "[eNB %"PRIu8"] find_ue() returns -1\n", Mod_id); + return; } if (physicalConfigDedicated) { - eNB->physicalConfigDedicated[UE_id] = physicalConfigDedicated; - LOG_I(PHY,"phy_config_dedicated_eNB: physicalConfigDedicated=%p\n",physicalConfigDedicated); - - if (physicalConfigDedicated->antennaInfo) { - switch(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode) { - case AntennaInfoDedicated__transmissionMode_tm1: - eNB->transmission_mode[UE_id] = 1; - break; - case AntennaInfoDedicated__transmissionMode_tm2: - eNB->transmission_mode[UE_id] = 2; - break; - case AntennaInfoDedicated__transmissionMode_tm3: - eNB->transmission_mode[UE_id] = 3; - break; - case AntennaInfoDedicated__transmissionMode_tm4: - eNB->transmission_mode[UE_id] = 4; - break; - case AntennaInfoDedicated__transmissionMode_tm5: - eNB->transmission_mode[UE_id] = 5; - break; - case AntennaInfoDedicated__transmissionMode_tm6: - eNB->transmission_mode[UE_id] = 6; - break; - case AntennaInfoDedicated__transmissionMode_tm7: - lte_gold_ue_spec_port5(eNB->lte_gold_uespec_port5_table[0],eNB->frame_parms.Nid_cell,rnti); - - for (i=0;i<eNB->num_RU;i++) eNB->RU_list[i]->do_precoding=1; - eNB->transmission_mode[UE_id] = 7; - break; - default: - LOG_E(PHY,"Unknown transmission mode!\n"); - break; - } - LOG_I(PHY,"Transmission Mode (phy_config_dedicated_eNB) %d\n",eNB->transmission_mode[UE_id]); + eNB->physicalConfigDedicated[UE_id] = physicalConfigDedicated; + LOG_I(PHY,"phy_config_dedicated_eNB: physicalConfigDedicated=%p\n",physicalConfigDedicated); + + if (physicalConfigDedicated->antennaInfo) { + switch(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode) { + case AntennaInfoDedicated__transmissionMode_tm1: + eNB->transmission_mode[UE_id] = 1; + break; + case AntennaInfoDedicated__transmissionMode_tm2: + eNB->transmission_mode[UE_id] = 2; + break; + case AntennaInfoDedicated__transmissionMode_tm3: + eNB->transmission_mode[UE_id] = 3; + break; + case AntennaInfoDedicated__transmissionMode_tm4: + eNB->transmission_mode[UE_id] = 4; + break; + case AntennaInfoDedicated__transmissionMode_tm5: + eNB->transmission_mode[UE_id] = 5; + break; + case AntennaInfoDedicated__transmissionMode_tm6: + eNB->transmission_mode[UE_id] = 6; + break; + case AntennaInfoDedicated__transmissionMode_tm7: + lte_gold_ue_spec_port5(eNB->lte_gold_uespec_port5_table[0],eNB->frame_parms.Nid_cell,rnti); + + for (i=0;i<eNB->num_RU;i++) eNB->RU_list[i]->do_precoding=1; + eNB->transmission_mode[UE_id] = 7; + break; + default: + LOG_E(PHY,"Unknown transmission mode!\n"); + break; + } + LOG_I(PHY,"Transmission Mode (phy_config_dedicated_eNB) %d\n",eNB->transmission_mode[UE_id]); - } else { - LOG_D(PHY,"[eNB %d] : Received NULL radioResourceConfigDedicated->antennaInfo from eNB %d\n",Mod_id,UE_id); - } } else { - LOG_E(PHY,"[eNB %d] Received NULL radioResourceConfigDedicated from eNB %d\n",Mod_id, UE_id); - return; + LOG_D(PHY,"[eNB %d] : Received NULL radioResourceConfigDedicated->antennaInfo from eNB %d\n",Mod_id,UE_id); + } + } else { + LOG_E(PHY,"[eNB %d] Received NULL radioResourceConfigDedicated from eNB %d\n",Mod_id, UE_id); + return; } -} + } */ #if defined(Rel10) || defined(Rel14) @@ -953,11 +955,11 @@ void phy_config_dedicated_scell_ue(uint8_t Mod_id, } /* -void phy_config_dedicated_scell_eNB(uint8_t Mod_id, - uint16_t rnti, - SCellToAddMod_r10_t *sCellToAddMod_r10, - int CC_id) -{ + void phy_config_dedicated_scell_eNB(uint8_t Mod_id, + uint16_t rnti, + SCellToAddMod_r10_t *sCellToAddMod_r10, + int CC_id) + { uint8_t UE_id = find_ue(rnti,RC.eNB[Mod_id][0]); @@ -968,37 +970,37 @@ void phy_config_dedicated_scell_eNB(uint8_t Mod_id, uint32_t carrier_freq_local; if ((dl_CarrierFreq_r10>=36000) && (dl_CarrierFreq_r10<=36199)) { - carrier_freq_local = 1900000000 + (dl_CarrierFreq_r10-36000)*100000; //band 33 from 3GPP 36.101 v 10.9 Table 5.7.3-1 - LOG_I(PHY,"[eNB %d] Frame %d: Configured SCell %d to frequency %d (ARFCN %ld) for UE %d\n",Mod_id, - //eNB->frame - 0, - CC_id,carrier_freq_local,dl_CarrierFreq_r10,UE_id); + carrier_freq_local = 1900000000 + (dl_CarrierFreq_r10-36000)*100000; //band 33 from 3GPP 36.101 v 10.9 Table 5.7.3-1 + LOG_I(PHY,"[eNB %d] Frame %d: Configured SCell %d to frequency %d (ARFCN %ld) for UE %d\n",Mod_id, + //eNB->frame + 0, + CC_id,carrier_freq_local,dl_CarrierFreq_r10,UE_id); } else if ((dl_CarrierFreq_r10>=6150) && (dl_CarrierFreq_r10<=6449)) { - carrier_freq_local = 832000000 + (dl_CarrierFreq_r10-6150)*100000; //band 20 from 3GPP 36.101 v 10.9 Table 5.7.3-1 - // this is actually for the UL only, but we use it for DL too, since there is no TDD mode for this band - LOG_I(PHY,"[eNB %d] Frame %d: Configured SCell %d to frequency %d (ARFCN %ld) for UE %d\n",Mod_id, - //eNB->frame - 0,CC_id,carrier_freq_local,dl_CarrierFreq_r10,UE_id); + carrier_freq_local = 832000000 + (dl_CarrierFreq_r10-6150)*100000; //band 20 from 3GPP 36.101 v 10.9 Table 5.7.3-1 + // this is actually for the UL only, but we use it for DL too, since there is no TDD mode for this band + LOG_I(PHY,"[eNB %d] Frame %d: Configured SCell %d to frequency %d (ARFCN %ld) for UE %d\n",Mod_id, + //eNB->frame + 0,CC_id,carrier_freq_local,dl_CarrierFreq_r10,UE_id); } else { - LOG_E(PHY,"[eNB %d] Frame %d: ARFCN %ld of SCell %d for UE %d not supported\n",Mod_id, - //eNB->frame - 0,dl_CarrierFreq_r10,CC_id,UE_id); + LOG_E(PHY,"[eNB %d] Frame %d: ARFCN %ld of SCell %d for UE %d not supported\n",Mod_id, + //eNB->frame + 0,dl_CarrierFreq_r10,CC_id,UE_id); } if (physicalConfigDedicatedSCell_r10) { -//#warning " eNB->physicalConfigDedicatedSCell_r10 does not exist in eNB" - // eNB->physicalConfigDedicatedSCell_r10[UE_id] = physicalConfigDedicatedSCell_r10; - LOG_I(PHY,"[eNB %d] Frame %d: Configured phyConfigDedicatedSCell with CC_id %d for UE %d\n",Mod_id, - //eNB->frame - 0,CC_id,UE_id); + //#warning " eNB->physicalConfigDedicatedSCell_r10 does not exist in eNB" + // eNB->physicalConfigDedicatedSCell_r10[UE_id] = physicalConfigDedicatedSCell_r10; + LOG_I(PHY,"[eNB %d] Frame %d: Configured phyConfigDedicatedSCell with CC_id %d for UE %d\n",Mod_id, + //eNB->frame + 0,CC_id,UE_id); } else { - LOG_E(PHY,"[eNB %d] Frame %d: Received NULL radioResourceConfigDedicated (CC_id %d, UE %d)\n",Mod_id, - //eNB->frame - 0,CC_id,UE_id); - return; + LOG_E(PHY,"[eNB %d] Frame %d: Received NULL radioResourceConfigDedicated (CC_id %d, UE %d)\n",Mod_id, + //eNB->frame + 0,CC_id,UE_id); + return; } -} + } */ #endif @@ -1172,7 +1174,7 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id, } if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) { if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_setup) { - // configure PUCCH CQI reporting + // configure PUCCH CQI reporting phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex = physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex; if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex) @@ -1211,12 +1213,12 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id, phy_vars_ue->decode_MIB = 0; //phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti; if(phy_vars_ue->pdcch_vars[0][eNB_id]->crnti == 0x1234) - phy_vars_ue->pdcch_vars[0][eNB_id]->crnti = phy_vars_ue->pdcch_vars[1][eNB_id]->crnti; + phy_vars_ue->pdcch_vars[0][eNB_id]->crnti = phy_vars_ue->pdcch_vars[1][eNB_id]->crnti; else - phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti; + phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti; LOG_I(PHY,"C-RNTI %x %x \n", phy_vars_ue->pdcch_vars[0][eNB_id]->crnti, - phy_vars_ue->pdcch_vars[1][eNB_id]->crnti); + phy_vars_ue->pdcch_vars[1][eNB_id]->crnti); } @@ -1653,7 +1655,7 @@ int phy_init_RU(RU_t *ru) { ru->common.txdata[i] = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) ); LOG_I(PHY,"[INIT] common.txdata[%d] = %p (%lu bytes)\n",i,ru->common.txdata[i], - fp->samples_per_tti*10*sizeof(int32_t)); + fp->samples_per_tti*10*sizeof(int32_t)); } for (i=0;i<ru->nb_rx;i++) { @@ -1843,12 +1845,12 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, #endif /* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) - AssertFatal(fp->nb_antennas_rx <= sizeof(prach_vars->rxsigF) / sizeof(prach_vars->rxsigF[0]), - "nb_antennas_rx too large"); - for (i=0; i<fp->nb_antennas_rx; i++) { - prach_vars->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,prach_vars->rxsigF[i]); - }*/ + AssertFatal(fp->nb_antennas_rx <= sizeof(prach_vars->rxsigF) / sizeof(prach_vars->rxsigF[0]), + "nb_antennas_rx too large"); + for (i=0; i<fp->nb_antennas_rx; i++) { + prach_vars->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,prach_vars->rxsigF[i]); + }*/ for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) { @@ -1876,7 +1878,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, pusch_vars[UE_id]->rxdataF_comp[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti ); pusch_vars[UE_id]->ul_ch_mag[i] = (int32_t*)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 ); pusch_vars[UE_id]->ul_ch_magb[i] = (int32_t*)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 ); - } + } pusch_vars[UE_id]->llr = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); } //UE_id diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c index b9576e9c9d..2e8d3f5e46 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci.c +++ b/openair1/PHY/LTE_TRANSPORT/dci.c @@ -2130,11 +2130,11 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, if (dci_alloc[i].L == (uint8_t)L) { -#ifdef DEBUG_DCI_ENCODING + //#ifdef DEBUG_DCI_ENCODING LOG_I(PHY,"Generating DCI %d/%d (nCCE %d) of length %d, aggregation %d (%x)\n",i,num_dci,dci_alloc[i].firstCCE,dci_alloc[i].dci_length,dci_alloc[i].L, *(unsigned int*)dci_alloc[i].dci_pdu); dump_dci(frame_parms,&dci_alloc[i]); -#endif + //#endif if (dci_alloc[i].firstCCE>=0) { e_ptr = generate_dci0(dci_alloc[i].dci_pdu, diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 2a43455e25..7deb8e8da7 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -863,13 +863,12 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_ uint8_t *dci_pdu = &dci_alloc->dci_pdu[0]; nfapi_dl_config_dci_dl_pdu_rel8_t *rel8 = &pdu->dci_dl_pdu_rel8; - int harq_pid; + LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL; LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL; int beamforming_mode = 0; int UE_id=-1; int subframe = proc->subframe_tx; - int RIV_max; int NPRB; int TB0_active; int TB1_active; @@ -882,7 +881,8 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_ dci_alloc->harq_pid = rel8->harq_process; dci_alloc->ra_flag = 0; - LOG_D(PHY,"NFAPI: DCI format %d, nCCE %d, L %d, rnti %x,harq_pid %d\n", + + LOG_I(PHY,"NFAPI: DCI format %d, nCCE %d, L %d, rnti %x,harq_pid %d\n", rel8->dci_format,rel8->cce_idx,rel8->aggregation_level,rel8->rnti,rel8->harq_process); if ((rel8->rnti_type == 2 ) && (rel8->rnti != SI_RNTI) && (rel8->rnti != P_RNTI)) dci_alloc->ra_flag = 1; @@ -898,12 +898,13 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_ dlsch1_harq = dlsch1->harq_processes[rel8->harq_process]; dlsch1_harq->codeword = 1; dlsch0->subframe_tx[subframe] = 1; - + dlsch0->harq_mask |= (1<<rel8->harq_process); switch (rel8->dci_format) { case NFAPI_DL_DCI_FORMAT_1A: dci_alloc->format = format1A; dlsch0->active = 1; + dlsch0->harq_mask |= (1<<rel8->harq_process); switch (fp->N_RB_DL) { case 6: @@ -936,7 +937,6 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_ dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT6[rel8->resource_block_coding]; dlsch0_harq->vrb_type = rel8->virtual_resource_block_assignment_flag; dlsch0_harq->nb_rb = RIV2nb_rb_LUT6[rel8->resource_block_coding];//NPRB; - RIV_max = RIV_max6; break; case 25: if (fp->frame_type == TDD) { @@ -967,7 +967,6 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_ dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT25[rel8->resource_block_coding]; dlsch0_harq->vrb_type = rel8->virtual_resource_block_assignment_flag; dlsch0_harq->nb_rb = RIV2nb_rb_LUT25[rel8->resource_block_coding];//NPRB; - RIV_max = RIV_max25; break; case 50: if (fp->frame_type == TDD) { @@ -999,7 +998,6 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_ dlsch0_harq->rb_alloc[1] = localRIV2alloc_LUT50_1[rel8->resource_block_coding]; dlsch0_harq->vrb_type = rel8->virtual_resource_block_assignment_flag; dlsch0_harq->nb_rb = RIV2nb_rb_LUT50[rel8->resource_block_coding];//NPRB; - RIV_max = RIV_max50; break; case 100: if (fp->frame_type == TDD) { @@ -1033,7 +1031,6 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_ dlsch0_harq->rb_alloc[3] = localRIV2alloc_LUT100_3[rel8->resource_block_coding]; dlsch0_harq->vrb_type = rel8->virtual_resource_block_assignment_flag; dlsch0_harq->nb_rb = RIV2nb_rb_LUT100[rel8->resource_block_coding];//NPRB; - RIV_max = RIV_max100; break; } @@ -1072,6 +1069,9 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_ dci_alloc->format = format1; dlsch0->active = 1; + dlsch0->harq_mask |= (1<<rel8->harq_process); + + LOG_I(PHY,"Frame %d, Subframe %d: Programming DLSCH for Format 1 DCI, harq_pid %d\n",proc->frame_tx,subframe,rel8->harq_process); switch (fp->N_RB_DL) { case 6: @@ -1224,6 +1224,7 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_ } + LOG_I(PHY,"DCI: Set harq_ids[%d] to %d\n",subframe,rel8->harq_process); dlsch0->harq_ids[subframe] = rel8->harq_process; @@ -1414,15 +1415,18 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_ dlsch1_harq->Nl = 1; dlsch0->active = 1; dlsch1->active = 1; - + 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)) { dlsch0->active = 0; + dlsch0->harq_mask &= ~(1<<rel8->harq_process); } if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) { dlsch1->active = 0; + dlsch1->harq_mask &= ~(1<<rel8->harq_process); } // dlsch0_harq->dl_power_off = 0; @@ -1704,6 +1708,8 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_ if (TB0_active && TB1_active && rel8->transport_block_to_codeword_swap_flag==0) { dlsch0->active = 1; dlsch1->active = 1; + dlsch0->harq_mask |= (1<<rel8->harq_process); + dlsch1->harq_mask |= (1<<rel8->harq_process); dlsch0_harq = dlsch0->harq_processes[rel8->harq_process]; dlsch1_harq = dlsch1->harq_processes[rel8->harq_process]; dlsch0_harq->mcs = rel8->mcs_1; @@ -1725,7 +1731,10 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_ dlsch1 = eNB->dlsch[UE_id][0]; dlsch0->active = 1; dlsch1->active = 1; - dlsch0_harq = dlsch0->harq_processes[rel8->harq_process]; + + dlsch0->harq_mask |= (1<<rel8->harq_process); + dlsch1->harq_mask |= (1<<rel8->harq_process); + dlsch1_harq = dlsch1->harq_processes[rel8->harq_process]; dlsch0_harq->mcs = rel8->mcs_1; dlsch1_harq->mcs = rel8->mcs_2; @@ -1740,6 +1749,7 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_ } else if (TB0_active && (TB1_active==0)) { dlsch0->active = 1; + dlsch0->harq_mask |= (1<<rel8->harq_process); dlsch0_harq = dlsch0->harq_processes[rel8->harq_process]; dlsch0_harq->mcs = rel8->mcs_1; dlsch0_harq->Qm = get_Qm(rel8->mcs_1); @@ -1754,6 +1764,7 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_ } else if ((TB0_active==0) && TB1_active) { dlsch1->active = 1; + dlsch1->harq_mask |= (1<<rel8->harq_process); dlsch1_harq = dlsch1->harq_processes[rel8->harq_process]; dlsch1_harq->mcs = rel8->mcs_2; dlsch1_harq->Qm = get_Qm(rel8->mcs_2); @@ -2196,7 +2207,7 @@ int fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *dc dlsch0_harq->dl_power_off = 1; dlsch0->active = 1; - + dlsch0->harq_mask |= (1<<rel13->harq_process); if (dlsch0_harq->round == 0) { @@ -2222,9 +2233,225 @@ int fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *dc } -int fill_dci_and_ulsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,nfapi_hi_dci0_dci_pdu *pdu) { +void fill_dci0(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc, + nfapi_hi_dci0_dci_pdu *pdu) { + + uint8_t UE_id; + + AssertFatal((UE_id=find_ulsch(pdu->dci_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0, + "No existing UE ULSCH for rnti %x\n",pdu->dci_pdu_rel8.rnti); + + LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; + + uint32_t cqi_req = pdu->dci_pdu_rel8.cqi_csi_request; + uint32_t dai = pdu->dci_pdu_rel8.dl_assignment_index; + uint32_t cshift = pdu->dci_pdu_rel8.cyclic_shift_2_for_drms; + uint32_t TPC = pdu->dci_pdu_rel8.tpc; + uint32_t mcs = pdu->dci_pdu_rel8.mcs_1; + uint32_t rballoc = computeRIV(frame_parms->N_RB_DL, + pdu->dci_pdu_rel8.resource_block_start, + pdu->dci_pdu_rel8.number_of_resource_block); + + uint32_t ndi = pdu->dci_pdu_rel8.new_data_indication_1; + + void *dci_pdu = (void*)dci_alloc->dci_pdu; + + dci_alloc->format = format0; + dci_alloc->firstCCE = pdu->dci_pdu_rel8.cce_index; + dci_alloc->L = pdu->dci_pdu_rel8.aggregation_level; + dci_alloc->rnti = pdu->dci_pdu_rel8.rnti; + // dci_alloc->harq_pid = pdu->dci_pdu_rel8.harq_process; + dci_alloc->ra_flag = 0; + + switch (frame_parms->N_RB_DL) { + case 6: + if (frame_parms->frame_type == TDD) { + ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req = cqi_req; + ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->dai = dai; + ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cshift = cshift; + ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC = TPC; + ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs = mcs; + ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->ndi = ndi; + ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc = rballoc; + // hopping = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->hopping; + ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->type = 0; + } else { + ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cqi_req = cqi_req; + ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cshift = cshift; + ((DCI0_1_5MHz_FDD_t *)dci_pdu)->TPC = TPC; + ((DCI0_1_5MHz_FDD_t *)dci_pdu)->mcs = mcs; + ((DCI0_1_5MHz_FDD_t *)dci_pdu)->ndi = ndi; + ((DCI0_1_5MHz_FDD_t *)dci_pdu)->rballoc = rballoc; + // hopping = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->hopping; + ((DCI0_1_5MHz_FDD_t *)dci_pdu)->type = 0; + } + + break; + + case 25: + if (frame_parms->frame_type == TDD) { + ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req = cqi_req; + ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->dai = dai; + ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift = cshift; + ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->TPC = TPC; + ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->mcs = mcs; + ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->ndi = ndi; + ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->rballoc = rballoc; + // hopping = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->hopping; + ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->type = 0; + } else { + ((DCI0_5MHz_FDD_t *)dci_pdu)->cqi_req = cqi_req; + ((DCI0_5MHz_FDD_t *)dci_pdu)->cshift = cshift; + ((DCI0_5MHz_FDD_t *)dci_pdu)->TPC = TPC; + ((DCI0_5MHz_FDD_t *)dci_pdu)->mcs = mcs; + ((DCI0_5MHz_FDD_t *)dci_pdu)->ndi = ndi; + ((DCI0_5MHz_FDD_t *)dci_pdu)->rballoc = rballoc; + // hopping = ((DCI0_5MHz_FDD_t *)dci_pdu)->hopping; + ((DCI0_5MHz_FDD_t *)dci_pdu)->type = 0; + } + + break; + + case 50: + if (frame_parms->frame_type == TDD) { + ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cqi_req = cqi_req; + ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->dai = dai; + ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cshift = cshift; + ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->TPC = TPC; + ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->mcs = mcs; + ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->ndi = ndi; + ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->rballoc = rballoc; + // hopping = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->hopping; + ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->type = 0; + } else { + ((DCI0_10MHz_FDD_t *)dci_pdu)->cqi_req = cqi_req; + ((DCI0_10MHz_FDD_t *)dci_pdu)->cshift = cshift; + ((DCI0_10MHz_FDD_t *)dci_pdu)->TPC = TPC; + ((DCI0_10MHz_FDD_t *)dci_pdu)->mcs = mcs; + ((DCI0_10MHz_FDD_t *)dci_pdu)->ndi = ndi; + ((DCI0_10MHz_FDD_t *)dci_pdu)->rballoc = rballoc; + // hopping = ((DCI0_10MHz_FDD_t *)dci_pdu)->hopping; + ((DCI0_10MHz_FDD_t *)dci_pdu)->type = 0; + } + + break; + + case 100: + if (frame_parms->frame_type == TDD) { + ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cqi_req = cqi_req; + ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->dai = dai; + ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cshift = cshift; + ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->TPC = TPC; + ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->mcs = mcs; + ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->ndi = ndi; + ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->rballoc = rballoc; + // hopping = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->hopping; + ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->type = 0; + } else { + ((DCI0_20MHz_FDD_t *)dci_pdu)->cqi_req = cqi_req; + ((DCI0_20MHz_FDD_t *)dci_pdu)->cshift = cshift; + ((DCI0_20MHz_FDD_t *)dci_pdu)->TPC = TPC; + ((DCI0_20MHz_FDD_t *)dci_pdu)->mcs = mcs; + ((DCI0_20MHz_FDD_t *)dci_pdu)->ndi = ndi; + ((DCI0_20MHz_FDD_t *)dci_pdu)->rballoc = rballoc; + // hopping = ((DCI0_20MHz_FDD_t *)dci_pdu)->hopping; + ((DCI0_20MHz_FDD_t *)dci_pdu)->type = 0; + } + + //printf("eNB: rb_alloc (20 MHz dci) %d\n",rballoc); + break; + + default: + LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); + DevParam (frame_parms->N_RB_DL, 0, 0); + break; + } +} + +void fill_ulsch(PHY_VARS_eNB *eNB,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame,int subframe) { + + uint8_t harq_pid; + + uint8_t UE_id; + + AssertFatal((UE_id=find_ulsch(ulsch_pdu->ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0, + "No existing UE ULSCH for rnti %x\n",ulsch_pdu->ulsch_pdu_rel8.rnti); + + LTE_eNB_ULSCH_t *ulsch=eNB->ulsch[UE_id]; + LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; + + int use_srs = 0; + + harq_pid = ulsch_pdu->ulsch_pdu_rel8.harq_process_number; + + + ulsch->harq_processes[harq_pid]->frame = frame; + ulsch->harq_processes[harq_pid]->subframe = subframe; + + ulsch->harq_processes[harq_pid]->first_rb = ulsch_pdu->ulsch_pdu_rel8.resource_block_start; + ulsch->harq_processes[harq_pid]->nb_rb = ulsch_pdu->ulsch_pdu_rel8.number_of_resource_blocks; + + AssertFatal(ulsch->harq_processes[harq_pid]->nb_rb>0,"nb_rb = 0\n"); + + ulsch->harq_processes[harq_pid]->dci_alloc = 1; + ulsch->harq_processes[harq_pid]->rar_alloc = 0; + ulsch->harq_processes[harq_pid]->n_DMRS = ulsch_pdu->ulsch_pdu_rel8.cyclic_shift_2_for_drms; + + ulsch->harq_processes[harq_pid]->Nsymb_pusch = 12-(frame_parms->Ncp<<1)-(use_srs==0?0:1); + ulsch->harq_processes[harq_pid]->srs_active = use_srs; + + //Mapping of cyclic shift field in DCI format0 to n_DMRS2 (3GPP 36.211, Table 5.5.2.1.1-1) + if(ulsch->harq_processes[harq_pid]->n_DMRS == 0) + ulsch->harq_processes[harq_pid]->n_DMRS2 = 0; + else if(ulsch->harq_processes[harq_pid]->n_DMRS == 1) + ulsch->harq_processes[harq_pid]->n_DMRS2 = 6; + else if(ulsch->harq_processes[harq_pid]->n_DMRS == 2) + ulsch->harq_processes[harq_pid]->n_DMRS2 = 3; + else if(ulsch->harq_processes[harq_pid]->n_DMRS == 3) + ulsch->harq_processes[harq_pid]->n_DMRS2 = 4; + else if(ulsch->harq_processes[harq_pid]->n_DMRS == 4) + ulsch->harq_processes[harq_pid]->n_DMRS2 = 2; + else if(ulsch->harq_processes[harq_pid]->n_DMRS == 5) + ulsch->harq_processes[harq_pid]->n_DMRS2 = 8; + else if(ulsch->harq_processes[harq_pid]->n_DMRS == 6) + ulsch->harq_processes[harq_pid]->n_DMRS2 = 10; + else if(ulsch->harq_processes[harq_pid]->n_DMRS == 7) + ulsch->harq_processes[harq_pid]->n_DMRS2 = 9; + + + LOG_I(PHY,"[eNB %d][PUSCH %d] Programming PUSCH with n_DMRS2 %d (cshift %d) for Frame %d, Subframe %d\n", + eNB->Mod_id,harq_pid,ulsch->harq_processes[harq_pid]->n_DMRS2,ulsch->harq_processes[harq_pid]->n_DMRS, + frame,subframe); + + + ulsch->harq_processes[harq_pid]->rvidx = ulsch_pdu->ulsch_pdu_rel8.redundancy_version; + ulsch->harq_processes[harq_pid]->Qm = ulsch_pdu->ulsch_pdu_rel8.modulation_type; + - exit(-1); + if (ulsch->harq_processes[harq_pid]->round == 0) { + ulsch->harq_processes[harq_pid]->status = ACTIVE; + + ulsch->harq_processes[harq_pid]->TBS = ulsch_pdu->ulsch_pdu_rel8.size<<3; + + ulsch->harq_processes[harq_pid]->Msc_initial = ulsch_pdu->ulsch_pdu_rel8.number_of_resource_blocks; + ulsch->harq_processes[harq_pid]->Nsymb_initial = ulsch->harq_processes[harq_pid]->Nsymb_pusch; + ulsch->harq_processes[harq_pid]->round = 0; + } + + ulsch->rnti = ulsch_pdu->ulsch_pdu_rel8.rnti; + LOG_I(PHY,"Filling ULSCH %x for Frame %d, Subframe %d : harq_pid %d, first_rb %d, nb_rb %d, rvidx %d, Qm %d, TBS %d, round %d \n", + ulsch->rnti, + frame, + subframe, + harq_pid, + ulsch->harq_processes[harq_pid]->first_rb, + ulsch->harq_processes[harq_pid]->nb_rb, + ulsch->harq_processes[harq_pid]->rvidx, + ulsch->harq_processes[harq_pid]->Qm, + ulsch->harq_processes[harq_pid]->TBS, + ulsch->harq_processes[harq_pid]->round); + + } int generate_eNB_dlsch_params_from_dci(int frame, @@ -6488,16 +6715,33 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format, uint8_t rah = pdci_info_extarcted->rah; uint8_t dai = pdci_info_extarcted->dai; - uint8_t NPRB = 0; + uint8_t NPRB = 0; + uint8_t NPRB4TBS = 0; if(dci_format == format1A) { - if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) + switch (N_RB_DL) { + case 6: + NPRB = RIV2nb_rb_LUT6[rballoc]; + break; + case 25: + NPRB = RIV2nb_rb_LUT25[rballoc]; + break; + case 50: + NPRB = RIV2nb_rb_LUT50[rballoc]; + break; + case 100: + NPRB = RIV2nb_rb_LUT100[rballoc]; + break; + } + if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) { - NPRB = (TPC&1) + 2; + NPRB4TBS = (TPC&1) + 2; } - else + else { + NPRB4TBS = NPRB; + /* switch (N_RB_DL) { case 6: NPRB = RIV2nb_rb_LUT6[rballoc];//NPRB; @@ -6512,11 +6756,13 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format, NPRB = RIV2nb_rb_LUT100[rballoc];//NPRB; break; } + */ } } else // format1 { NPRB = conv_nprb(rah, rballoc, N_RB_DL); + NPRB4TBS=NPRB; } pdlsch0->current_harq_pid = harq_pid; @@ -6607,7 +6853,7 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format, pdlsch0_harq->rb_alloc_even[1] = localRIV2alloc_LUT50_1[rballoc]; pdlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT50_0[rballoc]; pdlsch0_harq->rb_alloc_odd[1] = localRIV2alloc_LUT50_1[rballoc]; - // printf("rballoc: %08x.%08x\n",pdlsch0_harq->rb_alloc_even[0],pdlsch0_harq->rb_alloc_even[1]); + printf("rballoc: %08x.%08x\n",pdlsch0_harq->rb_alloc_even[0],pdlsch0_harq->rb_alloc_even[1]); } else { // DISTRIBUTED if ((rballoc&(1<<10)) == 0) { rballoc = rballoc&(~(1<<10)); @@ -6674,14 +6920,14 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format, if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) { - pdlsch0_harq->TBS = TBStable[mcs1][NPRB-1]; + pdlsch0_harq->TBS = TBStable[mcs1][NPRB4TBS-1]; pdlsch0_harq->Qm = 2; } else { if(mcs1 < 29) { - pdlsch0_harq->TBS = TBStable[get_I_TBS(mcs1)][NPRB-1]; + pdlsch0_harq->TBS = TBStable[get_I_TBS(mcs1)][NPRB4TBS-1]; pdlsch0_harq->Qm = get_Qm(mcs1); } } @@ -9443,6 +9689,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, } +/* int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, void *dci_pdu, @@ -9612,13 +9859,13 @@ int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB, if (cqi_req == 1) { - /* 36.213 7.2.1 (release 10) says: - * "RI is only reported for transmission modes 3 and 4, - * as well as transmission modes 8 and 9 with PMI/RI reporting" - * This is for aperiodic reporting. - * TODO: deal with TM 8&9 correctly when they are implemented. - * TODO: deal with periodic reporting if we implement it. - */ + // 36.213 7.2.1 (release 10) says: + // "RI is only reported for transmission modes 3 and 4, + // as well as transmission modes 8 and 9 with PMI/RI reporting" + // This is for aperiodic reporting. + // TODO: deal with TM 8&9 correctly when they are implemented. + // TODO: deal with periodic reporting if we implement it. + // if (transmission_mode == 3 || transmission_mode == 4) ulsch->harq_processes[harq_pid]->O_RI = 1; //we only support 2 antenna ports, so this is always 1 according to 3GPP 36.213 Table else @@ -10022,13 +10269,13 @@ int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB, ulsch->harq_processes[harq_pid]->mcs = mcs; // ulsch->harq_processes[harq_pid]->calibration_flag = 0; //if (ulsch->harq_processes[harq_pid]->mcs) - /* - if (ulsch->harq_processes[harq_pid]->mcs == 29) { - ulsch->harq_processes[harq_pid]->mcs = 4; + // + //if (ulsch->harq_processes[harq_pid]->mcs == 29) { + //ulsch->harq_processes[harq_pid]->mcs = 4; // ulsch->harq_processes[harq_pid]->calibration_flag = 1; // printf("Auto-Calibration (eNB): mcs %d, nb_rb %d\n",ulsch->harq_processes[harq_pid]->mcs,ulsch->harq_processes[harq_pid]->nb_rb); - } - */ + //} + ulsch->harq_processes[harq_pid]->TBS = TBStable[get_I_TBS_UL(ulsch->harq_processes[harq_pid]->mcs)][ulsch->harq_processes[harq_pid]->nb_rb-1]; ulsch->harq_processes[harq_pid]->Msc_initial = 12*ulsch->harq_processes[harq_pid]->nb_rb; @@ -10073,7 +10320,7 @@ int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB, } } - +*/ double sinr_eff_cqi_calc(PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe) { diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/defs.h index e8be4facd4..fd5adcdf4b 100644 --- a/openair1/PHY/LTE_TRANSPORT/defs.h +++ b/openair1/PHY/LTE_TRANSPORT/defs.h @@ -398,14 +398,10 @@ typedef struct { uint8_t subframe; /// Frame for reception uint32_t frame; - /// Subframe cba scheduling indicator (i.e. CBA Transmission opportunity indicator) - uint8_t subframe_cba_scheduling_flag; /// PHICH active flag uint8_t phich_active; /// PHICH ACK uint8_t phich_ACK; - /// Last TPC command - uint8_t TPC; /// First Allocated RB uint16_t first_rb; /// First Allocated RB - previous scheduling @@ -413,7 +409,9 @@ typedef struct { /// is done after a new scheduling uint16_t previous_first_rb; /// Current Number of RBs - uint16_t nb_rb; + uint16_t nb_rb; + /// Current Modulation order + uint8_t Qm; /// Transport block size uint32_t TBS; /// The payload + CRC size in bits @@ -468,8 +466,6 @@ typedef struct { uint8_t srs_active; /// Index of current HARQ round for this ULSCH uint8_t round; - /// MCS format for this ULSCH - uint8_t mcs; /// Redundancy-version of the current sub-frame uint8_t rvidx; /// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) @@ -513,6 +509,9 @@ typedef enum { pucch_format1=0, pucch_format1a, pucch_format1b, + pucch_format1b_csA2, + pucch_format1b_csA3, + pucch_format1b_csA4, pucch_format2, pucch_format2a, pucch_format2b, @@ -547,14 +546,24 @@ typedef struct { uint16_t rnti; /// Type (SR,HARQ,CQI,HARQ_SR,HARQ_CQI,SR_CQI,HARQ_SR_CQI) UCI_type_t type; + /// SRS active flag + uint8_t srs_active; /// PUCCH format to use PUCCH_FMT_t pucch_fmt; - /// antenna indicator + /// number of PUCCH antenna ports + uint8_t num_antenna_ports; + /// number of PUCCH resources uint8_t num_pucch_resources; - /// two antenna n1_pucch - uint16_t n_pucch_1[2]; - /// two antenna n2_pucch + /// two antenna n1_pucch 1_0 + uint16_t n_pucch_1[4][2]; + /// two antenna n1_pucch 1_0 for SR + uint16_t n_pucch_1_0_sr[2]; + /// two antenna n2_pucch uint16_t n_pucch_2[2]; + /// two antenna n3_pucch + uint16_t n_pucch_3[2]; + /// TDD Bundling/multiplexing flag + uint8_t tdd_bundling; #ifdef Rel14 /// non BL/CE, CEmodeA, CEmodeB UE_type_t ue_type; @@ -573,7 +582,7 @@ typedef struct { // Indicates if the resource blocks allocated for this grant overlap with the SRS configuration. uint8_t Nsrs; #endif -} LTE_eNB_UCI_t; +} LTE_eNB_UCI; typedef struct { /// HARQ process mask, indicates which processes are currently active diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 489b6bbfcb..091beddec7 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -353,10 +353,10 @@ int rx_pdsch(PHY_VARS_UE *ue, } -#ifdef DEBUG_PHY + //#ifdef DEBUG_PHY LOG_D(PHY,"[DLSCH] nb_rb %d log2_maxh = %d (%d,%d)\n",nb_rb,pdsch_vars[eNB_id]->log2_maxh,avg[0],avgs); LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode); -#endif + //#endif aatx = frame_parms->nb_antenna_ports_eNB; aarx = frame_parms->nb_antennas_rx; @@ -3327,9 +3327,9 @@ void dlsch_scale_channel(int **dl_ch_estimates_ext, // Determine scaling amplitude based the symbol -ch_amp = ((pilots) ? (dlsch_ue[0]->sqrt_rho_b) : (dlsch_ue[0]->sqrt_rho_a)); - - LOG_D(PHY,"Scaling PDSCH Chest in OFDM symbol %d by %d, pilots %d nb_rb %d NCP %d symbol %d\n",symbol_mod,ch_amp,pilots,nb_rb,frame_parms->Ncp,symbol); + ch_amp = ((pilots) ? (dlsch_ue[0]->sqrt_rho_b) : (dlsch_ue[0]->sqrt_rho_a)); + + LOG_D(PHY,"Scaling PDSCH Chest in OFDM symbol %d by %d, pilots %d nb_rb %d NCP %d symbol %d\n",symbol_mod,ch_amp,pilots,nb_rb,frame_parms->Ncp,symbol); // printf("Scaling PDSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp); ch_amp128 = _mm_set1_epi16(ch_amp); // Q3.13 diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c index bbd29e6d70..5eeb661f8c 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c @@ -124,7 +124,7 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, } #ifdef DEBUG_SCRAMBLING - printf("scrambling: rnti %x, q %d, Ns %d, Nid_cell %d, length %d\n",dlsch->rnti,q,Ns,frame_parms->Nid_cell, G); + printf("scrambling: i0 %d rnti %x, q %d, Ns %d, Nid_cell %d, G %d x2 %x\n",dlsch->i0,dlsch->rnti,q,Ns,frame_parms->Nid_cell, G, x2); #endif s = lte_gold_scram(&x1, &x2, 1); @@ -206,7 +206,7 @@ void dlsch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms, x2 = ((Ns>>1)<<9) + frame_parms->Nid_cell_mbsfn; //this is c_init in 36.211 Sec 6.3.1 #ifdef DEBUG_SCRAMBLING - printf("unscrambling: rnti %x, q %d, Ns %d, Nid_cell %d length %d\n",dlsch->rnti,q,Ns,frame_parms->Nid_cell,G); + printf("unscrambling: rnti %x, q %d, Ns %d, Nid_cell %d G %d, x2 %x\n",dlsch->rnti,q,Ns,frame_parms->Nid_cell,G,x2); #endif s = lte_gold_scram(&x1, &x2, 1); diff --git a/openair1/PHY/LTE_TRANSPORT/if4_tools.c b/openair1/PHY/LTE_TRANSPORT/if4_tools.c index 1c77083deb..ccd842f215 100644 --- a/openair1/PHY/LTE_TRANSPORT/if4_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/if4_tools.c @@ -200,14 +200,14 @@ void send_IF4p5(RU_t *ru, int frame, int subframe, uint16_t packet_type) { if (packet_type > IF4p5_PRACH) rxF = &prach_rxsigF_br[packet_type - IF4p5_PRACH - 1][0][0]; else -#else +#endif rxF = &prach_rxsigF[0][0]; -#endif + AssertFatal(rxF!=NULL,"rxF is null\n"); if (eth->flags == ETH_RAW_IF4p5_MODE) { - memcpy((void *)(tx_buffer_prach + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t), - (void*)rxF, - PRACH_BLOCK_SIZE_BYTES); + memcpy((void *)(tx_buffer_prach + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t), + (void*)rxF, + PRACH_BLOCK_SIZE_BYTES); } else { memcpy((void *)(tx_buffer_prach + sizeof_IF4p5_header_t), (void *)rxF, @@ -335,13 +335,14 @@ void recv_IF4p5(RU_t *ru, int *frame, int *subframe, uint16_t *packet_type, uint if (*packet_type > IF4p5_PRACH) rxF = &prach_rxsigF_br[*packet_type - IF4p5_PRACH - 1][0][0]; else -#else - rxF = &prach_rxsigF[0][0]; #endif + rxF = &prach_rxsigF[0][0]; // FIX: hard coded prach samples length db_fulllength = PRACH_NUM_SAMPLES; + AssertFatal(rxF!=NULL,"rxF is null\n"); + if (eth->flags == ETH_RAW_IF4p5_MODE) { memcpy(rxF, (int16_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES+sizeof_IF4p5_header_t), diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c index 121f9b8490..e44a345d90 100644 --- a/openair1/PHY/LTE_TRANSPORT/phich.c +++ b/openair1/PHY/LTE_TRANSPORT/phich.c @@ -1474,8 +1474,9 @@ void rx_phich(PHY_VARS_UE *ue, //ulsch->harq_processes[8] = ulsch->harq_processes[harq_pid]; - ulsch->harq_processes[harq_pid]->status = SCH_IDLE; - ulsch->harq_processes[harq_pid]->round = 0; + ulsch->harq_processes[harq_pid]->status = SCH_IDLE; + ulsch->harq_processes[harq_pid]->round = 0; + ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 0; // inform MAC? ue->ulsch_Msg3_active[eNB_id] = 0; @@ -1490,21 +1491,20 @@ void rx_phich(PHY_VARS_UE *ue, void generate_phich_top(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, - int16_t amp, - uint8_t sect_id) + int16_t amp) { LTE_DL_FRAME_PARMS *frame_parms=&eNB->frame_parms; - LTE_eNB_ULSCH_t **ulsch = eNB->ulsch; int32_t **txdataF = eNB->common_vars.txdataF; uint8_t harq_pid; uint8_t Ngroup_PHICH,ngroup_PHICH,nseq_PHICH; uint8_t NSF_PHICH = 4; uint8_t pusch_subframe; - uint8_t UE_id; + uint8_t i; uint32_t pusch_frame; int subframe = proc->subframe_tx; + phich_config_t *phich; // compute Ngroup_PHICH (see formula at beginning of Section 6.9 in 36-211 @@ -1520,98 +1520,42 @@ void generate_phich_top(PHY_VARS_eNB *eNB, pusch_subframe = phich_subframe2_pusch_subframe(frame_parms,subframe); harq_pid = subframe2harq_pid(frame_parms,pusch_frame,pusch_subframe); - for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) { - if ((ulsch[UE_id])&&(ulsch[UE_id]->rnti>0)) { - if (ulsch[UE_id]->harq_processes[harq_pid]->phich_active == 1) { + for (i=0; i<eNB->phich_vars[subframe&1].num_hi; i++) { - LOG_I(PHY,"[eNB][PUSCH %d/%x] Frame %d subframe %d (pusch_subframe %d,pusch_frame %d) phich active %d\n", - harq_pid,ulsch[UE_id]->rnti,proc->frame_tx,subframe,pusch_subframe,pusch_frame,ulsch[UE_id]->harq_processes[harq_pid]->phich_active); - - /* the HARQ process may have been reused by a new scheduling, so we use - * previous values of first_rb and n_DMRS to compute ngroup_PHICH and nseq_PHICH - */ - - ngroup_PHICH = (ulsch[UE_id]->harq_processes[harq_pid]->previous_first_rb + - ulsch[UE_id]->harq_processes[harq_pid]->previous_n_DMRS)%Ngroup_PHICH; - - if ((frame_parms->tdd_config == 0) && (frame_parms->frame_type == TDD) ) { - - if ((pusch_subframe == 4) || (pusch_subframe == 9)) - ngroup_PHICH += Ngroup_PHICH; - } - - nseq_PHICH = ((ulsch[UE_id]->harq_processes[harq_pid]->previous_first_rb/Ngroup_PHICH) + - ulsch[UE_id]->harq_processes[harq_pid]->previous_n_DMRS)%(2*NSF_PHICH); - LOG_I(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d Generating PHICH, ngroup_PHICH %d/%d, nseq_PHICH %d : HI %d, first_rb %d dci_alloc %d)\n", - eNB->Mod_id,harq_pid,proc->frame_tx, - subframe,ngroup_PHICH,Ngroup_PHICH,nseq_PHICH, - ulsch[UE_id]->harq_processes[harq_pid]->phich_ACK, - ulsch[UE_id]->harq_processes[harq_pid]->previous_first_rb, - ulsch[UE_id]->harq_processes[harq_pid]->dci_alloc); - - T(T_ENB_PHY_PHICH, T_INT(eNB->Mod_id), T_INT(proc->frame_tx), T_INT(subframe), - T_INT(UE_id), T_INT(ulsch[UE_id]->rnti), T_INT(harq_pid), - T_INT(Ngroup_PHICH), T_INT(NSF_PHICH), - T_INT(ngroup_PHICH), T_INT(nseq_PHICH), - T_INT(ulsch[UE_id]->harq_processes[harq_pid]->phich_ACK), - T_INT(ulsch[UE_id]->harq_processes[harq_pid]->previous_first_rb), - T_INT(ulsch[UE_id]->harq_processes[harq_pid]->previous_n_DMRS)); - - if (ulsch[UE_id]->Msg3_active == 1) { - LOG_I(PHY,"[eNB %d][PUSCH %d][RAPROC] Frame %d, subframe %d: Generating Msg3 PHICH for UE %d, ngroup_PHICH %d/%d, nseq_PHICH %d : HI %d, first_rb %d\n", - eNB->Mod_id,harq_pid,proc->frame_tx,subframe, - UE_id,ngroup_PHICH,Ngroup_PHICH,nseq_PHICH,ulsch[UE_id]->harq_processes[harq_pid]->phich_ACK, - ulsch[UE_id]->harq_processes[harq_pid]->previous_first_rb); - } - - if (eNB->abstraction_flag == 0) { - generate_phich(frame_parms, - amp,//amp*2, - nseq_PHICH, - ngroup_PHICH, - ulsch[UE_id]->harq_processes[harq_pid]->phich_ACK, - subframe, - txdataF); - } else { - /* - generate_phich_emul(frame_parms, - //nseq_PHICH, - //ngroup_PHICH, - ulsch[UE_id]->harq_processes[harq_pid]->phich_ACK, - subframe); - */ - } - - // if no format0 DCI was transmitted by MAC, prepare the - // MCS parameters for the retransmission - - - if ((ulsch[UE_id]->harq_processes[harq_pid]->dci_alloc == 0) && - (ulsch[UE_id]->harq_processes[harq_pid]->rar_alloc == 0) ) { - if (ulsch[UE_id]->harq_processes[harq_pid]->phich_ACK==0 ) { - T(T_ENB_PHY_ULSCH_UE_NO_DCI_RETRANSMISSION, T_INT(eNB->Mod_id), T_INT(proc->frame_tx), - T_INT(subframe), T_INT(UE_id), T_INT(ulsch[UE_id]->rnti), T_INT(harq_pid)); - LOG_I(PHY,"[eNB %d][PUSCH %d] frame %d, subframe %d : PHICH NACK / (no format0 DCI) Setting subframe_scheduling_flag\n", - eNB->Mod_id,harq_pid,proc->frame_tx,subframe); - // ulsch[UE_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1; - ulsch[UE_id]->harq_processes[harq_pid]->subframe = (subframe + 4)%10; - if (subframe>5) ulsch[UE_id]->harq_processes[harq_pid]->frame++; - ulsch[UE_id]->harq_processes[harq_pid]->rvidx = rv_table[ulsch[UE_id]->harq_processes[harq_pid]->round&3]; - ulsch[UE_id]->harq_processes[harq_pid]->O_RI = 0; - ulsch[UE_id]->harq_processes[harq_pid]->Or2 = 0; - ulsch[UE_id]->harq_processes[harq_pid]->Or1 = 0; - ulsch[UE_id]->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_nopmi; - - } else { - LOG_I(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d PHICH ACK (no format0 DCI) Clearing subframe_scheduling_flag, setting round to 0\n", - eNB->Mod_id,harq_pid,proc->frame_tx,subframe); - ulsch[UE_id]->harq_processes[harq_pid]->status = SCH_IDLE; - ulsch[UE_id]->harq_processes[harq_pid]->round=0; - } - } - - ulsch[UE_id]->harq_processes[harq_pid]->phich_active=0; - } // phich_active==1 - } //ulsch_ue[UE_id] is non-null - }// UE loop + phich = &eNB->phich_vars[subframe&1].config[i]; + + ngroup_PHICH = (phich->first_rb + + phich->n_DMRS)%Ngroup_PHICH; + + if ((frame_parms->tdd_config == 0) && (frame_parms->frame_type == TDD) ) { + + if ((pusch_subframe == 4) || (pusch_subframe == 9)) + ngroup_PHICH += Ngroup_PHICH; + } + + nseq_PHICH = ((phich->first_rb/Ngroup_PHICH) + + phich->n_DMRS)%(2*NSF_PHICH); + LOG_I(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d Generating PHICH, AMP %d ngroup_PHICH %d/%d, nseq_PHICH %d : HI %d, first_rb %d)\n", + eNB->Mod_id,harq_pid,proc->frame_tx, + subframe,amp,ngroup_PHICH,Ngroup_PHICH,nseq_PHICH, + phich->hi, + phich->first_rb); + + T(T_ENB_PHY_PHICH, T_INT(eNB->Mod_id), T_INT(proc->frame_tx), T_INT(subframe), + T_INT(i), T_INT(0), T_INT(harq_pid), + T_INT(Ngroup_PHICH), T_INT(NSF_PHICH), + T_INT(ngroup_PHICH), T_INT(nseq_PHICH), + T_INT(phich->hi), + T_INT(phich->first_rb), + T_INT(phich->n_DMRS)); + + generate_phich(frame_parms, + amp,//amp*2, + nseq_PHICH, + ngroup_PHICH, + phich->hi, + subframe, + txdataF); + }// for (i=0; i<eNB->phich_vars[subframe&1].num_hi; i++) { + eNB->phich_vars[subframe&1].num_hi=0; } diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 867a2877fe..f69a22419c 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -1661,11 +1661,12 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB, DCI_ALLOC_t *dci_alloc, nfapi_dl_config_dci_dl_pdu *pdu); +int fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *dci_alloc,nfapi_dl_config_mpdcch_pdu *pdu); -int fill_dci_and_ulsch(PHY_VARS_eNB *eNB, - eNB_rxtx_proc_t *proc, - DCI_ALLOC_t *dci_alloc, - nfapi_hi_dci0_dci_pdu *pdu); +void fill_dci0(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc, + nfapi_hi_dci0_dci_pdu *pdu); + +void fill_ulsch(PHY_VARS_eNB *eNB,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame,int subframe); int32_t generate_eNB_dlsch_params_from_dci(int frame, uint8_t subframe, @@ -1862,8 +1863,7 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *phy_vars_eNB, void generate_phich_top(PHY_VARS_eNB *phy_vars_eNB, eNB_rxtx_proc_t *proc, - int16_t amp, - uint8_t sect_id); + int16_t amp); /* \brief This routine demodulates the PHICH and updates PUSCH/ULSCH parameters. @param phy_vars_ue Pointer to UE variables diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c index 47e60808c3..add3d67554 100644 --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -1857,25 +1857,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, } first_call=0; } - /* - switch (frame_parms->N_RB_UL) { - - case 6: - sigma2_dB -= 8; - break; - case 25: - sigma2_dB -= 14; - break; - case 50: - sigma2_dB -= 17; - break; - case 100: - sigma2_dB -= 20; - break; - default: - sigma2_dB -= 14; - } - */ + if(fmt!=pucch_format3) { /* PUCCH format3 */ @@ -2241,8 +2223,8 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, stat_re += ((rxcomp[aa][off]*(int32_t)cfo[l2<<1])>>15) - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l2<<1)])>>15); stat_im += ((rxcomp[aa][off]*(int32_t)cfo[1+(l2<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l2<<1)])>>15); } else { //reference_symbols - stat_ref_re += ((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15) - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15); - stat_ref_im += ((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15); + stat_ref_re += ((rxcomp[aa][off]*(int32_t)cfo[l2<<1])>>15) - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l2<<1)])>>15); + stat_ref_im += ((rxcomp[aa][off]*(int32_t)cfo[1+(l2<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l2<<1)])>>15); } off+=2; @@ -2420,13 +2402,13 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, if (fmt==pucch_format1b) *(1+payload) = (stat_im<0) ? 1 : 0; } else { // insufficient energy on PUCCH so NAK - *payload = 0; + *payload = 4; // DTX ((int16_t*)&eNB->pucch1ab_stats[UE_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe])])[0] = (int16_t)(stat_re); ((int16_t*)&eNB->pucch1ab_stats[UE_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe])])[1] = (int16_t)(stat_im); eNB->pucch1ab_stats_cnt[UE_id][subframe] = (eNB->pucch1ab_stats_cnt[UE_id][subframe]+1)&1023; if (fmt==pucch_format1b) - *(1+payload) = 0; + *(1+payload) = 6; } } else { LOG_E(PHY,"[eNB] PUCCH fmt2/2a/2b not supported\n"); diff --git a/openair1/PHY/LTE_TRANSPORT/rar_tools.c b/openair1/PHY/LTE_TRANSPORT/rar_tools.c index 92f2851a6d..158521f598 100644 --- a/openair1/PHY/LTE_TRANSPORT/rar_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/rar_tools.c @@ -116,7 +116,7 @@ int generate_eNB_ulsch_params_from_rar(PHY_VARS_eNB *eNB, break; } - ulsch_harq->TPC = (rar[3]>>2)&7;//rar->TPC; + rballoc = (((uint16_t)(rar[1]&7))<<7)|(rar[2]>>1); if (rballoc>RIV_max) { @@ -150,19 +150,19 @@ int generate_eNB_ulsch_params_from_rar(PHY_VARS_eNB *eNB, ulsch->rnti = rnti; ulsch->harq_mask = 1<<harq_pid; - if (ulsch_harq->round == 0) { + // if (ulsch_harq->round == 0) { ulsch_harq->status = ACTIVE; ulsch_harq->rvidx = 0; - ulsch_harq->mcs = ((rar[2]&1)<<3)|(rar[3]>>5); - //ulsch_harq->TBS = dlsch_tbs25[ulsch_harq->mcs][ulsch_harq->nb_rb-1]; - ulsch_harq->TBS = TBStable[get_I_TBS_UL(ulsch_harq->mcs)][ulsch_harq->nb_rb-1]; + uint8_t mcs = ((rar[2]&1)<<3)|(rar[3]>>5); + ulsch_harq->TBS = TBStable[get_I_TBS_UL(mcs)][ulsch_harq->nb_rb-1]; + ulsch_harq->Qm = get_Qm_ul(mcs); ulsch_harq->Msc_initial = 12*ulsch_harq->nb_rb; ulsch_harq->Nsymb_initial = 9; ulsch_harq->round = 0; - } else { + /* } else { ulsch_harq->rvidx = 0; ulsch_harq->round++; - } + }*/ ulsch->Msg3_active = 1; @@ -173,6 +173,7 @@ int generate_eNB_ulsch_params_from_rar(PHY_VARS_eNB *eNB, &ulsch_harq->frame, &ulsch_harq->subframe); + LOG_I(PHY,"Programming msg3 reception in (%d,%d)\n",ulsch_harq->frame,ulsch_harq->subframe); use_srs = is_srs_occasion_common(frame_parms,ulsch_harq->frame,ulsch_harq->subframe); ulsch_harq->Nsymb_pusch = 12-(frame_parms->Ncp<<1)-(use_srs==0?0:1); ulsch_harq->srs_active = use_srs; @@ -264,15 +265,11 @@ int generate_ue_ulsch_params_from_rar(PHY_VARS_UE *ue, ulsch->harq_processes[harq_pid]->first_rb = RIV2first_rb_LUT[rballoc]; ulsch->harq_processes[harq_pid]->nb_rb = RIV2nb_rb_LUT[rballoc]; - if (ulsch->harq_processes[harq_pid]->nb_rb ==0) - return(-1); + AssertFatal(ulsch->harq_processes[harq_pid]->nb_rb >0, "nb_rb == 0\n"); ulsch->power_offset = ue_power_offsets[ulsch->harq_processes[harq_pid]->nb_rb]; - if (ulsch->harq_processes[harq_pid]->nb_rb > 4) { - LOG_D(PHY,"rar_tools.c: unlikely rb count for RAR grant : nb_rb > 3\n"); - return(-1); - } + AssertFatal(ulsch->harq_processes[harq_pid]->nb_rb > 6,"unlikely rb count for RAR grant : nb_rb > 6\n"); // ulsch->harq_processes[harq_pid]->Ndi = 1; if (ulsch->harq_processes[harq_pid]->round == 0) diff --git a/openair1/PHY/LTE_TRANSPORT/uci_tools.c b/openair1/PHY/LTE_TRANSPORT/uci_tools.c index 8b72b4e733..f61749e6ca 100644 --- a/openair1/PHY/LTE_TRANSPORT/uci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/uci_tools.c @@ -232,18 +232,6 @@ void extract_CQI(void *o,UCI_format_t uci_format,LTE_eNB_UE_stats *stats, uint8_ stats->DL_pmi_dual = ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->pmi; break; - case HLC_subband_cqi_mcs_CBA: - if ((*crnti == ((HLC_subband_cqi_mcs_CBA_1_5MHz *)o)->crnti) && (*crnti !=0)) { - *access_mode=CBA_ACCESS; - LOG_N(PHY,"[eNB] UCI for CBA : mcs %d crnti %x\n", - ((HLC_subband_cqi_mcs_CBA_1_5MHz *)o)->mcs, ((HLC_subband_cqi_mcs_CBA_1_5MHz *)o)->crnti); - } else { - LOG_D(PHY,"[eNB] UCI for CBA : rnti (enb context %x, rx uci %x) invalid, unknown access\n", - *crnti, ((HLC_subband_cqi_mcs_CBA_1_5MHz *)o)->crnti); - } - - break; - case unknown_cqi: default: LOG_N(PHY,"[eNB][UCI] received unknown uci (rb %d)\n",N_RB_DL); @@ -318,18 +306,6 @@ void extract_CQI(void *o,UCI_format_t uci_format,LTE_eNB_UE_stats *stats, uint8_ stats->DL_pmi_dual = ((HLC_subband_cqi_rank2_2A_5MHz *)o)->pmi; break; - case HLC_subband_cqi_mcs_CBA: - if ((*crnti == ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->crnti) && (*crnti !=0)) { - *access_mode=CBA_ACCESS; - LOG_N(PHY,"[eNB] UCI for CBA : mcs %d crnti %x\n", - ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->mcs, ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->crnti); - } else { - LOG_D(PHY,"[eNB] UCI for CBA : rnti (enb context %x, rx uci %x) invalid, unknown access\n", - *crnti, ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->crnti); - } - - break; - case unknown_cqi: default: LOG_N(PHY,"[eNB][UCI] received unknown uci (rb %d)\n",N_RB_DL); @@ -398,18 +374,6 @@ void extract_CQI(void *o,UCI_format_t uci_format,LTE_eNB_UE_stats *stats, uint8_ stats->DL_pmi_dual = ((HLC_subband_cqi_rank2_2A_10MHz *)o)->pmi; break; - case HLC_subband_cqi_mcs_CBA: - if ((*crnti == ((HLC_subband_cqi_mcs_CBA_10MHz *)o)->crnti) && (*crnti !=0)) { - *access_mode=CBA_ACCESS; - LOG_N(PHY,"[eNB] UCI for CBA : mcs %d crnti %x\n", - ((HLC_subband_cqi_mcs_CBA_10MHz *)o)->mcs, ((HLC_subband_cqi_mcs_CBA_10MHz *)o)->crnti); - } else { - LOG_D(PHY,"[eNB] UCI for CBA : rnti (enb context %x, rx uci %x) invalid, unknown access\n", - *crnti, ((HLC_subband_cqi_mcs_CBA_10MHz *)o)->crnti); - } - - break; - case unknown_cqi: default: LOG_N(PHY,"[eNB][UCI] received unknown uci (RB %d)\n",N_RB_DL); @@ -478,18 +442,6 @@ void extract_CQI(void *o,UCI_format_t uci_format,LTE_eNB_UE_stats *stats, uint8_ stats->DL_pmi_dual = ((HLC_subband_cqi_rank2_2A_20MHz *)o)->pmi; break; - case HLC_subband_cqi_mcs_CBA: - if ((*crnti == ((HLC_subband_cqi_mcs_CBA_20MHz *)o)->crnti) && (*crnti !=0)) { - *access_mode=CBA_ACCESS; - LOG_N(PHY,"[eNB] UCI for CBA : mcs %d crnti %x\n", - ((HLC_subband_cqi_mcs_CBA_20MHz *)o)->mcs, ((HLC_subband_cqi_mcs_CBA_20MHz *)o)->crnti); - } else { - LOG_D(PHY,"[eNB] UCI for CBA : rnti (enb context %x, rx uci %x) invalid, unknown access\n", - *crnti, ((HLC_subband_cqi_mcs_CBA_20MHz *)o)->crnti); - } - - break; - case unknown_cqi: default: LOG_N(PHY,"[eNB][UCI] received unknown uci (RB %d)\n",N_RB_DL); @@ -750,13 +702,6 @@ void print_CQI(void *o,UCI_format_t uci_format,unsigned char eNB_id,int N_RB_DL) break; } -#endif //DEBUG_UCI - break; - - case HLC_subband_cqi_mcs_CBA: -#ifdef DEBUG_UCI - LOG_I(PHY,"[PRINT CQI] hlc_cqi_mcs_CBA : eNB %d, mcs %d\n",eNB_id,((HLC_subband_cqi_mcs_CBA_5MHz *)o)->mcs); - LOG_I(PHY,"[PRINT CQI] hlc_cqi_mcs_CBA : eNB %d, rnti %x\n",eNB_id,((HLC_subband_cqi_mcs_CBA_5MHz *)o)->crnti); #endif //DEBUG_UCI break; diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index 6ff4fd58fd..ac2c682bc1 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -224,7 +224,7 @@ int ulsch_decoding_data_2thread0(td_params* tdp) { 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 = get_Qm_ul(ulsch_harq->mcs); + int Q_m = ulsch_harq->Qm; int G = ulsch_harq->G; uint32_t E; uint32_t Gp,GpmodC,Nl=1; @@ -352,7 +352,7 @@ int ulsch_decoding_data_2thread0(td_params* tdp) { 1, ulsch_harq->rvidx, (ulsch_harq->round==0)?1:0, // clear - get_Qm_ul(ulsch_harq->mcs), + ulsch_harq->Qm, 1, r, &E)==-1) { @@ -447,7 +447,7 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr 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 = get_Qm_ul(ulsch_harq->mcs); + int G = ulsch_harq->G; unsigned int E; int Cby2; @@ -571,7 +571,7 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr 1, ulsch_harq->rvidx, (ulsch_harq->round==0)?1:0, // clear - get_Qm_ul(ulsch_harq->mcs), + ulsch_harq->Qm, 1, r, &E)==-1) { @@ -655,7 +655,7 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) 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 = get_Qm_ul(ulsch_harq->mcs); + int G = ulsch_harq->G; unsigned int E; @@ -736,7 +736,7 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) 1, ulsch_harq->rvidx, (ulsch_harq->round==0)?1:0, // clear - get_Qm_ul(ulsch_harq->mcs), + ulsch_harq->Qm, 1, r, &E)==-1) { @@ -907,16 +907,15 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, A = ulsch_harq->TBS; - Q_m = get_Qm_ul(ulsch_harq->mcs); + Q_m = ulsch_harq->Qm; G = nb_rb * (12 * Q_m) * ulsch_harq->Nsymb_pusch; #ifdef DEBUG_ULSCH_DECODING - printf("ulsch_decoding (Nid_cell %d, rnti %x, x2 %x): round %d, RV %d, mcs %d, O_RI %d, O_ACK %d, G %d, subframe %d\n", + printf("ulsch_decoding (Nid_cell %d, rnti %x, x2 %x): round %d, RV %d, O_RI %d, O_ACK %d, G %d, subframe %d\n", frame_parms->Nid_cell,ulsch->rnti,x2, ulsch_harq->round, ulsch_harq->rvidx, - ulsch_harq->mcs, ulsch_harq->O_RI, ulsch_harq->O_ACK, G, @@ -952,12 +951,11 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, } AssertFatal(sumKr>0, - "[eNB %d] ulsch_decoding.c: FATAL sumKr is 0! (Nid_cell %d, rnti %x, x2 %x): harq_pid %d round %d, RV %d, mcs %d, O_RI %d, O_ACK %d, G %d, subframe %d\n", + "[eNB %d] ulsch_decoding.c: FATAL sumKr is 0! (Nid_cell %d, rnti %x, x2 %x): harq_pid %d round %d, RV %d, O_RI %d, O_ACK %d, G %d, subframe %d\n", frame_parms->Nid_cell,ulsch->rnti,x2, harq_pid, ulsch_harq->round, ulsch_harq->rvidx, - ulsch_harq->mcs, ulsch_harq->O_RI, ulsch_harq->O_ACK, G, @@ -2015,41 +2013,6 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, } else *crnti = 0x0; - // Do abstraction here to determine if packet it in error - /* if (ulsch_abstraction_MIESM(eNB->sinr_dB_eNB,1, eNB->ulsch[UE_id]->harq_processes[harq_pid]->mcs,eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, eNB->ulsch[UE_id]->harq_processes[harq_pid]->first_rb) == 1) - flag = 1; - else flag = 0;*/ - - - /* - //SINRdbPost = eNB->sinr_dB_eNB; - mcsPost = eNB->ulsch[UE_id]->harq_processes[harq_pid]->mcs, - nrbPost = eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb; - frbPost = eNB->ulsch[UE_id]->harq_processes[harq_pid]->first_rb; - - - if(nrbPost > 0) - { - SINRdbPost = eNB->sinr_dB_eNB; - ULflag1 = 1; - } - else - { - SINRdbPost = NULL ; - ULflag1 = 0 ; - }*/ - - // - // write_output("postprocSINR.m","SINReNB",eNB->sinr_dB,301,1,7); - - - //Yazdir buraya her frame icin 300 eNb - // fprintf(SINRrx,"%e,%e,%e,%e;\n",SINRdbPost); - //fprintf(SINRrx,"%e\n",SINRdbPost); - - // fprintf(csv_fd,"%e+i*(%e),",channelx,channely); - - // if (ulsch_abstraction(eNB->sinr_dB,1, eNB->ulsch[UE_id]->harq_processes[harq_pid]->mcs,eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, eNB->ulsch[UE_id]->harq_processes[harq_pid]->first_rb) == 1) { if (1) { LOG_D(PHY,"ulsch_decoding_emul abstraction successful\n"); diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c index 18f46adf8f..1c947949a7 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c @@ -1025,381 +1025,16 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext, -#if defined(__x86_64__) || defined(__i386__) -__m128i QAM_amp128U_0,QAM_amp128bU_0,QAM_amp128U_1,QAM_amp128bU_1; -#endif - -void ulsch_channel_compensation_alamouti(int32_t **rxdataF_ext, // For Distributed Alamouti Combining - int32_t **ul_ch_estimates_ext_0, - int32_t **ul_ch_estimates_ext_1, - int32_t **ul_ch_mag_0, - int32_t **ul_ch_magb_0, - int32_t **ul_ch_mag_1, - int32_t **ul_ch_magb_1, - int32_t **rxdataF_comp_0, - int32_t **rxdataF_comp_1, - LTE_DL_FRAME_PARMS *frame_parms, - uint8_t symbol, - uint8_t Qm, - uint16_t nb_rb, - uint8_t output_shift) -{ -#if defined(__x86_64__) || defined(__i386__) - uint16_t rb; - __m128i *ul_ch128_0,*ul_ch128_1,*ul_ch_mag128_0,*ul_ch_mag128_1,*ul_ch_mag128b_0,*ul_ch_mag128b_1,*rxdataF128,*rxdataF_comp128_0,*rxdataF_comp128_1; - uint8_t aarx;//,symbol_mod; - __m128i mmtmpU0,mmtmpU1,mmtmpU2,mmtmpU3; - - // symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - - // printf("comp: symbol %d\n",symbol); - - - if (Qm == 4) { - QAM_amp128U_0 = _mm_set1_epi16(QAM16_n1); - QAM_amp128U_1 = _mm_set1_epi16(QAM16_n1); - } else if (Qm == 6) { - QAM_amp128U_0 = _mm_set1_epi16(QAM64_n1); - QAM_amp128bU_0 = _mm_set1_epi16(QAM64_n2); - - QAM_amp128U_1 = _mm_set1_epi16(QAM64_n1); - QAM_amp128bU_1 = _mm_set1_epi16(QAM64_n2); - } - - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - - ul_ch128_0 = (__m128i *)&ul_ch_estimates_ext_0[aarx][symbol*frame_parms->N_RB_DL*12]; - ul_ch_mag128_0 = (__m128i *)&ul_ch_mag_0[aarx][symbol*frame_parms->N_RB_DL*12]; - ul_ch_mag128b_0 = (__m128i *)&ul_ch_magb_0[aarx][symbol*frame_parms->N_RB_DL*12]; - ul_ch128_1 = (__m128i *)&ul_ch_estimates_ext_1[aarx][symbol*frame_parms->N_RB_DL*12]; - ul_ch_mag128_1 = (__m128i *)&ul_ch_mag_1[aarx][symbol*frame_parms->N_RB_DL*12]; - ul_ch_mag128b_1 = (__m128i *)&ul_ch_magb_1[aarx][symbol*frame_parms->N_RB_DL*12]; - rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128_0 = (__m128i *)&rxdataF_comp_0[aarx][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128_1 = (__m128i *)&rxdataF_comp_1[aarx][symbol*frame_parms->N_RB_DL*12]; - - - for (rb=0; rb<nb_rb; rb++) { - // printf("comp: symbol %d rb %d\n",symbol,rb); - if (Qm>2) { - // get channel amplitude if not QPSK - - mmtmpU0 = _mm_madd_epi16(ul_ch128_0[0],ul_ch128_0[0]); - - mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift); - mmtmpU1 = _mm_madd_epi16(ul_ch128_0[1],ul_ch128_0[1]); - mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift); - mmtmpU0 = _mm_packs_epi32(mmtmpU0,mmtmpU1); - ul_ch_mag128_0[0] = _mm_unpacklo_epi16(mmtmpU0,mmtmpU0); - ul_ch_mag128b_0[0] = ul_ch_mag128_0[0]; - ul_ch_mag128_0[0] = _mm_mulhi_epi16(ul_ch_mag128_0[0],QAM_amp128U_0); - ul_ch_mag128_0[0] = _mm_slli_epi16(ul_ch_mag128_0[0],2); // 2 to compensate the scale channel estimate - ul_ch_mag128_0[1] = _mm_unpackhi_epi16(mmtmpU0,mmtmpU0); - ul_ch_mag128b_0[1] = ul_ch_mag128_0[1]; - ul_ch_mag128_0[1] = _mm_mulhi_epi16(ul_ch_mag128_0[1],QAM_amp128U_0); - ul_ch_mag128_0[1] = _mm_slli_epi16(ul_ch_mag128_0[1],2); // 2 to scale compensate the scale channel estimate - mmtmpU0 = _mm_madd_epi16(ul_ch128_0[2],ul_ch128_0[2]); - mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift); - mmtmpU1 = _mm_packs_epi32(mmtmpU0,mmtmpU0); - ul_ch_mag128_0[2] = _mm_unpacklo_epi16(mmtmpU1,mmtmpU1); - ul_ch_mag128b_0[2] = ul_ch_mag128_0[2]; - ul_ch_mag128_0[2] = _mm_mulhi_epi16(ul_ch_mag128_0[2],QAM_amp128U_0); - ul_ch_mag128_0[2] = _mm_slli_epi16(ul_ch_mag128_0[2],2); // 2 to scale compensate the scale channel estimat - ul_ch_mag128b_0[0] = _mm_mulhi_epi16(ul_ch_mag128b_0[0],QAM_amp128bU_0); - ul_ch_mag128b_0[0] = _mm_slli_epi16(ul_ch_mag128b_0[0],2); // 2 to scale compensate the scale channel estima - ul_ch_mag128b_0[1] = _mm_mulhi_epi16(ul_ch_mag128b_0[1],QAM_amp128bU_0); - ul_ch_mag128b_0[1] = _mm_slli_epi16(ul_ch_mag128b_0[1],2); // 2 to scale compensate the scale channel estima - - ul_ch_mag128b_0[2] = _mm_mulhi_epi16(ul_ch_mag128b_0[2],QAM_amp128bU_0); - ul_ch_mag128b_0[2] = _mm_slli_epi16(ul_ch_mag128b_0[2],2); // 2 to scale compensate the scale channel estima - - - - - mmtmpU0 = _mm_madd_epi16(ul_ch128_1[0],ul_ch128_1[0]); - - mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift); - - mmtmpU1 = _mm_madd_epi16(ul_ch128_1[1],ul_ch128_1[1]); - mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift); - mmtmpU0 = _mm_packs_epi32(mmtmpU0,mmtmpU1); - - ul_ch_mag128_1[0] = _mm_unpacklo_epi16(mmtmpU0,mmtmpU0); - ul_ch_mag128b_1[0] = ul_ch_mag128_1[0]; - ul_ch_mag128_1[0] = _mm_mulhi_epi16(ul_ch_mag128_1[0],QAM_amp128U_1); - ul_ch_mag128_1[0] = _mm_slli_epi16(ul_ch_mag128_1[0],2); // 2 to compensate the scale channel estimate - - ul_ch_mag128_1[1] = _mm_unpackhi_epi16(mmtmpU0,mmtmpU0); - ul_ch_mag128b_1[1] = ul_ch_mag128_1[1]; - ul_ch_mag128_1[1] = _mm_mulhi_epi16(ul_ch_mag128_1[1],QAM_amp128U_1); - ul_ch_mag128_1[1] = _mm_slli_epi16(ul_ch_mag128_1[1],2); // 2 to scale compensate the scale channel estimate - - mmtmpU0 = _mm_madd_epi16(ul_ch128_1[2],ul_ch128_1[2]); - mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift); - mmtmpU1 = _mm_packs_epi32(mmtmpU0,mmtmpU0); - - ul_ch_mag128_1[2] = _mm_unpacklo_epi16(mmtmpU1,mmtmpU1); - ul_ch_mag128b_1[2] = ul_ch_mag128_1[2]; - - ul_ch_mag128_1[2] = _mm_mulhi_epi16(ul_ch_mag128_1[2],QAM_amp128U_0); - ul_ch_mag128_1[2] = _mm_slli_epi16(ul_ch_mag128_1[2],2); // 2 to scale compensate the scale channel estimat - - - ul_ch_mag128b_1[0] = _mm_mulhi_epi16(ul_ch_mag128b_1[0],QAM_amp128bU_1); - ul_ch_mag128b_1[0] = _mm_slli_epi16(ul_ch_mag128b_1[0],2); // 2 to scale compensate the scale channel estima - - - ul_ch_mag128b_1[1] = _mm_mulhi_epi16(ul_ch_mag128b_1[1],QAM_amp128bU_1); - ul_ch_mag128b_1[1] = _mm_slli_epi16(ul_ch_mag128b_1[1],2); // 2 to scale compensate the scale channel estima - - ul_ch_mag128b_1[2] = _mm_mulhi_epi16(ul_ch_mag128b_1[2],QAM_amp128bU_1); - ul_ch_mag128b_1[2] = _mm_slli_epi16(ul_ch_mag128b_1[2],2); // 2 to scale compensate the scale channel estima - } - - - /************************For Computing (y)*(h0*)********************************************/ - - // multiply by conjugated channel - mmtmpU0 = _mm_madd_epi16(ul_ch128_0[0],rxdataF128[0]); - // print_ints("re",&mmtmpU0); - - // mmtmpU0 contains real part of 4 consecutive outputs (32-bit) - mmtmpU1 = _mm_shufflelo_epi16(ul_ch128_0[0],_MM_SHUFFLE(2,3,0,1)); - mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1)); - mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)&conjugate[0]); - // print_ints("im",&mmtmpU1); - mmtmpU1 = _mm_madd_epi16(mmtmpU1,rxdataF128[0]); - // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift); - // print_ints("re(shift)",&mmtmpU0); - mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift); - // print_ints("im(shift)",&mmtmpU1); - mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1); - mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1); - // print_ints("c0",&mmtmpU2); - // print_ints("c1",&mmtmpU3); - rxdataF_comp128_0[0] = _mm_packs_epi32(mmtmpU2,mmtmpU3); - // print_shorts("rx:",rxdataF128[0]); - // print_shorts("ch:",ul_ch128_0[0]); - // print_shorts("pack:",rxdataF_comp128_0[0]); - - // multiply by conjugated channel - mmtmpU0 = _mm_madd_epi16(ul_ch128_0[1],rxdataF128[1]); - // mmtmpU0 contains real part of 4 consecutive outputs (32-bit) - mmtmpU1 = _mm_shufflelo_epi16(ul_ch128_0[1],_MM_SHUFFLE(2,3,0,1)); - mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1)); - mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)conjugate); - mmtmpU1 = _mm_madd_epi16(mmtmpU1,rxdataF128[1]); - // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift); - mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift); - mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1); - mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1); - - rxdataF_comp128_0[1] = _mm_packs_epi32(mmtmpU2,mmtmpU3); - // print_shorts("rx:",rxdataF128[1]); - // print_shorts("ch:",ul_ch128_0[1]); - // print_shorts("pack:",rxdataF_comp128_0[1]); - // multiply by conjugated channel - mmtmpU0 = _mm_madd_epi16(ul_ch128_0[2],rxdataF128[2]); - // mmtmpU0 contains real part of 4 consecutive outputs (32-bit) - mmtmpU1 = _mm_shufflelo_epi16(ul_ch128_0[2],_MM_SHUFFLE(2,3,0,1)); - mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1)); - mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)conjugate); - mmtmpU1 = _mm_madd_epi16(mmtmpU1,rxdataF128[2]); - // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift); - mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift); - mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1); - mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1); - - rxdataF_comp128_0[2] = _mm_packs_epi32(mmtmpU2,mmtmpU3); - // print_shorts("rx:",rxdataF128[2]); - // print_shorts("ch:",ul_ch128_0[2]); - // print_shorts("pack:",rxdataF_comp128_0[2]); - - - - - /*************************For Computing (y*)*(h1)************************************/ - // multiply by conjugated signal - mmtmpU0 = _mm_madd_epi16(ul_ch128_1[0],rxdataF128[0]); - // print_ints("re",&mmtmpU0); - - // mmtmpU0 contains real part of 4 consecutive outputs (32-bit) - mmtmpU1 = _mm_shufflelo_epi16(rxdataF128[0],_MM_SHUFFLE(2,3,0,1)); - mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1)); - mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)&conjugate[0]); - // print_ints("im",&mmtmpU1); - mmtmpU1 = _mm_madd_epi16(mmtmpU1,ul_ch128_1[0]); - // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift); - // print_ints("re(shift)",&mmtmpU0); - mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift); - // print_ints("im(shift)",&mmtmpU1); - mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1); - mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1); - // print_ints("c0",&mmtmpU2); - // print_ints("c1",&mmtmpU3); - rxdataF_comp128_1[0] = _mm_packs_epi32(mmtmpU2,mmtmpU3); - // print_shorts("rx:",rxdataF128[0]); - // print_shorts("ch_conjugate:",ul_ch128_1[0]); - // print_shorts("pack:",rxdataF_comp128_1[0]); - - - // multiply by conjugated signal - mmtmpU0 = _mm_madd_epi16(ul_ch128_1[1],rxdataF128[1]); - // mmtmpU0 contains real part of 4 consecutive outputs (32-bit) - mmtmpU1 = _mm_shufflelo_epi16(rxdataF128[1],_MM_SHUFFLE(2,3,0,1)); - mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1)); - mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)conjugate); - mmtmpU1 = _mm_madd_epi16(mmtmpU1,ul_ch128_1[1]); - // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift); - mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift); - mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1); - mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1); - - rxdataF_comp128_1[1] = _mm_packs_epi32(mmtmpU2,mmtmpU3); - // print_shorts("rx:",rxdataF128[1]); - // print_shorts("ch_conjugate:",ul_ch128_1[1]); - // print_shorts("pack:",rxdataF_comp128_1[1]); - - - // multiply by conjugated signal - mmtmpU0 = _mm_madd_epi16(ul_ch128_1[2],rxdataF128[2]); - // mmtmpU0 contains real part of 4 consecutive outputs (32-bit) - mmtmpU1 = _mm_shufflelo_epi16(rxdataF128[2],_MM_SHUFFLE(2,3,0,1)); - mmtmpU1 = _mm_shufflehi_epi16(mmtmpU1,_MM_SHUFFLE(2,3,0,1)); - mmtmpU1 = _mm_sign_epi16(mmtmpU1,*(__m128i*)conjugate); - mmtmpU1 = _mm_madd_epi16(mmtmpU1,ul_ch128_1[2]); - // mmtmpU1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift); - mmtmpU1 = _mm_srai_epi32(mmtmpU1,output_shift); - mmtmpU2 = _mm_unpacklo_epi32(mmtmpU0,mmtmpU1); - mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1); - - rxdataF_comp128_1[2] = _mm_packs_epi32(mmtmpU2,mmtmpU3); - // print_shorts("rx:",rxdataF128[2]); - // print_shorts("ch_conjugate:",ul_ch128_0[2]); - // print_shorts("pack:",rxdataF_comp128_1[2]); - - - - ul_ch128_0+=3; - ul_ch_mag128_0+=3; - ul_ch_mag128b_0+=3; - ul_ch128_1+=3; - ul_ch_mag128_1+=3; - ul_ch_mag128b_1+=3; - rxdataF128+=3; - rxdataF_comp128_0+=3; - rxdataF_comp128_1+=3; - - } - } - - - _mm_empty(); - _m_empty(); -#endif -} - - - - -void ulsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms,// For Distributed Alamouti Receiver Combining - int32_t **rxdataF_comp, - int32_t **rxdataF_comp_0, - int32_t **rxdataF_comp_1, - int32_t **ul_ch_mag, - int32_t **ul_ch_magb, - int32_t **ul_ch_mag_0, - int32_t **ul_ch_magb_0, - int32_t **ul_ch_mag_1, - int32_t **ul_ch_magb_1, - uint8_t symbol, - uint16_t nb_rb) -{ - -#if defined(__x86_64__) || defined(__i386__) - int16_t *rxF,*rxF0,*rxF1; - __m128i *ch_mag,*ch_magb,*ch_mag0,*ch_mag1,*ch_mag0b,*ch_mag1b; - uint8_t rb,re,aarx; - int32_t jj=(symbol*frame_parms->N_RB_DL*12); - - - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - - rxF = (int16_t*)&rxdataF_comp[aarx][jj]; - rxF0 = (int16_t*)&rxdataF_comp_0[aarx][jj]; // Contains (y)*(h0*) - rxF1 = (int16_t*)&rxdataF_comp_1[aarx][jj]; // Contains (y*)*(h1) - ch_mag = (__m128i *)&ul_ch_mag[aarx][jj]; - ch_mag0 = (__m128i *)&ul_ch_mag_0[aarx][jj]; - ch_mag1 = (__m128i *)&ul_ch_mag_1[aarx][jj]; - ch_magb = (__m128i *)&ul_ch_magb[aarx][jj]; - ch_mag0b = (__m128i *)&ul_ch_magb_0[aarx][jj]; - ch_mag1b = (__m128i *)&ul_ch_magb_1[aarx][jj]; - - for (rb=0; rb<nb_rb; rb++) { - - for (re=0; re<12; re+=2) { - - // Alamouti RX combining - - rxF[0] = rxF0[0] + rxF1[2]; // re((y0)*(h0*))+ re((y1*)*(h1)) = re(x0) - rxF[1] = rxF0[1] + rxF1[3]; // im((y0)*(h0*))+ im((y1*)*(h1)) = im(x0) - - rxF[2] = rxF0[2] - rxF1[0]; // re((y1)*(h0*))- re((y0*)*(h1)) = re(x1) - rxF[3] = rxF0[3] - rxF1[1]; // im((y1)*(h0*))- im((y0*)*(h1)) = im(x1) - - rxF+=4; - rxF0+=4; - rxF1+=4; - } - - // compute levels for 16QAM or 64 QAM llr unit - ch_mag[0] = _mm_adds_epi16(ch_mag0[0],ch_mag1[0]); - ch_mag[1] = _mm_adds_epi16(ch_mag0[1],ch_mag1[1]); - ch_mag[2] = _mm_adds_epi16(ch_mag0[2],ch_mag1[2]); - ch_magb[0] = _mm_adds_epi16(ch_mag0b[0],ch_mag1b[0]); - ch_magb[1] = _mm_adds_epi16(ch_mag0b[1],ch_mag1b[1]); - ch_magb[2] = _mm_adds_epi16(ch_mag0b[2],ch_mag1b[2]); - - ch_mag+=3; - ch_mag0+=3; - ch_mag1+=3; - ch_magb+=3; - ch_mag0b+=3; - ch_mag1b+=3; - } - } - - _mm_empty(); - _m_empty(); - -#endif -} - - - - - -#if defined(__x86_64__) || defined(__i386__) -__m128i avg128U; -#elif defined(__arm__) -int32x4_t avg128U; -#endif void ulsch_channel_level(int32_t **drs_ch_estimates_ext, LTE_DL_FRAME_PARMS *frame_parms, @@ -1410,10 +1045,13 @@ void ulsch_channel_level(int32_t **drs_ch_estimates_ext, int16_t rb; uint8_t aarx; #if defined(__x86_64__) || defined(__i386__) + __m128i avg128U; __m128i *ul_ch128; #elif defined(__arm__) int16x4_t *ul_ch128; + int32x4_t avg128U; #endif + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { //clear average level #if defined(__x86_64__) || defined(__i386__) @@ -1464,8 +1102,7 @@ void ulsch_channel_level(int32_t **drs_ch_estimates_ext, #endif } -int32_t avgU[2]; -int32_t avgU_0[2],avgU_1[2]; // For the Distributed Alamouti Scheme + void rx_ulsch(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, @@ -1482,7 +1119,7 @@ void rx_ulsch(PHY_VARS_eNB *eNB, uint32_t l,i; int32_t avgs; uint8_t log2_maxh=0,aarx; - + int32_t avgU[2]; // uint8_t harq_pid = ( ulsch->RRCConnRequest_flag== 0) ? subframe2harq_pid_tdd(frame_parms->tdd_config,subframe) : 0; @@ -1492,7 +1129,7 @@ void rx_ulsch(PHY_VARS_eNB *eNB, int subframe = proc->subframe_rx; harq_pid = subframe2harq_pid(frame_parms,proc->frame_rx,subframe); - Qm = get_Qm_ul(ulsch[UE_id]->harq_processes[harq_pid]->mcs); + Qm = ulsch[UE_id]->harq_processes[harq_pid]->Qm; #ifdef DEBUG_ULSCH printf("rx_ulsch: harq_pid %d, nb_rb %d first_rb %d\n",harq_pid,ulsch[UE_id]->harq_processes[harq_pid]->nb_rb,ulsch[UE_id]->harq_processes[harq_pid]->first_rb); @@ -1701,8 +1338,8 @@ void rx_ulsch_emul(PHY_VARS_eNB *eNB, harq_pid = subframe2harq_pid(&eNB->frame_parms,proc->frame_rx,subframe); - printf("Dumping ULSCH in subframe %d with harq_pid %d, for NB_rb %d, mcs %d, Qm %d, N_symb %d\n", subframe,harq_pid,eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, - eNB->ulsch[UE_id]->harq_processes[harq_pid]->mcs,get_Qm_ul(eNB->ulsch[UE_id]->harq_processes[harq_pid]->mcs), + printf("Dumping ULSCH in subframe %d with harq_pid %d, for NB_rb %d, TBS %d, Qm %d, N_symb %d\n", subframe,harq_pid,eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, + eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS,eNB->ulsch[UE_id]->harq_processes[harq_pid]->Qm, eNB->ulsch[UE_id]->harq_processes[harq_pid]->Nsymb_pusch); //#ifndef OAI_EMU write_output("/tmp/ulsch_d.m","ulsch_dseq",&eNB->ulsch[UE_id]->harq_processes[harq_pid]->d[0][96], @@ -1739,7 +1376,7 @@ void rx_ulsch_emul(PHY_VARS_eNB *eNB, write_output("/tmp/ulsch_rxF_comp0.m","ulsch0_rxF_comp0",&eNB->pusch_vars[UE_id]->rxdataF_comp[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); // write_output("ulsch_rxF_comp1.m","ulsch0_rxF_comp1",&eNB->pusch_vars[UE_id]->rxdataF_comp[0][1][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); write_output("/tmp/ulsch_rxF_llr.m","ulsch_llr",eNB->pusch_vars[UE_id]->llr, - eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12*get_Qm_ul(eNB->ulsch[UE_id]->harq_processes[harq_pid]->mcs) + eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12*eNB->ulsch[UE_id]->harq_processes[harq_pid]->Qm *eNB->ulsch[UE_id]->harq_processes[harq_pid]->Nsymb_pusch,1,0); write_output("/tmp/ulsch_ch_mag.m","ulsch_ch_mag",&eNB->pusch_vars[UE_id]->ul_ch_mag[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); // write_output("ulsch_ch_mag1.m","ulsch_ch_mag1",&eNB->pusch_vars[UE_id]->ul_ch_mag[1][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index cea702ef78..a3e96e5284 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -180,16 +180,16 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, uint32_t total_dlsch_bitrate = phy_vars_enb->total_dlsch_bitrate; int coded_bits_per_codeword = 0; uint8_t harq_pid; // in TDD config 3 it is sf-2, i.e., can be 0,1,2 - int mcs = 0; + int Qm = 2; // choose max MCS to compute coded_bits_per_codeword if (phy_vars_enb->ulsch[UE_id]!=NULL) { for (harq_pid=0; harq_pid<3; harq_pid++) { - mcs = cmax(phy_vars_enb->ulsch[UE_id]->harq_processes[harq_pid]->mcs,mcs); + Qm = cmax(phy_vars_enb->ulsch[UE_id]->harq_processes[harq_pid]->Qm,Qm); } } - coded_bits_per_codeword = frame_parms->N_RB_UL*12*get_Qm(mcs)*frame_parms->symbols_per_tti; + coded_bits_per_codeword = frame_parms->N_RB_UL*12*Qm*frame_parms->symbols_per_tti; chest_f_abs = (float*) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float)); llr = (float*) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index 2c1ec60967..2ca502d1f6 100644 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -901,6 +901,14 @@ typedef struct PHY_VARS_eNB_s { nfapi_rx_indication_pdu_t rx_pdu_list[NFAPI_RX_IND_MAX_PDU]; /// NFAPI RX ULSCH CRC information nfapi_crc_indication_pdu_t crc_pdu_list[NFAPI_CRC_IND_MAX_PDU]; + /// NFAPI HARQ information + nfapi_harq_indication_pdu_t harq_pdu_list[NFAPI_HARQ_IND_MAX_PDU]; + /// NFAPI SR information + nfapi_sr_indication_pdu_t sr_pdu_list[NFAPI_SR_IND_MAX_PDU]; + /// NFAPI CQI information + nfapi_cqi_indication_pdu_t cqi_pdu_list[NFAPI_CQI_IND_MAX_PDU]; + /// NFAPI CQI information (raw component) + nfapi_cqi_indication_raw_pdu_t cqi_raw_pdu_list[NFAPI_CQI_IND_MAX_PDU]; /// NFAPI PRACH information nfapi_preamble_pdu_t preamble_list[MAX_NUM_RX_PRACH_PREAMBLES]; #ifdef Rel14 @@ -909,13 +917,14 @@ typedef struct PHY_VARS_eNB_s { #endif Sched_Rsp_t Sched_INFO; LTE_eNB_PDCCH pdcch_vars[2]; + LTE_eNB_PHICH phich_vars[2]; #ifdef Rel14 LTE_eNB_EPDCCH epdcch_vars[2]; LTE_eNB_MPDCCH mpdcch_vars[2]; LTE_eNB_PRACH prach_vars_br; #endif LTE_eNB_COMMON common_vars; - LTE_eNB_UCI_t uci_vars[NUMBER_OF_UE_MAX]; + LTE_eNB_UCI uci_vars[NUMBER_OF_UE_MAX]; LTE_eNB_SRS srs_vars[NUMBER_OF_UE_MAX]; LTE_eNB_PBCH pbch; LTE_eNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX]; diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h index 2a0e1dbf50..fd6e36246f 100644 --- a/openair1/PHY/impl_defs_lte.h +++ b/openair1/PHY/impl_defs_lte.h @@ -350,6 +350,14 @@ typedef struct { /// SoundingRS-UL-ConfigDedicated Information Element from 36.331 RRC spec typedef struct { + /// This descriptor is active + uint8_t active; + /// This descriptor's frame + uint16_t frame; + /// This descriptor's subframe + uint8_t subframe; + /// rnti + uint16_t rnti; /// Parameter: \f$B_\text{SRS}\f$, see TS 36.211 (table 5.5.3.2-1, 5.5.3.2-2, 5.5.3.2-3 and 5.5.3.2-4). \vr{[0..3]} \note the specification sais it is an enumerated value. uint8_t srs_Bandwidth; /// Parameter: SRS hopping bandwidth \f$b_\text{hop}\in\{0,1,2,3\}\f$, see TS 36.211 (5.5.3.2) \vr{[0..3]} \note the specification sais it is an enumerated value. @@ -831,6 +839,16 @@ typedef struct { DCI_ALLOC_t dci_alloc[32]; } LTE_eNB_PDCCH; +typedef struct { + uint8_t hi; + uint8_t first_rb; + uint8_t n_DMRS; +} phich_config_t; + +typedef struct { + uint8_t num_hi; + phich_config_t config[32]; +} LTE_eNB_PHICH; typedef struct { uint8_t num_dci; diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index f387dd5efb..14ffc6a5dc 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -95,212 +95,12 @@ int harq_pid_round[NUMBER_OF_UE_MAX][8] = {{0}}; //DCI_ALLOC_t dci_alloc[8]; -uint8_t is_SR_subframe(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,uint8_t UE_id) -{ - - const int subframe = proc->subframe_rx; - const int frame = proc->frame_rx; - - LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Checking for SR TXOp(sr_ConfigIndex %d)\n", - eNB->Mod_id,eNB->ulsch[UE_id]->rnti,frame,subframe, - eNB->scheduling_request_config[UE_id].sr_ConfigIndex); - - if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 4) { // 5 ms SR period - if ((subframe%5) == eNB->scheduling_request_config[UE_id].sr_ConfigIndex) - return(1); - } else if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 14) { // 10 ms SR period - if (subframe==(eNB->scheduling_request_config[UE_id].sr_ConfigIndex-5)) - return(1); - } else if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 34) { // 20 ms SR period - if ((10*(frame&1)+subframe) == (eNB->scheduling_request_config[UE_id].sr_ConfigIndex-15)) - return(1); - } else if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 74) { // 40 ms SR period - if ((10*(frame&3)+subframe) == (eNB->scheduling_request_config[UE_id].sr_ConfigIndex-35)) - return(1); - } else if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 154) { // 80 ms SR period - if ((10*(frame&7)+subframe) == (eNB->scheduling_request_config[UE_id].sr_ConfigIndex-75)) - return(1); - } - - return(0); -} - - -int32_t add_ue(int16_t rnti, PHY_VARS_eNB *eNB) -{ - uint8_t i; - - - LOG_D(PHY,"[eNB %d/%d] Adding UE with rnti %x\n", - eNB->Mod_id, - eNB->CC_id, - (uint16_t)rnti); - - for (i=0; i<NUMBER_OF_UE_MAX; i++) { - if ((eNB->dlsch[i]==NULL) || (eNB->ulsch[i]==NULL)) { - MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed add ue %"PRIx16" (ENOMEM)", rnti); - LOG_E(PHY,"Can't add UE, not enough memory allocated\n"); - return(-1); - } else { - if (eNB->UE_stats[i].crnti==0) { - MSC_LOG_EVENT(MSC_PHY_ENB, "0 Add ue %"PRIx16" ", rnti); - LOG_D(PHY,"UE_id %d associated with rnti %x\n",i, (uint16_t)rnti); - eNB->dlsch[i][0]->rnti = rnti; - eNB->ulsch[i]->rnti = rnti; - eNB->UE_stats[i].crnti = rnti; - - eNB->UE_stats[i].Po_PUCCH1_below = 0; - eNB->UE_stats[i].Po_PUCCH1_above = (int32_t)pow(10.0,.1*(eNB->frame_parms.ul_power_control_config_common.p0_NominalPUCCH+eNB->rx_total_gain_dB)); - eNB->UE_stats[i].Po_PUCCH = (int32_t)pow(10.0,.1*(eNB->frame_parms.ul_power_control_config_common.p0_NominalPUCCH+eNB->rx_total_gain_dB)); - LOG_D(PHY,"Initializing Po_PUCCH: p0_NominalPUCCH %d, gain %d => %d\n", - eNB->frame_parms.ul_power_control_config_common.p0_NominalPUCCH, - eNB->rx_total_gain_dB, - eNB->UE_stats[i].Po_PUCCH); - - return(i); - } - } - } - return(-1); -} - -int mac_phy_remove_ue(module_id_t Mod_idP,rnti_t rntiP) { - uint8_t i; - int CC_id; - PHY_VARS_eNB *eNB; - - for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { - eNB = RC.eNB[Mod_idP][CC_id]; - for (i=0; i<NUMBER_OF_UE_MAX; i++) { - if ((eNB->dlsch[i]==NULL) || (eNB->ulsch[i]==NULL)) { - MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed remove ue %"PRIx16" (ENOMEM)", rntiP); - LOG_E(PHY,"Can't remove UE, not enough memory allocated\n"); - return(-1); - } else { - if (eNB->UE_stats[i].crnti==rntiP) { - MSC_LOG_EVENT(MSC_PHY_ENB, "0 Removed ue %"PRIx16" ", rntiP); - - LOG_D(PHY,"eNB %d removing UE %d with rnti %x\n",eNB->Mod_id,i,rntiP); - - //LOG_D(PHY,("[PHY] UE_id %d\n",i); - clean_eNb_dlsch(eNB->dlsch[i][0]); - clean_eNb_ulsch(eNB->ulsch[i]); - //eNB->UE_stats[i].crnti = 0; - memset(&eNB->UE_stats[i],0,sizeof(LTE_eNB_UE_stats)); - // mac_exit_wrapper("Removing UE"); - - - return(i); - } - } - } - } - MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed remove ue %"PRIx16" (not found)", rntiP); - return(-1); -} - -/* -int8_t find_next_ue_index(PHY_VARS_eNB *eNB) -{ - uint8_t i; - - for (i=0; i<NUMBER_OF_UE_MAX; i++) { - if (eNB->UE_stats[i].crnti==0) { - (eNB->dlsch[i][0]->rnti==0)) - LOG_D(PHY,"Next free UE id is %d\n",i); - return(i); - } - } - - return(-1); -} -*/ - -/* -int get_ue_active_harq_pid(const uint8_t Mod_id,const uint8_t CC_id,const uint16_t rnti, const int frame, const uint8_t subframe,uint8_t *harq_pid,uint8_t *round,const uint8_t harq_flag) -{ - LTE_eNB_DLSCH_t *DLSCH_ptr; - LTE_eNB_ULSCH_t *ULSCH_ptr; - uint8_t ulsch_subframe,ulsch_frame; - int i; - int8_t UE_id = find_ue(rnti,RC.eNB[Mod_id][CC_id]); - - if (UE_id==-1) { - LOG_D(PHY,"Cannot find UE with rnti %x (Mod_id %d, CC_id %d)\n",rnti, Mod_id, CC_id); - *round=0; - return(-1); - } - - if ((harq_flag == openair_harq_DL) || (harq_flag == openair_harq_RA)) {// this is a DL request - - DLSCH_ptr = RC.eNB[Mod_id][CC_id]->dlsch[(uint32_t)UE_id][0]; - - if (harq_flag == openair_harq_RA) { - if (DLSCH_ptr->harq_processes[0] != NULL) { - *harq_pid = 0; - *round = DLSCH_ptr->harq_processes[0]->round; - return 0; - } else { - return -1; - } - } - - // let's go synchronous for the moment - maybe we can change at some point - i = (frame * 10 + subframe) % 8; - - if (DLSCH_ptr->harq_processes[i]->status == ACTIVE) { - *harq_pid = i; - *round = DLSCH_ptr->harq_processes[i]->round; - } else if (DLSCH_ptr->harq_processes[i]->status == SCH_IDLE) { - *harq_pid = i; - *round = 0; - } else { - printf("%s:%d: bad state for harq process - PLEASE REPORT!!\n", __FILE__, __LINE__); - abort(); - } - } else { // This is a UL request - - ULSCH_ptr = RC.eNB[Mod_id][CC_id]->ulsch[(uint32_t)UE_id]; - ulsch_subframe = pdcch_alloc2ul_subframe(&RC.eNB[Mod_id][CC_id]->frame_parms,subframe); - ulsch_frame = pdcch_alloc2ul_frame(&RC.eNB[Mod_id][CC_id]->frame_parms,frame,subframe); - // Note this is for TDD configuration 3,4,5 only - *harq_pid = subframe2harq_pid(&RC.eNB[Mod_id][CC_id]->frame_parms, - ulsch_frame, - ulsch_subframe); - *round = ULSCH_ptr->harq_processes[*harq_pid]->round; - LOG_T(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d Checking HARQ, round %d\n",Mod_id,*harq_pid,frame,subframe,*round); - } - - return(0); -} -*/ - -int16_t get_target_pusch_rx_power(const module_id_t module_idP, const uint8_t CC_id) -{ - return RC.eNB[module_idP][CC_id]->frame_parms.ul_power_control_config_common.p0_NominalPUSCH; -} - -int16_t get_target_pucch_rx_power(const module_id_t module_idP, const uint8_t CC_id) -{ - return RC.eNB[module_idP][CC_id]->frame_parms.ul_power_control_config_common.p0_NominalPUCCH; -} - -void phy_procedures_eNB_S_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,relaying_type_t r_type) -{ - UNUSED(r_type); - int subframe = proc->subframe_rx; - -#ifdef DEBUG_PHY_PROC - LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_S_RX(%d)\n", eNB->Mod_id,proc->frame_rx, subframe); -#endif - - - lte_eNB_I0_measurements(eNB, - subframe, - 0, - eNB->first_run_I0_measurements); - -} +void fill_uci_harq_indication(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); +void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq,uint16_t rnti, int frame,int subframe,int bundling); +void fill_ulsch_cqi_indication(PHY_VARS_eNB *eNB,uint16_t frame,uint8_t subframe,LTE_UL_eNB_HARQ_t *ulsch_harq,uint16_t rnti); +void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe); +void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe); +void fill_crc_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe,uint8_t crc_flag); @@ -513,191 +313,7 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { } -/* -void generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,const int UE_id) { - - LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; - int frame = proc->frame_tx; - int subframe = proc->subframe_tx; - - // if we have SI_RNTI, configure dlsch parameters and CCE index - if (dci_alloc->rnti == SI_RNTI) { - LOG_D(PHY,"Generating dlsch params for SI_RNTI\n"); - - generate_eNB_dlsch_params_from_dci(frame, - subframe, - &dci_alloc->dci_pdu[0], - dci_alloc->rnti, - dci_alloc->format, - &eNB->dlsch_SI, - fp, - NULL, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - 0); - LOG_I(PHY,"frame %d, subframe %d : SI with mcs %d\n",frame,subframe,eNB->dlsch_SI->harq_processes[0]->mcs); - - eNB->dlsch_SI->nCCE[subframe] = dci_alloc->firstCCE; - - LOG_I(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for common DCI (SI) => %"PRIu8", aggregation %d\n",eNB->Mod_id,frame,subframe, - eNB->dlsch_SI->nCCE[subframe],1<<dci_alloc->L); - - } else if (dci_alloc->ra_flag == 1) { // This is format 1A allocation for RA - // configure dlsch parameters and CCE index - LOG_D(PHY,"Generating dlsch params for RA_RNTI\n"); - - generate_eNB_dlsch_params_from_dci(frame, - subframe, - &dci_alloc->dci_pdu[0], - dci_alloc->rnti, - dci_alloc->format, - &eNB->dlsch_ra, - fp, - NULL, - SI_RNTI, - dci_alloc->rnti, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - 0); - - - eNB->dlsch_ra->nCCE[subframe] = dci_alloc->firstCCE; - - LOG_I(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for common DCI (RA) => %"PRIu8" length %d bits\n",eNB->Mod_id,frame,subframe, - eNB->dlsch_ra->nCCE[subframe], - dci_alloc->dci_length); - } - - else if ((dci_alloc->format != format0)&& - (dci_alloc->format != format3)&& - (dci_alloc->format != format3A)&& - (dci_alloc->format != format4)){ // this is a normal DLSCH allocation - - - - if (UE_id>=0) { - LOG_I(PHY,"Generating dlsch params for RNTI %x\n",dci_alloc->rnti); - - generate_eNB_dlsch_params_from_dci(frame, - subframe, - &dci_alloc->dci_pdu[0], - dci_alloc->rnti, - dci_alloc->format, - eNB->dlsch[(uint8_t)UE_id], - fp, - &eNB->pdsch_config_dedicated[UE_id], - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[(uint8_t)UE_id].DL_pmi_single, - eNB->transmission_mode[(uint8_t)UE_id]<7?0:eNB->transmission_mode[(uint8_t)UE_id]); - LOG_D(PHY,"[eNB %"PRIu8"][PDSCH %"PRIx16"/%"PRIu8"] Frame %d subframe %d: Generated dlsch params\n", - eNB->Mod_id,dci_alloc->rnti,eNB->dlsch[(uint8_t)UE_id][0]->current_harq_pid,frame,subframe); - - - T(T_ENB_PHY_DLSCH_UE_DCI, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(UE_id), - T_INT(dci_alloc->rnti), T_INT(dci_alloc->format), - T_INT(dci_alloc->harq_pid), - T_INT(eNB->dlsch[(int)UE_id][0]->harq_processes[dci_alloc->harq_pid]->mcs), - T_INT(eNB->dlsch[(int)UE_id][0]->harq_processes[dci_alloc->harq_pid]->TBS)); - - eNB->dlsch[(uint8_t)UE_id][0]->nCCE[subframe] = dci_alloc->firstCCE; - - LOG_I(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for ue DCI (PDSCH %"PRIx16") => %"PRIu8" length %d bits\n",eNB->Mod_id,frame,subframe, - dci_alloc->rnti,eNB->dlsch[(uint8_t)UE_id][0]->nCCE[subframe],dci_alloc->dci_length); - - LOG_D(PHY,"[eNB %"PRIu8"][DCI][PDSCH %"PRIx16"] Frame %d subframe %d UE_id %"PRId8" Generated DCI format %d, aggregation %d\n", - eNB->Mod_id, dci_alloc->rnti, - frame, subframe,UE_id, - dci_alloc->format, - 1<<dci_alloc->L); - } else { - LOG_D(PHY,"[eNB %"PRIu8"][PDSCH] Frame %d : No UE_id with corresponding rnti %"PRIx16", dropping DLSCH\n", - eNB->Mod_id,frame,dci_alloc->rnti); - } - } - -} - -void generate_eNB_ulsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,const int UE_id) { - int harq_pid; - LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; - int frame = proc->frame_tx; - int subframe = proc->subframe_tx; - -// uint16_t srsPeriodicity=0; -// uint16_t srsOffset=0; -// uint16_t srsConfigIndex=0; -// uint16_t do_srs=0; - - uint16_t is_srs_pos=0; - - LOG_I(PHY, - "[eNB %"PRIu8"][PUSCH %"PRIu8"] Frame %d subframe %d UL Frame %"PRIu32", UL Subframe %"PRIu8", Generated ULSCH (format0) DCI (rnti %"PRIx16", dci %"PRIx8"), aggregation %d\n", - eNB->Mod_id, - subframe2harq_pid(fp, - pdcch_alloc2ul_frame(fp,frame,subframe), - pdcch_alloc2ul_subframe(fp,subframe)), - frame, - subframe, - pdcch_alloc2ul_frame(fp,frame,subframe), - pdcch_alloc2ul_subframe(fp,subframe), - dci_alloc->rnti, - dci_alloc->dci_pdu[0], - 1<<dci_alloc->L); - - is_srs_pos = is_srs_occasion_common(fp,pdcch_alloc2ul_frame(fp,frame,subframe),pdcch_alloc2ul_subframe(fp,subframe)); - -//if (is_srs_pos && eNB->soundingrs_ul_config_dedicated[UE_id].srsConfigDedicatedSetup) { -// srsConfigIndex = eNB->soundingrs_ul_config_dedicated[UE_id].srs_ConfigIndex; -// compute_srs_pos(fp->frame_type, srsConfigIndex, &srsPeriodicity, &srsOffset); -// if ((((10*pdcch_alloc2ul_frame(fp,frame,subframe)+pdcch_alloc2ul_subframe(fp,subframe)) % srsPeriodicity) == srsOffset)) { -// do_srs = 1; -// } -// } -// LOG_D(PHY,"frame %d (%d), subframe %d (%d), UE_id %d: is_srs_pos %d, do_SRS %d, index %d, period %d, offset %d \n", -// frame,pdcch_alloc2ul_frame(fp,frame,subframe),subframe,pdcch_alloc2ul_subframe(fp,subframe), -// UE_id,is_srs_pos,do_srs,srsConfigIndex,srsPeriodicity,srsOffset); -// - - generate_eNB_ulsch_params_from_dci(eNB, - proc, - &dci_alloc->dci_pdu[0], - dci_alloc->rnti, - format0, - UE_id, - SI_RNTI, - 0, - P_RNTI, - CBA_RNTI, - is_srs_pos); - LOG_T(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resources for UE spec DCI (PUSCH %"PRIx16") => %d\n", - eNB->Mod_id,frame,subframe,dci_alloc->rnti, - dci_alloc->firstCCE); - - // get the hard_pid for this subframe - harq_pid = subframe2harq_pid(fp, - pdcch_alloc2ul_frame(fp,frame,subframe), - pdcch_alloc2ul_subframe(fp,subframe)); - - AssertFatal(harq_pid!=255,"[eNB %"PRIu8"] Frame %d: Bad harq_pid for ULSCH allocation\n",eNB->Mod_id,frame); - - eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1; - - T(T_ENB_PHY_ULSCH_UE_DCI, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(UE_id), - T_INT(dci_alloc->rnti), T_INT(harq_pid), - T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->mcs), - T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->round), - T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->first_rb), - T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->nb_rb), - T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->TBS), - T_INT(dci_alloc->L), - T_INT(dci_alloc->firstCCE)); -} -*/ void pdsch_procedures(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, @@ -712,11 +328,10 @@ void pdsch_procedures(PHY_VARS_eNB *eNB, LTE_DL_eNB_HARQ_t *dlsch_harq=dlsch->harq_processes[harq_pid]; int input_buffer_length = dlsch_harq->TBS/8; LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; - int i; if (frame < 20) { - LOG_D(PHY, + LOG_I(PHY, "[eNB %"PRIu8"][PDSCH %"PRIx16"/%"PRIu8"] Frame %d, subframe %d: Generating PDSCH/DLSCH with input size = %"PRIu16", pdsch_start %d, G %d, nb_rb %"PRIu16", rb0 %x, rb1 %x, TBS %"PRIu16", pmi_alloc %"PRIx64", rv %"PRIu8" (round %"PRIu8")\n", eNB->Mod_id, dlsch->rnti,harq_pid, frame, subframe, input_buffer_length, dlsch_harq->pdsch_start, @@ -777,8 +392,9 @@ void pdsch_procedures(PHY_VARS_eNB *eNB, LOG_D(PHY,"Generating DLSCH/PDSCH %d\n",ra_flag); - // 36-212 + // 36-212 start_meas(&eNB->dlsch_encoding_stats); + AssertFatal(dlsch_harq->pdu!=NULL,"dlsch_harq->pdu == NULL (rnti %x)\n",dlsch->rnti); eNB->te(eNB, dlsch_harq->pdu, dlsch_harq->pdsch_start, @@ -858,13 +474,12 @@ void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu); void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, - nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) { + nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu){ int idx = proc->subframe_tx&1; LTE_eNB_PDCCH *pdcch_vars = &eNB->pdcch_vars[idx]; - nfapi_hi_dci0_dci_pdu *pdu = &hi_dci0_config_pdu->dci_pdu; // copy dci configuration in to eNB structure - fill_dci_and_ulsch(eNB,proc,&pdcch_vars->dci_alloc[pdcch_vars->num_dci],pdu); + fill_dci0(eNB,proc,&pdcch_vars->dci_alloc[pdcch_vars->num_dci], &hi_dci0_config_pdu->dci_pdu); } void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, @@ -875,17 +490,25 @@ void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) { nfapi_hi_dci0_hi_pdu *pdu = &hi_dci0_config_pdu->hi_pdu; + LTE_eNB_PHICH *phich = &eNB->phich_vars[proc->subframe_tx&1]; + // copy dci configuration in to eNB structure LOG_D(PHY,"Received HI PDU which value %d (rbstart %d,cshift %d)\n", hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.hi_value, hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.resource_block_start, hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms); -} -handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, - nfapi_dl_config_request_pdu_t *dl_config_pdu, - uint8_t *sdu) { + phich->config[phich->num_hi].hi = hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.hi_value; + phich->config[phich->num_hi].first_rb = hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.resource_block_start; + phich->config[phich->num_hi].n_DMRS = hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms; + phich->num_hi++; + AssertFatal(phich->num_hi<32,"Maximum number of phich reached in subframe\n"); +} +void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, + nfapi_dl_config_request_pdu_t *dl_config_pdu, + uint8_t *sdu) { + nfapi_dl_config_bch_pdu_rel8_t *rel8 = &dl_config_pdu->bch_pdu.bch_pdu_rel8; AssertFatal(rel8->length == 3, "BCH PDU has length %d != 3\n",rel8->length); @@ -910,10 +533,10 @@ extern uint32_t localRIV2alloc_LUT100_2[6000]; extern uint32_t localRIV2alloc_LUT100_3[6000]; #endif -handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, - nfapi_dl_config_request_pdu_t *dl_config_pdu, - uint8_t codeword_index, - uint8_t *sdu) { +void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, + nfapi_dl_config_request_pdu_t *dl_config_pdu, + uint8_t codeword_index, + uint8_t *sdu) { nfapi_dl_config_dlsch_pdu_rel8_t *rel8 = &dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8; #ifndef Rel8 @@ -926,7 +549,7 @@ handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL; int UE_id; int harq_pid; - + UE_id = find_dlsch(rel8->rnti,eNB,SEARCH_EXIST_OR_FREE); AssertFatal(UE_id!=-1,"no free or exiting dlsch_context\n"); @@ -945,12 +568,15 @@ handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, dlsch1_harq = dlsch1->harq_processes[harq_pid]; AssertFatal(dlsch0_harq!=NULL,"dlsch_harq is null\n"); + dlsch0_harq->pdsch_start = eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols; - LOG_D(PHY,"NFAPI: frame %d, subframe %d: programming dlsch, rnti %x, UE_id %d, harq_pid %d\n", - proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid); - if (codeword_index == 0) dlsch0_harq->pdu = sdu; - else dlsch1_harq->pdu = sdu; + if (dlsch0_harq->round==0) { //get pointer to SDU if this a new SDU + LOG_I(PHY,"NFAPI: frame %d, subframe %d: programming dlsch, rnti %x, UE_id %d, harq_pid %d\n", + proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid); + if (codeword_index == 0) dlsch0_harq->pdu = sdu; + else dlsch1_harq->pdu = sdu; + } #ifdef Rel14 dlsch0->sib1_br_flag=0; @@ -1005,131 +631,330 @@ handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, dlsch0_harq->codeword = 0; } else { - + dlsch0->i0 = 0xFFFF; } #endif } -handle_uci_harq_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,nfapi_ul_config_request_pdu_t *ul_config_pdu) { +uint16_t to_beta_offset_harqack[16]={16,20,25,32,40,50,64,80,101,127,160,248,400,640,1008,8}; +void handle_ulsch_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe) { + + nfapi_ul_config_ulsch_pdu_rel8_t *rel8 = &ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8; + + LTE_eNB_ULSCH_t *ulsch=eNB->ulsch[UE_id]; + LTE_UL_eNB_HARQ_t *ulsch_harq; + nfapi_ul_config_ulsch_harq_information *harq_information = &ul_config_pdu->ulsch_harq_pdu.harq_information; + + int harq_pid = rel8->harq_process_number; + ulsch_harq = ulsch->harq_processes[harq_pid]; + ulsch_harq->frame = frame; + ulsch_harq->subframe = subframe; + ulsch_harq->O_ACK = harq_information->harq_information_rel10.harq_size; + ulsch->beta_offset_harqack_times8 = to_beta_offset_harqack[harq_information->harq_information_rel10.delta_offset_harq]; } -handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, - nfapi_ul_config_request_pdu_t *ul_config_pdu) { +uint16_t to_beta_offset_ri[16]={9,13,16,20,25,32,40,50,64,80,101,127,160,0,0,0}; +uint16_t to_beta_offset_cqi[16]={0,0,9,10,11,13,14,16,18,20,23,25,28,32,40,50}; - nfapi_ul_config_ulsch_pdu_rel8_t *rel8 = &ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8; +void handle_ulsch_cqi_ri_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe) { + + nfapi_ul_config_cqi_ri_information_rel9_t *rel9 = &ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9; + + LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id]; + int harq_pid = ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number; + LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid]; + + ulsch_harq->frame = frame; + ulsch_harq->subframe = subframe; + ulsch_harq->O_RI = rel9->aperiodic_cqi_pmi_ri_report.cc[0].ri_size; + ulsch_harq->Or1 = rel9->aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[0]; + if (ulsch_harq->O_RI>1) ulsch_harq->Or2 = rel9->aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[1]; + ulsch->beta_offset_ri_times8 = to_beta_offset_ri[rel9->delta_offset_ri]; + ulsch->beta_offset_cqi_times8 = to_beta_offset_cqi[rel9->delta_offset_cqi]; +} + +void handle_ulsch_cqi_harq_ri_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe) { + + nfapi_ul_config_cqi_ri_information_rel9_t *rel9 = &ul_config_pdu->ulsch_cqi_harq_ri_pdu.cqi_ri_information.cqi_ri_information_rel9; + + LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id]; + int harq_pid = ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number; + LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid]; + nfapi_ul_config_ulsch_harq_information *harq_information = &ul_config_pdu->ulsch_cqi_harq_ri_pdu.harq_information; + + ulsch_harq->frame = frame; + ulsch_harq->subframe = subframe; + ulsch_harq->O_RI = rel9->aperiodic_cqi_pmi_ri_report.cc[0].ri_size; + ulsch_harq->Or1 = rel9->aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[0]; + ulsch_harq->O_ACK = harq_information->harq_information_rel10.harq_size; + + if (ulsch_harq->O_RI>1) ulsch_harq->Or2 = rel9->aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[1]; + + ulsch->beta_offset_harqack_times8 = to_beta_offset_harqack[harq_information->harq_information_rel10.delta_offset_harq]; + ulsch->beta_offset_ri_times8 = to_beta_offset_ri[rel9->delta_offset_ri]; + ulsch->beta_offset_cqi_times8 = to_beta_offset_cqi[rel9->delta_offset_cqi]; + +} + +void handle_uci_harq_information(PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci,nfapi_ul_config_harq_information *harq_information) { + + + if (eNB->frame_parms.frame_type == FDD) { + uci->num_pucch_resources = harq_information->harq_information_rel9_fdd.number_of_pucch_resources; + + LOG_I(PHY,"Programming UCI HARQ mode %d : size %d in (%d,%d)\n", + harq_information->harq_information_rel9_fdd.ack_nack_mode, + harq_information->harq_information_rel9_fdd.harq_size, + uci->frame,uci->subframe); + + if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 0) && + (harq_information->harq_information_rel9_fdd.harq_size == 1)) { + uci->pucch_fmt = pucch_format1a; + uci->n_pucch_1[0][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_0; + uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0; + } + else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 0) && + (harq_information->harq_information_rel9_fdd.harq_size == 2)) { + uci->pucch_fmt = pucch_format1b; + uci->n_pucch_1[0][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_0; + uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0; + } + else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 1) && + (harq_information->harq_information_rel9_fdd.harq_size == 2)) { + uci->pucch_fmt = pucch_format1b_csA2; + uci->n_pucch_1[0][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_0; + uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0; + uci->n_pucch_1[1][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_1; + uci->n_pucch_1[1][1] = harq_information->harq_information_rel11.n_pucch_2_1; + } + else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 1) && + (harq_information->harq_information_rel9_fdd.harq_size == 3)) { + uci->pucch_fmt = pucch_format1b_csA3; + uci->n_pucch_1[0][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_0; + uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0; + uci->n_pucch_1[1][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_1; + uci->n_pucch_1[1][1] = harq_information->harq_information_rel11.n_pucch_2_1; + uci->n_pucch_1[2][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_2; + uci->n_pucch_1[2][1] = harq_information->harq_information_rel11.n_pucch_2_2; + } + else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 1) && + (harq_information->harq_information_rel9_fdd.harq_size == 4)) { + uci->pucch_fmt = pucch_format1b_csA4; + uci->n_pucch_1[0][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_0; + uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0; + uci->n_pucch_1[1][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_1; + uci->n_pucch_1[1][1] = harq_information->harq_information_rel11.n_pucch_2_1; + uci->n_pucch_1[2][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_2; + uci->n_pucch_1[2][1] = harq_information->harq_information_rel11.n_pucch_2_2; + } + else if (harq_information->harq_information_rel9_fdd.ack_nack_mode == 2) { + uci->pucch_fmt = pucch_format3; + uci->n_pucch_3[0] = harq_information->harq_information_rel9_fdd.n_pucch_1_0; + uci->n_pucch_3[1] = harq_information->harq_information_rel11.n_pucch_2_0; + } + else AssertFatal(1==0,"unsupported HARQ mode %d\n",harq_information->harq_information_rel9_fdd.ack_nack_mode); + } + else { // TDD + uci->num_pucch_resources = harq_information->harq_information_rel10_tdd.number_of_pucch_resources; + + if (harq_information->harq_information_rel10_tdd.ack_nack_mode == 0) {//bundling + + uci->pucch_fmt = harq_information->harq_information_rel10_tdd.harq_size==1 ? pucch_format1a : pucch_format1b; + uci->tdd_bundling = 1; + uci->n_pucch_1[0][0] = harq_information->harq_information_rel10_tdd.n_pucch_1_0; + uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0; + } + else if ((harq_information->harq_information_rel10_tdd.ack_nack_mode == 1) && //multiplexing + (uci->num_pucch_resources == 1)) { + uci->pucch_fmt = harq_information->harq_information_rel10_tdd.harq_size==1 ? pucch_format1a : pucch_format1b; + uci->tdd_bundling = 0; + uci->n_pucch_1[0][0] = harq_information->harq_information_rel10_tdd.n_pucch_1_0; + uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0; + } + else if ((harq_information->harq_information_rel10_tdd.ack_nack_mode == 1) && //multiplexing M>1 + (uci->num_pucch_resources > 1)) { + uci->pucch_fmt = pucch_format1b; + uci->tdd_bundling = 0; + uci->n_pucch_1[0][0] = harq_information->harq_information_rel10_tdd.n_pucch_1_0; + uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0; + uci->n_pucch_1[1][0] = harq_information->harq_information_rel10_tdd.n_pucch_1_1; + uci->n_pucch_1[1][1] = harq_information->harq_information_rel11.n_pucch_2_1; + uci->n_pucch_1[2][0] = harq_information->harq_information_rel10_tdd.n_pucch_1_2; + uci->n_pucch_1[2][1] = harq_information->harq_information_rel11.n_pucch_2_2; + uci->n_pucch_1[3][0] = harq_information->harq_information_rel10_tdd.n_pucch_1_3; + uci->n_pucch_1[3][1] = harq_information->harq_information_rel11.n_pucch_2_3; + } + else if (harq_information->harq_information_rel10_tdd.ack_nack_mode == 2) { + uci->pucch_fmt = pucch_format3; + uci->n_pucch_3[0] = harq_information->harq_information_rel10_tdd.n_pucch_1_0; + uci->n_pucch_3[1] = harq_information->harq_information_rel11.n_pucch_2_0; + } + else AssertFatal(1==0,"unsupported HARQ mode %d\n",harq_information->harq_information_rel10_tdd.ack_nack_mode); + } +} + +void handle_uci_sr_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe,uint8_t srs_active) { + LTE_eNB_UCI *uci = &eNB->uci_vars[UE_id]; + + uci->frame = frame; + uci->subframe = subframe; + uci->rnti = ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti; + uci->type = SR; + uci->pucch_fmt = pucch_format1; + uci->num_antenna_ports = 1; + uci->num_pucch_resources = 1; + uci->n_pucch_1_0_sr[0] = ul_config_pdu->uci_sr_pdu.sr_information.sr_information_rel8.pucch_index; + uci->srs_active = srs_active; + uci->active = 1; + + LOG_I(PHY,"Programming UCI SR rnti %x, pucch1_0 %d for (%d,%d)\n", + uci->rnti,uci->n_pucch_1_0_sr[0],frame,subframe); + + +} + +void handle_uci_sr_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe,uint8_t srs_active) { + + LTE_eNB_UCI *uci = &eNB->uci_vars[UE_id]; + + uci->frame = frame; + uci->subframe = subframe; + uci->rnti = ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti; + uci->type = HARQ_SR; + uci->num_antenna_ports = 1; + uci->num_pucch_resources = 1; + uci->n_pucch_1_0_sr[0] = ul_config_pdu->uci_sr_harq_pdu.sr_information.sr_information_rel8.pucch_index; + uci->srs_active = srs_active; + uci->active = 1; + + + handle_uci_harq_information(eNB,uci,&ul_config_pdu->uci_sr_harq_pdu.harq_information); +} + +void handle_uci_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe,uint8_t srs_active) { + + LTE_eNB_UCI *uci = &eNB->uci_vars[UE_id]; + + uci->frame = frame; + uci->subframe = subframe; + uci->rnti = ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti; + uci->type = HARQ; + uci->srs_active = srs_active; + uci->num_antenna_ports = ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel11.num_ant_ports; + + handle_uci_harq_information(eNB,uci,&ul_config_pdu->uci_harq_pdu.harq_information); + + uci->active=1; + +} + + +void handle_srs_pdu(PHY_VARS_eNB *eNB,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe) { + + int i; + + for (i=0;i<NUMBER_OF_UE_MAX;i++) { + + if (eNB->soundingrs_ul_config_dedicated[i].active==1) continue; + + eNB->soundingrs_ul_config_dedicated[i].active = 1; + eNB->soundingrs_ul_config_dedicated[i].frame = frame; + eNB->soundingrs_ul_config_dedicated[i].subframe = subframe; + eNB->soundingrs_ul_config_dedicated[i].rnti = ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti; + eNB->soundingrs_ul_config_dedicated[i].srs_Bandwidth = ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_bandwidth; + eNB->soundingrs_ul_config_dedicated[i].srs_HoppingBandwidth = ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth; + eNB->soundingrs_ul_config_dedicated[i].freqDomainPosition = ul_config_pdu->srs_pdu.srs_pdu_rel8.frequency_domain_position; + eNB->soundingrs_ul_config_dedicated[i].transmissionComb = ul_config_pdu->srs_pdu.srs_pdu_rel8.transmission_comb; + eNB->soundingrs_ul_config_dedicated[i].srs_ConfigIndex = ul_config_pdu->srs_pdu.srs_pdu_rel8.i_srs; + eNB->soundingrs_ul_config_dedicated[i].cyclicShift = ul_config_pdu->srs_pdu.srs_pdu_rel8.sounding_reference_cyclic_shift; + break; + } + AssertFatal(i<NUMBER_OF_UE_MAX,"No room for SRS processing\n"); +} - uint16_t *RIV2nb_rb_LUT, *RIV2first_rb_LUT; - uint16_t RIV_max; - uint16_t use_srs=0; +void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, + nfapi_ul_config_request_pdu_t *ul_config_pdu, + uint16_t frame,uint8_t subframe,uint8_t srs_present) { + + nfapi_ul_config_ulsch_pdu_rel8_t *rel8 = &ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8; int8_t UE_id; - LTE_eNB_ULSCH_t *ulsch; - LTE_UL_eNB_HARQ_t *ulsch_harq; // check if we have received a dci for this ue and ulsch descriptor is configured - if (ul_config_pdu == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) { - AssertFatal((UE_id = find_ulsch(rel8->rnti,eNB,SEARCH_EXIST))>=0, + if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) { + AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST))>=0, "No existing UE ULSCH for rnti %x\n",rel8->rnti); AssertFatal(eNB->ulsch[UE_id]->harq_mask > 0, "ulsch for UE_id %d is not active\n",UE_id); - LOG_I(PHY,"Applying UL config for UE %d, rnti %x\n", - UE_id,rel8->rnti); - /* -#ifdef Rel14 - nfapi_ul_config_ulsch_pdu_rel13_t *rel13 = &ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13; - int harq_pid = rel8->harq_process_number; + LOG_I(PHY,"Applying UL config for UE %d, rnti %x for frame %d, subframe %d\n", + UE_id,rel8->rnti,frame,subframe); - if (rel13->ue_type > 0) { // This is a BL/CE UE, retrieve PUSCH programming - ulsch = eNB->ulsch[UE_id]; - - ulsch_harq = ulsch->harq_processes[harq_pid]; - - switch (eNB->frame_parms.N_RB_DL) { - case 6: - RIV2nb_rb_LUT = &RIV2nb_rb_LUT6[0]; - RIV2first_rb_LUT = &RIV2first_rb_LUT6[0]; - RIV_max = RIV_max6; - break; - - case 25: - RIV2nb_rb_LUT = &RIV2nb_rb_LUT25[0]; - RIV2first_rb_LUT = &RIV2first_rb_LUT25[0]; - RIV_max = RIV_max25; - break; - - case 50: - RIV2nb_rb_LUT = &RIV2nb_rb_LUT50[0]; - RIV2first_rb_LUT = &RIV2first_rb_LUT50[0]; - RIV_max = RIV_max50; - break; - - case 100: - RIV2nb_rb_LUT = &RIV2nb_rb_LUT100[0]; - RIV2first_rb_LUT = &RIV2first_rb_LUT100[0]; - RIV_max = RIV_max100; - break; - - default: - DevParam(frame_parms->N_RB_DL, harq_pid, 0); - break; - } - - - ulsch_harq->first_rb = rel8->resource_block_start; - ulsch_harq->nb_rb = rel8->number_of_resource_blocks; - ulsch_harq->O_RI = 0;//1; - ulsch_harq->Or2 = 0; - ulsch_harq->Or1 = 0; - ulsch_harq->O_ACK = 0;//2; - ulsch->beta_offset_cqi_times8 = 18; - ulsch->beta_offset_ri_times8 = 10; - ulsch->beta_offset_harqack_times8 = 16; - - ulsch->rnti = rel8->rnti; - ulsch->harq_mask = 1<<harq_pid; - - if (ulsch_harq->round == 0) { - ulsch_harq->status = ACTIVE; - ulsch_harq->rvidx = 0; - //ulsch_harq->TBS = dlsch_tbs25[ulsch_harq->mcs][ulsch_harq->nb_rb-1]; - ulsch_harq->TBS = TBStable[get_I_TBS_UL(ulsch_harq->mcs)][ulsch_harq->nb_rb-1]; - ulsch_harq->Msc_initial = 12*ulsch_harq->nb_rb; - ulsch_harq->Nsymb_initial = 9; - ulsch_harq->round = 0; - } else { - ulsch_harq->rvidx = 0; - ulsch_harq->round++; - } - use_srs = is_srs_occasion_common(frame_parms,ulsch_harq->frame,ulsch_harq->subframe); - ulsch_harq->Nsymb_pusch = 12-(frame_parms->Ncp<<1)-(use_srs==0?0:1); - ulsch_harq->srs_active = use_srs; - } - #endif -*/ + fill_ulsch(eNB,&ul_config_pdu->ulsch_pdu,frame,subframe); + + } + + else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) { + AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0, + "No available UE ULSCH for rnti %x\n",ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti); + AssertFatal(eNB->ulsch[UE_id]->harq_mask > 0, + "ulsch for UE_id %d is not active\n",UE_id); + + fill_ulsch(eNB,&ul_config_pdu->ulsch_harq_pdu.ulsch_pdu,frame,subframe); + handle_ulsch_harq_pdu(eNB,UE_id,ul_config_pdu,frame,subframe); + + } + else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) { + AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti, + eNB,SEARCH_EXIST_OR_FREE))>=0, + "No available UE ULSCH for rnti %x\n",ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti); + AssertFatal(eNB->ulsch[UE_id]->harq_mask > 0, + "ulsch for UE_id %d is not active\n",UE_id); + fill_ulsch(eNB,&ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu,frame,subframe); + handle_ulsch_cqi_ri_pdu(eNB,UE_id,ul_config_pdu,frame,subframe); + + } + else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE) { + AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti, + eNB,SEARCH_EXIST_OR_FREE))>=0, + "No available UE ULSCH for rnti %x\n",ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti); + AssertFatal(eNB->ulsch[UE_id]->harq_mask > 0, + "ulsch for UE_id %d is not active\n",UE_id); + fill_ulsch(eNB,&ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu,frame,subframe); + handle_ulsch_cqi_harq_ri_pdu(eNB,UE_id,ul_config_pdu,frame,subframe); + + } + else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) { + AssertFatal((UE_id = find_uci(ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti, + proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST_OR_FREE))>=0, + "No available UE UCI for rnti %x\n",ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti); + handle_uci_harq_pdu(eNB,UE_id,ul_config_pdu,frame,subframe,srs_present); } - else if (ul_config_pdu == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) { - AssertFatal((UE_id = find_uci(rel8->rnti,proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST))>=0, - "No existing UE UCI for rnti %x\n",rel8->rnti); - handle_uci_harq_pdu(eNB,proc,ul_config_pdu); + else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE) { + AssertFatal(1==0,"NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE not handled yet\n"); } - else if (ul_config_pdu == NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE) { - + else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE) { + AssertFatal(1==0,"NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE not handled yet\n"); } - else if (ul_config_pdu == NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE) { - + else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE) { + AssertFatal(1==0,"NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE not handled yet\n"); } - else if (ul_config_pdu == NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE) { + else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE) { + AssertFatal((UE_id = find_uci(ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti, + proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST_OR_FREE))>=0, + "No available UE UCI for rnti %x\n",ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti); + handle_uci_sr_pdu(eNB,UE_id,ul_config_pdu,frame,subframe,srs_present); } - else if (ul_config_pdu == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE) { - + else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE) { + AssertFatal((UE_id = find_uci(rel8->rnti,proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST_OR_FREE))>=0, + "No available UE UCI for rnti %x\n",ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti); + handle_uci_sr_harq_pdu(eNB,UE_id,ul_config_pdu,frame,subframe,srs_present); } - else if (ul_config_pdu == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE) { - + else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_SRS_PDU_TYPE) { + handle_srs_pdu(eNB,ul_config_pdu,frame,subframe); } - } void schedule_response(Sched_Rsp_t *Sched_INFO) { @@ -1164,12 +989,9 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { AssertFatal(proc->subframe_tx == subframe, "Current subframe %d != NFAPI subframe %d\n",proc->subframe_tx,subframe); AssertFatal(proc->subframe_tx == subframe, "Current frame %d != NFAPI frame %d\n",proc->frame_tx,frame); - int8_t UE_id; uint8_t number_dl_pdu = DL_req->dl_config_request_body.number_pdu; uint8_t number_hi_dci0_pdu = HI_DCI0_req->hi_dci0_request_body.number_of_dci+HI_DCI0_req->hi_dci0_request_body.number_of_hi; uint8_t number_ul_pdu = UL_req->ul_config_request_body.number_of_pdus; - uint8_t number_pdsch_rnti = DL_req->dl_config_request_body.number_pdsch_rnti; - uint8_t transmission_power_pcfich = DL_req->dl_config_request_body.transmission_power_pcfich; nfapi_dl_config_request_pdu_t *dl_config_pdu; @@ -1180,10 +1002,10 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { eNB->pdcch_vars[subframe&1].num_pdcch_symbols = DL_req->dl_config_request_body.number_pdcch_ofdm_symbols; eNB->pdcch_vars[subframe&1].num_dci = 0; + eNB->phich_vars[subframe&1].num_hi = 0; - - LOG_D(PHY,"NFAPI: received %d dl_pdu, %d tx_req, %d hi_dci0_config_req, %d UL_config \n", - number_dl_pdu,TX_req->tx_request_body.number_of_pdus,number_hi_dci0_pdu,number_ul_pdu); + LOG_I(PHY,"NFAPI: Frame %d, Subframe %d: received %d dl_pdu, %d tx_req, %d hi_dci0_config_req, %d UL_config \n", + frame,subframe,number_dl_pdu,TX_req->tx_request_body.number_of_pdus,number_hi_dci0_pdu,number_ul_pdu); if ((subframe_select(fp,ul_subframe)==SF_UL) || @@ -1202,7 +1024,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { } for (i=0;i<number_dl_pdu;i++) { dl_config_pdu = &DL_req->dl_config_request_body.dl_config_pdu_list[i]; - LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_config_pdu->pdu_type); + LOG_I(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_config_pdu->pdu_type); switch (dl_config_pdu->pdu_type) { case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: handle_nfapi_dci_dl_pdu(eNB,proc,dl_config_pdu); @@ -1233,7 +1055,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks-1, TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data); if (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == eNB->preamble_list[0].preamble_rel8.rnti) {// is RAR pdu - LOG_I(PHY,"Frame %d, Subframe %d: Received LTE RAR pdu, programming based on UL Grant\n"); + LOG_I(PHY,"Frame %d, Subframe %d: Received LTE RAR pdu, programming based on UL Grant\n",frame,subframe); generate_eNB_ulsch_params_from_rar(eNB, TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data, frame, @@ -1261,9 +1083,14 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { } for (i=0;i<number_hi_dci0_pdu;i++) { + hi_dci0_req_pdu = &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[i]; + + LOG_I(PHY,"NFAPI: hi_dci0_pdu %d : type %d\n",i,hi_dci0_req_pdu->pdu_type); + switch (hi_dci0_req_pdu->pdu_type) { + case NFAPI_HI_DCI0_DCI_PDU_TYPE: handle_nfapi_hi_dci0_dci_pdu(eNB,proc,hi_dci0_req_pdu); eNB->pdcch_vars[subframe&1].num_dci++; @@ -1271,7 +1098,6 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { case NFAPI_HI_DCI0_HI_PDU_TYPE: handle_nfapi_hi_dci0_hi_pdu(eNB,proc,hi_dci0_req_pdu); - eNB->pdcch_vars[subframe&1].num_dci++; break; } @@ -1281,9 +1107,15 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) { ul_config_pdu = &UL_req->ul_config_request_body.ul_config_pdu_list[i]; LOG_I(PHY,"NFAPI: ul_pdu %d : type %d\n",i,ul_config_pdu->pdu_type); AssertFatal(ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE || - ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE, + ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE || + ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE || + ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE || + ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE || + ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE || + ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE + , "Optional UL_PDU type %d not supported\n",ul_config_pdu->pdu_type); - handle_nfapi_ul_pdu(eNB,proc,ul_config_pdu); + handle_nfapi_ul_pdu(eNB,proc,ul_config_pdu,UL_req->sfn_sf>>4,UL_req->sfn_sf&0xf,UL_req->ul_config_request_body.srs_present); } } @@ -1298,7 +1130,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, UNUSED(rn); int frame=proc->frame_tx; int subframe=proc->subframe_tx; - uint32_t i,j,aa; + uint32_t i,aa; uint8_t harq_pid; int8_t UE_id=0; uint8_t num_pdcch_symbols=0; @@ -1317,39 +1149,6 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, T(T_ENB_PHY_DL_TICK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe)); - /* - for (i=0; i<NUMBER_OF_UE_MAX; i++) { - // If we've dropped the UE, go back to PRACH mode for this UE - if ((frame==0)&&(subframe==0)) { - if (eNB->UE_stats[i].crnti > 0) { - LOG_I(PHY,"UE %d : rnti %x\n",i,eNB->UE_stats[i].crnti); - } - } - if (eNB->UE_stats[i].ulsch_consecutive_errors == ULSCH_max_consecutive_errors) { - LOG_W(PHY,"[eNB %d, CC %d] frame %d, subframe %d, UE %d: ULSCH consecutive error count reached %u, triggering UL Failure\n", - eNB->Mod_id,eNB->CC_id,frame,subframe, i, eNB->UE_stats[i].ulsch_consecutive_errors); - eNB->UE_stats[i].ulsch_consecutive_errors=0; - mac_xface->UL_failure_indication(eNB->Mod_id, - eNB->CC_id, - frame, - eNB->UE_stats[i].crnti, - subframe); - - } - - - } - - - // Get scheduling info for next subframe - // This is called only for the CC_id = 0 and triggers scheduling for all CC_id's - if (eNB->mac_enabled==1) { - if (eNB->CC_id == 0) { - mac_xface->eNB_dlsch_ulsch_scheduler(eNB->Mod_id,0,frame,subframe);//,1); - } - } - */ - // clear the transmit data array for the current subframe for (aa=0; aa<fp->nb_antenna_ports_eNB; aa++) { memset(&eNB->common_vars.txdataF[aa][subframe*fp->ofdm_symbol_size*(fp->symbols_per_tti)], @@ -1422,12 +1221,8 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DCI_INFO,(frame*10)+subframe); - // Apply physicalConfigDedicated if needed - // This is for UEs that have received this IE, which changes these DL and UL configuration, we apply after a delay for the eNodeB UL parameters - phy_config_dedicated_eNB_step2(eNB); - if (num_dci > 0) - LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Calling generate_dci_top (pdcch) (num_dci %"PRIu8")\n",eNB->Mod_id,frame, subframe, + LOG_I(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Calling generate_dci_top (pdcch) (num_dci %"PRIu8")\n",eNB->Mod_id,frame, subframe, num_dci); generate_dci_top(num_pdcch_symbols, @@ -1479,73 +1274,23 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, - // if we have PHICH to generate - - if (is_phich_subframe(fp,subframe)) - { - generate_phich_top(eNB, - proc, - AMP, - 0); - } - - /* - if (frame>=10 && subframe>=9) { - write_output("/tmp/txsigF0.m","txsF0", &eNB->common_vars.txdataF[0][0][0],120*eNB->frame_parms.ofdm_symbol_size,1,1); - write_output("/tmp/txsigF1.m","txsF1", &eNB->common_vars.txdataF[0][0][0],120*eNB->frame_parms.ofdm_symbol_size,1,1); - abort(); - } - */ + generate_phich_top(eNB, + proc, + AMP); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,0); if (do_meas==1) stop_meas(&eNB->phy_proc_tx); } -void process_Msg3(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,uint8_t UE_id, uint8_t harq_pid) -{ - // this prepares the demodulation of the first PUSCH of a new user, containing Msg3 - int subframe = proc->subframe_rx; - int frame = proc->frame_rx; - LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id]; - LTE_UL_eNB_HARQ_t *ulsch_harq=ulsch->harq_processes[harq_pid]; - - LOG_D(PHY,"[eNB %d][RAPROC] frame %d : subframe %d : process_Msg3 UE_id %d (active %d, subframe %d, frame %d)\n", - eNB->Mod_id, - frame,subframe, - UE_id,ulsch->Msg3_active, - ulsch_harq->subframe, - ulsch_harq->frame); - - ulsch_harq->Msg3_flag = 0; - - if ((ulsch->Msg3_active == 1) && - (ulsch_harq->subframe == subframe) && - (ulsch_harq->frame == (uint32_t)frame)) { - - // harq_pid = 0; - - ulsch->Msg3_active = 0; - ulsch_harq->Msg3_flag = 1; - LOG_D(PHY,"[eNB %d][RAPROC] frame %d, subframe %d: Setting subframe_scheduling_flag (Msg3) for UE %d\n", - eNB->Mod_id, - frame,subframe,UE_id); - } -} - - -// This function retrieves the harq_pid of the corresponding DLSCH process -// and updates the error statistics of the DLSCH based on the received ACK -// info from UE along with the round index. It also performs the fine-grain -// rate-adaptation based on the error statistics derived from the ACK/NAK process void process_HARQ_feedback(uint8_t UE_id, - PHY_VARS_eNB *eNB, + PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, - uint8_t pusch_flag, - uint8_t *pucch_payload, - uint8_t pucch_sel, - uint8_t SR_payload) + uint8_t pusch_flag, + uint8_t *pucch_payload, + uint8_t pucch_sel, + uint8_t SR_payload) { LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; @@ -1817,145 +1562,6 @@ void process_HARQ_feedback(uint8_t UE_id, } } -void get_n1_pucch_eNB(PHY_VARS_eNB *eNB, - eNB_rxtx_proc_t *proc, - uint8_t UE_id, - int16_t *n1_pucch0, - int16_t *n1_pucch1, - int16_t *n1_pucch2, - int16_t *n1_pucch3) -{ - - LTE_DL_FRAME_PARMS *frame_parms=&eNB->frame_parms; - uint8_t nCCE0,nCCE1; - int sf; - int frame = proc->frame_rx; - int subframe = proc->subframe_rx; - - if (frame_parms->frame_type == FDD ) { - sf = (subframe<4) ? (subframe+6) : (subframe-4); - - if (eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[sf]>0) { - *n1_pucch0 = frame_parms->pucch_config_common.n1PUCCH_AN + eNB->dlsch[(uint32_t)UE_id][0]->nCCE[sf]; - *n1_pucch1 = -1; - } else { - *n1_pucch0 = -1; - *n1_pucch1 = -1; - } - } else { - - switch (frame_parms->tdd_config) { - case 1: // DL:S:UL:UL:DL:DL:S:UL:UL:DL - if (subframe == 2) { // ACK subframes 5 and 6 - /* if (eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[6]>0) { - nCCE1 = eNB->dlsch[(uint32_t)UE_id][0]->nCCE[6]; - *n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN; - } - else - *n1_pucch1 = -1;*/ - - if (eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[5]>0) { - nCCE0 = eNB->dlsch[(uint32_t)UE_id][0]->nCCE[5]; - *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN; - } else - *n1_pucch0 = -1; - - *n1_pucch1 = -1; - } else if (subframe == 3) { // ACK subframe 9 - - if (eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[9]>0) { - nCCE0 = eNB->dlsch[(uint32_t)UE_id][0]->nCCE[9]; - *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 +frame_parms->pucch_config_common.n1PUCCH_AN; - } else - *n1_pucch0 = -1; - - *n1_pucch1 = -1; - - } else if (subframe == 7) { // ACK subframes 0 and 1 - //harq_ack[0].nCCE; - //harq_ack[1].nCCE; - if (eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[0]>0) { - nCCE0 = eNB->dlsch[(uint32_t)UE_id][0]->nCCE[0]; - *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 + frame_parms->pucch_config_common.n1PUCCH_AN; - } else - *n1_pucch0 = -1; - - *n1_pucch1 = -1; - } else if (subframe == 8) { // ACK subframes 4 - //harq_ack[4].nCCE; - if (eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[4]>0) { - nCCE0 = eNB->dlsch[(uint32_t)UE_id][0]->nCCE[4]; - *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 + frame_parms->pucch_config_common.n1PUCCH_AN; - } else - *n1_pucch0 = -1; - - *n1_pucch1 = -1; - } else { - LOG_D(PHY,"[eNB %d] frame %d: phy_procedures_lte.c: get_n1pucch, illegal subframe %d for tdd_config %d\n", - eNB->Mod_id, - frame, - subframe,frame_parms->tdd_config); - return; - } - - break; - - case 3: // DL:S:UL:UL:UL:DL:DL:DL:DL:DL - if (subframe == 2) { // ACK subframes 5,6 and 1 (S in frame-2), forget about n-11 for the moment (S-subframe) - if (eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[6]>0) { - nCCE1 = eNB->dlsch[(uint32_t)UE_id][0]->nCCE[6]; - *n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN; - } else - *n1_pucch1 = -1; - - if (eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[5]>0) { - nCCE0 = eNB->dlsch[(uint32_t)UE_id][0]->nCCE[5]; - *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN; - } else - *n1_pucch0 = -1; - } else if (subframe == 3) { // ACK subframes 7 and 8 - LOG_D(PHY,"get_n1_pucch_eNB : subframe 3, subframe_tx[7] %d, subframe_tx[8] %d\n", - eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[7],eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[8]); - - if (eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[8]>0) { - nCCE1 = eNB->dlsch[(uint32_t)UE_id][0]->nCCE[8]; - *n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN; - LOG_D(PHY,"nCCE1 %d, n1_pucch1 %d\n",nCCE1,*n1_pucch1); - } else - *n1_pucch1 = -1; - - if (eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[7]>0) { - nCCE0 = eNB->dlsch[(uint32_t)UE_id][0]->nCCE[7]; - *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 +frame_parms->pucch_config_common.n1PUCCH_AN; - LOG_D(PHY,"nCCE0 %d, n1_pucch0 %d\n",nCCE0,*n1_pucch0); - } else - *n1_pucch0 = -1; - } else if (subframe == 4) { // ACK subframes 9 and 0 - if (eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[0]>0) { - nCCE1 = eNB->dlsch[(uint32_t)UE_id][0]->nCCE[0]; - *n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN; - } else - *n1_pucch1 = -1; - - if (eNB->dlsch[(uint32_t)UE_id][0]->subframe_tx[9]>0) { - nCCE0 = eNB->dlsch[(uint32_t)UE_id][0]->nCCE[9]; - *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 +frame_parms->pucch_config_common.n1PUCCH_AN; - } else - *n1_pucch0 = -1; - } else { - LOG_D(PHY,"[eNB %d] Frame %d: phy_procedures_lte.c: get_n1pucch, illegal subframe %d for tdd_config %d\n", - eNB->Mod_id,frame,subframe,frame_parms->tdd_config); - return; - } - - break; - } // switch tdd_config - - // Don't handle the case M>2 - *n1_pucch2 = -1; - *n1_pucch3 = -1; - } -} void prach_procedures(PHY_VARS_eNB *eNB, #ifdef Rel14 @@ -1998,12 +1604,12 @@ void prach_procedures(PHY_VARS_eNB *eNB, for (i=0;i<eNB->num_RU;i++) { ru=eNB->RU_list[i]; for (ru_aa=0,aa=0;ru_aa<ru->nb_rx;ru_aa++,aa++) { - eNB->prach_vars.rxsigF[aa] = eNB->RU_list[i]->prach_rxsigF[ru_aa]; + eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[ru_aa]; #ifdef Rel14 int ce_level; if (br_flag==1) - for (ce_level=0;ce_level<4;ce_level++) eNB->prach_vars_br.rxsigF[aa] = eNB->RU_list[i]->prach_rxsigF_br[ce_level][ru_aa]; + for (ce_level=0;ce_level<4;ce_level++) eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[i]->prach_rxsigF_br[ce_level][ru_aa]; #endif } } @@ -2020,13 +1626,13 @@ void prach_procedures(PHY_VARS_eNB *eNB, #endif ); -#ifdef DEBUG_PHY_PROC + //#ifdef DEBUG_PHY_PROC LOG_I(PHY,"[RAPROC] Frame %d, subframe %d : Most likely preamble %d, energy %d dB delay %d\n", frame,subframe, max_preamble[0], max_preamble_energy[0]/10, max_preamble_delay[0]); -#endif + //q#endif #ifdef Rel14 if (br_flag==1) { @@ -2046,7 +1652,7 @@ void prach_procedures(PHY_VARS_eNB *eNB, (prach_mask&(1<<(1+ce_level)) > 0) && // prach is active and CE level has finished its repetitions (eNB->prach_vars_br.repetition_number[ce_level]== eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[ce_level])) { - */ + */ if (eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0]==1){ if (max_preamble_energy[0] > 350) { eNB->UL_INFO.rach_ind_br.number_of_preambles++; @@ -2076,7 +1682,7 @@ void prach_procedures(PHY_VARS_eNB *eNB, #endif { - if (max_preamble_energy[0] > 10000) { + if (max_preamble_energy[0] > 350) { LOG_D(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, @@ -2091,29 +1697,27 @@ void prach_procedures(PHY_VARS_eNB *eNB, T(T_ENB_PHY_INITIATE_RA_PROCEDURE, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), 0, T_INT(max_preamble[0]), T_INT(max_preamble_energy[0]), T_INT(max_preamble_delay[0])); - if (eNB->mac_enabled==1) { - - prach_vars = &eNB->prach_vars; - - - pthread_mutex_lock(&eNB->UL_INFO_mutex); - - eNB->UL_INFO.rach_ind.number_of_preambles = 1; - eNB->UL_INFO.rach_ind.preamble_list = eNB->preamble_list; - - 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+subframe; // 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 - - LOG_I(PHY,"Filling NFAPI indication for RACH : TA %d, Preamble %d, rnti %x, rach_resource_type %d\n", - eNB->preamble_list[0].preamble_rel8.timing_advance, - eNB->preamble_list[0].preamble_rel8.preamble, - eNB->preamble_list[0].preamble_rel8.rnti, - eNB->preamble_list[0].preamble_rel13.rach_resource_type); - pthread_mutex_unlock(&eNB->UL_INFO_mutex); - } + prach_vars = &eNB->prach_vars; + + + pthread_mutex_lock(&eNB->UL_INFO_mutex); + + eNB->UL_INFO.rach_ind.number_of_preambles = 1; + eNB->UL_INFO.rach_ind.preamble_list = eNB->preamble_list; + + 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+subframe; // 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 + + LOG_I(PHY,"Filling NFAPI indication for RACH : TA %d, Preamble %d, rnti %x, rach_resource_type %d\n", + eNB->preamble_list[0].preamble_rel8.timing_advance, + eNB->preamble_list[0].preamble_rel8.preamble, + eNB->preamble_list[0].preamble_rel8.rnti, + eNB->preamble_list[0].preamble_rel13.rach_resource_type); + pthread_mutex_unlock(&eNB->UL_INFO_mutex); + } // max_preamble_energy > 350 } // else br_flag /* @@ -2134,47 +1738,74 @@ void prach_procedures(PHY_VARS_eNB *eNB, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0); } -void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq_pid,uint8_t do_srs) +void srs_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { + + LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; + const int subframe = proc->subframe_rx; + const int frame = proc->frame_rx; + + int i; + + if (is_srs_occasion_common(fp,frame,subframe)) { + + // Do SRS processing + // check if there is SRS and we have to use shortened format + // TODO: check for exceptions in transmission of SRS together with ACK/NACK + for (i=0;i<NUMBER_OF_UE_MAX;i++) { + + if (eNB->soundingrs_ul_config_dedicated[i].active==1) { + + + if (lte_srs_channel_estimation(fp, + &eNB->common_vars, + &eNB->srs_vars[i], + &eNB->soundingrs_ul_config_dedicated[i], + subframe, + 0/*eNB_id*/)) { + LOG_E(PHY,"problem processing SRS\n"); + } + eNB->soundingrs_ul_config_dedicated[i].active=0; + } + } + } +} + +void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe) { + + pthread_mutex_lock(&eNB->UL_INFO_mutex); + nfapi_sr_indication_pdu_t *pdu = &eNB->UL_INFO.sr_ind.sr_pdu_list[eNB->UL_INFO.sr_ind.number_of_srs]; + + pdu->instance_length = 0; // don't know what to do with this + // pdu->rx_ue_information.handle = handle; + pdu->rx_ue_information.rnti = rnti; + pthread_mutex_unlock(&eNB->UL_INFO_mutex); + + eNB->UL_INFO.sr_ind.number_of_srs++; + pthread_mutex_unlock(&eNB->UL_INFO_mutex); +} + +void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; - uint8_t SR_payload = 0,*pucch_payload=NULL,pucch_payload0[2]= {0,0},pucch_payload1[2]= {0,0}; - int16_t n1_pucch0 = -1, n1_pucch1 = -1, n1_pucch2 = -1, n1_pucch3 = -1; + uint8_t SR_payload = 0,pucch_b0b1[4][2]= {{0,0},{0,0},{0,0},{0,0}},harq_ack[4]={0,0,0,0}; uint8_t do_SR = 0; uint8_t pucch_sel = 0; - int32_t metric0=0,metric1=0,metric0_SR=0; + int32_t metric[4]={0,0,0,0},metric_SR=0,max_metric; ANFBmode_t bundling_flag; PUCCH_FMT_t format; const int subframe = proc->subframe_rx; const int frame = proc->frame_rx; + int i; + LTE_eNB_UCI *uci; + uint16_t tdd_multiplexing_mask=0; + int res; - if ((eNB->dlsch[UE_id][0]) && - (eNB->dlsch[UE_id][0]->rnti>0) && - (eNB->ulsch[UE_id]->harq_processes[harq_pid]->frame != frame) && - (eNB->ulsch[UE_id]->harq_processes[harq_pid]->subframe != subframe)) { - - // check SR availability - do_SR = is_SR_subframe(eNB,proc,UE_id); - // do_SR = 0; - - // Now ACK/NAK - // First check subframe_tx flag for earlier subframes - - get_n1_pucch_eNB(eNB, - proc, - UE_id, - &n1_pucch0, - &n1_pucch1, - &n1_pucch2, - &n1_pucch3); - - LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d, subframe %d Checking for PUCCH (%d,%d,%d,%d) SR %d\n", - eNB->Mod_id,eNB->dlsch[UE_id][0]->rnti, - frame,subframe, - n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3,do_SR); + for (i=0;i<NUMBER_OF_UE_MAX;i++) { - if ((n1_pucch0==-1) && (n1_pucch1==-1) && (do_SR==0)) { // no TX PDSCH that have to be checked and no SR for this UE_id - } else { - // otherwise we have some PUCCH detection to do + uci = &eNB->uci_vars[i]; + if ((uci->active == 1) && + (uci->frame == frame) && + (uci->subframe == subframe)) { // Null out PUCCH PRBs for noise measurement switch(fp->N_RB_UL) { @@ -2204,285 +1835,699 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq break; } - if (do_SR == 1) { - eNB->UE_stats[UE_id].sr_total++; - - - metric0_SR = rx_pucch(eNB, - pucch_format1, - UE_id, - eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex, + switch (uci->type) { + case SR: + case HARQ_SR: + + metric_SR = rx_pucch(eNB, + uci->pucch_fmt, + i, + uci->n_pucch_1_0_sr[0], 0, // n2_pucch - do_srs, // shortened format + uci->srs_active, // shortened format &SR_payload, frame, subframe, PUCCH1_THRES); - LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Checking SR is %d (SR n1pucch is %d)\n", + LOG_I(PHY,"[eNB %d][SR %x] Frame %d subframe %d Checking SR is %d (SR n1pucch is %d)\n", eNB->Mod_id, - eNB->ulsch[UE_id]->rnti, + uci->rnti, frame, subframe, SR_payload, - eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex); - }// do_SR==1 - - if ((n1_pucch0==-1) && (n1_pucch1==-1)) { // just check for SR - } else if (fp->frame_type==FDD) { // FDD - // if SR was detected, use the n1_pucch from SR, else use n1_pucch0 - // n1_pucch0 = (SR_payload==1) ? eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex:n1_pucch0; - - LOG_D(PHY,"Demodulating PUCCH for ACK/NAK: n1_pucch0 %d (%d), SR_payload %d\n",n1_pucch0,eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex,SR_payload); - - metric0 = rx_pucch(eNB, - pucch_format1a, - UE_id, - (uint16_t)n1_pucch0, - 0, //n2_pucch - do_srs, // shortened format - pucch_payload0, - frame, - subframe, - PUCCH1a_THRES); - - - /* cancel SR detection if reception on n1_pucch0 is better than on SR PUCCH resource index */ - if (do_SR && metric0 > metric0_SR) SR_payload = 0; - - if (do_SR && metric0 <= metric0_SR) { - /* when transmitting ACK/NACK on SR PUCCH resource index, SR payload is always 1 */ - SR_payload = 1; - - metric0=rx_pucch(eNB, - pucch_format1a, - UE_id, - eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex, - 0, //n2_pucch - do_srs, // shortened format - pucch_payload0, - frame, - subframe, - PUCCH1a_THRES); - } - + uci->n_pucch_1_0_sr[0]); + if (uci->type == SR) { + if (SR_payload == 1) { + fill_sr_indication(eNB,uci->rnti,frame,subframe); + return; + } + else { + return; + } + } + case HARQ: + if (fp->frame_type == FDD) { + LOG_I(PHY,"Frame %d Subframe %d Demodulating PUCCH (UCI %d) for ACK/NAK (uci->pucch_fmt %d,uci->type %d.uci->frame %d, uci->subframe %d): n1_pucch0 %d SR_payload %d\n", + frame,subframe,i, + uci->pucch_fmt,uci->type, + uci->frame,uci->subframe,uci->n_pucch_1[0][0], + SR_payload); + + metric[0] = rx_pucch(eNB, + uci->pucch_fmt, + i, + uci->n_pucch_1[0][0], + 0, //n2_pucch + uci->srs_active, // shortened format + pucch_b0b1[0], + frame, + subframe, + PUCCH1a_THRES); + + + /* cancel SR detection if reception on n1_pucch0 is better than on SR PUCCH resource index, otherwise send it up to MAC */ + if (uci->type==HARQ_SR && metric[0] > metric_SR) SR_payload = 0; + else if (SR_payload == 1) fill_sr_indication(eNB,uci->rnti,frame,subframe); + + if (uci->type==HARQ_SR && metric[0] <= metric_SR) { + /* when transmitting ACK/NACK on SR PUCCH resource index, SR payload is always 1 */ + SR_payload = 1; + + metric[0]=rx_pucch(eNB, + uci->pucch_fmt, + i, + uci->n_pucch_1_0_sr[0], + 0, //n2_pucch + uci->srs_active, // shortened format + pucch_b0b1[0], + frame, + subframe, + PUCCH1a_THRES); + } + #ifdef DEBUG_PHY_PROC - LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d pucch1a (FDD) payload %d (metric %d)\n", - eNB->Mod_id, - eNB->dlsch[UE_id][0]->rnti, - frame,subframe, - pucch_payload0[0],metric0); + LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d pucch1a (FDD) payload %d (metric %d)\n", + eNB->Mod_id, + uci->rnti, + frame,subframe, + pucch_b0b1[0][0],metric0); #endif + + fill_uci_harq_indication(eNB,uci,frame,subframe,pucch_b0b1[0],0,0xffff); - process_HARQ_feedback(UE_id,eNB,proc, - 0,// pusch_flag - pucch_payload0, - 2, - SR_payload); - } // FDD - else { //TDD - - bundling_flag = eNB->pucch_config_dedicated[UE_id].tdd_AckNackFeedbackMode; - - // fix later for 2 TB case and format1b - - if ((fp->frame_type==FDD) || - (bundling_flag==bundling) || - ((fp->frame_type==TDD)&&(fp->tdd_config==1)&&((subframe!=2)&&(subframe!=7)))) { - format = pucch_format1a; - } else { - format = pucch_format1b; - } + } + else { // frame_type == TDD + - // if SR was detected, use the n1_pucch from SR - if (SR_payload==1) { + // if SR was detected, use the n1_pucch from SR + if (SR_payload==1) { #ifdef DEBUG_PHY_PROC - LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d Checking ACK/NAK (%d,%d,%d,%d) format %d with SR\n",eNB->Mod_id, - eNB->dlsch[UE_id][0]->rnti, - frame,subframe, - n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3,format); + LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d Checking ACK/NAK (%d,%d,%d,%d) format %d with SR\n",eNB->Mod_id, + eNB->dlsch[UE_id][0]->rnti, + frame,subframe, + n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3,format); #endif - - metric0 = rx_pucch(eNB, - format, - UE_id, - eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex, - 0, //n2_pucch - do_srs, // shortened format - pucch_payload0, - frame, - subframe, - PUCCH1a_THRES); - } else { //using n1_pucch0/n1_pucch1 resources + + metric[0] = rx_pucch(eNB, + pucch_format1b, + i, + uci->n_pucch_1_0_sr[0], + 0, //n2_pucch + uci->srs_active, // shortened format + pucch_b0b1[0], + frame, + subframe, + PUCCH1a_THRES); + } else { //using assigned pucch resources #ifdef DEBUG_PHY_PROC - LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d Checking ACK/NAK (%d,%d,%d,%d) format %d\n",eNB->Mod_id, - eNB->dlsch[UE_id][0]->rnti, - frame,subframe, - n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3,format); + LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d Checking ACK/NAK M=%d (%d,%d,%d,%d) format %d\n",eNB->Mod_id, + eNB->dlsch[UE_id][0]->rnti, + frame,subframe, + uci->num_pucch_resources, + uci->n_pucch_1[res][0], + uci->n_pucch_1[res][1], + uci->n_pucch_1[res][2], + uci->n_pucch_1[res][3], + uci->pucch_fmt); #endif - metric0=0; - metric1=0; - - // Check n1_pucch0 metric - if (n1_pucch0 != -1) { - metric0 = rx_pucch(eNB, - format, - UE_id, - (uint16_t)n1_pucch0, - 0, // n2_pucch - do_srs, // shortened format - pucch_payload0, - frame, - subframe, - PUCCH1a_THRES); - } + for (res=0;res<uci->num_pucch_resources;res++) + metric[res] = rx_pucch(eNB, + uci->pucch_fmt, + i, + uci->n_pucch_1[res][0], + 0, // n2_pucch + uci->srs_active, // shortened format + pucch_b0b1[res], + frame, + subframe, + PUCCH1a_THRES); + + + + } - // Check n1_pucch1 metric - if (n1_pucch1 != -1) { - metric1 = rx_pucch(eNB, - format, - UE_id, - (uint16_t)n1_pucch1, - 0, //n2_pucch - do_srs, // shortened format - pucch_payload1, - frame, - subframe, - PUCCH1a_THRES); - } - } - - if (SR_payload == 1) { - pucch_payload = pucch_payload0; - if (bundling_flag == bundling) - pucch_sel = 2; - } else if (bundling_flag == multiplexing) { // multiplexing + no SR - pucch_payload = (metric1>metric0) ? pucch_payload1 : pucch_payload0; - pucch_sel = (metric1>metric0) ? 1 : 0; - } else { // bundling + no SR - if (n1_pucch1 != -1) - pucch_payload = pucch_payload1; - else if (n1_pucch0 != -1) - pucch_payload = pucch_payload0; + if (SR_payload == 1) { // this implements Table 7.3.1 from 36.213 + if (pucch_b0b1[0][0] == 4) { // there isn't a likely transmission + harq_ack[0] = 4; // DTX + } + else if (pucch_b0b1[1][0] == 1 && pucch_b0b1[1][1] == 1) { // 1/4/7 ACKs + harq_ack[0] = 1; + } + else if (pucch_b0b1[1][0] == 1 && pucch_b0b1[1][1] != 1) { // 2/5/8 ACKs + harq_ack[0] = 2; + } + else if (pucch_b0b1[1][0] != 1 && pucch_b0b1[1][1] == 1) { // 3/6/9 ACKs + harq_ack[0] = 3; + } + else if (pucch_b0b1[1][0] != 1 && pucch_b0b1[1][1] != 1) { // 0 ACKs, or at least one DL assignment missed + harq_ack[0] = 0; + } + fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,2,0xffff); // special_bundling mode + } + else if ((bundling_flag == 0) && (res==2)){ // multiplexing + no SR, implement Table 10.1.3-5 (Rel14) for multiplexing with M=2 + if (pucch_b0b1[0][0] == 4 || + pucch_b0b1[1][0] == 4) { // there isn't a likely transmission + harq_ack[0] = 4; // DTX + harq_ack[1] = 6; // NACK/DTX + } + else { + if (metric[1]>metric[0]) { + if (pucch_b0b1[1][0] == 1 && pucch_b0b1[1][1] != 1){ + harq_ack[0] = 1; // ACK + harq_ack[1] = 1; // ACK + tdd_multiplexing_mask = 0x3; + } + else if (pucch_b0b1[1][0] != 1 && pucch_b0b1[1][1] == 1){ + harq_ack[0] = 6; // NACK/DTX + harq_ack[1] = 1; // ACK + tdd_multiplexing_mask = 0x2; + } + else { + harq_ack[0] = 4; // DTX + harq_ack[1] = 4; // DTX + } + } + else { + if (pucch_b0b1[0][0] == 1 && pucch_b0b1[0][1] == 1){ + harq_ack[0] = 1; // ACK + harq_ack[1] = 6; // NACK/DTX + tdd_multiplexing_mask = 0x1; + } + else if (pucch_b0b1[0][0] != 1 && pucch_b0b1[0][1] != 1){ + harq_ack[0] = 2; // NACK + harq_ack[1] = 6; // NACK/DTX + } + else { + harq_ack[0] = 4; // DTX + harq_ack[1] = 4; // DTX + } + } + } + fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode + } //else if ((bundling_flag == 0) && (res==2)) + else if ((bundling_flag == 0) && (res==3)){ // multiplexing + no SR, implement Table 10.1.3-6 (Rel14) for multiplexing with M=3 + + if (harq_ack[0] == 4 || + harq_ack[1] == 4 || + harq_ack[2] == 4) { // there isn't a likely transmission + harq_ack[0] = 4; // DTX + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 6; // NACK/DTX + + } + else { + + max_metric = max(metric[0],max(metric[1],metric[2])); + + if (metric[0]==max_metric) { + if (pucch_b0b1[0][0] == 1 && pucch_b0b1[0][1] == 1){ + harq_ack[0] = 1; // ACK + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 6; // NACK/DTX + tdd_multiplexing_mask = 0x1; + } + else if (pucch_b0b1[0][0] != 1 && pucch_b0b1[0][1] != 1){ + harq_ack[0] = 2; // NACK + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 6; // NACK/DTX + } + else { + harq_ack[0] = 4; // DTX + harq_ack[1] = 4; // DTX + harq_ack[2] = 4; // DTX + } + } // if (metric[0]==max_metric) { + else if (metric[1]==max_metric) { + + if (pucch_b0b1[1][0] == 1 && pucch_b0b1[1][1] != 1){ + harq_ack[0] = 1; // ACK + harq_ack[1] = 1; // ACK + harq_ack[2] = 6; // NACK/DTX + tdd_multiplexing_mask = 0x3; + } + else if (pucch_b0b1[1][0] != 1 && pucch_b0b1[1][1] == 1 ) { + harq_ack[0] = 6; // NACK/DTX + harq_ack[1] = 1; // ACK + harq_ack[2] = 6; // NACK/DTX + tdd_multiplexing_mask = 0x2; + } + else { + harq_ack[0] = 4; // DTX + harq_ack[1] = 4; // DTX + harq_ack[2] = 4; // DTX + } + } // if (metric[1]==max_metric) { + else { + if (pucch_b0b1[2][0] == 1 && pucch_b0b1[2][1] == 1){ + harq_ack[0] = 1; // ACK + harq_ack[1] = 1; // ACK + harq_ack[2] = 1; // ACK + tdd_multiplexing_mask = 0x7; + } + else if (pucch_b0b1[2][0] == 1 && pucch_b0b1[2][1] != 1 ) { + harq_ack[0] = 1; // ACK + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 1; // ACK + tdd_multiplexing_mask = 0x5; + } + else if (pucch_b0b1[2][0] != 1 && pucch_b0b1[2][1] == 1 ) { + harq_ack[0] = 6; // NACK/DTX + harq_ack[1] = 1; // ACK + harq_ack[2] = 1; // ACK + tdd_multiplexing_mask = 0x6; + } + else if (pucch_b0b1[2][0] != 1 && pucch_b0b1[2][1] != 1 ) { + harq_ack[0] = 6; // NACK/DTX + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 1; // ACK + tdd_multiplexing_mask = 0x4; + } + } + } + fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode + } //else if ((bundling_flag == 0) && (res==3)) + else if ((bundling_flag == 0) && (res==4)){ // multiplexing + no SR, implement Table 10.1.3-7 (Rel14) for multiplexing with M=4 + if (pucch_b0b1[0][0] == 4 || + pucch_b0b1[1][0] == 4 || + pucch_b0b1[2][0] == 4 || + pucch_b0b1[3][0] == 4) { // there isn't a likely transmission + harq_ack[0] = 4; // DTX + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 6; // NACK/DTX + harq_ack[3] = 6; // NACK/DTX + + } else { + + max_metric = max(metric[0],max(metric[1],max(metric[2],metric[3]))); + + if (metric[0]==max_metric) { + if (pucch_b0b1[0][0] == 1 && pucch_b0b1[0][1] != 1){ + harq_ack[0] = 2; // NACK + harq_ack[1] = 4; // DTX + harq_ack[2] = 4; // DTX + harq_ack[3] = 4; // DTX + } + else if (pucch_b0b1[0][0] != 1 && pucch_b0b1[0][1] == 1){ + harq_ack[0] = 1; // ACK + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 6; // NACK/DTX + harq_ack[3] = 1; // ACK + tdd_multiplexing_mask = 0x9; + } + else if (pucch_b0b1[0][0] == 1 && pucch_b0b1[0][1] == 1){ + harq_ack[0] = 1; // ACK + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 6; // NACK/DTX + harq_ack[3] = 6; // NACK/DTX + tdd_multiplexing_mask = 0x1; + } + else if (pucch_b0b1[0][0] != 1 && pucch_b0b1[0][1] != 1){ + harq_ack[0] = 2; // NACK + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 6; // NACK/DTX + harq_ack[3] = 6; // NACK/DTX + } + + } + else if (metric[1]==max_metric) { + if (pucch_b0b1[1][0] == 1 && pucch_b0b1[1][1] == 1){ + harq_ack[0] = 1; // ACK + harq_ack[1] = 1; // ACK + harq_ack[2] = 1; // ACK + harq_ack[3] = 1; // ACK + tdd_multiplexing_mask = 0xF; + } + else if (pucch_b0b1[1][0] == 1 && pucch_b0b1[1][1] != 1 ) { + harq_ack[0] = 1; // ACK + harq_ack[1] = 1; // ACK + harq_ack[2] = 6; // NACK/DTX + harq_ack[3] = 6; // NACK/DTX + tdd_multiplexing_mask = 0x3; + } + else if (pucch_b0b1[1][0] != 1 && pucch_b0b1[1][1] != 1 ) { + harq_ack[0] = 6; // NACK/DTX + harq_ack[1] = 1; // ACK + harq_ack[2] = 1; // ACK + harq_ack[3] = 1; // ACK + tdd_multiplexing_mask = 0xE; + } + else if (pucch_b0b1[1][0] != 1 && pucch_b0b1[1][1] == 1 ) { + harq_ack[0] = 6; // NACK/DTX + harq_ack[1] = 1; // ACK + harq_ack[2] = 6; // NACK/DTX + harq_ack[3] = 6; // NACK/DTX + tdd_multiplexing_mask = 0x2; + } + } + else if (metric[2]==max_metric) { + if (pucch_b0b1[2][0] == 1 && pucch_b0b1[2][1] == 1){ + harq_ack[0] = 1; // ACK + harq_ack[1] = 1; // ACK + harq_ack[2] = 1; // ACK + harq_ack[3] = 6; // NACK/DTX + tdd_multiplexing_mask = 0x7; + } + else if (pucch_b0b1[2][0] == 1 && pucch_b0b1[2][1] != 1 ) { + harq_ack[0] = 1; // ACK + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 1; // ACK + harq_ack[3] = 6; // NACK/DTX + tdd_multiplexing_mask = 0x5; + } + else if (pucch_b0b1[2][0] != 1 && pucch_b0b1[2][1] == 1 ) { + harq_ack[0] = 4; // NACK/DTX + harq_ack[1] = 1; // ACK + harq_ack[2] = 1; // ACK + harq_ack[3] = 4; // NACK/DTX + tdd_multiplexing_mask = 0x6; + } + else if (pucch_b0b1[2][0] != 1 && pucch_b0b1[2][1] != 1 ) { + harq_ack[0] = 4; // NACK/DTX + harq_ack[1] = 4; // NACK/DTX + harq_ack[2] = 1; // ACK + harq_ack[3] = 4; // NACK/DTX + tdd_multiplexing_mask = 0x4; + } + } + else { // max_metric[3]=max_metric + if (pucch_b0b1[2][0] == 1 && pucch_b0b1[2][1] == 1){ + harq_ack[0] = 1; // ACK + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 1; // ACK + harq_ack[3] = 1; // ACK + tdd_multiplexing_mask = 0xD; + } + else if (pucch_b0b1[2][0] == 1 && pucch_b0b1[2][1] != 1 ) { + harq_ack[0] = 6; // NACK/DTX + harq_ack[1] = 1; // ACK + harq_ack[2] = 6; // NACK/DTX + harq_ack[3] = 1; // ACK + tdd_multiplexing_mask = 0xA; + } + else if (pucch_b0b1[2][0] != 1 && pucch_b0b1[2][1] == 1 ) { + harq_ack[0] = 6; // NACK/DTX + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 1; // ACK + harq_ack[3] = 1; // ACK + tdd_multiplexing_mask = 0xC; + } + else if (pucch_b0b1[2][0] != 1 && pucch_b0b1[2][1] != 1 ) { + harq_ack[0] = 6; // NACK/DTX + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 6; // NACK/DTX + harq_ack[3] = 1; // ACK + tdd_multiplexing_mask = 0x8; + } + } + } + fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode + } // else if ((bundling_flag == 0) && (res==4)) + else { // bundling + harq_ack[0] = pucch_b0b1[0][0]; + harq_ack[1] = pucch_b0b1[0][1]; + fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,0,0xffff); // special_bundling mode + } - pucch_sel = 2; // indicate that this is a bundled ACK/NAK - } - #ifdef DEBUG_PHY_PROC - LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d ACK/NAK metric 0 %d, metric 1 %d, sel %d, (%d,%d)\n",eNB->Mod_id, - eNB->dlsch[UE_id][0]->rnti, - frame,subframe, - metric0,metric1,pucch_sel,pucch_payload[0],pucch_payload[1]); + LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d ACK/NAK metric 0 %d, metric 1 %d, sel %d, (%d,%d)\n",eNB->Mod_id, + eNB->dlsch[UE_id][0]->rnti, + frame,subframe, + metric0,metric1,pucch_sel,pucch_b0b1[0],pucch_b0b1[1]); #endif - process_HARQ_feedback(UE_id,eNB,proc, - 0,// pusch_flag - pucch_payload, - pucch_sel, - SR_payload); - } // TDD - } - - if (SR_payload == 1) { - LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Got SR for PUSCH, transmitting to MAC\n",eNB->Mod_id, - eNB->ulsch[UE_id]->rnti,frame,subframe); - eNB->UE_stats[UE_id].sr_received++; - - if (eNB->first_sr[UE_id] == 1) { // this is the first request for uplink after Connection Setup, so clear HARQ process 0 use for Msg4 - eNB->first_sr[UE_id] = 0; - eNB->dlsch[UE_id][0]->harq_processes[0]->round=0; - eNB->dlsch[UE_id][0]->harq_processes[0]->status=SCH_IDLE; - LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d First SR\n", - eNB->Mod_id, - eNB->ulsch[UE_id]->rnti,frame,subframe); + } + break; + default: + AssertFatal(1==0,"Unsupported UCI type %d\n",uci->type); + break; } - - if (eNB->mac_enabled==1) { - /* - mac_xface->SR_indication(eNB->Mod_id, - eNB->CC_id, - frame, - eNB->dlsch[UE_id][0]->rnti,subframe); - */ - - // fill eNB->UL_info with SR indications + + if (SR_payload == 1) { + LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Got SR for PUSCH, transmitting to MAC\n",eNB->Mod_id, + uci->rnti,frame,subframe); + + if (eNB->first_sr[i] == 1) { // this is the first request for uplink after Connection Setup, so clear HARQ process 0 use for Msg4 + eNB->first_sr[i] = 0; + eNB->dlsch[i][0]->harq_processes[0]->round=0; + eNB->dlsch[i][0]->harq_processes[0]->status=SCH_IDLE; + LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d First SR\n", + eNB->Mod_id, + eNB->ulsch[i]->rnti,frame,subframe); + } } } } } +void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { + uint32_t ret=0,i,j,k; + uint32_t harq_pid, harq_idx, round; + uint8_t nPRS; + int sync_pos; + uint16_t rnti=0; + uint8_t access_mode; + LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; + LTE_eNB_ULSCH_t *ulsch; + LTE_UL_eNB_HARQ_t *ulsch_harq; -extern int oai_exit; + const int subframe = proc->subframe_rx; + const int frame = proc->frame_rx; + int offset = eNB->CC_id;//(proc == &eNB->proc.proc_rxtx[0]) ? 0 : 1; + + if (fp->frame_type == FDD) harq_pid = ((10*frame) + subframe)&7; + else harq_pid = subframe%10; -extern void *td_thread(void*); -void init_td_thread(PHY_VARS_eNB *eNB,pthread_attr_t *attr_td) { - eNB_proc_t *proc = &eNB->proc; + for (i=0; i<NUMBER_OF_UE_MAX; i++) { - proc->tdp.eNB = eNB; - proc->instance_cnt_td = -1; + ulsch = eNB->ulsch[i]; + ulsch_harq = ulsch->harq_processes[harq_pid]; + if (ulsch->rnti>0) LOG_I(PHY,"Frame %d, subframe %d: PUSCH procedures, harq_pid %d, UE %d/%x\n", + frame,subframe,harq_pid,i,ulsch->rnti); - pthread_mutex_init( &proc->mutex_td, NULL); - pthread_cond_init( &proc->cond_td, NULL); - - pthread_create(&proc->pthread_td, attr_td, td_thread, (void*)&proc->tdp); + if ((ulsch) && + (ulsch->rnti>0) && + (ulsch_harq->status == ACTIVE) && + (ulsch_harq->frame == frame) && + (ulsch_harq->subframe == subframe)) { + + + // UE is has ULSCH scheduling + round = ulsch_harq->round; + + for (int rb=0; + rb<=ulsch_harq->nb_rb; + rb++) { + int rb2 = rb+ulsch_harq->first_rb; + eNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31)); + } -} -extern void *te_thread(void*); + LOG_I(PHY,"[eNB %d] frame %d, subframe %d: Scheduling ULSCH Reception for UE %d \n", + eNB->Mod_id, + frame, + subframe, + i); -void init_te_thread(PHY_VARS_eNB *eNB,pthread_attr_t *attr_te) { - eNB_proc_t *proc = &eNB->proc; + nPRS = fp->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe<<1]; - proc->tep.eNB = eNB; - proc->instance_cnt_te = -1; - - pthread_mutex_init( &proc->mutex_te, NULL); - pthread_cond_init( &proc->cond_te, NULL); + ulsch->cyclicShift = (ulsch_harq->n_DMRS2 + + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift + + nPRS)%12; - printf("Creating te_thread\n"); - pthread_create(&proc->pthread_te, attr_te, te_thread, (void*)&proc->tep); + LOG_I(PHY, + "[eNB %d][PUSCH %d] Frame %d Subframe %d Demodulating PUSCH: dci_alloc %d, rar_alloc %d, round %d, first_rb %d, nb_rb %d, Qm %d, TBS %d, rv %d, cyclic_shift %d (n_DMRS2 %d, cyclicShift_common %d, nprs %d), O_ACK %d \n", + eNB->Mod_id,harq_pid,frame,subframe, + ulsch_harq->dci_alloc, + ulsch_harq->rar_alloc, + ulsch_harq->round, + ulsch_harq->first_rb, + ulsch_harq->nb_rb, + ulsch_harq->Qm, + ulsch_harq->TBS, + ulsch_harq->rvidx, + ulsch->cyclicShift, + ulsch_harq->n_DMRS2, + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift, + nPRS, + ulsch_harq->O_ACK); -} + start_meas(&eNB->ulsch_demodulation_stats); + rx_ulsch(eNB,proc, + i); + + stop_meas(&eNB->ulsch_demodulation_stats); -/* -void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc){ + start_meas(&eNB->ulsch_decoding_stats); + + ret = ulsch_decoding(eNB,proc, + i, + 0, // control_only_flag + ulsch_harq->V_UL_DAI, + ulsch_harq->nb_rb>20 ? 1 : 0); + - // eNB_proc_t *proc = &eNB->proc; - LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; - const int subframe = proc->subframe_rx; - const int frame = proc->frame_rx; - int offset = (eNB->single_thread_flag==1) ? 0 : (subframe&1); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_ENB+offset, proc->frame_rx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_ENB+offset, proc->subframe_rx ); + stop_meas(&eNB->ulsch_decoding_stats); + + LOG_I(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n", + eNB->Mod_id,harq_pid, + frame,subframe, + ulsch->rnti, + dB_fixed(eNB->pusch_vars[i]->ulsch_power[0]), + dB_fixed(eNB->pusch_vars[i]->ulsch_power[1]), + 20,//eNB->measurements.n0_power_dB[0], + 20,//eNB->measurements.n0_power_dB[1], + ulsch_harq->o_ACK[0], + ulsch_harq->o_ACK[1], + ret); - if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) { - if (eNB->node_function == NGFI_RRU_IF4p5) { - /// **** in TDD during DL send_IF4 of ULTICK to RCC **** /// - send_IF4p5(eNB, proc->frame_rx, proc->subframe_rx, IF4p5_PULTICK, 0); - } - return; - } + //compute the expected ULSCH RX power (for the stats) + eNB->ulsch[(uint32_t)i]->harq_processes[harq_pid]->delta_TF = + get_hundred_times_delta_IF_eNB(eNB,i,harq_pid, 0); // 0 means bw_factor is not considered + + + if (ulsch_harq->cqi_crc_status == 1) { +#ifdef DEBUG_PHY_PROC + //if (((frame%10) == 0) || (frame < 50)) + print_CQI(ulsch_harq->o,ulsch_harq->uci_format,0,fp->N_RB_DL); +#endif + + } + fill_ulsch_cqi_indication(eNB,frame,subframe, + ulsch_harq, + ulsch->rnti); + + if (ret == (1+MAX_TURBO_ITERATIONS)) { + T(T_ENB_PHY_ULSCH_UE_NACK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(i), T_INT(ulsch->rnti), + T_INT(harq_pid)); + + ulsch_harq->round++; + + fill_crc_indication(eNB,i,frame,subframe,1); // indicate NAK to MAC + + LOG_I(PHY,"[eNB][PUSCH %d] Increasing to round %d\n",harq_pid,ulsch_harq->round); + + LOG_I(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d Error receiving ULSCH, round %d/%d (ACK %d,%d)\n", + eNB->Mod_id,harq_pid, + frame,subframe, i, + ulsch_harq->round-1, + ulsch->Mlimit, + ulsch_harq->o_ACK[0], + ulsch_harq->o_ACK[1]); + +#if defined(MESSAGE_CHART_GENERATOR_PHY) + MSC_LOG_RX_DISCARDED_MESSAGE( + MSC_PHY_ENB,MSC_PHY_UE, + NULL,0, + "%05u:%02u ULSCH received rnti %x harq id %u round %d", + frame,subframe, + ulsch->rnti,harq_pid, + ulsch_harq->round-1 + ); +#endif + + } // ulsch in error + else { + + + fill_crc_indication(eNB,i,frame,subframe,0); // indicate ACK to MAC + fill_rx_indication(eNB,i,frame,subframe); // indicate SDU to MAC + T(T_ENB_PHY_ULSCH_UE_ACK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(i), T_INT(ulsch->rnti), + T_INT(harq_pid)); + +#if defined(MESSAGE_CHART_GENERATOR_PHY) + MSC_LOG_RX_MESSAGE( + MSC_PHY_ENB,MSC_PHY_UE, + NULL,0, + "%05u:%02u ULSCH received rnti %x harq id %u", + frame,subframe, + ulsch->rnti,harq_pid + ); +#endif + +#ifdef DEBUG_PHY_PROC +#ifdef DEBUG_ULSCH + LOG_D(PHY,"[eNB] Frame %d, Subframe %d : ULSCH SDU (RX harq_pid %d) %d bytes:",frame,subframe, + harq_pid,ulsch_harq->TBS>>3); + + for (j=0; j<ulsch_harq->TBS>>3; j++) + LOG_T(PHY,"%x.",ulsch->harq_processes[harq_pid]->b[j]); + + LOG_T(PHY,"\n"); +#endif +#endif + + + + } // ulsch not in error + + if (ulsch_harq->O_ACK>0) fill_ulsch_harq_indication(eNB,ulsch_harq,ulsch->rnti,frame,subframe,ulsch->bundling); + +#ifdef DEBUG_PHY_PROC + LOG_D(PHY,"[eNB %d] Frame %d subframe %d: received ULSCH harq_pid %d for UE %d, ret = %d, CQI CRC Status %d, ACK %d,%d, ulsch_errors %d/%d\n", + eNB->Mod_id,frame,subframe, + harq_pid, + i, + ret, + ulsch_harq->cqi_crc_status, + ulsch_harq->o_ACK[0], + ulsch_harq->o_ACK[1], + eNB->UE_stats[i].ulsch_errors[harq_pid], + eNB->UE_stats[i].ulsch_decoding_attempts[harq_pid][0]); +#endif + + } // if ((ulsch) && + // (ulsch->rnti>0) && + // (ulsch_harq->status == ACTIVE)) + } // for (i=0; i<NUMBER_OF_UE_MAX; i++) { +} + +extern int oai_exit; + +extern void *td_thread(void*); + +void init_td_thread(PHY_VARS_eNB *eNB,pthread_attr_t *attr_td) { + + eNB_proc_t *proc = &eNB->proc; + + proc->tdp.eNB = eNB; + proc->instance_cnt_td = -1; + + pthread_mutex_init( &proc->mutex_td, NULL); + pthread_cond_init( &proc->cond_td, NULL); + + pthread_create(&proc->pthread_td, attr_td, td_thread, (void*)&proc->tdp); + +} + +extern void *te_thread(void*); +void init_te_thread(PHY_VARS_eNB *eNB,pthread_attr_t *attr_te) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON+offset, 1 ); - start_meas(&eNB->phy_proc_rx); - LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_common_RX(%d)\n",eNB->Mod_id,frame,subframe); + eNB_proc_t *proc = &eNB->proc; + proc->tep.eNB = eNB; + proc->instance_cnt_te = -1; + + pthread_mutex_init( &proc->mutex_te, NULL); + pthread_cond_init( &proc->cond_te, NULL); - if (eNB->fep) eNB->fep(eNB,proc); + printf("Creating te_thread\n"); + pthread_create(&proc->pthread_te, attr_te, te_thread, (void*)&proc->tep); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_COMMON+offset, 0 ); } -*/ + + + void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe) { @@ -2542,531 +2587,360 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe) { } -void fill_crc_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe,uint8_t crc_flag) { +void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subframe,uint16_t mask) { - pthread_mutex_lock(&eNB->UL_INFO_mutex); - nfapi_crc_indication_pdu_t *pdu = &eNB->UL_INFO.crc_ind.crc_pdu_list[eNB->UL_INFO.crc_ind.number_of_crcs]; + LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL; + LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL; + int harq_pid; + int subframe_tx; + int M,m; - pdu->instance_length = 0; // don't know what to do with this - // pdu->rx_ue_information.handle = handle; - pdu->rx_ue_information.rnti = eNB->ulsch[UE_id]->rnti; - pdu->crc_indication_rel8.crc_flag = crc_flag; - pthread_mutex_unlock(&eNB->UL_INFO_mutex); + AssertFatal(UE_id!=-1,"no existing dlsch context\n"); + AssertFatal(UE_id<NUMBER_OF_UE_MAX,"returned UE_id %d >= %d(NUMBER_OF_UE_MAX)\n",UE_id,NUMBER_OF_UE_MAX); + dlsch0 = eNB->dlsch[UE_id][0]; + dlsch1 = eNB->dlsch[UE_id][1]; - eNB->UL_INFO.crc_ind.number_of_crcs++; - pthread_mutex_unlock(&eNB->UL_INFO_mutex); -} + if (eNB->frame_parms.frame_type == FDD) { + subframe_tx = (subframe+6)%10; + harq_pid = dlsch0->harq_ids[subframe_tx]; + AssertFatal((harq_pid>=0) && (harq_pid<10),"harq_pid %d not in 0...9\n",harq_pid); + dlsch0_harq = dlsch0->harq_processes[harq_pid]; + dlsch1_harq = dlsch1->harq_processes[harq_pid]; + AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n"); + + dlsch0_harq->status = SCH_IDLE; + if ((dlsch1_harq == NULL)|| + ((dlsch1_harq!=NULL)&& + (dlsch1_harq->status == SCH_IDLE))) + dlsch0->harq_mask &= ~(1<<harq_pid); + } + else { // release all processes in the bundle that was acked, based on mask + // This is at most 4 for multiplexing and 9 for bundling/special bundling + M=ul_ACK_subframe2_M(&eNB->frame_parms, + subframe); -void update_harq_scheduling(LTE_DL_FRAME_PARMS *fp,LTE_UL_eNB_HARQ_t *ulsch_harq,int frame,int subframe) { - if (fp->frame_type == FDD) { - ulsch_harq->frame += (ulsch_harq->subframe>1) ? 1 : 0; - ulsch_harq->subframe = (ulsch_harq->subframe + 8)%10; + for (m=0; m<M; m++) { + subframe_tx = ul_ACK_subframe2_dl_subframe(&eNB->frame_parms, + subframe, + m); + if (((1<<m)&mask) > 0) { + harq_pid = dlsch0->harq_ids[subframe_tx]; + if ((harq_pid>=0) && (harq_pid<10)) { + dlsch0_harq = dlsch0->harq_processes[harq_pid]; + dlsch1_harq = dlsch1->harq_processes[harq_pid]; + AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n"); + + dlsch0_harq->status = SCH_IDLE; + if ((dlsch1_harq == NULL)|| + ((dlsch1_harq!=NULL)&& + (dlsch1_harq->status == SCH_IDLE))) + dlsch0->harq_mask &= ~(1<<harq_pid); + } + } + } } - else ulsch_harq->frame++; } +int getM(PHY_VARS_eNB *eNB,int frame,int subframe) { -void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const relaying_type_t r_type) -{ - //RX processing for ue-specific resources (i - UNUSED(r_type); - uint32_t ret=0,i,j,k; - uint32_t harq_pid, harq_idx, round; - uint8_t nPRS; - int sync_pos; - uint16_t rnti=0; - uint8_t access_mode; - LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; - LTE_eNB_ULSCH_t *ulsch; - LTE_UL_eNB_HARQ_t *ulsch_harq; - - const int subframe = proc->subframe_rx; - const int frame = proc->frame_rx; - int offset = eNB->CC_id;//(proc == &eNB->proc.proc_rxtx[0]) ? 0 : 1; - - uint16_t srsPeriodicity; - uint16_t srsOffset; - uint16_t do_srs=0; - uint16_t is_srs_pos=0; - - T(T_ENB_PHY_UL_TICK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe)); - - T(T_ENB_PHY_INPUT_SIGNAL, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(0), - T_BUFFER(&eNB->common_vars.rxdata[0][0][subframe*eNB->frame_parms.samples_per_tti], - eNB->frame_parms.samples_per_tti * 4)); - - if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) return; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC+offset, 1 ); - -#ifdef DEBUG_PHY_PROC - LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_uespec_RX(%d)\n",eNB->Mod_id,frame, subframe); -#endif + int M,Mtx=0; + LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL; + LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL; + int harq_pid; + int subframe_tx; + int m; - eNB->rb_mask_ul[0]=0; - eNB->rb_mask_ul[1]=0; - eNB->rb_mask_ul[2]=0; - eNB->rb_mask_ul[3]=0; + M=ul_ACK_subframe2_M(&eNB->frame_parms, + subframe); + + for (m=0; m<M; m++) { + subframe_tx = ul_ACK_subframe2_dl_subframe(&eNB->frame_parms, + subframe, + m); + harq_pid = dlsch0->harq_ids[subframe_tx]; + if (harq_pid>=0 && harq_pid<10) { + dlsch0_harq = dlsch0->harq_processes[harq_pid]; + dlsch1_harq = dlsch1->harq_processes[harq_pid]; + AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n"); + if (dlsch0_harq->status == ACTIVE|| + (dlsch1_harq!=NULL && dlsch1_harq->status == ACTIVE)) Mtx ++; + } + } + return(Mtx); +} - eNB->UL_INFO.rx_ind.number_of_pdus = 0; - eNB->UL_INFO.crc_ind.number_of_crcs = 0; - // Check for active processes in current subframe - harq_pid = subframe2harq_pid(fp, - frame,subframe); +void fill_ulsch_cqi_indication(PHY_VARS_eNB *eNB,uint16_t frame,uint8_t subframe,LTE_UL_eNB_HARQ_t *ulsch_harq,uint16_t rnti) { - is_srs_pos = is_srs_occasion_common(fp,frame,subframe); + pthread_mutex_lock(&eNB->UL_INFO_mutex); + nfapi_cqi_indication_pdu_t *pdu = &eNB->UL_INFO.cqi_ind.cqi_pdu_list[eNB->UL_INFO.cqi_ind.number_of_cqis]; + nfapi_cqi_indication_raw_pdu_t *raw_pdu = &eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list[eNB->UL_INFO.cqi_ind.number_of_cqis]; + uint8_t O; + + pdu->rx_ue_information.rnti = rnti; + if (ulsch_harq->cqi_crc_status != 1) pdu->cqi_indication_rel9.data_offset = 0; + else pdu->cqi_indication_rel9.data_offset = 1; // fill in after all cqi_indications have been generated when non-zero + + // by default set O to rank 1 value + pdu->cqi_indication_rel9.length = (ulsch_harq->Or1>>3) + (ulsch_harq->Or1&7) > 0 ? 1 : 0; + pdu->cqi_indication_rel9.ri[0] = 0; + + // if we have RI bits, set them and if rank2 overwrite O + if (ulsch_harq->O_RI>0) { + pdu->cqi_indication_rel9.ri[0] = ulsch_harq->o_RI[0]; + if (ulsch_harq->o_RI[0] == 2) pdu->cqi_indication_rel9.length = (ulsch_harq->Or2>>3) + (ulsch_harq->Or2&7) > 0 ? 1 : 0; + pdu->cqi_indication_rel9.timing_advance = 0; + } - for (i=0; i<NUMBER_OF_UE_MAX; i++) { + pdu->cqi_indication_rel9.number_of_cc_reported = 1; + pdu->ul_cqi_information.channel = 1; // PUSCH + memcpy((void*)raw_pdu->pdu,ulsch_harq->o,pdu->cqi_indication_rel9.length); + eNB->UL_INFO.cqi_ind.number_of_cqis++; + pthread_mutex_unlock(&eNB->UL_INFO_mutex); - ulsch = eNB->ulsch[i]; - ulsch_harq = ulsch->harq_processes[harq_pid]; +} - // Do SRS processing - // check if there is SRS and we have to use shortened format - // TODO: check for exceptions in transmission of SRS together with ACK/NACK - do_srs=0; - if (is_srs_pos && eNB->soundingrs_ul_config_dedicated[i].srsConfigDedicatedSetup ) { - compute_srs_pos(fp->frame_type, eNB->soundingrs_ul_config_dedicated[i].srs_ConfigIndex, &srsPeriodicity, &srsOffset); - if (((10*frame+subframe) % srsPeriodicity) == srsOffset) { - do_srs = 1; - } - } +void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq,uint16_t rnti, int frame,int subframe,int bundling) { - if (do_srs==1) { - if (lte_srs_channel_estimation(fp, - &eNB->common_vars, - &eNB->srs_vars[i], - &eNB->soundingrs_ul_config_dedicated[i], - subframe, - 0/*eNB_id*/)) { - LOG_E(PHY,"problem processing SRS\n"); - } - } - - // Do PUCCH processing + int UE_id; - pucch_procedures(eNB,proc,i,harq_pid, do_srs); + pthread_mutex_lock(&eNB->UL_INFO_mutex); + nfapi_harq_indication_pdu_t *pdu = &eNB->UL_INFO.harq_ind.harq_pdu_list[eNB->UL_INFO.harq_ind.number_of_harqs]; + int M; + int i; - // check for Msg3 - if (eNB->mac_enabled==1) { - // if (eNB->UE_stats[i].mode == RA_RESPONSE) { - process_Msg3(eNB,proc,i,harq_pid); - // } - } + pdu->instance_length = 0; // don't know what to do with this + // pdu->rx_ue_information.handle = handle; + pdu->rx_ue_information.rnti = rnti; + if (eNB->frame_parms.frame_type == FDD) { + pdu->harq_indication_fdd_rel13.mode = 0; + pdu->harq_indication_fdd_rel13.number_of_ack_nack = ulsch_harq->O_ACK; - eNB->pusch_stats_rb[i][(frame*10)+subframe] = -63; - eNB->pusch_stats_round[i][(frame*10)+subframe] = 0; - eNB->pusch_stats_mcs[i][(frame*10)+subframe] = -63; + for (i=0;i<ulsch_harq->O_ACK;i++) { + AssertFatal(ulsch_harq->o_ACK[i] == 0 || ulsch_harq->o_ACK[i] == 1, "harq_ack[%d] is %d, should be 1,2 or 4\n",i,ulsch_harq->o_ACK[i]); - if ((ulsch) && - (eNB->ulsch[i]->rnti>0) && - (ulsch_harq->status = ACTIVE)) - LOG_D(PHY,"Frame %d Subframe UE %d/%x active: scheduled for (%d,%d)\n", - frame,i,eNB->ulsch[i]->rnti,ulsch_harq->frame,ulsch_harq->subframe); - if ((ulsch) && - (eNB->ulsch[i]->rnti>0) && - (ulsch_harq->status = ACTIVE) && - (ulsch_harq->subframe==subframe)&& - (ulsch_harq->frame==frame)) { - // UE is has ULSCH scheduling - round = ulsch_harq->round; - - for (int rb=0; - rb<=ulsch_harq->nb_rb; - rb++) { - int rb2 = rb+ulsch_harq->first_rb; - eNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31)); + pdu->harq_indication_fdd_rel13.harq_tb_n[i] = 2-ulsch_harq->o_ACK[i]; + // release DLSCH if needed + if (ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff); + + } + } + else { // TDD + M=ul_ACK_subframe2_M(&eNB->frame_parms, + subframe); + + pdu->harq_indication_fdd_rel13.mode = 1-bundling; + pdu->harq_indication_fdd_rel13.number_of_ack_nack = ulsch_harq->O_ACK; + + for (i=0;i<ulsch_harq->O_ACK;i++) { + AssertFatal(ulsch_harq->o_ACK[i] == 0 || ulsch_harq->o_ACK[i] == 1, "harq_ack[%d] is %d, should be 1,2 or 4\n",i,ulsch_harq->o_ACK[i]); + + pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = 2-ulsch_harq->o_ACK[i]; + // release DLSCH if needed + if (ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff); + if (M==1 && ulsch_harq->O_ACK==1 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff); + else if (M==1 && ulsch_harq->O_ACK==2 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff); + else if (M>1 && ulsch_harq->o_ACK[i] == 1) { + // spatial bundling + release_harq(eNB,UE_id,0,frame,subframe,1<<i); + release_harq(eNB,UE_id,1,frame,subframe,1<<i); } + } + } + eNB->UL_INFO.harq_ind.number_of_harqs++; + pthread_mutex_unlock(&eNB->UL_INFO_mutex); +} - if (ulsch_harq->Msg3_flag == 1) { - LOG_D(PHY,"[eNB %d] frame %d, subframe %d: Scheduling ULSCH Reception for Msg3 in Sector %d\n", - eNB->Mod_id, - frame, - subframe, - eNB->UE_stats[i].sector); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_MSG3,1); - } else { - - LOG_D(PHY,"[eNB %d] frame %d, subframe %d: Scheduling ULSCH Reception for UE %d Mode %s\n", - eNB->Mod_id, - frame, - subframe, - i, - mode_string[eNB->UE_stats[i].mode]); - } +void fill_uci_harq_indication(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) { + int UE_id,i; - nPRS = fp->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe<<1]; - ulsch->cyclicShift = (ulsch_harq->n_DMRS2 + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift + - nPRS)%12; + pthread_mutex_lock(&eNB->UL_INFO_mutex); + nfapi_harq_indication_pdu_t *pdu = &eNB->UL_INFO.harq_ind.harq_pdu_list[eNB->UL_INFO.harq_ind.number_of_harqs]; - if (fp->frame_type == FDD ) { - int sf = (subframe<4) ? (subframe+6) : (subframe-4); + pdu->instance_length = 0; // don't know what to do with this + // pdu->rx_ue_information.handle = handle; + pdu->rx_ue_information.rnti = uci->rnti; - if (eNB->dlsch[i][0]->subframe_tx[sf]>0) { // we have downlink transmission - ulsch_harq->O_ACK = 1; - } else { - ulsch_harq->O_ACK = 0; - } - } - LOG_D(PHY, - "[eNB %d][PUSCH %d] Frame %d Subframe %d Demodulating PUSCH: dci_alloc %d, rar_alloc %d, round %d, first_rb %d, nb_rb %d, mcs %d, TBS %d, rv %d, cyclic_shift %d (n_DMRS2 %d, cyclicShift_common %d, nprs %d), O_ACK %d \n", - eNB->Mod_id,harq_pid,frame,subframe, - ulsch_harq->dci_alloc, - ulsch_harq->rar_alloc, - ulsch_harq->round, - ulsch_harq->first_rb, - ulsch_harq->nb_rb, - ulsch_harq->mcs, - ulsch_harq->TBS, - ulsch_harq->rvidx, - eNB->ulsch[i]->cyclicShift, - ulsch_harq->n_DMRS2, - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift, - nPRS, - ulsch_harq->O_ACK); - eNB->pusch_stats_rb[i][(frame*10)+subframe] = ulsch_harq->nb_rb; - eNB->pusch_stats_round[i][(frame*10)+subframe] = ulsch_harq->round; - eNB->pusch_stats_mcs[i][(frame*10)+subframe] = ulsch_harq->mcs; - start_meas(&eNB->ulsch_demodulation_stats); - - rx_ulsch(eNB,proc, - i); + if (eNB->frame_parms.frame_type == FDD) { + if (uci->pucch_fmt == pucch_format1a) { + pdu->harq_indication_fdd_rel13.mode = 0; + pdu->harq_indication_fdd_rel13.number_of_ack_nack = 1; + AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]); + pdu->harq_indication_fdd_rel13.harq_tb_n[0] = harq_ack[0]; + // release DLSCH if needed + if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff); + } + else if (uci->pucch_fmt == pucch_format1b) { + pdu->harq_indication_fdd_rel13.mode = 0; + pdu->harq_indication_fdd_rel13.number_of_ack_nack = 2; + AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[1] == 4, "harq_ack[0] is %d, should be 0,1 or 4\n",harq_ack[0]); + AssertFatal(harq_ack[1] == 1 || harq_ack[1] == 2 || harq_ack[1] == 4, "harq_ack[1] is %d, should be 0,1 or 4\n",harq_ack[1]); + pdu->harq_indication_fdd_rel13.harq_tb_n[0] = harq_ack[0]; + pdu->harq_indication_fdd_rel13.harq_tb_n[1] = harq_ack[1]; + // release DLSCH if needed + if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff); + if (harq_ack[1] == 1) release_harq(eNB,UE_id,1,frame,subframe,0xffff); + } + else AssertFatal(1==0,"only format 1a/b for now, received %d\n",uci->pucch_fmt); + } + else { // TDD - stop_meas(&eNB->ulsch_demodulation_stats); + AssertFatal(tdd_mapping_mode==0 || tdd_mapping_mode==1 || tdd_mapping_mode==2, + "Illegal tdd_mapping_mode %d\n",tdd_mapping_mode); + pdu->harq_indication_tdd_rel13.mode = tdd_mapping_mode; - start_meas(&eNB->ulsch_decoding_stats); + switch (tdd_mapping_mode) { + case 0: // bundling - ret = ulsch_decoding(eNB,proc, - i, - 0, // control_only_flag - ulsch_harq->V_UL_DAI, - ulsch_harq->nb_rb>20 ? 1 : 0); + if (uci->pucch_fmt == pucch_format1a) { + pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1; + AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]); + pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = harq_ack[0]; + // release all bundled DLSCH if needed + if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff); + } + else if (uci->pucch_fmt == pucch_format1b) { + pdu->harq_indication_tdd_rel13.number_of_ack_nack = 2; + AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[1] == 4, "harq_ack[0] is %d, should be 0,1 or 4\n",harq_ack[0]); + AssertFatal(harq_ack[1] == 1 || harq_ack[1] == 2 || harq_ack[1] == 4, "harq_ack[1] is %d, should be 0,1 or 4\n",harq_ack[1]); + pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = harq_ack[0]; + pdu->harq_indication_tdd_rel13.harq_data[1].bundling.value_0 = harq_ack[1]; + // release all DLSCH if needed + if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff); + if (harq_ack[1] == 1) release_harq(eNB,UE_id,1,frame,subframe,0xffff); + } + break; + case 1: // multiplexing + AssertFatal(uci->pucch_fmt == pucch_format1b,"uci->pucch_format %d is not format1b\n",uci->pucch_fmt); - - - stop_meas(&eNB->ulsch_decoding_stats); - - LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n", - eNB->Mod_id,harq_pid, - frame,subframe, - ulsch->rnti, - dB_fixed(eNB->pusch_vars[i]->ulsch_power[0]), - dB_fixed(eNB->pusch_vars[i]->ulsch_power[1]), - eNB->UE_stats[i].UL_rssi[0], - eNB->UE_stats[i].UL_rssi[1], - 20,//eNB->measurements.n0_power_dB[0], - 20,//eNB->measurements.n0_power_dB[1], - ulsch_harq->o_ACK[0], - ulsch_harq->o_ACK[1], - ret); - - - //compute the expected ULSCH RX power (for the stats) - eNB->ulsch[(uint32_t)i]->harq_processes[harq_pid]->delta_TF = - get_hundred_times_delta_IF_eNB(eNB,i,harq_pid, 0); // 0 means bw_factor is not considered - - eNB->UE_stats[i].ulsch_decoding_attempts[harq_pid][ulsch_harq->round]++; -#ifdef DEBUG_PHY_PROC - LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d harq_pid %d Clearing subframe_scheduling_flag\n", - eNB->Mod_id,harq_pid,frame,subframe,i,harq_pid); -#endif - - if (ulsch_harq->cqi_crc_status == 1) { -#ifdef DEBUG_PHY_PROC - //if (((frame%10) == 0) || (frame < 50)) - print_CQI(ulsch_harq->o,ulsch_harq->uci_format,0,fp->N_RB_DL); -#endif - extract_CQI(ulsch_harq->o, - ulsch_harq->uci_format, - &eNB->UE_stats[i], - fp->N_RB_DL, - &rnti, &access_mode); - eNB->UE_stats[i].rank = ulsch_harq->o_RI[0]; - + if (uci->num_pucch_resources == 1 && uci->pucch_fmt == pucch_format1a) { + pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1; + AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]); + pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0]; + // release all DLSCH if needed + if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff); } - - if (ulsch_harq->Msg3_flag == 1) - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_MSG3,0); - - if (ret == (1+MAX_TURBO_ITERATIONS)) { - T(T_ENB_PHY_ULSCH_UE_NACK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(i), T_INT(ulsch->rnti), - T_INT(harq_pid)); - - eNB->UE_stats[i].ulsch_round_errors[harq_pid][ulsch_harq->round]++; - ulsch_harq->phich_active = 1; - ulsch_harq->phich_ACK = 0; - ulsch_harq->round++; - - update_harq_scheduling(fp,ulsch_harq,frame,subframe); - - fill_crc_indication(eNB,i,frame,subframe,1); // indicate NAK to MAC - - LOG_D(PHY,"[eNB][PUSCH %d] Increasing to round %d\n",harq_pid,ulsch_harq->round); - - if (ulsch_harq->Msg3_flag == 1) { - - LOG_I(PHY,"[eNB %d/%d][RAPROC] frame %d, subframe %d, UE %d: Error receiving ULSCH (Msg3), round %d\n", - eNB->Mod_id, - eNB->CC_id, - frame,subframe, i, - ulsch_harq->round-1); - - - LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n", - eNB->Mod_id,harq_pid, - frame,subframe, - ulsch->rnti, - dB_fixed(eNB->pusch_vars[i]->ulsch_power[0]), - dB_fixed(eNB->pusch_vars[i]->ulsch_power[1]), - eNB->UE_stats[i].UL_rssi[0], - eNB->UE_stats[i].UL_rssi[1], - eNB->measurements.n0_power_dB[0], - eNB->measurements.n0_power_dB[1], - ulsch_harq->o_ACK[0], - ulsch_harq->o_ACK[1], - ret); - LOG_D(PHY,"[eNB] Frame %d, Subframe %d: Msg3 in error, i = %d \n", frame,subframe,i); - } // This is Msg3 error - - else { //normal ULSCH - LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d Error receiving ULSCH, round %d/%d (ACK %d,%d)\n", - eNB->Mod_id,harq_pid, - frame,subframe, i, - ulsch_harq->round-1, - ulsch->Mlimit, - ulsch_harq->o_ACK[0], - ulsch_harq->o_ACK[1]); - -#if defined(MESSAGE_CHART_GENERATOR_PHY) - MSC_LOG_RX_DISCARDED_MESSAGE( - MSC_PHY_ENB,MSC_PHY_UE, - NULL,0, - "%05u:%02u ULSCH received rnti %x harq id %u round %d", - frame,subframe, - ulsch->rnti,harq_pid, - ulsch_harq->round-1 - ); -#endif - - if (ulsch_harq->round== ulsch->Mlimit) { - LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d ULSCH Mlimit %d reached\n", - eNB->Mod_id,harq_pid, - frame,subframe, i, - ulsch->Mlimit); - - ulsch_harq->round=0; - ulsch_harq->phich_active=0; - eNB->UE_stats[i].ulsch_errors[harq_pid]++; - eNB->UE_stats[i].ulsch_consecutive_errors++; - - } + else if (uci->num_pucch_resources == 1 && uci->pucch_fmt == pucch_format1b) { + pdu->harq_indication_tdd_rel13.number_of_ack_nack = 2; + AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[1] == 4, "harq_ack[0] is %d, should be 0,1 or 4\n",harq_ack[0]); + AssertFatal(harq_ack[1] == 1 || harq_ack[1] == 2 || harq_ack[1] == 4, "harq_ack[1] is %d, should be 0,1 or 4\n",harq_ack[1]); + pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0]; + pdu->harq_indication_tdd_rel13.harq_data[1].multiplex.value_0 = harq_ack[1]; + // release all DLSCH if needed + if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff); + if (harq_ack[1] == 1) release_harq(eNB,UE_id,1,frame,subframe,0xffff); + } + else { // num_pucch_resources (M) > 1 + pdu->harq_indication_tdd_rel13.number_of_ack_nack = uci->num_pucch_resources; + + pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0]; + pdu->harq_indication_tdd_rel13.harq_data[1].multiplex.value_0 = harq_ack[1]; + if (uci->num_pucch_resources == 3) pdu->harq_indication_tdd_rel13.harq_data[2].multiplex.value_0 = harq_ack[2]; + if (uci->num_pucch_resources == 4) pdu->harq_indication_tdd_rel13.harq_data[3].multiplex.value_0 = harq_ack[3]; + // spatial-bundling in this case so release both HARQ if necessary + release_harq(eNB,UE_id,0,frame,subframe,tdd_multiplexing_mask); + release_harq(eNB,UE_id,1,frame,subframe,tdd_multiplexing_mask); + } + break; + case 2: // special bundling (SR collision) + pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1; + int tdd_config5_sf2scheds=0; + if (eNB->frame_parms.tdd_config==5) tdd_config5_sf2scheds = getM(eNB,frame,subframe); + + switch (harq_ack[0]) { + case 0: + break; + case 1: // check if M=1,4,7 + if (uci->num_pucch_resources == 1 || uci->num_pucch_resources == 4 || + tdd_config5_sf2scheds == 1 || tdd_config5_sf2scheds == 4 || tdd_config5_sf2scheds == 7) { + release_harq(eNB,UE_id,0,frame,subframe,0xffff); + release_harq(eNB,UE_id,1,frame,subframe,0xffff); } - } // ulsch in error - else { - + break; + case 2: // check if M=2,5,8 + if (uci->num_pucch_resources == 2 || tdd_config5_sf2scheds == 2 || + tdd_config5_sf2scheds == 5 || tdd_config5_sf2scheds == 8) { + release_harq(eNB,UE_id,0,frame,subframe,0xffff); + release_harq(eNB,UE_id,1,frame,subframe,0xffff); + } + break; + case 3: // check if M=3,6,9 + if (uci->num_pucch_resources == 3 || tdd_config5_sf2scheds == 3 || + tdd_config5_sf2scheds == 6 || tdd_config5_sf2scheds == 9) { + release_harq(eNB,UE_id,0,frame,subframe,0xffff); + release_harq(eNB,UE_id,1,frame,subframe,0xffff); + } + break; + } + break; - fill_crc_indication(eNB,i,frame,subframe,0); // indicate ACK to MAC - fill_rx_indication(eNB,i,frame,subframe); // indicate SDU to MAC - T(T_ENB_PHY_ULSCH_UE_ACK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(i), T_INT(ulsch->rnti), - T_INT(harq_pid)); + } + } //TDD - if (ulsch_harq->Msg3_flag == 1) { - LOG_D(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d ULSCH received, setting round to 0, PHICH ACK\n", - eNB->Mod_id,harq_pid, - frame,subframe); - LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n", - eNB->Mod_id,harq_pid, - frame,subframe, - ulsch->rnti, - dB_fixed(eNB->pusch_vars[i]->ulsch_power[0]), - dB_fixed(eNB->pusch_vars[i]->ulsch_power[1]), - eNB->UE_stats[i].UL_rssi[0], - eNB->UE_stats[i].UL_rssi[1], - eNB->measurements.n0_power_dB[0], - eNB->measurements.n0_power_dB[1], - ulsch_harq->o_ACK[0], - ulsch_harq->o_ACK[1], - ret); - } -#if defined(MESSAGE_CHART_GENERATOR_PHY) - MSC_LOG_RX_MESSAGE( - MSC_PHY_ENB,MSC_PHY_UE, - NULL,0, - "%05u:%02u ULSCH received rnti %x harq id %u", - frame,subframe, - ulsch->rnti,harq_pid - ); -#endif - for (j=0; j<fp->nb_antennas_rx; j++) - //this is the RSSI per RB - eNB->UE_stats[i].UL_rssi[j] = - - dB_fixed(eNB->pusch_vars[i]->ulsch_power[j]* - (ulsch_harq->nb_rb*12)/ - fp->ofdm_symbol_size) - - eNB->rx_total_gain_dB - - hundred_times_log10_NPRB[ulsch_harq->nb_rb-1]/100 - - get_hundred_times_delta_IF_eNB(eNB,i,harq_pid, 0)/100; - - ulsch_harq->phich_active = 1; - ulsch_harq->phich_ACK = 1; - ulsch_harq->round = 0; - eNB->UE_stats[i].ulsch_consecutive_errors = 0; - - if (ulsch_harq->Msg3_flag == 1) { - if (eNB->mac_enabled==1) { - - LOG_I(PHY,"[eNB %d][RAPROC] Frame %d Terminating ra_proc for harq %d, UE %d\n", - eNB->Mod_id, - frame,harq_pid,i); - if (eNB->mac_enabled) { - // Fill UL info - } - // one-shot msg3 detection by MAC: empty PDU (e.g. CRNTI) - if (ulsch_harq->Msg3_flag == 0 ) { - eNB->UE_stats[i].mode = PRACH; - eNB->ulsch[(uint32_t)i]->Msg3_active = 0; - } // Msg3_flag == 0 - - } // mac_enabled==1 - eNB->UE_stats[i].mode = PUSCH; - ulsch_harq->Msg3_flag = 0; + eNB->UL_INFO.harq_ind.number_of_harqs++; + pthread_mutex_unlock(&eNB->UL_INFO_mutex); - LOG_D(PHY,"[eNB %d][RAPROC] Frame %d : RX Subframe %d Setting UE %d mode to PUSCH\n",eNB->Mod_id,frame,subframe,i); +} - for (k=0; k<8; k++) { //harq_processes - for (j=0; j<eNB->dlsch[i][0]->Mlimit; j++) { - eNB->UE_stats[i].dlsch_NAK[k][j]=0; - eNB->UE_stats[i].dlsch_ACK[k][j]=0; - eNB->UE_stats[i].dlsch_trials[k][j]=0; - } - eNB->UE_stats[i].dlsch_l2_errors[k]=0; - eNB->UE_stats[i].ulsch_errors[k]=0; - eNB->UE_stats[i].ulsch_consecutive_errors=0; +void fill_crc_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe,uint8_t crc_flag) { - for (j=0; j<ulsch->Mlimit; j++) { - eNB->UE_stats[i].ulsch_decoding_attempts[k][j]=0; - eNB->UE_stats[i].ulsch_decoding_attempts_last[k][j]=0; - eNB->UE_stats[i].ulsch_round_errors[k][j]=0; - eNB->UE_stats[i].ulsch_round_fer[k][j]=0; - } - } + pthread_mutex_lock(&eNB->UL_INFO_mutex); + nfapi_crc_indication_pdu_t *pdu = &eNB->UL_INFO.crc_ind.crc_pdu_list[eNB->UL_INFO.crc_ind.number_of_crcs]; - eNB->UE_stats[i].dlsch_sliding_cnt=0; - eNB->UE_stats[i].dlsch_NAK_round0=0; - eNB->UE_stats[i].dlsch_mcs_offset=0; - } // Msg3_flag==1 - else { // Msg3_flag == 0 + pdu->instance_length = 0; // don't know what to do with this + // pdu->rx_ue_information.handle = handle; + pdu->rx_ue_information.rnti = eNB->ulsch[UE_id]->rnti; + pdu->crc_indication_rel8.crc_flag = crc_flag; -#ifdef DEBUG_PHY_PROC -#ifdef DEBUG_ULSCH - LOG_D(PHY,"[eNB] Frame %d, Subframe %d : ULSCH SDU (RX harq_pid %d) %d bytes:",frame,subframe, - harq_pid,ulsch_harq->TBS>>3); + eNB->UL_INFO.crc_ind.number_of_crcs++; + pthread_mutex_unlock(&eNB->UL_INFO_mutex); +} - for (j=0; j<ulsch_harq->TBS>>3; j++) - LOG_T(PHY,"%x.",eNB->ulsch[i]->harq_processes[harq_pid]->b[j]); +void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const relaying_type_t r_type) +{ + //RX processing for ue-specific resources (i + LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; + const int subframe = proc->subframe_rx; + const int frame = proc->frame_rx; - LOG_T(PHY,"\n"); -#endif -#endif - } // Msg3_flag == 0 + if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) return; - + T(T_ENB_PHY_UL_TICK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe)); -#ifdef DEBUG_PHY_PROC - LOG_D(PHY,"[eNB %d] frame %d, subframe %d: user %d: timing advance = %d\n", - eNB->Mod_id, - frame, subframe, - i, - eNB->UE_stats[i].timing_advance_update); -#endif + T(T_ENB_PHY_INPUT_SIGNAL, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(0), + T_BUFFER(&eNB->common_vars.rxdata[0][0][subframe*eNB->frame_parms.samples_per_tti], + eNB->frame_parms.samples_per_tti * 4)); - } // ulsch not in error - // process HARQ feedback -#ifdef DEBUG_PHY_PROC - LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d, Processing HARQ feedback for UE %d (after PUSCH)\n",eNB->Mod_id, - eNB->dlsch[i][0]->rnti, - frame,subframe, - i); -#endif - process_HARQ_feedback(i, - eNB,proc, - 1, // pusch_flag - 0, - 0, - 0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 1 ); -#ifdef DEBUG_PHY_PROC - LOG_D(PHY,"[eNB %d] Frame %d subframe %d, sect %d: received ULSCH harq_pid %d for UE %d, ret = %d, CQI CRC Status %d, ACK %d,%d, ulsch_errors %d/%d\n", - eNB->Mod_id,frame,subframe, - eNB->UE_stats[i].sector, - harq_pid, - i, - ret, - eNB->ulsch[i]->harq_processes[harq_pid]->cqi_crc_status, - eNB->ulsch[i]->harq_processes[harq_pid]->o_ACK[0], - eNB->ulsch[i]->harq_processes[harq_pid]->o_ACK[1], - eNB->UE_stats[i].ulsch_errors[harq_pid], - eNB->UE_stats[i].ulsch_decoding_attempts[harq_pid][0]); -#endif - - // dump stats to VCD - if (i==0) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_MCS0+harq_pid,eNB->pusch_stats_mcs[0][(frame*10)+subframe]); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_RB0+harq_pid,eNB->pusch_stats_rb[0][(frame*10)+subframe]); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_ROUND0+harq_pid,eNB->pusch_stats_round[0][(frame*10)+subframe]); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_RSSI0+harq_pid,dB_fixed(eNB->pusch_vars[0]->ulsch_power[0])); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_RES0+harq_pid,ret); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SFN0+harq_pid,(frame*10)+subframe); - } - } // ulsch[0] && ulsch[0]->rnti>0 && ulsch[0]->subframe_scheduling_flag == 1 - - - // update ULSCH statistics for tracing - if ((frame % 100 == 0) && (subframe == 4)) { - for (harq_idx=0; harq_idx<8; harq_idx++) { - for (round=0; round<ulsch->Mlimit; round++) { - if ((eNB->UE_stats[i].ulsch_decoding_attempts[harq_idx][round] - - eNB->UE_stats[i].ulsch_decoding_attempts_last[harq_idx][round]) != 0) { - eNB->UE_stats[i].ulsch_round_fer[harq_idx][round] = - (100*(eNB->UE_stats[i].ulsch_round_errors[harq_idx][round] - - eNB->UE_stats[i].ulsch_round_errors_last[harq_idx][round]))/ - (eNB->UE_stats[i].ulsch_decoding_attempts[harq_idx][round] - - eNB->UE_stats[i].ulsch_decoding_attempts_last[harq_idx][round]); - } else { - eNB->UE_stats[i].ulsch_round_fer[harq_idx][round] = 0; - } + LOG_I(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_uespec_RX(%d)\n",eNB->Mod_id,frame, subframe); - eNB->UE_stats[i].ulsch_decoding_attempts_last[harq_idx][round] = - eNB->UE_stats[i].ulsch_decoding_attempts[harq_idx][round]; - eNB->UE_stats[i].ulsch_round_errors_last[harq_idx][round] = - eNB->UE_stats[i].ulsch_round_errors[harq_idx][round]; - } - } - } + eNB->rb_mask_ul[0]=0; + eNB->rb_mask_ul[1]=0; + eNB->rb_mask_ul[2]=0; + eNB->rb_mask_ul[3]=0; - if ((frame % 100 == 0) && (subframe==4)) { - eNB->UE_stats[i].dlsch_bitrate = (eNB->UE_stats[i].total_TBS - - eNB->UE_stats[i].total_TBS_last); + eNB->UL_INFO.rx_ind.number_of_pdus = 0; + eNB->UL_INFO.crc_ind.number_of_crcs = 0; - eNB->UE_stats[i].total_TBS_last = eNB->UE_stats[i].total_TBS; - } + srs_procedures(eNB,proc); + + uci_procedures(eNB,proc); - } // loop i=0 ... NUMBER_OF_UE_MAX-1 + pusch_procedures(eNB,proc); lte_eNB_I0_measurements(eNB, subframe, @@ -3074,53 +2948,12 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const eNB->first_run_I0_measurements); eNB->first_run_I0_measurements = 0; - - - //} - -#if defined(FLEXRAN_AGENT_SB_IF) -#ifndef DISABLE_SF_TRIGGER - //Send subframe trigger to the controller - if (mac_agent_registered[eNB->Mod_id]) { - agent_mac_xface[eNB->Mod_id]->flexran_agent_send_sf_trigger(eNB->Mod_id); - } -#endif -#endif - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC+offset, 0 ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 0 ); stop_meas(&eNB->phy_proc_rx); } -#undef DEBUG_PHY_PROC -#if defined(Rel10) || defined(Rel14) -int phy_procedures_RN_eNB_TX(unsigned char last_slot, unsigned char next_slot, relaying_type_t r_type) -{ - int do_proc=0;// do nothing - - switch(r_type) { - case no_relay: - do_proc= no_relay; // perform the normal eNB operation - break; - - case multicast_relay: - if (((next_slot >>1) < 6) || ((next_slot >>1) > 8)) - do_proc = 0; // do nothing - else // SF#6, SF#7 and SF#8 - do_proc = multicast_relay; // do PHY procedures eNB TX - - break; - - default: // should'not be here - LOG_W(PHY,"Not supported relay type %d, do nothing\n", r_type); - do_proc=0; - break; - } - - return do_proc; -} -#endif diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 046e37097c..818a3402ca 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -1905,6 +1905,9 @@ void get_pucch_param(PHY_VARS_UE *ue, case pucch_format1a: case pucch_format1b: + case pucch_format1b_csA2: + case pucch_format1b_csA3: + case pucch_format1b_csA4: { pucch_resource[0] = get_n1_pucch(ue, proc, @@ -3379,16 +3382,16 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, subframe_rx<<1); stop_meas(&ue->dlsch_unscrambling_stats); -#if 0 - LOG_I(PHY," ------ start turbo decoder for AbsSubframe %d.%d / %d ------ \n", frame_rx, subframe_rx, harq_pid); - LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->nb_rb); - LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> rb_alloc_even %x \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->rb_alloc_even); - LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> Qm %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Qm); - LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> Nl %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Nl); - LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> G %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->G); - LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> Kmimo %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->Kmimo); - LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, subframe_rx, harq_pid, ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols); -#endif + //#if 0 + LOG_D(PHY," ------ start turbo decoder for AbsSubframe %d.%d / %d ------ \n", frame_rx, subframe_rx, harq_pid); + LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->nb_rb); + LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> rb_alloc_even %x \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->rb_alloc_even[0]); + LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> Qm %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Qm); + LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> Nl %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Nl); + LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> G %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->G); + LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> Kmimo %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->Kmimo); + LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, subframe_rx, harq_pid, ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols); + //#endif start_meas(&ue->dlsch_decoding_stats[subframe_rx&0x1]); ret = dlsch_decoding(ue, @@ -3471,13 +3474,13 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, if(dlsch0->rnti != 0xffff) { - LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,round %d, mcs %d,TBS %d)\n", - ue->Mod_id,dlsch0->rnti, - harq_pid,frame_rx,subframe_rx, - dlsch0->harq_processes[harq_pid]->rvidx, - dlsch0->harq_processes[harq_pid]->round, - dlsch0->harq_processes[harq_pid]->mcs, - dlsch0->harq_processes[harq_pid]->TBS); + LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,round %d, mcs %d,TBS %d)\n", + ue->Mod_id,dlsch0->rnti, + harq_pid,frame_rx,subframe_rx, + dlsch0->harq_processes[harq_pid]->rvidx, + dlsch0->harq_processes[harq_pid]->round, + dlsch0->harq_processes[harq_pid]->mcs, + dlsch0->harq_processes[harq_pid]->TBS); } diff --git a/openair1/SCHED/pucch_pc.c b/openair1/SCHED/pucch_pc.c index 92e756fa73..5186153821 100644 --- a/openair1/SCHED/pucch_pc.c +++ b/openair1/SCHED/pucch_pc.c @@ -63,6 +63,9 @@ int16_t pucch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t subframe,u case pucch_format1a: case pucch_format1b: + case pucch_format1b_csA2: + case pucch_format1b_csA3: + case pucch_format1b_csA4: Po_PUCCH += (1+(ue->frame_parms.ul_power_control_config_common.deltaF_PUCCH_Format1b<<1)); break; diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index be55afa231..19a0da05fe 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -496,9 +496,12 @@ void RCconfig_RU() { config_setting_lookup_string(setting_ru, CONFIG_STRING_RU_LOCAL_RF,(const char **)&local_rf) ) ) { - local_rf_flag = CONFIG_FALSE; + local_rf_flag = CONFIG_FALSE; } - + else { + if (strcmp(local_rf, "no") == 0) + local_rf_flag = CONFIG_FALSE; + } if (local_rf_flag == CONFIG_TRUE) { // eNB or RRU diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index 0d9980ed10..7913f1a602 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -582,7 +582,7 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, if (UE_id == -1) LOG_E(MAC,"%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, __LINE__, __FUNCTION__); else - config_dedicated(Mod_idP, CC_idP, UE_RNTI(Mod_idP, UE_id), physicalConfigDedicated); + UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated=physicalConfigDedicated; } @@ -658,19 +658,20 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, #endif - AssertFatal(RC.mac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n"); - PHY_Config_t phycfg; - phycfg.Mod_id = Mod_idP; - phycfg.CC_id = CC_idP; - phycfg.cfg = &RC.mac[Mod_idP]->config[CC_idP]; - - if (RC.mac[Mod_idP]->if_inst->PHY_config_req) RC.mac[Mod_idP]->if_inst->PHY_config_req(&phycfg); - + if (radioResourceConfigCommon!=NULL) { + AssertFatal(RC.mac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n"); + PHY_Config_t phycfg; + phycfg.Mod_id = Mod_idP; + phycfg.CC_id = CC_idP; + phycfg.cfg = &RC.mac[Mod_idP]->config[CC_idP]; + + if (RC.mac[Mod_idP]->if_inst->PHY_config_req) RC.mac[Mod_idP]->if_inst->PHY_config_req(&phycfg); + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT); - - return(0); - + + return(0); } + int rrc_mac_config_req_ue( module_id_t Mod_idP, diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index 1499ba3753..cee4688fe6 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -755,11 +755,12 @@ typedef struct { #ifdef Rel14 uint8_t rach_resource_type; - uint16_t mpdcch_repetition_cnt; - struct PhysicalConfigDedicated *physicalConfigDedicated; + uint16_t mpdcch_repetition_cnt; frame_t Msg2_frame; - sub_frame_t Msg2_subframe; #endif + sub_frame_t Msg2_subframe; + + PhysicalConfigDedicated_t *physicalConfigDedicated; } UE_TEMPLATE; @@ -791,9 +792,13 @@ typedef struct { uint16_t priority[MAX_NUM_LCID]; // resource scheduling information - uint8_t harq_pid[MAX_NUM_CCs]; - uint8_t round[MAX_NUM_CCs]; - uint8_t round_UL[8][MAX_NUM_CCs]; + + /// Current DL harq round per harq_pid on each CC + uint8_t round[MAX_NUM_CCs][10]; + /// Current Active TBs per harq_pid on each CC + uint8_t tbcnt[MAX_NUM_CCs][10]; + /// Current UL harq round per harq_pid on each CC + uint8_t round_UL[MAX_NUM_CCs][8]; uint8_t dl_pow_off[MAX_NUM_CCs]; uint16_t pre_nb_available_rbs[MAX_NUM_CCs]; unsigned char rballoc_sub_UE[MAX_NUM_CCs][N_RBG_MAX]; @@ -803,11 +808,34 @@ typedef struct { int32_t context_active_timer; int32_t cqi_req_timer; int32_t ul_inactivity_timer; - int32_t ul_failure_timer; + int32_t ul_failure_timer; int32_t ul_scheduled; int32_t ra_pdcch_order_sent; int32_t ul_out_of_sync; int32_t phr_received; + uint8_t periodic_ri_received[NFAPI_CC_MAX]; + uint8_t aperiodic_ri_received[NFAPI_CC_MAX]; + uint8_t pucch1_snr[NFAPI_CC_MAX]; + uint8_t pucch2_snr[NFAPI_CC_MAX]; + uint8_t pucch3_snr[NFAPI_CC_MAX]; + uint8_t pusch_snr[NFAPI_CC_MAX]; + uint16_t feedback_cnt[NFAPI_CC_MAX]; + uint16_t timing_advance; + uint16_t timing_advance_r9; + uint8_t periodic_wideband_cqi[NFAPI_CC_MAX]; + uint8_t periodic_wideband_spatial_diffcqi[NFAPI_CC_MAX]; + uint8_t periodic_wideband_pmi[NFAPI_CC_MAX]; + uint8_t periodic_subband_cqi[NFAPI_CC_MAX][16]; + uint8_t periodic_subband_spatial_diffcqi[NFAPI_CC_MAX][16]; + uint8_t aperiodic_subband_cqi0[NFAPI_CC_MAX][25]; + uint8_t aperiodic_subband_pmi[NFAPI_CC_MAX][25]; + uint8_t aperiodic_subband_diffcqi0[NFAPI_CC_MAX][25]; + uint8_t aperiodic_subband_cqi1[NFAPI_CC_MAX][25]; + uint8_t aperiodic_subband_diffcqi1[NFAPI_CC_MAX][25]; + uint8_t aperiodic_wideband_cqi0[NFAPI_CC_MAX]; + uint8_t aperiodic_wideband_pmi[NFAPI_CC_MAX]; + uint8_t aperiodic_wideband_cqi1[NFAPI_CC_MAX]; + uint8_t aperiodic_wideband_pmi1[NFAPI_CC_MAX]; } UE_sched_ctrl; /*! \brief eNB template for the Random access information */ typedef struct { @@ -867,12 +895,18 @@ typedef struct { uint8_t msg3_nb_rb; /// Msg3 MCS uint8_t msg3_mcs; + /// Msg3 TPC command + uint8_t msg3_TPC; + /// Msg3 ULdelay command + uint8_t msg3_ULdelay; + /// Msg3 cqireq command + uint8_t msg3_cqireq; /// Round of Msg3 HARQ uint8_t msg3_round; /// TBS used for Msg4 - int Msg4_TBsize; + int msg4_TBsize; /// MCS used for Msg4 - int Msg4_mcs; + int msg4_mcs; #ifdef Rel14 uint8_t rach_resource_type; uint8_t msg2_mpdcch_repetition_cnt; @@ -954,6 +988,8 @@ typedef struct { RA_TEMPLATE RA_template[NB_RA_PROC_MAX]; /// VRB map for common channels uint8_t vrb_map[100]; + /// VRB map for common channels and retransmissions by PHICH + uint8_t vrb_map_UL[100]; /// MBSFN SubframeConfig struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; /// number of subframe allocation pattern available for MBSFN sync area @@ -1006,7 +1042,7 @@ typedef struct eNB_MAC_INST_s { /// Common cell resources COMMON_channels_t common_channels[MAX_NUM_CCs]; /// current PDU index (BCH,MCH,DLSCH) - int pdu_index[MAX_NUM_CCs]; + uint16_t pdu_index[MAX_NUM_CCs]; /// NFAPI Config Request Structure nfapi_config_request_t config[MAX_NUM_CCs]; @@ -1016,9 +1052,12 @@ typedef struct eNB_MAC_INST_s { nfapi_dl_config_request_t DL_req[MAX_NUM_CCs]; /// Preallocated UL pdu list nfapi_ul_config_request_pdu_t ul_config_pdu_list[MAX_NUM_CCs][MAX_NUM_UL_PDU]; - nfapi_ul_config_request_pdu_t ul_config_pdu_list_msg3[MAX_NUM_CCs]; - /// NFAPI UL Config Request Structure + /// Preallocated UL pdu list for ULSCH (n+k delay) + nfapi_ul_config_request_pdu_t ul_config_pdu_list_tmp[MAX_NUM_CCs][10][MAX_NUM_UL_PDU]; + /// NFAPI UL Config Request Structure, send to L1 4 subframes before processing takes place nfapi_ul_config_request_t UL_req[MAX_NUM_CCs]; + /// NFAPI "Temporary" UL Config Request Structure, holds future UL_config requests + nfapi_ul_config_request_t UL_req_tmp[MAX_NUM_CCs][10]; /// Preallocated HI_DCI0 pdu list nfapi_hi_dci0_request_pdu_t hi_dci0_pdu_list[MAX_NUM_CCs][MAX_NUM_HI_DCI0_PDU]; /// NFAPI HI/DCI0 Config Request Structure diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 7e6e2b67c9..eb6a56d39e 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -70,6 +70,234 @@ extern RAN_CONTEXT_t RC; uint16_t pdcch_order_table[6] = {31,31,511,2047,2047,8191}; + +void schedule_SRS(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) { + + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &eNB->UE_list; + nfapi_ul_config_request_body_t *ul_req; + int CC_id,UE_id; + COMMON_channels_t *cc = RC.mac[module_idP]->common_channels; + SoundingRS_UL_ConfigCommon_t *soundingRS_UL_ConfigCommon; + struct SoundingRS_UL_ConfigDedicated *soundingRS_UL_ConfigDedicated; + uint8_t TSFC; + uint16_t deltaTSFC; // bitmap + uint8_t srs_SubframeConfig; + + // table for TSFC (Period) and deltaSFC (offset) + const uint16_t deltaTSFCTabType1[15][2] = { {1,1},{1,2},{2,2},{1,5},{2,5},{4,5},{8,5},{3,5},{12,5},{1,10},{2,10},{4,10},{8,10},{351,10},{383,10} }; // Table 5.5.3.3-2 3GPP 36.211 FDD + const uint16_t deltaTSFCTabType2[14][2] = { {2,5},{6,5},{10,5},{18,5},{14,5},{22,5},{26,5},{30,5},{70,10},{74,10},{194,10},{326,10},{586,10},{210,10} }; // Table 5.5.3.3-2 3GPP 36.211 TDD + + uint16_t srsPeriodicity,srsOffset; + + for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { + soundingRS_UL_ConfigCommon = &cc[CC_id].radioResourceConfigCommon->soundingRS_UL_ConfigCommon; + // check if SRS is enabled in this frame/subframe + if (soundingRS_UL_ConfigCommon) { + srs_SubframeConfig = soundingRS_UL_ConfigCommon->choice.setup.srs_SubframeConfig; + if (cc[CC_id].tdd_Config == NULL) { // FDD + deltaTSFC = deltaTSFCTabType1[srs_SubframeConfig][0]; + TSFC = deltaTSFCTabType1[srs_SubframeConfig][1]; + } + else { // TDD + deltaTSFC = deltaTSFCTabType2[srs_SubframeConfig][0]; + TSFC = deltaTSFCTabType2[srs_SubframeConfig][1]; + } + // Sounding reference signal subframes are the subframes satisfying ns/2 mod TSFC (- deltaTSFC + uint16_t tmp = (subframeP % TSFC); + + if((1<<tmp) & deltaTSFC) { + // This is an SRS subframe, loop over UEs + for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { + + ul_req = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body; + + + AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",UE_id); + + if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL) { + if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) { + get_srs_pos(&cc[CC_id], soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex, &srsPeriodicity, &srsOffset); + if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset) { + // Prorgram SRS + ul_req->srs_present = 1; + nfapi_ul_config_request_pdu_t* ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; + memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t)); + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_SRS_PDU_TYPE; + ul_config_pdu->pdu_size = 2+(uint8_t)(2+sizeof(nfapi_ul_config_srs_pdu)); + ul_config_pdu->srs_pdu.srs_pdu_rel8.size = (uint8_t)sizeof(nfapi_ul_config_srs_pdu);; + ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; + ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth; + ul_config_pdu->srs_pdu.srs_pdu_rel8.frequency_domain_position = soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition; + ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth;; + ul_config_pdu->srs_pdu.srs_pdu_rel8.transmission_comb = soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb; + ul_config_pdu->srs_pdu.srs_pdu_rel8.i_srs = soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex; + ul_config_pdu->srs_pdu.srs_pdu_rel8.sounding_reference_cyclic_shift = soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift; + // ul_config_pdu->srs_pdu.srs_pdu_rel10.antenna_port = ;// + // ul_config_pdu->srs_pdu.srs_pdu_rel13.number_of_combs = ;// + RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP<<4)+subframeP; + ul_req->number_of_pdus++; + } // if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset) + } // if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) + } // if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL) + } // for (UE_id ... + } // if((1<<tmp) & deltaTSFC) + + }// SRS config + } +} + +void schedule_CSI(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) { + + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &eNB->UE_list; + COMMON_channels_t *cc; + nfapi_ul_config_request_body_t *ul_req; + int CC_id,UE_id; + struct CQI_ReportPeriodic *cqi_ReportPeriodic; + uint16_t Npd,N_OFFSET_CQI; + int H; + + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + + cc = &eNB->common_channels[CC_id]; + for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { + + ul_req = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body; + + AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",UE_id); + + if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig) { + if ((cqi_ReportPeriodic = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic)!=NULL && + (cqi_ReportPeriodic->present!=CQI_ReportPeriodic_PR_release)) { + //Rel8 Periodic CQI/PMI/RI reporting + + get_csi_params(cc,cqi_ReportPeriodic,&Npd,&N_OFFSET_CQI,&H); + + if ((((frameP*10)+subframeP)%Npd) == N_OFFSET_CQI) { // CQI opportunity + UE_list->UE_sched_ctrl[UE_id].feedback_cnt[CC_id]=(((frameP*10)+subframeP)/Npd)%H; + // Program CQI + nfapi_ul_config_request_pdu_t* ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; + memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t)); + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE; + ul_config_pdu->pdu_size = 2+(uint8_t)(2+sizeof(nfapi_ul_config_uci_cqi_pdu)); + ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size = get_rel8_dl_cqi_pmi_size(&UE_list->UE_sched_ctrl[UE_id], + CC_id, + cc, + get_tmode(module_idP,CC_id,UE_id), + cqi_ReportPeriodic); + ul_req->number_of_pdus++; + +#if defined(Rel10) || defined(Rel14) + // PUT rel10-13 UCI options here +#endif + } + else if ((cqi_ReportPeriodic->choice.setup.ri_ConfigIndex) && + ((((frameP*10)+subframeP)%((H*Npd)<<(*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex/161)))== + N_OFFSET_CQI + (*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex%161))) { // RI opportunity + // Program RI + nfapi_ul_config_request_pdu_t* ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; + memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t)); + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE; + ul_config_pdu->pdu_size = 2+(uint8_t)(2+sizeof(nfapi_ul_config_uci_cqi_pdu)); + ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size = (cc->p_eNB==2)?1:2; + RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP<<4)+subframeP; + ul_req->number_of_pdus++; + } + + } // if ((cqi_ReportPeriodic = cqi_ReportConfig->cqi_ReportPeriodic)!=NULL) { + } // if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig) + } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { + } // for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { +} + +void schedule_SR(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) { + + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &eNB->UE_list; + nfapi_ul_config_request_body_t *ul_req; + int CC_id,UE_id; + SchedulingRequestConfig_t *SRconfig; + + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + + for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { + + ul_req = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body; + + + AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",UE_id); + + if ((SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig)!=NULL) { + if (SRconfig->present == SchedulingRequestConfig_PR_setup) { + + + if (SRconfig->choice.setup.sr_ConfigIndex <= 4) { // 5 ms SR period + if ((subframeP%5) != SRconfig->choice.setup.sr_ConfigIndex) + continue; + } else if (SRconfig->choice.setup.sr_ConfigIndex <= 14) { // 10 ms SR period + if (subframeP!=(SRconfig->choice.setup.sr_ConfigIndex-5)) + continue; + } else if (SRconfig->choice.setup.sr_ConfigIndex <= 34) { // 20 ms SR period + if ((10*(frameP&1)+subframeP) != (SRconfig->choice.setup.sr_ConfigIndex-15)) + continue; + } else if (SRconfig->choice.setup.sr_ConfigIndex <= 74) { // 40 ms SR period + if ((10*(frameP&3)+subframeP) != (SRconfig->choice.setup.sr_ConfigIndex-35)) + continue; + } else if (SRconfig->choice.setup.sr_ConfigIndex <= 154) { // 80 ms SR period + if ((10*(frameP&7)+subframeP) != (SRconfig->choice.setup.sr_ConfigIndex-75)) + continue; + } + } // SRconfig->present == SchedulingRequestConfig_PR_setup) + } // SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig)!=NULL) + + // if we get here there is some PUCCH1 reception to schedule for SR + + int ul_ulsch_only=0; + // check that there is no existing UL grant for ULSCH which overrides the SR + for (int i=0;i<ul_req->number_of_pdus;i++) + if ((ul_req->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) && + (ul_req->ul_config_pdu_list[i].ulsch_pdu.ulsch_pdu_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) { + ul_ulsch_only=1; + break; + } + + // drop the allocation because ULSCH with handle it with BSR + if (ul_ulsch_only==1) continue; + + // if we get here then there is no UL grant so program the SR + ul_req->ul_config_pdu_list[ul_req->number_of_pdus].pdu_type = NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE; + ul_req->ul_config_pdu_list[ul_req->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; + + // check Rel10 or Rel8 SR +#if defined(Rel10) || defined(Rel14) + if ((UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2) && + (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020)&& + (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020)) { + + ul_req->ul_config_pdu_list[ul_req->number_of_pdus].uci_sr_pdu.sr_information.sr_information_rel10.number_of_pucch_resources = 1; + ul_req->ul_config_pdu_list[ul_req->number_of_pdus].uci_sr_pdu.sr_information.sr_information_rel10.pucch_index_p1 = + *UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020->sr_PUCCH_ResourceIndexP1_r10; + + + } + else +#endif + { + ul_req->ul_config_pdu_list[ul_req->number_of_pdus].uci_sr_pdu.sr_information.sr_information_rel8.pucch_index = + UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex; + LOG_I(MAC,"Frame %d, Subframe %d : Scheduling SR for UE %d/%x\n",frameP,subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].rnti); + } + RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP<<4)+subframeP; + ul_req->number_of_pdus++; + } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) + } // for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) +} + void check_ul_failure(module_id_t module_idP,int CC_id,int UE_id, frame_t frameP, sub_frame_t subframeP) { @@ -138,6 +366,7 @@ void clear_nfapi_information(eNB_MAC_INST *eNB,int CC_idP,frame_t frameP,sub_fra 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; @@ -149,11 +378,40 @@ void clear_nfapi_information(eNB_MAC_INST *eNB,int CC_idP,frame_t frameP,sub_fra 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 copy_ulreq(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP) { + + int CC_id; + eNB_MAC_INST *eNB; + nfapi_ul_config_request_body_t *ul_req_tmp; + nfapi_ul_config_request_body_t *ul_req; + + eNB = RC.mac[module_idP]; + + for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { + + ul_req_tmp = &eNB->UL_req_tmp[CC_id][subframeP].ul_config_request_body; + ul_req = &eNB->UL_req[CC_id].ul_config_request_body; + + eNB->UL_req[CC_id].sfn_sf = (frameP<<4) + subframeP; + ul_req->number_of_pdus = ul_req_tmp->number_of_pdus; + ul_req_tmp->number_of_pdus = 0; + + memcpy((void*)ul_req->ul_config_pdu_list, + (void*)ul_req_tmp->ul_config_pdu_list, + ul_req->number_of_pdus*sizeof(nfapi_ul_config_request_pdu_t)); + + } } void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) @@ -187,17 +445,19 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { mbsfn_status[CC_id]=0; - // clear vrb_map + + // clear vrb_maps memset(cc[CC_id].vrb_map,0,100); + memset(cc[CC_id].vrb_map_UL,0,100); - // clear DL/UL info for new scheduling round - clear_nfapi_information(RC.mac[module_idP],CC_id,frameP,subframeP); #if defined(Rel10) || defined(Rel14) cc[CC_id].mcch_active =0; #endif RC.mac[module_idP]->frame = frameP; RC.mac[module_idP]->subframe = subframeP; + + clear_nfapi_information(RC.mac[module_idP],CC_id,frameP,subframeP); } // refresh UE list based on UEs dropped by PHY in previous subframe @@ -223,81 +483,10 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer++; - /* - //Inform the controller about the UE deactivation. Should be moved to RRC agent in the future -#if defined(FLEXRAN_AGENT_S_IF) - if (mac_agent_registered[module_idP]) { - agent_mac_xface[module_idP]->flexran_agent_notify_ue_state_change(module_idP, - rnti, - PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); - } -#endif -}*/ check_ul_failure(module_idP,CC_id,i,frameP,subframeP); } -#if defined(ENABLE_ITTI) - - do { - // Checks if a message has been sent to MAC sub-task - itti_poll_msg (TASK_MAC_ENB, &msg_p); - - if (msg_p != NULL) { - msg_name = ITTI_MSG_NAME (msg_p); - instance = ITTI_MSG_INSTANCE (msg_p); - - switch (ITTI_MSG_ID(msg_p)) { - case MESSAGE_TEST: - LOG_D(MAC, "Received %s\n", ITTI_MSG_NAME(msg_p)); - break; - - case RRC_MAC_BCCH_DATA_REQ: - LOG_D(MAC, "Received %s from %s: instance %d, frameP %d, eNB_index %d\n", - msg_name, ITTI_MSG_ORIGIN_NAME(msg_p), instance, - RRC_MAC_BCCH_DATA_REQ (msg_p).frame, RRC_MAC_BCCH_DATA_REQ (msg_p).enb_index); - - // TODO process BCCH data req. - break; - - case RRC_MAC_CCCH_DATA_REQ: - LOG_D(MAC, "Received %s from %s: instance %d, frameP %d, eNB_index %d\n", - msg_name, ITTI_MSG_ORIGIN_NAME(msg_p), instance, - RRC_MAC_CCCH_DATA_REQ (msg_p).frame, RRC_MAC_CCCH_DATA_REQ (msg_p).enb_index); - - // TODO process CCCH data req. - break; - -#if defined(Rel10) || defined(Rel14) - - case RRC_MAC_MCCH_DATA_REQ: - LOG_D(MAC, "Received %s from %s: instance %d, frameP %d, eNB_index %d, mbsfn_sync_area %d\n", - msg_name, ITTI_MSG_ORIGIN_NAME(msg_p), instance, - RRC_MAC_MCCH_DATA_REQ (msg_p).frame, RRC_MAC_MCCH_DATA_REQ (msg_p).enb_index, RRC_MAC_MCCH_DATA_REQ (msg_p).mbsfn_sync_area); - - // TODO process MCCH data req. - break; -#endif - - default: - LOG_E(MAC, "Received unexpected message %s\n", msg_name); - break; - } - - result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - } - } while(msg_p != NULL); - -#endif - -/* #ifndef DISABLE_SF_TRIGGER */ -/* //Send subframe trigger to the controller */ -/* if (mac_agent_registered[module_idP]) { */ -/* agent_mac_xface[module_idP]->flexran_agent_send_sf_trigger(module_idP); */ -/* } */ -/* #endif */ - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frameP, subframeP,module_idP); pdcp_run(&ctxt); @@ -319,34 +508,29 @@ 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 legacy LTE and eMTC + // This schedules SI for legacy LTE and eMTC starting in subframeP schedule_SI(module_idP,frameP,subframeP); - - // This schedules Random-Access for legacy LTE and eMTC + // This schedules Random-Access for legacy LTE and eMTC starting in subframeP schedule_RA(module_idP,frameP,subframeP); - // This schedules ULSCH in subframeP+k + // copy previously scheduled UL resources (ULSCH + HARQ) + + copy_ulreq(module_idP,frameP,subframeP); + // This schedules SRS in subframeP + schedule_SRS(module_idP,frameP,subframeP); + // This schedules ULSCH in subframeP (dci0) schedule_ulsch(module_idP,frameP,subframeP); + // This schedules UCI_SR in subframeP + schedule_SR(module_idP,frameP,subframeP); + // This schedules UCI_CSI in subframeP + schedule_CSI(module_idP, frameP, subframeP); // This schedules DLSCH in subframeP schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); - // 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); - check_and_add_msg3(module_idP,frameP,subframeP); - } - -#if defined(FLEXRAN_AGENT_SB_IF) -#ifndef DISABLE_CONT_STATS - //Send subframe trigger to the controller - if (mac_agent_registered[module_idP]) { - agent_mac_xface[module_idP]->flexran_agent_send_update_mac_stats(module_idP); - } -#endif -#endif - + // Allocate CCEs 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); + stop_meas(&RC.mac[module_idP]->eNB_scheduler); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index 457a41c517..99604b290d 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -62,136 +62,114 @@ #include "T.h" -void check_and_add_msg3(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP) { +void add_msg3(module_id_t module_idP,int CC_id, RA_TEMPLATE *RA_template, frame_t frameP, sub_frame_t subframeP) { eNB_MAC_INST *eNB = RC.mac[module_idP]; - RA_TEMPLATE *RA_template; - COMMON_channels_t *cc = eNB->common_channels; - uint8_t i; - int msg3_prog_subframe,msg3_prog_frame; - int CC_id; + COMMON_channels_t *cc = &eNB->common_channels[CC_id]; + uint8_t i,j; + nfapi_ul_config_request_t *ul_req; nfapi_ul_config_request_pdu_t *ul_config_pdu; - nfapi_ul_config_request_body_t *ul_req; + nfapi_ul_config_request_body_t *ul_req_body; nfapi_hi_dci0_request_body_t *hi_dci0_req; nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu; - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - hi_dci0_req = &eNB->HI_DCI0_req[CC_id].hi_dci0_request_body; - ul_req = &eNB->UL_req[CC_id].ul_config_request_body; - - for (i=0; i<NB_RA_PROC_MAX; i++) { + uint8_t rvseq[4] = {0,2,3,1}; - RA_template = (RA_TEMPLATE *)&cc[CC_id].RA_template[i]; - if (RA_template->RA_active == TRUE) { + hi_dci0_req = &eNB->HI_DCI0_req[CC_id].hi_dci0_request_body; + ul_req = &eNB->UL_req_tmp[CC_id][RA_template->Msg3_subframe]; + ul_req_body = &ul_req->ul_config_request_body; + AssertFatal(RA_template->RA_active == TRUE,"RA is not active for RA %X\n",RA_template->rnti); #ifdef Rel14 - if (RA_template->rach_resource_type>0) { - // program reception 4 subframes prior to transmission - msg3_prog_subframe = (RA_template->Msg3_subframe + 6)%10; - - if (RA_template->Msg3_subframe<4) msg3_prog_frame=(RA_template->Msg3_frame+1023)&1023; - else msg3_prog_frame=RA_template->Msg3_frame; - LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA %d CE level %d is active, Msg3 in (%d,%d), programmed in (%d,%d)\n", - module_idP,frameP,subframeP,CC_id,i,RA_template->rach_resource_type-1, - RA_template->Msg3_frame,RA_template->Msg3_subframe, - msg3_prog_frame,msg3_prog_subframe); - if ((msg3_prog_frame==frameP) && - (msg3_prog_subframe==subframeP)) { - LOG_I(MAC,"Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d)\n", - frameP,subframeP,RA_template->Msg3_frame,RA_template->Msg3_subframe); - eNB->UL_req[CC_id].sfn_sf = (RA_template->Msg3_frame<<4) + RA_template->Msg3_subframe; - if (RA_template->msg3_round == 0) { // program ULSCH - ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; - - memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; - ul_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_ul_config_ulsch_pdu)); - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = eNB->ul_handle++; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = RA_template->rnti; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = narrowband_to_first_rb(cc,RA_template->msg34_narrowband)+RA_template->msg3_first_rb; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = RA_template->msg3_nb_rb; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = ((10*frameP)+subframeP)&7; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = 1; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL(RA_template->msg3_mcs, - RA_template->msg3_nb_rb); - // Re13 fields - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type = RA_template->rach_resource_type>2 ? 2 : 1; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions = 1; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number = 1; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = (RA_template->Msg3_frame*10)+RA_template->Msg3_subframe; - ul_req->number_of_pdus++; - } - } - } - else + if (RA_template->rach_resource_type>0) { + LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA %d CE level %d is active, Msg3 in (%d,%d)\n", + module_idP,frameP,subframeP,CC_id,i,RA_template->rach_resource_type-1, + RA_template->Msg3_frame,RA_template->Msg3_subframe); + LOG_I(MAC,"Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d)\n", + frameP,subframeP,RA_template->Msg3_frame,RA_template->Msg3_subframe); + + ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; + + memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t)); + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_ul_config_ulsch_pdu)); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = eNB->ul_handle++; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = RA_template->rnti; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = narrowband_to_first_rb(cc,RA_template->msg34_narrowband)+RA_template->msg3_first_rb; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = RA_template->msg3_nb_rb; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = rvseq[RA_template->msg3_round]; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = ((10*RA_template->Msg3_frame)+RA_template->Msg3_subframe)&7; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = 1; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL(RA_template->msg3_mcs, + RA_template->msg3_nb_rb); + // Re13 fields + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type = RA_template->rach_resource_type>2 ? 2 : 1; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions = 1; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number = 1; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = (RA_template->Msg3_frame*10)+RA_template->Msg3_subframe; + ul_req_body->number_of_pdus++; + } // if (RA_template->rach_resource_type>0) { + else #endif - { - // program reception 4 subframes prior to transmission - msg3_prog_subframe = (RA_template->Msg3_subframe + 6)%10; - - if (RA_template->Msg3_subframe<4) msg3_prog_frame=(RA_template->Msg3_frame+1023)&1023; - else msg3_prog_frame=RA_template->Msg3_frame; - LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA %d is active, Msg3 in (%d,%d), programmed in (%d,%d)\n", - module_idP,frameP,subframeP,CC_id,i,RA_template->Msg3_frame,RA_template->Msg3_subframe, - msg3_prog_frame,msg3_prog_subframe); + { + LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA %d is active, Msg3 in (%d,%d)\n", + module_idP,frameP,subframeP,CC_id,i,RA_template->Msg3_frame,RA_template->Msg3_subframe); - if ((msg3_prog_frame==frameP) && - (msg3_prog_subframe==subframeP)) { - LOG_I(MAC,"Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d)\n", - frameP,subframeP,RA_template->Msg3_frame,RA_template->Msg3_subframe); - eNB->UL_req[CC_id].sfn_sf = (RA_template->Msg3_frame<<4) + RA_template->Msg3_subframe; - if (RA_template->msg3_round == 0) { // program ULSCH - ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; - - memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; - ul_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_ul_config_ulsch_pdu)); - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = eNB->ul_handle++; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = RA_template->rnti; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = 1; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = 1; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = 1; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL(10,ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks); - ul_req->number_of_pdus++; - } - } - else { // program HI - hi_dci0_pdu = &hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi]; - memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t)); - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; - hi_dci0_pdu->pdu_size = 2+sizeof(nfapi_hi_dci0_hi_pdu); - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = 1; // note this is hard-coded like in fill_rar - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0; - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 0; - hi_dci0_req->number_of_hi++; - - LOG_I(MAC,"[eNB %d][PUSCH-RA %x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) RA %d (mcs %d, first rb %d, nb_rb %d,round %d)\n", - module_idP,RA_template[i].rnti,CC_id,frameP,subframeP,i,10, - 1,1, - RA_template[i].msg3_round-1); - } // PHICH - } // non-BL/CE UE case - } // RA_active = TRUE - } // for RA_processes - } // for CCids + LOG_I(MAC,"Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d)\n", + frameP,subframeP,RA_template->Msg3_frame,RA_template->Msg3_subframe); + + ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; + + memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t)); + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_ul_config_ulsch_pdu)); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = eNB->ul_handle++; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = RA_template->rnti; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = RA_template->msg3_first_rb; + AssertFatal(RA_template->msg3_nb_rb > 0, "nb_rb = 0\n"); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = RA_template->msg3_nb_rb; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = rvseq[RA_template->msg3_round]; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = subframe2harqpid(cc,RA_template->Msg3_frame,RA_template->Msg3_subframe); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = 1; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL(10,RA_template->msg3_nb_rb); + ul_req_body->number_of_pdus++; + // save UL scheduling information for preprocessor + for (j=0;j<RA_template->msg3_nb_rb;j++) cc->vrb_map_UL[RA_template->msg3_first_rb+j]=1; + + + if (RA_template->msg3_round != 0) { // program HI too + hi_dci0_pdu = &hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi]; + memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t)); + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; + hi_dci0_pdu->pdu_size = 2+sizeof(nfapi_hi_dci0_hi_pdu); + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = RA_template->msg3_first_rb; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 0; + hi_dci0_req->number_of_hi++; + // save UL scheduling information for preprocessor + for (j=0;j<RA_template->msg3_nb_rb;j++) cc->vrb_map_UL[RA_template->msg3_first_rb+j]=1; + + LOG_I(MAC,"[eNB %d][PUSCH-RA %x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) RA %d (mcs %d, first rb %d, nb_rb %d,round %d)\n", + module_idP,RA_template->rnti,CC_id,frameP,subframeP,i,10, + 1,1, + RA_template->msg3_round-1); + } // if (RA_template->msg3_round != 0) { // program HI too + } // non-BL/CE UE case } void generate_Msg2(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t subframeP,RA_TEMPLATE *RA_template) { @@ -347,7 +325,7 @@ void generate_Msg2(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t if ((RA_template->Msg2_frame == frameP) && (RA_template->Msg2_subframe == subframeP)) { // Program PDSCH - LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming PDSCH %d\n", + LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming PDSCH\n", module_idP,frameP,subframeP); RA_template->generate_rar = 0; @@ -389,8 +367,7 @@ void generate_Msg2(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t // Program UL processing for Msg3, same as regular LTE get_Msg3alloc(&cc[CC_idP],subframeP,frameP,&RA_template->Msg3_frame,&RA_template->Msg3_subframe); - - + add_msg3(module_idP,CC_idP, RA_template,frameP,subframeP); fill_rar_br(eNB,CC_idP,RA_template,frameP,subframeP,cc[CC_idP].RAR_pdu.payload,RA_template->rach_resource_type-1); // DL request eNB->TX_req[CC_idP].sfn_sf = (frameP<<3)+subframeP; @@ -416,7 +393,8 @@ void generate_Msg2(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t RA_template->RA_dci_fmt1, RA_template->RA_dci_size_bits1); - + + // Allocate 4 PRBS starting in RB 0 first_rb = 0; vrb_map[first_rb] = 1; vrb_map[first_rb+1] = 1; @@ -440,7 +418,8 @@ void generate_Msg2(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t 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 = getRIV(N_RB_DL,first_rb,4); - + + // This checks if the above DCI allocation is feasible in current subframe if (!CCE_allocation_infeasible(module_idP,CC_idP,1,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->RA_rnti)) { LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for RA_RNTI %x\n", frameP,subframeP,RA_template->RA_rnti); @@ -477,10 +456,13 @@ void generate_Msg2(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t // Program UL processing for Msg3 get_Msg3alloc(&cc[CC_idP],subframeP,frameP,&RA_template->Msg3_frame,&RA_template->Msg3_subframe); + LOG_I(MAC,"Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n", frameP,subframeP,RA_template->Msg3_frame,RA_template->Msg3_subframe); fill_rar(module_idP,CC_idP,frameP,cc[CC_idP].RAR_pdu.payload,N_RB_DL,7); + add_msg3(module_idP,CC_idP, RA_template,frameP,subframeP); + // DL request eNB->TX_req[CC_idP].sfn_sf = (frameP<<3)+subframeP; TX_req = &eNB->TX_req[CC_idP].tx_request_body.tx_pdu_list[eNB->TX_req[CC_idP].tx_request_body.number_of_pdus]; @@ -517,7 +499,7 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t nfapi_ul_config_request_body_t *ul_req; uint8_t lcid; uint8_t offset; - + int harq_pid; #ifdef Rel14 @@ -579,13 +561,16 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t dl_req = &eNB->DL_req[CC_idP].dl_config_request_body; dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - ul_req = &eNB->UL_req[CC_idP].ul_config_request_body; - ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth); UE_id = find_UE_id(module_idP,RA_template->rnti); AssertFatal(UE_id>=0,"Can't find UE for t-crnti\n"); + // set HARQ process round to 0 for this UE + + if (cc->tdd_Config) harq_pid = ((frameP*10)+subframeP)%10; + else harq_pid = ((frameP*10)+subframeP)&7; + // Get RRCConnectionSetup for Piggyback rrc_sdu_length = mac_rrc_data_req(module_idP, @@ -598,11 +583,11 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t module_idP, 0); // not used in this case - AssertFatal(rrc_sdu_length>=0, + AssertFatal(rrc_sdu_length>0, "[MAC][eNB Scheduler] CCCH not allocated\n"); - LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: UE_id %d, rrc_sdu_length %d\n", + LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: UE_id %d, rrc_sdu_length %d\n", module_idP, CC_idP, frameP, subframeP,UE_id, rrc_sdu_length); @@ -657,7 +642,7 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 4; // fix to 4 for now dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = 0; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = harq_pid; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length = 0; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi = 0; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag = 0; @@ -741,23 +726,22 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t RA_template->generate_Msg4=0; RA_template->wait_ack_Msg4=1; - RA_template->RA_active = FALSE; + lcid=0; - // set HARQ process 0 round to 0 for this UE - UE_list->UE_sched_ctrl[UE_id].round[CC_idP] = 0; + UE_list->UE_sched_ctrl[UE_id].round[CC_idP][harq_pid] = 0; msg4_header = 1+6+1; // CR header, CR CE, SDU header - if ((RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) { - msg4_padding = RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header; + if ((RA_template->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) { + msg4_padding = RA_template->msg4_TBsize - rrc_sdu_length - msg4_header; msg4_post_padding = 0; } else { msg4_padding = 0; - msg4_post_padding = RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header -1; + msg4_post_padding = RA_template->msg4_TBsize - rrc_sdu_length - msg4_header -1; } LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d subframeP %d Msg4 : TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n", - module_idP,CC_idP,frameP,subframeP,RA_template->Msg4_TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding); + module_idP,CC_idP,frameP,subframeP,RA_template->msg4_TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding); DevAssert( UE_id != UE_INDEX_INVALID ); // FIXME not sure how to gracefully return // CHECK THIS: &cc[CC_idP].CCCH_pdu.payload[0] offset = generate_dlsch_header((unsigned char*)eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0], @@ -788,8 +772,10 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t int absSF = (RA_template->Msg3_frame*10)+RA_template->Msg3_subframe; // see Section 10.2 from 36.213 int ackNAK_absSF = absSF + reps + 4; - - eNB->UL_req[CC_idP].sfn_sf = ((ackNAK_absSF/10)<<4) + (ackNAK_absSF%10); + AssertFatal(reps>2,"Have to handle programming of ACK when PDSCH repetitions is > 2\n"); + ul_req = &eNB->UL_req_tmp[CC_idP][ackNAK_absSF%10].ul_config_request_body; + ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; ul_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_ul_config_uci_harq_pdu)); ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0; // don't know how to use this @@ -812,7 +798,7 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t } ul_req->number_of_pdus++; T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_idP), T_INT(RA_template->rnti), T_INT(frameP), T_INT(subframeP), - T_INT(0 /*harq_pid always 0?*/), T_BUFFER(&eNB->UE_list.DLSCH_pdu[CC_idP][0][UE_id].payload[0], RA_template->Msg4_TBsize)); + T_INT(0 /*harq_pid always 0?*/), T_BUFFER(&eNB->UE_list.DLSCH_pdu[CC_idP][0][UE_id].payload[0], RA_template->msg4_TBsize)); if (opt_enabled==1) { trace_pdu(1, (uint8_t *)eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0], @@ -831,6 +817,7 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RNTI %x)\n", module_idP, CC_idP, frameP, subframeP,RA_template->rnti); + /// Choose first 4 RBs for Msg4, should really check that these are free! first_rb=0; vrb_map[first_rb] = 1; @@ -839,48 +826,40 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t vrb_map[first_rb+3] = 1; - 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_1A; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = RA_template->rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // C-RNTI : 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 = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; - - // Compute MCS for 3 PRB + // Compute MCS/TBS for 3 PRB (coded on 4 vrb) msg4_header = 1+6+1; // CR header, CR CE, SDU header - if ((rrc_sdu_length+msg4_header) <= 22) { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 4; - RA_template->Msg4_TBsize = 22; + RA_template->msg4_mcs = 4; + RA_template->msg4_TBsize = 22; } else if ((rrc_sdu_length+msg4_header) <= 28) { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 5; - RA_template->Msg4_TBsize = 28; + RA_template->msg4_mcs = 5; + RA_template->msg4_TBsize = 28; } else if ((rrc_sdu_length+msg4_header) <= 32) { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 6; - RA_template->Msg4_TBsize = 32; + RA_template->msg4_mcs = 6; + RA_template->msg4_TBsize = 32; } else if ((rrc_sdu_length+msg4_header) <= 41) { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 7; - RA_template->Msg4_TBsize = 41; + RA_template->msg4_mcs = 7; + RA_template->msg4_TBsize = 41; } else if ((rrc_sdu_length+msg4_header) <= 49) { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 8; - RA_template->Msg4_TBsize = 49; + RA_template->msg4_mcs = 8; + RA_template->msg4_TBsize = 49; } else if ((rrc_sdu_length+msg4_header) <= 57) { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 9; - RA_template->Msg4_TBsize = 57; + RA_template->msg4_mcs = 9; + RA_template->msg4_TBsize = 57; } - RA_template->Msg4_mcs = dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1; - - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding= getRIV(N_RB_DL,first_rb,4); + fill_nfapi_dl_dci_1A(dl_config_pdu, + 4, // aggregation_level + RA_template->rnti, // rnti + 1, // rnti_type, CRNTI + harq_pid, // harq_process + 1, // tpc, none + getRIV(N_RB_DL,first_rb,4), // resource_block_coding + RA_template->msg4_mcs, // mcs + 1, // ndi + 0, // rv + 0); // vrb_flag if (!CCE_allocation_infeasible(module_idP,CC_idP,0,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->rnti)) { dl_req->number_dci++; @@ -888,22 +867,26 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t RA_template->generate_Msg4=0; RA_template->wait_ack_Msg4=1; - RA_template->RA_active = FALSE; + RA_template->Msg4_frame++; + RA_template->Msg4_frame&=1023; + lcid=0; // set HARQ process 0 round to 0 for this UE - UE_list->UE_sched_ctrl[UE_id].round[CC_idP] = 0; + if (cc->tdd_Config) harq_pid = ((frameP*10)+subframeP)%10; + else harq_pid = ((frameP*10)+subframeP)&7; + UE_list->UE_sched_ctrl[UE_id].round[CC_idP][harq_pid] = 0; - if ((RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) { - msg4_padding = RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header; + if ((RA_template->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) { + msg4_padding = RA_template->msg4_TBsize - rrc_sdu_length - msg4_header; msg4_post_padding = 0; } else { msg4_padding = 0; - msg4_post_padding = RA_template->Msg4_TBsize - rrc_sdu_length - msg4_header -1; + msg4_post_padding = RA_template->msg4_TBsize - rrc_sdu_length - msg4_header -1; } LOG_I(MAC,"[eNB %d][RAPROC] CC_idP %d Frame %d subframeP %d Msg4 : TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n", - module_idP,CC_idP,frameP,subframeP,RA_template->Msg4_TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding); + module_idP,CC_idP,frameP,subframeP,RA_template->msg4_TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding); DevAssert( UE_id != UE_INDEX_INVALID ); // FIXME not sure how to gracefully return // CHECK THIS: &cc[CC_idP].CCCH_pdu.payload[0] offset = generate_dlsch_header((unsigned char*)eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0], @@ -920,35 +903,50 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t &cc[CC_idP].CCCH_pdu.payload[0], rrc_sdu_length); + // DLSCH Config + fill_nfapi_dlsch_config(eNB, + dl_req, + RA_template->msg4_TBsize, + eNB->pdu_index[CC_idP]++, + RA_template->rnti, + 2, // resource_allocation_type : format 1A/1B/1D + 0, // virtual_resource_block_assignment_flag : localized + getRIV(N_RB_DL,first_rb,4), // resource_block_coding : RIV, 4 PRB + 2, // modulation: QPSK + 0, // redundancy version + 1, // transport_blocks + 0, // transport_block_to_codeword_swap_flag (0) + (cc->p_eNB==1 ) ? 0 : 1, // transmission_scheme + 1, // number of layers + 1, // number of subbands + //0, // codebook index + 1, // ue_category_capacity + 4, // pa: 0 dB + 0, // delta_power_offset_index + 0, // ngap + 1, // NPRB = 3 like in DCI + (cc->p_eNB==1 ) ? 1 : 2, // transmission mode + 1, // num_bf_prb_per_subband + 1); // num_bf_vector + // DL request - eNB->TX_req[CC_idP].sfn_sf = (frameP<<3)+subframeP; - TX_req = &eNB->TX_req[CC_idP].tx_request_body.tx_pdu_list[eNB->TX_req[CC_idP].tx_request_body.number_of_pdus]; - TX_req->pdu_length = rrc_sdu_length; - TX_req->pdu_index = eNB->pdu_index[CC_idP]++; - TX_req->num_segments = 1; - TX_req->segments[0].segment_length = rrc_sdu_length; - TX_req->segments[0].segment_data = eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0]; - eNB->TX_req[CC_idP].tx_request_body.number_of_pdus++; + eNB->TX_req[CC_idP].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_idP].tx_request_body, + (frameP*10)+subframeP, + rrc_sdu_length, + &eNB->pdu_index[CC_idP], + eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0]); // Program PUCCH1a for ACK/NAK - memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; - ul_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_ul_config_uci_harq_pdu)); - ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0; // don't know how to use this - ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti = RA_template->rnti; - if (cc[CC_idP].tdd_Config==NULL) { // FDD case - ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel8_fdd.n_pucch_1_0 = cc[CC_idP].radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx; - // NOTE: How to fill in the rest of the n_pucch_1_0 information 213 Section 10.1.2.1 in the general case - ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel8_fdd.harq_size = 1; // 1-bit ACK/NAK - } - else { - AssertFatal(1==0,"PUCCH configuration for ACK/NAK not handled yet for TDD case yet\n"); - } - - ul_req->number_of_pdus++; + // Program ACK/NAK for Msg4 PDSCH + fill_nfapi_uci_acknak(module_idP, + CC_idP, + RA_template->rnti, + (frameP*10)+subframeP, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); + T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_idP), T_INT(RA_template->rnti), T_INT(frameP), T_INT(subframeP), - T_INT(0 /*harq_pid always 0?*/), T_BUFFER(&eNB->UE_list.DLSCH_pdu[CC_idP][0][UE_id].payload[0], RA_template->Msg4_TBsize)); + T_INT(0 /*harq_pid always 0?*/), T_BUFFER(&eNB->UE_list.DLSCH_pdu[CC_idP][0][UE_id].payload[0], RA_template->msg4_TBsize)); if (opt_enabled==1) { trace_pdu(1, (uint8_t *)eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0], @@ -975,7 +973,7 @@ void check_Msg4_retransmission(module_id_t module_idP,int CC_idP,frame_t frameP, UE_list_t *UE_list=&eNB->UE_list; nfapi_dl_config_request_body_t *dl_req; - int round; + int round,harq_pid; /* #ifdef Rel14 COMMON_channels_t *cc = eNB->common_channels; @@ -1011,67 +1009,81 @@ void check_Msg4_retransmission(module_id_t module_idP,int CC_idP,frame_t frameP, */ // check HARQ status and retransmit if necessary - LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Checking if Msg4 was acknowledged: \tn", - module_idP,CC_idP,frameP,subframeP); + // Get candidate harq_pid from PHY UE_id = find_UE_id(module_idP,RA_template->rnti); AssertFatal(UE_id>=0,"Can't find UE for t-crnti\n"); - round = UE_list->UE_sched_ctrl[UE_id].round[CC_idP]; + if (cc[CC_idP].tdd_Config) harq_pid = ((frameP*10)+subframeP)%10; + else harq_pid = ((frameP*10)+subframeP)&7; + + round = UE_list->UE_sched_ctrl[UE_id].round[CC_idP][harq_pid]; vrb_map = cc[CC_idP].vrb_map; dl_req = &eNB->DL_req[CC_idP].dl_config_request_body; dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth); - if (round>0) { + LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Checking if Msg4 was acknowledged (round %d)\n", + module_idP,CC_idP,frameP,subframeP,round); + + if (round!=8) { #ifdef Rel14 - AssertFatal(1==0,"Msg4 Retransmissions not handled yet for BL/CE UEs\n"); + if (RA_template->rach_resource_type>0) { + AssertFatal(1==0,"Msg4 Retransmissions not handled yet for BL/CE UEs\n"); + } + else #endif - { - if ( (RA_template->Msg4_frame == frameP) && (RA_template->Msg4_subframe == subframeP)) { - - //RA_template->wait_ack_Msg4++; - // we have to schedule a retransmission - - first_rb=0; - vrb_map[first_rb] = 1; - vrb_map[first_rb+1] = 1; - vrb_map[first_rb+2] = 1; - vrb_map[first_rb+3] = 1; - - 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_1A; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = RA_template->rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // C-RNTI : 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 = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = round; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = RA_template->Msg4_mcs; - 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= getRIV(N_RB_DL,first_rb,4); - - if (!CCE_allocation_infeasible(module_idP,CC_idP,0,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->rnti)) { - dl_req->number_dci++; - dl_req->number_pdu++; + { + if ( (RA_template->Msg4_frame == frameP) && (RA_template->Msg4_subframe == subframeP)) { - LOG_I(MAC,"msg4 retransmission for rnti %x (round %d) fsf %d/%d\n", RA_template->rnti, round, frameP, subframeP); - } - else - LOG_I(MAC,"msg4 retransmission for rnti %x (round %d) fsf %d/%d CCE allocation failed!\n", RA_template->rnti, round, frameP, subframeP); - LOG_W(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Msg4 not acknowledged, adding ue specific dci (rnti %x) for RA (Msg4 Retransmission)\n", - module_idP,CC_idP,frameP,subframeP,RA_template->rnti); - } - } - + //RA_template->wait_ack_Msg4++; + // we have to schedule a retransmission + + first_rb=0; + vrb_map[first_rb] = 1; + vrb_map[first_rb+1] = 1; + vrb_map[first_rb+2] = 1; + vrb_map[first_rb+3] = 1; + + fill_nfapi_dl_dci_1A(dl_config_pdu, + 4, // aggregation_level + RA_template->rnti, // rnti + 1, // rnti_type, CRNTI + 0, // harq_process + 1, // tpc, none + getRIV(N_RB_DL,first_rb,4), // resource_block_coding + RA_template->msg4_mcs, // mcs + 1, // ndi + round, // rv + 0); // vrb_flag + + if (!CCE_allocation_infeasible(module_idP,CC_idP,0,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->rnti)) { + dl_req->number_dci++; + dl_req->number_pdu++; + + LOG_I(MAC,"msg4 retransmission for rnti %x (round %d) fsf %d/%d\n", RA_template->rnti, round, frameP, subframeP); + } + else + LOG_I(MAC,"msg4 retransmission for rnti %x (round %d) fsf %d/%d CCE allocation failed!\n", RA_template->rnti, round, frameP, subframeP); + LOG_W(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Msg4 not acknowledged, adding ue specific dci (rnti %x) for RA (Msg4 Retransmission)\n", + module_idP,CC_idP,frameP,subframeP,RA_template->rnti); + + + // Program PUCCH1a for ACK/NAK + + + fill_nfapi_uci_acknak(module_idP,CC_idP, + RA_template->rnti, + (frameP*10)+subframeP, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); + + // prepare frame for retransmission + RA_template->Msg4_frame++; + RA_template->Msg4_frame&=1023; + } // Msg4 frame/subframe + } // regular LTE case } else { LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d : Msg4 acknowledged\n",module_idP,CC_idP,frameP,subframeP); RA_template->wait_ack_Msg4=0; @@ -1095,7 +1107,7 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP) for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - // skip UL component carriers + // skip UL component carriers if TDD if (is_UL_sf(&cc[CC_id],subframeP)==1) continue; @@ -1141,15 +1153,20 @@ void initiate_ra_proc(module_id_t module_idP, COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id]; RA_TEMPLATE *RA_template = &cc->RA_template[0]; - struct PRACH_ConfigSIB_v1310 *ext4_prach=cc->radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310; - PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13= &ext4_prach->prach_ParametersListCE_r13; + struct PRACH_ConfigSIB_v1310 *ext4_prach = NULL; + PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = NULL; + if (cc->radioResourceConfigCommon_BR && cc->radioResourceConfigCommon_BR->ext4) { + ext4_prach=cc->radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310; + prach_ParametersListCE_r13= &ext4_prach->prach_ParametersListCE_r13; + } LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d Initiating RA procedure for preamble index %d\n",module_idP,CC_id,frameP,subframeP,preamble_index); #ifdef Rel14 LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d PRACH resource type %d\n",module_idP,CC_id,frameP,subframeP,rach_resource_type); #endif - if (prach_ParametersListCE_r13->list.count<rach_resource_type) { + if (prach_ParametersListCE_r13 && + prach_ParametersListCE_r13->list.count<rach_resource_type) { LOG_E(MAC,"[eNB %d][RAPROC] CC_id %d Received impossible PRACH resource type %d, only %d CE levels configured\n", module_idP,CC_id, rach_resource_type, diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c index 04485a9d3e..aec302c36a 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c @@ -240,7 +240,7 @@ schedule_SIB1_BR( // Rel13 fields dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 1; // CEModeA UE dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 0; // SIB1-BR - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SF + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SFx // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; dl_req->number_pdu++; @@ -401,8 +401,8 @@ schedule_SI_BR( vrb_map[first_rb+5] = 1; if ((frameP&1023) < 200) LOG_D(MAC,"[eNB %d] Frame %d Subframe %d: SI_BR->DLSCH CC_id %d, Narrowband %d rvidx %d (sf_mod_period %d : si_WindowLength_BR_r13 %d : si_RepetitionPattern_r13 %d) bcch_sdu_length %d\n", - module_idP,frameP,subframeP,CC_id,si_Narrowband_r13-1,rvidx, - sf_mod_period,si_WindowLength_BR_r13,si_RepetitionPattern_r13, + module_idP,frameP,subframeP,CC_id,(int)si_Narrowband_r13-1,rvidx, + sf_mod_period,(int)si_WindowLength_BR_r13,(int)si_RepetitionPattern_r13, bcch_sdu_length); @@ -524,7 +524,7 @@ void schedule_mib(module_id_t module_idP, LOG_D(MAC,"Frame %d, subframe %d: Adding BCH PDU in position %d (length %d)\n", frameP,subframeP,dl_req->number_pdu,mib_sdu_length); - if ((frameP&1023) < 40) LOG_D(MAC,"[eNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes (cc->mib->message.schedulingInfoSIB1_BR_r13 %d)\n",module_idP,frameP,CC_id,mib_sdu_length,cc->mib->message.schedulingInfoSIB1_BR_r13); + if ((frameP&1023) < 40) LOG_D(MAC,"[eNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes (cc->mib->message.schedulingInfoSIB1_BR_r13 %d)\n",module_idP,frameP,CC_id,mib_sdu_length,(int)cc->mib->message.schedulingInfoSIB1_BR_r13); 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)); @@ -671,7 +671,14 @@ schedule_SI( dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL,first_rb,4); - + + // Rel10 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; + // Rel13 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; // absolute SF + if (!CCE_allocation_infeasible(module_idP,CC_id,1,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,SI_RNTI)) { LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for S_RNTI\n", frameP,subframeP); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 825d0fa8b6..ebd880da12 100755 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -609,8 +609,12 @@ schedule_ue_spec( } nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id]; - harq_pid = ue_sched_ctl->harq_pid[CC_id]; - round = ue_sched_ctl->round[CC_id]; + + if (cc->tdd_Config) harq_pid = ((frameP*10)+subframeP)%10; + else harq_pid = ((frameP*10)+subframeP)&7; + + round = ue_sched_ctl->round[CC_id][harq_pid]; + UE_list->eNB_UE_stats[CC_id][UE_id].crnti= rnti; UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status=mac_eNB_get_rrc_status(module_idP,rnti); UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; @@ -645,8 +649,10 @@ schedule_ue_spec( /* process retransmission */ if (round > 0) { + // get freq_allocation nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + TBS = get_TBS_DL(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid],nb_rb); if (nb_rb <= nb_available_rb) { if (cc[CC_id].tdd_Config != NULL) { @@ -729,9 +735,38 @@ schedule_ue_spec( dl_req->number_dci++; dl_req->number_pdu++; + 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, unused here + 0, // resource_block_coding, to be filled in later + getQm(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]), + round&3 , // 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 + UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, + 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->pdu_index[CC_id]++; + program_dlsch_acknak(module_idP,CC_id,UE_id,frameP,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); + // No TX request for retransmission (check if null request for FAPI) } else { - // No TX request for retransmission (check if null request for FAPI) + LOG_W(MAC,"Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d\%x, infeasible CCE allocation\n", + frameP,subframeP,UE_id,rnti); } } @@ -789,7 +824,7 @@ schedule_ue_spec( ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, - TBS, //not used + TBS, //not used (char *)&dlsch_buffer[0]); T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), @@ -993,15 +1028,7 @@ schedule_ue_spec( j = j+1; } } - /* - RC.eNB[module_idP][CC_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; - RC.eNB[module_idP][CC_id]->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; - for(j=0; j<N_RBG[CC_id]; j++) { - RC.eNB[module_idP][CC_id]->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; - - } - */ // decrease mcs until TBS falls below required length while ((TBS > (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && (mcs>0)) { mcs--; @@ -1120,7 +1147,7 @@ schedule_ue_spec( // this is the normalized RX power eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; normalized_rx_power = eNB_UE_stats->Po_PUCCH_dBm; - target_rx_power = get_target_pucch_rx_power(module_idP,CC_id) + 20; + target_rx_power = cc[CC_id].radioResourceConfigCommon->uplinkPowerControlCommon.p0_NominalPUCCH + 20; // this assumes accumulated tpc // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out @@ -1184,27 +1211,59 @@ schedule_ue_spec( module_idP,CC_id,harq_pid,round,mcs); } - 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, - UE_list->UE_template[CC_id][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; - - eNB->TX_req[CC_id].sfn_sf = (frameP<<3)+subframeP; - TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; - TX_req->pdu_length = TBS; - TX_req->pdu_index = eNB->pdu_index[CC_id]++; - TX_req->num_segments = 1; - TX_req->segments[0].segment_length = TBS; - TX_req->segments[0].segment_data = eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[harq_pid]; - eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; - + if (!CCE_allocation_infeasible(module_idP,CC_id,1,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,rnti)) { + 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, unused here + 0, // resource_block_coding, to be filled in later + 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 + UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, + 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[harq_pid]); + + eNB->pdu_index[CC_id]++; + program_dlsch_acknak(module_idP,CC_id,UE_id,frameP,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); + + } + else { + LOG_W(MAC,"Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d/%x, infeasible CCE allocations\n", + frameP,subframeP,UE_id,rnti); + } } else { // There is no data from RLC or MAC header, so don't schedule } @@ -1277,7 +1336,8 @@ fill_DLSCH_dci( // clear scheduling flag eNB_dlsch_info[module_idP][CC_id][UE_id].status = S_DL_WAITING; rnti = UE_RNTI(module_idP,UE_id); - harq_pid = UE_list->UE_sched_ctrl[UE_id].harq_pid[CC_id]; + if (cc->tdd_Config) harq_pid = ((frameP*10)+subframeP)%10; + else harq_pid = ((frameP*10)+subframeP)&7; nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; @@ -1297,7 +1357,11 @@ fill_DLSCH_dci( (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti)) { dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb,N_RB_DL,N_RBG,rballoc_sub); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0; - break; + } + else if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE)&& + (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti)) { + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb,N_RB_DL,N_RBG,rballoc_sub); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 0; } } } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 45cb7082f9..dea0a91481 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -59,6 +59,52 @@ #define ENABLE_MAC_PAYLOAD_DEBUG #define DEBUG_eNB_SCHEDULER 1 +int choose(int n,int k) { + + int res = 1; + int res2 = 1; + int i; + + if (k>n) return(0); + if (n==k) return(1); + + for (i=n;i>k;i--) res*=i; + for (i=2;i<=(n-k);i++) res2*=i; + + return(res/res2); +} + +// Patented algorithm from Yang et al, US Patent 2009, "Channel Quality Indexing and Reverse Indexing" +void reverse_index(int N,int M,int r,int *v) { + + int BaseValue=0; + int IncreaseValue,ThresholdValue; + int sumV; + int i; + + r = choose(N,M) - 1 - r; + memset((void*)v,0,M*sizeof(int)); + + sumV=0; + i=M; + while (i>0 && r>0) { + + IncreaseValue = choose(N-M+1-sumV-v[i-1]+i-2,i-1); + ThresholdValue = BaseValue+IncreaseValue; + if (r>=ThresholdValue) { + v[i-1]++; + BaseValue=ThresholdValue; + } + else { + r=r-BaseValue; + sumV+=v[i-1]; + i--; + BaseValue=0; + } + + } + +} int to_prb(int dl_Bandwidth) { int prbmap[6] = {6,15,25,50,75,100}; @@ -97,7 +143,15 @@ uint16_t mac_computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs) { return(RIV); } +uint8_t getQm(uint8_t mcs) { + + if (mcs<10) return(2); + else if (mcs<17) return(4); + else return (6); +} + void get_Msg3alloc(COMMON_channels_t *cc, + sub_frame_t current_subframe, frame_t current_frame, frame_t *frame, @@ -403,6 +457,53 @@ uint8_t get_Msg3harqpid(COMMON_channels_t *cc, } +uint32_t pdcchalloc2ulframe(COMMON_channels_t *ccP,uint32_t frame, uint8_t n) +{ + uint32_t ul_frame; + + if ((ccP->tdd_Config) && + (ccP->tdd_Config->subframeAssignment == 1) && + ((n==1)||(n==6))) // tdd_config 0,1 SF 1,5 + ul_frame = (frame + (n==1 ? 0 : 1)); + else if ((ccP->tdd_Config) && + (ccP->tdd_Config->subframeAssignment == 6) && + ((n==0)||(n==1)||(n==5)||(n==6))) + ul_frame = (frame + (n>=5 ? 1 : 0)); + else if ((ccP->tdd_Config) && + (ccP->tdd_Config->subframeAssignment == 6) && + (n==9)) // tdd_config 6 SF 9 + ul_frame = (frame+1); + else + ul_frame = (frame+(n>=6 ? 1 : 0)); + + LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n", frame, n, ul_frame); + return ul_frame; + +} + +uint8_t pdcchalloc2ulsubframe(COMMON_channels_t *ccP,uint8_t n) { + + uint8_t ul_subframe; + + if ((ccP->tdd_Config) && + (ccP->tdd_Config->subframeAssignment == 1) && + ((n==1)||(n==6))) // tdd_config 0,1 SF 1,5 + ul_subframe = ((n+6)%10); + else if ((ccP->tdd_Config) && + (ccP->tdd_Config->subframeAssignment == 6) && + ((n==0)||(n==1)||(n==5)||(n==6))) + ul_subframe = ((n+7)%10); + else if ((ccP->tdd_Config) && + (ccP->tdd_Config->subframeAssignment == 6) && + (n==9)) // tdd_config 6 SF 9 + ul_subframe = ((n+5)%10); + else + ul_subframe = ((n+4)%10); + + LOG_D(PHY, "subframe %d: PUSCH subframe = %d\n", n, ul_subframe); + return ul_subframe; +} + int is_UL_sf(COMMON_channels_t *ccP,sub_frame_t subframeP) { @@ -460,12 +561,751 @@ int is_UL_sf(COMMON_channels_t *ccP,sub_frame_t subframeP) default: AssertFatal(1==0,"subframe %d Unsupported TDD configuration %d\n", - subframeP,ccP->tdd_Config->subframeAssignment); + subframeP,(int)ccP->tdd_Config->subframeAssignment); break; } } +uint16_t get_pucch1_absSF(COMMON_channels_t *cc,uint16_t dlsch_absSF) { + + uint16_t sf,f,nextf; + + if (cc->tdd_Config==NULL) { //FDD n+4 + return((dlsch_absSF + 4)%10240); + } + else { + sf = dlsch_absSF%10; + f = dlsch_absSF/10; + nextf = (f+1)&1023; + + switch (cc->tdd_Config->subframeAssignment) { + case 0: + AssertFatal(1==0,"SFA 0 to be filled in now, :-)\n"); + break; + case 1: + if ((sf==5) || (sf==6)) return((10*nextf) + 2); // ACK/NAK in SF 2 next frame + else if (sf==9) return((10*nextf) + 3); // ACK/NAK in SF 3 next frame + else if ((sf==0) || (sf==1)) return((10*f) + 2); // ACK/NAK in SF 7 same frame + else AssertFatal(1==0,"Impossible dlsch subframe %d for TDD configuration 3\n",sf); + break; + case 2: + if ((sf==4) || (sf==5) || (sf==6) || (sf==8)) return((10*nextf) + 2); // ACK/NAK in SF 2 next frame + else if (sf==9) return((10*nextf) + 7); // ACK/NAK in SF 7 next frame + else if ((sf==0) || (sf==1) || (sf==3)) return((10*f) + 7); // ACK/NAK in SF 7 same frame + else AssertFatal(1==0,"Impossible dlsch subframe %d for TDD configuration 3\n",sf); + break; + case 3: + if ((sf==5) || (sf==6) || (sf==7) || (sf==8) || (sf==9)) return((10*nextf) + (sf>>1)); // ACK/NAK in 2,3,4 resp. next frame + else if (sf==1) return((10*nextf) + 2); // ACK/NAK in 2 next frame + else if (sf==0) return((10*f) + 4); // ACK/NAK in 4 same frame + else AssertFatal(1==0,"Impossible dlsch subframe %d for TDD configuration 3\n",sf); + break; + case 4: + if ((sf==6) || (sf==7) || (sf==8) || (sf==9)) return(((10*nextf) + 3)%10240); // ACK/NAK in SF 3 next frame + else if ((sf==0) || (sf==1) || (sf==4) || (sf==5)) return(((10*nextf) + 2)%10240); // ACK/NAK in SF 2 next frame + else AssertFatal(1==0,"Impossible dlsch subframe %d for TDD configuration 4\n",sf); + break; + case 5: + if ((sf==0) || (sf==1) || (sf==3) || (sf==4) || (sf==5) || (sf==6) || (sf==7) || (sf==8)) return(((10*nextf) + 2)%10240); // ACK/NAK in SF 3 next frame + else if (sf==9) return(((10*(1+nextf)) + 2)%10240); // ACK/NAK in SF 2 next frame + else AssertFatal(1==0,"Impossible dlsch subframe %d for TDD configuration 5\n",sf); + break; + case 6: + AssertFatal(1==0,"SFA 6 To be filled in now, :-)\n"); + break; + default: + AssertFatal(1==0,"Illegal TDD subframe Assigment %d\n",(int)cc->tdd_Config->subframeAssignment); + break; + } + } + AssertFatal(1==0,"Shouldn't get here\n"); +} + +void get_srs_pos(COMMON_channels_t *cc,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset) { + + if(cc->tdd_Config) { // TDD + AssertFatal(isrs>=10,"2 ms SRS periodicity not supported"); + + if ((isrs>9)&&(isrs<15)) { + *psrsPeriodicity=5; + *psrsOffset=isrs-10; + } + if ((isrs>14)&&(isrs<25)) { + *psrsPeriodicity=10; + *psrsOffset=isrs-15; + } + if ((isrs>24)&&(isrs<45)) { + *psrsPeriodicity=20; + *psrsOffset=isrs-25; + } + if ((isrs>44)&&(isrs<85)) { + *psrsPeriodicity=40; + *psrsOffset=isrs-45; + } + if ((isrs>84)&&(isrs<165)) { + *psrsPeriodicity=80; + *psrsOffset=isrs-85; + } + if ((isrs>164)&&(isrs<325)) { + *psrsPeriodicity=160; + *psrsOffset=isrs-165; + } + if ((isrs>324)&&(isrs<645)) { + *psrsPeriodicity=320; + *psrsOffset=isrs-325; + } + + AssertFatal(isrs<=644,"Isrs out of range %d>644\n",isrs); + + } // TDD + else { // FDD + + if (isrs<2) { + *psrsPeriodicity=2; + *psrsOffset=isrs; + } + if ((isrs>1)&&(isrs<7)) { + *psrsPeriodicity=5; + *psrsOffset=isrs-2; + } + if ((isrs>6)&&(isrs<17)) { + *psrsPeriodicity=10; + *psrsOffset=isrs-7; + } + if ((isrs>16)&&(isrs<37)) { + *psrsPeriodicity=20; + *psrsOffset=isrs-17; + } + if ((isrs>36)&&(isrs<77)) { + *psrsPeriodicity=40; + *psrsOffset=isrs-37; + } + if ((isrs>76)&&(isrs<157)) { + *psrsPeriodicity=80; + *psrsOffset=isrs-77; + } + if ((isrs>156)&&(isrs<317)) { + *psrsPeriodicity=160; + *psrsOffset=isrs-157; + } + if ((isrs>316)&&(isrs<637)) { + *psrsPeriodicity=320; + *psrsOffset=isrs-317; + } + AssertFatal(isrs<=636,"Isrs out of range %d>636\n",isrs); + + } +} + +void get_csi_params(COMMON_channels_t *cc,struct CQI_ReportPeriodic *cqi_ReportPeriodic,uint16_t *Npd,uint16_t *N_OFFSET_CQI,int *H) { + + uint16_t cqi_PMI_ConfigIndex = cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex; + uint8_t Jtab[6] = {0,2,2,3,4,4}; + + AssertFatal(cqi_ReportPeriodic!=NULL,"cqi_ReportPeriodic is null!\n"); + + if (cc->tdd_Config==NULL) { //FDD + if (cqi_PMI_ConfigIndex <= 1) { // 2 ms CQI_PMI period + *Npd = 2; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex; + } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period + *Npd = 5; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex-2; + } else if (cqi_PMI_ConfigIndex <=16) { // 10ms CQI_PMI period + *Npd = 10; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex-7; + } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period + *Npd = 20; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex-17; + } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period + *Npd = 40; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex-37; + } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period + *Npd = 80; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex-77; + } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period + *Npd = 160; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex-157; + } + else if (cqi_PMI_ConfigIndex > 317) { + + if (cqi_PMI_ConfigIndex <= 349) { // 32 ms CQI_PMI period + *Npd = 32; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex-318; + } + else if (cqi_PMI_ConfigIndex <= 413) { // 64 ms CQI_PMI period + *Npd = 64; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex-350; + } + else if (cqi_PMI_ConfigIndex <= 541) { // 128 ms CQI_PMI period + *Npd = 128; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex-414; + } + } + } + else { // TDD + if (cqi_PMI_ConfigIndex == 0) { // all UL subframes + *Npd = 1; + *N_OFFSET_CQI = 0; + } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period + *Npd = 5; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex-1; + } else if (cqi_PMI_ConfigIndex <=16) { // 10ms CQI_PMI period + *Npd = 10; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex-6; + } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period + *Npd = 20; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex-16; + } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period + *Npd = 40; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex-36; + } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period + *Npd = 80; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex-76; + } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period + *Npd = 160; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex-156; + } + } + + // get H + if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) + *H = 1+(Jtab[cc->mib->message.dl_Bandwidth]*cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.choice.subbandCQI.k); + else + *H=1; +} + + +uint8_t get_dl_cqi_pmi_size_pusch(UE_sched_ctrl *sched_ctl,COMMON_channels_t *cc,uint8_t tmode,uint8_t ri, CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic) { + + int Ntab[6] = {0,4,7,9,10,13}; + int Ntab_uesel[6] = {0,8,13,17,19,25}; + int N = Ntab[cc->p_eNB]; + int Ltab_uesel[6] = {0,6,9,13,15,18}; + int L = Ltab_uesel[cc->p_eNB]; + + AssertFatal(cqi_ReportModeAperiodic != NULL,"cqi_ReportPeriodic is null!\n"); + + switch (*cqi_ReportModeAperiodic) { + + case CQI_ReportModeAperiodic_rm12: + AssertFatal(tmode==4 || tmode==6 || tmode==8 || tmode==9 || tmode==10,"Illegal TM (%d) for CQI_ReportModeAperiodic_rm12\n",tmode); + AssertFatal(cc->p_eNB<=4,"only up to 4 antenna ports supported here\n"); + if (ri==1 && cc->p_eNB==2) return(4+(N<<1)); + else if (ri==2 && cc->p_eNB==2) return(8+N); + else if (ri==1 && cc->p_eNB==4) return(4+(N<<2)); + else if (ri>1 && cc->p_eNB==4) return(8+(N<<2)); + break; + case CQI_ReportModeAperiodic_rm20: + // Table 5.2.2.6.3-1 (36.212) + AssertFatal(tmode==1 || tmode==2 || tmode==3 || tmode==7 || tmode==9 || tmode==10,"Illegal TM (%d) for CQI_ReportModeAperiodic_rm20\n",tmode); + AssertFatal(tmode!=9 && tmode!=10,"TM9/10 will be handled later for CQI_ReportModeAperiodic_rm20\n"); + return(4+2+L); + break; + case CQI_ReportModeAperiodic_rm22: + // Table 5.2.2.6.3-2 (36.212) + AssertFatal(tmode==4 || tmode==6 || tmode==8 || tmode==9 || tmode==10,"Illegal TM (%d) for CQI_ReportModeAperiodic_rm22\n",tmode); + AssertFatal(tmode!=9 && tmode!=10,"TM9/10 will be handled later for CQI_ReportModeAperiodic_rm22\n"); + if (ri==1 && cc->p_eNB==2) return(4+2+0+0+L+4); + if (ri==2 && cc->p_eNB==2) return(4+2+4+2+L+2); + if (ri==1 && cc->p_eNB==4) return(4+2+0+0+L+8); + if (ri>=2 && cc->p_eNB==4) return(4+2+4+2+L+8); + break; + case CQI_ReportModeAperiodic_rm30: + // Table 5.2.2.6.2-1 (36.212) + AssertFatal(tmode==1 || tmode==2 || tmode==3 || tmode==7 || tmode==8 || tmode==9 || tmode==10,"Illegal TM (%d) for CQI_ReportModeAperiodic_rm30\n",tmode); + AssertFatal(tmode!=8 && tmode!=9 && tmode!=10,"TM8/9/10 will be handled later for CQI_ReportModeAperiodic_rm30\n"); + return(4+(N<<1)); + break; + case CQI_ReportModeAperiodic_rm31: + // Table 5.2.2.6.2-2 (36.212) + AssertFatal(tmode==4 || tmode==6 || tmode==8 || tmode==9 || tmode==10,"Illegal TM (%d) for CQI_ReportModeAperiodic_rm31\n",tmode); + AssertFatal(tmode!=8 && tmode!=9 && tmode!=10,"TM8/9/10 will be handled later for CQI_ReportModeAperiodic_rm31\n"); + if (ri==1 && cc->p_eNB==2) return(4+(N<<1)+0+0+2); + else if (ri==2 && cc->p_eNB==2) return(4+(N<<1)+4+(N<<1)+1); + else if (ri==1 && cc->p_eNB==4) return(4+(N<<1)+0+0+4); + else if (ri>=2 && cc->p_eNB==4) return(4+(N<<1)+4+(N<<1)+4); + break; + case CQI_ReportModeAperiodic_rm32_v1250: + AssertFatal(tmode==4 || tmode==6 || tmode==8 || tmode==9 || tmode==10,"Illegal TM (%d) for CQI_ReportModeAperiodic_rm32\n",tmode); + AssertFatal(1==0,"CQI_ReportModeAperiodic_rm32_v1250 not supported yet\n"); + break; + case CQI_ReportModeAperiodic_rm10_v1310: + // Table 5.2.2.6.1-1F/G (36.212) + if (ri==1) return(4); // F + else return(7); // G + break; + case CQI_ReportModeAperiodic_rm11_v1310: + // Table 5.2.2.6.1-1H (36.212) + AssertFatal(tmode==4 || tmode==6 || tmode==8 || tmode==9 || tmode==10,"Illegal TM (%d) for CQI_ReportModeAperiodic_rm11\n",tmode); + AssertFatal(cc->p_eNB<=4,"only up to 4 antenna ports supported here\n"); + if (ri==1 && cc->p_eNB==2) return(4+0+2); + else if (ri==2 && cc->p_eNB==2) return(4+4+1); + else if (ri==1 && cc->p_eNB==4) return(4+0+4); + else if (ri>1 && cc->p_eNB==4) return(4+4+4); + + break; + } + +} + +uint8_t get_rel8_dl_cqi_pmi_size(UE_sched_ctrl *sched_ctl,int CC_idP,COMMON_channels_t *cc,uint8_t tmode, struct CQI_ReportPeriodic *cqi_ReportPeriodic) { + + int no_pmi=0; + // Ltab[6] = {0,log2(15/4/2),log2(25/4/2),log2(50/6/3),log2(75/8/4),log2(100/8/4)}; + + uint8_t Ltab[6] = {0,1,2,2,2,2}; + uint8_t ri = sched_ctl->periodic_ri_received[CC_idP]; + + AssertFatal(cqi_ReportPeriodic != NULL,"cqi_ReportPeriodic is null!\n"); + AssertFatal(cqi_ReportPeriodic->present != CQI_ReportPeriodic_PR_NOTHING, + "cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_NOTHING!\n"); + AssertFatal(cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present != CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING, + "cqi_ReportPeriodic->cqi_FormatIndicatorPeriodic.choice.setup.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING!\n"); + + switch(tmode) { + case 1: + case 2: + case 5: + case 6: + case 7: + no_pmi=1; + break; + default: + no_pmi=0; + } + + + + if ((cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_widebandCQI) || + (sched_ctl->feedback_cnt[CC_idP] == 0)) { + // send wideband report every opportunity if wideband reporting mode is selected, else every H opportunities + if (no_pmi == 1) + return(4); + else if ((cc->p_eNB==2) && (ri==1)) return(6); + else if ((cc->p_eNB==2) && (ri==2)) return(8); + else if ((cc->p_eNB==4) && (ri==1)) return(8); + else if ((cc->p_eNB==4) && (ri==2)) return(11); + else AssertFatal(1==0,"illegal combination p %d, ri %d, no_pmi %d\n",cc->p_eNB,ri,no_pmi); + } + else if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) { + if ((no_pmi == 1)||ri==1) return(4+Ltab[cc->mib->message.dl_Bandwidth]); + else + return(7+Ltab[cc->mib->message.dl_Bandwidth]); + } + AssertFatal(1==0,"Shouldn't get here : cqi_ReportPeriodic->present %d\n",cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present); +} + +void fill_nfapi_dl_dci_1A(nfapi_dl_config_request_pdu_t *dl_config_pdu, + uint8_t aggregation_level, + uint16_t rnti, + uint8_t rnti_type, + uint8_t harq_process, + uint8_t tpc, + uint16_t resource_block_coding, + uint8_t mcs, + uint8_t ndi, + uint8_t rv, + uint8_t vrb_flag) { + + 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_1A; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = aggregation_level; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = rnti_type; + 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_process; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; // no TPC + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = resource_block_coding; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; + 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.redundancy_version_1 = rv; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = vrb_flag; + +} + +void program_dlsch_acknak(module_id_t module_idP, int CC_idP,int UE_idP, frame_t frameP, sub_frame_t subframeP,uint8_t cce_idx) { + + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = eNB->common_channels; + UE_list_t *UE_list = &eNB->UE_list; + rnti_t rnti = UE_RNTI(module_idP,UE_idP); + nfapi_ul_config_request_body_t *ul_req; + nfapi_ul_config_request_pdu_t *ul_config_pdu; + + int use_simultaneous_pucch_pusch=0; + nfapi_ul_config_ulsch_harq_information *ulsch_harq_information = NULL; + nfapi_ul_config_harq_information *harq_information = NULL; + +#if defined(Rel10) || defined(Rel14) + + if ((UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2) && + (UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020) && + (UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020->simultaneousPUCCH_PUSCH_r10) && + (*UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020->simultaneousPUCCH_PUSCH_r10 == PUCCH_ConfigDedicated_v1020__simultaneousPUCCH_PUSCH_r10_true)) use_simultaneous_pucch_pusch=1; +#endif + + // pucch1 and pusch feedback is similar, namely in n+k subframes from now + // This is used in the following "if/else" condition to check if there isn't or is already an UL grant in n+k + int16_t ul_absSF = get_pucch1_absSF(&cc[CC_idP],subframeP+(10*frameP)); + + if ((ul_config_pdu = has_ul_grant(module_idP,CC_idP, + ul_absSF, + rnti)) == NULL) { + // no UL grant so + // Program ACK/NAK alone Format 1a/b or 3 + + ul_req = &RC.mac[module_idP]->UL_req_tmp[CC_idP][ul_absSF%10].ul_config_request_body; + ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; + // Do PUCCH + fill_nfapi_uci_acknak(module_idP, + CC_idP, + rnti, + (frameP*10)+subframeP, + cce_idx); + } + else { // there is already an existing UL grant so update it if needed + // on top of some other UL resource (PUSCH,combined SR/CQI/HARQ on PUCCH, etc) + switch(ul_config_pdu->pdu_type) { + case NFAPI_UL_CONFIG_ULSCH_PDU_TYPE: + case NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE: + case NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE: + if (use_simultaneous_pucch_pusch==1) { + AssertFatal(ul_config_pdu->pdu_type==NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE, + "Cannot be NFAPI_UL_CONFIG_ULSCH_PDU_TYPE, simultaneous_pucch_pusch is active\n"); + // Convert it to an NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE + harq_information = &ul_config_pdu->ulsch_uci_harq_pdu.harq_information; + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE; + } + else { + AssertFatal(ul_config_pdu->pdu_type==NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE, + "Cannot be NFAPI_UL_CONFIG_ULSCH_UCI_PDU_TYPE, simultaneous_pucch_pusch is inactive\n"); + // Convert it to an NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE + ulsch_harq_information = &ul_config_pdu->ulsch_harq_pdu.harq_information; + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; + ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial=0; // last symbol not punctured + ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks= + ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks; // we don't change the number of resource blocks across retransmissions yet + } + break; + case NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE: + case NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE: + case NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE: + case NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE: + if (use_simultaneous_pucch_pusch==1) { + AssertFatal(ul_config_pdu->pdu_type==NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE|| + ul_config_pdu->pdu_type==NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE, + "Cannot be NFAPI_UL_CONFIG_ULSCH_CQI_RI_xxx_PDU_TYPE, simultaneous_pucch_pusch is active\n"); + // convert it to an NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE + harq_information = &ul_config_pdu->ulsch_csi_uci_harq_pdu.harq_information; + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE; + + } + else { + AssertFatal(ul_config_pdu->pdu_type==NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE || + ul_config_pdu->pdu_type==NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE, + "Cannot be NFAPI_UL_CONFIG_ULSCH_UCI_xxx_PDU_TYPE, simultaneous_pucch_pusch is inactive\n"); + // Convert it to an NFAPI_UL_CONFIG_ULSCH_CQI_RI_HARQ_PDU_TYPE + ulsch_harq_information = &ul_config_pdu->ulsch_cqi_harq_ri_pdu.harq_information; + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; + ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial=0; // last symbol not punctured + ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks= + ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks; // we don't change the number of resource blocks across retransmissions yet + } + + break; + + case NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE: + case NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE: + // convert/keep it to NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE; + harq_information = &ul_config_pdu->uci_sr_harq_pdu.harq_information; + break; + case NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE: + case NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE: + // convert/keep it to NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE; + harq_information = &ul_config_pdu->uci_cqi_harq_pdu.harq_information; + break; + + case NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE: + case NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE: + // convert/keep it to NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE; + harq_information = &ul_config_pdu->uci_cqi_sr_harq_pdu.harq_information; + break; + } + } + + if (ulsch_harq_information) fill_nfapi_ulsch_harq_information(module_idP,CC_idP, + rnti, + ulsch_harq_information); + + + if (harq_information) fill_nfapi_harq_information(module_idP,CC_idP, + rnti, + (frameP*10)+subframeP, + harq_information, + cce_idx); +} + +uint8_t get_V_UL_DAI(module_id_t module_idP,int CC_idP,uint16_t rntiP) { + + nfapi_hi_dci0_request_body_t *HI_DCI0_req = &RC.mac[module_idP]->HI_DCI0_req[CC_idP].hi_dci0_request_body; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[0]; + + for (int i=0;i<HI_DCI0_req->number_of_dci;i++) { + if ((hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE)&& + (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti == rntiP)) + return(hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.dl_assignment_index); + } + return(4); // this is rule from Section 7.3 in 36.213 +} +void fill_nfapi_ulsch_harq_information(module_id_t module_idP, + int CC_idP, + uint16_t rntiP, + nfapi_ul_config_ulsch_harq_information *harq_information) { + + + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; + UE_list_t *UE_list = &eNB->UE_list; + + int UE_id = find_UE_id(module_idP,rntiP); + + PUSCH_ConfigDedicated_t *puschConfigDedicated; + // PUSCH_ConfigDedicated_v1020_t *puschConfigDedicated_v1020; + // PUSCH_ConfigDedicated_v1130_t *puschConfigDedicated_v1130; + // PUSCH_ConfigDedicated_v1250_t *puschConfigDedicated_v1250; + + AssertFatal(UE_id>=0,"UE_id cannot be found, impossible\n"); + AssertFatal(UE_list!=NULL,"UE_list is null\n"); + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated!=NULL,"physicalConfigDedicated for rnti %x is null\n",rntiP); + AssertFatal((puschConfigDedicated = (PUSCH_ConfigDedicated_t *)UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pusch_ConfigDedicated)!=NULL,"physicalConfigDedicated->puschConfigDedicated for rnti %x is null\n",rntiP); +#if defined(Rel14) || defined(Rel14) + /* if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext2) puschConfigDedicated_v1020 = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext2->pusch_ConfigDedicated_v1020; +#endif +#ifdef Rel14 + if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext4) puschConfigDedicated_v1130 = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext4->pusch_ConfigDedicated_v1130; + if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext5) puschConfigDedicated_v1250 = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext5->pusch_ConfigDedicated_v1250; + */ +#endif + harq_information->harq_information_rel10.delta_offset_harq = puschConfigDedicated->betaOffset_ACK_Index; + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated!=NULL,"pucch_ConfigDedicated is null!\n"); + if ((UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode!=NULL)&& + (*UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode==PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) + harq_information->harq_information_rel10.ack_nack_mode = 1; // multiplexing + else + harq_information->harq_information_rel10.ack_nack_mode = 0; // bundling + + switch(get_tmode(module_idP,CC_idP,UE_id)) { + case 1: + case 2: + case 5: + case 6: + case 7: + + if (cc->tdd_Config==NULL) // FDD + harq_information->harq_information_rel10.harq_size = 1; + else { + if (harq_information->harq_information_rel10.ack_nack_mode == 1) + harq_information->harq_information_rel10.harq_size = get_V_UL_DAI(module_idP,CC_idP,rntiP); + else + harq_information->harq_information_rel10.harq_size = 1; + } + break; + default: // for any other TM we need 2 bits harq + + if (cc->tdd_Config==NULL) { + harq_information->harq_information_rel10.harq_size = 2; + } + else { + if (harq_information->harq_information_rel10.ack_nack_mode == 1) + harq_information->harq_information_rel10.harq_size = get_V_UL_DAI(module_idP,CC_idP,rntiP); + else + harq_information->harq_information_rel10.harq_size = 2; + } + break; + } // get Tmode +} + +void fill_nfapi_harq_information(module_id_t module_idP, + int CC_idP, + uint16_t rntiP, + uint16_t absSFP, + nfapi_ul_config_harq_information *harq_information, + uint8_t cce_idxP) { + + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; + UE_list_t *UE_list = &eNB->UE_list; + + int UE_id = find_UE_id(module_idP,rntiP); + + + AssertFatal(UE_id>=0,"UE_id cannot be found, impossible\n"); + AssertFatal(UE_list!=NULL,"UE_list is null\n"); + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated!=NULL,"physicalConfigDedicated for rnti %x is null\n",rntiP); + + harq_information->harq_information_rel11.num_ant_ports = 1; + + switch(get_tmode(module_idP,CC_idP,UE_id)) { + case 1: + case 2: + case 5: + case 6: + case 7: + if (cc->tdd_Config!=NULL) { + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated!=NULL, + "pucch_ConfigDedicated is null for TDD!\n"); + if ((UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode!=NULL)&& + (*UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode==PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) { + harq_information->harq_information_rel10_tdd.harq_size = 2; // 2-bit ACK/NAK + harq_information->harq_information_rel10_tdd.ack_nack_mode = 1; // multiplexing + } + else { + harq_information->harq_information_rel10_tdd.harq_size = 1; // 1-bit ACK/NAK + harq_information->harq_information_rel10_tdd.ack_nack_mode = 0; // bundling + } + harq_information->harq_information_rel10_tdd.n_pucch_1_0 = cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP; + harq_information->harq_information_rel10_tdd.number_of_pucch_resources = 1; + } else { + harq_information->harq_information_rel9_fdd.number_of_pucch_resources = 1; + harq_information->harq_information_rel9_fdd.harq_size = 1; // 1-bit ACK/NAK + harq_information->harq_information_rel9_fdd.n_pucch_1_0 = cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP; + } + break; + default: // for any other TM we need 2 bits harq + if (cc->tdd_Config!=NULL) { + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated!=NULL, + "pucch_ConfigDedicated is null for TDD!\n"); + if ((UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode!=NULL)&& + (*UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode==PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) { + harq_information->harq_information_rel10_tdd.ack_nack_mode = 1; // multiplexing + } + else { + harq_information->harq_information_rel10_tdd.ack_nack_mode = 0; // bundling + } + harq_information->harq_information_rel10_tdd.harq_size = 2; + harq_information->harq_information_rel10_tdd.n_pucch_1_0 = cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP; + harq_information->harq_information_rel10_tdd.number_of_pucch_resources = 1; + } + else { + harq_information->harq_information_rel9_fdd.number_of_pucch_resources = 1; + harq_information->harq_information_rel9_fdd.ack_nack_mode = 0; // 1a/b + harq_information->harq_information_rel9_fdd.harq_size = 2; + harq_information->harq_information_rel9_fdd.n_pucch_1_0 = cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP; + } + break; + } // get Tmode +} + + +uint16_t fill_nfapi_uci_acknak(module_id_t module_idP, + int CC_idP, + uint16_t rntiP, + uint16_t absSFP, + uint8_t cce_idxP) { + + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; + + int ackNAK_absSF = get_pucch1_absSF(cc,absSFP); + nfapi_ul_config_request_body_t *ul_req = &eNB->UL_req_tmp[CC_idP][ackNAK_absSF%10].ul_config_request_body; + nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; + + + memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t)); + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_ul_config_uci_harq_pdu)); + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0; // don't know how to use this + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti = rntiP; + + fill_nfapi_harq_information(module_idP,CC_idP, + rntiP, + absSFP, + &ul_config_pdu->uci_harq_pdu.harq_information, + cce_idxP); + LOG_I(MAC,"Filled in HARQ for rnti %x, cce_idxP %d-> n1_pucch %d\n",rntiP,cce_idxP,ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.n_pucch_1_0); + + ul_req->number_of_pdus++; + + return(((ackNAK_absSF/10)<<4) + (ackNAK_absSF%10)); +} + +void fill_nfapi_dlsch_config(eNB_MAC_INST *eNB, + nfapi_dl_config_request_body_t *dl_req, + uint16_t length, + uint16_t pdu_index, + uint16_t rnti, + uint8_t resource_allocation_type, + uint8_t virtual_resource_block_assignment_flag, + uint16_t resource_block_coding, + uint8_t modulation, + uint8_t redundancy_version, + uint8_t transport_blocks, + uint8_t transport_block_to_codeword_swap_flag, + uint8_t transmission_scheme, + uint8_t number_of_layers, + uint8_t number_of_subbands, + // uint8_t codebook_index, + uint8_t ue_category_capacity, + uint8_t pa, + uint8_t delta_power_offset_index, + uint8_t ngap, + uint8_t nprb, + uint8_t transmission_mode, + uint8_t num_bf_prb_per_subband, + uint8_t num_bf_vector + ) { + + nfapi_dl_config_request_pdu_t *dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + + 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_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = length; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = pdu_index; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = rnti; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = resource_allocation_type; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = virtual_resource_block_assignment_flag; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = resource_block_coding; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = modulation; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = redundancy_version; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = transport_blocks; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = transport_block_to_codeword_swap_flag; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = transmission_scheme; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = number_of_layers; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = number_of_subbands; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = codebook_index; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = ue_category_capacity; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = pa; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = delta_power_offset_index; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = ngap; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = nprb; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = transmission_mode; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = num_bf_prb_per_subband; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = num_bf_vector; + dl_req->number_pdu++; +} + +uint16_t fill_nfapi_tx_req(nfapi_tx_request_body_t *tx_req_body,uint16_t absSF,uint16_t pdu_length, uint16_t *pdu_index, uint8_t *pdu) { + + nfapi_tx_request_pdu_t *TX_req = &tx_req_body->tx_pdu_list[tx_req_body->number_of_pdus]; + LOG_I(MAC,"Filling TX_req %d for pdu length %d\n",tx_req_body->number_of_pdus,pdu_length); + TX_req->pdu_length = pdu_length; + TX_req->pdu_index = *pdu_index++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = pdu_length; + TX_req->segments[0].segment_data = pdu; + tx_req_body->number_of_pdus++; + + return(((absSF/10)<<4) + (absSF%10)); +} #ifdef Rel14 int get_numnarrowbands(long dl_Bandwidth) { @@ -517,7 +1357,7 @@ int mpdcch_sf_condition(eNB_MAC_INST *eNB,int CC_id, frame_t frameP,sub_frame_t AssertFatal(1==0,"MPDCCH Type 2A not handled yet\n"); break; case TYPEUESPEC: - epdcch_setconfig_r11= &eNB->UE_list.UE_template[CC_id][UE_id].physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0] ; + epdcch_setconfig_r11= eNB->UE_list.UE_template[CC_id][UE_id].physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0] ; AssertFatal(epdcch_setconfig_r11 != NULL," epdcch_setconfig_r11 is null for UE specific \n"); @@ -564,7 +1404,7 @@ int narrowband_to_first_rb(COMMON_channels_t *cc, int nb_index) { else return(1+(6*nb_index)); break; default: - AssertFatal(1==0,"Impossible dl_Bandwidth %d\n",cc->mib->message.dl_Bandwidth); + AssertFatal(1==0,"Impossible dl_Bandwidth %d\n",(int)cc->mib->message.dl_Bandwidth); break; } } @@ -632,10 +1472,16 @@ int find_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP) - for (RA_id = 0; RA_id < NB_RA_PROC_MAX; RA_id++) + for (RA_id = 0; RA_id < NB_RA_PROC_MAX; RA_id++) { + LOG_I(MAC,"Checking RA_id %d for %x : RA_active %d, wait_ack_Msg4 %d\n", + RA_id,rntiP, + RA_template[RA_id].RA_active, + RA_template[RA_id].wait_ack_Msg4); + if (RA_template[RA_id].RA_active==TRUE && RA_template[RA_id].wait_ack_Msg4 == 0 && RA_template[RA_id].rnti == rntiP) return(RA_id); + } return(-1); } @@ -815,9 +1661,7 @@ int rrc_mac_remove_ue(module_id_t mod_idP,rnti_t rntiP) int pCC_id; if (UE_id == -1) { -printf("MAC: cannot remove UE rnti %x\n", rntiP); LOG_W(MAC,"rrc_mac_remove_ue: UE %x not found\n", rntiP); - mac_phy_remove_ue(mod_idP, rntiP); return 0; } @@ -843,7 +1687,6 @@ printf("MAC: cannot remove UE rnti %x\n", rntiP); eNB_dlsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI; eNB_dlsch_info[mod_idP][pCC_id][UE_id].status = S_DL_NONE; - mac_phy_remove_ue(mod_idP,rntiP); // check if this has an RA process active RA_TEMPLATE *RA_template; @@ -1151,7 +1994,7 @@ uint8_t UE_is_to_be_scheduled(module_id_t module_idP,int CC_id,uint8_t UE_id) if (UE_sched_ctl->ul_out_of_sync>0) return(0); - LOG_D(MAC,"[eNB %d][PUSCH] Checking UL requirements UE %d/%x\n",module_idP,UE_id,UE_RNTI(module_idP,UE_id)); + LOG_I(MAC,"[eNB %d][PUSCH] Checking UL requirements UE %d/%x\n",module_idP,UE_id,UE_RNTI(module_idP,UE_id)); if ((UE_template->bsr_info[LCGID0]>0) || (UE_template->bsr_info[LCGID1]>0) || @@ -1165,7 +2008,7 @@ uint8_t UE_is_to_be_scheduled(module_id_t module_idP,int CC_id,uint8_t UE_id) (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED))) // every Frame when not RRC_CONNECTED { - LOG_D(MAC,"[eNB %d][PUSCH] UE %d/%x should be scheduled\n",module_idP,UE_id,UE_RNTI(module_idP,UE_id)); + LOG_I(MAC,"[eNB %d][PUSCH] UE %d/%x should be scheduled\n",module_idP,UE_id,UE_RNTI(module_idP,UE_id)); return(1); } else { return(0); @@ -1955,10 +2798,94 @@ try_again: return 0; -failed: + failed: return -1; } +/* +uint8_t get_ul_req_index(module_id_t module_idP, int CC_idP, sub_frame_t subframeP) { + + if (RC.mac[module_idP]->common_channels[CC_idP].tdd_Config == NULL) + return(0); + + switch (RC.mac[module_idP]->common_channels[CC_idP].tdd_Config->subframeAssignment) { + + case 0: + case 1: + case 2: + case 6: + return(0); + case 3: + // 1,5,6 -> 2, prog. 8, buffer 0 + // 7,8 -> 3, prog. 9, buffer 1 + // 9,0 -> 4, prog. 0, buffer 0 + if ((subframeP == 7) || (subframeP == 8)) return(1); + else return(0); + case 4: + // 0,1,4,5 -> 2, prog. 8, buffer 0 + // 6,7,8,9 -> 3, prog. 9, buffer 1 + if (subframeP<6) return(0); + else return(1); + return(1); + break; + case 5: + // 9(-1),0,1,3,4,5,6,7,8,9 -> 2, prog 8, buffer 0 + return(0); + break; + default: + AssertFatal(1==0,"Should not get here, why is tdd_Config->subframeAssignment = %d\n",(int)RC.mac[module_idP]->common_channels[CC_idP].tdd_Config->subframeAssignment); + break; + } + return(0); +} +*/ + +nfapi_ul_config_request_pdu_t* has_ul_grant(module_id_t module_idP,int CC_idP,uint16_t subframeP,uint16_t rnti) { + + nfapi_ul_config_request_body_t *ul_req; + nfapi_ul_config_request_pdu_t *ul_config_pdu; + + ul_req = &RC.mac[module_idP]->UL_req_tmp[CC_idP][subframeP].ul_config_request_body; + ul_config_pdu = &ul_req->ul_config_pdu_list[0]; + + for (int i=0; i<ul_req->number_of_pdus;i++){ + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE)&& + (ul_config_pdu[i].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) return(&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE)&& + (ul_config_pdu[i].ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) return(&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE)&& + (ul_config_pdu[i].ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) return(&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE)&& + (ul_config_pdu[i].ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) return(&ul_config_pdu[i]); + + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE)&& + (ul_config_pdu[i].uci_cqi_pdu.ue_information.ue_information_rel8.rnti == rnti)) return(&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE)&& + (ul_config_pdu[i].uci_sr_pdu.ue_information.ue_information_rel8.rnti == rnti)) return(&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE)&& + (ul_config_pdu[i].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) return(&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE)&& + (ul_config_pdu[i].uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) return(&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE)&& + (ul_config_pdu[i].uci_cqi_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) return(&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE)&& + (ul_config_pdu[i].uci_cqi_sr_pdu.ue_information.ue_information_rel8.rnti == rnti)) return(&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE) && + (ul_config_pdu[i].uci_cqi_sr_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) return(&ul_config_pdu[i]); + + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE)&& + (ul_config_pdu[i].ulsch_uci_csi_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) return(&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE)&& + (ul_config_pdu[i].ulsch_uci_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) return(&ul_config_pdu[i]); + if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE)&& + (ul_config_pdu[i].ulsch_csi_uci_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) return(&ul_config_pdu[i]); + + + + } + return(NULL); // no ul grant at all for this UE +} + boolean_t CCE_allocation_infeasible(int module_idP, int CC_idP, int format_flag, @@ -1995,7 +2922,570 @@ boolean_t CCE_allocation_infeasible(int module_idP, return(res); } -void SR_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, rnti_t rntiP, sub_frame_t subframeP) +void extract_harq(module_id_t mod_idP,int CC_idP,int UE_id,frame_t frameP,sub_frame_t subframeP,void *harq_indication,int format) { + + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + rnti_t rnti = UE_RNTI(mod_idP,UE_id); + COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; + nfapi_harq_indication_fdd_rel13_t *harq_indication_fdd; + nfapi_harq_indication_tdd_rel13_t *harq_indication_tdd; + uint16_t num_ack_nak; + int numCC = UE_list->numactiveCCs[UE_id]; + int pCCid = UE_list->pCC_id[UE_id]; + int spatial_bundling = 0; + int tmode[5]; + int i,j; + uint8_t *pdu; + +#ifdef Rel14 + AssertFatal(UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->pucch_ConfigDedicated!=NULL,"pucch_ConfigDedicated is null!\n"); + if ((UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7) && + (UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13) && + (((UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13->spatialBundlingPUCCH_r13) && + (format==0)) || + ((UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13->spatialBundlingPUSCH_r13) && + (format==1)))) + spatial_bundling = 1; +#endif + + for (i=0;i<numCC;i++) tmode[i] = get_tmode(mod_idP,i,UE_id); + + if (cc->tdd_Config) { + harq_indication_tdd = (nfapi_harq_indication_tdd_rel13_t *)harq_indication; + // pdu = &harq_indication_tdd->harq_tb_n[0]; + + num_ack_nak = harq_indication_tdd->number_of_ack_nack; + + switch (harq_indication_tdd->mode) { + case 0: // Format 1a/b + AssertFatal(numCC==1,"numCC %d > 1, should not be using Format1a/b\n",numCC); + break; + case 1: // Channel Selection + break; + case 2: // Format 3 + break; + case 3: // Format 4 + break; + case 4: // Format 5 + break; + } + } + else { + + harq_indication_fdd = (nfapi_harq_indication_fdd_rel13_t *)harq_indication; + num_ack_nak = harq_indication_fdd->number_of_ack_nack; + pdu = &harq_indication_fdd->harq_tb_n[0]; + + uint8_t harq_pid = ((10*frameP) + subframeP + 10236)&7; + + switch (harq_indication_fdd->mode) { + case 0: // Format 1a/b (10.1.2.1) + AssertFatal(numCC==1,"numCC %d > 1, should not be using Format1a/b\n",numCC); + if (tmode[0]==1 || tmode[0]==2 || tmode[0]==5 || tmode[0]==6 || tmode[0]==7) { // NOTE: have to handle the case of TM9-10 with 1 antenna port + // single ACK/NAK bit + AssertFatal(num_ack_nak==1,"num_ack_nak %d > 1 for 1 CC and single-layer transmission\n",num_ack_nak); + AssertFatal(sched_ctl->round[CC_idP][harq_pid]<8,"Got ACK/NAK for inactive harq_pid %d for UE %d/%x\n",harq_pid,UE_id,rnti); + AssertFatal(pdu[0] == 1 || pdu[0] == 2, "Received ACK/NAK %d which is not 1 or 2 for harq_pid %d from UE %d/%x\n",pdu[0],harq_pid,UE_id,rnti); + LOG_I(MAC,"Received %d for harq_pid %d\n",pdu[0],harq_pid); + + if (pdu[0] == 1) { // ACK + sched_ctl->round[CC_idP][harq_pid]=8; // release HARQ process + sched_ctl->tbcnt[CC_idP][harq_pid]=0; + } + else if (pdu[0] == 2) // NAK + sched_ctl->round[CC_idP][harq_pid]++; // increment round + } + else { + // one or two ACK/NAK bits + AssertFatal(num_ack_nak>2,"num_ack_nak %d > 2 for 1 CC and TM3/4/8/9/10\n",num_ack_nak); + if ((num_ack_nak==2) && (sched_ctl->round[CC_idP][harq_pid]<8) && (sched_ctl->tbcnt[CC_idP][harq_pid]==1) && (pdu[0] == 1) && (pdu[1] == 1)) { + sched_ctl->round[CC_idP][harq_pid]=8; + sched_ctl->tbcnt[CC_idP][harq_pid]=0; + } + if ((num_ack_nak==2) && (sched_ctl->round[CC_idP][harq_pid]<8) && (sched_ctl->tbcnt[CC_idP][harq_pid]==1) && (pdu[0] == 2) && (pdu[1] == 2)) + sched_ctl->round[CC_idP][harq_pid]++; + else if (((num_ack_nak==2) && (sched_ctl->round[CC_idP][harq_pid]<8) && (sched_ctl->tbcnt[0][harq_pid]==2) && (pdu[0] == 1) && (pdu[1] == 2)) || + ((num_ack_nak==2) && (sched_ctl->round[CC_idP][harq_pid]<8) && (sched_ctl->tbcnt[CC_idP][harq_pid]==2) && (pdu[0] == 2) && (pdu[1] == 1))) { + sched_ctl->round[CC_idP][harq_pid]++; + sched_ctl->tbcnt[CC_idP][harq_pid]=1; + } + else if ((num_ack_nak==2) && (sched_ctl->round[CC_idP][harq_pid]<8) && (sched_ctl->tbcnt[CC_idP][harq_pid]==2) && (pdu[0] == 2) && (pdu[1] == 2)) + sched_ctl->round[CC_idP][harq_pid]++; + else AssertFatal(1==0,"Illegal ACK/NAK/round combination (%d,%d,%d,%d,%d) for harq_pid %d, UE %d/%x\n", + num_ack_nak,sched_ctl->round[CC_idP][harq_pid],sched_ctl->round[CC_idP][harq_pid],pdu[0],pdu[1], harq_pid,UE_id, + rnti); + } + break; + case 1: // FDD Channel Selection (10.1.2.2.1), must be received for 2 serving cells + AssertFatal(numCC==2,"Should not receive harq indication with channel selection with %d active CCs\n", + numCC); + + if ((num_ack_nak == 2) && (sched_ctl->round[pCCid][harq_pid]<8) && (sched_ctl->round[1-pCCid][harq_pid]<8) && (sched_ctl->tbcnt[pCCid][harq_pid]==1) && (sched_ctl->tbcnt[1-pCCid][harq_pid]==1)) { + AssertFatal(pdu[0]<=3,"pdu[0] %d is not ACK/NAK/DTX\n",pdu[0]); + AssertFatal(pdu[1]<=3,"pdu[1] %d is not ACK/NAK/DTX\n",pdu[1]); + if (pdu[0] == 1) sched_ctl->round[pCCid][harq_pid]=8; + else sched_ctl->round[pCCid][harq_pid]++; + if (pdu[1] == 1) sched_ctl->round[1-pCCid][harq_pid]=8; + else sched_ctl->round[1-pCCid][harq_pid]++; + } // A=2 + else if ((num_ack_nak == 3) && (sched_ctl->round[pCCid][harq_pid]<8) && (sched_ctl->tbcnt[pCCid][harq_pid]==2) && (sched_ctl->round[1-pCCid][harq_pid]<8) && (sched_ctl->tbcnt[1-pCCid][harq_pid]==1)) { + AssertFatal(pdu[0]<=3,"pdu[0] %d is not ACK/NAK/DTX\n",pdu[0]); + AssertFatal(pdu[1]<=3,"pdu[1] %d is not ACK/NAK/DTX\n",pdu[1]); + AssertFatal(pdu[2]<=3,"pdu[2] %d is not ACK/NAK/DTX\n",pdu[2]); + AssertFatal(sched_ctl->tbcnt[pCCid][harq_pid] == 2,"sched_ctl->tbcnt[%d][%d] != 2 for UE %d/%x\n",pCCid,harq_pid,UE_id,rnti); + AssertFatal(sched_ctl->tbcnt[1-pCCid][harq_pid] == 1,"sched_ctl->tbcnt[%d][%d] != 1 for UE %d/%x\n",1-pCCid,harq_pid,UE_id,rnti); + if ((pdu[0] == 1) && (pdu[1] == 1)) { // both ACK + sched_ctl->round[pCCid][harq_pid]=8; + sched_ctl->tbcnt[pCCid][harq_pid]=0; + } + else if (((pdu[0] == 2) && (pdu[1] == 1))|| + ((pdu[0] == 1) && (pdu[1] == 2))){ + sched_ctl->round[pCCid][harq_pid]++; + sched_ctl->tbcnt[pCCid][harq_pid]=1; + } + else + sched_ctl->round[pCCid][harq_pid]++; + + if (pdu[2] == 1) sched_ctl->round[1-pCCid][harq_pid]=8; + else sched_ctl->round[1-pCCid][harq_pid]++; + } // A=3 primary cell has 2 TBs + else if ((num_ack_nak == 3) && (sched_ctl->round[1-pCCid][harq_pid]<8) && (sched_ctl->round[pCCid][harq_pid]<8) && (sched_ctl->tbcnt[1-pCCid][harq_pid]==2) && (sched_ctl->tbcnt[pCCid][harq_pid]==1)) { + AssertFatal(pdu[0]<=3,"pdu[0] %d is not ACK/NAK/DTX\n",pdu[0]); + AssertFatal(pdu[1]<=3,"pdu[1] %d is not ACK/NAK/DTX\n",pdu[1]); + AssertFatal(pdu[2]<=3,"pdu[2] %d is not ACK/NAK/DTX\n",pdu[2]); + AssertFatal(sched_ctl->tbcnt[1-pCCid][harq_pid] == 2,"sched_ctl->tbcnt[%d][%d] != 2 for UE %d/%x\n",1-pCCid,harq_pid,UE_id,rnti); + AssertFatal(sched_ctl->tbcnt[pCCid][harq_pid] == 1,"sched_ctl->tbcnt[%d][%d] != 1 for UE %d/%x\n",pCCid,harq_pid,UE_id,rnti); + if ((pdu[0] == 1) && (pdu[1] == 1)) { // both ACK + sched_ctl->round[1-pCCid][harq_pid]=8; + sched_ctl->tbcnt[1-pCCid][harq_pid]=0; + } + else if (((pdu[0] >= 2) && (pdu[1] == 1))|| + ((pdu[0] == 1) && (pdu[1] >= 2))){ // one ACK + sched_ctl->round[1-pCCid][harq_pid]++; + sched_ctl->tbcnt[1-pCCid][harq_pid]=1; + } + else // both NAK/DTX + sched_ctl->round[1-pCCid][harq_pid]++; + + if (pdu[2] == 1) sched_ctl->round[pCCid][harq_pid]=8; + else sched_ctl->round[pCCid][harq_pid]++; + } // A=3 secondary cell has 2 TBs +#if MAX_NUM_CCs>1 + else if ((num_ack_nak == 4) && (sched_ctl->round[0][harq_pid]<8) && (sched_ctl->round[1][harq_pid]<8) && (sched_ctl->tbcnt[1-pCCid][harq_pid]==2) && (sched_ctl->tbcnt[pCCid][harq_pid]==2)) { + AssertFatal(pdu[0]<=3,"pdu[0] %d is not ACK/NAK/DTX\n",pdu[0]); + AssertFatal(pdu[1]<=3,"pdu[1] %d is not ACK/NAK/DTX\n",pdu[1]); + AssertFatal(pdu[2]<=3,"pdu[2] %d is not ACK/NAK/DTX\n",pdu[2]); + AssertFatal(pdu[3]<=3,"pdu[3] %d is not ACK/NAK/DTX\n",pdu[3]); + AssertFatal(sched_ctl->tbcnt[0][harq_pid] == 2,"sched_ctl->tbcnt[0][%d] != 2 for UE %d/%x\n",harq_pid,UE_id,rnti); + AssertFatal(sched_ctl->tbcnt[1][harq_pid] == 2,"sched_ctl->tbcnt[1][%d] != 2 for UE %d/%x\n",harq_pid,UE_id,rnti); + if ((pdu[0] == 1) && (pdu[1] == 1)) { // both ACK + sched_ctl->round[0][harq_pid]=8; + sched_ctl->tbcnt[0][harq_pid]=0; + } + else if (((pdu[0] >= 2) && (pdu[1] == 1))|| + ((pdu[0] == 1) && (pdu[1] >= 2))){ // one ACK + sched_ctl->round[0][harq_pid]++; + sched_ctl->tbcnt[0][harq_pid]=1; + } + else // both NAK/DTX + sched_ctl->round[0][harq_pid]++; + + if ((pdu[2] == 1) && (pdu[3] == 1)) { // both ACK + sched_ctl->round[1][harq_pid]=8; + sched_ctl->tbcnt[1][harq_pid]=0; + } + else if (((pdu[2] >= 2) && (pdu[3] == 1))|| + ((pdu[2] == 1) && (pdu[3] >= 2))){ // one ACK + sched_ctl->round[1][harq_pid]++; + sched_ctl->tbcnt[1][harq_pid]=1; + } + else // both NAK/DTX + sched_ctl->round[1][harq_pid]++; + } // A=4 both serving cells have 2 TBs +#endif + break; + case 2: // Format 3 + AssertFatal(numCC>2,"Should not receive harq indication with FDD format 3 with %d < 3 active CCs\n", + numCC); + for (i=0,j=0;i<numCC;i++) { + if ((sched_ctl->round[i][harq_pid]<8)) { + if (tmode[i]==1 || tmode[i]==2 || tmode[0]==5 || tmode[0]==6 || tmode[0]==7) { + if (pdu[j] == 1) { + sched_ctl->round[i][harq_pid]=8; + sched_ctl->tbcnt[i][harq_pid]=0; + } + else if (pdu[j] == 2) sched_ctl->round[i][harq_pid]++; + else AssertFatal(1==0,"Illegal harq_ack value for CC %d harq_pid %d (%d) UE %d/%x\n", + i,harq_pid,pdu[j],UE_id,rnti); + j++; + } + else if (spatial_bundling == 0) { + if ((sched_ctl->tbcnt[i][harq_pid]==2) && (pdu[j] == 1) && (pdu[j+1]==1)) { + sched_ctl->round[i][harq_pid]=8; + sched_ctl->tbcnt[i][harq_pid]=0; + } + else if ((sched_ctl->tbcnt[i][harq_pid]==2) && (pdu[j] == 1) && (pdu[j+1]==2)) { + sched_ctl->round[i][harq_pid]++; + sched_ctl->tbcnt[i][harq_pid]=1; + } + else if ((sched_ctl->tbcnt[i][harq_pid]==2) && (pdu[j] == 2) && (pdu[j+1]==1)) { + sched_ctl->round[i][harq_pid]++; + sched_ctl->tbcnt[i][harq_pid]=1; + } + else if ((sched_ctl->tbcnt[i][harq_pid]==2) && (pdu[j] == 2) && (pdu[j+1]==2)) { + sched_ctl->round[i][harq_pid]++; + } + else AssertFatal(1==0,"Illegal combination for CC %d harq_pid %d (%d,%d,%d) UE %d/%x\n", + i,harq_pid,sched_ctl->tbcnt[i][harq_pid],pdu[j],pdu[j+1],UE_id,rnti); + j+=2; + } + else if (spatial_bundling == 1) { + if (pdu[j] == 1) { + sched_ctl->round[i][harq_pid]=8; + sched_ctl->tbcnt[i][harq_pid]=0; + } + else if (pdu[j] == 2) { + sched_ctl->round[i][harq_pid]++; + } + else AssertFatal(1==0,"Illegal hack_nak value %d for CC %d harq_pid %d UE %d/%x\n", + pdu[j],i,harq_pid,UE_id,rnti); + j++; + } + else AssertFatal(1==0,"Illegal value for spatial_bundling %d\n",spatial_bundling); + } + } + break; + case 3: // Format 4 + AssertFatal(1==0,"Should not receive harq indication with Format 4\n"); + break; + case 4: // Format 5 + AssertFatal(1==0,"Should not receive harq indication with Format 5\n"); + break; + } + } +} +void extract_pucch_csi(module_id_t mod_idP,int CC_idP,int UE_id, frame_t frameP,sub_frame_t subframeP,uint8_t *pdu, uint8_t length) { + + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + COMMON_channels_t *cc=&RC.mac[mod_idP]->common_channels[CC_idP]; + struct CQI_ReportPeriodic *cqi_ReportPeriodic; + int no_pmi; + uint8_t Ltab[6] = {0,2,4,4,4,4}; + uint8_t Jtab[6] = {0,2,2,3,4,4}; + int feedback_cnt; + + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",UE_id); + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig != NULL,"cqi_ReportConfig is null for UE %d\n",UE_id); + AssertFatal((cqi_ReportPeriodic = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic)!=NULL, + "cqi_ReportPeriodic is null for UE %d\n",UE_id); + + // determine feedback mode + AssertFatal(cqi_ReportPeriodic->present != CQI_ReportPeriodic_PR_NOTHING, + "cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_NOTHING!\n"); + AssertFatal(cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present != CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING, + "cqi_ReportPeriodic->cqi_FormatIndicatorPeriodic.choice.setup.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING!\n"); + + uint16_t Npd,N_OFFSET_CQI; + int H,K,bandwidth_part,L,Lmask; + int ri = sched_ctl->periodic_ri_received[CC_idP]; + + get_csi_params(cc,cqi_ReportPeriodic,&Npd,&N_OFFSET_CQI,&H); + K =(H-1)/Jtab[cc->mib->message.dl_Bandwidth]; + L = Ltab[cc->mib->message.dl_Bandwidth]; + Lmask =L-1; + feedback_cnt = (((frameP*10)+subframeP)/Npd)%H; + + if (feedback_cnt>0) bandwidth_part = (feedback_cnt-1)%K; + else bandwidth_part = 0; + + switch(get_tmode(mod_idP,CC_idP,UE_id)) { + case 1: + case 2: + case 3: + case 7: + no_pmi=1; + break; + case 4: + case 5: + case 6: + no_pmi=0; + break; + default: + // note: need to check TM8-10 without PMI/RI or with 1 antenna port (see Section 5.2.3.3.1 from 36.213) + no_pmi=0; + } + + if ((cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_widebandCQI) || + (feedback_cnt==0)){ + // Note: This implements only Tables: 5.3.3.1-1,5.3.3.1-1A and 5.3.3.1-2 from 36.213 (1,2,4 antenna ports Wideband CQI/PMI) + + if (no_pmi == 1) { // get spatial_diffcqi if needed + sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0]&0xF; + sched_ctl->periodic_wideband_spatial_diffcqi[CC_idP] = (pdu[0]>>4)&7; + } + else if ((cc->p_eNB==2) && (ri==1)) { + // p=2 Rank 1 wideband CQI/PMI 6 bits + sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0]&0xF; + sched_ctl->periodic_wideband_pmi[CC_idP] = (pdu[0]>>4)&3; + } + else if ((cc->p_eNB==2) && (ri>1)) { + // p=2 Rank 2 wideband CQI/PMI 8 bits + sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0]&0xF; + sched_ctl->periodic_wideband_spatial_diffcqi[CC_idP] = (pdu[0]>>4)&7; + sched_ctl->periodic_wideband_pmi[CC_idP] = (pdu[0]>>7)&1; + } + else if ((cc->p_eNB==4) && (ri==1)) { + // p=4 Rank 1 wideband CQI/PMI 8 bits + sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0]&0xF; + sched_ctl->periodic_wideband_pmi[CC_idP] = (pdu[0]>>4)&0x0F; + + } + else if ((cc->p_eNB==4) && (ri>1)) { + // p=4 Rank 2 wideband CQI/PMI 11 bits + sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0]&0xF; + sched_ctl->periodic_wideband_spatial_diffcqi[CC_idP] = (pdu[0]>>4)&7; + sched_ctl->periodic_wideband_pmi[CC_idP] = (pdu[0]>>7)&0xF; + } + else AssertFatal(1==0,"illegal combination p %d, ri %d, no_pmi %d\n",cc->p_eNB,ri,no_pmi); + } + else if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) { + // This is Table 5.2.3.3.2-2 for 36.213 + if (ri==1) { + //4+Ltab[cc->mib->message.dl_Bandwidth] bits + sched_ctl->periodic_subband_cqi[CC_idP][(bandwidth_part*L)+((pdu[0]>>4)&Lmask)] = pdu[0]&0xF; + } + else if (ri>1) { + //7+Ltab[cc->mib->message.dl_Bandwidth] bits; + sched_ctl->periodic_subband_spatial_diffcqi[CC_idP][(bandwidth_part*L)+((pdu[0]>>7)&Lmask)] = (pdu[0]>>4)&7; + sched_ctl->periodic_subband_cqi[CC_idP][(bandwidth_part*L)+((pdu[0]>>7)&Lmask)] = pdu[0]&0xF; + } + } +} + +void extract_pusch_csi(module_id_t mod_idP,int CC_idP,int UE_id, frame_t frameP,sub_frame_t subframeP,uint8_t *pdu, uint8_t length) { + + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; + UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + int Ntab[6] = {0,4,7,9,10,13}; + int Ntab_uesel[6] = {0,8,13,17,19,25}; + int Ltab_uesel[6] = {0,6,9,13,15,18}; + int Mtab_uesel[6] = {0,1,3,5,6,6}; + int v[6]; + int i; + uint64_t p = *(uint64_t*)pdu; + CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic; + + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",UE_id); + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig != NULL,"cqi_ReportConfig is null for UE %d\n",UE_id); + AssertFatal((cqi_ReportModeAperiodic = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic)!=NULL, + "cqi_ReportModeAperiodic is null for UE %d\n",UE_id); + + int N = Ntab[cc->p_eNB]; + int tmode = get_tmode(mod_idP,CC_idP,UE_id); + int ri = sched_ctl->aperiodic_ri_received[CC_idP]; + int r,diffcqi0=0,diffcqi1=0,pmi_uesel=0; + int bw = cc->mib->message.dl_Bandwidth; + int m; + + switch(*cqi_ReportModeAperiodic) { + + case CQI_ReportModeAperiodic_rm12: + // wideband multiple PMI (TM4/6), Table 5.2.2.6.1-1 (for TM4/6) + AssertFatal(tmode==4 || tmode==6 || tmode==8|| tmode==9 || tmode==10,"Illegal transmission mode %d for CQI_ReportModeAperiodic_rm12\n",tmode); + if (tmode <= 6) { //Table 5.2.2.6.1-1 36.213 + if ((ri==1) && (cc->p_eNB==2)) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t)(p&0x0F); p>>=4; + for (i=0;i<N;i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t)(p&0x03); + p>>=2; + } + } + if ((ri==2) && (cc->p_eNB==2)) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t)(p&0x0F); p>>=4; + sched_ctl->aperiodic_wideband_cqi1[CC_idP] = (uint8_t)(p&0x0F); p>>=4; + for (i=0;i<N;i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t)(p&0x01); + p>>=1; + } + } + if ((ri==1) && (cc->p_eNB==4)) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t)(p&0x0F); p>>=4; + for (i=0;i<N;i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t)(p&0x03); + p>>=4; + } + } + if ((ri==2) && (cc->p_eNB==4)) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t)(p&0x0F); p>>=4; + sched_ctl->aperiodic_wideband_cqi1[CC_idP] = (uint8_t)(p&0x0F); p>>=4; + for (i=0;i<N;i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t)(p&0x01); + p>>=4; + } + } + } // if (tmode <= 6) { //Table 5.2.2.6.1-1 36.213 + else { + AssertFatal(1==0,"support for TM 8-10 to be done\n"); + } + + break; + case CQI_ReportModeAperiodic_rm20: + // UE-selected subband CQI no PMI (TM1/2/3/7) , Table 5.2.2.6.3-1 from 36.213 + AssertFatal(tmode==1 || tmode==2 || tmode==3 || tmode==7,"Illegal transmission mode %d for CQI_ReportModeAperiodic_rm20\n",tmode); + + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t)(p&0x0F); p>>=4; + diffcqi0 = (uint8_t)(p&0x03); p>>=2; + r = (uint8_t)(p&((1>>Ltab_uesel[bw])-1)); + reverse_index(Ntab_uesel[bw],Mtab_uesel[bw],r,v); + for (m=0;m<Mtab_uesel[bw];m++) sched_ctl->aperiodic_subband_diffcqi0[CC_idP][v[m]] = diffcqi0; + break; + case CQI_ReportModeAperiodic_rm22: + // UE-selected subband CQI multiple PMI (TM4/6) Table 5.2.2.6.3-2 from 36.213 + + AssertFatal(tmode==4 || tmode==6 || tmode==8|| tmode==9 || tmode==10,"Illegal transmission mode %d for CQI_ReportModeAperiodic_rm22\n",tmode); + + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t)(p&0x0F); p>>=4; + diffcqi0 = (uint8_t)(p&0x03); p>>=2; + + if (ri>1) { + sched_ctl->aperiodic_wideband_cqi1[CC_idP] = (uint8_t)(p&0x0F); p>>=4; + diffcqi1 = (uint8_t)(p&0x03); p>>=2; + } + r = (uint8_t)(p&((1>>Ltab_uesel[bw])-1)); p>>=Ltab_uesel[bw]; + reverse_index(Ntab_uesel[bw],Mtab_uesel[bw],r,v); + if ((ri==1)&&(cc->p_eNB==2)) { + pmi_uesel = p&0x3; p>>=2; + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p&0x3; + } + else if ((ri==2)&&(cc->p_eNB==2)) { + pmi_uesel = p&0x1; p>>=1; + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p&0x1; + } + else if (cc->p_eNB==4) { + pmi_uesel = p&0x0F; p>>=4; + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p&0x0F; + } + for (m=0;m<Mtab_uesel[bw];m++) { + sched_ctl->aperiodic_subband_diffcqi0[CC_idP][v[m]] = diffcqi0; + if (ri>1) sched_ctl->aperiodic_subband_diffcqi1[CC_idP][v[m]] = diffcqi1; + sched_ctl->aperiodic_subband_pmi[CC_idP][v[m]] = pmi_uesel; + } + break; + case CQI_ReportModeAperiodic_rm30: + //subband CQI no PMI (TM1/2/3/7) + AssertFatal(tmode==1 || tmode==2 || tmode==3 || tmode==7,"Illegal transmission mode %d for CQI_ReportModeAperiodic_rm30\n",tmode); + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t)(p&0x0F); p>>=4; + for (i=0;i<N;i++) { + sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = (uint8_t)(p&0x03); + p>>=2; + } + break; + case CQI_ReportModeAperiodic_rm31: + //subband CQI single PMI (TM4/5/6) + AssertFatal(tmode==4 || tmode==5 || tmode==6 || tmode==8|| tmode==9|| tmode==10,"Illegal transmission mode %d for CQI_ReportModeAperiodic_rm31\n",tmode); + + if ((ri==1) && (cc->p_eNB==2)) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t)(p&0x0F); p>>=4; + for (i=0;i<N;i++) { + sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = (uint8_t)(p&0x03); + p>>=2; + } + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p&0x03; + } + if ((ri==2) && (cc->p_eNB==2)) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t)(p&0x0F); p>>=4; + for (i=0;i<N;i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t)(p&0x01); + p>>=1; + } + sched_ctl->aperiodic_wideband_cqi1[CC_idP] = (uint8_t)(p&0x0F); p>>=4; + for (i=0;i<N;i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t)(p&0x01); + p>>=1; + } + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p&0x01; + } + if ((ri==1) && (cc->p_eNB==4)) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t)(p&0x0F); p>>=4; + for (i=0;i<N;i++) { + sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = (uint8_t)(p&0x03); + p>>=2; + } + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p&0x0F; + } + if ((ri>1) && (cc->p_eNB==4)) { // Note : 64 bits for 20 MHz + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t)(p&0x0F); p>>=4; + for (i=0;i<N;i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t)(p&0x01); + p>>=1; + } + sched_ctl->aperiodic_wideband_cqi1[CC_idP] = (uint8_t)(p&0x0F); p>>=4; + for (i=0;i<N;i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t)(p&0x01); + p>>=2; + } + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p&0x0F; + } + + break; + case CQI_ReportModeAperiodic_rm32_v1250: + AssertFatal(tmode==4 || tmode==5 || tmode==6 || tmode==8|| tmode==9|| tmode==10,"Illegal transmission mode %d for CQI_ReportModeAperiodic_rm32\n",tmode); + AssertFatal(1==0,"CQI_ReportModeAperiodic_rm32 to be done\n"); + break; + case CQI_ReportModeAperiodic_rm10_v1310: + AssertFatal(tmode==1 || tmode==2 || tmode==3 || tmode==7,"Illegal transmission mode %d for CQI_ReportModeAperiodic_rm10\n",tmode); + AssertFatal(1==0,"CQI_ReportModeAperiodic_rm10 to be done\n"); + break; + case CQI_ReportModeAperiodic_rm11_v1310: + AssertFatal(tmode==4 || tmode==5 || tmode==6 || tmode==8|| tmode==9|| tmode==10,"Illegal transmission mode %d for CQI_ReportModeAperiodic_rm11\n",tmode); + AssertFatal(1==0,"CQI_ReportModeAperiodic_rm11 to be done\n"); + break; + } + + +} + +void cqi_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, sub_frame_t subframeP, rnti_t rntiP, + nfapi_cqi_indication_rel9_t *rel9,uint8_t *pdu, + nfapi_ul_cqi_information_t *ul_cqi_information) { + + int UE_id = find_UE_id(mod_idP, rntiP); + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + + if (UE_id >= 0) { + + if (ul_cqi_information->channel == 0) { // PUCCH + + // extract pucch csi information before changing RI information + extract_pucch_csi(mod_idP,CC_idP,UE_id,frameP,subframeP,pdu,rel9->length); + + memcpy((void*)sched_ctl->periodic_ri_received, + (void*)rel9->ri, + rel9->number_of_cc_reported); + + // SNR for PUCCH2 + sched_ctl->pucch2_snr[CC_idP] = ul_cqi_information->ul_cqi; + } + else { //PUSCH + memcpy((void*)sched_ctl->aperiodic_ri_received, + (void*)rel9->ri, + rel9->number_of_cc_reported); + + extract_pusch_csi(mod_idP,CC_idP,UE_id,frameP,subframeP,pdu,rel9->length); + + } + + // timing advance + sched_ctl->timing_advance = rel9->timing_advance; + sched_ctl->timing_advance_r9 = rel9->timing_advance_r9; + } +} + +void SR_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, sub_frame_t subframeP, rnti_t rntiP, uint8_t ul_cqi) { int UE_id = find_UE_id(mod_idP, rntiP); @@ -2003,7 +3493,7 @@ void SR_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, rnti_t rntiP if (UE_id != -1) { if (mac_eNB_get_rrc_status(mod_idP,UE_RNTI(mod_idP,UE_id)) < RRC_CONNECTED) - LOG_D(MAC,"[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d on CC_id %d\n",mod_idP,rntiP,frameP,subframeP, UE_id,cc_idP); + LOG_I(MAC,"[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d on CC_id %d\n",mod_idP,rntiP,frameP,subframeP, UE_id,cc_idP); UE_list->UE_template[cc_idP][UE_id].ul_SR = 1; UE_list->UE_template[cc_idP][UE_id].ul_active = TRUE; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION,1); @@ -2033,3 +3523,21 @@ void UL_failure_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, rnti LOG_W(MAC,"[eNB %d][SR %x] Frame %d subframeP %d Signaling UL Failure for UE %d (unknown UEid) on CC_id %d\n",mod_idP,rntiP,frameP,subframeP, UE_id,cc_idP); } } + +void harq_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, sub_frame_t subframeP, nfapi_harq_indication_pdu_t *harq_pdu) { + + + rnti_t rnti = harq_pdu->rx_ue_information.rnti; + uint8_t ul_cqi = harq_pdu->ul_cqi_information.ul_cqi; + uint8_t channel = harq_pdu->ul_cqi_information.channel; + int UE_id = find_UE_id(mod_idP, rnti); + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; + // extract HARQ Information + LOG_I(MAC,"Frame %d, subframe %d: Received harq indication (%d) from UE %d/%x\n",frameP,subframeP,channel,UE_id,rnti); + if (cc->tdd_Config) extract_harq(mod_idP,CC_idP,UE_id,frameP,subframeP,(void*)&harq_pdu->harq_indication_tdd_rel13,channel); + else extract_harq(mod_idP,CC_idP,UE_id,frameP,subframeP,(void*)&harq_pdu->harq_indication_fdd_rel13,channel); + if (channel == 0) sched_ctl->pucch1_snr[CC_idP] = ul_cqi; + +} diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index bd0ef80011..0c49914bf5 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -133,7 +133,7 @@ void rx_sdu(const module_id_t enb_mod_idP, "maxHARQ %d should be greater than 1\n", (int)eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx); - if (sduP==NULL) { // we've got an error + if (sduP==NULL) { // we've got an error on Msg3 LOG_I(MAC,"[eNB %d] CC_id %d, RA %d ULSCH in error in round %d/%d\n",enb_mod_idP,CC_idP,RA_id, RA_template[RA_id].msg3_round, (int)eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx); @@ -145,6 +145,7 @@ void rx_sdu(const module_id_t enb_mod_idP, // prepare handling of retransmission RA_template[RA_id].Msg3_frame += ((RA_template[RA_id].Msg3_subframe>1) ? 1 : 0); RA_template[RA_id].Msg3_subframe = (RA_template[RA_id].Msg3_subframe+8)%10; + add_msg3(enb_mod_idP,CC_idP, &RA_template[RA_id],frameP,subframeP); return; } } @@ -333,7 +334,7 @@ void rx_sdu(const module_id_t enb_mod_idP, } for (i=0; i<num_sdu; i++) { - LOG_D(MAC,"SDU Number %d MAC Subheader SDU_LCID %d, length %d\n",i,rx_lcids[i],rx_lengths[i]); + LOG_I(MAC,"SDU Number %d MAC Subheader SDU_LCID %d, length %d\n",i,rx_lcids[i],rx_lengths[i]); T(T_ENB_MAC_UE_UL_SDU, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP), T_INT(rx_lcids[i]), T_INT(rx_lengths[i])); @@ -343,8 +344,8 @@ void rx_sdu(const module_id_t enb_mod_idP, switch (rx_lcids[i]) { case CCCH : if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) { - LOG_E(MAC, "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d), dropping packet\n", - enb_mod_idP, CC_idP, frameP, rx_lengths[i], CCCH_PAYLOAD_SIZE_MAX); + LOG_E(MAC, "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d, sdu_len %d), dropping packet\n", + enb_mod_idP, CC_idP, frameP, rx_lengths[i], CCCH_PAYLOAD_SIZE_MAX,sdu_lenP); break; } LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH: %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n", @@ -407,7 +408,17 @@ void rx_sdu(const module_id_t enb_mod_idP, // prepare transmission of Msg4 RA_template->generate_Msg4 = 1; RA_template->wait_ack_Msg4 = 0; - + // Program ACK for PHICH + LOG_I(MAC,"Programming PHICH ACK for Msg3 rnti %x\n",RA_template->rnti); + nfapi_hi_dci0_request_body_t *hi_dci0_req = &eNB->HI_DCI0_req[CC_idP].hi_dci0_request_body; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi]; + memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t)); + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; + hi_dci0_pdu->pdu_size = 2+sizeof(nfapi_hi_dci0_hi_pdu); + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = RA_template->msg3_first_rb; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 1; + hi_dci0_req->number_of_hi++; // Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, // Check if this is ok for BL/CE, or if the rule is different RA_template->Msg4_frame = frameP + ((subframeP>5) ? 1 : 0); RA_template->Msg4_subframe = (subframeP+4)%10; @@ -786,7 +797,7 @@ void schedule_ulsch(module_id_t module_idP, void schedule_ulsch_rnti(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, - unsigned char sched_subframe, + unsigned char sched_subframeP, uint16_t *first_rb) { @@ -812,8 +823,22 @@ void schedule_ulsch_rnti(module_id_t module_idP, UE_list_t *UE_list=&eNB->UE_list; UE_TEMPLATE *UE_template; UE_sched_ctrl *UE_sched_ctrl; - 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; + int tmode; + int sched_frame=frameP; + + if (sched_subframeP<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; + + + + nfapi_ul_config_request_body_t *ul_req_tmp = &eNB->UL_req_tmp[CC_id][sched_subframeP].ul_config_request_body; + + ul_config_pdu = &ul_req_tmp->ul_config_pdu_list[0]; + LOG_D(MAC,"entering ulsch preprocesor\n"); ulsch_scheduler_pre_processor(module_idP, @@ -823,9 +848,9 @@ void schedule_ulsch_rnti(module_id_t module_idP, LOG_D(MAC,"exiting ulsch preprocesor\n"); - eNB->HI_DCI0_req[CC_id].sfn_sf = (frameP<<3)+subframeP; - hi_dci0_req->number_of_dci = 0; - hi_dci0_req->number_of_hi = 0; + eNB->HI_DCI0_req[CC_id].sfn_sf = (frameP<<4)+subframeP; + + // loop over all active UEs for (UE_id=UE_list->head_ul; UE_id>=0; UE_id=UE_list->next_ul[UE_id]) { @@ -904,8 +929,8 @@ abort(); 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],frameP,subframeP); - round = UE_sched_ctrl->round_UL[harq_pid][CC_id]; + harq_pid = subframe2harqpid(&cc[CC_id],sched_frame,sched_subframeP); + round = UE_sched_ctrl->round_UL[harq_pid][CC_id]; /* if (get_UL_harq_info(module_idP,CC_id,frameP,subframeP,&harq_pid,&round)<0) { LOG_W(MAC,"[eNB %d] Scheduler Frame %d, subframeP %d: candidate harq_pid from PHY for UE %d CC %d RNTI %x\n", @@ -1049,13 +1074,85 @@ abort(); 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]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = UE_template->DAI_ul[sched_subframeP]; if (!CCE_allocation_infeasible(module_idP,CC_id,2,subframeP, aggregation, - rnti)) + rnti)) { + eNB->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_dci++; - + + LOG_I(MAC,"Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", + frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP); + + // Add UL_config PDUs + ul_config_pdu = &ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus]; + + memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t)); + if (cqi_req==0) + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; + else + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_ul_config_ulsch_pdu)); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = eNB->ul_handle++; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = rnti; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = first_rb[CC_id]; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = rb_table[rb_table_index]; + if (mcs<11) ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2; + else if (mcs<21) ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 4; + else ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 6; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = cshift; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = ndi; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = harq_pid; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL(mcs, + rb_table[rb_table_index]); +#ifdef Rel14 + // Re13 fields + if (UE_template->rach_resource_type>0) { // This is a BL/CE UE allocation + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type = UE_template->rach_resource_type>2 ? 2 : 1; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions = 1; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number = 1; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = (frameP*10)+subframeP; + } +#endif + ul_req_tmp->number_of_pdus++; + + if (cqi_req == 1) { + // Add CQI portion + tmode = get_tmode(module_idP,CC_id,UE_id); + + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_ul_config_ulsch_cqi_ri_pdu)); + ((nfapi_ul_config_ulsch_cqi_ri_pdu*)ul_config_pdu)->cqi_ri_information.cqi_ri_information_rel9.report_type = 1; + ((nfapi_ul_config_ulsch_cqi_ri_pdu*)ul_config_pdu)->cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.number_of_cc = 1; + if (cc->p_eNB<=2 && (tmode==3||tmode==4||tmode==8||tmode==9||tmode==10)) + ((nfapi_ul_config_ulsch_cqi_ri_pdu*)ul_config_pdu)->cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 1; + else if (cc->p_eNB<=2) + ((nfapi_ul_config_ulsch_cqi_ri_pdu*)ul_config_pdu)->cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 0; + else if (cc->p_eNB==4) + ((nfapi_ul_config_ulsch_cqi_ri_pdu*)ul_config_pdu)->cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 2; + + AssertFatal(UE_template->physicalConfigDedicated->cqi_ReportConfig!=NULL,"physicalConfigDedicated->cqi_ReportConfig is null!\n"); + AssertFatal(UE_template->physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic!=NULL,"physicalConfigDedicated->cqi_ReportModeAperiodic is null!\n"); + AssertFatal(UE_template->physicalConfigDedicated->pusch_ConfigDedicated!=NULL,"physicalConfigDedicated->puschConfigDedicated is null!\n"); + for (int ri=0;ri<(1<<((nfapi_ul_config_ulsch_cqi_ri_pdu*)ul_config_pdu)->cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size);ri++) + ((nfapi_ul_config_ulsch_cqi_ri_pdu*)ul_config_pdu)->cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[ri] = + get_dl_cqi_pmi_size_pusch(&UE_list->UE_sched_ctrl[UE_id], + cc, + tmode, + 1+ri, + UE_template->physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic); + + ((nfapi_ul_config_ulsch_cqi_ri_pdu*)ul_config_pdu)->cqi_ri_information.cqi_ri_information_rel9.delta_offset_cqi = UE_template->physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index; + ((nfapi_ul_config_ulsch_cqi_ri_pdu*)ul_config_pdu)->cqi_ri_information.cqi_ri_information_rel9.delta_offset_ri = UE_template->physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index; + } + } add_ue_ulsch_info(module_idP, CC_id, UE_id, @@ -1080,7 +1177,6 @@ abort(); hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = UE_template->cshift[harq_pid]; hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 0; hi_dci0_req->number_of_hi++; - LOG_D(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) UE %d (mcs %d, first rb %d, nb_rb %d, TBS %d, harq_pid %d,round %d)\n", module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,mcs, UE_template->first_rb_ul[harq_pid], UE_template->nb_rb_ul[harq_pid], diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index 6e5fa91f14..ae4b52222d 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -175,11 +175,20 @@ int mac_top_init_eNB() for (j=0;j<MAX_NUM_CCs;j++) { RC.mac[i]->DL_req[j].dl_config_request_body.dl_config_pdu_list = RC.mac[i]->dl_config_pdu_list[j]; RC.mac[i]->UL_req[j].ul_config_request_body.ul_config_pdu_list = RC.mac[i]->ul_config_pdu_list[j]; + for (int k=0;k<10;k++) RC.mac[i]->UL_req_tmp[j][k].ul_config_request_body.ul_config_pdu_list = RC.mac[i]->ul_config_pdu_list_tmp[j][k]; RC.mac[i]->HI_DCI0_req[j].hi_dci0_request_body.hi_dci0_pdu_list = RC.mac[i]->hi_dci0_pdu_list[j]; RC.mac[i]->TX_req[j].tx_request_body.tx_pdu_list = RC.mac[i]->tx_request_pdu[j]; RC.mac[i]->ul_handle = 0; } } + + AssertFatal(rlc_module_init()==0,"Could not initialize RLC layer\n"); + + // These should be out of here later + pdcp_layer_init (); + + rrc_init_global_param(); + } else { RC.mac = NULL; } diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 7c77bf8729..4bcda249e9 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -263,13 +263,19 @@ int maxround(module_id_t Mod_id,uint16_t rnti,int frame,sub_frame_t subframe,uin { uint8_t round,round_max=0,UE_id; - int CC_id; + int CC_id,harq_pid; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + COMMON_channels_t *cc; for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + cc = &RC.mac[Mod_id]->common_channels[CC_id]; + UE_id = find_UE_id(Mod_id,rnti); - round = UE_list->UE_sched_ctrl[UE_id].round[CC_id]; + if (cc->tdd_Config) harq_pid = ((frame*10)+subframe)%10; + else harq_pid = ((frame*10)+subframe)&7; + + round = UE_list->UE_sched_ctrl[UE_id].round[CC_id][harq_pid]; if (round > round_max) { round_max = round; } @@ -507,9 +513,10 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id, int transmission_mode = 0; UE_sched_ctrl *ue_sched_ctl; // int rrc_status = RRC_IDLE; + COMMON_channels_t *cc; #ifdef TM5 - int harq_pid1=0,harq_pid2=0; + int harq_pid1=0; int round1=0,round2=0; int UE_id2; uint16_t i1,i2,i3; @@ -581,12 +588,10 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id, for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) { CC_id = UE_list->ordered_CCids[ii][UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - harq_pid = ue_sched_ctl->harq_pid[CC_id]; - round = ue_sched_ctl->round[CC_id]; - - // if there is no available harq_process, skip the UE - if (UE_list->UE_sched_ctrl[UE_id].harq_pid[CC_id]<0) - continue; + cc=&RC.mac[Mod_id]->common_channels[ii]; + if (cc->tdd_Config) harq_pid = ((frameP*10)+subframeP)%10; + else harq_pid = ((frameP*10)+subframeP)&7; + round = ue_sched_ctl->round[CC_id][harq_pid]; average_rbs_per_user[CC_id]=0; @@ -681,8 +686,7 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id, for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) { CC_id = UE_list->ordered_CCids[ii][UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - harq_pid = ue_sched_ctl->harq_pid[CC_id]; - round = ue_sched_ctl->round[CC_id]; + round = ue_sched_ctl->round[CC_id][harq_pid]; rnti = UE_RNTI(Mod_id,UE_id); @@ -731,7 +735,6 @@ void dlsch_scheduler_pre_processor (module_id_t Mod_id, UE_id2 = ii; rnti2 = UE_RNTI(Mod_id,UE_id2); ue_sched_ctl2 = &UE_list->UE_sched_ctrl[UE_id2]; - harq_pid2 = ue_sched_ctl2->harq_pid[CC_id]; round2 = ue_sched_ctl2->round[CC_id]; if(rnti2 == NOT_A_RNTI) continue; @@ -887,7 +890,7 @@ void dlsch_scheduler_pre_processor_reset (int module_idP, #endif - LOG_I(MAC,"Running preprocessor for UE %d (%x)\n",UE_id,rnti); + LOG_D(MAC,"Running preprocessor for UE %d (%x)\n",UE_id,rnti); // initialize harq_pid and round /* @@ -1078,11 +1081,11 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, UE_TEMPLATE *UE_template = 0; int N_RB_DL; int N_RB_UL; - //LOG_I(MAC,"assign max mcs min rb\n"); + LOG_D(MAC,"In ulsch_preprocessor: assign max mcs min rb\n"); // maximize MCS and then allocate required RB according to the buffer occupancy with the limit of max available UL RB assign_max_mcs_min_rb(module_idP,frameP, subframeP, first_rb); - //LOG_I(MAC,"sort ue \n"); + LOG_D(MAC,"In ulsch_preprocessor: sort ue \n"); // sort ues sort_ue_ul (module_idP,frameP, subframeP); @@ -1101,7 +1104,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, } } - //LOG_I(MAC,"step2 \n"); + LOG_D(MAC,"In ulsch_preprocessor: step2 \n"); // step 2: calculate the average rb per UE total_ue_count =0; max_num_ue_to_be_scheduled=0; @@ -1119,9 +1122,11 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, UE_id = i; + LOG_D(MAC,"In ulsch_preprocessor: handling UE %d/%x\n",UE_id,rnti); for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) { // This is the actual CC_id in the list CC_id = UE_list->ordered_ULCCids[n][UE_id]; + LOG_D(MAC,"In ulsch_preprocessor: handling UE %d/%x CCid %d\n",UE_id,rnti,CC_id); UE_template = &UE_list->UE_template[CC_id][UE_id]; average_rbs_per_user[CC_id]=0; @@ -1174,6 +1179,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, CC_id = UE_list->ordered_ULCCids[n][UE_id]; harq_pid = subframe2harqpid(&RC.mac[module_idP]->common_channels[CC_id],frameP,subframeP); + // mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL); if(UE_list->UE_sched_ctrl[UE_id].round_UL[CC_id]>0) { @@ -1183,7 +1189,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, } total_allocated_rbs[CC_id]+= nb_allocated_rbs[CC_id][UE_id]; - + LOG_D(MAC,"In ulsch_preprocessor: assigning %d RBs for UE %d/%x CCid %d, harq_pid %d\n",nb_allocated_rbs[CC_id][UE_id],UE_id,rnti,CC_id,harq_pid); } } diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/proto.h index 85eaca5b21..ac969cc02c 100644 --- a/openair2/LAYER2/MAC/proto.h +++ b/openair2/LAYER2/MAC/proto.h @@ -29,6 +29,8 @@ #ifndef __LAYER2_MAC_PROTO_H__ #define __LAYER2_MAC_PROTO_H__ +#include "LAYER2/MAC/defs.h" + /** \addtogroup _mac * @{ */ @@ -287,11 +289,14 @@ void rx_sdu(const module_id_t enb_mod_idP, /* \brief Function to indicate a scheduled schduling request (SR) was received by eNB. -@param Mod_id Instance ID of eNB +@param Mod_idP Instance ID of eNB +@param CC_idP CC_id of received SR +@param frameP of received SR +@param subframeP Index of subframe where SR was received @param rnti RNTI of UE transmitting the SR -@param subframe Index of subframe where SR was received +@param ul_cqi SNR measurement of PUCCH (SNR quantized to 8 bits, -64 ... 63.5 dB in .5dB steps) */ -void SR_indication(module_id_t module_idP,int CC_id,frame_t frameP,rnti_t rnti, sub_frame_t subframe); +void SR_indication(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subframe,rnti_t rnti,uint8_t ul_cqi); /* \brief Function to indicate a UL failure was detected by eNB PHY. @param Mod_id Instance ID of eNB @@ -314,10 +319,7 @@ uint8_t *get_dlsch_sdu(module_id_t module_idP,int CC_id,frame_t frameP,rnti_t rn MCH_PDU *get_mch_sdu( module_id_t Mod_id, int CC_id, frame_t frame, sub_frame_t subframe); -//added for ALU icic purpose -uint32_t Get_Cell_SBMap(module_id_t module_idP); -void UpdateSBnumber(module_id_t module_idP); -//end ALU's algo + void ue_mac_reset (module_id_t module_idP,uint8_t eNB_index); @@ -326,6 +328,7 @@ void init_ue_sched_info(void); void add_ue_ulsch_info (module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframe,UE_ULSCH_STATUS status); void add_ue_dlsch_info (module_id_t module_idP, int CC_id,int UE_id, sub_frame_t subframe,UE_DLSCH_STATUS status); int find_UE_id (module_id_t module_idP, rnti_t rnti) ; +int find_RA_id (module_id_t mod_idP, int CC_idP, rnti_t rntiP); rnti_t UE_RNTI (module_id_t module_idP, int UE_id); int UE_PCCID (module_id_t module_idP, int UE_id); uint8_t find_active_UEs (module_id_t module_idP); @@ -896,11 +899,92 @@ int to_prb(int dl_Bandwidth); uint8_t get_Msg3harqpid(COMMON_channels_t *cc, frame_t frame, sub_frame_t current_subframe); + +uint32_t pdcchalloc2ulframe(COMMON_channels_t *ccP,uint32_t frame, uint8_t n); + +uint8_t pdcchalloc2ulsubframe(COMMON_channels_t *ccP,uint8_t n); + int is_UL_sf(COMMON_channels_t *ccP,sub_frame_t subframeP); -uint8_t subframe2harqpid(COMMON_channels_t *cc,frame_t frame,sub_frame_t subframe); +uint8_t getQm(uint8_t mcs); +uint8_t subframe2harqpid(COMMON_channels_t *cc,frame_t frame,sub_frame_t subframe); +void get_srs_pos(COMMON_channels_t *cc,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset); + +void get_csi_params(COMMON_channels_t *cc,struct CQI_ReportPeriodic *cqi_PMI_ConfigIndex,uint16_t *Npd,uint16_t *N_OFFSET_CQI,int *H); + +uint8_t get_rel8_dl_cqi_pmi_size(UE_sched_ctrl *sched_ctl,int CC_idP,COMMON_channels_t *cc,uint8_t tmode, struct CQI_ReportPeriodic *cqi_ReportPeriodic); + +uint8_t get_dl_cqi_pmi_size_pusch(UE_sched_ctrl *sched_ctl,COMMON_channels_t *cc,uint8_t tmode, uint8_t ri, CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic); +void extract_pucch_csi(module_id_t mod_idP,int CC_idP,int UE_id, frame_t frameP,sub_frame_t subframeP, uint8_t *pdu, uint8_t length); + +void extract_pusch_csi(module_id_t mod_idP,int CC_idP,int UE_id, frame_t frameP,sub_frame_t subframeP,uint8_t *pdu, uint8_t length); + +uint16_t fill_nfapi_tx_req(nfapi_tx_request_body_t *tx_req_body,uint16_t absSF,uint16_t pdu_length, uint16_t *pdu_index, uint8_t *pdu ); + +void program_dlsch_acknak(module_id_t module_idP, int CC_idP,int UE_idP, frame_t frameP, sub_frame_t subframeP,uint8_t cce_idx); + +void fill_nfapi_dlsch_config(eNB_MAC_INST *eNB, nfapi_dl_config_request_body_t *dl_req, + uint16_t length, + uint16_t pdu_index, + uint16_t rnti, + uint8_t resource_allocation_type, + uint8_t virtual_resource_block_assignment_flag, + uint16_t resource_block_coding, + uint8_t modulation, + uint8_t redundancy_version, + uint8_t transport_blocks, + uint8_t transport_block_to_codeword_swap_flag, + uint8_t transmission_scheme, + uint8_t number_of_layers, + uint8_t number_of_subbands, + // uint8_t codebook_index, + uint8_t ue_category_capacity, + uint8_t pa, + uint8_t delta_power_offset_index, + uint8_t ngap, + uint8_t nprb, + uint8_t transmission_mode, + uint8_t num_bf_prb_per_subband, + uint8_t num_bf_vector + ); + +void fill_nfapi_harq_information(module_id_t module_idP, + int CC_idP, + uint16_t rntiP, + uint16_t absSFP, + nfapi_ul_config_harq_information *harq_information, + uint8_t cce_idxP); + +void fill_nfapi_ulsch_harq_information(module_id_t module_idP, + int CC_idP, + uint16_t rntiP, + nfapi_ul_config_ulsch_harq_information *harq_information); + +uint16_t fill_nfapi_uci_acknak(module_id_t module_idP, + int CC_idP, + uint16_t rntiP, + uint16_t absSFP, + uint8_t cce_idxP); + +void fill_nfapi_dl_dci_1A(nfapi_dl_config_request_pdu_t *dl_config_pdu, + uint8_t aggregation_level, + uint16_t rnti, + uint8_t rnti_type, + uint8_t harq_process, + uint8_t tpc, + uint16_t resource_block_coding, + uint8_t mcs, + uint8_t ndi, + uint8_t rv, + uint8_t vrb_flag); + +nfapi_ul_config_request_pdu_t* has_ul_grant(module_id_t module_idP,int CC_idP,uint16_t subframeP,uint16_t rnti); + +uint8_t get_tmode(module_id_t module_idP,int CC_idP,int UE_idP); + +uint8_t get_ul_req_index(module_id_t module_idP, int CC_idP, sub_frame_t subframeP); #ifdef Rel14 int get_numnarrowbandbits(long dl_Bandwidth); diff --git a/openair2/LAYER2/MAC/rar_tools.c b/openair2/LAYER2/MAC/rar_tools.c index f9ccd4f9ed..a225037e3b 100644 --- a/openair2/LAYER2/MAC/rar_tools.c +++ b/openair2/LAYER2/MAC/rar_tools.c @@ -62,8 +62,8 @@ unsigned short fill_rar( // RAR_PDU *rar = (RAR_PDU *)(dlsch_buffer+1); uint8_t *rar = (uint8_t *)(dlsch_buffer+1); int i,ra_idx = -1; - uint16_t rballoc; - uint8_t mcs,TPC,ULdelay,cqireq; + RA_TEMPLATE *RA_template; + AssertFatal(CC_id < MAX_NUM_CCs, "CC_id %u < MAX_NUM_CCs %u", CC_id, MAX_NUM_CCs); for (i=0; i<NB_RA_PROC_MAX; i++) { @@ -73,7 +73,8 @@ unsigned short fill_rar( break; } } - + RA_template = &RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx]; + //DevAssert( ra_idx != -1 ); if (ra_idx==-1) return(0); @@ -81,52 +82,43 @@ unsigned short fill_rar( // subheader fixed rarh->E = 0; // First and last RAR rarh->T = 1; // 0 for E/T/R/R/BI subheader, 1 for E/T/RAPID subheader - rarh->RAPID = RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx].preamble_index; // Respond to Preamble 0 only for the moment - /* - rar->R = 0; - rar->Timing_Advance_Command = eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset/4; - rar->hopping_flag = 0; - rar->rb_alloc = mac_xface->computeRIV(N_RB_UL,12,2); // 2 RB - rar->mcs = 2; // mcs 2 - rar->TPC = 4; // 2 dB power adjustment - rar->UL_delay = 0; - rar->cqi_req = 1; - rar->t_crnti = eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].rnti; - */ - rar[4] = (uint8_t)(RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx].rnti>>8); - rar[5] = (uint8_t)(RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx].rnti&0xff); - //RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx].timing_offset = 0; - RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx].timing_offset /= 16; //T_A = N_TA/16, where N_TA should be on a 30.72Msps - rar[0] = (uint8_t)(RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx].timing_offset>>(2+4)); // 7 MSBs of timing advance + divide by 4 - rar[1] = (uint8_t)(RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx].timing_offset<<(4-2))&0xf0; // 4 LSBs of timing advance + divide by 4 - rballoc = mac_computeRIV(N_RB_UL,1,1); // first PRB only for UL Grant + rarh->RAPID = RA_template->preamble_index; // Respond to Preamble 0 only for the moment + rar[4] = (uint8_t)(RA_template->rnti>>8); + rar[5] = (uint8_t)(RA_template->rnti&0xff); + //RA_template->timing_offset = 0; + RA_template->timing_offset /= 16; //T_A = N_TA/16, where N_TA should be on a 30.72Msps + rar[0] = (uint8_t)(RA_template->timing_offset>>(2+4)); // 7 MSBs of timing advance + divide by 4 + rar[1] = (uint8_t)(RA_template->timing_offset<<(4-2))&0xf0; // 4 LSBs of timing advance + divide by 4 + RA_template->msg3_first_rb=1; + RA_template->msg3_nb_rb=1; + uint16_t rballoc = mac_computeRIV(N_RB_UL,RA_template->msg3_first_rb,RA_template->msg3_nb_rb); // first PRB only for UL Grant rar[1] |= (rballoc>>7)&7; // Hopping = 0 (bit 3), 3 MSBs of rballoc rar[2] = ((uint8_t)(rballoc&0xff))<<1; // 7 LSBs of rballoc - mcs = 10; - TPC = 3; - ULdelay = 0; - cqireq = 0; - rar[2] |= ((mcs&0x8)>>3); // mcs 10 - rar[3] = (((mcs&0x7)<<5)) | ((TPC&7)<<2) | ((ULdelay&1)<<1) | (cqireq&1); + RA_template->msg3_mcs = 10; + RA_template->msg3_TPC = 3; + RA_template->msg3_ULdelay = 0; + RA_template->msg3_cqireq = 0; + rar[2] |= ((RA_template->msg3_mcs&0x8)>>3); // mcs 10 + rar[3] = (((RA_template->msg3_mcs&0x7)<<5)) | ((RA_template->msg3_TPC&7)<<2) | ((RA_template->msg3_ULdelay&1)<<1) | (RA_template->msg3_cqireq&1); LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Generating RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for ra_idx %d, CRNTI %x,preamble %d/%d,TIMING OFFSET %d\n", module_idP, CC_id, frameP, *(uint8_t*)rarh,rar[0],rar[1],rar[2],rar[3],rar[4],rar[5], ra_idx, - RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx].rnti, + RA_template->rnti, rarh->RAPID,RC.mac[module_idP]->common_channels[CC_id].RA_template[0].preamble_index, - RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx].timing_offset); + RA_template->timing_offset); if (opt_enabled) { trace_pdu(1, dlsch_buffer, input_buffer_length, module_idP, 2, 1, RC.mac[module_idP]->frame, RC.mac[module_idP]->subframe, 0, 0); LOG_D(OPT,"[eNB %d][RAPROC] CC_id %d RAR Frame %d trace pdu for rnti %x and rapid %d size %d\n", - module_idP, CC_id, frameP, RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx].rnti, + module_idP, CC_id, frameP, RA_template->rnti, rarh->RAPID, input_buffer_length); } - return(RC.mac[module_idP]->common_channels[CC_id].RA_template[ra_idx].rnti); + return(RA_template->rnti); } #ifdef Rel14 diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c index 70104e8331..b05e983c30 100644 --- a/openair2/PHY_INTERFACE/IF_Module.c +++ b/openair2/PHY_INTERFACE/IF_Module.c @@ -54,6 +54,52 @@ void handle_rach(UL_IND_t *UL_info) { #endif } +void handle_sr(UL_IND_t *UL_info) { + + int i; + + for (i=0;i<UL_info->sr_ind.number_of_srs;i++) + SR_indication(UL_info->module_id, + UL_info->CC_id, + UL_info->frame, + UL_info->subframe, + UL_info->sr_ind.sr_pdu_list[i].rx_ue_information.rnti, + UL_info->sr_ind.sr_pdu_list[i].ul_cqi_information.ul_cqi); + + UL_info->sr_ind.number_of_srs=0; +} + +void handle_cqi(UL_IND_t *UL_info) { + + int i; + + for (i=0;i<UL_info->cqi_ind.number_of_cqis;i++) + cqi_indication(UL_info->module_id, + UL_info->CC_id, + UL_info->frame, + UL_info->subframe, + UL_info->cqi_ind.cqi_pdu_list[i].rx_ue_information.rnti, + &UL_info->cqi_ind.cqi_pdu_list[i].cqi_indication_rel9, + UL_info->cqi_ind.cqi_raw_pdu_list[i].pdu, + &UL_info->cqi_ind.cqi_pdu_list[i].ul_cqi_information); + + UL_info->cqi_ind.number_of_cqis=0; +} + +void handle_harq(UL_IND_t *UL_info) { + + int i; + + for (i=0;i<UL_info->harq_ind.number_of_harqs;i++) + harq_indication(UL_info->module_id, + UL_info->CC_id, + UL_info->frame, + UL_info->subframe, + &UL_info->harq_ind.harq_pdu_list[i]); + + UL_info->harq_ind.number_of_harqs=0; +} + void handle_ulsch(UL_IND_t *UL_info) { int i; @@ -70,12 +116,12 @@ void handle_ulsch(UL_IND_t *UL_info) { UL_info->rx_ind.rx_pdu_list[i].rx_indication_rel8.length, UL_info->rx_ind.rx_pdu_list[i].rx_indication_rel8.timing_advance, UL_info->rx_ind.rx_pdu_list[i].rx_indication_rel8.ul_cqi); - } + UL_info->rx_ind.number_of_pdus=0; - + for (i=0;i<UL_info->crc_ind.number_of_crcs;i++) { - + if (UL_info->crc_ind.crc_pdu_list[i].crc_indication_rel8.crc_flag == 1) { // CRC error indication LOG_D(MAC,"Frame %d, Subframe %d Calling rx_sdu (CRC error) \n",UL_info->frame,UL_info->subframe); rx_sdu(UL_info->module_id, @@ -88,8 +134,8 @@ void handle_ulsch(UL_IND_t *UL_info) { 0, 0); } - - + + } UL_info->crc_ind.number_of_crcs=0; } @@ -121,9 +167,19 @@ void UL_indication(UL_IND_t *UL_info) ifi->CC_mask |= (1<<CC_id); + // clear DL/UL info for new scheduling round + clear_nfapi_information(RC.mac[module_id],CC_id, + UL_info->frame,UL_info->subframe); + handle_rach(UL_info); + handle_sr(UL_info); + + handle_cqi(UL_info); + + handle_harq(UL_info); + // clear HI prior to hanling ULSCH mac->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_hi = 0; @@ -143,13 +199,19 @@ void UL_indication(UL_IND_t *UL_info) sched_info->subframe = (UL_info->subframe+4)%10; sched_info->DL_req = &mac->DL_req[CC_id]; sched_info->HI_DCI0_req = &mac->HI_DCI0_req[CC_id]; - sched_info->UL_req = &mac->UL_req[CC_id]; + if ((mac->common_channels[CC_id].tdd_Config==NULL) || + (is_UL_sf(&mac->common_channels[CC_id],(sched_info->subframe+4)%10)>0)) + sched_info->UL_req = &mac->UL_req[CC_id]; + else + sched_info->UL_req = NULL; + sched_info->TX_req = &mac->TX_req[CC_id]; AssertFatal(ifi->schedule_response!=NULL, "UL_indication is null (mod %d, cc %d)\n", module_id, CC_id); ifi->schedule_response(sched_info); + LOG_D(PHY,"Schedule_response: frame %d, subframe %d (dl_pdus %d / %p)\n",sched_info->frame,sched_info->subframe,sched_info->DL_req->dl_config_request_body.number_pdu, &sched_info->DL_req->dl_config_request_body.number_pdu); } diff --git a/openair2/PHY_INTERFACE/IF_Module.h b/openair2/PHY_INTERFACE/IF_Module.h index 80844b10c8..e33a8291e2 100644 --- a/openair2/PHY_INTERFACE/IF_Module.h +++ b/openair2/PHY_INTERFACE/IF_Module.h @@ -1,10 +1,4 @@ - -/*This is the interface module between PHY -*Provided the FAPI style interface structures for P7. -* -* -* -*//* +/* * 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. @@ -43,14 +37,6 @@ #include "openair1/PHY/LTE_TRANSPORT/defs.h" #include "nfapi_interface.h" -// uplink subframe P7 - - - /// - -/*UL_IND_t: -* A structure handles all the uplink information. -*/ #define MAX_NUM_DL_PDU 100 #define MAX_NUM_UL_PDU 100 diff --git a/openair2/RRC/LITE/L2_interface.c b/openair2/RRC/LITE/L2_interface.c index a67e86f808..7d3cd34730 100644 --- a/openair2/RRC/LITE/L2_interface.c +++ b/openair2/RRC/LITE/L2_interface.c @@ -84,7 +84,7 @@ mac_rrc_data_req( #ifdef DEBUG_RRC int i; - LOG_T(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id); + LOG_I(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id); #endif eNB_RRC_INST *rrc; @@ -218,7 +218,7 @@ mac_rrc_data_req( // check if data is there for MAC if(Srb_info->Tx_buffer.payload_size>0) { //Fill buffer - LOG_D(RRC,"[eNB %d] CCCH (%p) has %d bytes (dest: %p, src %p)\n",Mod_idP,Srb_info,Srb_info->Tx_buffer.payload_size,buffer_pP,Srb_info->Tx_buffer.Payload); + LOG_I(RRC,"[eNB %d] CCCH (%p) has %d bytes (dest: %p, src %p)\n",Mod_idP,Srb_info,Srb_info->Tx_buffer.payload_size,buffer_pP,Srb_info->Tx_buffer.Payload); #if defined(ENABLE_ITTI) { @@ -504,9 +504,9 @@ mac_rrc_data_ind( } else { // This is an eNB Srb_info = &RC.rrc[module_idP]->carrier[CC_id].Srb0; - LOG_T(RRC,"[eNB %d] Received SDU for CCCH on SRB %d\n",module_idP,Srb_info->Srb_id); - -#if defined(ENABLE_ITTI) + LOG_I(RRC,"[eNB %d] Received SDU for CCCH on SRB %d\n",module_idP,Srb_info->Srb_id); + +#if 0 //defined(ENABLE_ITTI) { MessageDef *message_p; int msg_sdu_size = sizeof(RRC_MAC_CCCH_DATA_IND (message_p).sdu); @@ -526,6 +526,7 @@ mac_rrc_data_ind( RRC_MAC_CCCH_DATA_IND (message_p).CC_id = CC_id; memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); memcpy (RRC_MAC_CCCH_DATA_IND (message_p).sdu, sduP, sdu_size); + LOG_I(RRC,"[eNB %d] Sending message to RRC task\n",module_idP); itti_send_msg_to_task (TASK_RRC_ENB, ctxt.instance, message_p); } #else diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c index 70f27a7cf5..dcbbaf28d2 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c @@ -1371,9 +1371,7 @@ do_RRCConnectionSetup( physicalConfigDedicated2->soundingRS_UL_ConfigDedicated = NULL; physicalConfigDedicated2->antennaInfo = CALLOC(1,sizeof(*physicalConfigDedicated2->antennaInfo)); physicalConfigDedicated2->schedulingRequestConfig = CALLOC(1,sizeof(*physicalConfigDedicated2->schedulingRequestConfig)); -#ifdef CBA - physicalConfigDedicated2->pusch_CBAConfigDedicated_vlola = CALLOC(1,sizeof(*physicalConfigDedicated2->pusch_CBAConfigDedicated_vlola)); -#endif + // PDSCH //assign_enum(&physicalConfigDedicated2->pdsch_ConfigDedicated->p_a, // PDSCH_ConfigDedicated__p_a_dB0); diff --git a/openair2/RRC/LITE/rrc_common.c b/openair2/RRC/LITE/rrc_common.c index d9d7799270..5c9d06f986 100644 --- a/openair2/RRC/LITE/rrc_common.c +++ b/openair2/RRC/LITE/rrc_common.c @@ -151,72 +151,9 @@ rrc_init_global_param( Rlc_info_am_config.rlc.rlc_am_info.t_poll_retransmit = 15; Rlc_info_am_config.rlc.rlc_am_info.t_reordering = 50; Rlc_info_am_config.rlc.rlc_am_info.t_status_prohibit = 10; -#ifndef NO_RRM - - if (L3_xface_init ()) { - return (-1); - } - -#endif - - return 0; -} - -#ifndef NO_RRM -//----------------------------------------------------------------------------- -int -L3_xface_init( - void -) -//----------------------------------------------------------------------------- -{ - - int ret = 0; - -#ifdef USER_MODE - int sock; - LOG_D(RRC, "[L3_XFACE] init de l'interface \n"); - - if (open_socket (&S_rrc, RRC_RRM_SOCK_PATH, RRM_RRC_SOCK_PATH, 0) == -1) { - return (-1); - } - - if (S_rrc.s == -1) { - return (-1); - } - - socket_setnonblocking (S_rrc.s); - msg ("Interface Connected... RRM-RRC\n"); return 0; - -#else - - ret=rtf_create(RRC2RRM_FIFO,32768); - - if (ret < 0) { - msg("[openair][MAC][INIT] Cannot create RRC2RRM fifo %d (ERROR %d)\n",RRC2RRM_FIFO,ret); - return(-1); - } else { - msg("[openair][MAC][INIT] Created RRC2RRM fifo %d\n",RRC2RRM_FIFO); - rtf_reset(RRC2RRM_FIFO); - } - - ret=rtf_create(RRM2RRC_FIFO,32768); - - if (ret < 0) { - msg("[openair][MAC][INIT] Cannot create RRM2RRC fifo %d (ERROR %d)\n",RRM2RRC_FIFO,ret); - return(-1); - } else { - msg("[openair][MAC][INIT] Created RRC2RRM fifo %d\n",RRM2RRC_FIFO); - rtf_reset(RRM2RRC_FIFO); - } - - return(0); - -#endif } -#endif //----------------------------------------------------------------------------- void diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index c733ebdfd4..a8769c2690 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -3453,38 +3453,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ue_context_pP->ue_context.kenb, &kRRCint); #endif -#if ENABLE_RAL - { - MessageDef *message_ral_p = NULL; - rrc_ral_connection_reconfiguration_ind_t connection_reconfiguration_ind; - int i; - - message_ral_p = itti_alloc_new_message(TASK_RRC_ENB, RRC_RAL_CONNECTION_RECONFIGURATION_IND); - memset(&connection_reconfiguration_ind, 0, sizeof(rrc_ral_connection_reconfiguration_ind_t)); - connection_reconfiguration_ind.ue_id = ctxt_pP->rnti; - - if (DRB_configList != NULL) { - connection_reconfiguration_ind.num_drb = DRB_configList->list.count; - - for (i = 0; (i < DRB_configList->list.count) && (i < maxDRB); i++) { - connection_reconfiguration_ind.drb_id[i] = DRB_configList->list.array[i]->drb_Identity; - } - } else { - connection_reconfiguration_ind.num_drb = 0; - } - - if (SRB_configList != NULL) { - connection_reconfiguration_ind.num_srb = SRB_configList->list.count; - } else { - connection_reconfiguration_ind.num_srb = 0; - } - memcpy(&message_ral_p->ittiMsg, (void *)&connection_reconfiguration_ind, - sizeof(rrc_ral_connection_reconfiguration_ind_t)); - LOG_I(RRC, "Sending RRC_RAL_CONNECTION_RECONFIGURATION_IND to RAL\n"); - itti_send_msg_to_task(TASK_RAL_ENB, ctxt_pP->instance, message_ral_p); - } -#endif // Refresh SRBs/DRBs MSC_LOG_TX_MESSAGE( MSC_RRC_ENB, @@ -4423,7 +4392,7 @@ rrc_eNB_decode_dcch( sdu_sizeP, 0, 0); - + /* #if defined(ENABLE_ITTI) # if defined(DISABLE_ITTI_XER_PRINT) { @@ -4452,7 +4421,7 @@ rrc_eNB_decode_dcch( } # endif #endif - + */ { for (i = 0; i < sdu_sizeP; i++) { LOG_T(RRC, "%x.", Rx_sdu[i]); @@ -4971,13 +4940,14 @@ rrc_enb_task( protocol_ctxt_t ctxt; itti_mark_task_ready(TASK_RRC_ENB); - + LOG_I(RRC,"Entering main loop of RRC message task\n"); while (1) { // Wait for a message itti_receive_msg(TASK_RRC_ENB, &msg_p); msg_name_p = ITTI_MSG_NAME(msg_p); instance = ITTI_MSG_INSTANCE(msg_p); + LOG_I(RRC,"Received message %s\n",msg_name_p); switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c index c28b9e839c..ef3124ff24 100644 --- a/targets/COMMON/create_tasks.c +++ b/targets/COMMON/create_tasks.c @@ -98,19 +98,13 @@ int create_tasks(uint32_t enb_nb, uint32_t ue_nb) # endif if (enb_nb > 0) { + LOG_I(RRC,"Creating RRC eNB Task\n"); + if (itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL) < 0) { LOG_E(RRC, "Create task for RRC eNB failed\n"); return -1; } -# if ENABLE_RAL - - if (itti_create_task (TASK_RAL_ENB, eRAL_task, NULL) < 0) { - LOG_E(RAL_ENB, "Create task for RAL eNB failed\n"); - return -1; - } - -# endif } if (ue_nb > 0) { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf index 218adf0050..11abf64431 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf @@ -195,8 +195,8 @@ L1s = ( RUs = ( { local_if_name = "lo"; - remote_address = "127.0.0.1"; - local_address = "127.0.0.2"; + remote_address = "127.0.0.2"; + local_address = "127.0.0.1"; local_portc = 50000; remote_portc = 50000; local_portd = 50001; diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 386026690c..956914a38a 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -940,6 +940,10 @@ void init_eNB(int single_thread_flag,int wait_for_sync) { LOG_I(PHY,"Setting indication lists\n"); eNB->UL_INFO.rx_ind.rx_pdu_list = eNB->rx_pdu_list; eNB->UL_INFO.crc_ind.crc_pdu_list = eNB->crc_pdu_list; + eNB->UL_INFO.sr_ind.sr_pdu_list = eNB->sr_pdu_list; + eNB->UL_INFO.harq_ind.harq_pdu_list = eNB->harq_pdu_list; + eNB->UL_INFO.cqi_ind.cqi_pdu_list = eNB->cqi_pdu_list; + eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list; } } -- GitLab