gNB_scheduler.c 23 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*
 * 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 gNB_scheduler.c
 * \brief gNB scheduler top level function operates on per subframe basis
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
24 25 26
 * \author  Navid Nikaein and Raymond Knopp, WEI-TAI CHEN
 * \date 2010 - 2014, 2018
 * \email: navid.nikaein@eurecom.fr, kroempa@gmail.com
27
 * \version 0.5
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
28
 * \company Eurecom, NTUST
29 30 31 32 33 34 35
 * @ingroup _mac

 */

#include "assertions.h"

#include "LAYER2/MAC/mac.h"
36
#include "NR_MAC_COMMON/nr_mac_extern.h"
37
#include "LAYER2/MAC/mac_proto.h"
38
#include "NR_MAC_gNB/mac_proto.h"
39

Raymond Knopp's avatar
Raymond Knopp committed
40 41
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
42 43 44 45
#include "UTIL/OPT/opt.h"
#include "OCG.h"
#include "OCG_extern.h"

46
#include "RRC/NR/nr_rrc_extern.h"
47 48 49 50

//#include "LAYER2/MAC/pre_processor.c"
#include "pdcp.h"

51
#include "openair1/PHY/defs_gNB.h"
52
#include "openair1/PHY/NR_TRANSPORT/nr_dlsch.h"
53

54 55 56 57 58 59
//Agent-related headers
#include "flexran_agent_extern.h"
#include "flexran_agent_mac.h"

#include "intertask_interface.h"

60
#include "executables/softmodem-common.h"
61

62
const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160};
63 64
uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 };

65
void clear_mac_stats(gNB_MAC_INST *gNB) {
66
  memset((void*)gNB->UE_info.mac_stats,0,MAX_MOBILES_PER_GNB*sizeof(NR_mac_stats_t));
67 68 69 70
}

void dump_mac_stats(gNB_MAC_INST *gNB) {

71
  NR_UE_info_t *UE_info = &gNB->UE_info;
72 73 74 75
  NR_mac_stats_t *stats;
  int lc_id;

  for (int UE_id=0;UE_id<MAX_MOBILES_PER_GNB;UE_id++) {
76 77 78
    if (UE_info->active[UE_id]) {
      LOG_I(MAC, "UE %x\n", UE_info->rnti[UE_id]);
      stats = &UE_info->mac_stats[UE_id];
79 80 81 82 83 84 85 86 87 88 89 90
      LOG_I(MAC,"dlsch_rounds %d/%d/%d/%d, dlsch_errors %d\n",stats->dlsch_rounds[0],stats->dlsch_rounds[1],stats->dlsch_rounds[2],stats->dlsch_rounds[3],stats->dlsch_errors);
      LOG_I(MAC,"dlsch_total_bytes %d\n",stats->dlsch_total_bytes);
      LOG_I(MAC,"ulsch_rounds %d/%d/%d/%d, ulsch_errors %d\n",stats->ulsch_rounds[0],stats->ulsch_rounds[1],stats->ulsch_rounds[2],stats->ulsch_rounds[3],stats->ulsch_errors);
      LOG_I(MAC,"ulsch_total_bytes_scheduled %d, ulsch_total_bytes_received %d\n",stats->ulsch_total_bytes_scheduled,stats->ulsch_total_bytes_rx);
      for (lc_id=0;lc_id<63;lc_id++) {
	if (stats->lc_bytes_tx[lc_id]>0) LOG_I(MAC,"LCID %d : %d bytes TX\n",lc_id,stats->lc_bytes_tx[lc_id]);
	if (stats->lc_bytes_rx[lc_id]>0) LOG_I(MAC,"LCID %d : %d bytes RX\n",lc_id,stats->lc_bytes_rx[lc_id]);
      }
    }
  }
}

