diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
index 3b502167ef4d57bb2a0993791186129715d4bd50..fce11235a1d353bf72aa7d0c1cb0b235efc76efa 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
@@ -1234,12 +1234,16 @@ schedule_ulsch(module_id_t module_idP,
 
   /* Note: RC.nb_mac_CC[module_idP] should be lower than or equal to NFAPI_CC_MAX */
   for (int CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++, cc++) {
-    first_rb[CC_id] = 1;  // leave out first RB for PUCCH
-
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
     first_rb[CC_id] = (emtc_active[CC_id] == 1) ? 7 : 1;
 #else
-    first_rb[CC_id] = 1;
+    /* Note: the size of PUCCH is arbitrary, to be done properly. */
+    switch (RC.eNB[module_idP][CC_id]->frame_parms.N_RB_DL) {
+    case 25:  first_rb[CC_id] = 1; break; // leave out first RB for PUCCH
+    case 50:  first_rb[CC_id] = 2; break; // leave out first RB for PUCCH
+    case 100: first_rb[CC_id] = 3; break; // leave out first RB for PUCCH
+    default: LOG_E(MAC, "nb RBs not handled, todo.\n"); exit(1);
+    }
 #endif
 
     RA_t *ra_ptr = cc->ra;
@@ -1351,6 +1355,7 @@ schedule_ulsch_rnti(module_id_t module_idP,
 
   if (sched_subframeP < subframeP) {
     sched_frame++;
+    sched_frame %= 1024;
   }
 
   /* NFAPI struct init */
@@ -1366,6 +1371,21 @@ schedule_ulsch_rnti(module_id_t module_idP,
   /* Note: RC.nb_mac_CC[module_idP] should be lower than or equal to NFAPI_CC_MAX */
   for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) {
     n_rb_ul_tab[CC_id] = to_prb(cc[CC_id].ul_Bandwidth); // return total number of PRB
+    /* HACK: let's remove the PUCCH from available RBs
+     * we suppose PUCCH size is:
+     * - for 25 RBs: 1 RB (top and bottom of ressource grid)
+     * - for 50:     2 RBs
+     * - for 100:    3 RBs
+     * This is totally arbitrary and might even be wrong.
+     * We suppose 'first_rb[]' has been correctly populated by the caller,
+     * so we only remove the top part of the resource grid.
+     */
+    switch (n_rb_ul_tab[CC_id]) {
+    case 25:  n_rb_ul_tab[CC_id] -= 1; break;
+    case 50:  n_rb_ul_tab[CC_id] -= 2; break;
+    case 100: n_rb_ul_tab[CC_id] -= 3; break;
+    default: LOG_E(MAC, "RBs setting not handled. Todo.\n"); exit(1);
+    }
     UE_list->first_rb_offset[CC_id][slice_idx] = cmin(n_rb_ul_tab[CC_id], sli->ul[slice_idx].first_rb);
   }
 
@@ -1374,7 +1394,7 @@ schedule_ulsch_rnti(module_id_t module_idP,
    * pre_assigned_mcs_ul
    * pre_allocated_rb_table_index_ul
    */
-  ulsch_scheduler_pre_processor(module_idP, slice_idx, frameP, subframeP, sched_subframeP, first_rb);
+  ulsch_scheduler_pre_processor(module_idP, slice_idx, frameP, subframeP, sched_frame, sched_subframeP, first_rb);
 
   for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) {
     first_rb_slice[CC_id] = first_rb[CC_id] + UE_list->first_rb_offset[CC_id][slice_idx];
@@ -1467,7 +1487,7 @@ schedule_ulsch_rnti(module_id_t module_idP,
         /* New transmission */
         if (round_index == 0) {
           /* Be sure that there are some free RBs */
-          if (first_rb_slice[CC_id] >= n_rb_ul_tab[CC_id] - 1) {
+          if (first_rb_slice[CC_id] >= n_rb_ul_tab[CC_id]) {
             LOG_W(MAC, "[eNB %d] frame %d, subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n",
               module_idP,
               frameP,
@@ -1903,7 +1923,20 @@ schedule_ulsch_rnti(module_id_t module_idP,
             sched_frame,
             sched_subframeP,
             cqi_req);
-        }  // end of round > 0
+
+          /* HACK: RBs used by retransmission have to be reserved.
+           * The current mechanism uses the notion of 'first_rb', so
+           * we skip all RBs below the ones retransmitted. This is
+           * not correct. Imagine only RB 23 is retransmitted, then all
+           * RBs < 23 will be marked unusable for new transmissions (case where round == 0).
+           * Note also that this code works only if the preprocessor orders
+           * UEs with retransmission with higher priority than UEs with new
+           * transmission.
+           * All this should be cleaned up properly.
+           */
+          if (first_rb_slice[CC_id] < UE_template_ptr->first_rb_ul[harq_pid] + UE_template_ptr->nb_rb_ul[harq_pid])
+            first_rb_slice[CC_id] = UE_template_ptr->first_rb_ul[harq_pid] + UE_template_ptr->nb_rb_ul[harq_pid];
+        }  // end of round > 0 
       }  // UE_is_to_be_scheduled
     }  // loop over all active CC_ids
   }  // loop over UE_ids
diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h
index 8943a21d60ae6d349610c63fab4991a76db11945..e902065ad1dbed1dead166628bd72a1c6854475b 100644
--- a/openair2/LAYER2/MAC/mac_proto.h
+++ b/openair2/LAYER2/MAC/mac_proto.h
@@ -711,8 +711,6 @@ int rrc_mac_remove_ue(module_id_t Mod_id, rnti_t rntiP);
 void store_dlsch_buffer(module_id_t Mod_id, int slice_idx, frame_t frameP, sub_frame_t subframeP);
 void assign_rbs_required(module_id_t Mod_id, int slice_idx, frame_t frameP, sub_frame_t subframe, uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], int min_rb_unit[NFAPI_CC_MAX]);
 
-int maxround(module_id_t Mod_id, uint16_t rnti, int frame,
-	     sub_frame_t subframe, uint8_t ul_flag);
 void swap_UEs(UE_list_t * listP, int nodeiP, int nodejP, int ul_flag);
 int prev(UE_list_t * listP, int nodeP, int ul_flag);
 void dump_ue_list(UE_list_t * listP, int ul_flag);
@@ -730,11 +728,11 @@ void set_ul_DAI(int module_idP,
 
 void ulsch_scheduler_pre_processor(module_id_t module_idP, int slice_idx, int frameP,
 				   sub_frame_t subframeP,
+                                   int sched_frameP,
                                    unsigned char sched_subframeP,
 				   uint16_t * first_rb);
 void store_ulsch_buffer(module_id_t module_idP, int frameP,
 			sub_frame_t subframeP);
-void sort_ue_ul(module_id_t module_idP, int slice_idx, int frameP, sub_frame_t subframeP, rnti_t *rntiTable);
 void assign_max_mcs_min_rb(module_id_t module_idP, int slice_idx, int frameP,
 			   sub_frame_t subframeP, uint16_t * first_rb);
 void adjust_bsr_info(int buffer_occupancy, uint16_t TBS,
diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c
index b14b7eab65da3c23c9cb5f2031ab20b67ad63455..292eecbb2894ef88a9d5f36840e78d31df73af4f 100644
--- a/openair2/LAYER2/MAC/pre_processor.c
+++ b/openair2/LAYER2/MAC/pre_processor.c
@@ -56,6 +56,13 @@ extern RAN_CONTEXT_t RC;
 
 //#define ICIC 0
 
+void
+sort_ue_ul(module_id_t module_idP,
+           int slice_idx,
+           int sched_frameP,
+           sub_frame_t sched_subframeP,
+           rnti_t *rntiTable);
+
 /* this function checks that get_eNB_UE_stats returns
  * a non-NULL pointer for all the active CCs of an UE
  */
@@ -264,7 +271,7 @@ assign_rbs_required(module_id_t Mod_id,
 // This function scans all CC_ids for a particular UE to find the maximum round index of its HARQ processes
 int
 maxround(module_id_t Mod_id, uint16_t rnti, int frame,
-         sub_frame_t subframe, uint8_t ul_flag) {
+         sub_frame_t subframe) {
   uint8_t round, round_max = 0, UE_id;
   int CC_id, harq_pid;
   UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
@@ -284,6 +291,28 @@ maxround(module_id_t Mod_id, uint16_t rnti, int frame,
   return round_max;
 }
 
+int
+maxround_ul(module_id_t Mod_id, uint16_t rnti, int sched_frame,
+         sub_frame_t sched_subframe) {
+  uint8_t round, round_max = 0, UE_id;
+  int CC_id, harq_pid;
+  UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
+  COMMON_channels_t *cc;
+
+  for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) {
+    cc = &RC.mac[Mod_id]->common_channels[CC_id];
+    UE_id = find_UE_id(Mod_id, rnti);
+    harq_pid = subframe2harqpid(cc, sched_frame, sched_subframe);
+    round = UE_list->UE_sched_ctrl[UE_id].round_UL[CC_id][harq_pid];
+
+    if (round > round_max) {
+      round_max = round;
+    }
+  }
+
+  return round_max;
+}
+
 // This function scans all CC_ids for a particular UE to find the maximum DL CQI
 // it returns -1 if the UE is not found in PHY layer (get_eNB_UE_stats gives NULL)
 int maxcqi(module_id_t Mod_id, int32_t UE_id) {
@@ -332,10 +361,10 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params) {
   int UE_id2 = *(const int *) _b;
   int rnti1 = UE_RNTI(params->Mod_idP, UE_id1);
   int pCC_id1 = UE_PCCID(params->Mod_idP, UE_id1);
-  int round1 = maxround(params->Mod_idP, rnti1, params->frameP, params->subframeP, 1);
+  int round1 = maxround(params->Mod_idP, rnti1, params->frameP, params->subframeP);
   int rnti2 = UE_RNTI(params->Mod_idP, UE_id2);
   int pCC_id2 = UE_PCCID(params->Mod_idP, UE_id2);
-  int round2 = maxround(params->Mod_idP, rnti2, params->frameP, params->subframeP, 1);
+  int round2 = maxround(params->Mod_idP, rnti2, params->frameP, params->subframeP);
   int cqi1 = maxcqi(params->Mod_idP, UE_id1);
   int cqi2 = maxcqi(params->Mod_idP, UE_id2);
   long lcgid1 = min_lcgidpriority(params->Mod_idP, UE_id1);
@@ -1626,6 +1655,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
                                    int slice_idx,
                                    int frameP,
                                    sub_frame_t subframeP,
+                                   int sched_frameP,
                                    unsigned char sched_subframeP,
                                    uint16_t *first_rb) {
   int UE_id;
@@ -1646,7 +1676,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
 
   // sort ues
   LOG_D(MAC, "In ulsch_preprocessor: sort ue \n");
-   sort_ue_ul(module_idP, slice_idx, frameP, subframeP, rntiTable);
+   sort_ue_ul(module_idP, slice_idx, sched_frameP, sched_subframeP, rntiTable);
   // maximize MCS and then allocate required RB according to the buffer occupancy with the limit of max available UL RB
   LOG_D(MAC, "In ulsch_preprocessor: assign max mcs min rb\n");
   assign_max_mcs_min_rb(module_idP, slice_idx, frameP, subframeP, first_rb);
@@ -1741,7 +1771,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
       CC_id = UE_list->ordered_ULCCids[n][UE_id];
       UE_template = &UE_list->UE_template[CC_id][UE_id];
       harq_pid = subframe2harqpid(&RC.mac[module_idP]->common_channels[CC_id],
-                                  frameP, sched_subframeP);
+                                  sched_frameP, sched_subframeP);
 
       //      mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL);
 
@@ -1924,8 +1954,8 @@ assign_max_mcs_min_rb(module_id_t module_idP,
 
 struct sort_ue_ul_params {
   int module_idP;
-  int frameP;
-  int subframeP;
+  int sched_frameP;
+  int sched_subframeP;
 };
 
 static int ue_ul_compare(const void *_a, const void *_b, void *_params) {
@@ -1935,12 +1965,12 @@ static int ue_ul_compare(const void *_a, const void *_b, void *_params) {
   int UE_id2 = *(const int *) _b;
   int rnti1 = UE_RNTI(params->module_idP, UE_id1);
   int pCCid1 = UE_PCCID(params->module_idP, UE_id1);
-  int round1 = maxround(params->module_idP, rnti1, params->frameP,
-                        params->subframeP, 1);
+  int round1 = maxround_ul(params->module_idP, rnti1, params->sched_frameP,
+                           params->sched_subframeP);
   int rnti2 = UE_RNTI(params->module_idP, UE_id2);
   int pCCid2 = UE_PCCID(params->module_idP, UE_id2);
-  int round2 = maxround(params->module_idP, rnti2, params->frameP,
-                        params->subframeP, 1);
+  int round2 = maxround_ul(params->module_idP, rnti2, params->sched_frameP,
+                           params->sched_subframeP);
 
   if (round1 > round2)
     return -1;
@@ -1984,14 +2014,14 @@ static int ue_ul_compare(const void *_a, const void *_b, void *_params) {
 void
 sort_ue_ul(module_id_t module_idP,
            int slice_idx,
-           int frameP,
-           sub_frame_t subframeP,
+           int sched_frameP,
+           sub_frame_t sched_subframeP,
            rnti_t *rntiTable)
 {
   int i;
   int list[MAX_MOBILES_PER_ENB];
   int list_size = 0;
-  struct sort_ue_ul_params params = { module_idP, frameP, subframeP };
+  struct sort_ue_ul_params params = { module_idP, sched_frameP, sched_subframeP };
   UE_list_t *UE_list = &RC.mac[module_idP]->UE_list;
 
   for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {