NR_IF_Module.c 20.7 KB
Newer Older
WEI-TAI CHEN's avatar
WEI-TAI CHEN 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 32
/*
 * 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 openair2/NR_PHY_INTERFACE/NR_IF_Module.c
* \brief data structures for PHY/MAC interface modules
* \author EURECOM/NTUST
* \date 2018
* \version 0.1
* \company Eurecom, NTUST
* \email: raymond.knopp@eurecom.fr, kroempa@gmail.com
* \note
* \warning
*/

33 34
#include "openair1/SCHED_NR/fapi_nr_l1.h"
#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
35
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
36 37
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "common/ran_context.h"
38
#include "executables/softmodem-common.h"
Mahesh's avatar
Mahesh committed
39
#include "nfapi/oai_integration/vendor_ext.h" 
40
#include "nfapi/oai_integration/gnb_ind_vars.h"
41
#include "openair2/PHY_INTERFACE/queue_t.h"
42

43
#define MAX_IF_MODULES 100
Francesco Mani's avatar
Francesco Mani committed
44
//#define UL_HARQ_PRINT
45

46 47
static NR_IF_Module_t *nr_if_inst[MAX_IF_MODULES];
static NR_Sched_Rsp_t NR_Sched_INFO[MAX_IF_MODULES][MAX_NUM_CCs];
48 49 50 51 52
extern int oai_nfapi_harq_indication(nfapi_harq_indication_t *harq_ind);
extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind);
extern int oai_nfapi_cqi_indication(nfapi_cqi_indication_t *cqi_ind);
extern int oai_nfapi_sr_indication(nfapi_sr_indication_t *ind);
extern int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind);
53 54 55 56 57 58
extern int oai_nfapi_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind);
extern int oai_nfapi_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind);
extern int oai_nfapi_nr_crc_indication(nfapi_nr_crc_indication_t *ind);
extern int oai_nfapi_nr_srs_indication(nfapi_nr_srs_indication_t *ind);
extern int oai_nfapi_nr_uci_indication(nfapi_nr_uci_indication_t *ind);
extern int oai_nfapi_nr_rach_indication(nfapi_nr_rach_indication_t *ind);
59 60
extern uint8_t nfapi_mode;
extern uint16_t sf_ahead;
61
extern uint16_t sl_ahead;
62 63


64 65
void handle_nr_rach(NR_UL_IND_t *UL_info)
{
66
  if (NFAPI_MODE == NFAPI_MODE_PNF) {
67
    if (UL_info->rach_ind.number_of_pdus > 0) {
Mahesh's avatar
Mahesh committed
68
      LOG_D(PHY,"UL_info->UL_info->rach_ind.number_of_pdus:%d SFN/Slot:%d.%d \n", UL_info->rach_ind.number_of_pdus, UL_info->rach_ind.sfn,UL_info->rach_ind.slot);
69 70 71
      oai_nfapi_nr_rach_indication(&UL_info->rach_ind);
      UL_info->rach_ind.number_of_pdus = 0;
    }
72 73
    return;
  }
74

75 76
  int frame_diff = UL_info->frame - UL_info->rach_ind.sfn;
  if (frame_diff < 0) {
77 78 79 80
    frame_diff += 1024;
  }
  bool in_timewindow = frame_diff == 0 || (frame_diff == 1 && UL_info->slot < 7);

81
  if (UL_info->rach_ind.number_of_pdus > 0 && in_timewindow) {
82
    LOG_A(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n",
83 84
          UL_info->frame, UL_info->slot, UL_info->rach_ind.sfn, UL_info->rach_ind.slot);
    for (int i = 0; i < UL_info->rach_ind.number_of_pdus; i++) {
85
      UL_info->rach_ind.number_of_pdus--;
86 87 88 89 90 91 92 93 94
      AssertFatal(UL_info->rach_ind.pdu_list[i].num_preamble == 1, "More than 1 preamble not supported\n");
      nr_initiate_ra_proc(UL_info->module_id,
                          UL_info->CC_id,
                          UL_info->rach_ind.sfn,
                          UL_info->rach_ind.slot,
                          UL_info->rach_ind.pdu_list[i].preamble_list[0].preamble_index,
                          UL_info->rach_ind.pdu_list[i].freq_index,
                          UL_info->rach_ind.pdu_list[i].symbol_index,
                          UL_info->rach_ind.pdu_list[i].preamble_list[0].timing_advance);
Francesco Mani's avatar
Francesco Mani committed
95
    }
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
96 97
  }
}
98

