dci_tools.c 351 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * 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
 */

22
/*! \file PHY/LTE_TRANSPORT/dci_tools.c
23
 * \brief PHY Support routines (eNB/UE) for filling PDSCH/PUSCH/DLSCH/ULSCH data structures based on DCI PDUs generated by eNB MAC scheduler.
24 25 26 27 28 29 30 31 32 33 34 35 36 37
 * \author R. Knopp
 * \date 2011
 * \version 0.1
 * \company Eurecom
 * \email: knopp@eurecom.fr
 * \note
 * \warning
 */
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "SCHED/defs.h"
#ifdef DEBUG_DCI_TOOLS
#include "PHY/vars.h"
#endif
winckel's avatar
winckel committed
38
#include "assertions.h"
39

40

41
//#define DEBUG_HARQ
42

43 44 45
#include "LAYER2/MAC/extern.h"
#include "LAYER2/MAC/defs.h"

46 47
//#define DEBUG_DCI

48 49 50
uint32_t localRIV2alloc_LUT6[32];
uint32_t distRIV2alloc_even_LUT6[32];
uint32_t distRIV2alloc_odd_LUT6[32];
51 52 53 54
uint16_t RIV2nb_rb_LUT6[32];
uint16_t RIV2first_rb_LUT6[32];
uint16_t RIV_max6=0;

55 56 57
uint32_t localRIV2alloc_LUT25[512];
uint32_t distRIV2alloc_even_LUT25[512];
uint32_t distRIV2alloc_odd_LUT25[512];
58 59 60 61 62
uint16_t RIV2nb_rb_LUT25[512];
uint16_t RIV2first_rb_LUT25[512];
uint16_t RIV_max25=0;


63 64 65 66 67 68 69 70 71 72
uint32_t localRIV2alloc_LUT50_0[1600];
uint32_t localRIV2alloc_LUT50_1[1600];
uint32_t distRIV2alloc_gap0_even_LUT50_0[1600];
uint32_t distRIV2alloc_gap0_odd_LUT50_0[1600];
uint32_t distRIV2alloc_gap0_even_LUT50_1[1600];
uint32_t distRIV2alloc_gap0_odd_LUT50_1[1600];
uint32_t distRIV2alloc_gap1_even_LUT50_0[1600];
uint32_t distRIV2alloc_gap1_odd_LUT50_0[1600];
uint32_t distRIV2alloc_gap1_even_LUT50_1[1600];
uint32_t distRIV2alloc_gap1_odd_LUT50_1[1600];
73 74 75 76
uint16_t RIV2nb_rb_LUT50[1600];
uint16_t RIV2first_rb_LUT50[1600];
uint16_t RIV_max50=0;

77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
uint32_t localRIV2alloc_LUT100_0[6000];
uint32_t localRIV2alloc_LUT100_1[6000];
uint32_t localRIV2alloc_LUT100_2[6000];
uint32_t localRIV2alloc_LUT100_3[6000];
uint32_t distRIV2alloc_gap0_even_LUT100_0[6000];
uint32_t distRIV2alloc_gap0_odd_LUT100_0[6000];
uint32_t distRIV2alloc_gap0_even_LUT100_1[6000];
uint32_t distRIV2alloc_gap0_odd_LUT100_1[6000];
uint32_t distRIV2alloc_gap0_even_LUT100_2[6000];
uint32_t distRIV2alloc_gap0_odd_LUT100_2[6000];
uint32_t distRIV2alloc_gap0_even_LUT100_3[6000];
uint32_t distRIV2alloc_gap0_odd_LUT100_3[6000];
uint32_t distRIV2alloc_gap1_even_LUT100_0[6000];
uint32_t distRIV2alloc_gap1_odd_LUT100_0[6000];
uint32_t distRIV2alloc_gap1_even_LUT100_1[6000];
uint32_t distRIV2alloc_gap1_odd_LUT100_1[6000];
uint32_t distRIV2alloc_gap1_even_LUT100_2[6000];
uint32_t distRIV2alloc_gap1_odd_LUT100_2[6000];
uint32_t distRIV2alloc_gap1_even_LUT100_3[6000];
uint32_t distRIV2alloc_gap1_odd_LUT100_3[6000];
97 98 99 100 101 102 103 104 105
uint16_t RIV2nb_rb_LUT100[6000];
uint16_t RIV2first_rb_LUT100[6000];
uint16_t RIV_max100=0;


extern uint32_t current_dlsch_cqi;

// Table 8.6.3-3 36.213
uint16_t beta_cqi[16] = {0,   //reserved
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
                         0,   //reserved
                         9,   //1.125
                         10,  //1.250
                         11,  //1.375
                         13,  //1.625
                         14,  //1.750
                         16,  //2.000
                         18,  //2.250
                         20,  //2.500
                         23,  //2.875
                         25,  //3.125
                         28,  //3.500
                         32,  //4.000
                         40,  //5.000
                         50
                        }; //6.250
122 123 124

// Table 8.6.3-2 36.213
uint16_t beta_ri[16] = {10,   //1.250
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
                        13,   //1.625
                        16,   //2.000
                        20,   //2.500
                        25,   //3.125
                        32,   //4.000
                        40,   //5.000
                        50,   //6.250
                        64,   //8.000
                        80,   //10.000
                        101,  //12.625
                        127,  //15.875
                        160,  //20.000
                        0,    //reserved
                        0,    //reserved
                        0
                       };   //reserved
141 142 143

// Table 8.6.3-2 36.213
uint16_t beta_ack[16] = {16,  //2.000
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
                         20,  //2.500
                         25,  //3.125
                         32,  //4.000
                         40,  //5.000
                         50,  //6.250
                         64,  //8.000
                         80,  //10.000
                         101, //12.625
                         127, //15.875
                         160, //20.000
                         248, //31.000
                         400, //50.000
                         640, //80.000
                         808
                        };//126.00
159 160 161 162 163

int8_t delta_PUSCH_abs[4] = {-4,-1,1,4};
int8_t delta_PUSCH_acc[4] = {-1,0,1,3};

int8_t *delta_PUCCH_lut = delta_PUSCH_acc;
164 165 166