91 92 93 94
void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
                                int CC_idP,
                                frame_t frameP,
                                sub_frame_t slotP){
95

Raymond Knopp's avatar
Raymond Knopp committed
96
  nfapi_nr_dl_tti_request_t    *DL_req = &gNB->DL_req[0];
97
  nfapi_nr_ul_tti_request_t    *UL_tti_req = &gNB->UL_tti_req[0];
98
  nfapi_nr_ul_dci_request_t    *UL_dci_req = &gNB->UL_dci_req[0];
Raymond Knopp's avatar
Raymond Knopp committed
99
  nfapi_nr_tx_data_request_t   *TX_req = &gNB->TX_req[0];
100 101 102 103 104

  gNB->pdu_index[CC_idP] = 0;

  if (nfapi_mode==0 || nfapi_mode == 1) { // monolithic or PNF

Raymond Knopp's avatar
Raymond Knopp committed
105 106 107 108 109
    DL_req[CC_idP].SFN                                   = frameP;
    DL_req[CC_idP].Slot                                  = slotP;
    DL_req[CC_idP].dl_tti_request_body.nPDUs             = 0;
    DL_req[CC_idP].dl_tti_request_body.nGroup            = 0;
    //DL_req[CC_idP].dl_tti_request_body.transmission_power_pcfich           = 6000;
110

111 112 113
    UL_dci_req[CC_idP].SFN                         = frameP;
    UL_dci_req[CC_idP].Slot                        = slotP;
    UL_dci_req[CC_idP].numPdus                     = 0;
114

Raymond Knopp's avatar
Raymond Knopp committed
115 116
    UL_tti_req[CC_idP].SFN                         = frameP;
    UL_tti_req[CC_idP].Slot                        = slotP;
117 118 119 120
    UL_tti_req[CC_idP].n_pdus                      = 0;
    UL_tti_req[CC_idP].n_ulsch                     = 0;
    UL_tti_req[CC_idP].n_ulcch                     = 0;
    UL_tti_req[CC_idP].n_group                     = 0;
121 122 123

    TX_req[CC_idP].Number_of_PDUs                  = 0;

124 125
  }
}
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
126
/*
127 128
void check_nr_ul_failure(module_id_t module_idP,
                         int CC_id,
129
                         int UE_id,
130
                         frame_t frameP,
131
                         sub_frame_t slotP) {
132

133
  NR_UE_info_t                 *UE_info  = &RC.nrmac[module_idP]->UE_info;
Raymond Knopp's avatar
Raymond Knopp committed
134
  nfapi_nr_dl_dci_request_t  *DL_req   = &RC.nrmac[module_idP]->DL_req[0];
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
135 136
  uint16_t                      rnti      = UE_RNTI(module_idP, UE_id);
  NR_COMMON_channels_t          *cc       = RC.nrmac[module_idP]->common_channels;
137 138

  // check uplink failure
139 140
  if ((UE_info->UE_sched_ctrl[UE_id].ul_failure_timer > 0) &&
      (UE_info->UE_sched_ctrl[UE_id].ul_out_of_sync == 0)) {
141
    LOG_I(MAC, "UE %d rnti %x: UL Failure timer %d \n", UE_id, rnti,
142 143 144
    UE_info->UE_sched_ctrl[UE_id].ul_failure_timer);
    if (UE_info->UE_sched_ctrl[UE_id].ra_pdcch_order_sent == 0) {
      UE_info->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 1;
145 146

      // add a format 1A dci for this UE to request an RA procedure (only one UE per subframe)
Raymond Knopp's avatar
Raymond Knopp committed
147 148
      nfapi_nr_dl_dci_request_pdu_t *dl_config_pdu                    = &DL_req[CC_id].dl_tti_request_body.dl_config_pdu_list[DL_req[CC_id].dl_tti_request_body.number_pdu];
      memset((void *) dl_config_pdu, 0,sizeof(nfapi_dl_dci_request_pdu_t));
149 150
      dl_config_pdu->pdu_type                                         = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
      dl_config_pdu->pdu_size                                         = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu));
Raymond Knopp's avatar
Raymond Knopp committed
151
      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag                = NFAPI_DL_DCI_REQUEST_DCI_DL_PDU_REL8_TAG;
152 153
      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format            = NFAPI_DL_DCI_FORMAT_1A;
      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level     = get_aggregation(get_bw_index(module_idP, CC_id),
154
                      UE_info->UE_sched_ctrl[UE_id].
155 156 157 158 159 160 161 162 163
                      dl_cqi[CC_id], format1A);
      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti                  = rnti;
      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type             = 1;  // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications
      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power    = 6000; // equal to RS power

      AssertFatal((cc[CC_id].mib->message.dl_Bandwidth >= 0) && (cc[CC_id].mib->message.dl_Bandwidth < 6),
      "illegal dl_Bandwidth %d\n",
      (int) cc[CC_id].mib->message.dl_Bandwidth);
      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = nr_pdcch_order_table[cc[CC_id].mib->message.dl_Bandwidth];
Raymond Knopp's avatar
Raymond Knopp committed
164 165 166
      DL_req[CC_id].dl_tti_request_body.number_dci++;
      DL_req[CC_id].dl_tti_request_body.number_pdu++;
      DL_req[CC_id].dl_tti_request_body.tl.tag                      = NFAPI_DL_TTI_REQUEST_BODY_TAG;
167 168 169
      LOG_I(MAC,
      "UE %d rnti %x: sending PDCCH order for RAPROC (failure timer %d), resource_block_coding %d \n",
      UE_id, rnti,
170
      UE_info->UE_sched_ctrl[UE_id].ul_failure_timer,
171 172 173 174 175 176
      dl_config_pdu->dci_dl_pdu.
      dci_dl_pdu_rel8.resource_block_coding);
    } else {    // ra_pdcch_sent==1
      LOG_I(MAC,
      "UE %d rnti %x: sent PDCCH order for RAPROC waiting (failure timer %d) \n",
      UE_id, rnti,
177 178
      UE_info->UE_sched_ctrl[UE_id].ul_failure_timer);
      if ((UE_info->UE_sched_ctrl[UE_id].ul_failure_timer % 40) == 0) UE_info->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 0;  // resend every 4 frames
179 180
    }

181
    UE_info->UE_sched_ctrl[UE_id].ul_failure_timer++;
182
    // check threshold
183
    if (UE_info->UE_sched_ctrl[UE_id].ul_failure_timer > 20000) {
184 185 186 187 188
      // inform RRC of failure and clear timer
      LOG_I(MAC,
      "UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n",
      UE_id, rnti);
      mac_eNB_rrc_ul_failure(module_idP, CC_id, frameP, subframeP,rnti);
189 190
      UE_info->UE_sched_ctrl[UE_id].ul_failure_timer = 0;
      UE_info->UE_sched_ctrl[UE_id].ul_out_of_sync   = 1;
191 192 193 194 195 196 197 198 199 200 201

      //Inform the controller about the UE deactivation. Should be moved to RRC agent in the future
      if (rrc_agent_registered[module_idP]) {
        LOG_W(MAC, "notify flexran Agent of UE state change\n");
        agent_rrc_xface[module_idP]->flexran_agent_notify_ue_state_change(module_idP,
            rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED);
      }
    }
  }       // ul_failure_timer>0

}
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
202
*/
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
203
/*
204 205 206
void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
{
  gNB_MAC_INST *gNB = RC.nrmac[module_idP];
207
  NR_UE_info_t *UE_info = &gNB->UE_info;
208 209
  nfapi_ul_config_request_body_t *ul_req;
  int CC_id, UE_id;
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
210
  NR_COMMON_channels_t *cc = RC.nrmac[module_idP]->common_channels;
211 212 213 214 215
  SoundingRS_UL_ConfigCommon_t *soundingRS_UL_ConfigCommon;
  struct SoundingRS_UL_ConfigDedicated *soundingRS_UL_ConfigDedicated;
  uint8_t TSFC;
  uint16_t deltaTSFC;   // bitmap
  uint8_t srs_SubframeConfig;
216

217 218 219
  // table for TSFC (Period) and deltaSFC (offset)
  const uint16_t deltaTSFCTabType1[15][2] = { {1, 1}, {1, 2}, {2, 2}, {1, 5}, {2, 5}, {4, 5}, {8, 5}, {3, 5}, {12, 5}, {1, 10}, {2, 10}, {4, 10}, {8, 10}, {351, 10}, {383, 10} };  // Table 5.5.3.3-2 3GPP 36.211 FDD
  const uint16_t deltaTSFCTabType2[14][2] = { {2, 5}, {6, 5}, {10, 5}, {18, 5}, {14, 5}, {22, 5}, {26, 5}, {30, 5}, {70, 10}, {74, 10}, {194, 10}, {326, 10}, {586, 10}, {210, 10} }; // Table 5.5.3.3-2 3GPP 36.211 TDD
220

221
  uint16_t srsPeriodicity, srsOffset;
222

223 224 225 226 227 228 229 230 231 232 233 234 235 236
  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
    soundingRS_UL_ConfigCommon = &cc[CC_id].radioResourceConfigCommon->soundingRS_UL_ConfigCommon;
    // check if SRS is enabled in this frame/subframe
    if (soundingRS_UL_ConfigCommon) {
      srs_SubframeConfig = soundingRS_UL_ConfigCommon->choice.setup.srs_SubframeConfig;
      if (cc[CC_id].tdd_Config == NULL) { // FDD
  deltaTSFC = deltaTSFCTabType1[srs_SubframeConfig][0];
  TSFC = deltaTSFCTabType1[srs_SubframeConfig][1];
      } else {    // TDD
  deltaTSFC = deltaTSFCTabType2[srs_SubframeConfig][0];
  TSFC = deltaTSFCTabType2[srs_SubframeConfig][1];
      }
      // Sounding reference signal subframes are the subframes satisfying ns/2 mod TSFC (- deltaTSFC
      uint16_t tmp = (subframeP % TSFC);
237

238 239 240
      if ((1 << tmp) & deltaTSFC) {
  // This is an SRS subframe, loop over UEs
  for (UE_id = 0; UE_id < MAX_MOBILES_PER_GNB; UE_id++) {
241
    if (!RC.nrmac[module_idP]->UE_info.active[UE_id]) continue;
242 243 244
    ul_req = &RC.nrmac[module_idP]->UL_req[CC_id].ul_config_request_body;
    // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet
    if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) continue;
245

246
    AssertFatal(UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL,
247 248
          "physicalConfigDedicated is null for UE %d\n",
          UE_id);
249

250
    if ((soundingRS_UL_ConfigDedicated = UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated) != NULL) {
251 252 253 254 255 256 257 258 259 260 261 262 263 264
      if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) {
        get_srs_pos(&cc[CC_id],
        soundingRS_UL_ConfigDedicated->choice.
        setup.srs_ConfigIndex,
        &srsPeriodicity, &srsOffset);
        if (((10 * frameP + subframeP) % srsPeriodicity) == srsOffset) {
    // Program SRS
    ul_req->srs_present = 1;
    nfapi_ul_config_request_pdu_t * ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus];
    memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t));
    ul_config_pdu->pdu_type =  NFAPI_UL_CONFIG_SRS_PDU_TYPE;
    ul_config_pdu->pdu_size =  2 + (uint8_t) (2 + sizeof(nfapi_ul_config_srs_pdu));
    ul_config_pdu->srs_pdu.srs_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG;
    ul_config_pdu->srs_pdu.srs_pdu_rel8.size = (uint8_t)sizeof(nfapi_ul_config_srs_pdu);
265
    ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti = UE_info->UE_template[CC_id][UE_id].rnti;
266 267 268 269 270 271 272 273 274 275 276 277
    ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth;
    ul_config_pdu->srs_pdu.srs_pdu_rel8.frequency_domain_position = soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition;
    ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth;;
    ul_config_pdu->srs_pdu.srs_pdu_rel8.transmission_comb = soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb;
    ul_config_pdu->srs_pdu.srs_pdu_rel8.i_srs = soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex;
    ul_config_pdu->srs_pdu.srs_pdu_rel8.sounding_reference_cyclic_shift = soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift;    //              ul_config_pdu->srs_pdu.srs_pdu_rel10.antenna_port                   = ;//
    //              ul_config_pdu->srs_pdu.srs_pdu_rel13.number_of_combs                = ;//
    RC.nrmac[module_idP]->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP;
    RC.nrmac[module_idP]->UL_req[CC_id].header.message_id = NFAPI_UL_CONFIG_REQUEST;
    ul_req->number_of_pdus++;
        } // if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset)
      } // if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup)
278
    }   // if ((soundingRS_UL_ConfigDedicated = UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL)
279 280
  }   // for (UE_id ...
      }     // if((1<<tmp) & deltaTSFC)
281

282 283 284
    }     // SRS config
  }
}
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
285
*/
286 287


