diff --git a/executables/nr-ru.c b/executables/nr-ru.c
index a5ef03be99dea5de7443ebe52557f529fcdd7814..f960bcc5e783c2a33af999630680005ee57cc0db 100644
--- a/executables/nr-ru.c
+++ b/executables/nr-ru.c
@@ -61,6 +61,7 @@ static int DEFRUTPCORES[] = {-1,-1,-1,-1};
 
 #include "ENB_APP/enb_paramdef.h"
 #include "GNB_APP/gnb_paramdef.h"
+#include "GNB_APP/MACRLC_nr_paramdef.h"
 #include "common/config/config_userapi.h"
 
 #include "SIMULATION/ETH_TRANSPORT/proto.h"
@@ -746,12 +747,12 @@ static radio_tx_gpio_flag_t get_gpio_flags(RU_t *ru, int slot)
   return flags_gpio;
 }
 
-void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
+void tx_rf(RU_t *ru, int frame,int slot, uint64_t timestamp)
+{
   RU_proc_t *proc = &ru->proc;
   NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
   nfapi_nr_config_request_scf_t *cfg = &ru->config;
   void *txp[ru->nb_tx];
-  unsigned int txs;
   int i;
   T(T_ENB_PHY_OUTPUT_SIGNAL,
     T_INT(0),
@@ -807,7 +808,7 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
     flags_burst = proc->first_tx == 1 ? TX_BURST_START : TX_BURST_MIDDLE;
   }
 
-  if (fp->freq_range == FR2)
+  if (ru->openair0_cfg.gpio_controller != RU_GPIO_CONTROL_NONE)
     flags_gpio = get_gpio_flags(ru, slot);
 
   const int flags = flags_burst | (flags_gpio << 4);
@@ -825,8 +826,11 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
   VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp + ru->ts_offset) & 0xffffffff);
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1);
   // prepare tx buffer pointers
