From 3da8cac59b23ba1900e2c0e39a4a375ce10c3994 Mon Sep 17 00:00:00 2001
From: Cedric Roux <cedric.roux@eurecom.fr>
Date: Thu, 15 Mar 2018 10:48:16 +0100
Subject: [PATCH] bugfix: try to release HARQ processes properly

The code is too complex. This commit may not be enough.
---
 openair1/SCHED/phy_procedures_lte_eNb.c       |  88 ++++++++------
 .../LAYER2/MAC/eNB_scheduler_primitives.c     | 114 ++++++++++++++++--
 openair2/LAYER2/MAC/pre_processor.c           |   2 +-
 3 files changed, 157 insertions(+), 47 deletions(-)

diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index 6c2e580947..780d3a1a6f 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -1451,7 +1451,9 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe)
   pthread_mutex_unlock(&eNB->UL_INFO_mutex);
 }
 
-void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subframe,uint16_t mask) {
+/* release the harq if its round is >= 'after_rounds' */
+static void do_release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subframe,uint16_t mask, int after_rounds)
+{
 
   LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
   LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
@@ -1472,11 +1474,13 @@ void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subf
     dlsch1_harq     = dlsch1->harq_processes[harq_pid];
     AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n");
 
-    dlsch0_harq->status = SCH_IDLE;
-    /*if ((dlsch1_harq == NULL)||
-	((dlsch1_harq!=NULL)&&
-	 (dlsch1_harq->status == SCH_IDLE)))*/
-    dlsch0->harq_mask   &= ~(1<<harq_pid);
+    if (dlsch0_harq->round >= after_rounds) {
+      dlsch0_harq->status = SCH_IDLE;
+      /*if ((dlsch1_harq == NULL)||
+	  ((dlsch1_harq!=NULL)&&
+	   (dlsch1_harq->status == SCH_IDLE)))*/
+      dlsch0->harq_mask   &= ~(1<<harq_pid);
+    }
     LOG_D(PHY,"Frame %d, subframe %d: Releasing harq %d for UE %x\n",frame,subframe,harq_pid,dlsch0->rnti);
 
   }
@@ -1496,17 +1500,28 @@ void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subf
 	  dlsch1_harq     = dlsch1->harq_processes[harq_pid];
 	  AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n");
       
-	  dlsch0_harq->status = SCH_IDLE;
-	  if ((dlsch1_harq == NULL)||
-	      ((dlsch1_harq!=NULL)&&
-	       (dlsch1_harq->status == SCH_IDLE)))
-	    dlsch0->harq_mask   &= ~(1<<harq_pid);
+          if (dlsch0_harq->round >= after_rounds) {
+	    dlsch0_harq->status = SCH_IDLE;
+	    if ((dlsch1_harq == NULL)||
+	        ((dlsch1_harq!=NULL)&&
+	         (dlsch1_harq->status == SCH_IDLE)))
+	      dlsch0->harq_mask   &= ~(1<<harq_pid);
+          }
 	}
       }
     }
   }
 }
 
+static void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subframe,uint16_t mask, int is_ack)
+{
+  /* Maximum number of DL transmissions = 4.
+   * TODO: get the value from configuration.
+   * If is_ack is true then we release immediately. The value -1 can be used for that.
+   */
+  do_release_harq(eNB, UE_id, tb, frame, subframe, mask, is_ack ? -1 : 4);
+}
+
 int getM(PHY_VARS_eNB *eNB,int frame,int subframe) {
 
   int M,Mtx=0;
@@ -1607,7 +1622,7 @@ void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq,
 
       pdu->harq_indication_fdd_rel13.harq_tb_n[i] = 2-ulsch_harq->o_ACK[i];
       // release DLSCH if needed
-      if (ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff);
+      release_harq(eNB,UE_id,i,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1);
 
 #if T_TRACER
       /* TODO: get correct harq pid */
@@ -1633,13 +1648,17 @@ void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq,
 
       pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = 2-ulsch_harq->o_ACK[i];
       // release DLSCH if needed
-      if (ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff);
-      if      (M==1 && ulsch_harq->O_ACK==1 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
-      else if (M==1 && ulsch_harq->O_ACK==2 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff);
+      /* TODO: review this code, it's most certainly wrong.
+       * We have to release the proper HARQ in case of ACK or NACK if max retransmission reached.
+       * Basically, call release_harq with 1 as last argument when ACK and 0 when NACK.
+       */
+      release_harq(eNB,UE_id,i,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1);
+      if      (M==1 && ulsch_harq->O_ACK==1 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1);
+      else if (M==1 && ulsch_harq->O_ACK==2 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1);
       else if (M>1 && ulsch_harq->o_ACK[i] == 1) {
 	// spatial bundling
-	release_harq(eNB,UE_id,0,frame,subframe,1<<i);
-	release_harq(eNB,UE_id,1,frame,subframe,1<<i);
+	release_harq(eNB,UE_id,0,frame,subframe,1<<i, ulsch_harq->o_ACK[i] == 1);
+	release_harq(eNB,UE_id,1,frame,subframe,1<<i, ulsch_harq->o_ACK[i] == 1);
       }
     }	
   }
