1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
#ifndef _PCILIB_DMA_IPE_PRIVATE_H
#define _PCILIB_DMA_IPE_PRIVATE_H
#include "dma.h"
//#define IPEDMA_ENFORCE_64BIT_MODE 1 /**< enforce 64-bit mode addressing (otherwise it is used only if register 0x18 specifies PCIe gen3 as required by DMA engine) */
#define IPEDMA_CORES 1
#define IPEDMA_MAX_TLP_SIZE 256 /**< Defines maximum TLP in bytes supported by device */
//#define IPEDMA_TLP_SIZE 128 /**< If set, enforces the specified TLP size */
#define IPEDMA_STREAMING_MODE /**< Enables streaming DMA operation mode instead of ring-buffer, the page is written once and forgotten and need to be pushed in queue again */
//#define IPEDMA_STREAMING_CHECKS /**< Enables status checks in streaming mode (it will cause _significant_ performance penalty, max ~ 2 GB/s) */
#define IPEDMA_DMA_PROGRESS_THRESHOLD 1 /**< how many pages the DMA engine should fill before reporting progress */
#define IPEDMA_DESCRIPTOR_SIZE 128
#define IPEDMA_DESCRIPTOR_ALIGNMENT 64
//#define IPEDMA_BUG_LAST_READ /**< We should forbid writting the second last available DMA buffer (the last is forbidden by design) */
//#define IPEDMA_DETECT_PACKETS /**< Using empty_deceted flag */
#define IPEDMA_SUPPORT_EMPTY_DETECTED /**< Avoid waiting for data when empty_detected flag is set in hardware */
#define IPEDMA_REG_RESET 0x00
#define IPEDMA_REG_CONTROL 0x04
#define IPEDMA_REG_TLP_SIZE 0x0C
#define IPEDMA_REG_TLP_COUNT 0x10
#define IPEDMA_REG_PCIE_GEN 0x18
#define IPEDMA_REG_VERSION 0x20
#define IPEDMA_REG_PAGE_ADDR 0x50
#define IPEDMA_REG_UPDATE_ADDR 0x54
#define IPEDMA_REG_LAST_READ 0x58 /**< In streaming mode, we can use it freely to track current status */
#define IPEDMA_REG_PAGE_COUNT 0x5C
#define IPEDMA_REG_UPDATE_THRESHOLD 0x60
#define IPEDMA_REG_STREAMING_STATUS 0x68
#define IPEDMA_FLAG_NOSYNC 0x01 /**< Do not call kernel space for page synchronization */
#define IPEDMA_FLAG_NOSLEEP 0x02 /**< Do not sleep in the loop while waiting for the data */
#define IPEDMA_MASK_PCIE_GEN 0xF
#define IPEDMA_MASK_STREAMING_MODE 0x10
#define IPEDMA_RESET_DELAY 10000 /**< Sleep between accessing DMA control and reset registers */
#define IPEDMA_ADD_PAGE_DELAY 1000 /**< Delay between submitting successive DMA pages into IPEDMA_REG_PAGE_ADDR register */
#define IPEDMA_NODATA_SLEEP 100 /**< To keep CPU free, in nanoseconds */
#define WR(addr, value) { *(uint32_t*)(ctx->base_addr + addr) = value; }
#define RD(addr, value) { value = *(uint32_t*)(ctx->base_addr + addr); }
typedef struct ipe_dma_s ipe_dma_t;
struct ipe_dma_s {
pcilib_dma_context_t dmactx;
//pcilib_dma_engine_description_t engine[2];
const pcilib_register_bank_description_t *dma_bank;
char *base_addr;
pcilib_irq_type_t irq_enabled; /**< indicates that IRQs are enabled */
pcilib_irq_type_t irq_preserve; /**< indicates that IRQs should not be disabled during clean-up */
int irq_started; /**< indicates that IRQ subsystem is initialized (detecting which types should be preserverd) */
uint32_t version; /**< hardware version */
int started; /**< indicates that DMA buffers are initialized and reading is allowed */
int writting; /**< indicates that we are in middle of writting packet */
int reused; /**< indicates that DMA was found intialized, buffers were reused, and no additional initialization is needed */
int preserve; /**< indicates that DMA should not be stopped during clean-up */
int mode64; /**< indicates 64-bit operation mode */
int streaming; /**< indicates if DMA is operating in streaming or ring-buffer mode */
uint32_t dma_flags; /**< Various operation flags, see IPEDMA_FLAG_* */
size_t dma_timeout; /**< DMA timeout,IPEDMA_DMA_TIMEOUT is used by default */
size_t dma_pages; /**< Number of DMA pages in ring buffer to allocate */
size_t dma_page_size; /**< Size of a single DMA page */
pcilib_kmem_handle_t *desc; /**< in-memory status descriptor written by DMA engine upon operation progess */
pcilib_kmem_handle_t *pages; /**< collection of memory-locked pages for DMA operation */
size_t ring_size, page_size;
size_t last_read, last_read_addr, last_written;
};
#endif /* _PCILIB_DMA_IPE_PRIVATE_H */
|