99

100 101
void handle_nr_uci(NR_UL_IND_t *UL_info)
{
102
  if(NFAPI_MODE == NFAPI_MODE_PNF) {
103
    if (UL_info->uci_ind.num_ucis > 0) {
104
      LOG_D(PHY,"PNF Sending UL_info->num_ucis:%d PDU_type: %d, SFN/SF:%d.%d \n", UL_info->uci_ind.num_ucis, UL_info->uci_ind.uci_list[0].pdu_type ,UL_info->frame, UL_info->slot);
105 106 107
      oai_nfapi_nr_uci_indication(&UL_info->uci_ind);
      UL_info->uci_ind.num_ucis = 0;
    }
108
    return;
109 110
  }

111
  const module_id_t mod_id = UL_info->module_id;
112 113 114 115
  const frame_t frame = UL_info->uci_ind.sfn;
  const sub_frame_t slot = UL_info->uci_ind.slot;
  int num_ucis = UL_info->uci_ind.num_ucis;
  nfapi_nr_uci_t *uci_list = UL_info->uci_ind.uci_list;
116 117 118

  for (int i = 0; i < num_ucis; i++) {
    switch (uci_list[i].pdu_type) {
119 120 121
      case NFAPI_NR_UCI_PUSCH_PDU_TYPE:
        LOG_E(MAC, "%s(): unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE\n", __func__);
        break;
122 123

      case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
124
        const nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &uci_list[i].pucch_pdu_format_0_1;
125
        LOG_D(NR_MAC, "The received uci has sfn slot %d %d, num_ucis %d and pdu_size %d\n",
126
                UL_info->uci_ind.sfn, UL_info->uci_ind.slot, num_ucis, uci_list[i].pdu_size);
127
        handle_nr_uci_pucch_0_1(mod_id, frame, slot, uci_pdu);
128 129
        break;
      }
130 131 132 133 134 135

        case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
          const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &uci_list[i].pucch_pdu_format_2_3_4;
          handle_nr_uci_pucch_2_3_4(mod_id, frame, slot, uci_pdu);
          break;
        }
136
      LOG_D(MAC, "UCI handled \n");
137 138 139
    }
  }

140
  UL_info->uci_ind.num_ucis = 0;
141

142 143
}

144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
static bool crc_sfn_slot_matcher(void *wanted, void *candidate)
{
  nfapi_p7_message_header_t *msg = candidate;
  int sfn_sf = *(int*)wanted;

  switch (msg->message_id)
  {
    case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
    {
      nfapi_nr_crc_indication_t *ind = candidate;
      return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot;
    }

    default:
      LOG_E(NR_MAC, "sfn_slot_match bad ID: %d\n", msg->message_id);

  }
  return false;
162 163
}