-  txs = ru->rfdevice
-            .trx_write_func(&ru->rfdevice, timestamp + ru->ts_offset - sf_extension, txp, siglen + sf_extension, ru->nb_tx, flags);
+  uint32_t txs = ru->rfdevice.trx_write_func(&ru->rfdevice,
+                                             timestamp + ru->ts_offset - sf_extension,
+                                             txp,
+                                             siglen + sf_extension,
+                                             ru->nb_tx, flags);
   LOG_D(PHY,
         "[TXPATH] RU %d aa %d tx_rf, writing to TS %llu, %d.%d, unwrapped_frame %d, slot %d, flags %d, siglen+sf_extension %d, "
         "returned %d, E %f\n",
@@ -1060,7 +1064,8 @@ void *ru_stats_thread(void *param) {
   return(NULL);
 }
 
-void ru_tx_func(void *param) {
+void ru_tx_func(void *param)
+{
   processingData_RU_t *info = (processingData_RU_t *) param;
   RU_t *ru = info->ru;
   NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
@@ -1660,7 +1665,8 @@ void init_precoding_weights(PHY_VARS_gNB *gNB) {
   }
 }*/
 
-void set_function_spec_param(RU_t *ru) {
+void set_function_spec_param(RU_t *ru)
+{
   switch (ru->if_south) {
     case LOCAL_RF:   // this is an RU with integrated RF (RRU, gNB)
       reset_meas(&ru->rx_fhaul);
@@ -1877,6 +1883,17 @@ void stop_RU(int nb_ru) {
 /* from here function to use configuration module          */
 static void NRRCconfig_RU(configmodule_interface_t *cfg)
 {
+  paramdef_t  MacRLC_Params[] = MACRLCPARAMS_DESC;
+  paramlist_def_t MacRLC_ParamList = {CONFIG_STRING_MACRLC_LIST, NULL, 0};
+  config_getlist(config_get_if(), &MacRLC_ParamList, MacRLC_Params, sizeofArray(MacRLC_Params), NULL);
+  bool analog = false;
+  for (int n = 0; n < MacRLC_ParamList.numelt; n++) {
+    if (n != 0)
+      AssertFatal(analog == *MacRLC_ParamList.paramarray[n][MACRLC_ANALOG_BEAMFORMING_IDX].u8ptr,
+                  "Configuration error! Impossible to have different beamforming type in different instances\n");
+    analog = *MacRLC_ParamList.paramarray[n][MACRLC_ANALOG_BEAMFORMING_IDX].u8ptr;
+  }
+
   paramdef_t RUParams[] = RUPARAMS_DESC;
   paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST, NULL, 0};
   config_getlist(cfg, &RUParamList, RUParams, sizeofArray(RUParams), NULL);
@@ -1887,18 +1904,19 @@ static void NRRCconfig_RU(configmodule_interface_t *cfg)
     printf("Set RU mask to %lx\n",RC.ru_mask);
 
     for (int j = 0; j < RC.nb_RU; j++) {
-      RC.ru[j]                                      = (RU_t *)malloc(sizeof(RU_t));
+      RC.ru[j]  = (RU_t *)malloc(sizeof(RU_t));
       memset((void *)RC.ru[j],0,sizeof(RU_t));
-      RC.ru[j]->idx                                 = j;
-      RC.ru[j]->nr_frame_parms                      = (NR_DL_FRAME_PARMS *)malloc(sizeof(NR_DL_FRAME_PARMS));
-      RC.ru[j]->frame_parms                         = (LTE_DL_FRAME_PARMS *)malloc(sizeof(LTE_DL_FRAME_PARMS));
+      RC.ru[j]->idx  = j;
+      RC.ru[j]->nr_frame_parms  = (NR_DL_FRAME_PARMS *)malloc(sizeof(NR_DL_FRAME_PARMS));
+      RC.ru[j]->frame_parms = (LTE_DL_FRAME_PARMS *)malloc(sizeof(LTE_DL_FRAME_PARMS));
       printf("Creating RC.ru[%d]:%p\n", j, RC.ru[j]);
-      RC.ru[j]->if_timing                           = synch_to_ext_device;
+      RC.ru[j]->if_timing = synch_to_ext_device;
+      RC.ru[j]->analog_beamforming = analog;
 
       if (RC.nb_nr_L1_inst > 0)
-        RC.ru[j]->num_gNB                           = RUParamList.paramarray[j][RU_ENB_LIST_IDX].numelt;
+        RC.ru[j]->num_gNB = RUParamList.paramarray[j][RU_ENB_LIST_IDX].numelt;
       else
-        RC.ru[j]->num_gNB                           = 0;
+        RC.ru[j]->num_gNB  = 0;
 
       for (int i = 0; i < RC.ru[j]->num_gNB; i++)
         RC.ru[j]->gNB_list[i] = RC.gNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]];
@@ -1919,10 +1937,8 @@ static void NRRCconfig_RU(configmodule_interface_t *cfg)
                       "bad GPIO controller in configuration file: '%s'\n",
                       *(RUParamList.paramarray[j][RU_GPIO_CONTROL].strptr));
         }
-      } else {
-        RC.ru[j]->openair0_cfg.gpio_controller = RU_GPIO_CONTROL_GENERIC;
-        LOG_I(PHY, "RU GPIO control set as 'generic'\n");
-      }
+      } else
+        RC.ru[j]->openair0_cfg.gpio_controller = RU_GPIO_CONTROL_NONE;
 
       if (config_isparamset(RUParamList.paramarray[j], RU_TX_SUBDEV)) {
         RC.ru[j]->openair0_cfg.tx_subdev = strdup(*(RUParamList.paramarray[j][RU_TX_SUBDEV].strptr));
diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c
index a9f630198dc01f9abe4fe6ed1289ae0144118eff..e3ee0e45ab65f77c7d7c197f1b1e0c1bf77b6156 100644
--- a/openair1/PHY/INIT/nr_init_ru.c
+++ b/openair1/PHY/INIT/nr_init_ru.c
@@ -29,22 +29,22 @@
 
 void init_prach_ru_list(RU_t *ru);
 
-int nr_phy_init_RU(RU_t *ru) {
-
+int nr_phy_init_RU(RU_t *ru)
+{
   NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
-  int i,j;
-  int p;
-  int re;
 
   LOG_I(PHY,"Initializing RU signal buffers (if_south %s) nb_tx %d, nb_rx %d\n",ru_if_types[ru->if_south],ru->nb_tx, ru->nb_rx);
 
   nfapi_nr_config_request_scf_t *cfg;
-  ru->nb_log_antennas=0;
+  ru->nb_log_antennas = 0;
   for (int n=0;n<ru->num_gNB;n++) {
     cfg = &ru->config;
-    if (cfg->carrier_config.num_tx_ant.value > ru->nb_log_antennas) ru->nb_log_antennas = cfg->carrier_config.num_tx_ant.value;   
+    if (cfg->carrier_config.num_tx_ant.value > ru->nb_log_antennas)
+      ru->nb_log_antennas = cfg->carrier_config.num_tx_ant.value;
   }
-  // copy configuration from gNB[0] in to RU, assume that all gNB instances sharing RU use the same configuration (at least the parts that are needed by the RU, numerology and PRACH)
+
+  // copy configuration from gNB[0] in to RU, assume that all gNB instances sharing RU use the same configuration
+  // (at least the parts that are needed by the RU, numerology and PRACH)
 
   AssertFatal(ru->nb_log_antennas > 0 && ru->nb_log_antennas < 13, "ru->nb_log_antennas %d ! \n",ru->nb_log_antennas);
   if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so allocate memory for time-domain signals 
@@ -53,7 +53,7 @@ int nr_phy_init_RU(RU_t *ru) {
     ru->common.rxdata        = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) );
 
 
-    for (i=0; i<ru->nb_tx; i++) {
+    for (int i = 0; i < ru->nb_tx; i++) {
       // Allocate 10 subframes of I/Q TX signal data (time) if not
       ru->common.txdata[i]  = (int32_t*)malloc16_clear((ru->sf_extension + fp->samples_per_frame)*sizeof(int32_t));
       LOG_I(PHY,"[INIT] common.txdata[%d] = %p (%lu bytes,sf_extension %d)\n",i,ru->common.txdata[i],
@@ -63,7 +63,7 @@ int nr_phy_init_RU(RU_t *ru) {
       LOG_I(PHY,"[INIT] common.txdata[%d] = %p \n",i,ru->common.txdata[i]);
 
     }
-    for (i=0;i<ru->nb_rx;i++) {
+    for (int i = 0; i < ru->nb_rx; i++) {
       ru->common.rxdata[i] = (int32_t*)malloc16_clear( fp->samples_per_frame*sizeof(int32_t) );
     }
   } // IF5 or local RF
@@ -76,7 +76,7 @@ int nr_phy_init_RU(RU_t *ru) {
   if (ru->function != NGFI_RRU_IF5) { // we need to do RX/TX RU processing
     LOG_I(PHY,"nb_tx %d\n",ru->nb_tx);
     ru->common.rxdata_7_5kHz = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) );
-    for (i=0;i<ru->nb_rx;i++) {
+    for (int i = 0; i < ru->nb_rx; i++) {
       ru->common.rxdata_7_5kHz[i] = (int32_t*)malloc16_clear( 2*fp->samples_per_subframe*2*sizeof(int32_t) );
       LOG_I(PHY,"rxdata_7_5kHz[%d] %p for RU %d\n",i,ru->common.rxdata_7_5kHz[i],ru->idx);
     }
@@ -84,31 +84,33 @@ int nr_phy_init_RU(RU_t *ru) {
 
     // allocate precoding input buffers (TX)
     ru->common.txdataF = (int32_t **)malloc16(ru->nb_tx*sizeof(int32_t*));
-    for(i=0; i< ru->nb_tx; ++i)  ru->common.txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t)); // [hna] samples_per_frame without CP
+    // [hna] samples_per_frame without CP
+    for(int i = 0; i < ru->nb_tx; ++i)
+      ru->common.txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t));
 
     // allocate IFFT input buffers (TX)
     ru->common.txdataF_BF = (int32_t **)malloc16(ru->nb_tx*sizeof(int32_t*));
-    LOG_I(PHY,"[INIT] common.txdata_BF= %p (%lu bytes)\n",ru->common.txdataF_BF,
-	  ru->nb_tx*sizeof(int32_t*));
-    for (i=0; i<ru->nb_tx; i++) {
+    LOG_I(PHY,"[INIT] common.txdata_BF= %p (%lu bytes)\n", ru->common.txdataF_BF, ru->nb_tx*sizeof(int32_t*));
+    for (int i = 0; i < ru->nb_tx; i++) {
       ru->common.txdataF_BF[i] = (int32_t*)malloc16_clear(fp->samples_per_subframe_wCP*sizeof(int32_t) );
       LOG_I(PHY,"txdataF_BF[%d] %p for RU %d\n",i,ru->common.txdataF_BF[i],ru->idx);
     }
     // allocate FFT output buffers (RX)
     ru->common.rxdataF     = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) );
-    for (i=0; i<ru->nb_rx; i++) {    
+    for (int i = 0; i < ru->nb_rx; i++) {
       // allocate 4 slots of I/Q signal data (frequency)
-      ru->common.rxdataF[i] = (int32_t*)malloc16_clear(sizeof(**ru->common.rxdataF)*(RU_RX_SLOT_DEPTH*fp->symbols_per_slot*fp->ofdm_symbol_size) ); 
+      int size = RU_RX_SLOT_DEPTH * fp->symbols_per_slot * fp->ofdm_symbol_size;
+      ru->common.rxdataF[i] = (int32_t*)malloc16_clear(sizeof(**ru->common.rxdataF) * size);
       LOG_I(PHY,"rxdataF[%d] %p for RU %d\n",i,ru->common.rxdataF[i],ru->idx);
     }
 
     /* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) */
     //    AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]),
     //		"nb_antennas_rx too large");
-    for (j=0;j<NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX;j++) {
+    for (int j = 0; j < NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX; j++) {
       ru->prach_rxsigF[j] = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*));
       
-      for (i=0; i<ru->nb_rx; i++) {
+      for (int i = 0; i < ru->nb_rx; i++) {
 	// largest size for PRACH FFT is 4x98304 (16*24576)
 	ru->prach_rxsigF[j][i] = (int16_t*)malloc16_clear( 4*98304*2*sizeof(int16_t) );
 	LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[j][i]);
@@ -120,44 +122,8 @@ int nr_phy_init_RU(RU_t *ru) {
 
     LOG_I(PHY,"[INIT] %s() ru->num_gNB:%d \n", __FUNCTION__, ru->num_gNB);
 
-    if (ru->do_precoding == 1) {
-      int beam_count = 0;
-      if (ru->nb_tx>1) { //Enable beamforming when nb_tx > 1
-
-        for (p=0;p<ru->nb_log_antennas;p++) {
-          //if ((fp->L_ssb >> (63-p)) & 0x01)//64 bit-map with the MSB @2⁶³ corresponds to SSB ssb_index 0
-            beam_count++;
-        }
-        AssertFatal(ru->nb_bfw==(beam_count*ru->nb_tx),"Number of beam weights from config file is %d while the expected number is %d",ru->nb_bfw,(beam_count*ru->nb_tx));
-    
-        for (i=0; i<ru->num_gNB; i++) {
-          int l_ind = 0;
-          for (p=0;p<ru->nb_log_antennas;p++) {
-          //if ((fp->L_ssb >> (63-p)) & 0x01)  {
-            ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*));
-            for (j=0; j<ru->nb_tx; j++) {
-              ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t));
-              AssertFatal(ru->bw_list[i],"ru->bw_list[%d] is null\n",i);
-              for (re=0; re<fp->ofdm_symbol_size; re++)
-                ru->beam_weights[i][p][j][re] = ru->bw_list[i][l_ind];
-              //printf("Beam Weight %08x for beam %d and tx %d\n",ru->bw_list[i][l_ind],p,j);
-              l_ind++;
-            } // for j
-          //}
-          } // for p
-        } // for i
-      }
-
-      ru->common.beam_id = (uint8_t**)malloc16_clear(ru->nb_tx*sizeof(uint8_t*));
-      for(i=0; i< ru->nb_tx; ++i) {
-        ru->common.beam_id[i] = (uint8_t*)malloc16_clear(fp->symbols_per_slot*fp->slots_per_frame*sizeof(uint8_t));
-        memset(ru->common.beam_id[i],255,fp->symbols_per_slot*fp->slots_per_frame);
-      }
-    }
   } // !=IF5
 
-  ru->common.sync_corr = (uint32_t*)malloc16_clear( LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(uint32_t)*fp->samples_per_subframe_wCP );
-
   init_prach_ru_list(ru);
 
   return(0);
@@ -216,5 +182,4 @@ void nr_phy_free_RU(RU_t *ru)
       free_and_zero(ru->common.beam_id);
     }
   }
