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

/*! \file eNB_scheduler.c
nikaeinn's avatar
nikaeinn committed
23
 * \brief eNB scheduler top level function operates on per subframe basis
24
25
 * \author  Navid Nikaein and Raymond Knopp
 * \date 2010 - 2014
26
 * \email: navid.nikaein@eurecom.fr
27
28
 * \version 0.5
 * @ingroup _mac
29

30
 */
31

32
#include "assertions.h"
33
34
35
36
37
38
39
40
#include "PHY/defs.h"
#include "PHY/extern.h"

#include "SCHED/defs.h"
#include "SCHED/extern.h"

#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/extern.h"
gauthier's avatar
gauthier committed
41

42
43
44
45
46
47
#include "LAYER2/MAC/proto.h"
#include "UTIL/LOG/log.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
#include "OCG.h"
#include "OCG_extern.h"
gauthier's avatar
gauthier committed
48

49
50
#include "RRC/LITE/extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
gauthier's avatar
gauthier committed
51

52
53
//#include "LAYER2/MAC/pre_processor.c"
#include "pdcp.h"
54

55
#if defined(FLEXRAN_AGENT_SB_IF)
56
//Agent-related headers
57
58
59
#include "flexran_agent_extern.h"
#include "flexran_agent_mac.h"
#include "flexran_agent_mac_proto.h"
60
#endif
61

62
63
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
64
65
#endif

66
67
#define ENABLE_MAC_PAYLOAD_DEBUG
#define DEBUG_eNB_SCHEDULER 1
68

69
extern RAN_CONTEXT_t RC;
70

71
72
uint16_t pdcch_order_table[6] = {31,31,511,2047,2047,8191};

73

74
75
void schedule_SRS(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
{
76
77
78
  eNB_MAC_INST                   *eNB            = RC.mac[module_idP];
  UE_list_t                      *UE_list        = &eNB->UE_list;
  nfapi_ul_config_request_body_t *ul_req;
79
  int CC_id,UE_id;
80
81
82
83
84
85
  COMMON_channels_t                   *cc        = RC.mac[module_idP]->common_channels;
  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;
86

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
  // 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

  uint16_t srsPeriodicity,srsOffset;

  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);

      if((1<<tmp) & deltaTSFC) {
	// This is an SRS subframe, loop over UEs
111
112
	for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
	  if (RC.mac[module_idP]->UE_list.active[UE_id]!=TRUE) continue;
113
	  ul_req        = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body;
114
115


116
117
118
          // 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;

119
	  AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",UE_id);
120

121
122
123
124
125
126
	  if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL) {
	    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) {
		// Prorgram SRS
		ul_req->srs_present                                                 = 1;
127
		nfapi_ul_config_request_pdu_t* ul_config_pdu                        = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus];
128
129
130
131
132
133
134
135
136
		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.size                            = (uint8_t)sizeof(nfapi_ul_config_srs_pdu);;
		ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti                            = UE_list->UE_template[CC_id][UE_id].rnti;
		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;
137
138
		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;
139
140
141
142
		//		ul_config_pdu->srs_pdu.srs_pdu_rel10.antenna_port                   = ;//
		//		ul_config_pdu->srs_pdu.srs_pdu_rel13.number_of_combs                = ;//
		RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP<<4)+subframeP;
		ul_req->number_of_pdus++;
143
144
145
	      } // if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset)
	    } // if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup)
	  } // if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL)
146
147
148
149
150
151
152
	} // for (UE_id ...
      } // if((1<<tmp) & deltaTSFC)

    }// SRS config
  }
}

