diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c
index 6ed3b7a3d3b8817d9bdc6b79970be53f39c6c5f0..30b7c3a6fd2dee6dc0d572289e60236a1b03800a 100644
--- a/openair1/PHY/INIT/lte_init.c
+++ b/openair1/PHY/INIT/lte_init.c
@@ -1046,6 +1046,7 @@ void phy_init_lte_ue__PDSCH( LTE_UE_PDSCH* const pdsch, const LTE_DL_FRAME_PARMS
   pdsch->rxdataF_ext            = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
   pdsch->rxdataF_uespec_pilots  = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
   pdsch->rxdataF_comp0          = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+  pdsch->rxdataF_comp0_tm4      = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
   pdsch->rho                    = (int32_t**)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) );
   pdsch->dl_ch_estimates_ext    = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
   pdsch->dl_bf_ch_estimates     = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
@@ -1054,6 +1055,8 @@ void phy_init_lte_ue__PDSCH( LTE_UE_PDSCH* const pdsch, const LTE_DL_FRAME_PARMS
   //pdsch->dl_ch_rho2_ext         = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
   pdsch->dl_ch_mag0             = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
   pdsch->dl_ch_magb0            = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+  pdsch->dl_ch_mag0_tm4             = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+  pdsch->dl_ch_magb0_tm4            = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
 
 
   // the allocated memory size is fixed:
@@ -1068,6 +1071,9 @@ void phy_init_lte_ue__PDSCH( LTE_UE_PDSCH* const pdsch, const LTE_DL_FRAME_PARMS
       pdsch->rxdataF_ext[idx]             = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
       pdsch->rxdataF_uespec_pilots[idx]   = (int32_t*)malloc16_clear( sizeof(int32_t) * fp->N_RB_DL*12);
       pdsch->rxdataF_comp0[idx]           = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+      pdsch->rxdataF_comp0_tm4[idx] =(int32_t*)malloc16_clear( sizeof(int32_t) * 2 *num );
+      pdsch->dl_ch_mag0_tm4[idx]   =(int32_t*)malloc16_clear( sizeof(int32_t) * 2 *num );
+      pdsch->dl_ch_magb0_tm4[idx]  =(int32_t*)malloc16_clear( sizeof(int32_t) * 2 *num );
       pdsch->dl_ch_estimates_ext[idx]     = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
       pdsch->dl_bf_ch_estimates[idx]      = (int32_t*)malloc16_clear( sizeof(int32_t) * fp->ofdm_symbol_size*7*2);
       pdsch->dl_bf_ch_estimates_ext[idx]  = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
index b5756d2783a79ce0333b132744f89b276b2b02f5..dab2be7be14dbb92696e74f4ec16ebf3a0ec9130 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
@@ -544,19 +544,17 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
 
   eNB_id=0;
 
-  /*SFN:
+  /*Khodr Saaifan:
    * Rank Estimation:
-   * We shall control the function according to ue->transmission_mode[eNB_id]
-   * where ue->transmission_mode[eNB_id]=3 or 4 for TM3/TM4
+   * We activate it as a feature for 2X2 MIMO
    *
    * */
-#ifdef FHG_TM4
+  if ((frame_parms->nb_antennas_rx>1) && (frame_parms->nb_antenna_ports_eNB>1))
   rank_tm3_tm4 = rank_estimation_tm3_tm4(&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][0][4],
                                              &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2][4],//2
                                              &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][1][4],//1
                                              &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][3][4],//3
                                              N_RB_DL);
-#endif
 
   ue->measurements.rank[eNB_id] = rank_tm3_tm4;
 
@@ -814,7 +812,7 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
      pmi2hex_2Ar1(quantize_subband_pmi2(&ue->measurements,eNB,1,7));*/
 
     }  // if frame_parms->mode1_flag == 0
-    else //SFN: we need still to fix here for SISO
+    else //SFN: we fix SISO measurements
     {
       // cqi information only for mode 1
       for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
@@ -829,23 +827,27 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
           if (subband<6) {
             //      for (i=0;i<48;i++)
             //        printf("subband %d (%d) : %d,%d\n",subband,i,((short *)dl_ch0)[2*i],((short *)dl_ch0)[1+(2*i)]);
-            ue->measurements.subband_cqi[eNB_id][aarx][subband] =
-              (signal_energy_nodc(dl_ch0,48)) - ue->measurements.n0_power[aarx];
-
-
+            ue->measurements.subband_cqi[eNB_id][aarx][subband] = (signal_energy_nodc(dl_ch0,48));
             if (ue->measurements.subband_cqi[eNB_id][aarx][subband]<0)
             	ue->measurements.subband_cqi[eNB_id][aarx][subband] =0;
 
             ue->measurements.subband_cqi_tot[eNB_id][subband] += ue->measurements.subband_cqi[eNB_id][aarx][subband];
-            ue->measurements.subband_cqi_dB[eNB_id][aarx][subband] = dB_fixed2(ue->measurements.subband_cqi[eNB_id][aarx][subband],
-                ue->measurements.n0_power[aarx]);
+            if (aarx==(frame_parms->nb_antennas_rx-1))
+            ue->measurements.subband_cqi_tot[eNB_id][subband] /=frame_parms->nb_antennas_rx;
+
+                  ue->measurements.subband_cqi_dB[eNB_id][aarx][subband] = dB_fixed2(ue->measurements.subband_cqi[eNB_id][aarx][subband],
+                      ue->measurements.n0_power[aarx]);
+
           } else {
             //      for (i=0;i<12;i++)
             //        printf("subband %d (%d) : %d,%d\n",subband,i,((short *)dl_ch0)[2*i],((short *)dl_ch0)[1+(2*i)]);
-            ue->measurements.subband_cqi[eNB_id][aarx][subband] = (signal_energy_nodc(dl_ch0,12) ) - ue->measurements.n0_power[aarx];
+            ue->measurements.subband_cqi[eNB_id][aarx][subband] = (signal_energy_nodc(dl_ch0,12) );
             if (ue->measurements.subband_cqi[eNB_id][aarx][subband]<0)
             	ue->measurements.subband_cqi[eNB_id][aarx][subband] =0;
             ue->measurements.subband_cqi_tot[eNB_id][subband] += ue->measurements.subband_cqi[eNB_id][aarx][subband];
+            if (aarx==(frame_parms->nb_antennas_rx-1))
+                 ue->measurements.subband_cqi_tot[eNB_id][subband] /=frame_parms->nb_antennas_rx;
+
             ue->measurements.subband_cqi_dB[eNB_id][aarx][subband] = dB_fixed2(ue->measurements.subband_cqi[eNB_id][aarx][subband],
                 ue->measurements.n0_power[aarx]);
           }
@@ -856,8 +858,9 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
       }
 
       for (subband=0; subband<nb_subbands; subband++) {
-        ue->measurements.subband_cqi_tot_dB[eNB_id][subband] = dB_fixed2(ue->measurements.subband_cqi_tot[eNB_id][subband],ue->measurements.n0_power_tot);
-      }
+          ue->measurements.subband_cqi_tot_dB[eNB_id][subband] = dB_fixed2(ue->measurements.subband_cqi_tot[eNB_id][subband],ue->measurements.n0_power_tot);
+          //    msg("subband_cqi_tot[%d][%d] => %d dB (n0 %d)\n",eNB_id,subband,ue->measurements.subband_cqi_tot_dB[eNB_id][subband],ue->measurements.n0_power_tot);
+        }
     }
 
     //ue->measurements.rank[eNB_id] = 0;
diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c
index a508175b8f108ddb65a7c3acf04511f72b95ace6..b9c43e5a75ea726406a1ba3689d3bbfac1b6ca22 100755
--- a/openair1/PHY/LTE_TRANSPORT/dci.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci.c
@@ -3592,7 +3592,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
     ra_rnti = ue->prach_resources[eNB_id]->ra_RNTI;
 
   // Now check UE_SPEC format0/1A ue_spec search spaces at aggregation 8