-  free_and_zero(ru->common.sync_corr);
 }
diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h
index 2f564eac6b6ddf5271f9adfe35a1e5c14fff2cda..3161b2066fe63ff08608f9edd7ae1e04b5310ebd 100644
--- a/openair1/PHY/defs_RU.h
+++ b/openair1/PHY/defs_RU.h
@@ -662,6 +662,7 @@ typedef struct RU_t_s {
   int num_tpcores;
   /// structure for analyzing high-level RT measurements
   rt_ru_profiling_t rt_ru_profiling; 
+  bool analog_beamforming;
 } RU_t;
 
 
diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c
index 93619732aeedc8f9044f1382739cc5996161b060..4189042c73b95a3b2cc4cd688df78ca43a5ba5bf 100644
--- a/openair1/SCHED_NR/nr_ru_procedures.c
+++ b/openair1/SCHED_NR/nr_ru_procedures.c
@@ -52,28 +52,37 @@
 extern int oai_exit;
 
 // OFDM modulation core routine, generates a first_symbol to first_symbol+num_symbols on a particular slot and TX antenna port
-void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) {
-
+void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa)
+{
   NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
 
   unsigned int slot_offset,slot_offsetF;
   int slot = tti_tx;
 
-
   //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(first_symbol!=0?1:0) , 1 );
 
-  if (aa==0 && first_symbol == 0) start_meas(&ru->ofdm_mod_stats);
-  slot_offset  = fp->get_samples_slot_timestamp(slot,fp,0);
-  slot_offsetF = first_symbol*fp->ofdm_symbol_size;
+  if (aa == 0 && first_symbol == 0)
+    start_meas(&ru->ofdm_mod_stats);
+  slot_offset  = fp->get_samples_slot_timestamp(slot, fp, 0);
+  slot_offsetF = first_symbol * fp->ofdm_symbol_size;
 
-  int abs_first_symbol = slot*fp->symbols_per_slot;
+  int abs_first_symbol = slot * fp->symbols_per_slot;
 
-  for (uint16_t idx_sym=abs_first_symbol; idx_sym<abs_first_symbol+first_symbol; idx_sym++)
-    slot_offset += (idx_sym%(0x7<<fp->numerology_index)) ? fp->nb_prefix_samples : fp->nb_prefix_samples0;
+  for (int idx_sym = abs_first_symbol; idx_sym < abs_first_symbol + first_symbol; idx_sym++)
+    slot_offset += (idx_sym % (0x7 << fp->numerology_index)) ? fp->nb_prefix_samples : fp->nb_prefix_samples0;
 
-  slot_offset += fp->ofdm_symbol_size*first_symbol;
+  slot_offset += fp->ofdm_symbol_size * first_symbol;
 
-  LOG_D(PHY,"SFN/SF:RU:TX:%d/%d aa %d Generating slot %d (first_symbol %d num_symbols %d) slot_offset %d, slot_offsetF %d\n",ru->proc.frame_tx, ru->proc.tti_tx,aa,slot,first_symbol,num_symbols,slot_offset,slot_offsetF);
+  LOG_D(PHY,
+        "SFN/SF:RU:TX:%d/%d aa %d Generating slot %d (first_symbol %d num_symbols %d) slot_offset %d, slot_offsetF %d\n",
+        ru->proc.frame_tx,
+        ru->proc.tti_tx,
+        aa,
+        slot,
+        first_symbol,
+        num_symbols,
+        slot_offset,
+        slot_offsetF);
   
   if (fp->Ncp == 1) {
     PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF],
@@ -110,8 +119,8 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) {
       }
     } // numerology_index!=0
     else { //numerology_index == 0
-      for (uint16_t idx_sym=abs_first_symbol; idx_sym<abs_first_symbol+num_symbols; idx_sym++) {
-        if (idx_sym%0x7) {
+      for (int idx_sym = abs_first_symbol; idx_sym < abs_first_symbol+num_symbols; idx_sym++) {
+        if (idx_sym % 0x7) {
           PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF],
                        (int*)&ru->common.txdata[aa][slot_offset],
                        fp->ofdm_symbol_size,
@@ -135,7 +144,8 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) {
     } //  numerology 0
   }
 
-  if (aa==0 && first_symbol==0) stop_meas(&ru->ofdm_mod_stats);
+  if (aa == 0 && first_symbol == 0)
+    stop_meas(&ru->ofdm_mod_stats);
         
   //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(first_symbol!=0?1:0), 0);
 }
@@ -261,48 +271,42 @@ void nr_fep_full(RU_t *ru, int slot) {
 }
 
 // core routine for FEP TX, called from threads in RU TX thread-pool 
-void nr_feptx(void *arg) {
-
+void nr_feptx(void *arg)
+{
   feptx_cmd_t *feptx = (feptx_cmd_t *)arg;
 
-  RU_t *ru    = feptx->ru;
-  int  slot  = feptx->slot;
-  int  aa    = feptx->aid;
-  int  startSymbol = feptx->startSymbol;
-  NR_DL_FRAME_PARMS  *fp    = ru->nr_frame_parms;
-  int  numSymbols  = feptx->numSymbols;
-  int  numSamples  = feptx->numSymbols*fp->ofdm_symbol_size; 
-  int txdataF_offset = (slot*fp->samples_per_slot_wCP) + startSymbol*fp->ofdm_symbol_size;
-  int txdataF_BF_offset = startSymbol*fp->ofdm_symbol_size;
-
-      ////////////precoding////////////
+  RU_t *ru = feptx->ru;
+  int slot = feptx->slot;
+  int aa = feptx->aid;
+  int startSymbol = feptx->startSymbol;
+  NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
+  int numSymbols = feptx->numSymbols;
+  int numSamples = feptx->numSymbols * fp->ofdm_symbol_size;
+  int txdataF_offset = (slot * fp->samples_per_slot_wCP) + startSymbol * fp->ofdm_symbol_size;
+  int txdataF_BF_offset = startSymbol * fp->ofdm_symbol_size;
+
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->aid , 1);
-      
-  if (aa==0) start_meas(&ru->precoding_stats);
 
-  if (ru->do_precoding == 1) {
-     for(int i=0; i<ru->nb_log_antennas; ++i) {
+  if (aa == 0)
+    start_meas(&ru->precoding_stats);
+
+  if (ru->config.dbt_config.num_dig_beams != 0) {
+     for(int i = 0; i < ru->nb_log_antennas; ++i) {
        memcpy((void*) &ru->common.beam_id[i][slot*fp->symbols_per_slot],
               (void*) &ru->gNB_list[0]->common_vars.beam_id[i][slot*fp->symbols_per_slot],
               (fp->symbols_per_slot)*sizeof(uint8_t));
       }
   }
 
-  if (ru->nb_tx == 1 && ru->nb_log_antennas == 1) {
-     memcpy((void*)&ru->common.txdataF_BF[0][txdataF_BF_offset],
-            (void*)&ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset],
-            numSamples*sizeof(int32_t));
-  }
-  else if (ru->do_precoding == 0) {
-     int gNB_tx = ru->gNB_list[0]->frame_parms.nb_antennas_tx;
+  // If there is no digital beamforming we just need to copy the data to RU
+  if (ru->config.dbt_config.num_dig_beams == 0 || ru->analog_beamforming)
      memcpy((void*)&ru->common.txdataF_BF[aa][txdataF_BF_offset],
-            (void*)&ru->gNB_list[0]->common_vars.txdataF[aa%gNB_tx][txdataF_offset],
-            numSamples*sizeof(int32_t));
-  }
+            (void*)&ru->gNB_list[0]->common_vars.txdataF[aa][txdataF_offset],
+            numSamples * sizeof(int32_t));
   else {
-     AssertFatal(1==0,"This needs to be fixed, do not use beamforming.\n");
+     AssertFatal(1 == 0, "This needs to be fixed, do not use beamforming.\n");
      int32_t ***bw  = ru->beam_weights[0];
-     for(int i=0; i<fp->symbols_per_slot; ++i){
+     for(int i = 0; i < fp->symbols_per_slot; ++i) {
        nr_beam_precoding((c16_t **)ru->gNB_list[0]->common_vars.txdataF,
                          (c16_t **)ru->common.txdataF_BF,
                          fp,
@@ -311,55 +315,60 @@ void nr_feptx(void *arg) {
                          i,
                          aa,
                          ru->nb_log_antennas,
-                         txdataF_offset);//here
+                         txdataF_offset);
      }
   }
-  if (aa==0) stop_meas(&ru->precoding_stats);
+
+  if (aa==0)
+    stop_meas(&ru->precoding_stats);
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->aid , 0);
 
       ////////////FEPTX////////////
-  nr_feptx0(ru,slot,startSymbol,numSymbols,aa);
+  nr_feptx0(ru, slot, startSymbol, numSymbols, aa);
 }
 
 // RU FEP TX using thread-pool
-void nr_feptx_tp(RU_t *ru, int frame_tx, int slot) {
-
+void nr_feptx_tp(RU_t *ru, int frame_tx, int slot)
+{
   nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
-  int nbfeptx=0;
-  if (nr_slot_select(cfg,frame_tx,slot) == NR_UPLINK_SLOT) return;
-//  for (int aa=0; aa<ru->nb_tx; aa++) memset(ru->common.txdataF[aa],0,ru->nr_frame_parms->samples_per_slot_wCP*sizeof(int32_t));
-
-  if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM, 1 );
+  int nbfeptx = 0;
+  if (nr_slot_select(cfg, frame_tx, slot) == NR_UPLINK_SLOT)
+    return;
+  if (ru->idx == 0)
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM, 1);
   start_meas(&ru->ofdm_total_stats);
-  for (int aid=0;aid<ru->nb_tx;aid++) {
-       notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feptx_cmd_t), 2000 + aid,ru->respfeptx,nr_feptx);
-       feptx_cmd_t *feptx_cmd=(feptx_cmd_t*)NotifiedFifoData(req);       
-       feptx_cmd->aid          = aid;
-       feptx_cmd->ru           = ru;
-       feptx_cmd->slot         = slot;
-       feptx_cmd->startSymbol  = 0;
-       feptx_cmd->numSymbols   = (ru->half_slot_parallelization>0)?ru->nr_frame_parms->symbols_per_slot>>1:ru->nr_frame_parms->symbols_per_slot;
-       pushTpool(ru->threadPool,req);
+  for (int aid = 0; aid < ru->nb_tx; aid++) {
+       notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feptx_cmd_t), 2000 + aid, ru->respfeptx, nr_feptx);
+       feptx_cmd_t *feptx_cmd = (feptx_cmd_t*)NotifiedFifoData(req);
+       feptx_cmd->aid = aid;
+       feptx_cmd->ru = ru;
+       feptx_cmd->slot = slot;
+       feptx_cmd->startSymbol = 0;
+       feptx_cmd->numSymbols = (ru->half_slot_parallelization > 0) ?
+                               ru->nr_frame_parms->symbols_per_slot >> 1 :
+                               ru->nr_frame_parms->symbols_per_slot;
+       pushTpool(ru->threadPool, req);
        nbfeptx++;