void conv_rballoc(uint8_t ra_header,uint32_t rb_alloc,uint32_t N_RB_DL,uint32_t *rb_alloc2)
{
167 168

  uint32_t i,shift,subset;
169 170 171 172
  rb_alloc2[0] = 0;
  rb_alloc2[1] = 0;
  rb_alloc2[2] = 0;
  rb_alloc2[3] = 0;
173 174 175 176 177 178 179 180 181 182 183

  //  printf("N_RB_DL %d, ra_header %d, rb_alloc %x\n",N_RB_DL,ra_header,rb_alloc);

  switch (N_RB_DL) {

  case 6:
    rb_alloc2[0] = rb_alloc&0x3f;
    break;

  case 25:
    if (ra_header == 0) {// Type 0 Allocation
184 185 186 187 188 189

      for (i=12; i>0; i--) {
        if ((rb_alloc&(1<<i)) != 0)
          rb_alloc2[0] |= (3<<((2*(12-i))));

        //      printf("rb_alloc2 (type 0) %x\n",rb_alloc2);
190
      }
191

192
      if ((rb_alloc&1) != 0)
193 194
        rb_alloc2[0] |= (1<<24);
    } else {
195 196
      subset = rb_alloc&1;
      shift  = (rb_alloc>>1)&1;
197 198 199 200 201 202

      for (i=0; i<11; i++) {
        if ((rb_alloc&(1<<(i+2))) != 0)
          rb_alloc2[0] |= (1<<(2*i));

        //printf("rb_alloc2 (type 1) %x\n",rb_alloc2);
203
      }
204

205
      if ((shift == 0) && (subset == 1))
206
        rb_alloc2[0]<<=1;
207
      else if ((shift == 1) && (subset == 0))
208
        rb_alloc2[0]<<=4;
209
      else if ((shift == 1) && (subset == 1))
210
        rb_alloc2[0]<<=3;
211
    }
212

213
    break;
214

215 216 217 218 219 220 221
  case 50:
    if (ra_header == 0) {// Type 0 Allocation

      for (i=16; i>0; i--) {
        if ((rb_alloc&(1<<i)) != 0)
          rb_alloc2[(3*(16-i))>>5] |= (7<<((3*(16-i))%32));
      }
222

223
      /*
224 225 226 227
      for (i=1;i<=16;i++) {
        if ((rb_alloc&(1<<(16-i))) != 0)
      rb_alloc2[(3*i)>>5] |= (7<<((3*i)%32));
      }
228
      */
229
      // bit mask across
230 231
      if ((rb_alloc2[0]>>31)==1)
        rb_alloc2[1] |= 1;
232

233
      if ((rb_alloc&1) != 0)
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
        rb_alloc2[1] |= (3<<16);

      /*
        for (i=0;i<16;i++) {
        if (((rb_alloc>>(16-i))&1) != 0)
        rb_alloc2[(3*i)>>5] |= (7<<((3*i)%32));
        if ((i==10)&&((rb_alloc&(1<<6))!=0))
        rb_alloc2[1] = 1;
        //  printf("rb_alloc2[%d] (type 0) %x ((%x>>%d)&1=%d)\n",(3*i)>>5,rb_alloc2[(3*i)>>5],rb_alloc,i,(rb_alloc>>i)&1);

        }
        // fill in 2 from last bit instead of 3
        if ((rb_alloc&1) != 0)
        rb_alloc2[1] |= (3<<i);
        //    printf("rb_alloc2[%d] (type 0) %x ((%x>>%d)&1=%d)\n",(3*i)>>5,rb_alloc2[(3*i)>>5],rb_alloc,i,(rb_alloc>>i)&1);
        */
250
      //      printf("rb_alloc[1]=%x,rb_alloc[0]=%x\n",rb_alloc2[1],rb_alloc2[0]);
251
    } else {
252 253
      LOG_E(PHY,"resource type 1 not supported for  N_RB_DL=50\n");
      //      mac_xface->macphy_exit("resource type 1 not supported for  N_RB_DL=100\n");
254
      /*
255 256 257 258 259 260 261 262 263 264 265 266 267
      subset = rb_alloc&1;
      shift  = (rb_alloc>>1)&1;
      for (i=0;i<11;i++) {
      if ((rb_alloc&(1<<(i+2))) != 0)
      rb_alloc2 |= (1<<(2*i));
      //      printf("rb_alloc2 (type 1) %x\n",rb_alloc2);
      }
      if ((shift == 0) && (subset == 1))
      rb_alloc2<<=1;
      else if ((shift == 1) && (subset == 0))
      rb_alloc2<<=4;
      else if ((shift == 1) && (subset == 1))
      rb_alloc2<<=3;
268 269
      */
    }
270

271 272 273 274
    break;

  case 100:
    if (ra_header == 0) {// Type 0 Allocation
275 276 277 278 279
      for (i=0; i<25; i++) {
        if ((rb_alloc&(1<<(24-i))) != 0)
          rb_alloc2[(4*i)>>5] |= (0xf<<((4*i)%32));

        //  printf("rb_alloc2[%d] (type 0) %x (%d)\n",(4*i)>>5,rb_alloc2[(4*i)>>5],rb_alloc&(1<<i));
280
      }
281
    } else {
282
      LOG_E(PHY,"resource type 1 not supported for  N_RB_DL=100\n");
283
      //      mac_xface->macphy_exit("resource type 1 not supported for  N_RB_DL=100\n");
284
      /*
285 286 287 288 289 290 291 292 293 294 295 296 297
      subset = rb_alloc&1;
      shift  = (rb_alloc>>1)&1;
      for (i=0;i<11;i++) {
      if ((rb_alloc&(1<<(i+2))) != 0)
      rb_alloc2 |= (1<<(2*i));
      //      printf("rb_alloc2 (type 1) %x\n",rb_alloc2);
      }
      if ((shift == 0) && (subset == 1))
      rb_alloc2<<=1;
      else if ((shift == 1) && (subset == 0))
      rb_alloc2<<=4;
      else if ((shift == 1) && (subset == 1))
      rb_alloc2<<=3;
298 299
      */
    }
300

301 302 303
    break;

  default:
winckel's avatar
winckel committed
304 305
    LOG_E(PHY,"Invalid N_RB_DL %d\n", N_RB_DL);
    DevParam (N_RB_DL, 0, 0);
306 307 308 309 310 311 312
    break;
  }

}



313 314
uint32_t conv_nprb(uint8_t ra_header,uint32_t rb_alloc,int N_RB_DL)
{
315 316 317 318 319

  uint32_t nprb=0,i;

  switch (N_RB_DL) {
  case 6:
320
    for (i=0; i<6; i++) {
321
      if ((rb_alloc&(1<<i)) != 0)
322
        nprb += 1;
323
    }
324

325
    break;
326

327 328
  case 25:
    if (ra_header == 0) {// Type 0 Allocation
329 330 331 332

      for (i=12; i>0; i--) {
        if ((rb_alloc&(1<<i)) != 0)
          nprb += 2;
333
      }
334

335
      if ((rb_alloc&1) != 0)
336 337 338 339 340
        nprb += 1;
    } else {
      for (i=0; i<11; i++) {
        if ((rb_alloc&(1<<(i+2))) != 0)
          nprb += 1;
341 342
      }
    }
343

344
    break;
345

346 347
  case 50:
    if (ra_header == 0) {// Type 0 Allocation
348 349 350 351

      for (i=0; i<16; i++) {
        if ((rb_alloc&(1<<(16-i))) != 0)
          nprb += 3;
352
      }
353

354
      if ((rb_alloc&1) != 0)
355
        nprb += 2;
356

357 358 359 360
    } else {
      for (i=0; i<17; i++) {
        if ((rb_alloc&(1<<(i+2))) != 0)
          nprb += 1;
361 362
      }
    }
363

364
    break;
365

366 367
  case 100:
    if (ra_header == 0) {// Type 0 Allocation
368 369 370 371

      for (i=0; i<25; i++) {
        if ((rb_alloc&(1<<(24-i))) != 0)
          nprb += 4;
372
      }
373 374 375 376
    } else {
      for (i=0; i<25; i++) {
        if ((rb_alloc&(1<<(i+2))) != 0)
          nprb += 1;
377 378
      }
    }
379

380
    break;
winckel's avatar
winckel committed
381 382 383 384 385

  default:
    LOG_E(PHY,"Invalide N_RB_DL %d\n", N_RB_DL);
    DevParam (N_RB_DL, 0, 0);
    break;
386 387 388 389 390
  }

  return(nprb);
}