164 165
void handle_nr_ulsch(NR_UL_IND_t *UL_info)
{
166
  if(NFAPI_MODE == NFAPI_MODE_PNF) {
167
    if (UL_info->crc_ind.number_crcs > 0) {
Mahesh's avatar
Mahesh committed
168
      LOG_D(PHY,"UL_info->UL_info->crc_ind.number_crcs:%d CRC_IND:SFN/Slot:%d.%d\n", UL_info->crc_ind.number_crcs, UL_info->crc_ind.sfn, UL_info->crc_ind.slot);
169 170 171 172
      oai_nfapi_nr_crc_indication(&UL_info->crc_ind);
      UL_info->crc_ind.number_crcs = 0;
    }

173
    if (UL_info->rx_ind.number_of_pdus > 0) {
Mahesh's avatar
Mahesh committed
174
      LOG_D(PHY,"UL_info->rx_ind.number_of_pdus:%d RX_IND:SFN/Slot:%d.%d \n", UL_info->rx_ind.number_of_pdus, UL_info->rx_ind.sfn, UL_info->rx_ind.slot);
175 176 177
      oai_nfapi_nr_rx_data_indication(&UL_info->rx_ind);
      UL_info->rx_ind.number_of_pdus = 0;
    }
178
    return;
179 180
  }

181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
  if (UL_info->rx_ind.number_of_pdus > 0 && UL_info->crc_ind.number_crcs > 0) {
    AssertFatal(UL_info->rx_ind.number_of_pdus == UL_info->crc_ind.number_crcs,
                "number_of_pdus %d, number_crcs %d\n",
                UL_info->rx_ind.number_of_pdus, UL_info->crc_ind.number_crcs);
    for (int i = 0; i < UL_info->rx_ind.number_of_pdus; i++) {
      const nfapi_nr_rx_data_pdu_t *rx = &UL_info->rx_ind.pdu_list[i];
      const nfapi_nr_crc_t *crc = &UL_info->crc_ind.crc_list[i];
      LOG_I(NR_PHY, "UL_info->crc_ind.pdu_list[%d].rnti:%04x "
                    "UL_info->rx_ind.pdu_list[%d].rnti:%04x\n",
                    i, crc->rnti, i, rx->rnti);

      AssertFatal(crc->rnti == rx->rnti, "mis-match between CRC RNTI %04x and RX RNTI %04x\n",
                  crc->rnti, rx->rnti);

      LOG_D(NR_MAC,
            "%4d.%2d Calling rx_sdu (CRC %s/tb_crc_status %d)\n",
            UL_info->frame,
            UL_info->slot,
            crc->tb_crc_status ? "error" : "ok",
            crc->tb_crc_status);

      /* if CRC passes, pass PDU, otherwise pass NULL as error indication */
      nr_rx_sdu(UL_info->module_id,
                UL_info->CC_id,
                UL_info->rx_ind.sfn,
                UL_info->rx_ind.slot,
                rx->rnti,
                crc->tb_crc_status ? NULL : rx->pdu,
                rx->pdu_length,
                rx->timing_advance,
                rx->ul_cqi,
                rx->rssi);
      handle_nr_ul_harq(UL_info->CC_id, UL_info->module_id, UL_info->frame, UL_info->slot, crc);
214
    }
215 216 217 218
  }
  UL_info->rx_ind.number_of_pdus = 0;
  UL_info->crc_ind.number_crcs = 0;
}
219

220 221 222 223 224 225 226
static void free_unqueued_nfapi_indications(nfapi_nr_rach_indication_t *rach_ind,
                                            nfapi_nr_uci_indication_t *uci_ind,
                                            nfapi_nr_rx_data_indication_t *rx_ind,
                                            nfapi_nr_crc_indication_t *crc_ind) {
  if (rach_ind && rach_ind->number_of_pdus > 0)
  {
    for(int i = 0; i < rach_ind->number_of_pdus; i++)
227
    {
228 229
      free(rach_ind->pdu_list[i].preamble_list);
      rach_ind->pdu_list[i].preamble_list = NULL;
230
    }
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
    free(rach_ind->pdu_list);
    rach_ind->pdu_list = NULL;
    free(rach_ind);
    rach_ind = NULL;
  }
  if (uci_ind && uci_ind->num_ucis > 0)
  {
    for (int i = 0; i < uci_ind->num_ucis; i++) {
      switch (uci_ind->uci_list[i].pdu_type) {
        case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE:
          if (uci_ind->uci_list[i].pucch_pdu_format_0_1.harq) {
            free(uci_ind->uci_list[i].pucch_pdu_format_0_1.harq->harq_list);
            uci_ind->uci_list[i].pucch_pdu_format_0_1.harq->harq_list = NULL;
          }
          free(uci_ind->uci_list[i].pucch_pdu_format_0_1.harq);
          uci_ind->uci_list[i].pucch_pdu_format_0_1.harq = NULL;
          free(uci_ind->uci_list[i].pucch_pdu_format_0_1.sr);
          uci_ind->uci_list[i].pucch_pdu_format_0_1.sr = NULL;
          break;
250

251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
        case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE:
          free(uci_ind->uci_list[i].pucch_pdu_format_2_3_4.harq.harq_payload);
          free(uci_ind->uci_list[i].pucch_pdu_format_2_3_4.csi_part1.csi_part1_payload);
          free(uci_ind->uci_list[i].pucch_pdu_format_2_3_4.csi_part2.csi_part2_payload);
          break;
      }
    }
    free(uci_ind->uci_list);
    uci_ind->uci_list = NULL;
    free(uci_ind);
    uci_ind = NULL;
  }
  if (rx_ind && rx_ind->number_of_pdus > 0)
  {
    free(rx_ind->pdu_list);
    rx_ind->pdu_list = NULL;
    free(rx_ind);
    rx_ind = NULL;
269
  }
270
  if (crc_ind && crc_ind->number_crcs > 0)
271
  {
272 273 274 275
    free(crc_ind->crc_list);
    crc_ind->crc_list = NULL;
    free(crc_ind);
    crc_ind = NULL;
276
  }
277
}
278

