dci_tools_NB_IoT.c 16.5 KB
Newer Older
Nick Ho's avatar
Nick Ho committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

/*! \file 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
 */
32
//#include "PHY/defs.h"
33 34
#include "PHY/impl_defs_lte_NB_IoT.h"
#include "openair1/PHY/extern_NB_IoT.h"
35 36 37
//#include "PHY/LTE_TRANSPORT/extern_NB_IoT.h"
//#include "SCHED/defs_NB_IoT.h"
/*
Nick Ho's avatar
Nick Ho committed
38
#ifdef DEBUG_DCI_TOOLS
39
#include "PHY/vars_NB_IoT.h"
Nick Ho's avatar
Nick Ho committed
40
#endif
41 42
*/
//#include "assertions.h"
43
//#include "dlsch_tbs_full.h"
44
#include "PHY/LTE_TRANSPORT/dlsch_tbs_full_NB_IoT.h"
Nick Ho's avatar
Nick Ho committed
45 46 47

//#define DEBUG_HARQ

48 49
//#include "LAYER2/MAC/extern_NB_IoT.h"
//#include "LAYER2/MAC/defs_NB_IoT.h"
50
#include "PHY/defs_NB_IoT.h"
51

Nick Ho's avatar
Nick Ho committed
52 53
//#define DEBUG_DCI

54
void add_dci_NB_IoT(DCI_PDU_NB_IoT *DCI_pdu,void *pdu,rnti_t rnti,unsigned char dci_size_bytes,unsigned char aggregation,unsigned char dci_size_bits,unsigned char dci_fmt, uint8_t npdcch_start_symbol)
55
{
56
	//put the pdu
57
  memcpy(&DCI_pdu->dci_alloc[DCI_pdu->Num_dci].dci_pdu[0],pdu,dci_size_bytes);
58
  //configure the dci alloc
59 60 61 62 63
  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].dci_length      = dci_size_bits;
  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].L               = aggregation;
  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].rnti            = rnti;
  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].format          = dci_fmt;
  DCI_pdu->npdcch_start_symbol                         = npdcch_start_symbol;
Nick Ho's avatar
Nick Ho committed
64

65
  DCI_pdu->Num_dci++;
Nick Ho's avatar
Nick Ho committed
66

67 68
  LOG_D(MAC,"add ue specific dci format %d for rnti %x \n",dci_fmt,rnti);
}
Nick Ho's avatar
Nick Ho committed
69 70


71 72 73 74 75 76 77 78
int generate_eNB_ulsch_params_from_dci_NB_IoT(PHY_VARS_eNB_NB_IoT        *eNB,
                                              eNB_rxtx_proc_NB_IoT_t     *proc,
                                              DCI_CONTENT                *DCI_Content,
                                              uint16_t                   rnti,
                                              DCI_format_NB_IoT_t        dci_format,
                                              uint8_t                    UE_id,
                                              uint8_t                    aggregation,
									                            uint8_t                    npdcch_start_symbol)