391 392
uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs)
{
393

394
  uint16_t RIV;
395

396 397 398 399
  if (Lcrbs<=(1+(N_RB_DL>>1)))
    RIV = (N_RB_DL*(Lcrbs-1)) + RBstart;
  else
    RIV = (N_RB_DL*(N_RB_DL+1-Lcrbs)) + (N_RB_DL-1-RBstart);
400

401
  return(RIV);
402 403
}

404
// Convert a DCI Format 1C RIV to a Format 1A RIV
405
// This extracts the start and length in PRBs from the 1C rballoc and
406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448
// recomputes the RIV as if it were the 1A rballoc

uint32_t conv_1C_RIV(int32_t rballoc,uint32_t N_RB_DL) {

  int NpDLVRB,N_RB_step,LpCRBsm1,RBpstart;

  switch (N_RB_DL) {

  case 6: // N_RB_step = 2, NDLVRB = 6, NpDLVRB = 3
    NpDLVRB   = 3;
    N_RB_step = 2;
    break;
  case 25: // N_RB_step = 2, NDLVRB = 24, NpDLVRB = 12
    NpDLVRB   = 12;
    N_RB_step = 2;
    break;
  case 50: // N_RB_step = 4, NDLVRB = 46, NpDLVRB = 11
    NpDLVRB   = 11;
    N_RB_step = 4;
    break;
  case 100: // N_RB_step = 4, NDLVRB = 96, NpDLVRB = 24
    NpDLVRB   = 24;
    N_RB_step = 4;
    break;
  default:
    NpDLVRB   = 24;
    N_RB_step = 4;
    break;
  }

  // This is the 1C part from 7.1.6.3 in 36.213
  LpCRBsm1 = rballoc/NpDLVRB;
  //  printf("LpCRBs = %d\n",LpCRBsm1+1);

  if (LpCRBsm1 <= (NpDLVRB/2)) {
    RBpstart = rballoc % NpDLVRB;
  }
  else {
    LpCRBsm1 = NpDLVRB-LpCRBsm1;
    RBpstart = NpDLVRB-(rballoc%NpDLVRB);
  }
  //  printf("RBpstart %d\n",RBpstart);
  return(computeRIV(N_RB_DL,N_RB_step*RBpstart,N_RB_step*(LpCRBsm1+1)));
449

450 451
}

452
uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) {
453 454 455 456

  int offset;

  switch (N_RB_DL) {
457

458 459 460
  case 6:
  // N_RB_DL = tildeN_RB_DL = 6
  // Ngap = 4 , P=1, Nrow = 2, Nnull = 2
461

462 463 464 465 466 467 468 469 470 471
    switch (vrb) {
    case 0:  // even: 0->0, 1->2, odd: 0->3, 1->5
    case 1:
      return ((3*odd_slot) + 2*(vrb&3))%6;
      break;
    case 2:  // even: 2->3, 3->5, odd: 2->0, 3->2
    case 3:
      return ((3*odd_slot) + 2*(vrb&3) + 5)%6;
      break;
    case 4:  // even: 4->1, odd: 4->4
472
      return ((3*odd_slot) + 1)%6;
473 474 475 476 477
    case 5:  // even: 5->4, odd: 5->1
      return ((3*odd_slot) + 4)%6;
      break;
    }
    break;
478

479 480 481
  case 15:
    if (vrb<12) {
      if ((vrb&3) < 2)     // even: 0->0, 1->4, 4->1, 5->5, 8->2, 9->6 odd: 0->7, 1->11
482
  return(((7*odd_slot) + 4*(vrb&3) + (vrb>>2))%14) + 14*(vrb/14);
483
      else if (vrb < 12) // even: 2->7, 3->11, 6->8, 7->12, 10->9, 11->13
484
  return (((7*odd_slot) + 4*(vrb&3) + (vrb>>2) +13 )%14) + 14*(vrb/14);
485 486 487 488 489 490 491
    }
    if (vrb==12)
      return (3+(7*odd_slot)) % 14;
    if (vrb==13)
      return (10+(7*odd_slot)) % 14;
    return 14;
    break;
492

493 494 495
  case 25:
    return (((12*odd_slot) + 6*(vrb&3) + (vrb>>2))%24) + 24*(vrb/24);
    break;
496

497 498 499 500
  case 50: // P=3
    if (Ngap==0) {
      // Nrow=12,Nnull=2,NVRBDL=46,Ngap1= 27
      if (vrb>=23)
501
  offset=4;
502
      else
503
  offset=0;
504
      if (vrb<44) {
505 506 507 508
  if ((vrb&3)>=2)
    return offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2) + 45)%46;
  else
    return offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2))%46;
509 510
      }
      if (vrb==44)  // even: 44->11, odd: 45->34
511
  return offset+((23*odd_slot) + 22-12+1);
512
      if (vrb==45)  // even: 45->10, odd: 45->33
513
  return offset+((23*odd_slot) + 22+12);
514
      if (vrb==46)
515
  return offset+46+((23*odd_slot) + 23-12+1) % 46;
516
      if (vrb==47)
517
  return offset+46+((23*odd_slot) + 23+12) % 46;
518
      if (vrb==48)
519
  return offset+46+((23*odd_slot) + 23-12+1) % 46;
520
      if (vrb==49)
521
  return offset+46+((23*odd_slot) + 23+12) % 46;
522 523 524 525
    }
    else {
      // Nrow=6,Nnull=6,NVRBDL=18,Ngap1= 27
      if (vrb>=9)
526
  offset=18;
527
      else
528
  offset=0;
529

530
      if (vrb<12) {
531 532 533 534
  if ((vrb&3)>=2)
    return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2) + 17)%18;
  else
    return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2))%18;
535 536
      }
      else {
537
  return offset+((9*odd_slot) + 12*(vrb&1)+(vrb>>1) )%18 + 18*(vrb/18);
538 539 540 541 542 543
      }
    }
    break;
  case 75:
    // Ngap1 = 32, NVRBRL=64, P=4, Nrow= 16, Nnull=0
    if (Ngap ==0) {
544
      return ((32*odd_slot) + 16*(vrb&3) + (vrb>>2))%64 + (vrb/64);
545 546
    } else {
      // Ngap2 = 16, NVRBDL=32, Nrow=8, Nnull=0
547
      return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32);
548 549 550 551 552
    }
    break;
  case 100:
    // Ngap1 = 48, NVRBDL=96, Nrow=24, Nnull=0
    if (Ngap ==0) {
553
      return ((48*odd_slot) + 24*(vrb&3) + (vrb>>2))%96 + (vrb/96);
554 555
    } else {
      // Ngap2 = 16, NVRBDL=32, Nrow=8, Nnull=0
556
      return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32);
557 558 559 560 561 562 563
    }
    break;
  default:
    LOG_E(PHY,"Unknown N_RB_DL %d\n",N_RB_DL);
    return 0;
  }
  return 0;
564