153
154
void schedule_CSI(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
{
155
156
157
158
  eNB_MAC_INST                   *eNB          = RC.mac[module_idP];
  UE_list_t                      *UE_list      = &eNB->UE_list;
  COMMON_channels_t              *cc;
  nfapi_ul_config_request_body_t *ul_req;
159
  int CC_id,UE_id;
160
161
162
163
164
165
166
  struct CQI_ReportPeriodic *cqi_ReportPeriodic;
  uint16_t Npd,N_OFFSET_CQI;
  int H;

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

    cc = &eNB->common_channels[CC_id];
167
168
    for (UE_id=0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
      if (UE_list->active[UE_id] != TRUE) continue;
169
170
171

      ul_req        = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body;

Cedric Roux's avatar
Cedric Roux committed
172
173
174
      // 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;

175
176
177
178
179
180
181
182
      AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",UE_id);

      if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig) {
	if ((cqi_ReportPeriodic = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic)!=NULL &&
	    (cqi_ReportPeriodic->present!=CQI_ReportPeriodic_PR_release)) {
	  //Rel8 Periodic CQI/PMI/RI reporting

	  get_csi_params(cc,cqi_ReportPeriodic,&Npd,&N_OFFSET_CQI,&H);
183

184
185
186
	  if ((((frameP*10)+subframeP)%Npd) == N_OFFSET_CQI) {  // CQI opportunity
	    UE_list->UE_sched_ctrl[UE_id].feedback_cnt[CC_id]=(((frameP*10)+subframeP)/Npd)%H;
	    // Program CQI
187
	    nfapi_ul_config_request_pdu_t* ul_config_pdu                                     = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus];
188
189
190
191
192
193
194
195
196
197
198
199
200
201
	    memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t));
	    ul_config_pdu->pdu_type                                                          = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE;
	    ul_config_pdu->pdu_size                                                          = 2+(uint8_t)(2+sizeof(nfapi_ul_config_uci_cqi_pdu));
	    ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti               = UE_list->UE_template[CC_id][UE_id].rnti;
	    ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index      = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex;
	    ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size  = get_rel8_dl_cqi_pmi_size(&UE_list->UE_sched_ctrl[UE_id],
															CC_id,
															cc,
															get_tmode(module_idP,CC_id,UE_id),
															cqi_ReportPeriodic);
	    ul_req->number_of_pdus++;

#if defined(Rel10) || defined(Rel14)
	    // PUT rel10-13 UCI options here
202
#endif
203
204
205
206
207
	  }
	  else if ((cqi_ReportPeriodic->choice.setup.ri_ConfigIndex) &&
		   ((((frameP*10)+subframeP)%((H*Npd)<<(*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex/161)))==
		    N_OFFSET_CQI + (*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex%161))) {  // RI opportunity
	    // Program RI
208
	    nfapi_ul_config_request_pdu_t* ul_config_pdu                                     = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus];
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
	    memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t));
	    ul_config_pdu->pdu_type                                                          = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE;
	    ul_config_pdu->pdu_size                                                          = 2+(uint8_t)(2+sizeof(nfapi_ul_config_uci_cqi_pdu));
	    ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti               = UE_list->UE_template[CC_id][UE_id].rnti;
	    ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index      = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex;
	    ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size  = (cc->p_eNB==2)?1:2;
	    RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP<<4)+subframeP;
	    ul_req->number_of_pdus++;
	  }

	} // if ((cqi_ReportPeriodic = cqi_ReportConfig->cqi_ReportPeriodic)!=NULL) {
      } // if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig)
    } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
  } // for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
}