279 280 281 282
static void remove_crc_pdu(nfapi_nr_crc_indication_t *crc_ind, int index) {
  AssertFatal(index >= 0, "Invalid index %d\n", index);
  AssertFatal(index < crc_ind->number_crcs, "Invalid index %d\n", index);
  AssertFatal(crc_ind->number_crcs > 0, "Invalid crc_ind->number_crcs %d\n", crc_ind->number_crcs);
283

284 285 286 287 288
  memmove(crc_ind->crc_list + index,
          crc_ind->crc_list + index + 1,
          sizeof(*crc_ind->crc_list) * (crc_ind->number_crcs - index - 1));
  crc_ind->number_crcs--;
}
289

290 291 292 293
static void remove_rx_pdu(nfapi_nr_rx_data_indication_t *rx_ind, int index) {
  AssertFatal(index >= 0, "Invalid index %d\n", index);
  AssertFatal(index < rx_ind->number_of_pdus, "Invalid index %d\n", index);
  AssertFatal(rx_ind->number_of_pdus > 0, "Invalid rx_ind->number_of_pdus %d\n", rx_ind->number_of_pdus);
294

295 296 297 298 299 300 301 302 303 304 305 306 307 308
  memmove(rx_ind->pdu_list + index,
          rx_ind->pdu_list + index + 1,
          sizeof(*rx_ind->pdu_list) * (rx_ind->number_of_pdus - index - 1));
  rx_ind->number_of_pdus--;
}

static bool crc_ind_has_rnti(nfapi_nr_crc_indication_t *crc_ind, uint16_t rnti) {
  for (int i = 0; i < crc_ind->number_crcs; i++) {
    if (rnti == crc_ind->crc_list[i].rnti) {
      return true;
    }
  }
  return false;
}
309

310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
static bool rx_ind_has_rnti(nfapi_nr_rx_data_indication_t *rx_ind, uint16_t rnti) {
  for (int i = 0; i < rx_ind->number_of_pdus; i++) {
    if (rnti == rx_ind->pdu_list[i].rnti) {
      return true;
    }
  }
  return false;
}