-  //  printf("[DCI search] Format 0/1A aggregation 8\n");
+  //  printf("[DCI search] Format 0/1A aggregation 1\n");
   dci_decoding_procedure0(pdcch_vars,0,mode,
                           subframe,
                           dci_alloc,
@@ -3694,7 +3694,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
 
   if (dci_cnt == 0)
   {
-  // Now check UE_SPEC format 0 search spaces at aggregation 1
+  // Now check UE_SPEC format 0 search spaces at aggregation 8
   dci_decoding_procedure0(pdcch_vars,0,mode,
                           subframe,
                           dci_alloc,
@@ -3726,7 +3726,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
   //printf("[DCI search] Format 0 aggregation 8 dci_cnt %d\n",dci_cnt);
 
   }
-  // These are for CRNTI based on transmission mode
+  // These are for CRNTI based on transmission mode //KhodrSaaifan
   if ((tmode < 3) || (tmode == 7)) {
     // Now check UE_SPEC format 1 search spaces at aggregation 1
     old_dci_cnt=dci_cnt;
@@ -3754,12 +3754,12 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             &CCEmap2);
     //printf("[DCI search] Format 1 aggregation 1 dci_cnt %d\n",dci_cnt);
 
-    if ((CCEmap0==0xffff) ||
+   /* if ((CCEmap0==0xffff) ||
         (format_c_found==1))
       return(dci_cnt);
 
     if (dci_cnt>old_dci_cnt)
-      return(dci_cnt);
+      return(dci_cnt);*/
 
     // Now check UE_SPEC format 1 search spaces at aggregation 2
     old_dci_cnt=dci_cnt;
@@ -3787,12 +3787,11 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             &CCEmap2);
     //printf("[DCI search] Format 1 aggregation 2 dci_cnt %d\n",dci_cnt);
 
-    if ((CCEmap0==0xffff)||
+    /*if ((CCEmap0==0xffff)||
         (format_c_found==1))
       return(dci_cnt);
-
     if (dci_cnt>old_dci_cnt)
-      return(dci_cnt);
+      return(dci_cnt);*/
 
     // Now check UE_SPEC format 1 search spaces at aggregation 4
     old_dci_cnt=dci_cnt;
@@ -3820,12 +3819,11 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             &CCEmap2);
     //printf("[DCI search] Format 1 aggregation 4 dci_cnt %d\n",dci_cnt);
 
-    if ((CCEmap0==0xffff)||
+    /*if ((CCEmap0==0xffff)||
         ((format0_found==1)&&(format_c_found==1)))
       return(dci_cnt);
-
     if (dci_cnt>old_dci_cnt)
-      return(dci_cnt);
+      return(dci_cnt);*/
 
     //#ifdef ALL_AGGREGATION
     // Now check UE_SPEC format 1 search spaces at aggregation 8
@@ -3854,12 +3852,11 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             &CCEmap2);
     //printf("[DCI search] Format 1 aggregation 8 dci_cnt %d\n",dci_cnt);
 
-    if ((CCEmap0==0xffff)||
+    /*if ((CCEmap0==0xffff)||
         ((format0_found==1)&&(format_c_found==1)))
       return(dci_cnt);
-
     if (dci_cnt>old_dci_cnt)
-      return(dci_cnt);
+      return(dci_cnt);*/
 
     //#endif //ALL_AGGREGATION
 /* sfn: Enable Format2 seaching in UE space
@@ -3877,7 +3874,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
                             ra_rnti,
 			    P_RNTI,
-                            0,
+                            3,
                             format1A,
                             format1A,
                             format1A,
@@ -3910,7 +3907,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
                             ra_rnti,
 			    P_RNTI,
-                            1,
+                            2,
                             format1A,
                             format1A,
                             format1A,
@@ -3943,7 +3940,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
                             ra_rnti,
 			    P_RNTI,
-                            2,
+                            1,
                             format1A,
                             format1A,
                             format1A,
@@ -3977,7 +3974,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
                             ra_rnti,
 			    P_RNTI,
-                            3,
+                            0,
                             format1A,
                             format1A,
                             format1A,
diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
index 10d065ac234752a5fd6e21d4c6984c4ec15455b8..9eb6436d99db0ae309536e007e41e53aaca4ed82 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
@@ -4999,6 +4999,7 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format,
     uint8_t  mcs2 = pdci_info_extarcted->mcs2;
     uint8_t  rv1  = pdci_info_extarcted->rv1;
     uint8_t  rv2  = pdci_info_extarcted->rv2;
+    uint8_t  tpmi  = pdci_info_extarcted->tpmi;
     uint8_t  harq_pid = pdci_info_extarcted->harq_pid;
     uint32_t rballoc  = pdci_info_extarcted->rballoc;
 
@@ -5033,7 +5034,7 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format,
       return(0);
     }
 
-    if( (rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti) )
+    if( ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) && harq_pid>0)
     {
         LOG_I(PHY,"bad rnti\n");
         return(0);
@@ -5049,35 +5050,6 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format,
       }
     }
 
-/*SFN: remove channel 2 from the test
-*
-*/
-    if( mcs2 > 28)
-    {
-    /*  if(pdlsch1_harq->round == 0)
-      {
-          LOG_I(PHY,"bad mcs2\n");
-          return(0);
-      }*/
-
-    }
-
-
-    if((pdlsch0_harq->round == 0) && (rv1 > 0) && (mcs1 != 0))
-    {
-      // DCI false detection
-        LOG_I(PHY,"bad rv1\n");
-      return(0);
-    }
-
-   /* if((pdlsch1_harq->round == 0) && (rv2 > 0) && (mcs2 != 0))
-    {
-      // DCI false detection
-        LOG_I(PHY,"bad rv2\n");
-      return(0);
-    }*/
-
-
     switch (N_RB_DL) {
     case 6:
         if (rah == 0)
@@ -5144,7 +5116,34 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format,
        LOG_I(PHY,"bad NPRB\n");
       return(0);
    }
+//Khodr Saaifan: only for this momentcheck alamouti and test Tm4
+   if ((rv2!=1)&&(mcs2!=0))//deactivate TBS1
+   {
+          // DCI false detection
+           LOG_I(PHY,"TBS1 is active %d\n");
+          return(0);
+       }
+//only for this moment
+   if((tpmi != 0) && (tpmi != 7))
+    {
+       // DCI false detection the PMI value is not as we sent
+        LOG_I(PHY,"bad tpmi %d\n", tpmi);
+       return(0);
+    }
+
 
+   /*if(pdlsch0_harq->round > 0)
+        {
+  	   // compare old TBS to new TBS
+  	   if((mcs1<29) && (pdlsch0_harq->TBS != TBStable[get_I_TBS(mcs1)][NPRB-1]))
+  	   {
+  		   // this is an eNB issue
+  	       // retransmisison but old and new TBS are different !!!
+  	       // work around, consider it as a new transmission
+  		   LOG_E(PHY,"Format2 Retransmission but TBS are different: consider it as new transmission !!! \n");
+  	       pdlsch0_harq->round = 0;
+  	   }
+        }*/
    return(1);
 }
 
@@ -5188,8 +5187,8 @@ void compute_llr_offset(LTE_DL_FRAME_PARMS *frame_parms,
         granted_re = nb_rb_alloc * (12-crs_re);
         pbch_pss_sss_re = adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,dlsch0_harq->Qm,subframe,symbol);
         pbch_pss_sss_re = (double)pbch_pss_sss_re * ((double)(12-crs_re)/12);
-        data_re = granted_re - pbch_pss_sss_re;
-        llr_offset = data_re * dlsch0_harq->Qm * 2;
+        data_re = dlsch0_harq->Nl*(granted_re - pbch_pss_sss_re);
+        llr_offset = data_re * dlsch0_harq->Qm * 2;//1 llr=16 bits, the offset is computed to address byte variables so we multiply by 2
 
         pdsch_vars->llr_length[symbol]   = data_re;
         if(symbol < (frame_parms->symbols_per_tti-1))
@@ -5774,33 +5773,51 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
     uint8_t  TPC      = pdci_info_extarcted->TPC;
     uint8_t  ndi1     = pdci_info_extarcted->ndi1;
     uint8_t  ndi2     = pdci_info_extarcted->ndi2;
+    uint8_t  Nl     = 1;
 
     uint8_t  NPRB    = 0;
     uint8_t  nb_rb_alloc = 0;
     NPRB = conv_nprb(rah, rballoc, 25);
     nb_rb_alloc = NPRB;
 
-pdlsch0->current_harq_pid = harq_pid;
-pdlsch0->active           = 1;
-pdlsch0->rnti             = rnti;
+    pdlsch0->current_harq_pid = harq_pid;
+    pdlsch0->active           = 1;
+    pdlsch0->rnti             = rnti;
+
 
-/*if (rnti == tc_rnti) {
-		//fix for standalone Contention Resolution Id
-		dlsch0_harq->DCINdi = (uint8_t)-1;
-		 LOG_D(PHY,"UE (%x/%d): Format1A DCI: C-RNTI is temporary. Set NDI = %d and to be ignored\n",
-			 rnti,harq_pid,dlsch0_harq->DCINdi);
-}*/
 
-// NDI has been toggled or this is the first transmission
-if ((ndi1!=dlsch0_harq->DCINdi) || (dlsch0_harq->first_tx==1))
+    /*SFN:
+     * Case 1:eNB receives ACK (due to channel) for erroneous decoded data
+     * Description: UE has a decoding error. Hence it increases round and send Nack to eNB
+     * if eNB receives ACK. So, it assumes a new Transmission and sends new TBS
+     * pdlsch0->harq_processes[harq_pid]
+     */
+    if(dlsch0_harq->round > 0)
+    {
+    	if(tpmi==0) Nl=1;
+    	else if(tpmi==7) Nl=2;
+    	// compare old TBS to new TBS
+    	if((mcs1<29) && (dlsch0_harq->TBS != TBStable[get_I_TBS(mcs1)][Nl*NPRB-1]))
+      	   {
+      		   // this is an eNB issue due to wrong receiption of Ack/Nack
+      	       // retransmisison but old and new TBS are different !!!
+      	       // work around, consider it as a new transmission
+      		   LOG_E(PHY,"Format2 Retransmission but TBS are different: consider it as new transmission !!! \n");
+      		 dlsch0_harq->round = 0;
+      	   }
+    }
+
+    // NDI has been toggled or this is the first transmission
+    if ((ndi1!=dlsch0_harq->DCINdi) || (dlsch0_harq->first_tx==1))
     {
         dlsch0_harq->round    = 0;
         dlsch0_harq->first_tx = 0;
         dlsch0_harq->status   = ACTIVE;
 
     }
-//NDI has not been toggled but rv was increased by eNB: retransmission
-else if (rv1  != 0)
+
+    //NDI has not been toggled but rv was increased by eNB: retransmission
+    else if (rv1  != 0)
     {
         if (dlsch0_harq->status == SCH_IDLE)
             //packet was actually decoded in previous transmission (ACK was missed by eNB)
@@ -5826,19 +5843,27 @@ else if (rv1  != 0)
         dlsch0_harq->status   = ACTIVE;
     }
 
+    dlsch0_harq->DCINdi = ndi1;
+    dlsch0_harq->mcs    = mcs1;
+    dlsch0_harq->rvidx  = rv1;
+    dlsch0_harq->nb_rb  = NPRB;
 
-dlsch0_harq->DCINdi = ndi1;
-dlsch0_harq->mcs    = mcs1;
-dlsch0_harq->rvidx  = rv1;
-dlsch0_harq->nb_rb  = NPRB;
-
-dlsch0_harq->codeword     = 0;
-dlsch0_harq->Nl           = 1;
-dlsch0_harq->mimo_mode    = frame_parms->mode1_flag == 1 ?SISO : ALAMOUTI;
-dlsch0_harq->dl_power_off = 1; //no power offset
-dlsch0_harq->delta_PUCCH  = delta_PUCCH_lut[TPC &3];
+    dlsch0_harq->codeword     = 0;
+    dlsch0_harq->Nl           = 1;
 
+    switch (tpmi){
+        case 0 :
+    	    dlsch0_harq->Nl           = 1;
+    	    dlsch0_harq->mimo_mode    = frame_parms->mode1_flag == 1 ?SISO : ALAMOUTI;
+    	    break;
+    	case 7 ://sfn:test TM4
+    		dlsch0_harq->Nl           = 2;
+    		dlsch0_harq->mimo_mode    = TM4_NO_PRECODING;
+    		break;
+    }
 
+    dlsch0_harq->dl_power_off = 1; //no power offset
+    dlsch0_harq->delta_PUCCH  = delta_PUCCH_lut[TPC &3];
 
     conv_rballoc(rah,rballoc,frame_parms->N_RB_DL,dlsch0_harq->rb_alloc_even);
     dlsch0_harq->rb_alloc_odd[0]= dlsch0_harq->rb_alloc_even[0];
@@ -5846,297 +5871,18 @@ dlsch0_harq->delta_PUCCH  = delta_PUCCH_lut[TPC &3];
     dlsch0_harq->rb_alloc_odd[2]= dlsch0_harq->rb_alloc_even[2];
     dlsch0_harq->rb_alloc_odd[3]= dlsch0_harq->rb_alloc_even[3];
 
-
-
     if(mcs1 < 29)
     {
-        dlsch0_harq->TBS = TBStable[get_I_TBS(mcs1)][NPRB-1];
+        dlsch0_harq->TBS = TBStable[get_I_TBS(mcs1)][(dlsch0_harq->Nl*NPRB)-1];
         dlsch0_harq->Qm  = get_Qm(mcs1);
     }
 
-
-compute_llr_offset(frame_parms,
+    compute_llr_offset(frame_parms,
                    pdcch_vars,
                    pdsch_vars,
                    dlsch0_harq,
                    nb_rb_alloc,
                    subframe);
-
-
-
-
-
-#ifdef SFN_Disable
-
-    uint8_t TB0_active = 1;
-    uint8_t TB1_active = 1;
-
-   // printf("inside prepare pdlsch1->pmi_alloc %d \n",pdlsch1->pmi_alloc);
-
-
-      if ((rv1 == 1) && (mcs1 == 0)) {
-        TB0_active=0;
-      }
-      if ((rv2 == 1) && (mcs2 == 0)) {
-        TB1_active=0;
-      }
-
-#ifdef DEBUG_HARQ
-      printf("[DCI UE]: TB0 status %d , TB1 status %d\n", TB0_active, TB1_active);
-#endif
-
-        dlsch0_harq->mcs      = mcs1;
-        dlsch1_harq->mcs      = mcs2;
-        dlsch0_harq->rvidx    = rv1;
-        dlsch1_harq->rvidx    = rv2;
-        dlsch0_harq->DCINdi   = ndi1;
-        dlsch1_harq->DCINdi   = ndi2;
-
-        dlsch0_harq->codeword = 0;
-        dlsch1_harq->codeword = 1;
-        dlsch0_harq->Nl       = 1;
-        dlsch1_harq->Nl       = 1;
-        dlsch0_harq->delta_PUCCH  = delta_PUCCH_lut[TPC&3];
-        dlsch1_harq->delta_PUCCH  = delta_PUCCH_lut[TPC&3];
-        dlsch0_harq->dl_power_off = 1;
-        dlsch1_harq->dl_power_off = 1;
-
-        pdlsch0->current_harq_pid = harq_pid;
-        pdlsch0->harq_ack[subframe].harq_id     = harq_pid;
-        pdlsch1->current_harq_pid = harq_pid;
-        pdlsch1->harq_ack[subframe].harq_id     = harq_pid;
-
-        // assume two CW are active
-        dlsch0_harq->status   = ACTIVE;
-        dlsch1_harq->status   = ACTIVE;
-        pdlsch0->active = 1;
-        pdlsch1->active = 1;
-        pdlsch0->rnti = rnti;
-        pdlsch1->rnti = rnti;
-
-
-      if (TB0_active && TB1_active && tbswap==1) {
-        dlsch0_harq->codeword = 1;
-        dlsch1_harq->codeword = 0;
-      }
-
-
-      if (!TB0_active && TB1_active){
-        dlsch1_harq->codeword = 0;
-      }
-
-      if (TB0_active && !TB1_active){
-        dlsch0_harq->codeword = 0;
-      }
-
-
-      if (TB0_active==0) {
-        dlsch0_harq->status = SCH_IDLE;
-        pdlsch0->active     = 0;
-  #ifdef DEBUG_HARQ
-        printf("[DCI UE]: TB0 is deactivated, retransmit TB1 transmit in TM6\n");
-  #endif
-      }
-
-      if (TB1_active==0) {
-        dlsch1_harq->status = SCH_IDLE;
-        pdlsch1->active     = 0;
-      }
-
-#ifdef DEBUG_HARQ
-      printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
-#endif
-
-      // compute resource allocation
-      if (TB0_active == 1){
-
-        dlsch0_harq->nb_rb = conv_nprb(rah,
-                                       rballoc,
-                                       frame_parms->N_RB_DL);
-        conv_rballoc(rah,
-                     rballoc,
-                     frame_parms->N_RB_DL,
-                     dlsch0_harq->rb_alloc_even);
-
-        dlsch0_harq->rb_alloc_odd[0]= dlsch0_harq->rb_alloc_even[0];
-        dlsch0_harq->rb_alloc_odd[1]= dlsch0_harq->rb_alloc_even[1];
-        dlsch0_harq->rb_alloc_odd[2]= dlsch0_harq->rb_alloc_even[2];
-        dlsch0_harq->rb_alloc_odd[3]= dlsch0_harq->rb_alloc_even[3];
-
-        if (TB1_active == 1){
-          dlsch1_harq->rb_alloc_even[0]= dlsch0_harq->rb_alloc_even[0];
-          dlsch1_harq->rb_alloc_even[1]= dlsch0_harq->rb_alloc_even[1];
-          dlsch1_harq->rb_alloc_even[2]= dlsch0_harq->rb_alloc_even[2];
-          dlsch1_harq->rb_alloc_even[3]= dlsch0_harq->rb_alloc_even[3];
-          dlsch1_harq->rb_alloc_odd[0] = dlsch0_harq->rb_alloc_odd[0];
-          dlsch1_harq->rb_alloc_odd[1] = dlsch0_harq->rb_alloc_odd[1];
-          dlsch1_harq->rb_alloc_odd[2] = dlsch0_harq->rb_alloc_odd[2];
-          dlsch1_harq->rb_alloc_odd[3] = dlsch0_harq->rb_alloc_odd[3];
-
-          dlsch1_harq->nb_rb = dlsch0_harq->nb_rb;
-
-          //dlsch0_harq->Nl       = 1;
-          //dlsch1_harq->Nl       = 1;
-        }
-      } else if ((TB0_active == 0) && (TB1_active == 1)){
-
-          conv_rballoc(rah,
-                       rballoc,
-                       frame_parms->N_RB_DL,
-                       dlsch1_harq->rb_alloc_even);
-
-          dlsch1_harq->rb_alloc_odd[0]= dlsch1_harq->rb_alloc_even[0];
-          dlsch1_harq->rb_alloc_odd[1]= dlsch1_harq->rb_alloc_even[1];
-          dlsch1_harq->rb_alloc_odd[2]= dlsch1_harq->rb_alloc_even[2];
-          dlsch1_harq->rb_alloc_odd[3]= dlsch1_harq->rb_alloc_even[3];
-          dlsch1_harq->nb_rb = conv_nprb(rah,
-                                         rballoc,
-                                         frame_parms->N_RB_DL);
-        }
-
-
-      // compute precoding matrix + mimo mode
-      if(dci_format == format2)
-      {
-      if ((TB0_active) && (TB1_active)){  //two CW active
-        compute_precoding_info_2cw(tpmi, tbswap, pdlsch0->pmi_alloc,frame_parms, dlsch0_harq, dlsch1_harq);
-
-   //   printf("[DCI UE 1]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
-      } else if ((TB0_active) && (!TB1_active))  { // only CW 0 active
-        compute_precoding_info_1cw(tpmi, pdlsch0->pmi_alloc, frame_parms, dlsch0_harq);
-      } else {
-        compute_precoding_info_1cw(tpmi, pdlsch1->pmi_alloc, frame_parms, dlsch1_harq);
-       // printf("I am doing compute_precoding_info_1cw with tpmi %d \n", tpmi);
-      }
-      //printf(" UE DCI harq0 MIMO mode = %d\n", dlsch0_harq->mimo_mode);
-      if ((frame_parms->mode1_flag == 1) && (TB0_active))
-        dlsch0_harq->mimo_mode   = SISO;
-      }
-      else
-      {
-        compute_precoding_info_format2A( tpmi,
-                                      frame_parms->nb_antenna_ports_eNB,
-                                      TB0_active,
-                                      TB1_active,
-                                      dlsch0_harq,
-                                      dlsch1_harq);
-      }
-  //    printf("[DCI UE 2]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
-      // reset round + compute Qm
-      if (TB0_active) {
-       // printf("TB0 ndi1 =%d, dlsch0_harq->DCINdi =%d, dlsch0_harq->first_tx = %d\n", ndi1, dlsch0_harq->DCINdi, dlsch0_harq->first_tx);
-        if ((ndi1!=dlsch0_harq->DCINdi) || (dlsch0_harq->first_tx==1))  {
-          dlsch0_harq->round = 0;
-           dlsch0_harq->status = ACTIVE;
-           dlsch0_harq->DCINdi = ndi1;
-
-          //LOG_I(PHY,"[UE] DLSCH: New Data Indicator CW0 subframe %d (pid %d, round %d)\n",
-          //           subframe,harq_pid,dlsch0_harq->round);
-          if ( dlsch0_harq->first_tx==1) {
-            LOG_D(PHY,"Format 2 DCI First TX0: Clearing flag\n");
-            dlsch0_harq->first_tx = 0;
-          }
-        }
-	/*else if (rv1  != 0 )
-	  //NDI has not been toggled but rv was increased by eNB: retransmission
-	  {
-	    if(dlsch0_harq->status == SCH_IDLE) {
-            // skip pdsch decoding and report ack
-	      //dlsch0_harq->status   = SCH_IDLE;
-            pdlsch0->active       = 0;
-            pdlsch0->harq_ack[subframe].ack = 1;
-            pdlsch0->harq_ack[subframe].harq_id = harq_pid;
-            pdlsch0->harq_ack[subframe].send_harq_status = 1;
-	    }*/
-
-        // if Imcs in [29..31] TBS is assumed to be as determined from DCI transported in the latest
-        // PDCCH for the same trasport block using Imcs in [0 .. 28]
-        if(dlsch0_harq->mcs <= 28)
-        {
-            dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
-            LOG_D(PHY,"[UE] DLSCH: New TBS CW0 subframe %d (pid %d, round %d) TBS %d \n",
-                       subframe,harq_pid,dlsch0_harq->round, dlsch0_harq->TBS);
-        }
-        else
-        {
-            LOG_D(PHY,"[UE] DLSCH: Keep the same TBS CW0 subframe %d (pid %d, round %d) TBS %d \n",
-                       subframe,harq_pid,dlsch0_harq->round, dlsch0_harq->TBS);
-        }
-        //if(dlsch0_harq->Nl == 2)
-        //dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1];
-        if (mcs1 <= 28)
-            dlsch0_harq->Qm = get_Qm(mcs1);
-        else if (mcs1<=31)
-            dlsch0_harq->Qm = (mcs1-28)<<1;
-      }
-
-   //   printf("[DCI UE 3]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
-
-      if (TB1_active) {
-       // printf("TB1 ndi2 =%d, dlsch1_harq->DCINdi =%d, dlsch1_harq->first_tx = %d\n", ndi2, dlsch1_harq->DCINdi, dlsch1_harq->first_tx);
-        if ((ndi2!=dlsch1_harq->DCINdi) || (dlsch1_harq->first_tx==1)) {
-          dlsch1_harq->round = 0;
-          dlsch1_harq->status = ACTIVE;
-          dlsch1_harq->DCINdi = ndi2;
-          //LOG_I(PHY,"[UE] DLSCH: New Data Indicator CW1 subframe %d (pid %d, round %d)\n",
-          //           subframe,harq_pid,dlsch0_harq->round);
-          if (dlsch1_harq->first_tx==1) {
-            LOG_D(PHY,"Format 2 DCI First TX1: Clearing flag\n");
-            dlsch1_harq->first_tx = 0;
-          }
-        }
-	/*else if (rv1  != 0 )
-	//NDI has not been toggled but rv was increased by eNB: retransmission
-	  {
-	    if(dlsch1_harq->status == SCH_IDLE) {
-            // skip pdsch decoding and report ack
-	      //dlsch1_harq->status   = SCH_IDLE;
-            pdlsch1->active       = 0;
-            pdlsch1->harq_ack[subframe].ack = 1;
-            pdlsch1->harq_ack[subframe].harq_id = harq_pid;
-            pdlsch1->harq_ack[subframe].send_harq_status = 1;
-         }
-	  }*/
-
-        // if Imcs in [29..31] TBS is assumed to be as determined from DCI transported in the latest
-        // PDCCH for the same trasport block using Imcs in [0 .. 28]
-        if(dlsch1_harq->mcs <= 28)
-        {
-            dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1];
-            LOG_D(PHY,"[UE] DLSCH: New TBS CW1 subframe %d (pid %d, round %d) TBS %d \n",
-                       subframe,harq_pid,dlsch1_harq->round, dlsch1_harq->TBS);
-        }
-        else
-        {
-            LOG_D(PHY,"[UE] DLSCH: Keep the same TBS CW1 subframe %d (pid %d, round %d) TBS %d \n",
-                       subframe,harq_pid,dlsch1_harq->round, dlsch1_harq->TBS);
-        }
-        if (mcs2 <= 28)
-            dlsch1_harq->Qm = get_Qm(mcs2);
-        else if (mcs1<=31)
-            dlsch1_harq->Qm = (mcs2-28)<<1;
-      }
-
-
-      compute_llr_offset(frame_parms,
-                         pdcch_vars,
-                         pdsch_vars,
-                         dlsch0_harq,
-                         dlsch0_harq->nb_rb,
-                         subframe);
-
-
- /* #ifdef DEBUG_HARQ
-      printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
-      printf("[DCI UE]: TB0_active %d , TB1_active %d\n", TB0_active, TB1_active);
-      if (dlsch0 != NULL && dlsch1 != NULL)
-        printf("[DCI UE] dlsch0_harq status = %d, dlsch1_harq status = %d\n", dlsch0_harq->status, dlsch1_harq->status);
-      else if (dlsch0 == NULL && dlsch1 != NULL)
-        printf("[DCI UE] dlsch0_harq NULL dlsch1_harq status = %d\n", dlsch1_harq->status);
-      else if (dlsch0 != NULL && dlsch1 == NULL)
-        printf("[DCI UE] dlsch1_harq NULL dlsch0_harq status = %d\n", dlsch0_harq->status);
-  #endif*/
-#endif
 }
 
 int generate_ue_dlsch_params_from_dci(int frame,
@@ -6375,13 +6121,12 @@ fflush(debug_sudas_LOG_PHY);
                 dci_pdu,
                 &dci_info_extarcted);
 
-
         // check dci content
         dlsch[0]->active = 0;
-        //dlsch[1]->active = 1;
+        dlsch[1]->active = 0;
 
             dlsch0 = dlsch[0];
-       //    dlsch1 = dlsch[1];
+          //  dlsch1 = dlsch[1];
 
     dlsch0_harq = dlsch0->harq_processes[dci_info_extarcted.harq_pid];
     //dlsch1_harq = dlsch1->harq_processes[dci_info_extarcted.harq_pid];
@@ -6398,11 +6143,11 @@ fflush(debug_sudas_LOG_PHY);
                 ra_rnti,
                 p_rnti,
                 dlsch0_harq,
-                dlsch0_harq);//dlsch0_harq
+                dlsch0_harq);//dlsch1_harq
          if(status == 0)
          {
              printf("bad DCI 2 !!! \n");
-             LOG_I(PHY,"[DCI-format2] frame.subframe %d.%d bad dci infomation \n", frame, subframe);
+             //LOG_I(PHY,"[DCI-format2] frame.subframe %d.%d bad dci infomation \n", frame, subframe);
              return(-1);
          }
 
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
index 6debacdb33419546318178d4c1a0d10cfcfb18b7..98e53e0276dbf551ce2f6237251e019a8d464f02 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
@@ -245,7 +245,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
     rballoc = dlsch0_harq->rb_alloc_even;
 
 