288
/*
289
void copy_nr_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
290 291 292 293 294 295
{
  int CC_id;
  gNB_MAC_INST *mac = RC.nrmac[module_idP];

  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {

296
    nfapi_ul_config_request_t *ul_req                 = &mac->UL_tti_req[CC_id];
297 298 299 300 301

    *ul_req = *ul_req_tmp;

    // Restore the pointer
    ul_req->ul_config_request_body.ul_config_pdu_list = ul_req_pdu;
302
    ul_req->sfn_sf                                    = (frameP<<7) + slotP;
303 304 305 306
    ul_req_tmp->ul_config_request_body.number_of_pdus = 0;

    if (ul_req->ul_config_request_body.number_of_pdus>0)
      {
307
        LOG_D(PHY, "%s() active NOW (frameP:%d slotP:%d) pdus:%d\n", __FUNCTION__, frameP, slotP, ul_req->ul_config_request_body.number_of_pdus);
308 309 310 311 312 313 314
      }

    memcpy((void*)ul_req->ul_config_request_body.ul_config_pdu_list,
     (void*)ul_req_tmp->ul_config_request_body.ul_config_pdu_list,
     ul_req->ul_config_request_body.number_of_pdus*sizeof(nfapi_ul_config_request_pdu_t));
  }
}
315
*/
316

