Commit 625fcb9e authored by Daniel Verkamp's avatar Daniel Verkamp
Browse files

ioat: add a union of all descriptor types



The ioat library currently only supports DMA copy operations, but the
hardware can do other types of transfers.  Add a union of the hardware
descriptor structures to enable support for the other operations in the
future.

Also add a generic hardware descriptor type to allow access to the parts
of the descriptor that are common between all types.

Change-Id: I3b54421ce771f58b78910e790b53026f311f918e
Signed-off-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
parent 777a0615
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
@@ -94,6 +94,31 @@ struct ioat_registers {

#define IOAT_CHANCMP_ALIGN		8	/* CHANCMP address must be 64-bit aligned */

struct ioat_generic_hw_descriptor {
	uint32_t size;
	union {
		uint32_t control_raw;
		struct {
			uint32_t int_enable: 1;
			uint32_t src_snoop_disable: 1;
			uint32_t dest_snoop_disable: 1;
			uint32_t completion_update: 1;
			uint32_t fence: 1;
			uint32_t reserved2: 1;
			uint32_t src_page_break: 1;
			uint32_t dest_page_break: 1;
			uint32_t bundle: 1;
			uint32_t dest_dca: 1;
			uint32_t hint: 1;
			uint32_t reserved: 13;
			uint32_t op: 8;
		} control;
	} u;
	uint64_t src_addr;
	uint64_t dest_addr;
	uint64_t next;
	uint64_t op_specific[4];
};

struct ioat_dma_hw_descriptor {
	uint32_t size;
@@ -265,4 +290,17 @@ struct ioat_raw_hw_descriptor {
	uint64_t field[8];
};

union ioat_hw_descriptor {
	struct ioat_raw_hw_descriptor raw;
	struct ioat_generic_hw_descriptor generic;
	struct ioat_dma_hw_descriptor dma;
	struct ioat_fill_hw_descriptor fill;
	struct ioat_xor_hw_descriptor xor;
	struct ioat_xor_ext_hw_descriptor xor_ext;
	struct ioat_pq_hw_descriptor pq;
	struct ioat_pq_ext_hw_descriptor pq_ext;
	struct ioat_pq_update_hw_descriptor pq_update;
};
_Static_assert(sizeof(union ioat_hw_descriptor) == 64, "incorrect ioat_hw_descriptor layout");

#endif /* __IOAT_SPEC_H__ */
+19 −19
Original line number Diff line number Diff line
@@ -208,7 +208,7 @@ ioat_get_ring_index(struct ioat_channel *ioat, uint32_t index)
static void
ioat_get_ring_entry(struct ioat_channel *ioat, uint32_t index,
		    struct ioat_descriptor **desc,
		    struct ioat_dma_hw_descriptor **hw_desc)
		    union ioat_hw_descriptor **hw_desc)
{
	uint32_t i = ioat_get_ring_index(ioat, index);

@@ -220,7 +220,7 @@ static uint64_t
ioat_get_desc_phys_addr(struct ioat_channel *ioat, uint32_t index)
{
	return ioat->hw_ring_phys_addr +
	       ioat_get_ring_index(ioat, index) * sizeof(struct ioat_dma_hw_descriptor);
	       ioat_get_ring_index(ioat, index) * sizeof(union ioat_hw_descriptor);
}

static void
@@ -239,7 +239,7 @@ static struct ioat_descriptor *
ioat_prep_null(struct ioat_channel *ioat)
{
	struct ioat_descriptor *desc;
	struct ioat_dma_hw_descriptor *hw_desc;
	union ioat_hw_descriptor *hw_desc;

	if (ioat_get_ring_space(ioat) < 1) {
		return NULL;
@@ -247,14 +247,14 @@ ioat_prep_null(struct ioat_channel *ioat)

	ioat_get_ring_entry(ioat, ioat->head, &desc, &hw_desc);

	hw_desc->u.control_raw = 0;
	hw_desc->u.control.op = IOAT_OP_COPY;
	hw_desc->u.control.null = 1;
	hw_desc->u.control.completion_update = 1;
	hw_desc->dma.u.control_raw = 0;
	hw_desc->dma.u.control.op = IOAT_OP_COPY;
	hw_desc->dma.u.control.null = 1;
	hw_desc->dma.u.control.completion_update = 1;

	hw_desc->size = 8;
	hw_desc->src_addr = 0;
	hw_desc->dest_addr = 0;
	hw_desc->dma.size = 8;
	hw_desc->dma.src_addr = 0;
	hw_desc->dma.dest_addr = 0;

	desc->callback_fn = NULL;
	desc->callback_arg = NULL;
@@ -269,7 +269,7 @@ ioat_prep_copy(struct ioat_channel *ioat, uint64_t dst,
	       uint64_t src, uint32_t len)
{
	struct ioat_descriptor *desc;
	struct ioat_dma_hw_descriptor *hw_desc;
	union ioat_hw_descriptor *hw_desc;

	ioat_assert(len <= ioat->max_xfer_size);

@@ -279,13 +279,13 @@ ioat_prep_copy(struct ioat_channel *ioat, uint64_t dst,

	ioat_get_ring_entry(ioat, ioat->head, &desc, &hw_desc);

	hw_desc->u.control_raw = 0;
	hw_desc->u.control.op = IOAT_OP_COPY;
	hw_desc->u.control.completion_update = 1;
	hw_desc->dma.u.control_raw = 0;
	hw_desc->dma.u.control.op = IOAT_OP_COPY;
	hw_desc->dma.u.control.completion_update = 1;

	hw_desc->size = len;
	hw_desc->src_addr = src;
	hw_desc->dest_addr = dst;
	hw_desc->dma.size = len;
	hw_desc->dma.src_addr = src;
	hw_desc->dma.dest_addr = dst;

	desc->callback_fn = NULL;
	desc->callback_arg = NULL;
@@ -449,14 +449,14 @@ ioat_channel_start(struct ioat_channel *ioat)
		return -1;
	}

	ioat->hw_ring = ioat_zmalloc(NULL, num_descriptors * sizeof(struct ioat_dma_hw_descriptor), 64,
	ioat->hw_ring = ioat_zmalloc(NULL, num_descriptors * sizeof(union ioat_hw_descriptor), 64,
				     &ioat->hw_ring_phys_addr);
	if (!ioat->hw_ring) {
		return -1;
	}

	for (i = 0; i < num_descriptors; i++) {
		ioat->hw_ring[i].next = ioat_get_desc_phys_addr(ioat, i + 1);
		ioat->hw_ring[i].generic.next = ioat_get_desc_phys_addr(ioat, i + 1);
	}

	ioat->head = 0;
+1 −1
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ struct ioat_channel {
	uint64_t            last_seen;

	struct ioat_descriptor		*ring;
	struct ioat_dma_hw_descriptor	*hw_ring;
	union ioat_hw_descriptor	*hw_ring;
	uint64_t			hw_ring_phys_addr;
};