-       if (ru->half_slot_parallelization>0) {
-         notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feptx_cmd_t), 2000 + aid + ru->nb_tx,ru->respfeptx,nr_feptx);
-         feptx_cmd_t *feptx_cmd=(feptx_cmd_t*)NotifiedFifoData(req);       
-         feptx_cmd->aid          = aid;
-         feptx_cmd->ru           = ru;
-         feptx_cmd->slot         = slot;
-         feptx_cmd->startSymbol  = ru->nr_frame_parms->symbols_per_slot>>1;
-         feptx_cmd->numSymbols   = ru->nr_frame_parms->symbols_per_slot>>1;
-         pushTpool(ru->threadPool,req);
+       if (ru->half_slot_parallelization > 0) {
+         notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feptx_cmd_t), 2000 + aid + ru->nb_tx, ru->respfeptx, nr_feptx);
+         feptx_cmd_t *feptx_cmd = (feptx_cmd_t*)NotifiedFifoData(req);
+         feptx_cmd->aid = aid;
+         feptx_cmd->ru = ru;
+         feptx_cmd->slot = slot;
+         feptx_cmd->startSymbol = ru->nr_frame_parms->symbols_per_slot >> 1;
+         feptx_cmd->numSymbols = ru->nr_frame_parms->symbols_per_slot >> 1;
+         pushTpool(ru->threadPool, req);
          nbfeptx++;
        }
   }