317
void nr_schedule_pusch(int Mod_idP,
318
                       int UE_id,
319 320
                       int num_slots_per_tdd,
                       int ul_slots,
321 322 323 324
                       frame_t frameP,
                       sub_frame_t slotP) {

  nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0];
325
  NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
326
  int k = slotP + ul_slots - num_slots_per_tdd;
327
  NR_sched_pusch *pusch = &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k];
328 329 330 331 332 333 334
  if ((pusch->active == true) && (frameP == pusch->frame) && (slotP == pusch->slot)) {
    UL_tti_req->SFN = pusch->frame;
    UL_tti_req->Slot = pusch->slot;
    UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
    UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
    UL_tti_req->pdus_list[UL_tti_req->n_pdus].pusch_pdu = pusch->pusch_pdu;
    UL_tti_req->n_pdus+=1;
335
    memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k],
336
           0, sizeof(NR_sched_pusch));
337 338 339
  }
}

340

341 342
void nr_schedule_pucch(int Mod_idP,
                       int UE_id,
343
                       int nr_ulmix_slots,
344
                       frame_t frameP,
345
                       sub_frame_t slotP) {
346

347 348
  uint16_t O_csi, O_ack, O_uci;
  uint8_t O_sr = 0; // no SR in PUCCH implemented for now
349
  NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
350
  NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
351
  AssertFatal(UE_info->active[UE_id],"Cannot find UE_id %d is not active\n",UE_id);
352

353
  NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id];