@@ -1701,7 +1720,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
       AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]);
       pdu->harq_indication_fdd_rel13.harq_tb_n[0] = harq_ack[0];
       // release DLSCH if needed
-      if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
+      release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
 
 #if T_TRACER
       if (harq_ack[0] != 1)
@@ -1721,8 +1740,8 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
       pdu->harq_indication_fdd_rel13.harq_tb_n[0] = harq_ack[0];
       pdu->harq_indication_fdd_rel13.harq_tb_n[1] = harq_ack[1]; 
       // release DLSCH if needed
-      if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
-      if (harq_ack[1] == 1) release_harq(eNB,UE_id,1,frame,subframe,0xffff);
+      release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
+      release_harq(eNB,UE_id,1,frame,subframe,0xffff, harq_ack[1] == 1);
     }
     else AssertFatal(1==0,"only format 1a/b for now, received %d\n",uci->pucch_fmt); 
   }
@@ -1743,7 +1762,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
 	AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]);
 	pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = harq_ack[0];
 	// release all bundled DLSCH if needed
-	if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
+	release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
       }
       else if (uci->pucch_fmt == pucch_format1b) {
 	pdu->harq_indication_tdd_rel13.number_of_ack_nack = 2;
@@ -1753,8 +1772,8 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
 	pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = harq_ack[0];
 	pdu->harq_indication_tdd_rel13.harq_data[1].bundling.value_0 = harq_ack[1]; 
 	// release all DLSCH if needed
-	if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
-	if (harq_ack[1] == 1) release_harq(eNB,UE_id,1,frame,subframe,0xffff);
+	release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
+	release_harq(eNB,UE_id,1,frame,subframe,0xffff, harq_ack[1] == 1);
       }
       break;
     case 1: // multiplexing
@@ -1766,7 +1785,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
 	AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]);
 	pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0];
 	// release all DLSCH if needed
-	if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
+	release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
       }
       else if (uci->num_pucch_resources == 1 && uci->pucch_fmt == pucch_format1b) {
         pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG;
@@ -1776,8 +1795,8 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
 	pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0];
 	pdu->harq_indication_tdd_rel13.harq_data[1].multiplex.value_0 = harq_ack[1]; 
 	// release all DLSCH if needed
-	if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
-	if (harq_ack[1] == 1) release_harq(eNB,UE_id,1,frame,subframe,0xffff);
+	release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1);
+	release_harq(eNB,UE_id,1,frame,subframe,0xffff, harq_ack[1] == 1);
       }
       else { // num_pucch_resources (M) > 1
         pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG;
@@ -1788,8 +1807,8 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
 	if (uci->num_pucch_resources == 3) 	pdu->harq_indication_tdd_rel13.harq_data[2].multiplex.value_0 = harq_ack[2];
 	if (uci->num_pucch_resources == 4) 	pdu->harq_indication_tdd_rel13.harq_data[3].multiplex.value_0 = harq_ack[3];
 	// spatial-bundling in this case so release both HARQ if necessary
-	release_harq(eNB,UE_id,0,frame,subframe,tdd_multiplexing_mask);
-	release_harq(eNB,UE_id,1,frame,subframe,tdd_multiplexing_mask);
+	release_harq(eNB,UE_id,0,frame,subframe,tdd_multiplexing_mask, 1 /* force release? previous code was unconditional */);
+	release_harq(eNB,UE_id,1,frame,subframe,tdd_multiplexing_mask, 1 /* force release? previous code was unconditional */);
       }
       break;
     case 2: // special bundling (SR collision)
