Index: /soft/giet_vm/giet_drivers/cma_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/cma_driver.c	(revision 447)
+++ /soft/giet_vm/giet_drivers/cma_driver.c	(revision 448)
@@ -34,5 +34,5 @@
 
 ////////////////////////////////////////////////////
-void _cma_start_channel( unsigned int       channel,
+void _cma_channel_start( unsigned int       channel,
                          unsigned long long src_paddr,
                          unsigned int       src_nbufs,
@@ -53,7 +53,7 @@
 
 //////////////////////////////////////////////
-void _cma_stop_channel( unsigned int channel )
+void _cma_channel_stop( unsigned int channel )
 {
-    _cma_set_register( channel, CHBUF_RUN      , 0 );
+    _cma_set_register( channel, CHBUF_RUN, 0 );
 }
 
@@ -63,6 +63,34 @@
                unsigned int channel )
 {
-    _puts("\n[GIET ERROR] _cma_isr() not implemented\n");
-    _exit();
+    // get CMA channel status
+    unsigned int status = _cma_get_register( channel, CHBUF_STATUS );
+
+    if (status == CHANNEL_SRC_DESC_ERROR )
+        _printf("\n[CMA WARNING] CMA channel %d blocked at cycle %d : "
+                "impossible access to source chbuf descriptor\n", 
+                channel, _get_proctime() );
+
+    else if (status == CHANNEL_SRC_DATA_ERROR )
+        _printf("\n[CMA WARNING] CMA channel %d blocked at cycle %d : "
+                "impossible access to source data buffer\n", 
+                channel, _get_proctime() );
+
+    else if (status == CHANNEL_DST_DESC_ERROR )
+        _printf("\n[CMA WARNING] CMA channel %d blocked at cycle %d : "
+                "impossible access to destination chbuf descriptor\n", 
+                channel, _get_proctime() );
+
+    else if (status == CHANNEL_DST_DATA_ERROR )
+        _printf("\n[CMA WARNING] CMA channel %d blocked at cycle %d : "
+                "impossible access to destination data buffer\n", 
+                channel, _get_proctime() );
+
+    else
+        _printf("\n[CMA WARNING] CMA channel %d : "
+                "... strange IRQ received, but channel not blocked...", 
+                channel, _get_proctime() );
+    
+    // acknowledge IRQ
+    _cma_set_register( channel, CHBUF_RUN, 0 );
 }
 
Index: /soft/giet_vm/giet_drivers/cma_driver.h
===================================================================
--- /soft/giet_vm/giet_drivers/cma_driver.h	(revision 447)
+++ /soft/giet_vm/giet_drivers/cma_driver.h	(revision 448)
@@ -27,8 +27,8 @@
 
 ///////////////////////////////////////////////////////////////////////////////////
-//  registers offsets
+//  CMA channel registers offsets
 ///////////////////////////////////////////////////////////////////////////////////
 
-enum CMA_registers 
+enum CMA_registers_e 
 {
     CHBUF_RUN           = 0,    // write-only : channel activated
@@ -47,18 +47,60 @@
 
 ///////////////////////////////////////////////////////////////////////////////////
+//  CMA channel status values
+///////////////////////////////////////////////////////////////////////////////////
+
+enum CMA_status_e
+{
+    CHANNEL_IDLE,
+
+    CHANNEL_SRC_DATA_ERROR,
+    CHANNEL_DST_DATA_ERROR,
+    CHANNEL_SRC_DESC_ERROR,
+    CHANNEL_DST_DESC_ERROR,
+
+    CHANNEL_READ_SRC_STATUS,
+    CHANNEL_READ_SRC_STATUS_WAIT,
+    CHANNEL_READ_SRC_STATUS_DELAY,
+    CHANNEL_READ_SRC_BUFADDR,
+    CHANNEL_READ_SRC_BUFADDR_WAIT,
+
+    CHANNEL_READ_DST_STATUS,
+    CHANNEL_READ_DST_STATUS_WAIT,
+    CHANNEL_READ_DST_STATUS_DELAY,
+    CHANNEL_READ_DST_BUFADDR,
+    CHANNEL_READ_DST_BUFADDR_WAIT,
+
+    CHANNEL_READ_BURST,
+    CHANNEL_READ_REQ_FIRST,
+    CHANNEL_READ_WAIT_FIRST,
+    CHANNEL_READ_REQ_SECOND,
+    CHANNEL_READ_WAIT_SECOND,
+
+    CHANNEL_WRITE_BURST,
+    CHANNEL_WRITE_REQ_FIRST,
+    CHANNEL_WRITE_WAIT_FIRST,
+    CHANNEL_WRITE_REQ_SECOND,
+    CHANNEL_WRITE_WAIT_SECOND,
+
+    CHANNEL_SRC_STATUS_WRITE,
+    CHANNEL_SRC_STATUS_WRITE_WAIT,
+    CHANNEL_DST_STATUS_WRITE,
+    CHANNEL_DST_STATUS_WRITE_WAIT,
+    CHANNEL_SRC_NEXT_BUFFER,
+    CHANNEL_DST_NEXT_BUFFER,
+};
+
+///////////////////////////////////////////////////////////////////////////////////
 //    access functions
 ///////////////////////////////////////////////////////////////////////////////////
 
-////////////////////////////////////////////////////////////
 extern unsigned int _cma_get_register( unsigned int channel,
                                        unsigned int index );
 
-///////////////////////////////////////////////////
 extern void _cma_set_register( unsigned int channel,
                                unsigned int index,
                                unsigned int value );
 
-///////////////////////////////////////////////////
-void _cma_start_channel( unsigned int       channel,
+void _cma_channel_start( unsigned int       channel,
                          unsigned long long src_paddr,
                          unsigned int       src_nbufs,
@@ -67,8 +109,6 @@
                          unsigned int       buf_length );
 
-//////////////////////////////////////////////
-void _cma_stop_channel( unsigned int channel );
+void _cma_channel_stop( unsigned int channel );
 
-////////////////////////////////////////////
 extern void _cma_isr( unsigned int irq_type,
                       unsigned int irq_id,
Index: /soft/giet_vm/giet_drivers/nic_driver.c
===================================================================
--- /soft/giet_vm/giet_drivers/nic_driver.c	(revision 447)
+++ /soft/giet_vm/giet_drivers/nic_driver.c	(revision 448)
@@ -49,6 +49,14 @@
 #endif
 
-#if !defined( GIET_CHBUF_NBUFS )
-# error: You must define GIET_CHBUF_NBUFS in the giet_config.h file
+#if !defined( GIET_NIC_CHBUF_NBUFS )
+# error: You must define GIET_NIC_CHBUF_NBUFS in the giet_config.h file
+#endif
+
+#if !defined( GIET_NIC_CHBUF_SIZE )
+# error: You must define GIET_NIC_CHBUF_SIZE in the giet_config.h file
+#endif
+
+#if !defined( GIET_NIC_CHBUF_TIMEOUT )
+# error: You must define GIET_NIC_CHBUF_TIMEOUT in the giet_config.h file
 #endif
 
@@ -115,264 +123,46 @@
 
 ////////////////////////////////////////////
-int _nic_channel_init( unsigned int index,
-                       unsigned int mac4,
-                       unsigned int mac2 )
+int _nic_channel_start( unsigned int channel,
+                        unsigned int is_rx,
+                        unsigned int mac4,
+                        unsigned int mac2 )
 {
     unsigned int base     = SEG_NIC_BASE;
     unsigned int extend   = (X_IO << Y_WIDTH) + Y_IO;
 
-    _nic_set_channel_register( index, NIC_RX_DESC_LO_0 + 4096, base );
-    _nic_set_channel_register( index, NIC_RX_DESC_LO_1 + 4096, base + 0x1000 );
-    _nic_set_channel_register( index, NIC_TX_DESC_LO_0 + 4096, base + 0x2000 );
-    _nic_set_channel_register( index, NIC_TX_DESC_LO_1 + 4096, base + 0x3000 );
+    if ( is_rx )
+    {
+        _nic_set_channel_register( channel, NIC_RX_DESC_LO_0 + 4096, base );
+        _nic_set_channel_register( channel, NIC_RX_DESC_LO_1 + 4096, base + 0x1000 );
+        _nic_set_channel_register( channel, NIC_RX_DESC_HI_0       , extend );
+        _nic_set_channel_register( channel, NIC_RX_DESC_HI_1       , extend );
+        _nic_set_channel_register( channel, NIC_RX_RUN             , 1 );
+    }
+    else
+    {
+        _nic_set_channel_register( channel, NIC_TX_DESC_LO_0 + 4096, base + 0x2000 );
+        _nic_set_channel_register( channel, NIC_TX_DESC_LO_1 + 4096, base + 0x3000 );
+        _nic_set_channel_register( channel, NIC_TX_DESC_HI_0       , extend );
+        _nic_set_channel_register( channel, NIC_TX_DESC_HI_1       , extend );
+        _nic_set_channel_register( channel, NIC_TX_RUN             , 1 );
+    }
 
-    _nic_set_channel_register( index, NIC_RX_DESC_HI_0       , extend );
-    _nic_set_channel_register( index, NIC_RX_DESC_HI_1       , extend );
-    _nic_set_channel_register( index, NIC_TX_DESC_HI_0       , extend );
-    _nic_set_channel_register( index, NIC_TX_DESC_HI_1       , extend );
-
-    _nic_set_channel_register( index, NIC_MAC_4              , mac4 );
-    _nic_set_channel_register( index, NIC_MAC_2              , mac2 );
+    _nic_set_channel_register( channel, NIC_MAC_4              , mac4 );
+    _nic_set_channel_register( channel, NIC_MAC_2              , mac2 );
     
-    _nic_set_channel_register( index, NIC_RX_RUN             , 1 );
-    _nic_set_channel_register( index, NIC_TX_RUN             , 1 );
-
     return 0;
 }
 
-/////////////////////////////////////////////////////////////////////////////////////
-//             Synchronous access functions
-/////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////
+int _nic_channel_stop( unsigned int channel,
+                       unsigned int is_rx )
+{
+    if ( is_rx )  _nic_set_channel_register( channel, NIC_RX_RUN, 0 );
+    else          _nic_set_channel_register( channel, NIC_TX_RUN, 0 );
 
-///////////////////////////////////////////////
-int _nic_sync_send( unsigned int        channel,
-                    unsigned long long  user_paddr )
-{
-    unsigned long long nic_paddr;   // nic buffer physical address
-    unsigned int       done = 0;
-    unsigned int       lsb;
-    unsigned int       msb;
-
-    if ( channel >= NB_NIC_CHANNELS )
-    {
-        _puts("[GIET ERROR] in _timer_sync_send()\n");
-        return -1;
-    }
-
-    // poll the NIC buffers
-    while ( done == 0 )
-    {
-        // test availability of NIC TX buffer 0
-        lsb  = _nic_get_channel_register( channel, NIC_TX_DESC_LO_0 );
-        msb  = _nic_get_channel_register( channel, NIC_TX_DESC_HI_0 );
-        if ( (msb & 0x80000000) == 0 )
-        {
-            msb  = msb & 0x0000FFFF;
-            done = 1;
-            continue;
-        }
-
-        // test availability of NIC TX buffer 1
-        lsb  = _nic_get_channel_register( channel, NIC_TX_DESC_LO_1 );
-        msb  = _nic_get_channel_register( channel, NIC_TX_DESC_HI_1 );
-        if ( (msb & 0x80000000) == 0 )
-        {
-            msb  = msb & 0x0000FFFF;
-            done = 1;
-            continue;
-        }
-
-        // random delay (average value: 380 cycle)
-        _random_wait( 8 );
-    }
-
-    // make the transfer
-    nic_paddr = (unsigned long long)lsb + (((unsigned long long)msb) << 32);
-
-    _physical_memcpy( nic_paddr , user_paddr, 4096 );
-
-    return 0;
+    return 0;   
 }
 
-///////////////////////////////////////////////////
-int _nic_sync_receive( unsigned int        channel,
-                       unsigned long long  user_paddr )
-{
-    unsigned long long nic_paddr;   // nic  buffer physical address
-    unsigned int       done = 0;
-    unsigned int       lsb;
-    unsigned int       msb;
 
-    if ( channel >= NB_NIC_CHANNELS )
-    {
-        _puts("[GIET ERROR] in _timer_sync_receive()\n");
-        return -1;
-    }
-
-    // polling the NIC buffers
-    while ( done == 0 )
-    {
-        // test availability of NIC RX buffer 0
-        lsb  = _nic_get_channel_register( channel, NIC_RX_DESC_LO_0 );
-        msb  = _nic_get_channel_register( channel, NIC_RX_DESC_HI_0 );
-        if ( (msb & 0x80000000) == 1 )
-        {
-            msb  = msb & 0x0000FFFF;
-            done = 1;
-            continue;
-        }
-
-        // test availability of NIC RX buffer 1
-        lsb  = _nic_get_channel_register( channel, NIC_RX_DESC_LO_1 );
-        msb  = _nic_get_channel_register( channel, NIC_RX_DESC_HI_1 );
-        if ( (msb & 0x80000000) == 1 )
-        {
-            msb  = msb & 0x0000FFFF;
-            done = 1;
-            continue;
-        }
-
-        // random delay (average value: 380 cycle)
-        _random_wait( 8 );
-    }
-
-    // make the transfer
-    nic_paddr = (unsigned long long)lsb + (((unsigned long long)msb) << 32);
-
-    _physical_memcpy( user_paddr, nic_paddr , 4096 );
-
-    return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////
-//             CMA access functions
-/////////////////////////////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////
-int _nic_cma_receive( unsigned int  nic_channel,
-                      unsigned int  cma_channel,
-                      nic_chbuf_t*  kernel_chbuf )
-                             
-{
-    unsigned int nic_chbuf_lsb;     // 32 LSB bits of the NIC chbuf physical address
-    unsigned int nic_chbuf_msb;     // 16 MSB bits of the NIC chbuf physical address
-    unsigned int mem_chbuf_lsb;     // 32 LSB bits of the kernel chbuf physical address
-    unsigned int mem_chbuf_msb;     // 16 MSB bits of the kernel chbuf physical address
-
-    unsigned int ppn;
-    unsigned int flags;
-
-    // checking parameters
-    if ( nic_channel >= NB_NIC_CHANNELS )
-    {
-        _puts("[GIET ERROR] in _nic_cma_start_receive() : nic_channel index too large\n");
-        return -1;
-    }
-    if ( cma_channel >= NB_CMA_CHANNELS )
-    {
-        _puts("[GIET ERROR] in _nic_cma_start_receive() : cma_channel index too large\n");
-        return -1;
-    }
-
-    // get the NIC_RX chbuf descriptor physical address
-    nic_chbuf_lsb = SEG_NIC_BASE + (nic_channel * NIC_CHANNEL_SPAN) + 0x1000;
-    nic_chbuf_msb = (X_IO << Y_WIDTH) + Y_IO;
-
-    // compute the kernel chbuf physical address
-    unsigned int ptab  = _get_context_slot(CTX_PTAB_ID);
-    unsigned int vaddr = (unsigned int)kernel_chbuf;
-    unsigned int ko    = _v2p_translate( (page_table_t*)ptab,
-                                          vaddr,
-                                          &ppn,
-                                          &flags );
-    if ( ko )
-    {
-        _puts("\n[GIET ERROR] in _nic_cma_start_receive() : kernel buffer unmapped\n");
-        return -1;
-    }
-
-    mem_chbuf_lsb = (ppn << 12) | (vaddr & 0x00000FFF);
-    mem_chbuf_msb = ppn >> 20;
-
-    // initializes CMA registers defining the source chbuf (NIC_RX)
-    _cma_set_register( cma_channel, CHBUF_SRC_DESC , nic_chbuf_lsb );
-    _cma_set_register( cma_channel, CHBUF_DST_EXT  , nic_chbuf_msb );
-    _cma_set_register( cma_channel, CHBUF_SRC_NBUFS, 2 );
-
-    // initializes CMA registers defining the destination chbuf (kernel memory)
-    _cma_set_register( cma_channel, CHBUF_DST_DESC , mem_chbuf_lsb );
-    _cma_set_register( cma_channel, CHBUF_DST_EXT  , mem_chbuf_msb );
-    _cma_set_register( cma_channel, CHBUF_DST_NBUFS, GIET_CHBUF_NBUFS );
-
-    // set buffer size, polling period, and start
-    _cma_set_register( cma_channel, CHBUF_BUF_SIZE , 4096 );
-    _cma_set_register( cma_channel, CHBUF_PERIOD   , 300 );
-    _cma_set_register( cma_channel, CHBUF_RUN      , 1 );
-
-    return 0;
-}
-
-//////////////////////////////////////////////////////////
-int _nic_cma_send( unsigned int  nic_channel,
-                   unsigned int  cma_channel,
-                   nic_chbuf_t*  kernel_chbuf )
-{
-    unsigned int nic_chbuf_lsb;     // 32 LSB bits of the NIC chbuf physical address
-    unsigned int nic_chbuf_msb;     // 16 MSB bits of the NIC chbuf physical address
-    unsigned int mem_chbuf_lsb;     // 32 LSB bits of the kernel chbuf physical address
-    unsigned int mem_chbuf_msb;     // 16 MSB bits of the kernel chbuf physical address
-
-    unsigned int ppn;
-    unsigned int flags;
-
-    // checking parameters
-    if ( nic_channel >= NB_NIC_CHANNELS )
-    {
-        _puts("[GIET ERROR] in _nic_cma_start_send() : nic_channel index too large\n");
-        return -1;
-    }
-    if ( cma_channel >= NB_CMA_CHANNELS )
-    {
-        _puts("[GIET ERROR] in _nic_cma_start_send() : cma_channel index too large\n");
-        return -1;
-    }
-
-    // get the NIC_TX chbuf descriptor physical address
-    nic_chbuf_lsb = SEG_NIC_BASE + (nic_channel * NIC_CHANNEL_SPAN) + 0x1010;
-    nic_chbuf_msb = (X_IO << Y_WIDTH) + Y_IO;
-
-    // compute the kernel chbuf physical address
-    unsigned int ptab  = _get_context_slot(CTX_PTAB_ID);
-    unsigned int vaddr = (unsigned int)kernel_chbuf;
-    unsigned int ko    = _v2p_translate( (page_table_t*)ptab,
-                                          vaddr,
-                                          &ppn,
-                                          &flags );
-    if ( ko )
-    {
-        _puts("\n[GIET ERROR] in _nic_cma_start_send() : kernel buffer unmapped\n");
-        return -1;
-    }
-
-    mem_chbuf_lsb = (ppn << 12) | (vaddr & 0x00000FFF);
-    mem_chbuf_msb = ppn >> 20;
-
-    // initializes CMA registers defining the source chbuf (kernel memory)
-    _cma_set_register( cma_channel, CHBUF_SRC_DESC , mem_chbuf_lsb );
-    _cma_set_register( cma_channel, CHBUF_DST_EXT  , mem_chbuf_msb );
-    _cma_set_register( cma_channel, CHBUF_SRC_NBUFS, GIET_CHBUF_NBUFS );
-
-    // initializes CMA registers defining the destination chbuf (NIC_TX)
-    _cma_set_register( cma_channel, CHBUF_DST_DESC , nic_chbuf_lsb );
-    _cma_set_register( cma_channel, CHBUF_DST_EXT  , nic_chbuf_msb );
-    _cma_set_register( cma_channel, CHBUF_DST_NBUFS, 2 );
-
-    // set buffer size, polling period, and start
-    _cma_set_register( cma_channel, CHBUF_BUF_SIZE , 4096 );
-    _cma_set_register( cma_channel, CHBUF_PERIOD   , 300 );
-    _cma_set_register( cma_channel, CHBUF_RUN      , 1 );
-
-    return 0;
-}
 
 ////////////////////////////////////////////////////////////////////////////////////////////
Index: /soft/giet_vm/giet_drivers/nic_driver.h
===================================================================
--- /soft/giet_vm/giet_drivers/nic_driver.h	(revision 447)
+++ /soft/giet_vm/giet_drivers/nic_driver.h	(revision 448)
@@ -99,14 +99,4 @@
 
 
-////////////////////////////////////////////////////////////////////////////////////
-//              Chained Buffer Descriptor Structure
-////////////////////////////////////////////////////////////////////////////////////
-typedef struct nic_chbuf_s
-{
-    unsigned long long buf[GIET_CHBUF_NBUFS]; // array of buffer descriptors 
-    unsigned int       buf_length;            // buffer length (bytes)
-    unsigned int       nb_buffers;            // actual number of buffers
-} nic_chbuf_t;
-
 ///////////////////////////////////////////////////////////////////////////////////
 //              Initialization functions
@@ -118,29 +108,12 @@
                              unsigned int bypass_enable );
 
-extern int _nic_channel_init( unsigned int index,
-                              unsigned int mac4,
-                              unsigned int mac2 );
+extern int _nic_channel_start( unsigned int channel,
+                               unsigned int is_rx,
+                               unsigned int mac4,
+                               unsigned int mac2 );
 
-///////////////////////////////////////////////////////////////////////////////////
-//              Blocking functions using a physical_memcpy()
-///////////////////////////////////////////////////////////////////////////////////
+extern int _nic_channel_stop( unsigned int channel,
+                              unsigned int is_rx );
 
-extern int _nic_sync_receive( unsigned int       channel, 
-                              unsigned long long user_paddr );
-
-extern int _nic_sync_send( unsigned int       channel,
-                           unsigned long long user_paddr );
-
-///////////////////////////////////////////////////////////////////////////////////
-//              Non blocking functions using the chained buffer DMA
-///////////////////////////////////////////////////////////////////////////////////
-
-extern int _nic_cma_receive( unsigned int  nic_channel,
-                             unsigned int  cma_channel,
-                             nic_chbuf_t*  kernel_chbuf );
-
-extern int _nic_cma_send( unsigned int  nic_channel,
-                          unsigned int  cma_channel,
-                          nic_chbuf_t*  kernel_chbuf );
 
 ///////////////////////////////////////////////////////////////////////////////////