354 355 356 357
  int bwp_id=1;
  NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1];
  nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0];

358 359 360
  NR_sched_pucch *curr_pucch;

  for (int k=0; k<nr_ulmix_slots; k++) {
361
    for (int l=0; l<2; l++) {
362
      curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][l];
363
      O_ack = curr_pucch->dai_c;
364 365 366
      O_csi = curr_pucch->csi_bits;
      O_uci = O_ack + O_csi + O_sr;
      if ((O_uci>0) && (frameP == curr_pucch->frame) && (slotP == curr_pucch->ul_slot)) {
367 368 369 370 371 372 373 374
        UL_tti_req->SFN = curr_pucch->frame;
        UL_tti_req->Slot = curr_pucch->ul_slot;
        UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE;
        UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pucch_pdu_t);
        nfapi_nr_pucch_pdu_t  *pucch_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].pucch_pdu;
        memset(pucch_pdu,0,sizeof(nfapi_nr_pucch_pdu_t));
        UL_tti_req->n_pdus+=1;

375
        LOG_I(MAC,"Scheduling pucch reception for frame %d slot %d with (%d, %d, %d) (SR ACK, CSI) bits\n",
376
              frameP,slotP,O_sr,O_ack,curr_pucch->csi_bits);
377 378 379 380

        nr_configure_pucch(pucch_pdu,
                           scc,
                           ubwp,
381
                           UE_info->rnti[UE_id],
382
                           curr_pucch->resource_indicator,
383
                           O_csi,
384
                           O_ack,
385
                           O_sr);