@@ -1800,26 +1819,27 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
  
       switch (harq_ack[0]) {
       case 0:
+        /* TODO: release_harq here? this whole code looks suspicious */
 	break;
       case 1: // check if M=1,4,7
 	if (uci->num_pucch_resources == 1 || uci->num_pucch_resources == 4 ||
 	    tdd_config5_sf2scheds == 1 || tdd_config5_sf2scheds == 4 || tdd_config5_sf2scheds == 7) {
-	  release_harq(eNB,UE_id,0,frame,subframe,0xffff);
-	  release_harq(eNB,UE_id,1,frame,subframe,0xffff);
+	  release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1);
+	  release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1);
 	}
 	break;
       case 2: // check if M=2,5,8
 	if (uci->num_pucch_resources == 2 || tdd_config5_sf2scheds == 2 || 
 	    tdd_config5_sf2scheds == 5 || tdd_config5_sf2scheds == 8) {
-	  release_harq(eNB,UE_id,0,frame,subframe,0xffff);
-	  release_harq(eNB,UE_id,1,frame,subframe,0xffff);
+	  release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1);
+	  release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1);
 	}
 	break;
       case 3: // check if M=3,6,9
 	if (uci->num_pucch_resources == 3 || tdd_config5_sf2scheds == 3 || 
 	    tdd_config5_sf2scheds == 6 || tdd_config5_sf2scheds == 9) {
-	  release_harq(eNB,UE_id,0,frame,subframe,0xffff);
-	  release_harq(eNB,UE_id,1,frame,subframe,0xffff);
+	  release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1);
+	  release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1);
 	}
 	break;
       }
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
index 341db67934..110afc1a5a 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
@@ -3268,8 +3268,13 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 	if (pdu[0] == 1) {	// ACK
 	  sched_ctl->round[CC_idP][harq_pid] = 8;	// release HARQ process
 	  sched_ctl->tbcnt[CC_idP][harq_pid] = 0;
-	} else if (pdu[0] == 2 || pdu[0] == 4)	// NAK (treat DTX as NAK)
+	} else if (pdu[0] == 2 || pdu[0] == 4) {	// NAK (treat DTX as NAK)
 	  sched_ctl->round[CC_idP][harq_pid]++;	// increment round
+          if (sched_ctl->round[CC_idP][harq_pid] == 4) {
+	    sched_ctl->round[CC_idP][harq_pid] = 8;	// release HARQ process
+	    sched_ctl->tbcnt[CC_idP][harq_pid] = 0;
+          }
+        }
       } else {
 	// one or two ACK/NAK bits
 	AssertFatal(num_ack_nak <= 2,
@@ -3285,8 +3290,13 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 	if ((num_ack_nak == 2)
 	    && (sched_ctl->round[CC_idP][harq_pid] < 8)
 	    && (sched_ctl->tbcnt[CC_idP][harq_pid] == 1)
-	    && (pdu[0] == 2) && (pdu[1] == 2))
+	    && (pdu[0] == 2) && (pdu[1] == 2)) {
 	  sched_ctl->round[CC_idP][harq_pid]++;
+          if (sched_ctl->round[CC_idP][harq_pid] == 4) {
+            sched_ctl->round[CC_idP][harq_pid] = 8;     // release HARQ process
+            sched_ctl->tbcnt[CC_idP][harq_pid] = 0;
+          }
+        }
 	else if (((num_ack_nak == 2)
 		  && (sched_ctl->round[CC_idP][harq_pid] < 8)
 		  && (sched_ctl->tbcnt[0][harq_pid] == 2)
@@ -3297,11 +3307,20 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 		     && (pdu[0] == 2) && (pdu[1] == 1))) {
 	  sched_ctl->round[CC_idP][harq_pid]++;
 	  sched_ctl->tbcnt[CC_idP][harq_pid] = 1;
+          if (sched_ctl->round[CC_idP][harq_pid] == 4) {
+            sched_ctl->round[CC_idP][harq_pid] = 8;     // release HARQ process
+            sched_ctl->tbcnt[CC_idP][harq_pid] = 0;  /* TODO: do we have to set it to 0? */
+          }
 	} else if ((num_ack_nak == 2)
 		   && (sched_ctl->round[CC_idP][harq_pid] < 8)
 		   && (sched_ctl->tbcnt[CC_idP][harq_pid] == 2)
-		   && (pdu[0] == 2) && (pdu[1] == 2))
+		   && (pdu[0] == 2) && (pdu[1] == 2)) {
 	  sched_ctl->round[CC_idP][harq_pid]++;
+          if (sched_ctl->round[CC_idP][harq_pid] == 4) {
+            sched_ctl->round[CC_idP][harq_pid] = 8;     // release HARQ process
+            sched_ctl->tbcnt[CC_idP][harq_pid] = 0;
+          }
+        }
 	else
 	  AssertFatal(1 == 0,
 		      "Illegal ACK/NAK/round combination (%d,%d,%d,%d,%d) for harq_pid %d, UE %d/%x\n",
@@ -3327,12 +3346,18 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 		    pdu[1]);
 	if (pdu[0] == 1)
 	  sched_ctl->round[pCCid][harq_pid] = 8;