Nick Ho's avatar
Nick Ho committed
79 80
{

81
  void *ULSCH_DCI_NB_IoT = NULL;
82

83
  eNB->DCI_pdu = (DCI_PDU_NB_IoT*) malloc(sizeof(DCI_PDU_NB_IoT));
Nick Ho's avatar
Nick Ho committed
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106

  /// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits
  uint8_t type;
  /// Subcarrier indication, 6 bits
  uint8_t scind;
  /// Resourse Assignment (RU Assignment), 3 bits
  uint8_t ResAssign;
  /// Modulation and Coding Scheme, 4 bits
  uint8_t mcs;
  /// New Data Indicator, 1 bits
  uint8_t ndi;
  /// Scheduling Delay, 2 bits
  uint8_t Scheddly;
  /// Repetition Number, 3 bits
  uint8_t RepNum;
  /// Redundancy version for HARQ (only use 0 and 2), 1 bits
  uint8_t rv;
  /// DCI subframe repetition Number, 2 bits
  uint8_t DCIRep;
  
  if (dci_format == DCIFormatN0) 
    {
      
107 108 109 110 111 112 113 114 115 116 117
      type        = DCI_Content->DCIN0.type;
      scind       = DCI_Content->DCIN0.scind;
      ResAssign   = DCI_Content->DCIN0.ResAssign;
      mcs         = DCI_Content->DCIN0.mcs;
      ndi         = DCI_Content->DCIN0.ndi;
      Scheddly    = DCI_Content->DCIN0.Scheddly;
      RepNum      = DCI_Content->DCIN0.RepNum;
      rv          = DCI_Content->DCIN0.rv;
      DCIRep      = DCI_Content->DCIN0.DCIRep;

      /*Packed DCI here*/
118 119 120 121 122 123 124 125 126
      ((DCIN0_t *)ULSCH_DCI_NB_IoT)->type      =type;
      ((DCIN0_t *)ULSCH_DCI_NB_IoT)->scind     =scind;
      ((DCIN0_t *)ULSCH_DCI_NB_IoT)->ResAssign =ResAssign;
      ((DCIN0_t *)ULSCH_DCI_NB_IoT)->Scheddly  =Scheddly;
      ((DCIN0_t *)ULSCH_DCI_NB_IoT)->mcs       =mcs;
      ((DCIN0_t *)ULSCH_DCI_NB_IoT)->rv        =rv;
      ((DCIN0_t *)ULSCH_DCI_NB_IoT)->RepNum    =RepNum;
      ((DCIN0_t *)ULSCH_DCI_NB_IoT)->ndi       =ndi;
      ((DCIN0_t *)ULSCH_DCI_NB_IoT)->DCIRep    =DCIRep;
127 128


129
      add_dci_NB_IoT(eNB->DCI_pdu,ULSCH_DCI_NB_IoT,rnti,sizeof(DCIN0_t),aggregation,sizeof_DCIN0_t,DCIFormatN0, npdcch_start_symbol);
Nick Ho's avatar
Nick Ho committed
130 131

      // use this value to configure PHY both harq_processes and resource mapping.
132 133


Nick Ho's avatar
Nick Ho committed
134 135 136
      
      return(0);
    } 
137 138
  else 
    {
Nick Ho's avatar
Nick Ho committed
139 140
        LOG_E(PHY,"generate_eNB_ulsch_params_from_dci, Illegal dci_format %d\n",dci_format);
        return(-1);
141
    }
Nick Ho's avatar
Nick Ho committed
142 143
}

144
//map the Isf (DCI param) to the number of subframes (Nsf)
145
int resource_to_subframe[8] = {1,2,3,4,5,6,8,10};
146

147 148 149 150 151 152 153 154 155 156
int generate_eNB_dlsch_params_from_dci_NB_IoT(PHY_VARS_eNB_NB_IoT      *eNB,
                                              int                      frame,
                                              uint8_t                  subframe,
                                              DCI_CONTENT              *DCI_Content,
                                              uint16_t                 rnti,
                                              DCI_format_NB_IoT_t      dci_format,
                                              NB_IoT_eNB_NDLSCH_t      *ndlsch,
                                              NB_IoT_DL_FRAME_PARMS    *frame_parms,
                                              uint8_t                  aggregation,
									                            uint8_t                  npdcch_start_symbol)