386

387
        memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][l],
388 389 390
               0,
               sizeof(NR_sched_pucch));
      }
391 392 393 394
    }
  }
}

395 396
bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot) {
  return (bitmap >> slot) & 0x01;
397 398
}

399
void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
400 401
                               frame_t frame,
                               sub_frame_t slot){
402

403
  protocol_ctxt_t   ctxt;
404
  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frame, slot,module_idP);
405
 
406
  int nb_periods_per_frame;
407

408 409
  const int UE_id = 0;
  const int bwp_id = 1;
410

411
  gNB_MAC_INST *gNB = RC.nrmac[module_idP];
412 413
  NR_UE_info_t *UE_info = &gNB->UE_info;
  NR_UE_sched_ctrl_t *ue_sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
414
  NR_COMMON_channels_t *cc = gNB->common_channels;
415
  NR_ServingCellConfigCommon_t        *scc     = cc->ServingCellConfigCommon;
416
  NR_TDD_UL_DL_Pattern_t *tdd_pattern = &scc->tdd_UL_DL_ConfigurationCommon->pattern1;
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 454 455

  switch(scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity) {
    case 0:
      nb_periods_per_frame = 20; // 10ms/0p5ms
      break;

    case 1:
      nb_periods_per_frame = 16; // 10ms/0p625ms
      break;

    case 2:
      nb_periods_per_frame = 10; // 10ms/1ms
      break;

    case 3:
      nb_periods_per_frame = 8; // 10ms/1p25ms
      break;

    case 4:
      nb_periods_per_frame = 5; // 10ms/2ms
      break;

    case 5:
      nb_periods_per_frame = 4; // 10ms/2p5ms
      break;

    case 6:
      nb_periods_per_frame = 2; // 10ms/5ms
      break;

    case 7:
      nb_periods_per_frame = 1; // 10ms/10ms
      break;

    default:
      AssertFatal(1==0,"Undefined tdd period %d\n", scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity);
  }

  int num_slots_per_tdd = (slots_per_frame[*scc->ssbSubcarrierSpacing])/nb_periods_per_frame;
456

457
  const int nr_ulmix_slots = tdd_pattern->nrofUplinkSlots + (tdd_pattern->nrofUplinkSymbols!=0);
458

459
  start_meas(&RC.nrmac[module_idP]->eNB_scheduler);
Rakesh's avatar
Rakesh committed
460
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN);
461

462
  pdcp_run(&ctxt);
Cedric Roux's avatar
Cedric Roux committed
463
  /* send tick to RLC and RRC every ms */
464 465 466
  if ((slot & ((1 << *scc->ssbSubcarrierSpacing) - 1)) == 0) {
    void nr_rlc_tick(int frame, int subframe);
    nr_rlc_tick(frame, slot >> *scc->ssbSubcarrierSpacing);
Cedric Roux's avatar
Cedric Roux committed
467
    nr_rrc_trigger(&ctxt, 0 /*CC_id*/, frame, slot >> *scc->ssbSubcarrierSpacing);
468
  }