-	else
+	else {
 	  sched_ctl->round[pCCid][harq_pid]++;
+          if (sched_ctl->round[pCCid][harq_pid] == 4)
+	    sched_ctl->round[pCCid][harq_pid] = 8;
+        }
 	if (pdu[1] == 1)
 	  sched_ctl->round[1 - pCCid][harq_pid] = 8;
-	else
+	else {
 	  sched_ctl->round[1 - pCCid][harq_pid]++;
+	  if (sched_ctl->round[1 - pCCid][harq_pid] == 4)
+	    sched_ctl->round[1 - pCCid][harq_pid] = 8;
+        }
       }			// A=2
       else if ((num_ack_nak == 3)
 	       && (sched_ctl->round[pCCid][harq_pid] < 8)
@@ -3358,13 +3383,26 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 		   ((pdu[0] == 1) && (pdu[1] == 2))) {
 	  sched_ctl->round[pCCid][harq_pid]++;
 	  sched_ctl->tbcnt[pCCid][harq_pid] = 1;
-	} else
+	  if (sched_ctl->round[pCCid][harq_pid] == 4) {
+	    sched_ctl->round[pCCid][harq_pid] = 8;
+	    sched_ctl->tbcnt[pCCid][harq_pid] = 0; /* TODO: do we have to set it to 0? */
+          }
+	} else {
 	  sched_ctl->round[pCCid][harq_pid]++;
+	  if (sched_ctl->round[pCCid][harq_pid] == 4) {
+	    sched_ctl->round[pCCid][harq_pid] = 8;
+	    sched_ctl->tbcnt[pCCid][harq_pid] = 0;
+          }
+        }
 
 	if (pdu[2] == 1)
 	  sched_ctl->round[1 - pCCid][harq_pid] = 8;
-	else
+	else {
 	  sched_ctl->round[1 - pCCid][harq_pid]++;
+	  if (sched_ctl->round[1 - pCCid][harq_pid] == 4) {
+	    sched_ctl->round[1 - pCCid][harq_pid] = 8;
+          }
+        }
       }			// A=3 primary cell has 2 TBs
       else if ((num_ack_nak == 3)
 	       && (sched_ctl->round[1 - pCCid][harq_pid] < 8)
@@ -3390,13 +3428,26 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 		   || ((pdu[0] == 1) && (pdu[1] >= 2))) {	// one ACK
 	  sched_ctl->round[1 - pCCid][harq_pid]++;
 	  sched_ctl->tbcnt[1 - pCCid][harq_pid] = 1;
-	} else		// both NAK/DTX
+	  if (sched_ctl->round[1 - pCCid][harq_pid] == 4) {
+	    sched_ctl->round[1 - pCCid][harq_pid] = 8;
+	    sched_ctl->tbcnt[1 - pCCid][harq_pid] = 0;
+          }
+	} else {		// both NAK/DTX
 	  sched_ctl->round[1 - pCCid][harq_pid]++;
+	  if (sched_ctl->round[1 - pCCid][harq_pid] == 4) {
+	    sched_ctl->round[1 - pCCid][harq_pid] = 8;
+	    sched_ctl->tbcnt[1 - pCCid][harq_pid] = 0;
+          }
+        }
 
 	if (pdu[2] == 1)
 	  sched_ctl->round[pCCid][harq_pid] = 8;
-	else
+	else {
 	  sched_ctl->round[pCCid][harq_pid]++;
+	  if (sched_ctl->round[pCCid][harq_pid] == 4) {
+	    sched_ctl->round[pCCid][harq_pid] = 8;
+          }
+        }
       }			// A=3 secondary cell has 2 TBs
 #if MAX_NUM_CCs>1
       else if ((num_ack_nak == 4)
@@ -3425,8 +3476,17 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 		   || ((pdu[0] == 1) && (pdu[1] >= 2))) {	// one ACK
 	  sched_ctl->round[0][harq_pid]++;
 	  sched_ctl->tbcnt[0][harq_pid] = 1;
-	} else		// both NAK/DTX
+	  if (sched_ctl->round[0][harq_pid] == 4) {
+	    sched_ctl->round[0][harq_pid] = 8;
+	    sched_ctl->tbcnt[0][harq_pid] = 0;
+          }
+	} else {		// both NAK/DTX
 	  sched_ctl->round[0][harq_pid]++;
+	  if (sched_ctl->round[0][harq_pid] == 4) {
+	    sched_ctl->round[0][harq_pid] = 8;
+	    sched_ctl->tbcnt[0][harq_pid] = 0;
+          }
+        }
 
 	if ((pdu[2] == 1) && (pdu[3] == 1)) {	// both ACK
 	  sched_ctl->round[1][harq_pid] = 8;
@@ -3435,8 +3495,17 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 		   || ((pdu[2] == 1) && (pdu[3] >= 2))) {	// one ACK
 	  sched_ctl->round[1][harq_pid]++;
 	  sched_ctl->tbcnt[1][harq_pid] = 1;
-	} else		// both NAK/DTX
+	  if (sched_ctl->round[1][harq_pid] == 4) {
+	    sched_ctl->round[1][harq_pid] = 8;
+	    sched_ctl->tbcnt[1][harq_pid] = 0;
+          }
+	} else {		// both NAK/DTX
 	  sched_ctl->round[1][harq_pid]++;
+	  if (sched_ctl->round[1][harq_pid] == 4) {
+	    sched_ctl->round[1][harq_pid] = 8;
+	    sched_ctl->tbcnt[1][harq_pid] = 0;
+          }
+        }
       }			// A=4 both serving cells have 2 TBs
 #endif
       break;