Nick Ho's avatar
Nick Ho committed
157 158
{

159 160 161
  NB_IoT_DL_eNB_HARQ_t  *ndlsch_harq      = ndlsch->harq_process;
  void                  *DLSCH_DCI_NB_IoT = NULL;

162
  eNB->DCI_pdu = (DCI_PDU_NB_IoT*) malloc(sizeof(DCI_PDU_NB_IoT));
Nick Ho's avatar
Nick Ho committed
163 164


165

166
  //N1 parameters
Nick Ho's avatar
Nick Ho committed
167

168
  /// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits
169
  uint8_t type = 0;
170
  //NPDCCH order indicator (set to 0),1 bits
171
  uint8_t orderIndicator = 0;
172
  // Scheduling Delay, 3 bits
173
  uint8_t Sched_delay = 0;
174
  // Resourse Assignment (RU Assignment), 3 bits
175
  uint8_t ResAssign = 0;//Isf
176
  // Modulation and Coding Scheme, 4 bits
177
  uint8_t mcs = 0;
178
  // Repetition Number, 4 bits
179
  uint8_t RepNum = 0;
180
  // DCI subframe repetition Number, 2 bits
181
  uint8_t DCIRep = 0;
182
  // New Data Indicator,1 bits
183
  uint8_t ndi = 0;
184
  // HARQ-ACK resource,4 bits
185
  uint8_t HARQackRes = 0;
Nick Ho's avatar
Nick Ho committed
186

187
  //N2 parameters
Nick Ho's avatar
Nick Ho committed
188

189
  //Direct indication information, 8 bits
190
  uint8_t directIndInf= 0;
191
  // Reserved information bits, 6 bits
192
  uint8_t resInfoBits =0;
Nick Ho's avatar
Nick Ho committed
193

194
  //   printf("Generate eNB DCI, format %d, rnti %x (pdu %p)\n",dci_format,rnti,dci_pdu);
Nick Ho's avatar
Nick Ho committed
195

196
  switch (dci_format) {
Nick Ho's avatar
Nick Ho committed
197

198
  // Impossible to have a DCI N0, we have condition before
199 200
  case DCIFormatN0:
    return(-1);
Nick Ho's avatar
Nick Ho committed
201 202
    break;

203
  case DCIFormatN1_RAR:  // This is DLSCH allocation for control traffic (no NDI and no ACK/NACK resource for RAR DCI)
Nick Ho's avatar
Nick Ho committed
204 205


206
	/*Packed DCI here-------------------------------------------*/
207 208
    type               = DCI_Content->DCIN1_RAR.type;
    orderIndicator     = DCI_Content->DCIN1_RAR.orderIndicator; 
209
    Sched_delay        = DCI_Content->DCIN1_RAR.Scheddly;
210 211 212
    ResAssign          = DCI_Content->DCIN1_RAR.ResAssign; 
    mcs                = DCI_Content->DCIN1_RAR.mcs; 
    RepNum             = DCI_Content->DCIN1_RAR.RepNum; 
213 214
    ndi                = DCI_Content->DCIN1_RAR.ndi;
    HARQackRes         = DCI_Content->DCIN1_RAR.HARQackRes; 
215 216
    DCIRep             = DCI_Content->DCIN1_RAR.DCIRep;
    
217
    //DCI pdu content
218 219 220 221 222 223 224 225 226
    ((DCIN1_RAR_t *)DLSCH_DCI_NB_IoT)->type           =type;
    ((DCIN1_RAR_t *)DLSCH_DCI_NB_IoT)->orderIndicator =orderIndicator;
    ((DCIN1_RAR_t *)DLSCH_DCI_NB_IoT)->Scheddly       =Sched_delay;
    ((DCIN1_RAR_t *)DLSCH_DCI_NB_IoT)->ResAssign      =ResAssign;
    ((DCIN1_RAR_t *)DLSCH_DCI_NB_IoT)->mcs            =mcs;
    ((DCIN1_RAR_t *)DLSCH_DCI_NB_IoT)->RepNum         =RepNum;
    ((DCIN1_RAR_t *)DLSCH_DCI_NB_IoT)->ndi            =ndi;
    ((DCIN1_RAR_t *)DLSCH_DCI_NB_IoT)->HARQackRes     =HARQackRes;
    ((DCIN1_RAR_t *)DLSCH_DCI_NB_IoT)->DCIRep         =DCIRep;
Nick Ho's avatar
Nick Ho committed
227 228


229
    add_dci_NB_IoT(eNB->DCI_pdu,DLSCH_DCI_NB_IoT,rnti,sizeof(DCIN1_RAR_t),aggregation,sizeof_DCIN1_RAR_t,DCIFormatN1_RAR, npdcch_start_symbol);
230 231 232 233 234


    /*Now configure the ndlsch structure*/

    ndlsch->subframe_tx[subframe] = 1; // check if it's OK
235 236
    ndlsch->rnti = rnti; //we store the RNTI (e.g. for RNTI will be used later)
    ndlsch->active = 0; //will be activated by the corresponding NDSLCH pdu
Nick Ho's avatar
Nick Ho committed
237

238
    // use this value to configure PHY both harq_processes and resource mapping.
239 240 241
    ndlsch_harq->scheduling_delay         = Sched_delay;
    ndlsch_harq->resource_assignment      = resource_to_subframe[ResAssign];  //from Isf of DCI to the number of subframe
    ndlsch_harq->repetition_number        = RepNum;
242
    ndlsch_harq->dci_subframe_repetitions = DCIRep;
243
    ndlsch_harq->modulation               = 2; //QPSK
244
    if(ndlsch_harq->round == 0) //this should be set from initialization (init-lte)
245 246 247

    	ndlsch_harq->status = ACTIVE_NB_IoT;
      ndlsch_harq->mcs    = mcs;
248 249 250 251 252 253 254

    /*
     * TS 36.213 ch 16.4.1.5
     * ITBS is always set equivalent to IMCS for data
     * ISF = ResAssign
     */

255 256
      ndlsch_harq->TBS      = TBStable_NB_IoT[mcs][ResAssign];
      ndlsch_harq->subframe = subframe;
257 258 259 260 261 262 263 264 265 266 267 268 269 270

    //ndlsch_harq->B; we don-t have now my is given when we receive the dlsch data
    //ndlsch->error_treshold
    //ndlsch->G??
    //ndlsc->nsoft?? //set in new_eNB_dlsch (initialization)
    //ndlsch-> sqrt_rho_a?? set in dlsch_modulation
    //ndlsch-> sqrt_rho_b??? set in dlsch_modulation

    //set in new_eNB_dlsch (initialization)
    /*
     * Mlimit
     * nsoft
     * round
     */
Nick Ho's avatar
Nick Ho committed
271 272


273
    break;
Nick Ho's avatar
Nick Ho committed
274

275
  case DCIFormatN1: // for user data
276
    
Nick Ho's avatar
Nick Ho committed
277

278 279
    type               = DCI_Content->DCIN1.type;
    orderIndicator     = DCI_Content->DCIN1.orderIndicator; 
280
    Sched_delay        = DCI_Content->DCIN1.Scheddly;
281 282 283 284 285 286 287 288
    ResAssign          = DCI_Content->DCIN1.ResAssign; 
    mcs                = DCI_Content->DCIN1.mcs; 
    RepNum             = DCI_Content->DCIN1.RepNum; 
    ndi                = DCI_Content->DCIN1.ndi;
    HARQackRes         = DCI_Content->DCIN1.HARQackRes; 
    DCIRep             = DCI_Content->DCIN1.DCIRep;
    
    /*Packed DCI here*/
289 290 291 292 293 294 295 296 297
    ((DCIN1_t *)DLSCH_DCI_NB_IoT)->type           =type;
    ((DCIN1_t *)DLSCH_DCI_NB_IoT)->orderIndicator =orderIndicator;
    ((DCIN1_t *)DLSCH_DCI_NB_IoT)->Scheddly       =Sched_delay;
    ((DCIN1_t *)DLSCH_DCI_NB_IoT)->ResAssign      =ResAssign;
    ((DCIN1_t *)DLSCH_DCI_NB_IoT)->mcs            =mcs;
    ((DCIN1_t *)DLSCH_DCI_NB_IoT)->RepNum         =RepNum;
    ((DCIN1_t *)DLSCH_DCI_NB_IoT)->ndi            =ndi;
    ((DCIN1_t *)DLSCH_DCI_NB_IoT)->HARQackRes     =HARQackRes;
    ((DCIN1_t *)DLSCH_DCI_NB_IoT)->DCIRep         =DCIRep;
Nick Ho's avatar
Nick Ho committed
298 299


300
    add_dci_NB_IoT(eNB->DCI_pdu,DLSCH_DCI_NB_IoT,rnti,sizeof(DCIN1_t),aggregation,sizeof_DCIN1_t,DCIFormatN1,npdcch_start_symbol);
Nick Ho's avatar
Nick Ho committed
301

302 303 304
    /*Now configure the ndlsch structure*/

    ndlsch->subframe_tx[subframe] = 1; // check if it's OK
305 306
    ndlsch->rnti                  = rnti; //we store the RNTI (e.g. for RNTI will be used later)
    ndlsch->active                = 0;//will be activated by the corresponding NDSLCH pdu
Nick Ho's avatar
Nick Ho committed
307

308
    // use this value to configure PHY both harq_processes and resource mapping.
309 310 311
        ndlsch_harq->scheduling_delay         = Sched_delay;
        ndlsch_harq->resource_assignment      = resource_to_subframe[ResAssign]; //from Isf of DCI to the number of subframe
        ndlsch_harq->repetition_number        = RepNum;
312
        ndlsch_harq->dci_subframe_repetitions = DCIRep;
313
        ndlsch_harq->modulation               = 2; //QPSK
314
        if(ndlsch_harq->round == 0){ //this should be set from initialization (init-lte)
315 316 317 318

        	ndlsch_harq->status  = ACTIVE_NB_IoT;
        	ndlsch_harq->mcs     = mcs;
        	ndlsch_harq->TBS     = TBStable_NB_IoT[mcs][ResAssign]; // this table should be rewritten for nb-iot
319
        }
320
        ndlsch_harq->frame    = frame;
321 322 323 324 325 326 327
        ndlsch_harq->subframe = subframe;



    break;

  case DCIFormatN2_Ind: //MP: for the moment is not implemented
Nick Ho's avatar
Nick Ho committed
328

329 330 331
    type               = DCI_Content->DCIN2_Ind.type;
    directIndInf       = DCI_Content->DCIN2_Ind.directIndInf; 
    resInfoBits        = DCI_Content->DCIN2_Ind.resInfoBits; 
Nick Ho's avatar
Nick Ho committed
332

333
    /*Packed DCI here*/
334 335 336
    ((DCIN2_Ind_t *)DLSCH_DCI_NB_IoT)->type           =type;
    ((DCIN2_Ind_t *)DLSCH_DCI_NB_IoT)->directIndInf   =directIndInf;
    ((DCIN2_Ind_t *)DLSCH_DCI_NB_IoT)->resInfoBits    =resInfoBits;
Nick Ho's avatar
Nick Ho committed
337 338


339
    add_dci_NB_IoT(eNB->DCI_pdu,DLSCH_DCI_NB_IoT,rnti,sizeof(DCIN2_Ind_t),aggregation,sizeof_DCIN2_Ind_t,DCIFormatN2_Ind,npdcch_start_symbol);
Nick Ho's avatar
Nick Ho committed
340

341
    // use this value to configure PHY both harq_processes and resource mapping.
342
    break;
Nick Ho's avatar
Nick Ho committed
343

344
    
345
  case DCIFormatN2_Pag:  //MP: for the moment is not implemented
Nick Ho's avatar
Nick Ho committed
346

347 348 349 350 351
    type               = DCI_Content->DCIN2_Pag.type;
    ResAssign          = DCI_Content->DCIN2_Pag.ResAssign; 
    mcs                = DCI_Content->DCIN2_Pag.mcs; 
    RepNum             = DCI_Content->DCIN2_Pag.RepNum; 
    DCIRep             = DCI_Content->DCIN2_Pag.DCIRep; 
Nick Ho's avatar
Nick Ho committed
352

353
    /*Packed DCI here*/
354 355 356 357 358
    ((DCIN2_Pag_t *)DLSCH_DCI_NB_IoT)->type      =type;
    ((DCIN2_Pag_t *)DLSCH_DCI_NB_IoT)->ResAssign =ResAssign;
    ((DCIN2_Pag_t *)DLSCH_DCI_NB_IoT)->mcs       =mcs;
    ((DCIN2_Pag_t *)DLSCH_DCI_NB_IoT)->RepNum    =RepNum;
    ((DCIN2_Pag_t *)DLSCH_DCI_NB_IoT)->DCIRep    =DCIRep;
Nick Ho's avatar
Nick Ho committed
359 360


361
    add_dci_NB_IoT(eNB->DCI_pdu,DLSCH_DCI_NB_IoT,rnti,sizeof(DCIN2_Pag_t),aggregation,sizeof_DCIN2_Pag_t,DCIFormatN2_Pag,npdcch_start_symbol);
Nick Ho's avatar
Nick Ho committed
362

363
    // use this value to configure PHY both harq_processes and resource mapping.
364
    break;
Nick Ho's avatar
Nick Ho committed
365 366 367 368 369 370 371 372 373 374 375 376 377


  default:
    LOG_E(PHY,"Unknown DCI format\n");
    return(-1);
    break;
  }

  // compute DL power control parameters



  return(0);
378
}
379 380 381 382


