xref: /linux/drivers/net/wireless/ath/ath10k/ce.h (revision 1863008369ae0407508033b4b00f98b985adeb15)
15e3dd157SKalle Valo /*
25e3dd157SKalle Valo  * Copyright (c) 2005-2011 Atheros Communications Inc.
38b1083d6SKalle Valo  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
4b7ba83f7SRakesh Pillai  * Copyright (c) 2018 The Linux Foundation. All rights reserved.
55e3dd157SKalle Valo  *
65e3dd157SKalle Valo  * Permission to use, copy, modify, and/or distribute this software for any
75e3dd157SKalle Valo  * purpose with or without fee is hereby granted, provided that the above
85e3dd157SKalle Valo  * copyright notice and this permission notice appear in all copies.
95e3dd157SKalle Valo  *
105e3dd157SKalle Valo  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
115e3dd157SKalle Valo  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
125e3dd157SKalle Valo  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
135e3dd157SKalle Valo  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
145e3dd157SKalle Valo  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
155e3dd157SKalle Valo  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
165e3dd157SKalle Valo  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
175e3dd157SKalle Valo  */
185e3dd157SKalle Valo 
195e3dd157SKalle Valo #ifndef _CE_H_
205e3dd157SKalle Valo #define _CE_H_
215e3dd157SKalle Valo 
225e3dd157SKalle Valo #include "hif.h"
235e3dd157SKalle Valo 
2443c9e384SMichal Kazior #define CE_HTT_H2T_MSG_SRC_NENTRIES 8192
255e3dd157SKalle Valo 
265e3dd157SKalle Valo /* Descriptor rings must be aligned to this boundary */
275e3dd157SKalle Valo #define CE_DESC_RING_ALIGN	8
285e3dd157SKalle Valo #define CE_SEND_FLAG_GATHER	0x00010000
295e3dd157SKalle Valo 
305e3dd157SKalle Valo /*
315e3dd157SKalle Valo  * Copy Engine support: low-level Target-side Copy Engine API.
325e3dd157SKalle Valo  * This is a hardware access layer used by code that understands
335e3dd157SKalle Valo  * how to use copy engines.
345e3dd157SKalle Valo  */
355e3dd157SKalle Valo 
362aa39115SMichal Kazior struct ath10k_ce_pipe;
375e3dd157SKalle Valo 
385e3dd157SKalle Valo #define CE_DESC_FLAGS_GATHER         (1 << 0)
395e3dd157SKalle Valo #define CE_DESC_FLAGS_BYTE_SWAP      (1 << 1)
402a1e1ad3SGovind Singh #define CE_WCN3990_DESC_FLAGS_GATHER BIT(31)
412a1e1ad3SGovind Singh 
425b9030ceSRakesh Pillai #define CE_DESC_ADDR_MASK		GENMASK_ULL(34, 0)
435b9030ceSRakesh Pillai #define CE_DESC_ADDR_HI_MASK		GENMASK(4, 0)
442adf99caSVasanthakumar Thiagarajan 
452adf99caSVasanthakumar Thiagarajan /* Following desc flags are used in QCA99X0 */
462adf99caSVasanthakumar Thiagarajan #define CE_DESC_FLAGS_HOST_INT_DIS	(1 << 2)
472adf99caSVasanthakumar Thiagarajan #define CE_DESC_FLAGS_TGT_INT_DIS	(1 << 3)
482adf99caSVasanthakumar Thiagarajan 
492adf99caSVasanthakumar Thiagarajan #define CE_DESC_FLAGS_META_DATA_MASK ar->hw_values->ce_desc_meta_data_mask
502adf99caSVasanthakumar Thiagarajan #define CE_DESC_FLAGS_META_DATA_LSB  ar->hw_values->ce_desc_meta_data_lsb
515e3dd157SKalle Valo 
524945af5bSGovind Singh #define CE_DDR_RRI_MASK			GENMASK(15, 0)
534945af5bSGovind Singh #define CE_DDR_DRRI_SHIFT		16
544945af5bSGovind Singh 
555e3dd157SKalle Valo struct ce_desc {
565e3dd157SKalle Valo 	__le32 addr;
575e3dd157SKalle Valo 	__le16 nbytes;
585e3dd157SKalle Valo 	__le16 flags; /* %CE_DESC_FLAGS_ */
595e3dd157SKalle Valo };
605e3dd157SKalle Valo 
612a1e1ad3SGovind Singh struct ce_desc_64 {
622a1e1ad3SGovind Singh 	__le64 addr;
632a1e1ad3SGovind Singh 	__le16 nbytes; /* length in register map */
642a1e1ad3SGovind Singh 	__le16 flags; /* fw_metadata_high */
652a1e1ad3SGovind Singh 	__le32 toeplitz_hash_result;
662a1e1ad3SGovind Singh };
672a1e1ad3SGovind Singh 
682a1e1ad3SGovind Singh #define CE_DESC_SIZE sizeof(struct ce_desc)
692a1e1ad3SGovind Singh #define CE_DESC_SIZE_64 sizeof(struct ce_desc_64)
702a1e1ad3SGovind Singh 
71d21fb959SMichal Kazior struct ath10k_ce_ring {
725e3dd157SKalle Valo 	/* Number of entries in this ring; must be power of 2 */
735e3dd157SKalle Valo 	unsigned int nentries;
745e3dd157SKalle Valo 	unsigned int nentries_mask;
755e3dd157SKalle Valo 
765e3dd157SKalle Valo 	/*
775e3dd157SKalle Valo 	 * For dest ring, this is the next index to be processed
785e3dd157SKalle Valo 	 * by software after it was/is received into.
795e3dd157SKalle Valo 	 *
805e3dd157SKalle Valo 	 * For src ring, this is the last descriptor that was sent
815e3dd157SKalle Valo 	 * and completion processed by software.
825e3dd157SKalle Valo 	 *
835e3dd157SKalle Valo 	 * Regardless of src or dest ring, this is an invariant
845e3dd157SKalle Valo 	 * (modulo ring size):
855e3dd157SKalle Valo 	 *     write index >= read index >= sw_index
865e3dd157SKalle Valo 	 */
875e3dd157SKalle Valo 	unsigned int sw_index;
885e3dd157SKalle Valo 	/* cached copy */
895e3dd157SKalle Valo 	unsigned int write_index;
905e3dd157SKalle Valo 	/*
915e3dd157SKalle Valo 	 * For src ring, this is the next index not yet processed by HW.
925e3dd157SKalle Valo 	 * This is a cached copy of the real HW index (read index), used
935e3dd157SKalle Valo 	 * for avoiding reading the HW index register more often than
945e3dd157SKalle Valo 	 * necessary.
955e3dd157SKalle Valo 	 * This extends the invariant:
965e3dd157SKalle Valo 	 *     write index >= read index >= hw_index >= sw_index
975e3dd157SKalle Valo 	 *
985e3dd157SKalle Valo 	 * For dest ring, this is currently unused.
995e3dd157SKalle Valo 	 */
1005e3dd157SKalle Valo 	/* cached copy */
1015e3dd157SKalle Valo 	unsigned int hw_index;
1025e3dd157SKalle Valo 
1035e3dd157SKalle Valo 	/* Start of DMA-coherent area reserved for descriptors */
1045e3dd157SKalle Valo 	/* Host address space */
1055e3dd157SKalle Valo 	void *base_addr_owner_space_unaligned;
1065e3dd157SKalle Valo 	/* CE address space */
1075b9030ceSRakesh Pillai 	dma_addr_t base_addr_ce_space_unaligned;
1085e3dd157SKalle Valo 
1095e3dd157SKalle Valo 	/*
1105e3dd157SKalle Valo 	 * Actual start of descriptors.
1115e3dd157SKalle Valo 	 * Aligned to descriptor-size boundary.
1125e3dd157SKalle Valo 	 * Points into reserved DMA-coherent area, above.
1135e3dd157SKalle Valo 	 */
1145e3dd157SKalle Valo 	/* Host address space */
1155e3dd157SKalle Valo 	void *base_addr_owner_space;
1165e3dd157SKalle Valo 
1175e3dd157SKalle Valo 	/* CE address space */
1185b9030ceSRakesh Pillai 	dma_addr_t base_addr_ce_space;
1195e3dd157SKalle Valo 
120b7ba83f7SRakesh Pillai 	char *shadow_base_unaligned;
121*18630083SRakesh Pillai 	struct ce_desc_64 *shadow_base;
122b7ba83f7SRakesh Pillai 
12325d0dbcbSMichal Kazior 	/* keep last */
12425d0dbcbSMichal Kazior 	void *per_transfer_context[0];
1255e3dd157SKalle Valo };
1265e3dd157SKalle Valo 
1272aa39115SMichal Kazior struct ath10k_ce_pipe {
1285e3dd157SKalle Valo 	struct ath10k *ar;
1295e3dd157SKalle Valo 	unsigned int id;
1305e3dd157SKalle Valo 
1315e3dd157SKalle Valo 	unsigned int attr_flags;
1325e3dd157SKalle Valo 
1335e3dd157SKalle Valo 	u32 ctrl_addr;
1345e3dd157SKalle Valo 
1355440ce25SMichal Kazior 	void (*send_cb)(struct ath10k_ce_pipe *);
1365440ce25SMichal Kazior 	void (*recv_cb)(struct ath10k_ce_pipe *);
1375e3dd157SKalle Valo 
1385e3dd157SKalle Valo 	unsigned int src_sz_max;
139d21fb959SMichal Kazior 	struct ath10k_ce_ring *src_ring;
140d21fb959SMichal Kazior 	struct ath10k_ce_ring *dest_ring;
1412a1e1ad3SGovind Singh 	const struct ath10k_ce_ops *ops;
1425e3dd157SKalle Valo };
1435e3dd157SKalle Valo 
1445e3dd157SKalle Valo /* Copy Engine settable attributes */
1455e3dd157SKalle Valo struct ce_attr;
1465e3dd157SKalle Valo 
147641fe28aSGovind Singh struct ath10k_bus_ops {
148641fe28aSGovind Singh 	u32 (*read32)(struct ath10k *ar, u32 offset);
149641fe28aSGovind Singh 	void (*write32)(struct ath10k *ar, u32 offset, u32 value);
150641fe28aSGovind Singh 	int (*get_num_banks)(struct ath10k *ar);
151641fe28aSGovind Singh };
152641fe28aSGovind Singh 
153641fe28aSGovind Singh static inline struct ath10k_ce *ath10k_ce_priv(struct ath10k *ar)
154641fe28aSGovind Singh {
155641fe28aSGovind Singh 	return (struct ath10k_ce *)ar->ce_priv;
156641fe28aSGovind Singh }
157641fe28aSGovind Singh 
158641fe28aSGovind Singh struct ath10k_ce {
159641fe28aSGovind Singh 	/* protects CE info */
160641fe28aSGovind Singh 	spinlock_t ce_lock;
161641fe28aSGovind Singh 	const struct ath10k_bus_ops *bus_ops;
162641fe28aSGovind Singh 	struct ath10k_ce_pipe ce_states[CE_COUNT_MAX];
1634945af5bSGovind Singh 	u32 *vaddr_rri;
1644945af5bSGovind Singh 	dma_addr_t paddr_rri;
165641fe28aSGovind Singh };
166641fe28aSGovind Singh 
1675e3dd157SKalle Valo /*==================Send====================*/
1685e3dd157SKalle Valo 
1695e3dd157SKalle Valo /* ath10k_ce_send flags */
1705e3dd157SKalle Valo #define CE_SEND_FLAG_BYTE_SWAP 1
1715e3dd157SKalle Valo 
1725e3dd157SKalle Valo /*
1735e3dd157SKalle Valo  * Queue a source buffer to be sent to an anonymous destination buffer.
1745e3dd157SKalle Valo  *   ce         - which copy engine to use
1755e3dd157SKalle Valo  *   buffer          - address of buffer
1765e3dd157SKalle Valo  *   nbytes          - number of bytes to send
1775e3dd157SKalle Valo  *   transfer_id     - arbitrary ID; reflected to destination
1785e3dd157SKalle Valo  *   flags           - CE_SEND_FLAG_* values
1795e3dd157SKalle Valo  * Returns 0 on success; otherwise an error status.
1805e3dd157SKalle Valo  *
1815e3dd157SKalle Valo  * Note: If no flags are specified, use CE's default data swap mode.
1825e3dd157SKalle Valo  *
1835e3dd157SKalle Valo  * Implementation note: pushes 1 buffer to Source ring
1845e3dd157SKalle Valo  */
1852aa39115SMichal Kazior int ath10k_ce_send(struct ath10k_ce_pipe *ce_state,
1865e3dd157SKalle Valo 		   void *per_transfer_send_context,
1875dac5f37SGovind Singh 		   dma_addr_t buffer,
1885e3dd157SKalle Valo 		   unsigned int nbytes,
1895e3dd157SKalle Valo 		   /* 14 bits */
1905e3dd157SKalle Valo 		   unsigned int transfer_id,
1915e3dd157SKalle Valo 		   unsigned int flags);
1925e3dd157SKalle Valo 
193726346fcSMichal Kazior int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state,
194726346fcSMichal Kazior 			  void *per_transfer_context,
1955dac5f37SGovind Singh 			  dma_addr_t buffer,
196726346fcSMichal Kazior 			  unsigned int nbytes,
197726346fcSMichal Kazior 			  unsigned int transfer_id,
198726346fcSMichal Kazior 			  unsigned int flags);
199726346fcSMichal Kazior 
20008b8aa09SMichal Kazior void __ath10k_ce_send_revert(struct ath10k_ce_pipe *pipe);
20108b8aa09SMichal Kazior 
2023efcb3b4SMichal Kazior int ath10k_ce_num_free_src_entries(struct ath10k_ce_pipe *pipe);
2035e3dd157SKalle Valo 
2045e3dd157SKalle Valo /*==================Recv=======================*/
2055e3dd157SKalle Valo 
206728f95eeSMichal Kazior int __ath10k_ce_rx_num_free_bufs(struct ath10k_ce_pipe *pipe);
2075dac5f37SGovind Singh int ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx,
2085dac5f37SGovind Singh 			  dma_addr_t paddr);
209128abd09SRajkumar Manoharan void ath10k_ce_rx_update_write_idx(struct ath10k_ce_pipe *pipe, u32 nentries);
2105e3dd157SKalle Valo 
2115e3dd157SKalle Valo /* recv flags */
2125e3dd157SKalle Valo /* Data is byte-swapped */
2135e3dd157SKalle Valo #define CE_RECV_FLAG_SWAPPED	1
2145e3dd157SKalle Valo 
2155e3dd157SKalle Valo /*
2165e3dd157SKalle Valo  * Supply data for the next completed unprocessed receive descriptor.
2175e3dd157SKalle Valo  * Pops buffer from Dest ring.
2185e3dd157SKalle Valo  */
2192aa39115SMichal Kazior int ath10k_ce_completed_recv_next(struct ath10k_ce_pipe *ce_state,
2205e3dd157SKalle Valo 				  void **per_transfer_contextp,
22124d9ef5eSRajkumar Manoharan 				  unsigned int *nbytesp);
2225e3dd157SKalle Valo /*
2235e3dd157SKalle Valo  * Supply data for the next completed unprocessed send descriptor.
2245e3dd157SKalle Valo  * Pops 1 completed send buffer from Source ring.
2255e3dd157SKalle Valo  */
2262aa39115SMichal Kazior int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state,
227765952e4SRajkumar Manoharan 				  void **per_transfer_contextp);
2285e3dd157SKalle Valo 
229eef25405SKalle Valo int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
230765952e4SRajkumar Manoharan 					 void **per_transfer_contextp);
231eef25405SKalle Valo 
2325e3dd157SKalle Valo /*==================CE Engine Initialization=======================*/
2335e3dd157SKalle Valo 
23425d0dbcbSMichal Kazior int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id,
23584cbf3a7SMichal Kazior 			const struct ce_attr *attr);
23684cbf3a7SMichal Kazior void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id);
23784cbf3a7SMichal Kazior int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
2389d9bdbb0SRajkumar Manoharan 			 const struct ce_attr *attr);
23925d0dbcbSMichal Kazior void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id);
2405e3dd157SKalle Valo 
2415e3dd157SKalle Valo /*==================CE Engine Shutdown=======================*/
2425e3dd157SKalle Valo /*
2435e3dd157SKalle Valo  * Support clean shutdown by allowing the caller to revoke
2445e3dd157SKalle Valo  * receive buffers.  Target DMA must be stopped before using
2455e3dd157SKalle Valo  * this API.
2465e3dd157SKalle Valo  */
2472aa39115SMichal Kazior int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state,
2485e3dd157SKalle Valo 			       void **per_transfer_contextp,
2495dac5f37SGovind Singh 			       dma_addr_t *bufferp);
2505e3dd157SKalle Valo 
251eef25405SKalle Valo int ath10k_ce_completed_recv_next_nolock(struct ath10k_ce_pipe *ce_state,
252eef25405SKalle Valo 					 void **per_transfer_contextp,
25324d9ef5eSRajkumar Manoharan 					 unsigned int *nbytesp);
254eef25405SKalle Valo 
2555e3dd157SKalle Valo /*
2565e3dd157SKalle Valo  * Support clean shutdown by allowing the caller to cancel
2575e3dd157SKalle Valo  * pending sends.  Target DMA must be stopped before using
2585e3dd157SKalle Valo  * this API.
2595e3dd157SKalle Valo  */
2602aa39115SMichal Kazior int ath10k_ce_cancel_send_next(struct ath10k_ce_pipe *ce_state,
2615e3dd157SKalle Valo 			       void **per_transfer_contextp,
2625dac5f37SGovind Singh 			       dma_addr_t *bufferp,
2635e3dd157SKalle Valo 			       unsigned int *nbytesp,
2645e3dd157SKalle Valo 			       unsigned int *transfer_idp);
2655e3dd157SKalle Valo 
2665e3dd157SKalle Valo /*==================CE Interrupt Handlers====================*/
2675e3dd157SKalle Valo void ath10k_ce_per_engine_service_any(struct ath10k *ar);
2685e3dd157SKalle Valo void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id);
26928642f42SMichal Kazior int ath10k_ce_disable_interrupts(struct ath10k *ar);
270145cc121SMichal Kazior void ath10k_ce_enable_interrupts(struct ath10k *ar);
271c75c398bSMohammed Shafi Shajakhan void ath10k_ce_dump_registers(struct ath10k *ar,
272c75c398bSMohammed Shafi Shajakhan 			      struct ath10k_fw_crash_data *crash_data);
2734945af5bSGovind Singh void ath10k_ce_alloc_rri(struct ath10k *ar);
2744945af5bSGovind Singh void ath10k_ce_free_rri(struct ath10k *ar);
2755e3dd157SKalle Valo 
2765e3dd157SKalle Valo /* ce_attr.flags values */
2775e3dd157SKalle Valo /* Use NonSnooping PCIe accesses? */
2789abcb937SGovind Singh #define CE_ATTR_NO_SNOOP		BIT(0)
2795e3dd157SKalle Valo 
2805e3dd157SKalle Valo /* Byte swap data words */
2819abcb937SGovind Singh #define CE_ATTR_BYTE_SWAP_DATA		BIT(1)
2825e3dd157SKalle Valo 
2835e3dd157SKalle Valo /* Swizzle descriptors? */
2849abcb937SGovind Singh #define CE_ATTR_SWIZZLE_DESCRIPTORS	BIT(2)
2855e3dd157SKalle Valo 
2865e3dd157SKalle Valo /* no interrupt on copy completion */
2879abcb937SGovind Singh #define CE_ATTR_DIS_INTR		BIT(3)
2889abcb937SGovind Singh 
2899abcb937SGovind Singh /* no interrupt, only polling */
2909abcb937SGovind Singh #define CE_ATTR_POLL			BIT(4)
2915e3dd157SKalle Valo 
2925e3dd157SKalle Valo /* Attributes of an instance of a Copy Engine */
2935e3dd157SKalle Valo struct ce_attr {
2945e3dd157SKalle Valo 	/* CE_ATTR_* values */
2955e3dd157SKalle Valo 	unsigned int flags;
2965e3dd157SKalle Valo 
2975e3dd157SKalle Valo 	/* #entries in source ring - Must be a power of 2 */
2985e3dd157SKalle Valo 	unsigned int src_nentries;
2995e3dd157SKalle Valo 
3005e3dd157SKalle Valo 	/*
3015e3dd157SKalle Valo 	 * Max source send size for this CE.
3025e3dd157SKalle Valo 	 * This is also the minimum size of a destination buffer.
3035e3dd157SKalle Valo 	 */
3045e3dd157SKalle Valo 	unsigned int src_sz_max;
3055e3dd157SKalle Valo 
3065e3dd157SKalle Valo 	/* #entries in destination ring - Must be a power of 2 */
3075e3dd157SKalle Valo 	unsigned int dest_nentries;
3080e5b2950SRajkumar Manoharan 
3090e5b2950SRajkumar Manoharan 	void (*send_cb)(struct ath10k_ce_pipe *);
3109d9bdbb0SRajkumar Manoharan 	void (*recv_cb)(struct ath10k_ce_pipe *);
3115e3dd157SKalle Valo };
3125e3dd157SKalle Valo 
3132a1e1ad3SGovind Singh struct ath10k_ce_ops {
3142a1e1ad3SGovind Singh 	struct ath10k_ce_ring *(*ce_alloc_src_ring)(struct ath10k *ar,
3152a1e1ad3SGovind Singh 						    u32 ce_id,
3162a1e1ad3SGovind Singh 						    const struct ce_attr *attr);
3172a1e1ad3SGovind Singh 	struct ath10k_ce_ring *(*ce_alloc_dst_ring)(struct ath10k *ar,
3182a1e1ad3SGovind Singh 						    u32 ce_id,
3192a1e1ad3SGovind Singh 						    const struct ce_attr *attr);
3202a1e1ad3SGovind Singh 	int (*ce_rx_post_buf)(struct ath10k_ce_pipe *pipe, void *ctx,
3212a1e1ad3SGovind Singh 			      dma_addr_t paddr);
3222a1e1ad3SGovind Singh 	int (*ce_completed_recv_next_nolock)(struct ath10k_ce_pipe *ce_state,
3232a1e1ad3SGovind Singh 					     void **per_transfer_contextp,
3242a1e1ad3SGovind Singh 					     u32 *nbytesp);
3252a1e1ad3SGovind Singh 	int (*ce_revoke_recv_next)(struct ath10k_ce_pipe *ce_state,
3262a1e1ad3SGovind Singh 				   void **per_transfer_contextp,
3272a1e1ad3SGovind Singh 				   dma_addr_t *nbytesp);
3282a1e1ad3SGovind Singh 	void (*ce_extract_desc_data)(struct ath10k *ar,
3292a1e1ad3SGovind Singh 				     struct ath10k_ce_ring *src_ring,
3302a1e1ad3SGovind Singh 				     u32 sw_index, dma_addr_t *bufferp,
3312a1e1ad3SGovind Singh 				     u32 *nbytesp, u32 *transfer_idp);
3322a1e1ad3SGovind Singh 	void (*ce_free_pipe)(struct ath10k *ar, int ce_id);
3332a1e1ad3SGovind Singh 	int (*ce_send_nolock)(struct ath10k_ce_pipe *pipe,
3342a1e1ad3SGovind Singh 			      void *per_transfer_context,
3352a1e1ad3SGovind Singh 			      dma_addr_t buffer, u32 nbytes,
3362a1e1ad3SGovind Singh 			      u32 transfer_id, u32 flags);
3375b9030ceSRakesh Pillai 	void (*ce_set_src_ring_base_addr_hi)(struct ath10k *ar,
3385b9030ceSRakesh Pillai 					     u32 ce_ctrl_addr,
3395b9030ceSRakesh Pillai 					     u64 addr);
3405b9030ceSRakesh Pillai 	void (*ce_set_dest_ring_base_addr_hi)(struct ath10k *ar,
3415b9030ceSRakesh Pillai 					      u32 ce_ctrl_addr,
3425b9030ceSRakesh Pillai 					      u64 addr);
3432a1e1ad3SGovind Singh };
344a3e712b7SKalle Valo 
345d63955b3SMichal Kazior static inline u32 ath10k_ce_base_address(struct ath10k *ar, unsigned int ce_id)
3465e3dd157SKalle Valo {
3475e3dd157SKalle Valo 	return CE0_BASE_ADDRESS + (CE1_BASE_ADDRESS - CE0_BASE_ADDRESS) * ce_id;
3485e3dd157SKalle Valo }
3495e3dd157SKalle Valo 
3504945af5bSGovind Singh #define COPY_ENGINE_ID(COPY_ENGINE_BASE_ADDRESS) (((COPY_ENGINE_BASE_ADDRESS) \
3514945af5bSGovind Singh 		- CE0_BASE_ADDRESS) / (CE1_BASE_ADDRESS - CE0_BASE_ADDRESS))
3524945af5bSGovind Singh 
3535e3dd157SKalle Valo #define CE_SRC_RING_TO_DESC(baddr, idx) \
3545e3dd157SKalle Valo 	(&(((struct ce_desc *)baddr)[idx]))
3555e3dd157SKalle Valo 
3565e3dd157SKalle Valo #define CE_DEST_RING_TO_DESC(baddr, idx) \
3575e3dd157SKalle Valo 	(&(((struct ce_desc *)baddr)[idx]))
3585e3dd157SKalle Valo 
3592a1e1ad3SGovind Singh #define CE_SRC_RING_TO_DESC_64(baddr, idx) \
3602a1e1ad3SGovind Singh 	(&(((struct ce_desc_64 *)baddr)[idx]))
3612a1e1ad3SGovind Singh 
3622a1e1ad3SGovind Singh #define CE_DEST_RING_TO_DESC_64(baddr, idx) \
3632a1e1ad3SGovind Singh 	(&(((struct ce_desc_64 *)baddr)[idx]))
3642a1e1ad3SGovind Singh 
3655e3dd157SKalle Valo /* Ring arithmetic (modulus number of entries in ring, which is a pwr of 2). */
3665e3dd157SKalle Valo #define CE_RING_DELTA(nentries_mask, fromidx, toidx) \
3675e3dd157SKalle Valo 	(((int)(toidx) - (int)(fromidx)) & (nentries_mask))
3685e3dd157SKalle Valo 
3695e3dd157SKalle Valo #define CE_RING_IDX_INCR(nentries_mask, idx) (((idx) + 1) & (nentries_mask))
370128abd09SRajkumar Manoharan #define CE_RING_IDX_ADD(nentries_mask, idx, num) \
371128abd09SRajkumar Manoharan 		(((idx) + (num)) & (nentries_mask))
3725e3dd157SKalle Valo 
373a521ee98SVasanthakumar Thiagarajan #define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB \
374a521ee98SVasanthakumar Thiagarajan 				ar->regs->ce_wrap_intr_sum_host_msi_lsb
375a521ee98SVasanthakumar Thiagarajan #define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK \
376a521ee98SVasanthakumar Thiagarajan 				ar->regs->ce_wrap_intr_sum_host_msi_mask
3775e3dd157SKalle Valo #define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET(x) \
3785e3dd157SKalle Valo 	(((x) & CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK) >> \
3795e3dd157SKalle Valo 		CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB)
3805e3dd157SKalle Valo #define CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS			0x0000
381ea66b12eSRakesh Pillai #define CE_INTERRUPT_SUMMARY		(GENMASK(CE_COUNT_MAX - 1, 0))
3825e3dd157SKalle Valo 
383641fe28aSGovind Singh static inline u32 ath10k_ce_interrupt_summary(struct ath10k *ar)
384641fe28aSGovind Singh {
385641fe28aSGovind Singh 	struct ath10k_ce *ce = ath10k_ce_priv(ar);
386641fe28aSGovind Singh 
387ea66b12eSRakesh Pillai 	if (!ar->hw_params.per_ce_irq)
388641fe28aSGovind Singh 		return CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET(
389641fe28aSGovind Singh 			ce->bus_ops->read32((ar), CE_WRAPPER_BASE_ADDRESS +
390641fe28aSGovind Singh 			CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS));
391ea66b12eSRakesh Pillai 	else
392ea66b12eSRakesh Pillai 		return CE_INTERRUPT_SUMMARY;
393641fe28aSGovind Singh }
3945e3dd157SKalle Valo 
3958ac5fe8eSBrian Norris /* Host software's Copy Engine configuration. */
3968ac5fe8eSBrian Norris #define CE_ATTR_FLAGS 0
3978ac5fe8eSBrian Norris 
3988ac5fe8eSBrian Norris /*
3998ac5fe8eSBrian Norris  * Configuration information for a Copy Engine pipe.
4008ac5fe8eSBrian Norris  * Passed from Host to Target during startup (one per CE).
4018ac5fe8eSBrian Norris  *
4028ac5fe8eSBrian Norris  * NOTE: Structure is shared between Host software and Target firmware!
4038ac5fe8eSBrian Norris  */
4048ac5fe8eSBrian Norris struct ce_pipe_config {
4058ac5fe8eSBrian Norris 	__le32 pipenum;
4068ac5fe8eSBrian Norris 	__le32 pipedir;
4078ac5fe8eSBrian Norris 	__le32 nentries;
4088ac5fe8eSBrian Norris 	__le32 nbytes_max;
4098ac5fe8eSBrian Norris 	__le32 flags;
4108ac5fe8eSBrian Norris 	__le32 reserved;
4118ac5fe8eSBrian Norris };
4128ac5fe8eSBrian Norris 
4138ac5fe8eSBrian Norris /*
4148ac5fe8eSBrian Norris  * Directions for interconnect pipe configuration.
4158ac5fe8eSBrian Norris  * These definitions may be used during configuration and are shared
4168ac5fe8eSBrian Norris  * between Host and Target.
4178ac5fe8eSBrian Norris  *
4188ac5fe8eSBrian Norris  * Pipe Directions are relative to the Host, so PIPEDIR_IN means
4198ac5fe8eSBrian Norris  * "coming IN over air through Target to Host" as with a WiFi Rx operation.
4208ac5fe8eSBrian Norris  * Conversely, PIPEDIR_OUT means "going OUT from Host through Target over air"
4218ac5fe8eSBrian Norris  * as with a WiFi Tx operation. This is somewhat awkward for the "middle-man"
4228ac5fe8eSBrian Norris  * Target since things that are "PIPEDIR_OUT" are coming IN to the Target
4238ac5fe8eSBrian Norris  * over the interconnect.
4248ac5fe8eSBrian Norris  */
4258ac5fe8eSBrian Norris #define PIPEDIR_NONE    0
4268ac5fe8eSBrian Norris #define PIPEDIR_IN      1  /* Target-->Host, WiFi Rx direction */
4278ac5fe8eSBrian Norris #define PIPEDIR_OUT     2  /* Host->Target, WiFi Tx direction */
4288ac5fe8eSBrian Norris #define PIPEDIR_INOUT   3  /* bidirectional */
4298ac5fe8eSBrian Norris 
4308ac5fe8eSBrian Norris /* Establish a mapping between a service/direction and a pipe. */
4318ac5fe8eSBrian Norris struct service_to_pipe {
4328ac5fe8eSBrian Norris 	__le32 service_id;
4338ac5fe8eSBrian Norris 	__le32 pipedir;
4348ac5fe8eSBrian Norris 	__le32 pipenum;
4358ac5fe8eSBrian Norris };
4368ac5fe8eSBrian Norris 
4375e3dd157SKalle Valo #endif /* _CE_H_ */
438