-  while (nbfeptx>0) {
+  while (nbfeptx > 0) {
     notifiedFIFO_elt_t *req=pullTpool(ru->respfeptx, ru->threadPool);
     delNotifiedFIFO_elt(req);
     nbfeptx--;
   }
   stop_meas(&ru->ofdm_total_stats);
-  if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM, 0 );
+  if (ru->idx == 0)
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM, 0);
 }
 
 // core RX FEP routine, called by threads in RU thread-pool
diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h
index ff594608ac941cca6998af0038ff89fb175292e4..5fd4cdce706bbd5c335a4e17e99907cd36e63e94 100644
--- a/openair2/ENB_APP/enb_paramdef.h
+++ b/openair2/ENB_APP/enb_paramdef.h
@@ -169,7 +169,7 @@ typedef enum {
 #define RU_NUM_INTERFACES             39
 #define RU_HALF_SLOT_PARALLELIZATION  40
 #define RU_RU_THREAD_CORE             41
-#define RU_GPIO_CONTROL 42
+#define RU_GPIO_CONTROL               42
 /*-----------------------------------------------------------------------------------------------------------------------------------------*/
 /*                                            RU configuration parameters                                                                  */
 /*   optname                                   helpstr   paramflags    XXXptr          defXXXval                   type      numelt        */
diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c
index cf4a17f8d377f9d3f8eccbcad88b7d57c3fb80e1..8976de0ed66fdce5ef94ef34931f2c8eb5af8b52 100644
--- a/openair2/GNB_APP/gnb_config.c
+++ b/openair2/GNB_APP/gnb_config.c
@@ -2412,7 +2412,7 @@ ngran_node_t get_node_type(void)
   char aprefix[MAX_OPTNAME_SIZE*2 + 8];
   sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0);
   config_getlist(config_get_if(), &GNBE1ParamList, GNBE1Params, sizeofArray(GNBE1Params), aprefix);