uint8_t subframe2harq_pid_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t subframe)
{
383
  //MAC_xface_NB_IoT *mac_xface_NB_IoT; //test_xface
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427
  /*
    #ifdef DEBUG_DCI
    if (frame_parms->frame_type == TDD)
    printf("dci_tools.c: subframe2_harq_pid, subframe %d for TDD configuration %d\n",subframe,frame_parms->tdd_config);
    else
    printf("dci_tools.c: subframe2_harq_pid, subframe %d for FDD \n",subframe);
    #endif
  */

  uint8_t ret = 255;

  if (frame_parms->frame_type == FDD_NB_IoT) {
    ret = (((frame<<1)+subframe)&7);
  } else {

    switch (frame_parms->tdd_config) {

    case 1:
      if ((subframe==2) ||
          (subframe==3) ||
          (subframe==7) ||
          (subframe==8))
        switch (subframe) {
        case 2:
        case 3:
          ret = (subframe-2);
          break;

        case 7:
        case 8:
          ret = (subframe-5);
          break;

        default:
          LOG_E(PHY,"subframe2_harq_pid_NB_IoT, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
          ret = (255);
          break;
        }

      break;

    case 2:
      if ((subframe!=2) && (subframe!=7)) {
        LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
428
        //mac_xface_NB_IoT->macphy_exit("subframe2_harq_pid_NB_IoT, Illegal subframe");
429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470
        ret = (255);
      }

      ret = (subframe/7);
      break;

    case 3:
      if ((subframe<2) || (subframe>4)) {
        LOG_E(PHY,"subframe2_harq_pid_NB_IoT, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
        ret = (255);
      }

      ret = (subframe-2);
      break;

    case 4:
      if ((subframe<2) || (subframe>3)) {
        LOG_E(PHY,"subframe2_harq_pid_NB_IoT, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
        ret = (255);
      }

      ret = (subframe-2);
      break;

    case 5:
      if (subframe!=2) {
        LOG_E(PHY,"subframe2_harq_pid_NB_IoT, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
        ret = (255);
      }

      ret = (subframe-2);
      break;

    default:
      LOG_E(PHY,"subframe2_harq_pid_NB_IoT, Unsupported TDD mode %d\n",frame_parms->tdd_config);
      ret = (255);

    }
  }

  if (ret == 255) {
    LOG_E(PHY, "invalid harq_pid(%d) at SFN/SF = %d/%d\n", ret, frame, subframe);
471
    //mac_xface_NB_IoT->macphy_exit("invalid harq_pid");
472 473 474 475
  }
  return ret;
}