@@ -3451,8 +3520,13 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 	    if (pdu[j] == 1) {
 	      sched_ctl->round[i][harq_pid] = 8;
 	      sched_ctl->tbcnt[i][harq_pid] = 0;
-	    } else if (pdu[j] == 2)
+	    } else if (pdu[j] == 2) {
 	      sched_ctl->round[i][harq_pid]++;
+	      if (sched_ctl->round[i][harq_pid] == 4) {
+	        sched_ctl->round[i][harq_pid] = 8;
+	        sched_ctl->tbcnt[i][harq_pid] = 0;
+              }
+            }
 	    else
 	      AssertFatal(1 == 0,
 			  "Illegal harq_ack value for CC %d harq_pid %d (%d) UE %d/%x\n",
@@ -3467,13 +3541,25 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 		       && (pdu[j] == 1) && (pdu[j + 1] == 2)) {
 	      sched_ctl->round[i][harq_pid]++;
 	      sched_ctl->tbcnt[i][harq_pid] = 1;
+	      if (sched_ctl->round[i][harq_pid] == 4) {
+	        sched_ctl->round[i][harq_pid] = 8;
+	        sched_ctl->tbcnt[i][harq_pid] = 0;
+              }
 	    } else if ((sched_ctl->tbcnt[i][harq_pid] == 2)
 		       && (pdu[j] == 2) && (pdu[j + 1] == 1)) {
 	      sched_ctl->round[i][harq_pid]++;
 	      sched_ctl->tbcnt[i][harq_pid] = 1;
+	      if (sched_ctl->round[i][harq_pid] == 4) {
+	        sched_ctl->round[i][harq_pid] = 8;
+	        sched_ctl->tbcnt[i][harq_pid] = 0;
+              }
 	    } else if ((sched_ctl->tbcnt[i][harq_pid] == 2)
 		       && (pdu[j] == 2) && (pdu[j + 1] == 2)) {
 	      sched_ctl->round[i][harq_pid]++;
+	      if (sched_ctl->round[i][harq_pid] == 4) {
+	        sched_ctl->round[i][harq_pid] = 8;
+	        sched_ctl->tbcnt[i][harq_pid] = 0;
+              }
 	    } else
 	      AssertFatal(1 == 0,
 			  "Illegal combination for CC %d harq_pid %d (%d,%d,%d) UE %d/%x\n",
@@ -3487,6 +3573,10 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 	      sched_ctl->tbcnt[i][harq_pid] = 0;
 	    } else if (pdu[j] == 2) {
 	      sched_ctl->round[i][harq_pid]++;
+	      if (sched_ctl->round[i][harq_pid] == 4) {
+	        sched_ctl->round[i][harq_pid] = 8;
+	        sched_ctl->tbcnt[i][harq_pid] = 0;
+              }
 	    } else
 	      AssertFatal(1 == 0,
 			  "Illegal hack_nak value %d for CC %d harq_pid %d UE %d/%x\n",
diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c
index e7458c347f..2cdcfc7de8 100644
--- a/openair2/LAYER2/MAC/pre_processor.c
+++ b/openair2/LAYER2/MAC/pre_processor.c
@@ -734,7 +734,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id,
 
       // control channel or retransmission
       /* TODO: do we have to check for retransmission? */
-      if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED || round > 0) {
+      if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED || round != 8) {
         nb_rbs_required_remaining_1[CC_id][UE_id] =
                 nb_rbs_required[CC_id][UE_id];
       } else {
-- 
GitLab