diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath10k/ce.h')
-rw-r--r-- | drivers/net/wireless/ath/ath10k/ce.h | 126 |
1 files changed, 105 insertions, 21 deletions
diff --git a/drivers/net/wireless/ath/ath10k/ce.h b/drivers/net/wireless/ath/ath10k/ce.h index 15d45b5..c17f07c 100644 --- a/drivers/net/wireless/ath/ath10k/ce.h +++ b/drivers/net/wireless/ath/ath10k/ce.h @@ -27,6 +27,7 @@ /* Descriptor rings must be aligned to this boundary */ #define CE_DESC_RING_ALIGN 8 +#define CE_SENDLIST_ITEMS_MAX 12 #define CE_SEND_FLAG_GATHER 0x00010000 /* @@ -35,9 +36,16 @@ * how to use copy engines. */ -struct ath10k_ce_pipe; +struct ce_state; +/* Copy Engine operational state */ +enum ce_op_state { + CE_UNUSED, + CE_PAUSED, + CE_RUNNING, +}; + #define CE_DESC_FLAGS_GATHER (1 << 0) #define CE_DESC_FLAGS_BYTE_SWAP (1 << 1) #define CE_DESC_FLAGS_META_DATA_MASK 0xFFFC @@ -49,7 +57,8 @@ struct ce_desc { __le16 flags; /* %CE_DESC_FLAGS_ */ }; -struct ath10k_ce_ring { +/* Copy Engine Ring internal state */ +struct ce_ring_state { /* Number of entries in this ring; must be power of 2 */ unsigned int nentries; unsigned int nentries_mask; @@ -107,20 +116,49 @@ struct ath10k_ce_ring { void **per_transfer_context; }; -struct ath10k_ce_pipe { +/* Copy Engine internal state */ +struct ce_state { struct ath10k *ar; unsigned int id; unsigned int attr_flags; u32 ctrl_addr; - - void (*send_cb)(struct ath10k_ce_pipe *); - void (*recv_cb)(struct ath10k_ce_pipe *); + enum ce_op_state state; + + void (*send_cb) (struct ce_state *ce_state, + void *per_transfer_send_context, + u32 buffer, + unsigned int nbytes, + unsigned int transfer_id); + void (*recv_cb) (struct ce_state *ce_state, + void *per_transfer_recv_context, + u32 buffer, + unsigned int nbytes, + unsigned int transfer_id, + unsigned int flags); unsigned int src_sz_max; - struct ath10k_ce_ring *src_ring; - struct ath10k_ce_ring *dest_ring; + struct ce_ring_state *src_ring; + struct ce_ring_state *dest_ring; +}; + +struct ce_sendlist_item { + /* e.g. buffer or desc list */ + dma_addr_t data; + union { + /* simple buffer */ + unsigned int nbytes; + /* Rx descriptor list */ + unsigned int ndesc; + } u; + /* externally-specified flags; OR-ed with internal flags */ + u32 flags; +}; + +struct ce_sendlist { + unsigned int num_items; + struct ce_sendlist_item item[CE_SENDLIST_ITEMS_MAX]; }; /* Copy Engine settable attributes */ @@ -144,7 +182,7 @@ struct ce_attr; * * Implementation note: pushes 1 buffer to Source ring */ -int ath10k_ce_send(struct ath10k_ce_pipe *ce_state, +int ath10k_ce_send(struct ce_state *ce_state, void *per_transfer_send_context, u32 buffer, unsigned int nbytes, @@ -152,11 +190,36 @@ int ath10k_ce_send(struct ath10k_ce_pipe *ce_state, unsigned int transfer_id, unsigned int flags); -void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state, - void (*send_cb)(struct ath10k_ce_pipe *), +void ath10k_ce_send_cb_register(struct ce_state *ce_state, + void (*send_cb) (struct ce_state *ce_state, + void *transfer_context, + u32 buffer, + unsigned int nbytes, + unsigned int transfer_id), int disable_interrupts); -int ath10k_ce_num_free_src_entries(struct ath10k_ce_pipe *pipe); +/* Append a simple buffer (address/length) to a sendlist. */ +void ath10k_ce_sendlist_buf_add(struct ce_sendlist *sendlist, + u32 buffer, + unsigned int nbytes, + /* OR-ed with internal flags */ + u32 flags); + +/* + * Queue a "sendlist" of buffers to be sent using gather to a single + * anonymous destination buffer + * ce - which copy engine to use + * sendlist - list of simple buffers to send using gather + * transfer_id - arbitrary ID; reflected to destination + * Returns 0 on success; otherwise an error status. + * + * Implemenation note: Pushes multiple buffers with Gather to Source ring. + */ +int ath10k_ce_sendlist_send(struct ce_state *ce_state, + void *per_transfer_send_context, + struct ce_sendlist *sendlist, + /* 14 bits */ + unsigned int transfer_id); /*==================Recv=======================*/ @@ -170,12 +233,17 @@ int ath10k_ce_num_free_src_entries(struct ath10k_ce_pipe *pipe); * * Implemenation note: Pushes a buffer to Dest ring. */ -int ath10k_ce_recv_buf_enqueue(struct ath10k_ce_pipe *ce_state, +int ath10k_ce_recv_buf_enqueue(struct ce_state *ce_state, void *per_transfer_recv_context, u32 buffer); -void ath10k_ce_recv_cb_register(struct ath10k_ce_pipe *ce_state, - void (*recv_cb)(struct ath10k_ce_pipe *)); +void ath10k_ce_recv_cb_register(struct ce_state *ce_state, + void (*recv_cb) (struct ce_state *ce_state, + void *transfer_context, + u32 buffer, + unsigned int nbytes, + unsigned int transfer_id, + unsigned int flags)); /* recv flags */ /* Data is byte-swapped */ @@ -185,7 +253,7 @@ void ath10k_ce_recv_cb_register(struct ath10k_ce_pipe *ce_state, * Supply data for the next completed unprocessed receive descriptor. * Pops buffer from Dest ring. */ -int ath10k_ce_completed_recv_next(struct ath10k_ce_pipe *ce_state, +int ath10k_ce_completed_recv_next(struct ce_state *ce_state, void **per_transfer_contextp, u32 *bufferp, unsigned int *nbytesp, @@ -195,7 +263,7 @@ int ath10k_ce_completed_recv_next(struct ath10k_ce_pipe *ce_state, * Supply data for the next completed unprocessed send descriptor. * Pops 1 completed send buffer from Source ring. */ -int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state, +int ath10k_ce_completed_send_next(struct ce_state *ce_state, void **per_transfer_contextp, u32 *bufferp, unsigned int *nbytesp, @@ -204,7 +272,7 @@ int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state, /*==================CE Engine Initialization=======================*/ /* Initialize an instance of a CE */ -struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar, +struct ce_state *ath10k_ce_init(struct ath10k *ar, unsigned int ce_id, const struct ce_attr *attr); @@ -214,7 +282,7 @@ struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar, * receive buffers. Target DMA must be stopped before using * this API. */ -int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state, +int ath10k_ce_revoke_recv_next(struct ce_state *ce_state, void **per_transfer_contextp, u32 *bufferp); @@ -223,13 +291,13 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state, * pending sends. Target DMA must be stopped before using * this API. */ -int ath10k_ce_cancel_send_next(struct ath10k_ce_pipe *ce_state, +int ath10k_ce_cancel_send_next(struct ce_state *ce_state, void **per_transfer_contextp, u32 *bufferp, unsigned int *nbytesp, unsigned int *transfer_idp); -void ath10k_ce_deinit(struct ath10k_ce_pipe *ce_state); +void ath10k_ce_deinit(struct ce_state *ce_state); /*==================CE Interrupt Handlers====================*/ void ath10k_ce_per_engine_service_any(struct ath10k *ar); @@ -254,6 +322,9 @@ struct ce_attr { /* CE_ATTR_* values */ unsigned int flags; + /* currently not in use */ + unsigned int priority; + /* #entries in source ring - Must be a power of 2 */ unsigned int src_nentries; @@ -265,8 +336,21 @@ struct ce_attr { /* #entries in destination ring - Must be a power of 2 */ unsigned int dest_nentries; + + /* Future use */ + void *reserved; }; +/* + * When using sendlist_send to transfer multiple buffer fragments, the + * transfer context of each fragment, except last one, will be filled + * with CE_SENDLIST_ITEM_CTXT. ce_completed_send will return success for + * each fragment done with send and the transfer context would be + * CE_SENDLIST_ITEM_CTXT. Upper layer could use this to identify the + * status of a send completion. + */ +#define CE_SENDLIST_ITEM_CTXT ((void *)0xcecebeef) + #define SR_BA_ADDRESS 0x0000 #define SR_SIZE_ADDRESS 0x0004 #define DR_BA_ADDRESS 0x0008 |