-  if ( MacRLC_ParamList.numelt > 0) {
+  if (MacRLC_ParamList.numelt > 0) {
     RC.nb_nr_macrlc_inst = MacRLC_ParamList.numelt; 
     for (int j = 0; j < RC.nb_nr_macrlc_inst; j++) {
       if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "f1") == 0) {
diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c
index 047fd9ead81d5305aff6dee08e042ef8f1b9ff68..98a0c1c43ef950cca9953f3d286efed12a50a494 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -596,17 +596,19 @@ static void config_common(gNB_MAC_INST *nrmac,
   cfg->pmi_list = init_DL_MIMO_codebook(nrmac, pdsch_AntennaPorts);
   // beamforming matrix configuration
   cfg->dbt_config.num_dig_beams = nb_beams;
-  cfg->dbt_config.num_txrus = nb_tx;
-  cfg->dbt_config.dig_beam_list = malloc16(nb_beams * sizeof(*cfg->dbt_config.dig_beam_list));
-  AssertFatal(cfg->dbt_config.dig_beam_list, "out of memory\n");
-  for (int i = 0; i < nb_beams; i++) {
-    nfapi_nr_dig_beam_t *beam = &cfg->dbt_config.dig_beam_list[i];
-    beam->beam_idx = i;
-    beam->txru_list = malloc16(nb_tx * sizeof(*beam->txru_list));
-    for (int j = 0; j < nb_tx; j++) {
-      beam->txru_list[j].dig_beam_weight_Re = bw_list[j + i * nb_tx] & 0xffff;
-      beam->txru_list[j].dig_beam_weight_Im = (bw_list[j + i * nb_tx] >> 16) & 0xffff;
-      LOG_D(NR_MAC, "Beam %d Tx %d Weight (%d, %d)\n", i, j, beam->txru_list[j].dig_beam_weight_Re, beam->txru_list[j].dig_beam_weight_Im);
+  if (nb_beams > 0) {
+    cfg->dbt_config.num_txrus = nb_tx;
+    cfg->dbt_config.dig_beam_list = malloc16(nb_beams * sizeof(*cfg->dbt_config.dig_beam_list));
+    AssertFatal(cfg->dbt_config.dig_beam_list, "out of memory\n");
+    for (int i = 0; i < nb_beams; i++) {
+      nfapi_nr_dig_beam_t *beam = &cfg->dbt_config.dig_beam_list[i];
+      beam->beam_idx = i;
+      beam->txru_list = malloc16(nb_tx * sizeof(*beam->txru_list));
+      for (int j = 0; j < nb_tx; j++) {
+        beam->txru_list[j].dig_beam_weight_Re = bw_list[j + i * nb_tx] & 0xffff;
+        beam->txru_list[j].dig_beam_weight_Im = (bw_list[j + i * nb_tx] >> 16) & 0xffff;
+        LOG_D(NR_MAC, "Beam %d Tx %d Weight (%d, %d)\n", i, j, beam->txru_list[j].dig_beam_weight_Re, beam->txru_list[j].dig_beam_weight_Im);
+      }
     }
   }
 }
diff --git a/radio/COMMON/common_lib.h b/radio/COMMON/common_lib.h
index 0ff54a79cec5e9bfc07404998b2ad692d7af806e..3822f7d1c5ecd0a685c018a65c2c7338ee230b60 100644
--- a/radio/COMMON/common_lib.h
+++ b/radio/COMMON/common_lib.h
@@ -174,6 +174,7 @@ typedef struct {
 } udp_ctx_t;
 
 typedef enum {
+  RU_GPIO_CONTROL_NONE,
   RU_GPIO_CONTROL_GENERIC,
   RU_GPIO_CONTROL_INTERDIGITAL,
 } gpio_control_t;