225
226
227
228
void schedule_SR(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
{
  eNB_MAC_INST                   *eNB        = RC.mac[module_idP];
  UE_list_t                      *UE_list    = &eNB->UE_list;
229
  nfapi_ul_config_request_body_t *ul_req;
230
231
  int                             CC_id;
  int                             UE_id;
232
  SchedulingRequestConfig_t      *SRconfig;
233
234
235
236
  int                             skip_ue;
  int                             is_harq;
  nfapi_ul_config_sr_information  sr;
  int                             i;
237

238
239
  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
    RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP;
240

241
242
    for (UE_id = 0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
      if (RC.mac[module_idP]->UE_list.active[UE_id]!=TRUE) continue;
243
244
245
246
247

      ul_req        = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body;

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

248
249
250
      // 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;

251
      if ((SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig)!=NULL) {
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
        if (SRconfig->present == SchedulingRequestConfig_PR_setup) {
          if (SRconfig->choice.setup.sr_ConfigIndex <= 4) {        // 5 ms SR period
            if ((subframeP%5) != SRconfig->choice.setup.sr_ConfigIndex)
              continue;
          } else if (SRconfig->choice.setup.sr_ConfigIndex <= 14) { // 10 ms SR period
            if (subframeP!=(SRconfig->choice.setup.sr_ConfigIndex-5))
              continue;
          } else if (SRconfig->choice.setup.sr_ConfigIndex <= 34) { // 20 ms SR period
            if ((10*(frameP&1)+subframeP) != (SRconfig->choice.setup.sr_ConfigIndex-15))
              continue;
          } else if (SRconfig->choice.setup.sr_ConfigIndex <= 74) { // 40 ms SR period
            if ((10*(frameP&3)+subframeP) != (SRconfig->choice.setup.sr_ConfigIndex-35))
              continue;
          } else if (SRconfig->choice.setup.sr_ConfigIndex <= 154) { // 80 ms SR period
            if ((10*(frameP&7)+subframeP) != (SRconfig->choice.setup.sr_ConfigIndex-75))
              continue;
          }
        } // SRconfig->present == SchedulingRequestConfig_PR_setup)
      } // SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig)!=NULL)
271
272
273

      // if we get here there is some PUCCH1 reception to schedule for SR

274
275
      skip_ue=0;
      is_harq = 0;
276
      // check that there is no existing UL grant for ULSCH which overrides the SR
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
      for (i = 0; i < ul_req->number_of_pdus; i++) {
        if (((ul_req->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE)||
             (ul_req->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE)||
             (ul_req->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE)||
             (ul_req->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE))&&
            (ul_req->ul_config_pdu_list[i].ulsch_pdu.ulsch_pdu_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) {
            skip_ue=1;
            break;
        }
        /* if there is already an HARQ pdu, convert to SR_HARQ */
        else if ((ul_req->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE)&&
                 (ul_req->ul_config_pdu_list[i].uci_harq_pdu.ue_information.ue_information_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) {
          is_harq = 1;
          break;
        }
      }
293
294

      // drop the allocation because ULSCH with handle it with BSR
295
      if (skip_ue==1) continue;
296

297
      LOG_D(MAC,"Frame %d, Subframe %d : Scheduling SR for UE %d/%x\n",frameP,subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].rnti);
298
299
300
301

      // check Rel10 or Rel8 SR
#if defined(Rel10) || defined(Rel14)
      if ((UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2) &&
302
303
304
305
306
          (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020)&&
          (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020)) {
        sr.sr_information_rel10.number_of_pucch_resources = 1;
        sr.sr_information_rel10.pucch_index_p1 = *UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020->sr_PUCCH_ResourceIndexP1_r10;
      } else
307
#endif
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
      {
        sr.sr_information_rel8.pucch_index = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex;
      }

      /* if there is already an HARQ pdu, convert to SR_HARQ */
      if (is_harq) {
        nfapi_ul_config_harq_information h = ul_req->ul_config_pdu_list[i].uci_harq_pdu.harq_information;
        ul_req->ul_config_pdu_list[i].pdu_type                         = NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE;
        ul_req->ul_config_pdu_list[i].uci_sr_harq_pdu.sr_information   = sr;
        ul_req->ul_config_pdu_list[i].uci_sr_harq_pdu.harq_information = h;
      } else {
        ul_req->ul_config_pdu_list[ul_req->number_of_pdus].pdu_type                                           = NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE;
        ul_req->ul_config_pdu_list[ul_req->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti;
        ul_req->ul_config_pdu_list[ul_req->number_of_pdus].uci_sr_pdu.sr_information                          = sr;
        ul_req->number_of_pdus++;
      } /* if (is_harq) */
324
325
326
327
    } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id])
  } // for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++)
}