-  if (dlsch0_harq->mimo_mode>DUALSTREAM_PUSCH_PRECODING) {
+  if ((dlsch0_harq->mimo_mode>DUALSTREAM_PUSCH_PRECODING) && (dlsch0_harq->mimo_mode!=TM4_NO_PRECODING)) {
     LOG_E(PHY,"This transmission mode is not yet supported!\n");
     return(-1);
   }
@@ -436,7 +436,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
 #endif
   if (first_symbol_flag==1) {
     if (beamforming_mode==0){
-      if (dlsch0_harq->mimo_mode<LARGE_CDD) {
+      if ((dlsch0_harq->mimo_mode<LARGE_CDD)||(dlsch0_harq->mimo_mode == TM4_NO_PRECODING)) {
         dlsch_channel_level(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                            frame_parms,
                            avg,
@@ -560,8 +560,8 @@ int rx_pdsch(PHY_VARS_UE *ue,
     start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
 #endif
 // Now channel compensation
-  if (dlsch0_harq->mimo_mode<LARGE_CDD) {
-    dlsch_channel_compensation(pdsch_vars[eNB_id]->rxdataF_ext,
+  if ((dlsch0_harq->mimo_mode<LARGE_CDD)||(dlsch0_harq->mimo_mode == TM4_NO_PRECODING)) {
+	  dlsch_channel_compensation(pdsch_vars[eNB_id]->rxdataF_ext,
                                pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                pdsch_vars[eNB_id]->dl_ch_mag0,
                                pdsch_vars[eNB_id]->dl_ch_magb0,
@@ -787,7 +787,10 @@ int rx_pdsch(PHY_VARS_UE *ue,
 
 	//sudas_LOG_PHY(debug_sudas_LOG_PHY,"ue->measurements: rx_pdsch: dlsch_detection_mrc(); \n");
         //fflush(debug_sudas_LOG_PHY);
-      dlsch_detection_mrc(frame_parms,
+    	//if (dlsch0_harq->mimo_mode<LARGE_CDD)//Apply it for Alamouti only
+    	 if (dlsch0_harq->mimo_mode != TM4_NO_PRECODING)
+    	 {
+    	dlsch_detection_mrc(frame_parms,
                           pdsch_vars[eNB_id]->rxdataF_comp0,
                           pdsch_vars[eNB_id_i]->rxdataF_comp0,
                           pdsch_vars[eNB_id]->rho,
@@ -799,6 +802,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
                           symbol,
                           nb_rb,
                           rx_type==rx_IC_single_stream);
+    	 }
     }
   }
   //  printf("Combining");
@@ -823,7 +827,20 @@ int rx_pdsch(PHY_VARS_UE *ue,
                    pdsch_vars[eNB_id]->dl_ch_magb0,
                    symbol,
                    nb_rb);
-  }
+  } else if (dlsch0_harq->mimo_mode == TM4_NO_PRECODING) {
+
+
+	      dlsch_postcoding_tm4(frame_parms,
+	                     pdsch_vars[eNB_id]->rxdataF_comp0,
+	                     pdsch_vars[eNB_id]->dl_ch_mag0,
+	                     pdsch_vars[eNB_id]->dl_ch_magb0,
+	                     pdsch_vars[eNB_id]->rxdataF_comp0_tm4,
+	                     pdsch_vars[eNB_id]->dl_ch_mag0_tm4,
+	                     pdsch_vars[eNB_id]->dl_ch_magb0_tm4,
+	                     symbol,
+	                     nb_rb,
+	                     dlsch0_harq->Nl);
+	    }
 
   //    printf("LLR");
   if ((dlsch0_harq->mimo_mode == LARGE_CDD) ||
@@ -853,13 +870,13 @@ int rx_pdsch(PHY_VARS_UE *ue,
   //printf("LLR dlsch0_harq->Qm %d rx_type %d cw0 %d cw1 %d symbol %d \n",dlsch0_harq->Qm,rx_type,codeword_TB0,codeword_TB1,symbol);
   // compute LLRs
   // -> // compute @pointer where llrs should filled for this ofdm-symbol
-  int8_t  *pllr_symbol_cw0;
+  int8_t  *pllr_symbol_cw0;//pointer to 8 elements
   int8_t  *pllr_symbol_cw1;
   uint32_t llr_offset_symbol;
   llr_offset_symbol = pdsch_vars[eNB_id]->llr_offset[symbol];
   pllr_symbol_cw0  = (int8_t*)pdsch_vars[eNB_id]->llr[0];
   pllr_symbol_cw1  = (int8_t*)pdsch_vars[eNB_id]->llr[1];
-  pllr_symbol_cw0 += llr_offset_symbol;
+  pllr_symbol_cw0 += llr_offset_symbol;//offest per byte
   pllr_symbol_cw1 += llr_offset_symbol;
 
   /*LOG_I(PHY,"compute LLRs [AbsSubframe %d.%d-%d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %x @LLR Buff(symb) %x\n",
@@ -873,7 +890,18 @@ int rx_pdsch(PHY_VARS_UE *ue,
   switch (dlsch0_harq->Qm) {
   case 2 :
     if ((rx_type==rx_standard) || (codeword_TB1 == -1)) {
-        dlsch_qpsk_llr(frame_parms,
+    	 if(dlsch0_harq->mimo_mode == TM4_NO_PRECODING)
+    	  {
+   		  dlsch_qpsk_llr_tm4(frame_parms,
+                      pdsch_vars[eNB_id]->rxdataF_comp0_tm4,
+                      (int16_t*)pllr_symbol_cw0,
+                      symbol,
+                      first_symbol_flag,
+                      nb_rb,
+                      adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
+                      beamforming_mode,dlsch0_harq->Nl);
+    	  }else{
+    		  dlsch_qpsk_llr(frame_parms,
                        pdsch_vars[eNB_id]->rxdataF_comp0,
                        (int16_t*)pllr_symbol_cw0,
                        symbol,
@@ -881,6 +909,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
                        nb_rb,
                        adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
                        beamforming_mode);
+    	  }
 
     } else if (codeword_TB0 == -1){
 
@@ -962,7 +991,18 @@ int rx_pdsch(PHY_VARS_UE *ue,
     break;
   case 4 :
     if ((rx_type==rx_standard ) || (codeword_TB1 == -1)) {
-      dlsch_16qam_llr(frame_parms,
+     //printf("[AbsSFN %d.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+    	 if(dlsch0_harq->mimo_mode == TM4_NO_PRECODING){
+    		 dlsch_16qam_llr_tm4(frame_parms,
+    		                       pdsch_vars[eNB_id]->rxdataF_comp0_tm4,
+    		                       pdsch_vars[eNB_id]->llr[0],
+    		                       pdsch_vars[eNB_id]->dl_ch_mag0_tm4,
+    		                       symbol,first_symbol_flag,nb_rb,
+    		                       adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
+    		                       pdsch_vars[eNB_id]->llr128,
+    		                       beamforming_mode,dlsch0_harq->Nl);
+    	 }else{
+    		 dlsch_16qam_llr(frame_parms,
                       pdsch_vars[eNB_id]->rxdataF_comp0,
                       pdsch_vars[eNB_id]->llr[0],
                       pdsch_vars[eNB_id]->dl_ch_mag0,
@@ -970,6 +1010,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
                       adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
                       pdsch_vars[eNB_id]->llr128,
                       beamforming_mode);
+    	 }
     } else if (codeword_TB0 == -1){
       dlsch_16qam_llr(frame_parms,
                       pdsch_vars[eNB_id]->rxdataF_comp0,
@@ -1055,7 +1096,20 @@ int rx_pdsch(PHY_VARS_UE *ue,
     break;
   case 6 :
     if ((rx_type==rx_standard) || (codeword_TB1 == -1))  {
-      dlsch_64qam_llr(frame_parms,
+
+    	if(dlsch0_harq->mimo_mode == TM4_NO_PRECODING){
+    		dlsch_64qam_llr_tm4(frame_parms,
+                      pdsch_vars[eNB_id]->rxdataF_comp0_tm4,
+                      (int16_t*)pllr_symbol_cw0,
+                      pdsch_vars[eNB_id]->dl_ch_mag0_tm4,
+                      pdsch_vars[eNB_id]->dl_ch_magb0_tm4,
+                      symbol,first_symbol_flag,nb_rb,
+                      adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
+                      pdsch_vars[eNB_id]->llr_offset[symbol],
+                      beamforming_mode,dlsch0_harq->Nl);
+
+    	}else{
+    		dlsch_64qam_llr(frame_parms,
                       pdsch_vars[eNB_id]->rxdataF_comp0,
                       (int16_t*)pllr_symbol_cw0,
                       pdsch_vars[eNB_id]->dl_ch_mag0,
@@ -1064,6 +1118,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
                       adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
                       pdsch_vars[eNB_id]->llr_offset[symbol],
                       beamforming_mode);
+    	}
     } else if (codeword_TB0 == -1){
       dlsch_64qam_llr(frame_parms,
                       pdsch_vars[eNB_id]->rxdataF_comp0,
@@ -3538,9 +3593,9 @@ void dlsch_channel_level(int **dl_ch_estimates_ext,
 
   symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
 
-  if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0))
+  if (((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp)))&&(frame_parms->mode1_flag==0))//4-
     nre=8;
-  else if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==1))
+  else if (((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp)))&&(frame_parms->mode1_flag==1))//4-
     nre=10;
   else
     nre=12;
@@ -3567,7 +3622,7 @@ void dlsch_channel_level(int **dl_ch_estimates_ext,
         //avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[0],_mm_srai_epi16(_mm_mulhi_epi16(dl_ch128[0], coeff128),15)));
         //avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[1],_mm_srai_epi16(_mm_mulhi_epi16(dl_ch128[1], coeff128),15)));
 
-        if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) {
+        if (((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp)))&&(frame_parms->mode1_flag==0)) {//4-
           dl_ch128+=2;
         }
         else {
@@ -4160,6 +4215,97 @@ void dlsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms,
 #endif
 }
 
+void dlsch_postcoding_tm4(LTE_DL_FRAME_PARMS *frame_parms,
+                    int **rxdataF_comp,
+                    int **dl_ch_mag,
+                    int **dl_ch_magb,
+                    int **rxdataF_comp_tm4,
+                    int **dl_ch_mag_tm4,
+                    int **dl_ch_magb_tm4,
+                    unsigned char symbol,
+                    unsigned short nb_rb, unsigned char N_l)
+{
+
+#if defined(__x86_64__)||defined(__i386__)
+
+  short *rxF0,*rxF1,*rxFComb;
+
+  __m128i *ch_mag0,*ch_mag1,*ch_mag0b,*ch_mag1b, *ch_magComb, *ch_magCombb;
+
+  unsigned char rb,re;
+  int jj = (symbol*frame_parms->N_RB_DL*12);
+  int njnj = N_l*(symbol*frame_parms->N_RB_DL*12);
+  uint8_t symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
+  uint8_t pilots = ((symbol_mod==0)||(symbol_mod==(4-frame_parms->Ncp))) ? 1 : 0;
+
+
+  // Separate the two layer
+  rxF0     = (short*)&rxdataF_comp[0][jj];  //Rx antenna 0  H_11*y
+  rxF1     = (short*)&rxdataF_comp[3][jj];  //Rx antenna 1  H_22*y
+  rxFComb     = (short*)&rxdataF_comp_tm4[0][njnj];  //Rx 2 layer  [H_11*y H_22*y]
+
+  // Separate the two channels
+  ch_mag0 = (__m128i *)&dl_ch_mag[0][jj];  //Rx |H_11|^2
+  ch_mag1 = (__m128i *)&dl_ch_mag[3][jj];  //Rx |H_22|^2
+  ch_mag0b = (__m128i *)&dl_ch_magb[0][jj];//Rx |H_11|^2
+  ch_mag1b = (__m128i *)&dl_ch_magb[3][jj];//Rx |H_22|^2
+  ch_magComb     = (__m128i *)&dl_ch_mag_tm4[0][njnj];  //Rx 2 layer  [H_11 H_22]
+  ch_magCombb    = (__m128i *)&dl_ch_magb_tm4[0][njnj];  //Rx 2 layer [H_11 H_22]
+
+
+  for (rb=0; rb<nb_rb; rb++) {
+    for (re=0; re<((pilots==0)?12:8); re+=1) {
+      // TM4 RX combining
+      rxFComb[0] = rxF0[0];//real
+      rxFComb[1] = rxF0[1];//Imag
+
+      rxFComb[2] = rxF1[0];
+      rxFComb[3] = rxF1[1];
+
+      rxF0+=2;
+      rxF1+=2;
+      rxFComb+=4;
+    }
+    // Combine Channel Magintude
+    ch_magComb[0] = _mm_unpacklo_epi32(ch_mag0[0],ch_mag1[0]);
+    ch_magComb[1] = _mm_unpackhi_epi32(ch_mag0[0],ch_mag1[0]);
+    ch_magCombb[0] = _mm_unpacklo_epi32(ch_mag0b[0],ch_mag1b[0]);
+    ch_magCombb[1] = _mm_unpackhi_epi32(ch_mag0b[0],ch_mag1b[0]);
+
+    ch_magComb[2] = _mm_unpacklo_epi32(ch_mag0[1],ch_mag1[1]);
+    ch_magComb[3] = _mm_unpackhi_epi32(ch_mag0[1],ch_mag1[1]);
+    ch_magCombb[2] = _mm_unpacklo_epi32(ch_mag0b[1],ch_mag1b[1]);
+    ch_magCombb[3] = _mm_unpackhi_epi32(ch_mag0b[1],ch_mag1b[1]);
+
+    if (pilots==0) {
+    ch_magComb[4] = _mm_unpacklo_epi32(ch_mag0[2],ch_mag1[2]);
+    ch_magComb[5] = _mm_unpackhi_epi32(ch_mag0[2],ch_mag1[2]);
+    ch_magCombb[4] = _mm_unpacklo_epi32(ch_mag0b[2],ch_mag1b[2]);
+    ch_magCombb[5] = _mm_unpackhi_epi32(ch_mag0b[2],ch_mag1b[2]);
+
+      ch_mag0+=3;
+      ch_mag1+=3;
+      ch_mag0b+=3;
+      ch_mag1b+=3;
+      ch_magComb+=6;
+      ch_magCombb+=6;
+    } else {
+      ch_mag0+=2;
+      ch_mag1+=2;
+      ch_mag0b+=2;
+      ch_mag1b+=2;
+      ch_magComb+=4;
+      ch_magCombb+=4;
+    }
+  }
+
+  _mm_empty();
+  _m_empty();
+
+#elif defined(__arm__)
+
+#endif
+}
 
 //==============================================================================================
 // Extraction functions
@@ -5015,16 +5161,16 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF,
 
 
           prb_off      = 12*prb;
-          prb_off2     = 7+(12*(prb-(frame_parms->N_RB_DL>>1)-1));
+          prb_off2     = 7+(12*(prb-(frame_parms->N_RB_DL>>1)-1));//7=1RE(DC)+6REs for RB 12
           dl_ch0p      = dl_ch0+(12*prb);
           dl_ch1p      = dl_ch1+(12*prb);
 
-          if (prb<=(frame_parms->N_RB_DL>>1)){
+          if (prb<=(frame_parms->N_RB_DL>>1)){//sfn: prb=0,...,12 -ve portion of the spectrum
             rxF      = &rxdataF[aarx][prb_off+
                                       frame_parms->first_carrier_offset +
                                       (symbol*(frame_parms->ofdm_symbol_size))];
           }
-          else {
+          else {//sfn: prb=13,...,25 +ve portion of the spectrum
             rxF      = &rxdataF[aarx][prb_off2+
                                       (symbol*(frame_parms->ofdm_symbol_size))];
           }
@@ -5037,7 +5183,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF,
            *pmi_loc=(pmi>>prb)&1;
          // printf("symbol_mod %d (pilots %d) rb %d, sb %d, pmi %d (pmi_loc %p,rxF %p, ch00 %p, ch01 %p, rxF_ext %p dl_ch0_ext %p dl_ch1_ext %p)\n",symbol_mod,pilots,prb,prb>>2,*pmi_loc,pmi_loc,rxF,dl_ch0, dl_ch1, rxF_ext,dl_ch0_ext,dl_ch1_ext);
 */
-         *pmi_loc = get_pmi(frame_parms->N_RB_DL,mimo_mode,pmi,prb);
+         *pmi_loc = get_pmi(frame_parms->N_RB_DL,mimo_mode,pmi,prb);//sfn: we check this later
           pmi_loc++;
 
           if (prb != (frame_parms->N_RB_DL>>1)) { // This PRB is not around DC
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
index a258fdeab276d06819f7fd128a4ecacaad37567b..d2b4e20c9e9a6cd2842dfffda68b177f5bc4304e 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
@@ -660,7 +660,7 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
 
   if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) {
     if (frame_parms->mode1_flag==0)
-      len = (nb_rb*8) - (2*pbch_pss_sss_adjust/3);
+      len = (nb_rb*8) - (2*pbch_pss_sss_adjust/3);// In the case of TM4 Nl=2, len should be multiplied by N_l
     else
       len = (nb_rb*10) - (5*pbch_pss_sss_adjust/6);
   } else if((beamforming_mode==7) && (frame_parms->Ncp==0) && (symbol==3 || symbol==6 || symbol==9 || symbol==12)){
@@ -668,7 +668,7 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
   } else if((beamforming_mode==7) && (frame_parms->Ncp==1) && (symbol==4 || symbol==7 || symbol==10)){
       len = (nb_rb*8) - (2*pbch_pss_sss_adjust/3);
   } else {
-    len = (nb_rb*12) - pbch_pss_sss_adjust;
+    len = (nb_rb*12) - pbch_pss_sss_adjust;// In the case of TM4 Nl=2, len should be multiplied by N_l
   }
 
 
@@ -693,6 +693,50 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
   return(0);
 }
 
+int dlsch_qpsk_llr_tm4(LTE_DL_FRAME_PARMS *frame_parms,
+                   int32_t **rxdataF_comp,
+                   int16_t *dlsch_llr,
+                   uint8_t symbol,
+                   uint8_t first_symbol_flag,
+                   uint16_t nb_rb,
+                   uint16_t pbch_pss_sss_adjust,
+                   uint8_t beamforming_mode,
+                   uint8_t Nl)
+{
+
+  uint32_t *rxF = (uint32_t*)&rxdataF_comp[0][((int32_t)symbol*frame_parms->N_RB_DL*12*Nl)];
+  uint32_t *llr32;
+  int i,len;
+  uint8_t symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol;
+
+  llr32 = (uint32_t*)dlsch_llr;
+  if (!llr32) {
+    msg("dlsch_qpsk_llr: llr is null, symbol %d, llr32=%p\n",symbol, llr32);
+    return(-1);
+  }
+
+  if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) {
+    if (frame_parms->mode1_flag==0)
+      len = Nl*((nb_rb*8) - (2*pbch_pss_sss_adjust/3));// In the case of TM4 Nl=2, len should be multiplied by N_l
+    else
+      len = (nb_rb*10) - (5*pbch_pss_sss_adjust/6);
+  } else if((beamforming_mode==7) && (frame_parms->Ncp==0) && (symbol==3 || symbol==6 || symbol==9 || symbol==12)){
+      len = (nb_rb*9) - (3*pbch_pss_sss_adjust/4);
+  } else if((beamforming_mode==7) && (frame_parms->Ncp==1) && (symbol==4 || symbol==7 || symbol==10)){
+      len = (nb_rb*8) - (2*pbch_pss_sss_adjust/3);
+  } else {
+    len = Nl*((nb_rb*12) - pbch_pss_sss_adjust);// In the case of TM4 Nl=2, len should be multiplied by N_l
+  }
+
+  for (i=0; i<len; i++) {
+    *llr32 = *rxF;
+    rxF++;
+    llr32++;
+  }
+
+  return(0);
+}
+
 int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms,
                            int32_t **rxdataF_comp,
                            int32_t **sic_buffer,  //Q15
@@ -930,6 +974,91 @@ void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
   _m_empty();
 #endif
 }
+//KhodrSaaifan
+void dlsch_16qam_llr_tm4(LTE_DL_FRAME_PARMS *frame_parms,
+                     int32_t **rxdataF_comp,
+                     int16_t *dlsch_llr,
+                     int32_t **dl_ch_mag,
+                     uint8_t symbol,
+                     uint8_t first_symbol_flag,
+                     uint16_t nb_rb,
+                     uint16_t pbch_pss_sss_adjust,
+                     int16_t **llr32p,
+                     uint8_t beamforming_mode,
+                     uint8_t Nl)
+{
+
+#if defined(__x86_64__) || defined(__i386__)
+  __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12*Nl)];
+  __m128i *ch_mag;
+  __m128i llr128[2];//Array of 128bit variable
+  uint32_t *llr32;
+
+  int i,len;
+  unsigned char symbol_mod,len_mod4=0;
+
+  if (first_symbol_flag==1) {
+    llr32 = (uint32_t*)dlsch_llr;//point to LLR[0]
+  } else {
+    llr32 = (uint32_t*)*llr32p;//update LLR pointer according to previous
+  }
+
+
+  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
+
+  ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12*Nl)];
+
+  if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) {
+    if (frame_parms->mode1_flag==0)
+      len = ((nb_rb*8) - (2*pbch_pss_sss_adjust/3))*Nl;
+    else
+      len = (nb_rb*10) - (5*pbch_pss_sss_adjust/6);
+  } else if((beamforming_mode==7) && (frame_parms->Ncp==0) && (symbol==3 || symbol==6 || symbol==9 || symbol==12)){
+      len = (nb_rb*9) - (3*pbch_pss_sss_adjust/4);
+  } else if((beamforming_mode==7) && (frame_parms->Ncp==1) && (symbol==4 || symbol==7 || symbol==10)){
+      len = (nb_rb*8) - (2*pbch_pss_sss_adjust/3);
+  } else {
+    len = ((nb_rb*12) - pbch_pss_sss_adjust)*Nl;
+  }
+
+  // update output pointer according to number of REs in this symbol (<<2 because 4 bits per RE)
+  if (first_symbol_flag == 1)
+    *llr32p = dlsch_llr + (len<<2);//Update for next time with Qm 4 bits
+  else
+    *llr32p += (len<<2);
+
+ // printf("len=%d\n", len);
+  len_mod4 = len&3;//in REs
+ // printf("len_mod4=%d\n", len_mod4);
+  len>>=2;  // length in quad words (4 REs)
+ // printf("len>>=2=%d\n", len);
+  len+=(len_mod4==0 ? 0 : 1);
+ // printf("len+=%d\n", len);
+  for (i=0; i<len; i++) {//Number of REs/4
+
+    xmm0 = _mm_abs_epi16(rxF[i]);//|I0| |Q0| |I1| |Q1| |I2| |Q2| |I3| |Q3|
+    xmm0 = _mm_subs_epi16(ch_mag[i],xmm0);//|h|^2-|I0| |h|^2-|Q0| |h|^2-|I1| |h|^2-|Q1| |h|^2-|I2| |h|^2-|Q2| |h|^2-|I3| |h|^2-|Q3|
+
+    // lambda_1=y_R, lambda_2=|y_R|-|h|^2, lamda_3=y_I, lambda_4=|y_I|-|h|^2
+    llr128[0] = _mm_unpacklo_epi32(rxF[i],xmm0);//upacking low 64 bits
+    llr128[1] = _mm_unpackhi_epi32(rxF[i],xmm0);//upacking high 64 bits
+    //////////////////////////////////////////////////////
+    llr32[0] = _mm_extract_epi32(llr128[0],0); //((uint32_t *)&llr128[0])[0];
+    llr32[1] = _mm_extract_epi32(llr128[0],1); //((uint32_t *)&llr128[0])[1];
+    llr32[2] = _mm_extract_epi32(llr128[0],2); //((uint32_t *)&llr128[0])[2];
+    llr32[3] = _mm_extract_epi32(llr128[0],3); //((uint32_t *)&llr128[0])[3];
+    llr32[4] = _mm_extract_epi32(llr128[1],0); //((uint32_t *)&llr128[1])[0];
+    llr32[5] = _mm_extract_epi32(llr128[1],1); //((uint32_t *)&llr128[1])[1];
+    llr32[6] = _mm_extract_epi32(llr128[1],2); //((uint32_t *)&llr128[1])[2];
+    llr32[7] = _mm_extract_epi32(llr128[1],3); //((uint32_t *)&llr128[1])[3];
+    llr32+=8;
+  }
+
+  _mm_empty();
+  _m_empty();
+#endif
+}
+
 
 void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms,
                           int32_t **rxdataF_comp,
@@ -1206,7 +1335,114 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
   _m_empty();
 #endif
 }
+//KhodrSaaifan
+void dlsch_64qam_llr_tm4(LTE_DL_FRAME_PARMS *frame_parms,
+                     int32_t **rxdataF_comp,
+                     int16_t *dlsch_llr,
+                     int32_t **dl_ch_mag,
+                     int32_t **dl_ch_magb,
+                     uint8_t symbol,
+                     uint8_t first_symbol_flag,
+                     uint16_t nb_rb,
+                     uint16_t pbch_pss_sss_adjust,
+                     //int16_t **llr_save,
+                     uint32_t llr_offset,
+                     uint8_t beamforming_mode,uint8_t Nl)
+{
+#if defined(__x86_64__) || defined(__i386__)
+  __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12*Nl)];
+  __m128i *ch_mag,*ch_magb;
+
+  int i,len,len2;
+  unsigned char symbol_mod,len_mod4;
+  short *llr;
+  int16_t *llr2;
+
+
+
+  llr = dlsch_llr;
+
+
+  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
+
+
+  ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12*Nl)];
+  ch_magb = (__m128i*)&dl_ch_magb[0][(symbol*frame_parms->N_RB_DL*12*Nl)];
+
+  if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) {
+    if (frame_parms->mode1_flag==0)
+      len = ((nb_rb*8) - (2*pbch_pss_sss_adjust/3))*Nl;
+    else
+      len = (nb_rb*10) - (5*pbch_pss_sss_adjust/6);
+  } else if((beamforming_mode==7) && (frame_parms->Ncp==0) && (symbol==3 || symbol==6 || symbol==9 || symbol==12)){
+      len = (nb_rb*9) - (3*pbch_pss_sss_adjust/4);
+  } else if((beamforming_mode==7) && (frame_parms->Ncp==1) && (symbol==4 || symbol==7 || symbol==10)){
+      len = (nb_rb*8) - (2*pbch_pss_sss_adjust/3);
+  } else {
+    len = ((nb_rb*12) - pbch_pss_sss_adjust)*Nl;
+  }
+
+
+
+  llr2 = llr;
+  llr += (len*6);
+
+  len_mod4 =len&3;
+  len2=len>>2;  // length in quad words (4 REs)
+  len2+=((len_mod4==0)?0:1);
+
+  for (i=0; i<len2; i++) {
+    xmm1 = _mm_abs_epi16(rxF[i]);
+    xmm1 = _mm_subs_epi16(ch_mag[i],xmm1);
+    xmm2 = _mm_abs_epi16(xmm1);
+    xmm2 = _mm_subs_epi16(ch_magb[i],xmm2);
+
+
+    llr2[0] = ((short *)&rxF[i])[0];
+    llr2[1] = ((short *)&rxF[i])[1];
+
+    llr2[2] = _mm_extract_epi16(xmm1,0);
+    llr2[3] = _mm_extract_epi16(xmm1,1);//((short *)&xmm1)[j+1];
+    llr2[4] = _mm_extract_epi16(xmm2,0);//((short *)&xmm2)[j];
+    llr2[5] = _mm_extract_epi16(xmm2,1);//((short *)&xmm2)[j+1];
+
 
+    llr2+=6;
+    llr2[0] = ((short *)&rxF[i])[2];
+    llr2[1] = ((short *)&rxF[i])[3];
+
+    llr2[2] = _mm_extract_epi16(xmm1,2);
+    llr2[3] = _mm_extract_epi16(xmm1,3);//((short *)&xmm1)[j+1];
+    llr2[4] = _mm_extract_epi16(xmm2,2);//((short *)&xmm2)[j];
+    llr2[5] = _mm_extract_epi16(xmm2,3);//((short *)&xmm2)[j+1];
+
+
+    llr2+=6;
+    llr2[0] = ((short *)&rxF[i])[4];
+    llr2[1] = ((short *)&rxF[i])[5];
+
+    llr2[2] = _mm_extract_epi16(xmm1,4);
+    llr2[3] = _mm_extract_epi16(xmm1,5);//((short *)&xmm1)[j+1];
+    llr2[4] = _mm_extract_epi16(xmm2,4);//((short *)&xmm2)[j];
+    llr2[5] = _mm_extract_epi16(xmm2,5);//((short *)&xmm2)[j+1];
+
+    llr2+=6;
+    llr2[0] = ((short *)&rxF[i])[6];
+    llr2[1] = ((short *)&rxF[i])[7];
+
+    llr2[2] = _mm_extract_epi16(xmm1,6);
+    llr2[3] = _mm_extract_epi16(xmm1,7);//((short *)&xmm1)[j+1];
+    llr2[4] = _mm_extract_epi16(xmm2,6);//((short *)&xmm2)[j];
+    llr2[5] = _mm_extract_epi16(xmm2,7);//((short *)&xmm2)[j+1];
+
+    llr2+=6;
+
+  }
+
+  _mm_empty();
+  _m_empty();
+#endif
+}
 //#if 0
 void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms,
                          int32_t **rxdataF_comp,