static void match_crc_rx_pdu(nfapi_nr_rx_data_indication_t *rx_ind, nfapi_nr_crc_indication_t *crc_ind) {
  AssertFatal(crc_ind->number_crcs > 0 &&  rx_ind->number_of_pdus > 0,
              "Invalid number of crc_ind->number_crcs %d or rx_ind->number_of_pdus %d\n",
              crc_ind->number_crcs, rx_ind->number_of_pdus);
  if (crc_ind->number_crcs > rx_ind->number_of_pdus) {
    nfapi_nr_crc_indication_t *crc_ind_unmatched = calloc(1, sizeof(*crc_ind_unmatched));
    crc_ind_unmatched->header = crc_ind->header;
    crc_ind_unmatched->sfn = crc_ind->sfn;
    crc_ind_unmatched->slot = crc_ind->slot;
    crc_ind_unmatched->number_crcs = 0;
    crc_ind_unmatched->crc_list = NULL;
    for (int i = 0; i < crc_ind->number_crcs; i++) {
      if (!rx_ind_has_rnti(rx_ind, crc_ind->crc_list[i].rnti)) {
          LOG_I(NR_MAC, "crc_ind->crc_list[%d].rnti %x does not match any rx_ind pdu rnti\n",
                i, crc_ind->crc_list[i].rnti);
          crc_ind_unmatched->number_crcs++;
          if (crc_ind_unmatched->crc_list == NULL) {
            crc_ind_unmatched->crc_list = malloc(sizeof(nfapi_nr_crc_t));
          }
          else {
            crc_ind_unmatched->crc_list = realloc(crc_ind_unmatched->crc_list,
                                                  sizeof(nfapi_nr_crc_t) * crc_ind_unmatched->number_crcs);
          }
          crc_ind_unmatched->crc_list[crc_ind_unmatched->number_crcs - 1] = crc_ind->crc_list[i];
          remove_crc_pdu(crc_ind, i);
344
      }
345 346
      if (crc_ind->number_crcs == rx_ind->number_of_pdus) {
        break;
347 348
      }
    }
349 350 351
    AssertFatal(crc_ind_unmatched->number_crcs > 0, "The nubmer of unmatched crc_ind pdus %d <= 0\n",
                crc_ind_unmatched->number_crcs);
    if (!requeue(&gnb_crc_ind_queue, crc_ind_unmatched))
352
    {
353 354 355
      LOG_E(NR_PHY, "requeue failed for crc_ind_unmatched.\n");
      free(crc_ind_unmatched);
      crc_ind_unmatched = NULL;
356
    }
357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395
  }
  else if (crc_ind->number_crcs < rx_ind->number_of_pdus) {
    nfapi_nr_rx_data_indication_t *rx_ind_unmatched = calloc(1, sizeof(*rx_ind_unmatched));
    rx_ind_unmatched->header = rx_ind->header;
    rx_ind_unmatched->sfn = rx_ind->sfn;
    rx_ind_unmatched->slot = rx_ind->slot;
    rx_ind_unmatched->number_of_pdus = 0;
    rx_ind_unmatched->pdu_list = NULL;
    for (int i = 0; i < rx_ind->number_of_pdus; i++) {
      if (!crc_ind_has_rnti(crc_ind, rx_ind->pdu_list[i].rnti)) {
        LOG_I(NR_MAC, "rx_ind->pdu_list[%d].rnti %d does not match any crc_ind pdu rnti\n",
              i, rx_ind->pdu_list[i].rnti);
        rx_ind_unmatched->number_of_pdus++;
        if (rx_ind_unmatched->pdu_list == NULL) {
          rx_ind_unmatched->pdu_list = malloc(sizeof(nfapi_nr_rx_data_pdu_t));
        }
        else {
          rx_ind_unmatched->pdu_list = realloc(rx_ind_unmatched->pdu_list,
                                             sizeof(nfapi_nr_rx_data_pdu_t) * rx_ind_unmatched->number_of_pdus);
        }
        rx_ind_unmatched->pdu_list[rx_ind_unmatched->number_of_pdus - 1] = rx_ind->pdu_list[i];
        remove_rx_pdu(rx_ind, i);
      }
      if (rx_ind->number_of_pdus == crc_ind->number_crcs) {
        break;
      }
    }
    AssertFatal(rx_ind_unmatched->number_of_pdus > 0, "The nubmer of unmatched rx_ind pdus %d <= 0\n",
                rx_ind_unmatched->number_of_pdus);
    if (!requeue(&gnb_rx_ind_queue, rx_ind_unmatched))
    {
      LOG_E(NR_PHY, "requeue failed for rx_ind_unmatched.\n");
      free(rx_ind_unmatched);
      rx_ind_unmatched = NULL;
    }
  }
  else {
    LOG_E(NR_MAC, "The number of crc pdus %d = the number of rx pdus %d\n",
          crc_ind->number_crcs, rx_ind->number_of_pdus);
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
396 397 398
  }
}