565 566
}

567

568 569
void generate_RIV_tables()
{
570 571 572 573

  // 6RBs localized RIV
  uint8_t Lcrbs,RBstart;
  uint16_t RIV;
574 575 576 577 578
  uint32_t alloc0,allocdist0_0_even,allocdist0_0_odd,allocdist0_1_even,allocdist0_1_odd;
  uint32_t alloc1,allocdist1_0_even,allocdist1_0_odd,allocdist1_1_even,allocdist1_1_odd;
  uint32_t alloc2,allocdist2_0_even,allocdist2_0_odd,allocdist2_1_even,allocdist2_1_odd;
  uint32_t alloc3,allocdist3_0_even,allocdist3_0_odd,allocdist3_1_even,allocdist3_1_odd;
  uint32_t nVRB,nVRB_even_dist,nVRB_odd_dist;
579

580
  for (RBstart=0; RBstart<6; RBstart++) {
581
    alloc0 = 0;
582 583
    allocdist0_0_even = 0;
    allocdist0_0_odd  = 0;
584
    for (Lcrbs=1; Lcrbs<=(6-RBstart); Lcrbs++) {
585
      //printf("RBstart %d, len %d --> ",RBstart,Lcrbs);
586 587 588 589
      nVRB             = Lcrbs-1+RBstart;
      alloc0          |= (1<<nVRB);
      allocdist0_0_even |= (1<<get_prb(6,0,nVRB,0));
      allocdist0_0_odd  |= (1<<get_prb(6,1,nVRB,0));
590
      RIV=computeRIV(6,RBstart,Lcrbs);
591

592
      if (RIV>RIV_max6)
593
        RIV_max6 = RIV;
594 595 596

      //      printf("RIV %d (%d) : first_rb %d NBRB %d\n",RIV,localRIV2alloc_LUT25[RIV],RBstart,Lcrbs);
      localRIV2alloc_LUT6[RIV] = alloc0;
597 598
      distRIV2alloc_even_LUT6[RIV]  = allocdist0_0_even;
      distRIV2alloc_odd_LUT6[RIV]  = allocdist0_0_odd;
599 600 601 602 603 604
      RIV2nb_rb_LUT6[RIV]      = Lcrbs;
      RIV2first_rb_LUT6[RIV]   = RBstart;
    }
  }


605
  for (RBstart=0; RBstart<25; RBstart++) {
606
    alloc0 = 0;
607 608
    allocdist0_0_even = 0;
    allocdist0_0_odd  = 0;
609
    for (Lcrbs=1; Lcrbs<=(25-RBstart); Lcrbs++) {
610
      nVRB = Lcrbs-1+RBstart;
611
      //printf("RBstart %d, len %d --> ",RBstart,Lcrbs);
612 613 614
      alloc0     |= (1<<nVRB);
      allocdist0_0_even |= (1<<get_prb(25,0,nVRB,0));
      allocdist0_0_odd  |= (1<<get_prb(25,1,nVRB,0));
615

616
      //printf("alloc 0 %x, allocdist0_even %x, allocdist0_odd %x\n",alloc0,allocdist0_0_even,allocdist0_0_odd);
617
      RIV=computeRIV(25,RBstart,Lcrbs);
618

619
      if (RIV>RIV_max25)
620
        RIV_max25 = RIV;;
621

622 623 624 625 626 627

      localRIV2alloc_LUT25[RIV]      = alloc0;
      distRIV2alloc_even_LUT25[RIV]  = allocdist0_0_even;
      distRIV2alloc_odd_LUT25[RIV]   = allocdist0_0_odd;
      RIV2nb_rb_LUT25[RIV]           = Lcrbs;
      RIV2first_rb_LUT25[RIV]        = RBstart;
628
    }
629 630 631
  }


632
  for (RBstart=0; RBstart<50; RBstart++) {
633 634
    alloc0 = 0;
    alloc1 = 0;
635 636 637 638 639 640 641 642
    allocdist0_0_even=0;
    allocdist1_0_even=0;
    allocdist0_0_odd=0;
    allocdist1_0_odd=0;
    allocdist0_1_even=0;
    allocdist1_1_even=0;
    allocdist0_1_odd=0;
    allocdist1_1_odd=0;
643 644

    for (Lcrbs=1; Lcrbs<=(50-RBstart); Lcrbs++) {
645

646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664
      nVRB = Lcrbs-1+RBstart;


      if (nVRB<32)
        alloc0 |= (1<<nVRB);
      else
        alloc1 |= (1<<(nVRB-32));

      // Distributed Gap1, even slot
      nVRB_even_dist = get_prb(50,0,nVRB,0);
      if (nVRB_even_dist<32)
        allocdist0_0_even |= (1<<nVRB_even_dist);
      else
        allocdist1_0_even |= (1<<(nVRB_even_dist-32));

      // Distributed Gap1, odd slot
      nVRB_odd_dist = get_prb(50,1,nVRB,0);
      if (nVRB_odd_dist<32)
        allocdist0_0_odd |= (1<<nVRB_odd_dist);
665
      else
666
        allocdist1_0_odd |= (1<<(nVRB_odd_dist-32));
667

668 669 670 671
      // Distributed Gap2, even slot
      nVRB_even_dist = get_prb(50,0,nVRB,1);
      if (nVRB_even_dist<32)
        allocdist0_1_even |= (1<<nVRB_even_dist);
672
      else
673 674 675 676 677 678 679 680
        allocdist1_1_even |= (1<<(nVRB_even_dist-32));

      // Distributed Gap2, odd slot
      nVRB_odd_dist = get_prb(50,1,nVRB,1);
      if (nVRB_odd_dist<32)
        allocdist0_1_odd |= (1<<nVRB_odd_dist);
      else
        allocdist1_1_odd |= (1<<(nVRB_odd_dist-32));
681 682

      RIV=computeRIV(50,RBstart,Lcrbs);
683

684
      if (RIV>RIV_max50)
685
        RIV_max50 = RIV;
686 687

      //      printf("RIV %d : first_rb %d NBRB %d\n",RIV,RBstart,Lcrbs);
688 689 690 691 692 693 694 695 696 697
      localRIV2alloc_LUT50_0[RIV]      = alloc0;
      localRIV2alloc_LUT50_1[RIV]      = alloc1;
      distRIV2alloc_gap0_even_LUT50_0[RIV]  = allocdist0_0_even;
      distRIV2alloc_gap0_even_LUT50_1[RIV]  = allocdist1_0_even;
      distRIV2alloc_gap0_odd_LUT50_0[RIV]   = allocdist0_0_odd;
      distRIV2alloc_gap0_odd_LUT50_1[RIV]   = allocdist1_0_odd;
      distRIV2alloc_gap1_even_LUT50_0[RIV]  = allocdist0_1_even;
      distRIV2alloc_gap1_even_LUT50_1[RIV]  = allocdist1_1_even;
      distRIV2alloc_gap1_odd_LUT50_0[RIV]   = allocdist0_1_odd;
      distRIV2alloc_gap1_odd_LUT50_1[RIV]   = allocdist1_1_odd;
698 699 700 701 702 703
      RIV2nb_rb_LUT50[RIV]        = Lcrbs;
      RIV2first_rb_LUT50[RIV]     = RBstart;
    }
  }


704
  for (RBstart=0; RBstart<100; RBstart++) {
705 706 707 708
    alloc0 = 0;
    alloc1 = 0;
    alloc2 = 0;
    alloc3 = 0;
709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724
    allocdist0_0_even=0;
    allocdist1_0_even=0;
    allocdist2_0_even=0;
    allocdist3_0_even=0;
    allocdist0_0_odd=0;
    allocdist1_0_odd=0;
    allocdist2_0_odd=0;
    allocdist3_0_odd=0;
    allocdist0_1_even=0;
    allocdist1_1_even=0;
    allocdist2_1_even=0;
    allocdist3_1_even=0;
    allocdist0_1_odd=0;
    allocdist1_1_odd=0;
    allocdist2_1_odd=0;
    allocdist3_1_odd=0;
725

726
    for (Lcrbs=1; Lcrbs<=(100-RBstart); Lcrbs++) {
727

728 729 730 731 732
      nVRB = Lcrbs-1+RBstart;

      if (nVRB<32)
        alloc0 |= (1<<nVRB);
      else if (nVRB<64)
733
        alloc1 |= (1<<(nVRB-32));
734
      else if (nVRB<96)
735
        alloc2 |= (1<<(nVRB-64));
736
      else
737
        alloc3 |= (1<<(nVRB-96));
738 739 740 741

      // Distributed Gap1, even slot
      nVRB_even_dist = get_prb(100,0,nVRB,0);

742
//      if ((RBstart==0) && (Lcrbs<=8))
743
//  printf("nVRB %d => nVRB_even_dist %d\n",nVRB,nVRB_even_dist);
744 745 746 747 748 749 750


      if (nVRB_even_dist<32)
        allocdist0_0_even |= (1<<nVRB_even_dist);
      else if (nVRB_even_dist<64)
        allocdist1_0_even |= (1<<(nVRB_even_dist-32));
      else if (nVRB_even_dist<96)
751
  allocdist2_0_even |= (1<<(nVRB_even_dist-64));
752
      else
753
  allocdist3_0_even |= (1<<(nVRB_even_dist-96));
754
/*      if ((RBstart==0) && (Lcrbs<=8))
755 756 757 758 759 760
  printf("rballoc =>(%08x.%08x.%08x.%08x)\n",
         allocdist0_0_even,
         allocdist1_0_even,
         allocdist2_0_even,
         allocdist3_0_even
         );
761
*/
762 763 764 765 766 767 768
      // Distributed Gap1, odd slot
      nVRB_odd_dist = get_prb(100,1,nVRB,0);
      if (nVRB_odd_dist<32)
        allocdist0_0_odd |= (1<<nVRB_odd_dist);
      else if (nVRB_odd_dist<64)
        allocdist1_0_odd |= (1<<(nVRB_odd_dist-32));
      else if (nVRB_odd_dist<96)
769
  allocdist2_0_odd |= (1<<(nVRB_odd_dist-64));
770
      else
771
  allocdist3_0_odd |= (1<<(nVRB_odd_dist-96));
772 773 774 775 776 777 778 779 780


      // Distributed Gap2, even slot
      nVRB_even_dist = get_prb(100,0,nVRB,1);
      if (nVRB_even_dist<32)
        allocdist0_1_even |= (1<<nVRB_even_dist);
      else if (nVRB_even_dist<64)
        allocdist1_1_even |= (1<<(nVRB_even_dist-32));
      else if (nVRB_even_dist<96)
781
  allocdist2_1_even |= (1<<(nVRB_even_dist-64));
782
      else
783
  allocdist3_1_even |= (1<<(nVRB_even_dist-96));
784 785 786 787 788 789 790 791 792


      // Distributed Gap2, odd slot
      nVRB_odd_dist = get_prb(100,1,nVRB,1);
      if (nVRB_odd_dist<32)
        allocdist0_1_odd |= (1<<nVRB_odd_dist);
      else if (nVRB_odd_dist<64)
        allocdist1_1_odd |= (1<<(nVRB_odd_dist-32));
      else if (nVRB_odd_dist<96)
793
  allocdist2_1_odd |= (1<<(nVRB_odd_dist-64));
794
      else
795
  allocdist3_1_odd |= (1<<(nVRB_odd_dist-96));
796

797 798

      RIV=computeRIV(100,RBstart,Lcrbs);
799

800
      if (RIV>RIV_max100)
801
        RIV_max100 = RIV;
802 803 804 805 806 807

      //      printf("RIV %d : first_rb %d NBRB %d\n",RIV,RBstart,Lcrbs);
      localRIV2alloc_LUT100_0[RIV] = alloc0;
      localRIV2alloc_LUT100_1[RIV] = alloc1;
      localRIV2alloc_LUT100_2[RIV] = alloc2;
      localRIV2alloc_LUT100_3[RIV] = alloc3;
808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824
      distRIV2alloc_gap0_even_LUT100_0[RIV]  = allocdist0_0_even;
      distRIV2alloc_gap0_even_LUT100_1[RIV]  = allocdist1_0_even;
      distRIV2alloc_gap0_even_LUT100_2[RIV]  = allocdist2_0_even;
      distRIV2alloc_gap0_even_LUT100_3[RIV]  = allocdist3_0_even;
      distRIV2alloc_gap0_odd_LUT100_0[RIV]   = allocdist0_0_odd;
      distRIV2alloc_gap0_odd_LUT100_1[RIV]   = allocdist1_0_odd;
      distRIV2alloc_gap0_odd_LUT100_2[RIV]   = allocdist2_0_odd;
      distRIV2alloc_gap0_odd_LUT100_3[RIV]   = allocdist3_0_odd;
      distRIV2alloc_gap1_even_LUT100_0[RIV]  = allocdist0_1_even;
      distRIV2alloc_gap1_even_LUT100_1[RIV]  = allocdist1_1_even;
      distRIV2alloc_gap1_even_LUT100_2[RIV]  = allocdist2_1_even;
      distRIV2alloc_gap1_even_LUT100_3[RIV]  = allocdist3_1_even;
      distRIV2alloc_gap1_odd_LUT100_0[RIV]   = allocdist0_1_odd;
      distRIV2alloc_gap1_odd_LUT100_1[RIV]   = allocdist1_1_odd;
      distRIV2alloc_gap1_odd_LUT100_2[RIV]   = allocdist2_1_odd;
      distRIV2alloc_gap1_odd_LUT100_3[RIV]   = allocdist3_1_odd;

825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840
      RIV2nb_rb_LUT100[RIV]      = Lcrbs;
      RIV2first_rb_LUT100[RIV]   = RBstart;
    }
  }
}