469

470
  const uint64_t dlsch_in_slot_bitmap = (1 << 1) | (1 << 2);
471
  const uint64_t ulsch_in_slot_bitmap = (1 << 8);
472

473 474
  memset(RC.nrmac[module_idP]->cce_list[bwp_id][0],0,MAX_NUM_CCE*sizeof(int)); // coreset0
  memset(RC.nrmac[module_idP]->cce_list[bwp_id][1],0,MAX_NUM_CCE*sizeof(int)); // coresetid 1
475 476
  for (int i=0; i<MAX_NUM_CORESET; i++)
    RC.nrmac[module_idP]->UE_info.num_pdcch_cand[UE_id][i] = 0;
477
  for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
478
    //mbsfn_status[CC_id] = 0;
479

480
    // clear vrb_maps
481 482
    memset(cc[CC_id].vrb_map, 0, sizeof(uint16_t) * 275);
    memset(cc[CC_id].vrb_map_UL, 0, sizeof(uint16_t) * 275);
483

484
    clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame, slot);
485
  }
486

487

488
  if ((slot == 0) && (frame & 127) == 0) dump_mac_stats(RC.nrmac[module_idP]);
489

490

491
  // This schedules MIB
492
  schedule_nr_mib(module_idP, frame, slot, slots_per_frame[*scc->ssbSubcarrierSpacing]);
493

494 495
  // This schedule PRACH if we are not in phy_test mode
  if (get_softmodem_params()->phy_test == 0)
496
    schedule_nr_prach(module_idP, frame, slot);
497

498 499
  // This schedule SR
  // TODO
500

501
  // This schedule CSI measurement reporting
502
  if (UE_info->active[UE_id])
503
    nr_csi_meas_reporting(module_idP, UE_id, frame, slot, num_slots_per_tdd, nr_ulmix_slots, slots_per_frame[*scc->ssbSubcarrierSpacing]);
504

505 506
  // This schedule RA procedure if not in phy_test mode
  // Otherwise already consider 5G already connected
507
  RC.nrmac[module_idP]->current_slot=slot;
508
  if (get_softmodem_params()->phy_test == 0) {
Chenyu's avatar
Chenyu committed
509
    nr_schedule_RA(module_idP, frame, slot, num_slots_per_tdd);
510
    nr_schedule_reception_msg3(module_idP, 0, frame, slot);
511

512
  }
513 514

  // This schedules the DCI for Uplink and subsequently PUSCH
515

516 517
  // The decision about whether to schedule is done for each UE independently
  // inside
518
  if (UE_info->active[UE_id] && slot < 10) {
519

520
    int tda = 1; // time domain assignment hardcoded for now
521
    schedule_fapi_ul_pdu(module_idP, frame, slot, num_slots_per_tdd, nr_ulmix_slots, tda, ulsch_in_slot_bitmap);
522
    nr_schedule_pusch(module_idP, UE_id, num_slots_per_tdd, nr_ulmix_slots, frame, slot);
523 524
  }

525

526
  if (UE_info->active[UE_id]
527
      && (is_xlsch_in_slot(dlsch_in_slot_bitmap, slot % num_slots_per_tdd))
Chenyu's avatar
Chenyu committed
528
      && slot < 10 && slot == 1) {
529

530
    ue_sched_ctl->current_harq_pid = slot % num_slots_per_tdd;
531
    nr_schedule_ue_spec(module_idP, frame, slot, num_slots_per_tdd);
532 533
  }

Laurent's avatar
Laurent committed
534

535
  if (UE_info->active[UE_id])
536
    nr_schedule_pucch(module_idP, UE_id, nr_ulmix_slots, frame, slot);
537

538
  stop_meas(&RC.nrmac[module_idP]->eNB_scheduler);
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
539
  
Rakesh's avatar
Rakesh committed
540
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT);
Raymond Knopp's avatar
Raymond Knopp committed
541
}