Files
openairinterface5g/openair1/PHY/LTE_TRANSPORT/dci_tools.c
T

2262 lines
111 KiB
C

/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.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"
//#undef LOG_D
//#define LOG_D(A,B...) printf(B)
int find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type) {
int first_free_index=-1;
AssertFatal(eNB!=NULL,"eNB is null\n");
for (int 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;
}
int find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type) {
int first_free_index=-1;
AssertFatal(eNB!=NULL,"eNB is null\n");
for (int 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,L1_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,
L1_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];
dlsch0->ue_type = 0;
dlsch1->ue_type = 0;
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;
LOG_D(PHY,"TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",rel8->mcs_1,rel8->resource_block_coding,rel8->redundancy_version_1,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 != SI_RNTI) LOG_I(PHY,"DCI 1A: round %d, mcs %d, TBS %d, rballoc %x, rv %d, rnti %x, harq process %d\n",dlsch0_harq->round,rel8->mcs_1,dlsch0_harq->TBS,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,L1_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;
UE_id = find_dlsch (rel13->rnti, eNB, SEARCH_EXIST_OR_FREE);
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];
dci_alloc->ra_flag = 0;
if (rel13->rnti_type == 2) {
dci_alloc->ra_flag = 1;
}
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;
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;
((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;
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&31;
((DCI6_1A_10MHz_t *) dci_pdu)->narrowband = rel13->resource_block_coding>>5;
((DCI6_1A_10MHz_t *) dci_pdu)->mcs = rel13->mcs;
((DCI6_1A_10MHz_t *) dci_pdu)->rep = (rel13->pdsch_reptition_levels);
((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;
LOG_D(PHY,
"Frame %d, Subframe %d : Programming Format 6-1A DCI, type %d, hopping %d, narrowband %d, rballoc %x, mcs %d, rep %d, harq_pid %d, ndi %d, rv %d, TPC %d, srs_req %d, harq_ack_off %d, dci_rep r%d => %x\n",
frame,subframe,
((DCI6_1A_10MHz_t *) dci_pdu)->type,
((DCI6_1A_10MHz_t *) dci_pdu)->hopping,
((DCI6_1A_10MHz_t *) dci_pdu)->narrowband,
((DCI6_1A_10MHz_t *) dci_pdu)->rballoc,
((DCI6_1A_10MHz_t *) dci_pdu)->mcs,
((DCI6_1A_10MHz_t *) dci_pdu)->rep,
((DCI6_1A_10MHz_t *) dci_pdu)->harq_pid,
((DCI6_1A_10MHz_t *) dci_pdu)->ndi,
((DCI6_1A_10MHz_t *) dci_pdu)->rv,
((DCI6_1A_10MHz_t *) dci_pdu)->TPC,
((DCI6_1A_10MHz_t *) dci_pdu)->srs_req,
((DCI6_1A_10MHz_t *) dci_pdu)->harq_ack_off,
((DCI6_1A_10MHz_t *) dci_pdu)->dci_rep,
((uint32_t *)dci_pdu)[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;
((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;
break;
}
break;
case 11: // Format 6-1B
dci_alloc->format = format6_1B;
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;
((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;
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;
((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;
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;
((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;
break;
}
case 12: // Format 6-2
dci_alloc->format = format6_2;
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;
} 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;
((DCI6_2_paging_5MHz_t *) dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number;
}
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;
} 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;
((DCI6_2_paging_10MHz_t *) dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number;
}
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;
} 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;
((DCI6_2_paging_20MHz_t *) dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number;
}
break;
}
}
AssertFatal (rel13->harq_process < 8, "ERROR: Format 6_1A: harq_pid=%d >= 8\n", rel13->harq_process);
dlsch0->ue_type = rel13->ce_mode;
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 + 2) % 10] = 1;
LOG_D(PHY,"PDSCH : resource_block_coding %x\n",rel13->resource_block_coding);
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;
dlsch0->subframe_tx[subframe] = 1;
if (dlsch0->rnti != rel13->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;
printf("*********************** rnti %x => %x, pos %d\n",rel13->rnti,dlsch0->rnti,UE_id);
}
if ((dlsch0->harq_mask & (1 << rel13->harq_process)) > 0) {
if ((rel13->new_data_indicator != dlsch0_harq->ndi)||(dci_alloc->ra_flag==1))
dlsch0_harq->round = 0;
} else { // process is inactive, so activate and set round to 0
dlsch0_harq->round = 0;
}
dlsch0_harq->ndi = rel13->new_data_indicator;
if (dlsch0_harq->round == 0) {
dlsch0_harq->status = ACTIVE;
dlsch0_harq->mcs = rel13->mcs;
if (dci_alloc->ra_flag == 0) // get TBS from table using mcs and nb_rb
dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
else if (rel13->tpc == 0) //N1A_PRB=2, get TBS from table using mcs and nb_rb=2
dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][1];
else if (rel13->tpc == 1) //N1A_PRB=3, get TBS from table using mcs and nb_rb=3
dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][2];
else AssertFatal(1==0,"Don't know how to set TBS (TPC %d)\n",rel13->tpc);
LOG_D(PHY,"fill_mdci_and_dlsch : TBS = %d(%d) %p, %x\n",dlsch0_harq->TBS,dlsch0_harq->mcs,dlsch0,rel13->rnti);
}
dlsch0->active = 1;
dlsch0->harq_mask |= (1 << rel13->harq_process);
dlsch0_harq->frame = (subframe >= 8) ? ((frame + 1) & 1023) : frame;
dlsch0_harq->subframe = (subframe + 2) % 10;
LOG_D(PHY,"Setting DLSCH UEid %d harq_ids[%d] from %d to %d\n",UE_id,dlsch0_harq->subframe,dlsch0->harq_ids[frame%2][dlsch0_harq->subframe],rel13->harq_process);
dlsch0->harq_ids[dlsch0_harq->frame%2][dlsch0_harq->subframe] = rel13->harq_process;
dlsch0_harq->pdsch_start = rel13->start_symbol;
LOG_D(PHY,"Setting DLSCH harq %d round %d to active for %d.%d\n",rel13->harq_process,dlsch0_harq->round,dlsch0_harq->frame,dlsch0_harq->subframe);
dlsch0->rnti = rel13->rnti;
dlsch0_harq->Qm = get_Qm(rel13->mcs);
}
void fill_dci0(PHY_VARS_eNB *eNB,int frame,int subframe,L1_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 >=0 -1 || UE_id < NUMBER_OF_ULSCH_MAX) {
eNB->ulsch[UE_id]->harq_processes[pdu->dci_pdu_rel8.harq_pid]->V_UL_DAI = dai +1;
}
}
}
int get_narrowband_index(int N_RB_UL,int rb) {
switch (N_RB_UL) {
case 6: // 6 PRBs, N_NB=1, i_0=0
case 25: // 25 PRBs, N_NB=4, i_0=0
return(rb/6);
break;
case 50: // 50 PRBs, N_NB=8, i_0=1
case 75: // 75 PRBs, N_NB=12, i_0=1
case 15: // 15 PRBs, N_NB=2, i_0=1
AssertFatal(rb>=1,"rb %d is not possible for %d PRBs\n",rb,N_RB_UL);
return((rb-1)/6);
break;
case 100: // 100 PRBs, N_NB=16, i_0=2
AssertFatal(rb>=2,"rb %d is not possible for %d PRBs\n",rb,N_RB_UL);
return(rb-2/6);
break;
default:
AssertFatal(1==0,"Impossible N_RB_UL %d\n",N_RB_UL);
break;
}
}
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;
LOG_D(PHY,"Filling ULSCH : ue_type %d, harq_pid %d\n",ulsch->ue_type,harq_pid);
ulsch->ue_type = ulsch_pdu->ulsch_pdu_rel13.ue_type;
AssertFatal(harq_pid ==0 || ulsch->ue_type == NOCE, "Harq PID is not zero for BL/CE UE\n");
if(ulsch_pdu->ulsch_pdu_rel13.repetition_number >1) // Fill the Harq process parameters in the first Rep only
{
return;
}
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]->repetition_number = ulsch_pdu->ulsch_pdu_rel13.repetition_number ;
ulsch->harq_processes[harq_pid]->total_number_of_repetitions = ulsch_pdu->ulsch_pdu_rel13.total_number_of_repetitions ;
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;
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);
}
int get_first_rb_in_narrowband(int N_RB_UL,
int rb) {
switch (N_RB_UL) {
case 6: // 6 PRBs, N_NB=1, i_0=0
case 25: // 25 PRBs, N_NB=4, i_0=0
return(rb - 6*(rb/6));
break;
case 50: // 50 PRBs, N_NB=8, i_0=1
case 75: // 75 PRBs, N_NB=12, i_0=1
case 15: // 15 PRBs, N_NB=2, i_0=1
AssertFatal(rb>=1,"rb %d is not possible for %d PRBs\n",rb,N_RB_UL);
return(rb-1-(6*((rb-1)/6)));
break;
case 100: // 100 PRBs, N_NB=16, i_0=2
AssertFatal(rb>=2,"rb %d is not possible for %d PRBs\n",rb,N_RB_UL);
return(rb-2-(6*((rb-2)/6)));
break;
default:
AssertFatal(1==0,"Impossible N_RB_UL %d\n",N_RB_UL);
break;
}
}
void fill_mpdcch_dci0 (PHY_VARS_eNB *eNB,
L1_rxtx_proc_t *proc,
mDCI_ALLOC_t *dci_alloc,
nfapi_hi_dci0_mpdcch_dci_pdu *pdu) {
LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
nfapi_hi_dci0_mpdcch_dci_pdu_rel13_t *rel13 = &pdu->mpdcch_dci_pdu_rel13;
uint32_t cqi_req = rel13->csi_request;
uint32_t TPC = rel13->tpc;
uint32_t mcs = rel13->mcs;
uint32_t hopping = rel13->frequency_hopping_flag;
uint32_t narrowband = get_narrowband_index(frame_parms->N_RB_UL,rel13->resource_block_start);
uint32_t rballoc = computeRIV (6,
get_first_rb_in_narrowband(frame_parms->N_RB_UL,rel13->resource_block_start),
rel13->number_of_resource_blocks);
uint32_t ndi = rel13->new_data_indication;
#ifdef T_TRACER
T (T_ENB_PHY_ULSCH_UE_DCI, T_INT (eNB->Mod_id), T_INT (proc->frame_tx), T_INT (proc->subframe_tx),
T_INT (rel13->rnti), T_INT (((proc->frame_tx * 10 + proc->subframe_tx + 4) % 8) /* TODO: correct harq pid */ ),
T_INT (mcs), T_INT (-1 /* TODO: remove round? */ ),
T_INT (rel13->resource_block_start),
T_INT (rel13->number_of_resource_blocks),
T_INT (get_TBS_UL (mcs, rel13->number_of_resource_blocks) * 8), T_INT (rel13->aggreagation_level), T_INT (rel13->ecce_index));
#endif
void *dci_pdu = (void *) dci_alloc->dci_pdu;
AssertFatal(rel13->ce_mode == 1 && rel13->dci_format == 4, "dci format 5 (CE_modeB) not supported yet\n");
LOG_D (PHY, "Filling DCI6-0A with cqi %d, mcs %d, hopping %d, rballoc %x (%d,%d) ndi %d TPC %d\n", cqi_req,
mcs, hopping, rballoc, rel13->resource_block_start, rel13->number_of_resource_blocks, ndi, TPC);
dci_alloc->format = format6_0A;
dci_alloc->firstCCE = rel13->ecce_index;
dci_alloc->L = rel13->aggreagation_level;
dci_alloc->rnti = rel13->rnti;
dci_alloc->harq_pid = rel13->harq_process;
dci_alloc->narrowband = rel13->mpdcch_narrowband;
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_transmission_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;
switch (frame_parms->N_RB_DL) {
case 6:
if (frame_parms->frame_type == TDD) {
AssertFatal(1==0,"TDD not supported for eMTC yet\n");
} else {
AssertFatal(1==0,"6 PRBS not supported for eMTC\n");
}
break;
case 25:
if (frame_parms->frame_type == TDD) {
AssertFatal(1==0,"TDD not supported for eMTC yet\n");
} else {
dci_alloc->dci_length = sizeof_DCI6_0A_5MHz_t;
((DCI6_0A_5MHz_t *) dci_pdu)->type = 0;
((DCI6_0A_5MHz_t *) dci_pdu)->hopping = hopping;
((DCI6_0A_5MHz_t *) dci_pdu)->rballoc = rballoc;
((DCI6_0A_5MHz_t *) dci_pdu)->narrowband = narrowband;
((DCI6_0A_5MHz_t *) dci_pdu)->mcs = mcs;
((DCI6_0A_5MHz_t *) dci_pdu)->rep = rel13->pusch_repetition_levels;
((DCI6_0A_5MHz_t *) dci_pdu)->harq_pid = rel13->harq_process;
((DCI6_0A_5MHz_t *) dci_pdu)->ndi = ndi;
((DCI6_0A_5MHz_t *) dci_pdu)->rv_idx = rel13->redudency_version;
((DCI6_0A_5MHz_t *) dci_pdu)->TPC = TPC;
((DCI6_0A_5MHz_t *) dci_pdu)->csi_req = cqi_req;
((DCI6_0A_5MHz_t *) dci_pdu)->srs_req = rel13->srs_request;
((DCI6_0A_5MHz_t *) dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number;
}
break;
case 50:
if (frame_parms->frame_type == TDD) {
AssertFatal(1==0,"TDD not supported for eMTC yet\n");
} else {
dci_alloc->dci_length = sizeof_DCI6_0A_10MHz_t;
((DCI6_0A_10MHz_t *) dci_pdu)->type = 0;
((DCI6_0A_10MHz_t *) dci_pdu)->hopping = hopping;
((DCI6_0A_10MHz_t *) dci_pdu)->rballoc = rballoc;
((DCI6_0A_10MHz_t *) dci_pdu)->narrowband = narrowband;
((DCI6_0A_10MHz_t *) dci_pdu)->mcs = mcs;
((DCI6_0A_10MHz_t *) dci_pdu)->rep = rel13->pusch_repetition_levels;
((DCI6_0A_10MHz_t *) dci_pdu)->harq_pid = rel13->harq_process;
((DCI6_0A_10MHz_t *) dci_pdu)->ndi = ndi;
((DCI6_0A_10MHz_t *) dci_pdu)->rv_idx = rel13->redudency_version;
((DCI6_0A_10MHz_t *) dci_pdu)->TPC = TPC;
((DCI6_0A_10MHz_t *) dci_pdu)->csi_req = cqi_req;
((DCI6_0A_10MHz_t *) dci_pdu)->srs_req = rel13->srs_request;
((DCI6_0A_10MHz_t *) dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number;
LOG_D(PHY,
"Frame %d, Subframe %d : Programming Format 6-0A DCI, type %d, hopping %d, narrowband %d, rballoc %x, mcs %d, rep %d, harq_pid %d, ndi %d, rv %d, TPC %d, csi_req %d, srs_req %d, dci_rep r%d => %x\n",
proc->frame_tx,proc->subframe_tx,
((DCI6_0A_10MHz_t *) dci_pdu)->type,
((DCI6_0A_10MHz_t *) dci_pdu)->hopping,
((DCI6_0A_10MHz_t *) dci_pdu)->narrowband,
((DCI6_0A_10MHz_t *) dci_pdu)->rballoc,
((DCI6_0A_10MHz_t *) dci_pdu)->mcs,
((DCI6_0A_10MHz_t *) dci_pdu)->rep,
((DCI6_0A_10MHz_t *) dci_pdu)->harq_pid,
((DCI6_0A_10MHz_t *) dci_pdu)->ndi,
((DCI6_0A_10MHz_t *) dci_pdu)->rv_idx,
((DCI6_0A_10MHz_t *) dci_pdu)->TPC,
((DCI6_0A_10MHz_t *) dci_pdu)->csi_req,
((DCI6_0A_10MHz_t *) dci_pdu)->srs_req,
((DCI6_0A_10MHz_t *) dci_pdu)->dci_rep,
((uint32_t *)dci_pdu)[0]);
}
break;
case 100:
if (frame_parms->frame_type == TDD) {
AssertFatal(1==0,"TDD not supported for eMTC yet\n");
} else {
dci_alloc->dci_length = sizeof_DCI6_0A_20MHz_t;
((DCI6_0A_20MHz_t *) dci_pdu)->type = 0;
((DCI6_0A_20MHz_t *) dci_pdu)->hopping = hopping;
((DCI6_0A_20MHz_t *) dci_pdu)->rballoc = rballoc;
((DCI6_0A_20MHz_t *) dci_pdu)->narrowband = narrowband;
((DCI6_0A_20MHz_t *) dci_pdu)->mcs = rel13->mcs;
((DCI6_0A_20MHz_t *) dci_pdu)->rep = rel13->pusch_repetition_levels;
((DCI6_0A_20MHz_t *) dci_pdu)->harq_pid = rel13->harq_process;
((DCI6_0A_20MHz_t *) dci_pdu)->ndi = ndi;
((DCI6_0A_20MHz_t *) dci_pdu)->rv_idx = rel13->redudency_version;
((DCI6_0A_20MHz_t *) dci_pdu)->TPC = TPC;
((DCI6_0A_20MHz_t *) dci_pdu)->csi_req = cqi_req;
((DCI6_0A_20MHz_t *) dci_pdu)->srs_req = rel13->srs_request;
((DCI6_0A_20MHz_t *) dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number;
}
//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;
}
}