Browse Source

Correctly detect the tail pointer of C2S ring

Suren A. Chilingaryan 13 năm trước cách đây
mục cha
commit
21d12d6157
4 tập tin đã thay đổi với 19 bổ sung34 xóa
  1. 1 1
      dma/nwl.h
  2. 1 1
      dma/nwl_engine.c
  3. 11 28
      dma/nwl_engine_buffers.h
  4. 6 4
      dma/nwl_loopback.c

+ 1 - 1
dma/nwl.h

@@ -16,7 +16,7 @@ typedef struct pcilib_nwl_engine_description_s pcilib_nwl_engine_description_t;
 #define PCILIB_NWL_DMA_PAGES			512 // 1024
 
 //#define DEBUG_HARDWARE
-
+//#define DEBUG_NWL
 
 #include "nwl_dma.h"
 #include "nwl_irq.h"

+ 1 - 1
dma/nwl_engine.c

@@ -14,7 +14,7 @@
 
 #include "nwl_defines.h"
 
-#include "nwl_buffers.h"    
+#include "nwl_engine_buffers.h"
 
 int dma_nwl_read_engine_config(nwl_dma_t *ctx, pcilib_nwl_engine_description_t *info, char *base) {
     uint32_t val;

+ 11 - 28
dma/nwl_buffers.h → dma/nwl_engine_buffers.h

@@ -44,7 +44,11 @@ static int dma_nwl_compute_read_s2c_pointers(nwl_dma_t *ctx, pcilib_nwl_engine_d
 	pcilib_warning("Inconsistent S2C DMA Ring buffer is found (REG_DMA_ENG_NEXT_BD register value (%zu) out of range)", info->tail);
 	return PCILIB_ERROR_INVALID_STATE;
     }
-    
+
+#ifdef DEBUG_NWL    
+    printf("S2C: %lu %lu\n", info->tail, info->head);
+#endif /* DEBUG_NWL */
+
     return 0;
 }
 
@@ -69,34 +73,12 @@ static int dma_nwl_compute_read_c2s_pointers(nwl_dma_t *ctx, pcilib_nwl_engine_d
 	return PCILIB_ERROR_INVALID_STATE;
     }
     
-    info->tail = info->head;
-    
-    
-	// Last read BD
-    nwl_read_register(val, ctx, base, REG_DMA_ENG_LAST_BD);
-    if ((val < ring_pa)||((val - ring_pa) % PCILIB_NWL_DMA_DESCRIPTOR_SIZE)) {
-	if (val < ring_pa) pcilib_warning("Inconsistent C2S DMA Ring buffer is found (REG_DMA_ENG_LAST_BD register value (%lx) is below start of ring [%lx,%lx])", val, ring_pa, PCILIB_NWL_DMA_DESCRIPTOR_SIZE);
-	else pcilib_warning("Inconsistent C2S DMA Ring buffer is found (REG_DMA_ENG_LAST_BD register value (%zu / %u) is fractal)", val - ring_pa, PCILIB_NWL_DMA_DESCRIPTOR_SIZE);
-	return PCILIB_ERROR_INVALID_STATE;
-    }
-
-    prev = (val - ring_pa) / PCILIB_NWL_DMA_DESCRIPTOR_SIZE;
-    if (prev >= PCILIB_NWL_DMA_PAGES) {
-	pcilib_warning("Inconsistent C2S DMA Ring buffer is found (REG_DMA_ENG_LAST_BD register value (%zu) out of range)", prev);
-	return PCILIB_ERROR_INVALID_STATE;
-    }
-    
-prev_buffer:
-    val = NWL_RING_GET(ring + prev * PCILIB_NWL_DMA_DESCRIPTOR_SIZE, DMA_BD_BUFL_STATUS_OFFSET)&DMA_BD_STATUS_MASK;
+    info->tail = info->head + 1;
+    if (info->tail == PCILIB_NWL_DMA_PAGES) info->tail = 0;
 
-    if (val & (DMA_BD_ERROR_MASK|DMA_BD_COMP_MASK)) {
-	info->tail = prev;
-
-        if (prev > 0) prev -= 1;
-	else prev = PCILIB_NWL_DMA_PAGES - 1;
-	
-	if (prev != info->head)	goto prev_buffer;
-    }
+#ifdef DEBUG_NWL    
+    printf("C2S: %lu %lu\n", info->tail, info->head);
+#endif /* DEBUG_NWL */
 
     return 0;
 }
@@ -137,6 +119,7 @@ static int dma_nwl_allocate_engine_buffers(nwl_dma_t *ctx, pcilib_nwl_engine_des
     reuse_ring = pcilib_kmem_is_reused(ctx->pcilib, ring);
     reuse_pages = pcilib_kmem_is_reused(ctx->pcilib, pages);
 
+
     if (!info->preserve) {
 	if (reuse_ring == reuse_pages) {
 	    if (reuse_ring & PCILIB_KMEM_REUSE_PARTIAL) pcilib_warning("Inconsistent DMA buffers are found (only part of required buffers is available), reinitializing...");

+ 6 - 4
dma/nwl_loopback.c

@@ -16,7 +16,8 @@
 int dma_nwl_start_loopback(nwl_dma_t *ctx,  pcilib_dma_direction_t direction, size_t packet_size) {
     uint32_t val;
 
-	// Re-initializing always
+    ctx->loopback_started = 1;
+    dma_nwl_stop_loopback(ctx);
     
     val = packet_size;
     nwl_write_register(val, ctx, ctx->base_addr, PKT_SIZE_ADDRESS);
@@ -24,17 +25,16 @@ int dma_nwl_start_loopback(nwl_dma_t *ctx,  pcilib_dma_direction_t direction, si
     switch (direction) {
       case PCILIB_DMA_BIDIRECTIONAL:
 	val = LOOPBACK;
+	nwl_write_register(val, ctx, ctx->base_addr, TX_CONFIG_ADDRESS);
 	break;
       case PCILIB_DMA_TO_DEVICE:
 	return -1;
       case PCILIB_DMA_FROM_DEVICE:
         val = PKTGENR;
+	nwl_write_register(val, ctx, ctx->base_addr, RX_CONFIG_ADDRESS);
 	break;
     }
 
-    nwl_write_register(val, ctx, ctx->base_addr, TX_CONFIG_ADDRESS);
-    nwl_write_register(val, ctx, ctx->base_addr, RX_CONFIG_ADDRESS);
-
     ctx->loopback_started = 1;
         
     return 0;
@@ -42,6 +42,8 @@ int dma_nwl_start_loopback(nwl_dma_t *ctx,  pcilib_dma_direction_t direction, si
 
 int dma_nwl_stop_loopback(nwl_dma_t *ctx) {
     uint32_t val = 0;
+    
+    if (!ctx->loopback_started) return 0;
 
 	/* Stop in any case, otherwise we can have problems in benchmark due to
 	engine initialized in previous run, and benchmark is only actual usage.