// Ngap = 3, N_VRB_DL=6, P=1, N_row=2, N_null=4*2-6=2
// permutation for even slots :
//    n_PRB'(0,2,4) = (0,1,2), n_PRB'(1,3,5) = (4,5,6)
//    n_PRB''(0,1,2,3) = (0,2,4,6)
//    => n_tilde_PRB(5) = (4)
//       n_tilde_PRB(4) = (1)
//       n_tilde_PRB(2,3) = (3,5)
//       n_tilde_PRB(0,1) = (0,2)


841

842
uint32_t get_rballoc(vrb_t vrb_type,uint16_t rb_alloc_dci)
843
{
844

845
  return(localRIV2alloc_LUT25[rb_alloc_dci]);
846 847 848

}

849 850
uint8_t get_transmission_mode(module_id_t Mod_id, uint8_t CC_id, rnti_t rnti)
{
851 852 853
  unsigned char UE_id;

  // find the UE_index corresponding to rnti
854
  UE_id = find_ue(rnti,PHY_vars_eNB_g[Mod_id][CC_id]);
855
  DevAssert( UE_id != (unsigned char)-1 );
856

857
  return(PHY_vars_eNB_g[Mod_id][CC_id]->transmission_mode[UE_id]);
858 859
}

860
int generate_eNB_dlsch_params_from_dci(int frame,
861
                                       uint8_t subframe,
862 863 864 865 866 867 868 869 870
                                       void *dci_pdu,
                                       uint16_t rnti,
                                       DCI_format_t dci_format,
                                       LTE_eNB_DLSCH_t **dlsch,
                                       LTE_DL_FRAME_PARMS *frame_parms,
                                       PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
                                       uint16_t si_rnti,
                                       uint16_t ra_rnti,
                                       uint16_t p_rnti,
871
                                       uint16_t DL_pmi_single,
872
                                       uint8_t beamforming_mode)