diff --git a/openair1/PHY/LTE_TRANSPORT/print_stats.c b/openair1/PHY/LTE_TRANSPORT/print_stats.c
index d26de08ff7ce30f0876446de674a5dc8a93ac04f..b9320a8ef932365c706e46433ffb12e45851f9b6 100644
--- a/openair1/PHY/LTE_TRANSPORT/print_stats.c
+++ b/openair1/PHY/LTE_TRANSPORT/print_stats.c
@@ -529,9 +529,10 @@ int dump_ue_stats(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,char* buffer, int length
 
       if (ue->transmission_mode[eNB] == 6)
         len += sprintf(&buffer[len], "[UE PROC] Mode 6 Wideband CQI eNB %d : %d dB\n",eNB,ue->measurements.precoded_cqi_dB[eNB][0]);
-
-      for (harq_pid=0;harq_pid<8;harq_pid++) {
-	len+=sprintf(&buffer[len],"[UE PROC] eNB %d: CW 0 harq_pid %d, mcs %d:",eNB,harq_pid,ue->dlsch[0][0][0]->harq_processes[harq_pid]->mcs);
+ 	 len += sprintf(&buffer[len], "/***************/\n");
+    for (harq_pid=0;harq_pid<8;harq_pid++) {
+	len+=sprintf(&buffer[len],"[UE PROC] eNB %d: CW 0 harq_pid %d, mcs %d:\n",eNB,harq_pid,ue->dlsch[0][0][0]->harq_processes[harq_pid]->mcs);
+	 len += sprintf(&buffer[len], "eNB %d: MIMO Mode = %d, Nl = %d, nb_rb = %d TBS = %d\n",eNB,ue->dlsch[0][0][0]->harq_processes[harq_pid]->mimo_mode==15? 4 : 2,ue->dlsch[0][0][0]->harq_processes[harq_pid]->Nl,ue->dlsch[0][0][0]->harq_processes[harq_pid]->nb_rb,ue->dlsch[0][0][0]->harq_processes[harq_pid]->TBS);
 	for (round=0;round<8;round++)
 	  len+=sprintf(&buffer[len],"%d/%d ",
 		       ue->dlsch[0][0][0]->harq_processes[harq_pid]->errors[round],
@@ -543,7 +544,7 @@ int dump_ue_stats(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,char* buffer, int length
 
         len += sprintf(&buffer[len], "[UE PROC] eNB %d: dl_power_off = %d\n",eNB,ue->dlsch[0][0][0]->harq_processes[0]->dl_power_off);
 
-	for (harq_pid=0;harq_pid<8;harq_pid++) {
+     for (harq_pid=0;harq_pid<8;harq_pid++) {
 	  len+=sprintf(&buffer[len],"[UE PROC] eNB %d: CW 1 harq_pid %d, mcs %d:",eNB,harq_pid,ue->dlsch[0][0][1]->harq_processes[0]->mcs);
 	  for (round=0;round<8;round++)
 	    len+=sprintf(&buffer[len],"%d/%d ",
diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h
index 17788b4506cb1d02bc44110cf1cca7063f66cc2c..0676f64b64e78ea58660a104b37eccbe765f1076 100644
--- a/openair1/PHY/LTE_TRANSPORT/proto.h
+++ b/openair1/PHY/LTE_TRANSPORT/proto.h
@@ -826,7 +826,16 @@ int32_t dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
                        uint16_t pbch_pss_sss_adj,
                        //int16_t **llr128p,
                        uint8_t beamforming_mode);
-
+//KhodrSaaifan
+int dlsch_qpsk_llr_tm4(LTE_DL_FRAME_PARMS *frame_parms,
+                   int32_t **rxdataF_comp,
+                   int16_t *dlsch_llr,
+                   uint8_t symbol,
+                   uint8_t first_symbol_flag,
+                   uint16_t nb_rb,
+                   uint16_t pbch_pss_sss_adjust,
+                   uint8_t beamforming_mode,
+                   uint8_t Nl);
 /**
    \brief This function generates log-likelihood ratios (decoder input) for single-stream 16QAM received waveforms
    @param frame_parms Frame descriptor structure
@@ -862,6 +871,18 @@ void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
                      uint16_t pbch_pss_sss_adjust,
                      int16_t **llr128p,
                      uint8_t beamforming_mode);
+//KhodrSaaifan
+void dlsch_16qam_llr_tm4(LTE_DL_FRAME_PARMS *frame_parms,
+                     int32_t **rxdataF_comp,
+                     int16_t *dlsch_llr,
+                     int32_t **dl_ch_mag,
+                     uint8_t symbol,
+                     uint8_t first_symbol_flag,
+                     uint16_t nb_rb,
+                     uint16_t pbch_pss_sss_adjust,
+                     int16_t **llr128p,
+                     uint8_t beamforming_mode,
+                     uint8_t Nl);
 /**
    \brief This function generates log-likelihood ratios (decoder input) for single-stream 16QAM received waveforms
    @param frame_parms Frame descriptor structure
@@ -914,6 +935,21 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
                      uint32_t llr_offset,
                      uint8_t beamforming_mode);
 
+//KhodrSaaifan
+void dlsch_64qam_llr_tm4(LTE_DL_FRAME_PARMS *frame_parms,
+		             int32_t **rxdataF_comp,
+                     int16_t *dlsch_llr,
+                     int32_t **dl_ch_mag,
+                     int32_t **dl_ch_magb,
+                     uint8_t symbol,
+                     uint8_t first_symbol_flag,
+                     uint16_t nb_rb,
+                     uint16_t pbch_pss_sss_adjust,
+                     //int16_t **llr_save,
+                     uint32_t llr_offset,
+                     uint8_t beamforming_mode,
+                     uint8_t Nl);
+
 
 /** \fn dlsch_siso(LTE_DL_FRAME_PARMS *frame_parms,
     int32_t **rxdataF_comp,
@@ -955,6 +991,30 @@ void dlsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms,
                     uint8_t symbol,
                     uint16_t nb_rb);
 
+/** \fn KhodrSaaifan: dlsch_postcoding_tm4(LTE_DL_FRAME_PARMS *frame_parms,
+    int32_t **rxdataF_comp,
+    int32_t **dl_ch_mag,
+    int32_t **dl_ch_magb,
+    uint8_t symbol,
+    uint16_t nb_rb)
+    \brief This function does Alamouti combining on RX and prepares LLR inputs by skipping pilots, PBCH and primary/secondary synchronization signals.
+    @param frame_parms Frame descriptor structure
+    @param rxdataF_comp Compensated channel output
+    @param dl_ch_mag First squared-magnitude of channel (16QAM and 64QAM) for LLR computation.  Alamouti combining should be performed on this as well. Result is stored in first antenna position
+    @param dl_ch_magb Second squared-magnitude of channel (64QAM only) for LLR computation.  Alamouti combining should be performed on this as well. Result is stored in first antenna position
+    @param symbol Symbol in sub-frame
+    @param nb_rb Number of RBs in this allocation
+*/
+void dlsch_postcoding_tm4(LTE_DL_FRAME_PARMS *frame_parms,
+                    int **rxdataF_comp,
+                    int **dl_ch_mag,
+                    int **dl_ch_magb,
+                    int **rxdataF_comp_tm4,
+                    int **dl_ch_mag_tm4,
+                    int **dl_ch_magb_tm4,
+                    uint8_t symbol,
+                    uint16_t nb_rb, uint8_t N_l);
+
 /** \fn dlsch_antcyc(LTE_DL_FRAME_PARMS *frame_parms,
     int32_t **rxdataF_comp,
     int32_t **dl_ch_mag,
diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h
index 535afc3eb1bc3c5cf13df109a5418837d4db281a..5c1df971d6189452166a7fc92282ad7a2294f869 100644
--- a/openair1/PHY/impl_defs_lte.h
+++ b/openair1/PHY/impl_defs_lte.h
@@ -614,7 +614,9 @@ typedef enum {
   DUALSTREAM_PUSCH_PRECODING=11,
   TM7=12,
   TM8=13,
-  TM9_10=14
+  TM9_10=14,
+  ////sfn: test TM4
+  TM4_NO_PRECODING=15
 } MIMO_mode_t;
 
 typedef enum {
@@ -850,6 +852,10 @@ typedef struct {
   /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
   /// - second index: ? [0..168*N_RB_DL[
   int32_t **rxdataF_comp0;
+  /// \brief Received frequency-domain signal after extraction and channel compensation.
+  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+  /// - second index: ? [0..N_l*168*N_RB_DL[
+  int32_t **rxdataF_comp0_tm4;
   /// \brief Received frequency-domain signal after extraction and channel compensation for the second stream. For the SIC receiver we need to store the history of this for each harq process and round
   /// - first index: ? [0..7] (hard coded) accessed via \c harq_pid
   /// - second index: ? [0..7] (hard coded) accessed via \c round
@@ -887,7 +893,11 @@ typedef struct {
   int32_t **dl_ch_mag0;
   /// \brief Magnitude of Downlink Channel second layer (16QAM level/First 64QAM level).
   /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: ? [0..168*N_RB_DL[
+  /// - second index: ? [0..N_l*168*N_RB_DL[
+  int32_t **dl_ch_mag0_tm4;
+    /// \brief Magnitude of Downlink Channel second layer (16QAM level/First 64QAM level).
+    /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+    /// - second index: ? [0..168*N_RB_DL[
   int32_t **dl_ch_mag1[8][8];
   /// \brief Magnitude of Downlink Channel, first layer (2nd 64QAM level).
   /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
@@ -895,6 +905,10 @@ typedef struct {
   int32_t **dl_ch_magb0;
   /// \brief Magnitude of Downlink Channel second layer (2nd 64QAM level).
   /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+  /// - second index: ? [0..N_l*168*N_RB_DL[
+  int32_t **dl_ch_magb0_tm4;
+  /// \brief Magnitude of Downlink Channel second layer (2nd 64QAM level).
+  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
   /// - second index: ? [0..168*N_RB_DL[
   int32_t **dl_ch_magb1[8][8];
   /// \brief Cross-correlation of two eNB signals.
diff --git a/openair2/NETWORK_DRIVER/MESH/common.c b/openair2/NETWORK_DRIVER/MESH/common.c
index 0eb7530ee6fabbf8c130d5172d5e9e27339879d0..81d3f31385036d55481d93f5a72c8dc56723132d 100644
--- a/openair2/NETWORK_DRIVER/MESH/common.c
+++ b/openair2/NETWORK_DRIVER/MESH/common.c
@@ -313,7 +313,7 @@ void nas_COMMON_receive(uint16_t dlen,
 
   printk("\n");
 #endif //NAS_DEBUG_RECEIVE
-  netif_rx(skb);
+  netif_rx_ni(skb);
 #ifdef NAS_DEBUG_RECEIVE
   printk("NAS_COMMON_RECEIVE: end\n");
 #endif