328
void check_ul_failure(module_id_t module_idP,int CC_id,int UE_id,
329
330
		      frame_t frameP, sub_frame_t subframeP)
{
331
  UE_list_t                           *UE_list      = &RC.mac[module_idP]->UE_list;
332
  nfapi_dl_config_request_t           *DL_req       = &RC.mac[module_idP]->DL_req[0];
333
334
335
336
337
338
  uint16_t                            rnti          = UE_RNTI(module_idP,UE_id);
  COMMON_channels_t                   *cc           = RC.mac[module_idP]->common_channels;

  // check uplink failure
  if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer>0)&&
      (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync==0)) {
339
    LOG_I(MAC,"UE %d rnti %x: UL Failure timer %d \n",UE_id,rnti,UE_list->UE_sched_ctrl[UE_id].ul_failure_timer);
340
341
    if (UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent==0) {
      UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent=1;
342

343
      // add a format 1A dci for this UE to request an RA procedure (only one UE per subframe)
344
      nfapi_dl_config_request_pdu_t* dl_config_pdu                    = &DL_req[CC_id].dl_config_request_body.dl_config_pdu_list[DL_req[CC_id].dl_config_request_body.number_pdu];
345
      memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
346
      dl_config_pdu->pdu_type                                         = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
347
      dl_config_pdu->pdu_size                                         = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu));
348
      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format            = NFAPI_DL_DCI_FORMAT_1A;
Cedric Roux's avatar
Cedric Roux committed
349
      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level     = get_aggregation(get_bw_index(module_idP,CC_id),UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id],format1A);
350
351
352
      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
353

354
355
356
      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 = pdcch_order_table[cc[CC_id].mib->message.dl_Bandwidth];
357
358
      DL_req[CC_id].dl_config_request_body.number_dci++;
      DL_req[CC_id].dl_config_request_body.number_pdu++;
359
      LOG_I(MAC,"UE %d rnti %x: sending PDCCH order for RAPROC (failure timer %d), resource_block_coding %d \n",UE_id,rnti,UE_list->UE_sched_ctrl[UE_id].ul_failure_timer,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding);
360
361
    }
    else { // ra_pdcch_sent==1
362
      LOG_I(MAC,"UE %d rnti %x: sent PDCCH order for RAPROC waiting (failure timer %d) \n",UE_id,rnti,UE_list->UE_sched_ctrl[UE_id].ul_failure_timer);
363
      if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer % 40) == 0)
364
	UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent=0; // resend every 4 frames
365
    }
366

367
368
369
370
    UE_list->UE_sched_ctrl[UE_id].ul_failure_timer++;
    // check threshold
    if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 200) {
      // inform RRC of failure and clear timer
371
      LOG_I(MAC,"UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n",UE_id,rnti);
372
373
374
375
376
377
      mac_eNB_rrc_ul_failure(module_idP,CC_id,frameP,subframeP,rnti);
      UE_list->UE_sched_ctrl[UE_id].ul_failure_timer=0;
      UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync=1;
    }
  } // ul_failure_timer>0

378
}
379