399
void NR_UL_indication(NR_UL_IND_t *UL_info) {
400
  AssertFatal(UL_info!=NULL,"UL_info is null\n");
401 402 403
#ifdef DUMP_FAPI
  dump_ul(UL_info);
#endif
404 405
  module_id_t      module_id   = UL_info->module_id;
  int              CC_id       = UL_info->CC_id;
406 407
  NR_Sched_Rsp_t   *sched_info = &NR_Sched_INFO[module_id][CC_id];
  NR_IF_Module_t   *ifi        = nr_if_inst[module_id];
408
  gNB_MAC_INST     *mac        = RC.nrmac[module_id];
409
  LOG_D(NR_PHY,"SFN/SLOT:%d.%d module_id:%d CC_id:%d UL_info[rach_pdus:%zu rx_ind:%zu crcs:%zu]\n",
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 449 450 451 452 453
        UL_info->frame, UL_info->slot,
        module_id, CC_id,
        gnb_rach_ind_queue.num_items,
        gnb_rx_ind_queue.num_items,
        gnb_crc_ind_queue.num_items);

  nfapi_nr_rach_indication_t *rach_ind = NULL;
  nfapi_nr_uci_indication_t *uci_ind = NULL;
  nfapi_nr_rx_data_indication_t *rx_ind = NULL;
  nfapi_nr_crc_indication_t *crc_ind = NULL;
  if (get_softmodem_params()->emulate_l1)
  {
    if (gnb_rach_ind_queue.num_items > 0) {
      LOG_I(NR_MAC, "gnb_rach_ind_queue size = %zu\n", gnb_rach_ind_queue.num_items);
      rach_ind = get_queue(&gnb_rach_ind_queue);
      UL_info->rach_ind = *rach_ind;
    }
    if (gnb_uci_ind_queue.num_items > 0) {
      LOG_I(NR_MAC, "gnb_uci_ind_queue size = %zu\n", gnb_uci_ind_queue.num_items);
      uci_ind = get_queue(&gnb_uci_ind_queue);
      UL_info->uci_ind = *uci_ind;
    }
    if (gnb_rx_ind_queue.num_items > 0 && gnb_crc_ind_queue.num_items > 0) {
      LOG_I(NR_MAC, "gnb_rx_ind_queue size = %zu and gnb_crc_ind_queue size = %zu\n",
            gnb_rx_ind_queue.num_items, gnb_crc_ind_queue.num_items);
      rx_ind = get_queue(&gnb_rx_ind_queue);
      int sfn_slot = NFAPI_SFNSLOT2HEX(rx_ind->sfn, rx_ind->slot);
      crc_ind = unqueue_matching(&gnb_crc_ind_queue,
                                 MAX_QUEUE_SIZE,
                                 crc_sfn_slot_matcher,
                                 &sfn_slot);
      if (!crc_ind) {
        LOG_I(NR_PHY, "No crc indication with the same SFN SLOT of rx indication %u %u\n", rx_ind->sfn, rx_ind->slot);
        requeue(&gnb_rx_ind_queue, rx_ind);
      }
      else {
        UL_info->rx_ind = *rx_ind;
        UL_info->crc_ind = *crc_ind;
        if (crc_ind->number_crcs != rx_ind->number_of_pdus) {
          match_crc_rx_pdu(&UL_info->rx_ind, &UL_info->crc_ind);
        }
      }
    }
  }
454

Rahul Gottipati's avatar
Rahul Gottipati committed
455 456 457 458 459 460
  handle_nr_rach(UL_info);
  handle_nr_uci(UL_info);
  // clear UL DCI prior to handling ULSCH
  mac->UL_dci_req[CC_id].numPdus = 0;
  handle_nr_ulsch(UL_info);

461 462 463
  if (get_softmodem_params()->emulate_l1) {
    free_unqueued_nfapi_indications(rach_ind, uci_ind, rx_ind, crc_ind);
  }
464
  if (NFAPI_MODE != NFAPI_MODE_PNF) {
Rahul Gottipati's avatar
Rahul Gottipati committed
465

466 467
    if (ifi->CC_mask==0) {
      ifi->current_frame    = UL_info->frame;
468
      ifi->current_slot = UL_info->slot;
469
    } else {
470
      AssertFatal(UL_info->frame != ifi->current_frame,"CC_mask %x is not full and frame has changed\n",ifi->CC_mask);
471
      AssertFatal(UL_info->slot != ifi->current_slot,"CC_mask %x is not full and slot has changed\n",ifi->CC_mask);
472
    }
473

474 475 476
    ifi->CC_mask |= (1<<CC_id);

    if (ifi->CC_mask == ((1<<MAX_NUM_CCs)-1)) {
477
      /*
478
      eNB_dlsch_ulsch_scheduler(module_id,
479 480
          (UL_info->frame+((UL_info->slot>(9-sl_ahead))?1:0)) % 1024,
          (UL_info->slot+sl_ahead)%10);
481
      */
482
      nfapi_nr_config_request_scf_t *cfg = &mac->config[CC_id];
483
      int spf = get_spf(cfg);
484
      gNB_dlsch_ulsch_scheduler(module_id,
485 486
				(UL_info->frame+((UL_info->slot>(spf-1-sl_ahead))?1:0)) % 1024,
				(UL_info->slot+sl_ahead)%spf);
487

488 489 490
      ifi->CC_mask            = 0;
      sched_info->module_id   = module_id;
      sched_info->CC_id       = CC_id;
491 492
      sched_info->frame       = (UL_info->frame + ((UL_info->slot>(spf-1-sl_ahead)) ? 1 : 0)) % 1024;
      sched_info->slot        = (UL_info->slot+sl_ahead)%spf;
493
      sched_info->DL_req      = &mac->DL_req[CC_id];
494
      sched_info->UL_dci_req  = &mac->UL_dci_req[CC_id];
495

496
      sched_info->UL_tti_req  = mac->UL_tti_req[CC_id];
497 498 499 500 501 502

      sched_info->TX_req      = &mac->TX_req[CC_id];
#ifdef DUMP_FAPI
      dump_dl(sched_info);
#endif

503 504 505 506 507
      AssertFatal(ifi->NR_Schedule_response!=NULL,
                  "nr_schedule_response is null (mod %d, cc %d)\n",
                  module_id,
                  CC_id);
      ifi->NR_Schedule_response(sched_info);
508

509
      LOG_D(NR_PHY,"NR_Schedule_response: SFN SLOT:%d %d dl_pdus:%d\n",
Raymond Knopp's avatar
Raymond Knopp committed
510 511
	    sched_info->frame,
	    sched_info->slot,
512
	    sched_info->DL_req->dl_tti_request_body.nPDUs);
513 514 515 516
    }
  }
}

517
NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {
518
  AssertFatal(Mod_id<MAX_MODULES,"Asking for Module %d > %d\n",Mod_id,MAX_IF_MODULES);
Raymond Knopp's avatar
Raymond Knopp committed
519
  LOG_I(PHY,"Installing callbacks for IF_Module - UL_indication\n");
520

521 522 523
  if (nr_if_inst[Mod_id]==NULL) {
    nr_if_inst[Mod_id] = (NR_IF_Module_t*)malloc(sizeof(NR_IF_Module_t));
    memset((void*)nr_if_inst[Mod_id],0,sizeof(NR_IF_Module_t));
524

525
    LOG_I(MAC,"Allocating shared L1/L2 interface structure for instance %d @ %p\n",Mod_id,nr_if_inst[Mod_id]);
526

527 528 529 530
    nr_if_inst[Mod_id]->CC_mask=0;
    nr_if_inst[Mod_id]->NR_UL_indication = NR_UL_indication;
    AssertFatal(pthread_mutex_init(&nr_if_inst[Mod_id]->if_mutex,NULL)==0,
                "allocation of nr_if_inst[%d]->if_mutex fails\n",Mod_id);
531
  }
532

533
  return nr_if_inst[Mod_id];
534
}