873
{
874

winckel's avatar
winckel committed
875 876 877
  uint8_t harq_pid = UINT8_MAX;
  uint32_t rballoc = UINT32_MAX;
  uint32_t RIV_max = 0;
878
  uint8_t NPRB,tbswap,tpmi=0;
879
  LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
880 881
  uint8_t frame_type=frame_parms->frame_type;
  uint8_t vrb_type=0;
knopp's avatar
knopp committed
882
  uint8_t mcs=0,mcs1=0,mcs2=0;
883
  uint8_t I_mcs = 0;
knopp's avatar
knopp committed
884
  uint8_t rv=0,rv1=0,rv2=0;
885 886
  uint8_t rah=0;
  uint8_t TPC=0;
887
  uint8_t TB0_active=0,TB1_active=0;
888
  LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
knopp's avatar
knopp committed
889

890 891 892 893 894 895 896
  //   printf("Generate eNB DCI, format %d, rnti %x (pdu %p)\n",dci_format,rnti,dci_pdu);

  switch (dci_format) {

  case format0:
    return(-1);
    break;
897

898 899
  case format1A:  // This is DLSCH allocation for control traffic

900

901 902 903

    dlsch[0]->subframe_tx[subframe] = 1;

904

905 906 907
    switch (frame_parms->N_RB_DL) {
    case 6:
      if (frame_type == TDD) {
908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924
        vrb_type = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type;
        mcs      = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs;
        rballoc  = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc;
        rv       = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rv;
        TPC      = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC;
        harq_pid = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid;

        //        printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      } else {
        vrb_type = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->vrb_type;
        mcs      = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->mcs;
        rballoc  = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rballoc;
        rv       = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rv;
        TPC      = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->TPC;
        harq_pid = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->harq_pid;

        //      printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
925
      }
926 927

      dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
928
      dlsch0_harq->codeword=0;
929

930
      if (vrb_type==LOCALIZED) {
931
  dlsch0_harq->rb_alloc[0]    = localRIV2alloc_LUT6[rballoc];
932 933
      }
      else {
934 935
  LOG_E(PHY,"Distributed RB allocation not done yet\n");
  mac_xface->macphy_exit("exiting");
936
      }
937 938
      dlsch0_harq->vrb_type       = vrb_type;
      dlsch0_harq->nb_rb          = RIV2nb_rb_LUT6[rballoc];//NPRB;
939 940
      RIV_max = RIV_max6;

941

942
      break;
943

944 945
    case 25:
      if (frame_type == TDD) {
946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962
        vrb_type = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type;
        mcs      = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->mcs;
        rballoc  = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rballoc;
        rv       = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rv;
        TPC      = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->TPC;
        harq_pid = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid;

        //      printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      } else {
        vrb_type = ((DCI1A_5MHz_FDD_t *)dci_pdu)->vrb_type;
        mcs      = ((DCI1A_5MHz_FDD_t *)dci_pdu)->mcs;
        rballoc  = ((DCI1A_5MHz_FDD_t *)dci_pdu)->rballoc;
        rv       = ((DCI1A_5MHz_FDD_t *)dci_pdu)->rv;
        TPC      = ((DCI1A_5MHz_FDD_t *)dci_pdu)->TPC;
        harq_pid = ((DCI1A_5MHz_FDD_t *)dci_pdu)->harq_pid;

        //      printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
963 964
      }

965
      dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
966

967

968
      if (vrb_type==LOCALIZED) {
969
  dlsch0_harq->rb_alloc[0]    = localRIV2alloc_LUT25[rballoc];
970 971
      }
      else {
972 973
  LOG_E(PHY,"Distributed RB allocation not done yet\n");
  mac_xface->macphy_exit("exiting");
974
      }
975 976 977
      dlsch0_harq->vrb_type       = vrb_type;
      dlsch0_harq->nb_rb          = RIV2nb_rb_LUT25[rballoc];//NPRB;
      RIV_max                     = RIV_max25;
978
      break;
979

980 981
    case 50:
      if (frame_type == TDD) {
982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997
        vrb_type = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->vrb_type;
        mcs      = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->mcs;
        rballoc  = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rballoc;
        rv       = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rv;
        TPC      = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->TPC;
        harq_pid = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->harq_pid;

        //      printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      } else {
        vrb_type = ((DCI1A_10MHz_FDD_t *)dci_pdu)->vrb_type;
        mcs      = ((DCI1A_10MHz_FDD_t *)dci_pdu)->mcs;
        rballoc  = ((DCI1A_10MHz_FDD_t *)dci_pdu)->rballoc;
        rv       = ((DCI1A_10MHz_FDD_t *)dci_pdu)->rv;
        TPC      = ((DCI1A_10MHz_FDD_t *)dci_pdu)->TPC;
        harq_pid = ((DCI1A_10MHz_FDD_t *)dci_pdu)->harq_pid;
        //printf("FDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC);
998 999
      }

1000
      dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
1001
      if (vrb_type==LOCALIZED) {
1002 1003
  dlsch0_harq->rb_alloc[0]     = localRIV2alloc_LUT50_0[rballoc];
  dlsch0_harq->rb_alloc[1]     = localRIV2alloc_LUT50_1[rballoc];
1004 1005
      }
      else {
1006 1007
  LOG_E(PHY,"Distributed RB allocation not done yet\n");
  mac_xface->macphy_exit("exiting");
1008 1009
      }

1010

1011
      dlsch0_harq->vrb_type        = vrb_type;
1012
      dlsch0_harq->nb_rb                               = RIV2nb_rb_LUT50[rballoc];//NPRB;
1013 1014
      RIV_max = RIV_max50;
      break;
1015

1016 1017
    case 100:
      if (frame_type == TDD) {
1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032
        vrb_type = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->vrb_type;
        mcs      = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->mcs;
        rballoc  = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rballoc;
        rv       = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rv;
        TPC      = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->TPC;
        harq_pid = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->harq_pid;
        //      printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      } else {
        vrb_type = ((DCI1A_20MHz_FDD_t *)dci_pdu)->vrb_type;
        mcs      = ((DCI1A_20MHz_FDD_t *)dci_pdu)->mcs;
        rballoc  = ((DCI1A_20MHz_FDD_t *)dci_pdu)->rballoc;
        rv       = ((DCI1A_20MHz_FDD_t *)dci_pdu)->rv;
        TPC      = ((DCI1A_20MHz_FDD_t *)dci_pdu)->TPC;
        harq_pid = ((DCI1A_20MHz_FDD_t *)dci_pdu)->harq_pid;
        //      printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
1033 1034
      }

knopp's avatar
knopp committed
1035
      dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
1036

1037
      dlsch0_harq->vrb_type         = vrb_type;
1038
      if (vrb_type==LOCALIZED) {
1039 1040 1041 1042
  dlsch0_harq->rb_alloc[0]      = localRIV2alloc_LUT100_0[rballoc];
  dlsch0_harq->rb_alloc[1]      = localRIV2alloc_LUT100_1[rballoc];
  dlsch0_harq->rb_alloc[2]      = localRIV2alloc_LUT100_2[rballoc];
  dlsch0_harq->rb_alloc[3]      = localRIV2alloc_LUT100_3[rballoc];
1043 1044
      }
      else {
1045 1046
  LOG_E(PHY,"Distributed RB allocation not done yet\n");
  mac_xface->macphy_exit("exiting");
1047 1048
      }

1049

1050

1051
      dlsch0_harq->nb_rb                               = RIV2nb_rb_LUT100[rballoc];//NPRB;
1052 1053
      RIV_max = RIV_max100;
      break;
winckel's avatar
winckel committed
1054

1055 1056 1057 1058
    default:
      LOG_E(PHY,"Invalid N_RB_D %dL\n", frame_parms->N_RB_DL);
      DevParam (frame_parms->N_RB_DL, 0, 0);
      break;
1059 1060 1061
    }

    // harq_pid field is reserved
1062
    if ((rnti==si_rnti) || (rnti==ra_rnti) || (rnti==p_rnti)) { //
1063 1064 1065 1066 1067
      harq_pid=0;
      // see 36-212 V8.6.0 p. 45
      NPRB      = (TPC&1)+2;
      // 36-213 sec.7.1.7.2 p.26
      I_mcs     = mcs;
1068
    } else {
1069 1070
      if (harq_pid>=8) {
        LOG_E(PHY,"ERROR: Format 1A: harq_pid=%d >= 8\n", harq_pid);
1071
        return(-1);
1072
      }
1073

1074
      if (rballoc>RIV_max) {
1075 1076
        LOG_E(PHY,"ERROR: Format 1A: rb_alloc (%x) > RIV_max (%x)\n",rballoc,RIV_max);
        return(-1);
1077
      }
1078

1079
      NPRB      = dlsch0_harq->nb_rb;
1080 1081 1082 1083 1084 1085
      I_mcs     = get_I_TBS(mcs);
    }

    if (NPRB==0)
      return(-1);

knopp's avatar
knopp committed
1086
    //printf("NPRB %d, nb_rb %d, ndi %d\n",NPRB,dlsch0_harq->nb_rb,ndi);
1087
    dlsch0_harq->rvidx     = rv;
1088

1089 1090
    dlsch0_harq->Nl          = 1;
    //dlsch0_harq->layer_index = 0;
1091

1092
    dlsch0_harq->mimo_mode   = (frame_parms->mode1_flag == 1) ? SISO : ALAMOUTI;
1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111
    /*
    if ((rnti!=si_rnti)&&(rnti!=ra_rnti)&&(rnti!=p_rnti)) {  //handle toggling for C-RNTI
    if (dlsch0_harq->first_tx == 1) {
    LOG_D(PHY,"First TX for TC-RNTI %x, clearing first_tx flag\n",rnti);
    dlsch0_harq->first_tx=0;
    dlsch0_harq->Ndi = 1;
    }
    else {
    if (ndi == dlsch0_harq->DCINdi)
    dlsch0_harq->Ndi         = 0;
    else
    dlsch0_harq->Ndi         = 1;
    }

    dlsch0_harq->DCINdi=ndi;
    }
    else {
    dlsch0_harq->Ndi         = 1;
    }
1112
    */
1113
    dlsch0_harq->dl_power_off = 1;
1114 1115 1116



1117 1118
    dlsch0_harq->mcs           = mcs;
    dlsch0_harq->TBS           = TBStable[I_mcs][NPRB-1];
1119

1120
    dlsch[0]->current_harq_pid   = harq_pid;
1121 1122 1123 1124 1125 1126 1127 1128
    dlsch[0]->harq_ids[subframe] = harq_pid;

    dlsch[0]->active = 1;
    dlsch0 = dlsch[0];

    dlsch[0]->rnti = rnti;

    dlsch[0]->harq_ids[subframe] = harq_pid;
1129

1130
    if (dlsch0_harq->round == 0)
1131
      dlsch0_harq->status = ACTIVE;
1132 1133

    break;
1134

1135 1136 1137 1138 1139 1140
  case format1:

    switch (frame_parms->N_RB_DL) {

    case 6:
      if (frame_type == TDD) {
1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151
        mcs       = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->mcs;
        rballoc   = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rballoc;
        rah       = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rah;
        rv        = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rv;
        harq_pid  = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->harq_pid;
      } else {
        mcs      = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->mcs;
        rah      = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rah;
        rballoc  = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rballoc;
        rv       = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rv;
        harq_pid = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->harq_pid;
1152
      }
1153

1154
      break;
1155

1156
    case 25:
1157

1158
      if (frame_type == TDD) {
1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171
        mcs       = ((DCI1_5MHz_TDD_t *)dci_pdu)->mcs;
        rballoc   = ((DCI1_5MHz_TDD_t *)dci_pdu)->rballoc;
        rah       = ((DCI1_5MHz_TDD_t *)dci_pdu)->rah;
        rv        = ((DCI1_5MHz_TDD_t *)dci_pdu)->rv;
        harq_pid  = ((DCI1_5MHz_TDD_t *)dci_pdu)->harq_pid;
        LOG_D(PHY,"eNB: subframe %d UE %x, Format1 DCI: ndi %d, harq_pid %d\n",subframe,rnti,((DCI1_5MHz_TDD_t *)dci_pdu)->ndi,harq_pid);
      } else {
        mcs      = ((DCI1_5MHz_FDD_t *)dci_pdu)->mcs;
        rah      = ((DCI1_5MHz_FDD_t *)dci_pdu)->rah;
        rballoc  = ((DCI1_5MHz_FDD_t *)dci_pdu)->rballoc;
        rv       = ((DCI1_5MHz_FDD_t *)dci_pdu)->rv;
        harq_pid = ((DCI1_5MHz_FDD_t *)dci_pdu)->harq_pid;
        LOG_D(PHY,"eNB: subframe %d UE %x, Format1 DCI: ndi %d, harq_pid %d\n",subframe,rnti,((DCI1_5MHz_FDD_t *)dci_pdu)->ndi,harq_pid);
1172

1173
      }
1174

1175
      break;
1176

1177 1178
    case 50:
      if (frame_type == TDD) {
1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189
        mcs       = ((DCI1_10MHz_TDD_t *)dci_pdu)->mcs;
        rballoc   = ((DCI1_10MHz_TDD_t *)dci_pdu)->rballoc;
        rah       = ((DCI1_10MHz_TDD_t *)dci_pdu)->rah;
        rv        = ((DCI1_10MHz_TDD_t *)dci_pdu)->rv;
        harq_pid  = ((DCI1_10MHz_TDD_t *)dci_pdu)->harq_pid;
      } else {
        mcs      = ((DCI1_10MHz_FDD_t *)dci_pdu)->mcs;
        rah      = ((DCI1_10MHz_FDD_t *)dci_pdu)->rah;
        rballoc  = ((DCI1_10MHz_FDD_t *)dci_pdu)->rballoc;
        rv       = ((DCI1_10MHz_FDD_t *)dci_pdu)->rv;
        harq_pid = ((DCI1_10MHz_FDD_t *)dci_pdu)->harq_pid;
1190
      }
1191

1192 1193 1194 1195
      break;

    case 100:
      if (frame_type == TDD) {
1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206
        mcs       = ((DCI1_20MHz_TDD_t *)dci_pdu)->mcs;
        rballoc   = ((DCI1_20MHz_TDD_t *)dci_pdu)->rballoc;
        rah       = ((DCI1_20MHz_TDD_t *)dci_pdu)->rah;
        rv        = ((DCI1_20MHz_TDD_t *)dci_pdu)->rv;
        harq_pid  = ((DCI1_20MHz_TDD_t *)dci_pdu)->harq_pid;
      } else {
        mcs      = ((DCI1_20MHz_FDD_t *)dci_pdu)->mcs;
        rah      = ((DCI1_20MHz_FDD_t *)dci_pdu)->rah;
        rballoc  = ((DCI1_20MHz_FDD_t *)dci_pdu)->rballoc;
        rv       = ((DCI1_20MHz_FDD_t *)dci_pdu)->rv;
        harq_pid = ((DCI1_20MHz_FDD_t *)dci_pdu)->harq_pid;
1207
      }
1208

1209 1210 1211 1212 1213
      break;

    }

    if (harq_pid>=8) {
1214
      LOG_E(PHY,"ERROR: Format 1: harq_pid=%d >= 8\n", harq_pid);
1215 1216 1217
      return(-1);
    }

1218
    dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
1219
    dlsch0_harq->codeword=0;
1220

1221
    // printf("DCI: Setting subframe_tx for subframe %d\n",subframe);
1222 1223 1224
    dlsch[0]->subframe_tx[subframe] = 1;

    conv_rballoc(rah,
1225 1226
                 rballoc,frame_parms->N_RB_DL,
                 dlsch0_harq->rb_alloc);
1227

1228
    dlsch0_harq->nb_rb = conv_nprb(rah,
1229 1230
                                   rballoc,
                                   frame_parms->N_RB_DL);
1231

1232
    NPRB      = dlsch0_harq->nb_rb;
1233 1234 1235 1236 1237 1238


    if (NPRB==0)
      return(-1);


1239
    dlsch0_harq->rvidx       = rv;
1240

1241 1242
    dlsch0_harq->Nl          = 1;
    //    dlsch[0]->layer_index = 0;
1243 1244 1245 1246 1247 1248
    if (beamforming_mode == 0)
      dlsch0_harq->mimo_mode = (frame_parms->mode1_flag == 1) ? SISO : ALAMOUTI;
    else if (beamforming_mode == 7)
      dlsch0_harq->mimo_mode = TM7;
    else
      LOG_E(PHY,"Invalid beamforming mode %dL\n", beamforming_mode);
1249

1250
    dlsch0_harq->dl_power_off = 1;
1251 1252 1253 1254 1255
    /*
      if (dlsch[0]->harq_processes[harq_pid]->first_tx == 1) {
      LOG_D(PHY,"First TX for C-RNTI %x, clearing first_tx flag, shouldn't happen!\n",rnti);
      dlsch[0]->harq_processes[harq_pid]->first_tx=0;
      dlsch[0]->harq_processes[harq_pid]->Ndi = 1;
1256
      }
1257 1258 1259 1260 1261 1262 1263 1264 1265
      else {
      LOG_D(PHY,"Checking for Toggled Ndi for C-RNTI %x, old value %d, DCINdi %d\n",rnti,dlsch[0]->harq_processes[harq_pid]->DCINdi,ndi);
      if (ndi == dlsch[0]->harq_processes[harq_pid]->DCINdi)
      dlsch[0]->harq_processes[harq_pid]->Ndi         = 0;
      else
      dlsch[0]->harq_processes[harq_pid]->Ndi         = 1;
      }
      dlsch[0]->harq_processes[harq_pid]->DCINdi=ndi;
    */
1266 1267 1268

    dlsch[0]->active = 1;

1269 1270


1271 1272
    if (dlsch0_harq->round == 0) {
      dlsch0_harq->status = ACTIVE;
1273 1274
      //            printf("Setting DLSCH process %d to ACTIVE\n",harq_pid);
      // MCS and TBS don't change across HARQ rounds
1275 1276
      dlsch0_harq->mcs         = mcs;
      dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][NPRB-1];
1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291

    }

    dlsch[0]->current_harq_pid = harq_pid;
    dlsch[0]->harq_ids[subframe] = harq_pid;



    dlsch0 = dlsch[0];

    dlsch[0]->rnti = rnti;


    break;

Elena Lukashova's avatar
Elena Lukashova committed
1292
  case format2: // DL Scheduling assignment for MIMO including closed loop spatial multiplexing
knopp's avatar
knopp committed
1293 1294 1295 1296

    switch (frame_parms->N_RB_DL) {

    case 6:
1297
      if (frame_parms->nb_antenna_ports_eNB == 2) {
1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316
        if (frame_type == TDD) {
          mcs1      = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
          mcs2      = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
          rballoc   = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rballoc;
          rv1       = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rv1;
          rv2       = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rv2;
          harq_pid  = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid;
          tbswap    = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap;
          tpmi      = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tpmi;
        } else {
          mcs1      = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->mcs1;
          mcs2      = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->mcs2;
          rballoc   = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rballoc;
          rv1       = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rv1;
          rv2       = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rv2;
          harq_pid  = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
          tbswap    = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
          tpmi      = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tpmi;
        }
1317
      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337
        if (frame_type == TDD) {
          mcs1      = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
          mcs2      = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
          rballoc   = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rballoc;
          rv1       = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rv1;
          rv2       = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rv2;
          harq_pid  = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->harq_pid;
          tbswap    = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->tb_swap;
          tpmi      = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->tpmi;
        } else {
          mcs1      = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->mcs1;
          mcs2      = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->mcs2;
          rballoc   = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rballoc;
          rv1       = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rv1;
          rv2       = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rv2;
          harq_pid  = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->harq_pid;
          tbswap    = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->tb_swap;
          tpmi      = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
        }
      } else {
1338
        LOG_E(PHY,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
knopp's avatar
knopp committed
1339
      }