/* * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * * http://www.openairinterface.org/?page_id=698 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ /*! \file PHY/LTE_TRANSPORT/dci_tools.c * \brief PHY Support routines (eNB/UE) for filling PDSCH/PUSCH/DLSCH/ULSCH data structures based on DCI PDUs generated by eNB MAC scheduler. * \author R. Knopp * \date 2011 * \version 0.1 * \company Eurecom * \email: knopp@eurecom.fr * \note * \warning */ #include "PHY/defs_eNB.h" #include "PHY/phy_extern.h" #include "SCHED/sched_eNB.h" #ifdef DEBUG_DCI_TOOLS #include "PHY/phy_vars.h" #endif #include "assertions.h" #include "nfapi_interface.h" //#define DEBUG_HARQ #include "LAYER2/MAC/mac.h" //#define DEBUG_DCI #include "dci_tools_common_extern.h" #include "transport_proto.h" int16_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type) { uint16_t i; int16_t first_free_index=-1; AssertFatal(eNB!=NULL,"eNB is null\n"); for (i=0; i<NUMBER_OF_UE_MAX; i++) { AssertFatal(eNB->dlsch[i]!=NULL,"eNB->dlsch[%d] is null\n",i); AssertFatal(eNB->dlsch[i]!=NULL,"eNB->dlsch[%d][0] is null\n",i); LOG_D(PHY,"searching for rnti %x : UE index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,eNB->dlsch[i][0]->harq_mask,eNB->dlsch[i][0]->rnti,first_free_index); if ((eNB->dlsch[i][0]->harq_mask >0) && (eNB->dlsch[i][0]->rnti==rnti)) return i; else if ((eNB->dlsch[i][0]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i; } if (type == SEARCH_EXIST) return -1; if (first_free_index != -1) eNB->dlsch[first_free_index][0]->rnti = 0; return first_free_index; } int16_t find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type) { uint16_t i; int16_t first_free_index=-1; AssertFatal(eNB!=NULL,"eNB is null\n"); for (i=0; i<NUMBER_OF_UE_MAX; i++) { AssertFatal(eNB->ulsch[i]!=NULL,"eNB->ulsch[%d] is null\n",i); if ((eNB->ulsch[i]->harq_mask >0) && (eNB->ulsch[i]->rnti==rnti)) return i; else if ((eNB->ulsch[i]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i; } if (type == SEARCH_EXIST) return -1; if (first_free_index != -1) eNB->ulsch[first_free_index]->rnti = 0; return first_free_index; } void fill_pdcch_order(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,nfapi_dl_config_dci_dl_pdu *pdu) { LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; uint8_t *dci_pdu = &dci_alloc->dci_pdu[0]; nfapi_dl_config_dci_dl_pdu_rel8_t *rel8 = &pdu->dci_dl_pdu_rel8; dci_alloc->firstCCE = rel8->cce_idx; dci_alloc->L = rel8->aggregation_level; dci_alloc->rnti = rel8->rnti; dci_alloc->harq_pid = rel8->harq_process; dci_alloc->ra_flag = 0; dci_alloc->format = format1A; LOG_D(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); switch (fp->N_RB_DL) { case 6: if (fp->frame_type == TDD) { dci_alloc->dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->type = 1; ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type = rel8->virtual_resource_block_assignment_flag; ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs = rel8->mcs_1; ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->ndi = rel8->new_data_indicator_1; ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->dai = rel8->downlink_assignment_index; ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->padding = 0; } else { dci_alloc->dci_length = sizeof_DCI1A_1_5MHz_FDD_t; ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->type = 1; ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->vrb_type = rel8->virtual_resource_block_assignment_flag; ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->mcs = rel8->mcs_1; ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->ndi = rel8->new_data_indicator_1; ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } break; case 25: if (fp->frame_type == TDD) { dci_alloc->dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->type = 1; ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type = rel8->virtual_resource_block_assignment_flag; ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->mcs = rel8->mcs_1; ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->ndi = rel8->new_data_indicator_1; ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->dai = rel8->downlink_assignment_index; ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->padding = 0; // printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI1A_5MHz_FDD_t; ((DCI1A_5MHz_FDD_t *)dci_pdu)->type = 1; ((DCI1A_5MHz_FDD_t *)dci_pdu)->vrb_type = rel8->virtual_resource_block_assignment_flag; ((DCI1A_5MHz_FDD_t *)dci_pdu)->mcs = rel8->mcs_1; ((DCI1A_5MHz_FDD_t *)dci_pdu)->ndi = rel8->new_data_indicator_1; ((DCI1A_5MHz_FDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI1A_5MHz_FDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_5MHz_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_5MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1A_5MHz_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } break; case 50: if (fp->frame_type == TDD) { dci_alloc->dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->type = 1; ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->vrb_type = rel8->virtual_resource_block_assignment_flag; ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->mcs = rel8->mcs_1; ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->ndi = rel8->new_data_indicator_1; ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->dai = rel8->downlink_assignment_index; ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->padding = 0; // printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI1A_10MHz_FDD_t; ((DCI1A_10MHz_FDD_t *)dci_pdu)->type = 1; ((DCI1A_10MHz_FDD_t *)dci_pdu)->vrb_type = rel8->virtual_resource_block_assignment_flag; ((DCI1A_10MHz_FDD_t *)dci_pdu)->mcs = rel8->mcs_1; ((DCI1A_10MHz_FDD_t *)dci_pdu)->ndi = rel8->new_data_indicator_1; ((DCI1A_10MHz_FDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI1A_10MHz_FDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_10MHz_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_10MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1A_10MHz_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } break; case 100: if (fp->frame_type == TDD) { dci_alloc->dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->type = 1; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->vrb_type = rel8->virtual_resource_block_assignment_flag; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->mcs = rel8->mcs_1; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->ndi = rel8->new_data_indicator_1; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->dai = rel8->downlink_assignment_index; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->padding = 0; // printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI1A_20MHz_FDD_t; ((DCI1A_20MHz_FDD_t *)dci_pdu)->type = 1; ((DCI1A_20MHz_FDD_t *)dci_pdu)->vrb_type = rel8->virtual_resource_block_assignment_flag; ((DCI1A_20MHz_FDD_t *)dci_pdu)->mcs = rel8->mcs_1; ((DCI1A_20MHz_FDD_t *)dci_pdu)->ndi = rel8->new_data_indicator_1; ((DCI1A_20MHz_FDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI1A_20MHz_FDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_20MHz_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_20MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1A_20MHz_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } break; } LOG_T(PHY,"%d.%d: DCI 1A: rnti %x, PDCCH order to do PRACH\n", proc->frame_tx, proc->subframe_tx, rel8->rnti); } void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,nfapi_dl_config_dci_dl_pdu *pdu) { LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; uint8_t *dci_pdu = &dci_alloc->dci_pdu[0]; nfapi_dl_config_dci_dl_pdu_rel8_t *rel8 = &pdu->dci_dl_pdu_rel8; /* check if this is a DCI 1A PDCCH order for RAPROC */ if (rel8->dci_format == NFAPI_DL_DCI_FORMAT_1A && rel8->rnti_type == 1) { int full_rb; switch (fp->N_RB_DL) { case 6: full_rb = 63; break; case 25: full_rb = 511; break; case 50: full_rb = 2047; break; case 100: full_rb = 8191; break; default: abort(); } if (rel8->resource_block_coding == full_rb) return fill_pdcch_order(eNB, proc, dci_alloc, pdu); } 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 NPRB; int TB0_active; int TB1_active; uint16_t DL_pmi_single=0; // This should be taken from DLSCH parameters for PUSCH precoding uint8_t I_mcs = 0; dci_alloc->firstCCE = rel8->cce_idx; dci_alloc->L = rel8->aggregation_level; dci_alloc->rnti = rel8->rnti; dci_alloc->harq_pid = rel8->harq_process; dci_alloc->ra_flag = 0; LOG_D(PHY,"NFAPI: SFN/SF:%04d%d proc:TX:[SFN/SF:%04d%d] DCI format %d, nCCE %d, L %d, rnti %x, harq_pid %d\n", frame,subframe,proc->frame_tx,proc->subframe_tx,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; UE_id = find_dlsch(rel8->rnti,eNB,SEARCH_EXIST_OR_FREE); if( (UE_id<0) || (UE_id>=NUMBER_OF_UE_MAX) ){ LOG_E(PHY,"illegal UE_id found!!! rnti %04x UE_id %d\n",rel8->rnti,UE_id); return; } //AssertFatal(UE_id!=-1,"no free or exiting 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]; beamforming_mode = eNB->transmission_mode[(uint8_t)UE_id]<7?0:eNB->transmission_mode[(uint8_t)UE_id]; dlsch0_harq = dlsch0->harq_processes[rel8->harq_process]; dlsch0_harq->codeword = 0; dlsch1_harq = dlsch1->harq_processes[rel8->harq_process]; dlsch1_harq->codeword = 1; dlsch0->subframe_tx[subframe] = 1; LOG_D(PHY,"NFAPI: SFN/SF:%04d%d proc:TX:SFN/SF:%04d%d dlsch0[rnti:%x harq_mask:%04x] dci_pdu[rnti:%x rnti_type:%d harq_process:%d ndi1:%d] dlsch0_harq[round:%d harq_mask:%x ndi:%d]\n", frame,subframe, proc->frame_tx,proc->subframe_tx, dlsch0->rnti,dlsch0->harq_mask, rel8->rnti, rel8->rnti_type, rel8->harq_process, rel8->new_data_indicator_1, dlsch0_harq->round, dlsch0->harq_mask, dlsch0_harq->ndi); if (dlsch0->rnti != rel8->rnti) { // if rnti of dlsch is not the same as in the config, this is a new entry dlsch0_harq->round=0; dlsch0->harq_mask=0; } if ((dlsch0->harq_mask & (1<<rel8->harq_process)) > 0 ) { if (rel8->new_data_indicator_1 != dlsch0_harq->ndi) dlsch0_harq->round=0; } else { // process is inactive, so activate and set round to 0 dlsch0_harq->round=0; } dlsch0_harq->ndi = rel8->new_data_indicator_1; #ifdef PHY_TX_THREAD dlsch0->active[subframe] = 1; #else dlsch0->active = 1; #endif if (rel8->rnti_type == 2) dlsch0_harq->round = 0; LOG_D(PHY,"NFAPI: rel8[rnti %x dci_format %d harq_process %d ndi1 %d rnti type %d] dlsch0[rnti %x harq_mask %x] dlsch0_harq[round %d ndi %d]\n", rel8->rnti,rel8->dci_format,rel8->harq_process, rel8->new_data_indicator_1, rel8->rnti_type, dlsch0->rnti,dlsch0->harq_mask, dlsch0_harq->round,dlsch0_harq->ndi ); switch (rel8->dci_format) { case NFAPI_DL_DCI_FORMAT_1A: AssertFatal(rel8->resource_block_coding < 8192, "SFN/SF:%04d%d proc:TX:SFN/SF:%04d%d: rel8->resource_block_coding (%p) %u >= 8192 (rnti %x, rnti_type %d, format %d, harq_id %d\n", frame,subframe,proc->frame_tx,subframe, &rel8->resource_block_coding,rel8->resource_block_coding,rel8->rnti,rel8->rnti_type,rel8->dci_format,rel8->harq_process); dci_alloc->format = format1A; switch (fp->N_RB_DL) { case 6: if (fp->frame_type == TDD) { dci_alloc->dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->type = 1; ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type = rel8->virtual_resource_block_assignment_flag; ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs = rel8->mcs_1; ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->ndi = rel8->new_data_indicator_1; ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->dai = rel8->downlink_assignment_index; ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->padding = 0; } else { dci_alloc->dci_length = sizeof_DCI1A_1_5MHz_FDD_t; ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->type = 1; ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->vrb_type = rel8->virtual_resource_block_assignment_flag; ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->mcs = rel8->mcs_1; ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->ndi = rel8->new_data_indicator_1; ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } AssertFatal(rel8->virtual_resource_block_assignment_flag==LOCALIZED,"Distributed RB allocation not done yet\n"); 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; break; case 25: if (fp->frame_type == TDD) { dci_alloc->dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->type = 1; ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type = rel8->virtual_resource_block_assignment_flag; ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->mcs = rel8->mcs_1; ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->ndi = rel8->new_data_indicator_1; ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->dai = rel8->downlink_assignment_index; ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->padding = 0; // printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI1A_5MHz_FDD_t; ((DCI1A_5MHz_FDD_t *)dci_pdu)->type = 1; ((DCI1A_5MHz_FDD_t *)dci_pdu)->vrb_type = rel8->virtual_resource_block_assignment_flag; ((DCI1A_5MHz_FDD_t *)dci_pdu)->mcs = rel8->mcs_1; ((DCI1A_5MHz_FDD_t *)dci_pdu)->ndi = rel8->new_data_indicator_1; ((DCI1A_5MHz_FDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI1A_5MHz_FDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_5MHz_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_5MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1A_5MHz_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } AssertFatal(rel8->virtual_resource_block_assignment_flag==LOCALIZED,"Distributed RB allocation not done yet\n"); 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; break; case 50: if (fp->frame_type == TDD) { dci_alloc->dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->type = 1; ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->vrb_type = rel8->virtual_resource_block_assignment_flag; ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->mcs = rel8->mcs_1; ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->ndi = rel8->new_data_indicator_1; ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->dai = rel8->downlink_assignment_index; ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->padding = 0; // printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI1A_10MHz_FDD_t; ((DCI1A_10MHz_FDD_t *)dci_pdu)->type = 1; ((DCI1A_10MHz_FDD_t *)dci_pdu)->vrb_type = rel8->virtual_resource_block_assignment_flag; ((DCI1A_10MHz_FDD_t *)dci_pdu)->mcs = rel8->mcs_1; ((DCI1A_10MHz_FDD_t *)dci_pdu)->ndi = rel8->new_data_indicator_1; ((DCI1A_10MHz_FDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI1A_10MHz_FDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_10MHz_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_10MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1A_10MHz_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } AssertFatal(rel8->virtual_resource_block_assignment_flag==LOCALIZED,"Distributed RB allocation not done yet\n"); dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT50_0[rel8->resource_block_coding]; 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; break; case 100: if (fp->frame_type == TDD) { dci_alloc->dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->type = 1; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->vrb_type = rel8->virtual_resource_block_assignment_flag; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->mcs = rel8->mcs_1; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->ndi = rel8->new_data_indicator_1; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->dai = rel8->downlink_assignment_index; ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->padding = 0; // printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI1A_20MHz_FDD_t; ((DCI1A_20MHz_FDD_t *)dci_pdu)->type = 1; ((DCI1A_20MHz_FDD_t *)dci_pdu)->vrb_type = rel8->virtual_resource_block_assignment_flag; ((DCI1A_20MHz_FDD_t *)dci_pdu)->mcs = rel8->mcs_1; ((DCI1A_20MHz_FDD_t *)dci_pdu)->ndi = rel8->new_data_indicator_1; ((DCI1A_20MHz_FDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI1A_20MHz_FDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1A_20MHz_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1A_20MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1A_20MHz_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } AssertFatal(rel8->virtual_resource_block_assignment_flag==LOCALIZED,"Distributed RB allocation not done yet\n"); dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT100_0[rel8->resource_block_coding]; dlsch0_harq->rb_alloc[1] = localRIV2alloc_LUT100_1[rel8->resource_block_coding]; dlsch0_harq->rb_alloc[2] = localRIV2alloc_LUT100_2[rel8->resource_block_coding]; 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; break; } if (rel8->rnti_type == 2 ) { // see 36-212 V8.6.0 p. 45 NPRB = (rel8->tpc&1)+2; // 36-213 sec.7.1.7.2 p.26 I_mcs = rel8->mcs_1; } else { NPRB = dlsch0_harq->nb_rb; I_mcs = get_I_TBS(rel8->mcs_1); } AssertFatal(NPRB>0,"DCI 1A: NPRB = 0 (rnti %x, rnti type %d, tpc %d, round %d, resource_block_coding %d, harq process %d)\n",rel8->rnti,rel8->rnti_type,rel8->tpc,dlsch0_harq->round,rel8->resource_block_coding,rel8->harq_process); dlsch0_harq->rvidx = rel8->redundancy_version_1; dlsch0_harq->Nl = 1; dlsch0_harq->mimo_mode = (fp->nb_antenna_ports_eNB == 1) ? SISO : ALAMOUTI; dlsch0_harq->dl_power_off = 1; dlsch0_harq->mcs = rel8->mcs_1; dlsch0_harq->Qm = 2; dlsch0_harq->TBS = TBStable[I_mcs][NPRB-1]; dlsch0->harq_ids[frame%2][subframe] = rel8->harq_process; #ifdef PHY_TX_THREAD dlsch0->active[subframe] = 1; #else dlsch0->active = 1; #endif dlsch0->rnti = rel8->rnti; //dlsch0->harq_ids[subframe] = rel8->harq_process; if (dlsch0_harq->round == 0) dlsch0_harq->status = ACTIVE; dlsch0->harq_mask |= (1<<rel8->harq_process); if (rel8->rnti_type == 1) LOG_I(PHY,"DCI 1A: round %d, mcs %d, rballoc %x, rv %d, rnti %x, harq process %d\n",dlsch0_harq->round,rel8->mcs_1,rel8->resource_block_coding,rel8->redundancy_version_1,rel8->rnti,rel8->harq_process); break; case NFAPI_DL_DCI_FORMAT_1: dci_alloc->format = format1; #ifdef PHY_TX_THREAD dlsch0->active[subframe] = 1; #else dlsch0->active = 1; #endif LOG_D(PHY,"SFN/SF:%04d%d proc:TX:SFN/SF:%04d%d: Programming DLSCH for Format 1 DCI, harq_pid %d\n",frame,subframe,proc->frame_tx,subframe,rel8->harq_process); switch (fp->N_RB_DL) { case 6: if (fp->frame_type == TDD) { dci_alloc->dci_length = sizeof_DCI1_1_5MHz_TDD_t; ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rah = rel8->resource_allocation_type; ((DCI1_1_5MHz_TDD_t *)dci_pdu)->mcs = rel8->mcs_1; ((DCI1_1_5MHz_TDD_t *)dci_pdu)->ndi = rel8->new_data_indicator_1; ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1_1_5MHz_TDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1_1_5MHz_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1_1_5MHz_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; ((DCI1_1_5MHz_TDD_t *)dci_pdu)->padding = 0; // printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI1_1_5MHz_FDD_t; ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rah = rel8->resource_allocation_type; ((DCI1_1_5MHz_FDD_t *)dci_pdu)->mcs = rel8->mcs_1; ((DCI1_1_5MHz_FDD_t *)dci_pdu)->ndi = rel8->new_data_indicator_1; ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1_1_5MHz_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1_1_5MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1_1_5MHz_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } break; case 25: if (fp->frame_type == TDD) { dci_alloc->dci_length = sizeof_DCI1_5MHz_TDD_t; ((DCI1_5MHz_TDD_t *)dci_pdu)->rah = rel8->resource_allocation_type; ((DCI1_5MHz_TDD_t *)dci_pdu)->mcs = rel8->mcs_1; ((DCI1_5MHz_TDD_t *)dci_pdu)->ndi = rel8->new_data_indicator_1; ((DCI1_5MHz_TDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI1_5MHz_TDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1_5MHz_TDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1_5MHz_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1_5MHz_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; ((DCI1_5MHz_TDD_t *)dci_pdu)->padding = 0; // printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI1_5MHz_FDD_t; ((DCI1_5MHz_FDD_t *)dci_pdu)->rah = rel8->resource_allocation_type; ((DCI1_5MHz_FDD_t *)dci_pdu)->mcs = rel8->mcs_1; ((DCI1_5MHz_FDD_t *)dci_pdu)->ndi = rel8->new_data_indicator_1; ((DCI1_5MHz_FDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI1_5MHz_FDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1_5MHz_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1_5MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1_5MHz_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } break; case 50: if (fp->frame_type == TDD) { dci_alloc->dci_length = sizeof_DCI1_10MHz_TDD_t; ((DCI1_10MHz_TDD_t *)dci_pdu)->rah = rel8->resource_allocation_type; ((DCI1_10MHz_TDD_t *)dci_pdu)->mcs = rel8->mcs_1; ((DCI1_10MHz_TDD_t *)dci_pdu)->ndi = rel8->new_data_indicator_1; ((DCI1_10MHz_TDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI1_10MHz_TDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1_10MHz_TDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1_10MHz_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1_10MHz_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; ((DCI1_10MHz_TDD_t *)dci_pdu)->padding = 0; // printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI1_10MHz_FDD_t; ((DCI1_10MHz_FDD_t *)dci_pdu)->rah = rel8->resource_allocation_type; ((DCI1_10MHz_FDD_t *)dci_pdu)->mcs = rel8->mcs_1; ((DCI1_10MHz_FDD_t *)dci_pdu)->ndi = rel8->new_data_indicator_1; ((DCI1_10MHz_FDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI1_10MHz_FDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1_10MHz_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1_10MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1_10MHz_FDD_t *)dci_pdu)->padding = 0; } break; case 100: if (fp->frame_type == TDD) { dci_alloc->dci_length = sizeof_DCI1_20MHz_TDD_t; ((DCI1_20MHz_TDD_t *)dci_pdu)->rah = rel8->resource_allocation_type; ((DCI1_20MHz_TDD_t *)dci_pdu)->mcs = rel8->mcs_1; ((DCI1_20MHz_TDD_t *)dci_pdu)->ndi = rel8->new_data_indicator_1; ((DCI1_20MHz_TDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI1_20MHz_TDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1_20MHz_TDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1_20MHz_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1_20MHz_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; ((DCI1_20MHz_TDD_t *)dci_pdu)->padding = 0; // printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI1_20MHz_FDD_t; ((DCI1_20MHz_FDD_t *)dci_pdu)->rah = rel8->resource_allocation_type; ((DCI1_20MHz_FDD_t *)dci_pdu)->mcs = rel8->mcs_1; ((DCI1_20MHz_FDD_t *)dci_pdu)->ndi = rel8->new_data_indicator_1; ((DCI1_20MHz_FDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI1_20MHz_FDD_t *)dci_pdu)->rv = rel8->redundancy_version_1; ((DCI1_20MHz_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI1_20MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI1_20MHz_FDD_t *)dci_pdu)->padding = 0; } break; } AssertFatal(rel8->harq_process<8,"Format 1: harq_pid=%d >= 8\n", rel8->harq_process); dlsch0_harq = dlsch0->harq_processes[rel8->harq_process]; dlsch0_harq->codeword=0; // printf("DCI: Setting subframe_tx for subframe %d\n",subframe); dlsch0->subframe_tx[subframe] = 1; conv_rballoc(rel8->resource_allocation_type, rel8->resource_block_coding, fp->N_RB_DL, dlsch0_harq->rb_alloc); dlsch0_harq->nb_rb = conv_nprb(rel8->resource_allocation_type, rel8->resource_block_coding, fp->N_RB_DL); NPRB = dlsch0_harq->nb_rb; AssertFatal(NPRB>0,"NPRB == 0\n"); dlsch0_harq->rvidx = rel8->redundancy_version_1; dlsch0_harq->Nl = 1; // dlsch[0]->layer_index = 0; if (beamforming_mode == 0) dlsch0_harq->mimo_mode = (fp->nb_antenna_ports_eNB == 1) ? SISO : ALAMOUTI; else if (beamforming_mode == 7) dlsch0_harq->mimo_mode = TM7; else LOG_E(PHY,"Invalid beamforming mode %dL\n", beamforming_mode); dlsch0_harq->dl_power_off = 1; #ifdef PHY_TX_THREAD dlsch0->active[subframe] = 1; #else dlsch0->active = 1; #endif if (dlsch0_harq->round == 0) { dlsch0_harq->status = ACTIVE; // printf("Setting DLSCH process %d to ACTIVE\n",rel8->harq_process); // MCS and TBS don't change across HARQ rounds dlsch0_harq->mcs = rel8->mcs_1; dlsch0_harq->Qm = get_Qm(rel8->mcs_1); dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][NPRB-1]; } LOG_D(PHY,"DCI: Set harq_ids[%d] to %d (%p)\n",subframe,rel8->harq_process,dlsch0); dlsch0->harq_ids[frame%2][subframe] = rel8->harq_process; dlsch0->harq_mask |= (1<<rel8->harq_process); dlsch0->rnti = rel8->rnti; break; case NFAPI_DL_DCI_FORMAT_2A: dci_alloc->format = format2A; switch (fp->N_RB_DL) { case 6: if (fp->frame_type == TDD) { dci_alloc->dci_length = sizeof_DCI2A_1_5MHz_2A_TDD_t; ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rah = rel8->resource_allocation_type; ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1 = rel8->mcs_1; ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2 = rel8->mcs_2; ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->ndi1 = rel8->new_data_indicator_1; ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->ndi2 = rel8->new_data_indicator_2; ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rv1 = rel8->redundancy_version_1; ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rv2 = rel8->redundancy_version_2; ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; /* there is no padding in this structure, it is exactly 32 bits */ // printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI2A_1_5MHz_2A_FDD_t; ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rah = rel8->resource_allocation_type; ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->mcs1 = rel8->mcs_1; ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->mcs2 = rel8->mcs_2; ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->ndi1 = rel8->new_data_indicator_1; ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->ndi2 = rel8->new_data_indicator_2; ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rv1 = rel8->redundancy_version_1; ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rv2 = rel8->redundancy_version_2; ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } break; case 25: if (fp->frame_type == TDD) { dci_alloc->dci_length = sizeof_DCI2A_5MHz_2A_TDD_t; ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rah = rel8->resource_allocation_type; ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs1 = rel8->mcs_1; ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs2 = rel8->mcs_2; ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->ndi1 = rel8->new_data_indicator_1; ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->ndi2 = rel8->new_data_indicator_2; ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv1 = rel8->redundancy_version_1; ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv2 = rel8->redundancy_version_2; ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->padding = 0; // printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI2A_5MHz_2A_FDD_t; ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rah = rel8->resource_allocation_type; ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->mcs1 = rel8->mcs_1; ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->mcs2 = rel8->mcs_2; ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->ndi1 = rel8->new_data_indicator_1; ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->ndi2 = rel8->new_data_indicator_2; ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rv1 = rel8->redundancy_version_1; ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rv2 = rel8->redundancy_version_2; ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } break; case 50: if (fp->frame_type == TDD) { dci_alloc->dci_length = sizeof_DCI2A_10MHz_2A_TDD_t; ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rah = rel8->resource_allocation_type; ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs1 = rel8->mcs_1; ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs2 = rel8->mcs_2; ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->ndi1 = rel8->new_data_indicator_1; ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->ndi2 = rel8->new_data_indicator_2; ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv1 = rel8->redundancy_version_1; ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv2 = rel8->redundancy_version_2; ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->padding = 0; // printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI2A_10MHz_2A_FDD_t; ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rah = rel8->resource_allocation_type; ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->mcs1 = rel8->mcs_1; ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->mcs2 = rel8->mcs_2; ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->ndi1 = rel8->new_data_indicator_1; ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->ndi2 = rel8->new_data_indicator_2; ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rv1 = rel8->redundancy_version_1; ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rv2 = rel8->redundancy_version_2; ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->padding = 0; } break; case 100: if (fp->frame_type == TDD) { dci_alloc->dci_length = sizeof_DCI2A_20MHz_2A_TDD_t; ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rah = rel8->resource_allocation_type; ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs1 = rel8->mcs_1; ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs2 = rel8->mcs_2; ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->ndi1 = rel8->new_data_indicator_1; ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->ndi2 = rel8->new_data_indicator_2; ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv1 = rel8->redundancy_version_1; ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv2 = rel8->redundancy_version_2; ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->padding = 0; // printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI2A_20MHz_2A_FDD_t; ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rah = rel8->resource_allocation_type; ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->mcs1 = rel8->mcs_1; ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->mcs2 = rel8->mcs_2; ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->ndi1 = rel8->new_data_indicator_1; ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->ndi2 = rel8->new_data_indicator_2; ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rv1 = rel8->redundancy_version_1; ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rv2 = rel8->redundancy_version_2; ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->padding = 0; } break; } AssertFatal(rel8->harq_process<8,"Format 2_2A: harq_pid=%d >= 8\n", rel8->harq_process); // Flip the TB to codeword mapping as described in 5.3.3.1.5 of 36-212 V11.3.0 // note that we must set tbswap=0 in eNB scheduler if one TB is deactivated // This must be set as in TM4, does not work properly now. if (rel8->transport_block_to_codeword_swap_flag == 1) { dlsch0 = eNB->dlsch[UE_id][1]; dlsch1 = eNB->dlsch[UE_id][0]; } dlsch0_harq = dlsch0->harq_processes[rel8->harq_process]; dlsch1_harq = dlsch1->harq_processes[rel8->harq_process]; dlsch0->subframe_tx[subframe] = 1; dlsch0->harq_ids[frame%2][subframe] = rel8->harq_process; dlsch1->harq_ids[frame%2][subframe] = rel8->harq_process; // printf("Setting DLSCH harq id %d to subframe %d\n",harq_pid,subframe); conv_rballoc(rel8->resource_allocation_type, rel8->resource_block_coding, fp->N_RB_DL, dlsch0_harq->rb_alloc); dlsch1_harq->rb_alloc[0] = dlsch0_harq->rb_alloc[0]; dlsch0_harq->nb_rb = conv_nprb(rel8->resource_allocation_type, rel8->resource_block_coding, fp->N_RB_DL); dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; AssertFatal(dlsch0_harq->nb_rb > 0,"nb_rb=0\n"); dlsch0_harq->mcs = rel8->mcs_1; dlsch1_harq->mcs = rel8->mcs_2; dlsch0_harq->Qm = get_Qm(rel8->mcs_1); dlsch1_harq->Qm = get_Qm(rel8->mcs_2); dlsch0_harq->rvidx = rel8->redundancy_version_1; dlsch1_harq->rvidx = rel8->redundancy_version_2; // assume both TBs are active dlsch0_harq->Nl = 1; dlsch1_harq->Nl = 1; #ifdef PHY_TX_THREAD dlsch0->active[subframe] = 1; dlsch1->active[subframe] = 1; #else dlsch0->active = 1; dlsch1->active = 1; #endif dlsch0->harq_mask |= (1<<rel8->harq_process); dlsch1->harq_mask |= (1<<rel8->harq_process); // check if either TB is disabled (see 36-213 V11.3 Section ) if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) { #ifdef PHY_TX_THREAD dlsch0->active[subframe] = 0; #else dlsch0->active = 0; #endif dlsch0->harq_mask &= ~(1<<rel8->harq_process); } if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) { #ifdef PHY_TX_THREAD dlsch1->active[subframe]= 0; #else dlsch1->active = 0; #endif dlsch1->harq_mask &= ~(1<<rel8->harq_process); } // dlsch0_harq->dl_power_off = 0; // dlsch1_harq->dl_power_off = 0; if (fp->nb_antenna_ports_eNB == 2) { dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-1]; #ifdef PHY_TX_THREAD if ((dlsch0->active[subframe]==1) && (dlsch1->active[subframe]==1)) { #else if ((dlsch0->active==1) && (dlsch1->active==1)) { #endif dlsch0_harq->mimo_mode = LARGE_CDD; dlsch1_harq->mimo_mode = LARGE_CDD; dlsch0_harq->dl_power_off = 1; dlsch1_harq->dl_power_off = 1; } else { dlsch0_harq->mimo_mode = ALAMOUTI; dlsch1_harq->mimo_mode = ALAMOUTI; } } else if (fp->nb_antenna_ports_eNB == 4) { // 4 antenna case #ifdef PHY_TX_THREAD if ((dlsch0->active[subframe]==1) && (dlsch1->active[subframe]==1)) { #else if ((dlsch0->active==1) && (dlsch1->active==1)) { #endif switch (rel8->precoding_information) { case 0: // one layer per transport block dlsch0_harq->mimo_mode = LARGE_CDD; dlsch1_harq->mimo_mode = LARGE_CDD; dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; dlsch0_harq->dl_power_off = 1; dlsch1_harq->dl_power_off = 1; break; case 1: // one-layers on TB 0, two on TB 1 dlsch0_harq->mimo_mode = LARGE_CDD; dlsch1_harq->mimo_mode = LARGE_CDD; dlsch1_harq->Nl = 2; dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][(dlsch1_harq->nb_rb<<1)-1]; dlsch0_harq->dl_power_off = 1; dlsch1_harq->dl_power_off = 1; break; case 2: // two-layers on TB 0, two on TB 1 dlsch0_harq->mimo_mode = LARGE_CDD; dlsch1_harq->mimo_mode = LARGE_CDD; dlsch0_harq->Nl = 2; dlsch0_harq->dl_power_off = 1; dlsch1_harq->dl_power_off = 1; if (fp->N_RB_DL <= 56) { dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1]; dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][(dlsch1_harq->nb_rb<<1)-1]; } else { LOG_E(PHY,"Add implementation of Table 7.1.7.2.2-1 for two-layer TBS conversion with N_RB_DL > 56\n"); } break; case 3: // LOG_E(PHY,"Illegal value (3) for TPMI in Format 2A DCI\n"); break; } #ifdef PHY_TX_THREAD } else if (dlsch0->active[subframe] == 1) { #else } else if (dlsch0->active == 1) { #endif switch (rel8->precoding_information) { case 0: // one layer per transport block dlsch0_harq->mimo_mode = ALAMOUTI; dlsch1_harq->mimo_mode = ALAMOUTI; dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; break; case 1: // two-layers on TB 0 dlsch0_harq->mimo_mode = LARGE_CDD; dlsch0_harq->Nl = 2; dlsch0_harq->dl_power_off = 1; dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1]; break; case 2: // two-layers on TB 0, two on TB 1 case 3: // LOG_E(PHY,"Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n",rel8->precoding_information); break; } #ifdef PHY_TX_THREAD } else if (dlsch1->active[subframe] == 1) { #else } else if (dlsch1->active == 1) { #endif switch (rel8->precoding_information) { case 0: // one layer per transport block dlsch0_harq->mimo_mode = ALAMOUTI; dlsch1_harq->mimo_mode = ALAMOUTI; dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; break; case 1: // two-layers on TB 0 dlsch1_harq->mimo_mode = LARGE_CDD; dlsch1_harq->Nl = 2; dlsch1_harq->dl_power_off = 1; dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][(dlsch1_harq->nb_rb<<1)-1]; break; case 2: // two-layers on TB 0, two on TB 1 case 3: // LOG_E(PHY,"Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n",rel8->precoding_information); break; } } } else { LOG_E(PHY,"Illegal number of antennas for eNB %d\n",fp->nb_antenna_ports_eNB); } // reset HARQ process if this is the first transmission #ifdef PHY_TX_THREAD if ((dlsch0->active[subframe]==1) && (dlsch0_harq->round == 0)) #else if ((dlsch0->active==1) && (dlsch0_harq->round == 0)) #endif dlsch0_harq->status = ACTIVE; #ifdef PHY_TX_THREAD if ((dlsch1->active[subframe]==1) && (dlsch1_harq->round == 0)) #else if ((dlsch1->active==1) && (dlsch1_harq->round == 0)) #endif dlsch1_harq->status = ACTIVE; dlsch0->rnti = rel8->rnti; dlsch1->rnti = rel8->rnti; break; case NFAPI_DL_DCI_FORMAT_2: dci_alloc->format = format2; switch (fp->N_RB_DL) { case 6: if (fp->frame_type == TDD) { dci_alloc->dci_length = sizeof_DCI2_1_5MHz_2A_TDD_t; ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1 = rel8->mcs_1; ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2 = rel8->mcs_2; ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->ndi1 = rel8->new_data_indicator_1; ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->ndi2 = rel8->new_data_indicator_2; ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rv1 = rel8->redundancy_version_1; ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rv2 = rel8->redundancy_version_2; ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tpmi = rel8->precoding_information; ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->padding = 0; // printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI2_1_5MHz_2A_FDD_t; ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->mcs1 = rel8->mcs_1; ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->mcs2 = rel8->mcs_2; ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->ndi1 = rel8->new_data_indicator_1; ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->ndi2 = rel8->new_data_indicator_2; ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rv1 = rel8->redundancy_version_1; ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rv2 = rel8->redundancy_version_2; ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tpmi = rel8->precoding_information; ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } break; case 25: if (fp->frame_type == TDD) { dci_alloc->dci_length = sizeof_DCI2_5MHz_2A_TDD_t; ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rah = rel8->resource_allocation_type; ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs1 = rel8->mcs_1; ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs2 = rel8->mcs_2; ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi1 = rel8->new_data_indicator_1; ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi2 = rel8->new_data_indicator_2; ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv1 = rel8->redundancy_version_1; ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv2 = rel8->redundancy_version_2; ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tpmi = rel8->precoding_information; ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->padding = 0; // printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI2_5MHz_2A_FDD_t; ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rah = rel8->resource_allocation_type; ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs1 = rel8->mcs_1; ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs2 = rel8->mcs_2; ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi1 = rel8->new_data_indicator_1; ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi2 = rel8->new_data_indicator_2; ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv1 = rel8->redundancy_version_1; ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv2 = rel8->redundancy_version_2; ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tpmi = rel8->precoding_information; ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->padding = 0; // printf("FDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } break; case 50: if (fp->frame_type == TDD) { dci_alloc->dci_length = sizeof_DCI2_10MHz_2A_TDD_t; ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rah = rel8->resource_allocation_type; ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs1 = rel8->mcs_1; ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs2 = rel8->mcs_2; ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->ndi1 = rel8->new_data_indicator_1; ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->ndi2 = rel8->new_data_indicator_2; ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv1 = rel8->redundancy_version_1; ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv2 = rel8->redundancy_version_2; ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tpmi = rel8->precoding_information; ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->padding = 0; // printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI2_10MHz_2A_FDD_t; ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rah = rel8->resource_allocation_type; ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs1 = rel8->mcs_1; ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs2 = rel8->mcs_2; ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->ndi1 = rel8->new_data_indicator_1; ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->ndi2 = rel8->new_data_indicator_2; ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv1 = rel8->redundancy_version_1; ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv2 = rel8->redundancy_version_2; ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tpmi = rel8->precoding_information; ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->padding = 0; } break; case 100: if (fp->frame_type == TDD) { dci_alloc->dci_length = sizeof_DCI2_20MHz_2A_TDD_t; ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rah = rel8->resource_allocation_type; ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs1 = rel8->mcs_1; ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs2 = rel8->mcs_2; ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->ndi1 = rel8->new_data_indicator_1; ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->ndi2 = rel8->new_data_indicator_2; ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv1 = rel8->redundancy_version_1; ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv2 = rel8->redundancy_version_2; ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->dai = rel8->downlink_assignment_index; ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tpmi = rel8->precoding_information; ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->padding = 0; // printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB); } else { dci_alloc->dci_length = sizeof_DCI2_20MHz_2A_FDD_t; ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rah = rel8->resource_allocation_type; ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs1 = rel8->mcs_1; ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs2 = rel8->mcs_2; ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->ndi1 = rel8->new_data_indicator_1; ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->ndi2 = rel8->new_data_indicator_2; ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rballoc = rel8->resource_block_coding; ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv1 = rel8->redundancy_version_1; ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv2 = rel8->redundancy_version_2; ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->TPC = rel8->tpc; ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process; ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tb_swap = rel8->transport_block_to_codeword_swap_flag; ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tpmi = rel8->precoding_information; ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->padding = 0; } break; } AssertFatal(rel8->harq_process>=8, "Format 2_2A: harq_pid=%d >= 8\n", rel8->harq_process); // Flip the TB to codeword mapping as described in 5.3.3.1.5 of 36-212 V11.3.0 // note that we must set tbswap=0 in eNB scheduler if one TB is deactivated TB0_active = 1; TB1_active = 1; if ((rel8->redundancy_version_1 == 1) && (rel8->mcs_1 == 0)) { TB0_active=0; } if ((rel8->redundancy_version_2 == 1) && (rel8->mcs_2 == 0)) { TB1_active=0; } #ifdef DEBUG_HARQ printf("RV0 = %d, RV1 = %d. MCS0 = %d, MCS1=%d\n", rel8->redundancy_version_1, rel8->redundancy_version_2, rel8->mcs_1, rel8->mcs_2); #endif if (TB0_active && TB1_active && rel8->transport_block_to_codeword_swap_flag==0) { #ifdef PHY_TX_THREAD dlsch0->active[subframe] = 1; dlsch1->active[subframe] = 1; #else dlsch0->active = 1; dlsch1->active = 1; #endif dlsch0->harq_mask |= (1<<rel8->harq_process); dlsch1->harq_mask |= (1<<rel8->harq_process); dlsch0_harq = dlsch0->harq_processes[rel8->harq_process]; dlsch1_harq = dlsch1->harq_processes[rel8->harq_process]; dlsch0_harq->mcs = rel8->mcs_1; dlsch1_harq->mcs = rel8->mcs_2; dlsch0_harq->Qm = get_Qm(rel8->mcs_1); dlsch1_harq->Qm = get_Qm(rel8->mcs_2); dlsch0_harq->rvidx = rel8->redundancy_version_1; dlsch1_harq->rvidx = rel8->redundancy_version_2; dlsch0_harq->status = ACTIVE; dlsch1_harq->status = ACTIVE; dlsch0_harq->codeword=0; dlsch1_harq->codeword=1; #ifdef DEBUG_HARQ printf("\n ENB: BOTH ACTIVE\n"); #endif } else if (TB0_active && TB1_active && rel8->transport_block_to_codeword_swap_flag==1) { dlsch0 = eNB->dlsch[UE_id][1]; dlsch1 = eNB->dlsch[UE_id][0]; #ifdef PHY_TX_THREAD dlsch0->active[subframe] = 1; dlsch1->active[subframe] = 1; #else dlsch0->active = 1; dlsch1->active = 1; #endif dlsch0->harq_mask |= (1<<rel8->harq_process); dlsch1->harq_mask |= (1<<rel8->harq_process); dlsch1_harq = dlsch1->harq_processes[rel8->harq_process]; dlsch0_harq->mcs = rel8->mcs_1; dlsch1_harq->mcs = rel8->mcs_2; dlsch0_harq->Qm = get_Qm(rel8->mcs_1); dlsch1_harq->Qm = get_Qm(rel8->mcs_2); dlsch0_harq->rvidx = rel8->redundancy_version_1; dlsch1_harq->rvidx = rel8->redundancy_version_2; dlsch0_harq->status = ACTIVE; dlsch1_harq->status = ACTIVE; dlsch0_harq->codeword=1; dlsch1_harq->codeword=0; } else if (TB0_active && (TB1_active==0)) { #ifdef PHY_TX_THREAD dlsch0->active[subframe] = 1; #else dlsch0->active = 1; #endif dlsch0->harq_mask |= (1<<rel8->harq_process); dlsch0_harq = dlsch0->harq_processes[rel8->harq_process]; dlsch0_harq->mcs = rel8->mcs_1; dlsch0_harq->Qm = get_Qm(rel8->mcs_1); dlsch0_harq->rvidx = rel8->redundancy_version_1; dlsch0_harq->status = ACTIVE; dlsch0_harq->codeword = 0; dlsch1=NULL; dlsch1_harq = NULL; #ifdef DEBUG_HARQ printf("\n ENB: TB1 is deactivated, retransmit TB0 transmit in TM6\n"); #endif } else if ((TB0_active==0) && TB1_active) { #ifdef PHY_TX_THREAD dlsch1->active[subframe] = 1; #else dlsch1->active = 1; #endif dlsch1->harq_mask |= (1<<rel8->harq_process); dlsch1_harq = dlsch1->harq_processes[rel8->harq_process]; dlsch1_harq->mcs = rel8->mcs_2; dlsch1_harq->Qm = get_Qm(rel8->mcs_2); dlsch1_harq->rvidx = rel8->redundancy_version_2; dlsch1_harq->status = ACTIVE; dlsch1_harq->codeword = 0; dlsch0=NULL; dlsch0_harq = NULL; #ifdef DEBUG_HARQ printf("\n ENB: TB0 is deactivated, retransmit TB1 transmit in TM6\n"); #endif } if (dlsch0 != NULL){ dlsch0->subframe_tx[subframe] = 1; dlsch0->harq_ids[frame%2][subframe] = rel8->harq_process; } if (dlsch1_harq != NULL){ dlsch1->harq_ids[frame%2][subframe] = rel8->harq_process; } if (dlsch0 != NULL ){ conv_rballoc(rel8->resource_allocation_type, rel8->resource_block_coding, fp->N_RB_DL, dlsch0_harq->rb_alloc); dlsch0_harq->nb_rb = conv_nprb(rel8->resource_allocation_type, rel8->resource_block_coding, fp->N_RB_DL); if (dlsch1 != NULL){ dlsch1_harq->rb_alloc[0] = dlsch0_harq->rb_alloc[0]; dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; } } else if ((dlsch0 == NULL ) && (dlsch1 != NULL )){ conv_rballoc(rel8->resource_allocation_type, rel8->resource_block_coding, fp->N_RB_DL, dlsch1_harq->rb_alloc); dlsch1_harq->nb_rb = conv_nprb(rel8->resource_allocation_type, rel8->resource_block_coding, fp->N_RB_DL); } // assume both TBs are active if (dlsch0_harq != NULL) dlsch0_harq->Nl = 1; if (dlsch1_harq != NULL) dlsch1_harq->Nl = 1; // check if either TB is disabled (see 36-213 V11.3 Section ) if (fp->nb_antenna_ports_eNB == 2) { if ((dlsch0 != NULL) && (dlsch1 != NULL)) { //two CW active dlsch0_harq->dl_power_off = 1; dlsch1_harq->dl_power_off = 1; dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; switch (rel8->precoding_information) { case 0: dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; dlsch0_harq->pmi_alloc = pmi_extend(fp,0,1); dlsch1_harq->pmi_alloc = pmi_extend(fp,0,1); break; case 1: dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; dlsch0_harq->pmi_alloc = pmi_extend(fp,1,1); dlsch0_harq->pmi_alloc = pmi_extend(fp,1,1); break; case 2: // PUSCH precoding dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; dlsch0_harq->pmi_alloc = DL_pmi_single; dlsch1_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; dlsch1_harq->pmi_alloc = DL_pmi_single; break; default: break; } } else if ((dlsch0 != NULL) && (dlsch1 == NULL)) { // only CW 0 active dlsch0_harq->dl_power_off = 1; dlsch0_harq->TBS= TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; switch (rel8->precoding_information) { case 0 : dlsch0_harq->mimo_mode = ALAMOUTI; break; case 1: dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; dlsch0_harq->pmi_alloc = pmi_extend(fp,0,0); break; case 2: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; dlsch0_harq->pmi_alloc = pmi_extend(fp,1,0); break; case 3: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; dlsch0_harq->pmi_alloc = pmi_extend(fp,2,0); break; case 4: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; dlsch0_harq->pmi_alloc = pmi_extend(fp,3,0); break; case 5: dlsch0_harq->mimo_mode = PUSCH_PRECODING0; dlsch0_harq->pmi_alloc = DL_pmi_single; break; case 6: dlsch0_harq->mimo_mode = PUSCH_PRECODING1; dlsch0_harq->pmi_alloc = DL_pmi_single; break; } } else if ((dlsch0 == NULL) && (dlsch1 != NULL)) { dlsch1_harq->dl_power_off = 1; dlsch1_harq->TBS= TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; switch (rel8->precoding_information) { case 0 : dlsch1_harq->mimo_mode = ALAMOUTI; break; case 1: dlsch1_harq->mimo_mode = UNIFORM_PRECODING11; dlsch1_harq->pmi_alloc = pmi_extend(fp,0,0); break; case 2: dlsch1_harq->mimo_mode = UNIFORM_PRECODING1m1; dlsch1_harq->pmi_alloc = pmi_extend(fp,1,0); break; case 3: dlsch1_harq->mimo_mode = UNIFORM_PRECODING1j; dlsch1_harq->pmi_alloc = pmi_extend(fp,2,0); break; case 4: dlsch1_harq->mimo_mode = UNIFORM_PRECODING1mj; dlsch1_harq->pmi_alloc = pmi_extend(fp,3,0); break; case 5: dlsch1_harq->mimo_mode = PUSCH_PRECODING0; dlsch1_harq->pmi_alloc = DL_pmi_single; break; case 6: dlsch1_harq->mimo_mode = PUSCH_PRECODING1; dlsch1_harq->pmi_alloc = DL_pmi_single; break; } } } else if (fp->nb_antenna_ports_eNB == 4) { // fill in later } // reset HARQ process if this is the first transmission /* if (dlsch0_harq->round == 0) dlsch0_harq->status = ACTIVE; if (dlsch1_harq->round == 0) dlsch1_harq->status = ACTIVE;*/ if (dlsch0_harq != NULL) dlsch0->rnti = rel8->rnti; if (dlsch1 != NULL) dlsch1->rnti = rel8->rnti; break; } if (dlsch0_harq) { dlsch0_harq->frame = frame; dlsch0_harq->subframe = subframe; } if (dlsch1_harq) { dlsch1_harq->frame = frame; dlsch1_harq->subframe = subframe; } #ifdef DEBUG_DCI if (dlsch0) { printf("dlsch0 eNB: dlsch0 %p\n",dlsch0); printf("dlsch0 eNB: rnti %x\n",dlsch0->rnti); printf("dlsch0 eNB: NBRB %d\n",dlsch0_harq->nb_rb); printf("dlsch0 eNB: rballoc %x\n",dlsch0_harq->rb_alloc[0]); printf("dlsch0 eNB: harq_pid %d\n",harq_pid); printf("dlsch0 eNB: round %d\n",dlsch0_harq->round); printf("dlsch0 eNB: rvidx %d\n",dlsch0_harq->rvidx); printf("dlsch0 eNB: TBS %d (NPRB %d)\n",dlsch0_harq->TBS,NPRB); printf("dlsch0 eNB: mcs %d\n",dlsch0_harq->mcs); printf("dlsch0 eNB: tpmi %d\n",rel8->precoding_information); printf("dlsch0 eNB: mimo_mode %d\n",dlsch0_harq->mimo_mode); } if (dlsch1) { printf("dlsch1 eNB: dlsch1 %p\n",dlsch1); printf("dlsch1 eNB: rnti %x\n",dlsch1->rnti); printf("dlsch1 eNB: NBRB %d\n",dlsch1_harq->nb_rb); printf("dlsch1 eNB: rballoc %x\n",dlsch1_harq->rb_alloc[0]); printf("dlsch1 eNB: harq_pid %d\n",harq_pid); printf("dlsch1 eNB: round %d\n",dlsch1_harq->round); printf("dlsch1 eNB: rvidx %d\n",dlsch1_harq->rvidx); printf("dlsch1 eNB: TBS %d (NPRB %d)\n",dlsch1_harq->TBS,NPRB); printf("dlsch1 eNB: mcs %d\n",dlsch1_harq->mcs); printf("dlsch1 eNB: tpmi %d\n",rel8->precoding_information); printf("dlsch1 eNB: mimo_mode %d\n",dlsch1_harq->mimo_mode); } #endif //printf("DCI %d.%d rnti %d harq %d TBS %d\n", frame, subframe, rel8->rnti, rel8->harq_process, dlsch0_harq->TBS); #if T_TRACER if (dlsch0->active) T(T_ENB_PHY_DLSCH_UE_DCI, T_INT(0), T_INT(frame), T_INT(subframe), T_INT(rel8->rnti), T_INT(rel8->dci_format), T_INT(rel8->harq_process), T_INT(rel8->mcs_1), T_INT(dlsch0_harq->TBS)); #endif } void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *dci_alloc,nfapi_dl_config_mpdcch_pdu *pdu) { LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; uint8_t *dci_pdu = &dci_alloc->dci_pdu[0]; nfapi_dl_config_mpdcch_pdu_rel13_t *rel13 = &pdu->mpdcch_pdu_rel13; LTE_eNB_DLSCH_t *dlsch0=NULL; LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL; int UE_id; int subframe = proc->subframe_tx; int frame = proc->frame_tx; dci_alloc->firstCCE = rel13->ecce_index; dci_alloc->L = rel13->aggregation_level; dci_alloc->rnti = rel13->rnti; dci_alloc->harq_pid = rel13->harq_process; dci_alloc->narrowband = rel13->mpdcch_narrow_band; dci_alloc->number_of_prb_pairs = rel13->number_of_prb_pairs; dci_alloc->resource_block_assignment = rel13->resource_block_assignment; dci_alloc->transmission_type = rel13->mpdcch_tansmission_type; dci_alloc->start_symbol = rel13->start_symbol; dci_alloc->ce_mode = rel13->ce_mode; dci_alloc->dmrs_scrambling_init = rel13->drms_scrambling_init; dci_alloc->i0 = rel13->initial_transmission_sf_io; dci_alloc->ra_flag = 0; if (rel13->rnti_type == 2 ) dci_alloc->ra_flag = 1; UE_id = find_dlsch(rel13->rnti,eNB,SEARCH_EXIST_OR_FREE); if( (UE_id<0) || (UE_id>=NUMBER_OF_UE_MAX) ){ LOG_E(PHY,"illegal UE_id found!!! rnti %04x UE_id %d\n",rel13->rnti,UE_id); return; } //AssertFatal(UE_id!=-1,"no free or exiting 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]; dlsch0_harq = dlsch0->harq_processes[rel13->harq_process]; AssertFatal(fp->frame_type==FDD,"TDD is not supported yet for eMTC\n"); AssertFatal(fp->N_RB_DL==25 || fp->N_RB_DL==50 ||fp->N_RB_DL==100, "eMTC only with N_RB_DL = 25,50,100\n"); switch (rel13->dci_format) { case 10: // Format 6-1A dci_alloc->format = format6_1A; #ifdef PHY_TX_THREAD dlsch0->active[subframe] = 1; #else dlsch0->active = 1; #endif switch (fp->N_RB_DL) { case 25: dci_alloc->dci_length = sizeof_DCI6_1A_5MHz_t; ((DCI6_1A_5MHz_t *)dci_pdu)->type = 1; ((DCI6_1A_5MHz_t *)dci_pdu)->hopping = rel13->frequency_hopping_enabled_flag; ((DCI6_1A_5MHz_t *)dci_pdu)->rballoc = rel13->resource_block_coding; ((DCI6_1A_5MHz_t *)dci_pdu)->mcs = rel13->mcs; ((DCI6_1A_5MHz_t *)dci_pdu)->rep = (rel13->pdsch_reptition_levels-1); ((DCI6_1A_5MHz_t *)dci_pdu)->harq_pid = rel13->harq_process; ((DCI6_1A_5MHz_t *)dci_pdu)->ndi = rel13->new_data_indicator; ((DCI6_1A_5MHz_t *)dci_pdu)->rv = rel13->redundancy_version; ((DCI6_1A_5MHz_t *)dci_pdu)->TPC = rel13->tpc; ((DCI6_1A_5MHz_t *)dci_pdu)->srs_req = rel13->srs_request; ((DCI6_1A_5MHz_t *)dci_pdu)->harq_ack_off = rel13->harq_resource_offset; ((DCI6_1A_5MHz_t *)dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number-1; ((DCI6_1A_5MHz_t *)dci_pdu)->padding = 0; break; case 50: dci_alloc->dci_length = sizeof_DCI6_1A_10MHz_t; ((DCI6_1A_10MHz_t *)dci_pdu)->type = 1; ((DCI6_1A_10MHz_t *)dci_pdu)->hopping = rel13->frequency_hopping_enabled_flag; ((DCI6_1A_10MHz_t *)dci_pdu)->rballoc = rel13->resource_block_coding; ((DCI6_1A_10MHz_t *)dci_pdu)->mcs = rel13->mcs; ((DCI6_1A_10MHz_t *)dci_pdu)->rep = (rel13->pdsch_reptition_levels-1); ((DCI6_1A_10MHz_t *)dci_pdu)->harq_pid = rel13->harq_process; ((DCI6_1A_10MHz_t *)dci_pdu)->ndi = rel13->new_data_indicator; ((DCI6_1A_10MHz_t *)dci_pdu)->rv = rel13->redundancy_version; ((DCI6_1A_10MHz_t *)dci_pdu)->TPC = rel13->tpc; ((DCI6_1A_10MHz_t *)dci_pdu)->srs_req = rel13->srs_request; ((DCI6_1A_10MHz_t *)dci_pdu)->harq_ack_off = rel13->harq_resource_offset; ((DCI6_1A_10MHz_t *)dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number-1; ((DCI6_1A_10MHz_t *)dci_pdu)->padding = 0; break; case 100: dci_alloc->dci_length = sizeof_DCI6_1A_20MHz_t; ((DCI6_1A_20MHz_t *)dci_pdu)->type = 1; ((DCI6_1A_20MHz_t *)dci_pdu)->hopping = rel13->frequency_hopping_enabled_flag; ((DCI6_1A_20MHz_t *)dci_pdu)->rballoc = rel13->resource_block_coding; ((DCI6_1A_20MHz_t *)dci_pdu)->mcs = rel13->mcs; ((DCI6_1A_20MHz_t *)dci_pdu)->rep = (rel13->pdsch_reptition_levels-1); ((DCI6_1A_20MHz_t *)dci_pdu)->harq_pid = rel13->harq_process; ((DCI6_1A_20MHz_t *)dci_pdu)->ndi = rel13->new_data_indicator; ((DCI6_1A_20MHz_t *)dci_pdu)->rv = rel13->redundancy_version; ((DCI6_1A_20MHz_t *)dci_pdu)->TPC = rel13->tpc; ((DCI6_1A_20MHz_t *)dci_pdu)->srs_req = rel13->srs_request; ((DCI6_1A_20MHz_t *)dci_pdu)->harq_ack_off = rel13->harq_resource_offset; ((DCI6_1A_20MHz_t *)dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number-1; ((DCI6_1A_20MHz_t *)dci_pdu)->padding = 0; break; } break; case 11: // Format 6-1B dci_alloc->format = format6_1B; #ifdef PHY_TX_THREAD dlsch0->active[subframe] = 1; #else dlsch0->active = 1; #endif switch (fp->N_RB_DL) { case 25: dci_alloc->dci_length = sizeof_DCI6_1B_5MHz_t; ((DCI6_1B_5MHz_t *)dci_pdu)->type = 1; ((DCI6_1B_5MHz_t *)dci_pdu)->rballoc = rel13->resource_block_coding; ((DCI6_1B_5MHz_t *)dci_pdu)->mcs = rel13->mcs; ((DCI6_1B_5MHz_t *)dci_pdu)->rep = (rel13->pdsch_reptition_levels-1); ((DCI6_1B_5MHz_t *)dci_pdu)->harq_pid = rel13->harq_process; ((DCI6_1B_5MHz_t *)dci_pdu)->ndi = rel13->new_data_indicator; ((DCI6_1B_5MHz_t *)dci_pdu)->harq_ack_off = rel13->harq_resource_offset; ((DCI6_1B_5MHz_t *)dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number-1; ((DCI6_1B_5MHz_t *)dci_pdu)->padding = 0; break; case 50: dci_alloc->dci_length = sizeof_DCI6_1B_10MHz_t; ((DCI6_1B_10MHz_t *)dci_pdu)->type = 1; ((DCI6_1B_10MHz_t *)dci_pdu)->rballoc = rel13->resource_block_coding; ((DCI6_1B_10MHz_t *)dci_pdu)->mcs = rel13->mcs; ((DCI6_1B_10MHz_t *)dci_pdu)->rep = (rel13->pdsch_reptition_levels-1); ((DCI6_1B_10MHz_t *)dci_pdu)->harq_pid = rel13->harq_process; ((DCI6_1B_10MHz_t *)dci_pdu)->ndi = rel13->new_data_indicator; ((DCI6_1B_10MHz_t *)dci_pdu)->harq_ack_off = rel13->harq_resource_offset; ((DCI6_1B_10MHz_t *)dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number-1; ((DCI6_1B_10MHz_t *)dci_pdu)->padding = 0; break; case 100: dci_alloc->dci_length = sizeof_DCI6_1B_20MHz_t; ((DCI6_1B_20MHz_t *)dci_pdu)->type = 1; ((DCI6_1B_20MHz_t *)dci_pdu)->rballoc = rel13->resource_block_coding; ((DCI6_1B_20MHz_t *)dci_pdu)->mcs = rel13->mcs; ((DCI6_1B_20MHz_t *)dci_pdu)->rep = (rel13->pdsch_reptition_levels-1); ((DCI6_1B_20MHz_t *)dci_pdu)->harq_pid = rel13->harq_process; ((DCI6_1B_20MHz_t *)dci_pdu)->ndi = rel13->new_data_indicator; ((DCI6_1B_20MHz_t *)dci_pdu)->harq_ack_off = rel13->harq_resource_offset; ((DCI6_1B_20MHz_t *)dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number-1; ((DCI6_1B_20MHz_t *)dci_pdu)->padding = 0; break; } case 12: // Format 6-2 dci_alloc->format = format6_2; #ifdef PHY_TX_THREAD dlsch0->active[subframe] = 1; #else dlsch0->active = 1; #endif switch (fp->N_RB_DL) { case 25: dci_alloc->dci_length = sizeof_DCI6_2_5MHz_t; if (rel13->paging_direct_indication_differentiation_flag==0) { ((DCI6_2_di_5MHz_t *)dci_pdu)->type = 0; ((DCI6_2_di_5MHz_t *)dci_pdu)->di_info = rel13->direct_indication; ((DCI6_2_di_5MHz_t *)dci_pdu)->padding = 0; } else { ((DCI6_2_paging_5MHz_t *)dci_pdu)->type = 1; ((DCI6_2_paging_5MHz_t *)dci_pdu)->rballoc = rel13->resource_block_coding; ((DCI6_2_paging_5MHz_t *)dci_pdu)->mcs = rel13->mcs; ((DCI6_2_paging_5MHz_t *)dci_pdu)->rep = (rel13->pdsch_reptition_levels-1); ((DCI6_2_paging_5MHz_t *)dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number-1; ((DCI6_2_paging_5MHz_t *)dci_pdu)->padding = 0; } break; case 50: dci_alloc->dci_length = sizeof_DCI6_2_10MHz_t; if (rel13->paging_direct_indication_differentiation_flag==0) { ((DCI6_2_di_10MHz_t *)dci_pdu)->type = 0; ((DCI6_2_di_10MHz_t *)dci_pdu)->di_info = rel13->direct_indication; ((DCI6_2_di_10MHz_t *)dci_pdu)->padding = 0; } else { ((DCI6_2_paging_10MHz_t *)dci_pdu)->type = 1; ((DCI6_2_paging_10MHz_t *)dci_pdu)->rballoc = rel13->resource_block_coding; ((DCI6_2_paging_10MHz_t *)dci_pdu)->mcs = rel13->mcs; ((DCI6_2_paging_10MHz_t *)dci_pdu)->rep = (rel13->pdsch_reptition_levels-1); ((DCI6_2_paging_10MHz_t *)dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number-1; ((DCI6_2_paging_10MHz_t *)dci_pdu)->padding = 0; } break; case 100: dci_alloc->dci_length = sizeof_DCI6_2_20MHz_t; if (rel13->paging_direct_indication_differentiation_flag==0) { ((DCI6_2_di_20MHz_t *)dci_pdu)->type = 0; ((DCI6_2_di_20MHz_t *)dci_pdu)->di_info = rel13->direct_indication; ((DCI6_2_di_20MHz_t *)dci_pdu)->padding = 0; } else { ((DCI6_2_paging_20MHz_t *)dci_pdu)->type = 1; ((DCI6_2_paging_20MHz_t *)dci_pdu)->rballoc = rel13->resource_block_coding; ((DCI6_2_paging_20MHz_t *)dci_pdu)->mcs = rel13->mcs; ((DCI6_2_paging_20MHz_t *)dci_pdu)->rep = (rel13->pdsch_reptition_levels-1); ((DCI6_2_paging_20MHz_t *)dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number-1; ((DCI6_2_paging_20MHz_t *)dci_pdu)->padding = 0; } break; } } AssertFatal(rel13->harq_process<8, "ERROR: Format 6_1A: harq_pid=%d >= 8\n", rel13->harq_process); dlsch0_harq = dlsch0->harq_processes[rel13->harq_process]; dlsch0_harq->codeword=0; // printf("DCI: Setting subframe_tx for subframe %d\n",subframe); dlsch0->subframe_tx[subframe] = 1; conv_eMTC_rballoc(rel13->resource_block_coding, fp->N_RB_DL, dlsch0_harq->rb_alloc); dlsch0_harq->nb_rb = RIV2nb_rb_LUT6[rel13->resource_block_coding&31]; // this is the 6PRB RIV dlsch0_harq->rvidx = rel13->redundancy_version; dlsch0_harq->Nl = 1; // dlsch[0]->layer_index = 0; // if (beamforming_mode == 0) dlsch0_harq->mimo_mode = (fp->nb_antenna_ports_eNB == 1) ? SISO : ALAMOUTI; //else if (beamforming_mode == 7) // dlsch0_harq->mimo_mode = TM7; //else //LOG_E(PHY,"Invalid beamforming mode %dL\n", beamforming_mode); dlsch0_harq->dl_power_off = 1; #ifdef PHY_TX_THREAD dlsch0->active[subframe] = 1; #else dlsch0->active = 1; #endif dlsch0->harq_mask |= (1<<rel13->harq_process); if (dlsch0_harq->round == 0) { dlsch0_harq->status = ACTIVE; // printf("Setting DLSCH process %d to ACTIVE\n",rel8->harq_process); // MCS and TBS don't change across HARQ rounds dlsch0_harq->mcs = rel13->mcs; dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; } dlsch0->harq_ids[frame%2][subframe] = rel13->harq_process; dlsch0->rnti = rel13->rnti; } void fill_dci0(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc, DCI_ALLOC_t *dci_alloc,nfapi_hi_dci0_dci_pdu *pdu) { 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 hopping = pdu->dci_pdu_rel8.frequency_hopping_enabled_flag; 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; uint16_t UE_id = -1; #ifdef T_TRACER T(T_ENB_PHY_ULSCH_UE_DCI, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(pdu->dci_pdu_rel8.rnti), T_INT(pdu->dci_pdu_rel8.harq_pid), T_INT(mcs), T_INT(-1 /* TODO: remove round? */), T_INT(pdu->dci_pdu_rel8.resource_block_start), T_INT(pdu->dci_pdu_rel8.number_of_resource_block), T_INT(get_TBS_UL(mcs, pdu->dci_pdu_rel8.number_of_resource_block) * 8), T_INT(pdu->dci_pdu_rel8.aggregation_level), T_INT(pdu->dci_pdu_rel8.cce_index)); #endif void *dci_pdu = (void*)dci_alloc->dci_pdu; LOG_D(PHY,"SFN/SF:%04d%d DCI0[rnti %x cqi %d mcs %d hopping %d rballoc %x (%d,%d) ndi %d TPC %d cshift %d]\n", frame,subframe, pdu->dci_pdu_rel8.rnti,cqi_req, mcs,hopping,rballoc, pdu->dci_pdu_rel8.resource_block_start, pdu->dci_pdu_rel8.number_of_resource_block, ndi,TPC,cshift); 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->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; ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->hopping = hopping; ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->type = 0; ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->padding = 0; dci_alloc->dci_length = sizeof_DCI0_1_5MHz_TDD_1_6_t; } 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; ((DCI0_1_5MHz_FDD_t *)dci_pdu)->hopping = hopping; ((DCI0_1_5MHz_FDD_t *)dci_pdu)->type = 0; ((DCI0_1_5MHz_FDD_t *)dci_pdu)->padding = 0; dci_alloc->dci_length = sizeof_DCI0_1_5MHz_FDD_t; } 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; ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->hopping = hopping; ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->type = 0; ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->padding = 0; dci_alloc->dci_length = sizeof_DCI0_5MHz_TDD_1_6_t; } 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; ((DCI0_5MHz_FDD_t *)dci_pdu)->hopping = hopping; ((DCI0_5MHz_FDD_t *)dci_pdu)->type = 0; ((DCI0_5MHz_FDD_t *)dci_pdu)->padding = 0; dci_alloc->dci_length = sizeof_DCI0_5MHz_FDD_t; } 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; ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->hopping = hopping; ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->type = 0; ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->padding = 0; dci_alloc->dci_length = sizeof_DCI0_10MHz_TDD_1_6_t; } 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; ((DCI0_10MHz_FDD_t *)dci_pdu)->hopping = hopping; ((DCI0_10MHz_FDD_t *)dci_pdu)->type = 0; ((DCI0_10MHz_FDD_t *)dci_pdu)->padding = 0; dci_alloc->dci_length = sizeof_DCI0_10MHz_FDD_t; } 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; ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->hopping = hopping; ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->type = 0; ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->padding = 0; dci_alloc->dci_length = sizeof_DCI0_20MHz_TDD_1_6_t; } 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; ((DCI0_20MHz_FDD_t *)dci_pdu)->hopping = hopping; ((DCI0_20MHz_FDD_t *)dci_pdu)->type = 0; ((DCI0_20MHz_FDD_t *)dci_pdu)->padding = 0; dci_alloc->dci_length = sizeof_DCI0_20MHz_FDD_t; } //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; } if(frame_parms->frame_type == TDD){ UE_id = find_ulsch(pdu->dci_pdu_rel8.rnti, eNB,SEARCH_EXIST_OR_FREE); if(UE_id != -1){ eNB->ulsch[UE_id]->harq_processes[pdu->dci_pdu_rel8.harq_pid]->V_UL_DAI = dai +1; } } } void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame,int subframe) { uint8_t harq_pid; //uint8_t UE_id; boolean_t new_ulsch = (find_ulsch(ulsch_pdu->ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST)==-1) ? TRUE : FALSE; //AssertFatal((UE_id=find_ulsch(ulsch_pdu->ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0, // "No existing/free 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_mask |= 1 << harq_pid; ulsch->harq_processes[harq_pid]->frame = frame; ulsch->harq_processes[harq_pid]->subframe = subframe; ulsch->harq_processes[harq_pid]->handled = 0; 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"); if(ulsch->harq_processes[harq_pid]->nb_rb == 0){ LOG_E(PHY, "fill_ulsch UE_id %d nb_rb = 0\n", UE_id); } 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_D(PHY,"[eNB %d][PUSCH %d] Frame %d, Subframe %d Programming PUSCH with n_DMRS2 %d (cshift %d) ulsch:ndi:%d ulsch_pdu:ndi:%d new_ulsch:%d status:%d ulsch_pdu:rvidx:%d ulsch_pdu->ulsch_pdu_rel8.size %d\n", eNB->Mod_id,harq_pid,frame,subframe, ulsch->harq_processes[harq_pid]->n_DMRS2, ulsch->harq_processes[harq_pid]->n_DMRS, ulsch->harq_processes[harq_pid]->ndi, ulsch_pdu->ulsch_pdu_rel8.new_data_indication, new_ulsch, ulsch->harq_processes[harq_pid]->status, ulsch_pdu->ulsch_pdu_rel8.redundancy_version, ulsch_pdu->ulsch_pdu_rel8.size); ulsch->harq_processes[harq_pid]->rvidx = ulsch_pdu->ulsch_pdu_rel8.redundancy_version; if(ulsch_pdu->ulsch_pdu_rel8.modulation_type!=0) ulsch->harq_processes[harq_pid]->Qm = ulsch_pdu->ulsch_pdu_rel8.modulation_type; // Set O_ACK to 0 by default, will be set of DLSCH is scheduled and needs to be ulsch->harq_processes[harq_pid]->O_ACK = 0; if ((ulsch->harq_processes[harq_pid]->status == SCH_IDLE) || (ulsch->harq_processes[harq_pid]->ndi != ulsch_pdu->ulsch_pdu_rel8.new_data_indication) || (new_ulsch == TRUE)){ 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 = 12*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->harq_processes[harq_pid]->ndi = ulsch_pdu->ulsch_pdu_rel8.new_data_indication; // note here, the CQI bits need to be kept constant as in initial transmission // set to 0 in initial transmission, and don't touch them during retransmissions // will be set if MAC has activated ULSCH_CQI_RI_PDU or ULSCH_CQI_HARQ_RI_PDU ulsch->harq_processes[harq_pid]->Or1 = 0; ulsch->harq_processes[harq_pid]->Or2 = 0; } else { ulsch->harq_processes[harq_pid]->round++; ulsch->harq_processes[harq_pid]->TBS = ulsch_pdu->ulsch_pdu_rel8.size<<3; ulsch->harq_processes[harq_pid]->Msc_initial = 12*ulsch_pdu->ulsch_pdu_rel8.number_of_resource_blocks; } ulsch->rnti = ulsch_pdu->ulsch_pdu_rel8.rnti; LOG_D(PHY,"Filling ULSCH %x (UE_id %d) (new_ulsch %d) for Frame %d, Subframe %d : harq_pid %d, status %d, handled %d, first_rb %d, nb_rb %d, rvidx %d, Qm %d, TBS %d, round %d \n", ulsch->rnti, UE_id, new_ulsch, frame, subframe, harq_pid, ulsch->harq_processes[harq_pid]->status, ulsch->harq_processes[harq_pid]->handled, 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); }