380
381
void clear_nfapi_information(eNB_MAC_INST *eNB,int CC_idP,frame_t frameP,sub_frame_t subframeP)
{
382
383
384
385
  nfapi_dl_config_request_t *DL_req         = &eNB->DL_req[0];
  nfapi_ul_config_request_t *UL_req         = &eNB->UL_req[0];
  nfapi_hi_dci0_request_t   *HI_DCI0_req    = &eNB->HI_DCI0_req[0];
  nfapi_tx_request_t        *TX_req         = &eNB->TX_req[0];
386

387

388
389
390
391
392
393
  eNB->pdu_index[CC_idP]                                     = 0;
  DL_req[CC_idP].dl_config_request_body.number_pdcch_ofdm_symbols           = 1;
  DL_req[CC_idP].dl_config_request_body.number_dci                          = 0;
  DL_req[CC_idP].dl_config_request_body.number_pdu                          = 0;
  DL_req[CC_idP].dl_config_request_body.number_pdsch_rnti                   = 0;
  DL_req[CC_idP].dl_config_request_body.transmission_power_pcfich           = 6000;
394

Cedric Roux's avatar
bugfix    
Cedric Roux committed
395
  HI_DCI0_req[CC_idP].hi_dci0_request_body.sfnsf                            = subframeP + (frameP<<4);
396
  HI_DCI0_req[CC_idP].hi_dci0_request_body.number_of_dci                    = 0;
397
398


399
400
401
  UL_req[CC_idP].ul_config_request_body.number_of_pdus                      = 0;
  UL_req[CC_idP].ul_config_request_body.rach_prach_frequency_resources      = 0; // ignored, handled by PHY for now
  UL_req[CC_idP].ul_config_request_body.srs_present                         = 0; // ignored, handled by PHY for now
402

403

404
405
  TX_req[CC_idP].tx_request_body.number_of_pdus                 = 0;

406
407
408

}

409
410
void copy_ulreq(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
{
411
412
413
414
415
416
417
418
419
420
421
  int CC_id;
  eNB_MAC_INST *eNB;
  nfapi_ul_config_request_body_t *ul_req_tmp;
  nfapi_ul_config_request_body_t *ul_req;

  eNB = RC.mac[module_idP];

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

    ul_req_tmp       = &eNB->UL_req_tmp[CC_id][subframeP].ul_config_request_body;
    ul_req           = &eNB->UL_req[CC_id].ul_config_request_body;
422

423
424
425
426
427
428
429
    eNB->UL_req[CC_id].sfn_sf   = (frameP<<4) + subframeP;
    ul_req->number_of_pdus                     = ul_req_tmp->number_of_pdus;
    ul_req_tmp->number_of_pdus = 0;

    memcpy((void*)ul_req->ul_config_pdu_list,
	   (void*)ul_req_tmp->ul_config_pdu_list,
	   ul_req->number_of_pdus*sizeof(nfapi_ul_config_request_pdu_t));
430

431
  }
432
433
}

434
void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
435
{
436

knopp's avatar
   
knopp committed
437
  int mbsfn_status[MAX_NUM_CCs];
438
  protocol_ctxt_t   ctxt;
439

440
  int CC_id,i; //,next_i;
441
  UE_list_t *UE_list=&RC.mac[module_idP]->UE_list;
442
  rnti_t rnti;
443

444
  COMMON_channels_t         *cc             = RC.mac[module_idP]->common_channels;
445

446
#if defined(FLEXRAN_AGENT_SB_IF)
447
  Protocol__FlexranMessage *msg;
448
#endif
449

450

451
  start_meas(&RC.mac[module_idP]->eNB_scheduler);
gauthier's avatar
gauthier committed
452
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN);
453

454
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
knopp's avatar
   
knopp committed
455
    mbsfn_status[CC_id]=0;
456
457

    // clear vrb_maps
knopp's avatar
knopp committed
458
    memset(cc[CC_id].vrb_map,0,100);
459
    memset(cc[CC_id].vrb_map_UL,0,100);
460

461

Cedric Roux's avatar
Cedric Roux committed
462
#if defined(Rel10) || defined(Rel14)
knopp's avatar
knopp committed
463
    cc[CC_id].mcch_active =0;
464
#endif
465
466
    RC.mac[module_idP]->frame    = frameP;
    RC.mac[module_idP]->subframe = subframeP;
467
468

    clear_nfapi_information(RC.mac[module_idP],CC_id,frameP,subframeP);
469
470
  }

knopp's avatar
   
knopp committed
471
  // refresh UE list based on UEs dropped by PHY in previous subframe
472
473
  for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
    if (UE_list->active[i] != TRUE) continue;
474

475
476
477
    rnti         = UE_RNTI(module_idP, i);
    CC_id        = UE_PCCID(module_idP, i);

478
    if ((frameP==0)&&(subframeP==0)) {
knopp's avatar
knopp committed
479
      LOG_I(MAC,"UE  rnti %x : %s, PHR %d dB DL CQI %d PUSCH SNR %d PUCCH SNR %d\n", rnti,
480
481
            UE_list->UE_sched_ctrl[i].ul_out_of_sync==0 ? "in synch" : "out of sync",
            UE_list->UE_template[CC_id][i].phr_info,
knopp's avatar
knopp committed
482
483
            UE_list->UE_sched_ctrl[i].dl_cqi[CC_id],
	    (UE_list->UE_sched_ctrl[i].pusch_snr[CC_id]-128)/2,
484
	    (UE_list->UE_sched_ctrl[i].pucch1_snr[CC_id]-128)/2);
485
    }
486

487
    RC.eNB[module_idP][CC_id]->pusch_stats_bsr[i][(frameP*10)+subframeP]=-63;
488
    if (i==UE_list->head)
489
      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR,RC.eNB[module_idP][CC_id]->pusch_stats_bsr[i][(frameP*10)+subframeP]);
490
    // increment this, it is cleared when we receive an sdu
491
    RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ul_inactivity_timer++;
492

493
    RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer++;
494
    LOG_D(MAC,"UE %d/%x : ul_inactivity %d, cqi_req %d\n",i,rnti,
knopp's avatar
knopp committed
495
496
	  RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ul_inactivity_timer,
	  RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer);
497
498
    check_ul_failure(module_idP,CC_id,i,frameP,subframeP);

knopp's avatar
   
knopp committed
499
  }
500

501
  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frameP, subframeP,module_idP);
502
  pdcp_run(&ctxt);
503

504
505
  rrc_rx_tx(&ctxt,
            0, // eNB index, unused in eNB
506
            CC_id);
507

Cedric Roux's avatar
Cedric Roux committed
508
#if defined(Rel10) || defined(Rel14)
509
510

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
knopp's avatar
knopp committed
511
    if (cc[CC_id].MBMS_flag >0) {
512
      start_meas(&RC.mac[module_idP]->schedule_mch);
513
      mbsfn_status[CC_id] = schedule_MBMS(module_idP,CC_id,frameP,subframeP);
514
      stop_meas(&RC.mac[module_idP]->schedule_mch);
knopp's avatar
   
knopp committed
515
    }
516
  }
517

518
#endif
519

520
521
  // This schedules MIB
  if ((subframeP==0) && (frameP&3) == 0) schedule_mib(module_idP,frameP,subframeP);
522
  // This schedules SI for legacy LTE and eMTC starting in subframeP
523
  schedule_SI(module_idP,frameP,subframeP);
524
  // This schedules Random-Access for legacy LTE and eMTC starting in subframeP
525
  schedule_RA(module_idP,frameP,subframeP);
526
527
528
529
530
  // copy previously scheduled UL resources (ULSCH + HARQ)
  copy_ulreq(module_idP,frameP,subframeP);
  // This schedules SRS in subframeP
  schedule_SRS(module_idP,frameP,subframeP);
  // This schedules ULSCH in subframeP (dci0)
531
  schedule_ulsch(module_idP,frameP,subframeP);
532
533
534
535
  // This schedules UCI_SR in subframeP
  schedule_SR(module_idP,frameP,subframeP);
  // This schedules UCI_CSI in subframeP
  schedule_CSI(module_idP, frameP, subframeP);
536

537
  // This schedules DLSCH in subframeP
538
539
  schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);

540
  // Allocate CCEs for good after scheduling is done
541

542
543
  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) allocate_CCEs(module_idP,CC_id,subframeP,0);
  
544

545
  stop_meas(&RC.mac[module_idP]->eNB_scheduler);
546

gauthier's avatar
gauthier committed
547
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT);
548
}