18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: ISC */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (c) 2005-2011 Atheros Communications Inc.
48c2ecf20Sopenharmony_ci * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
58c2ecf20Sopenharmony_ci * Copyright (c) 2018 The Linux Foundation. All rights reserved.
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#ifndef _CE_H_
98c2ecf20Sopenharmony_ci#define _CE_H_
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include "hif.h"
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#define CE_HTT_H2T_MSG_SRC_NENTRIES 8192
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci/* Descriptor rings must be aligned to this boundary */
168c2ecf20Sopenharmony_ci#define CE_DESC_RING_ALIGN	8
178c2ecf20Sopenharmony_ci#define CE_SEND_FLAG_GATHER	0x00010000
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci/*
208c2ecf20Sopenharmony_ci * Copy Engine support: low-level Target-side Copy Engine API.
218c2ecf20Sopenharmony_ci * This is a hardware access layer used by code that understands
228c2ecf20Sopenharmony_ci * how to use copy engines.
238c2ecf20Sopenharmony_ci */
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_cistruct ath10k_ce_pipe;
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci#define CE_DESC_FLAGS_GATHER         (1 << 0)
288c2ecf20Sopenharmony_ci#define CE_DESC_FLAGS_BYTE_SWAP      (1 << 1)
298c2ecf20Sopenharmony_ci#define CE_WCN3990_DESC_FLAGS_GATHER BIT(31)
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci#define CE_DESC_ADDR_MASK		GENMASK_ULL(34, 0)
328c2ecf20Sopenharmony_ci#define CE_DESC_ADDR_HI_MASK		GENMASK(4, 0)
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci/* Following desc flags are used in QCA99X0 */
358c2ecf20Sopenharmony_ci#define CE_DESC_FLAGS_HOST_INT_DIS	(1 << 2)
368c2ecf20Sopenharmony_ci#define CE_DESC_FLAGS_TGT_INT_DIS	(1 << 3)
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci#define CE_DESC_FLAGS_META_DATA_MASK ar->hw_values->ce_desc_meta_data_mask
398c2ecf20Sopenharmony_ci#define CE_DESC_FLAGS_META_DATA_LSB  ar->hw_values->ce_desc_meta_data_lsb
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci#define CE_DDR_RRI_MASK			GENMASK(15, 0)
428c2ecf20Sopenharmony_ci#define CE_DDR_DRRI_SHIFT		16
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_cistruct ce_desc {
458c2ecf20Sopenharmony_ci	__le32 addr;
468c2ecf20Sopenharmony_ci	__le16 nbytes;
478c2ecf20Sopenharmony_ci	__le16 flags; /* %CE_DESC_FLAGS_ */
488c2ecf20Sopenharmony_ci};
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_cistruct ce_desc_64 {
518c2ecf20Sopenharmony_ci	__le64 addr;
528c2ecf20Sopenharmony_ci	__le16 nbytes; /* length in register map */
538c2ecf20Sopenharmony_ci	__le16 flags; /* fw_metadata_high */
548c2ecf20Sopenharmony_ci	__le32 toeplitz_hash_result;
558c2ecf20Sopenharmony_ci};
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci#define CE_DESC_SIZE sizeof(struct ce_desc)
588c2ecf20Sopenharmony_ci#define CE_DESC_SIZE_64 sizeof(struct ce_desc_64)
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_cistruct ath10k_ce_ring {
618c2ecf20Sopenharmony_ci	/* Number of entries in this ring; must be power of 2 */
628c2ecf20Sopenharmony_ci	unsigned int nentries;
638c2ecf20Sopenharmony_ci	unsigned int nentries_mask;
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	/*
668c2ecf20Sopenharmony_ci	 * For dest ring, this is the next index to be processed
678c2ecf20Sopenharmony_ci	 * by software after it was/is received into.
688c2ecf20Sopenharmony_ci	 *
698c2ecf20Sopenharmony_ci	 * For src ring, this is the last descriptor that was sent
708c2ecf20Sopenharmony_ci	 * and completion processed by software.
718c2ecf20Sopenharmony_ci	 *
728c2ecf20Sopenharmony_ci	 * Regardless of src or dest ring, this is an invariant
738c2ecf20Sopenharmony_ci	 * (modulo ring size):
748c2ecf20Sopenharmony_ci	 *     write index >= read index >= sw_index
758c2ecf20Sopenharmony_ci	 */
768c2ecf20Sopenharmony_ci	unsigned int sw_index;
778c2ecf20Sopenharmony_ci	/* cached copy */
788c2ecf20Sopenharmony_ci	unsigned int write_index;
798c2ecf20Sopenharmony_ci	/*
808c2ecf20Sopenharmony_ci	 * For src ring, this is the next index not yet processed by HW.
818c2ecf20Sopenharmony_ci	 * This is a cached copy of the real HW index (read index), used
828c2ecf20Sopenharmony_ci	 * for avoiding reading the HW index register more often than
838c2ecf20Sopenharmony_ci	 * necessary.
848c2ecf20Sopenharmony_ci	 * This extends the invariant:
858c2ecf20Sopenharmony_ci	 *     write index >= read index >= hw_index >= sw_index
868c2ecf20Sopenharmony_ci	 *
878c2ecf20Sopenharmony_ci	 * For dest ring, this is currently unused.
888c2ecf20Sopenharmony_ci	 */
898c2ecf20Sopenharmony_ci	/* cached copy */
908c2ecf20Sopenharmony_ci	unsigned int hw_index;
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci	/* Start of DMA-coherent area reserved for descriptors */
938c2ecf20Sopenharmony_ci	/* Host address space */
948c2ecf20Sopenharmony_ci	void *base_addr_owner_space_unaligned;
958c2ecf20Sopenharmony_ci	/* CE address space */
968c2ecf20Sopenharmony_ci	dma_addr_t base_addr_ce_space_unaligned;
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci	/*
998c2ecf20Sopenharmony_ci	 * Actual start of descriptors.
1008c2ecf20Sopenharmony_ci	 * Aligned to descriptor-size boundary.
1018c2ecf20Sopenharmony_ci	 * Points into reserved DMA-coherent area, above.
1028c2ecf20Sopenharmony_ci	 */
1038c2ecf20Sopenharmony_ci	/* Host address space */
1048c2ecf20Sopenharmony_ci	void *base_addr_owner_space;
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci	/* CE address space */
1078c2ecf20Sopenharmony_ci	dma_addr_t base_addr_ce_space;
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci	char *shadow_base_unaligned;
1108c2ecf20Sopenharmony_ci	struct ce_desc_64 *shadow_base;
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci	/* keep last */
1138c2ecf20Sopenharmony_ci	void *per_transfer_context[];
1148c2ecf20Sopenharmony_ci};
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_cistruct ath10k_ce_pipe {
1178c2ecf20Sopenharmony_ci	struct ath10k *ar;
1188c2ecf20Sopenharmony_ci	unsigned int id;
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci	unsigned int attr_flags;
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci	u32 ctrl_addr;
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci	void (*send_cb)(struct ath10k_ce_pipe *);
1258c2ecf20Sopenharmony_ci	void (*recv_cb)(struct ath10k_ce_pipe *);
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci	unsigned int src_sz_max;
1288c2ecf20Sopenharmony_ci	struct ath10k_ce_ring *src_ring;
1298c2ecf20Sopenharmony_ci	struct ath10k_ce_ring *dest_ring;
1308c2ecf20Sopenharmony_ci	const struct ath10k_ce_ops *ops;
1318c2ecf20Sopenharmony_ci};
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci/* Copy Engine settable attributes */
1348c2ecf20Sopenharmony_cistruct ce_attr;
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_cistruct ath10k_bus_ops {
1378c2ecf20Sopenharmony_ci	u32 (*read32)(struct ath10k *ar, u32 offset);
1388c2ecf20Sopenharmony_ci	void (*write32)(struct ath10k *ar, u32 offset, u32 value);
1398c2ecf20Sopenharmony_ci	int (*get_num_banks)(struct ath10k *ar);
1408c2ecf20Sopenharmony_ci};
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_cistatic inline struct ath10k_ce *ath10k_ce_priv(struct ath10k *ar)
1438c2ecf20Sopenharmony_ci{
1448c2ecf20Sopenharmony_ci	return (struct ath10k_ce *)ar->ce_priv;
1458c2ecf20Sopenharmony_ci}
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_cistruct ath10k_ce {
1488c2ecf20Sopenharmony_ci	/* protects CE info */
1498c2ecf20Sopenharmony_ci	spinlock_t ce_lock;
1508c2ecf20Sopenharmony_ci	const struct ath10k_bus_ops *bus_ops;
1518c2ecf20Sopenharmony_ci	struct ath10k_ce_pipe ce_states[CE_COUNT_MAX];
1528c2ecf20Sopenharmony_ci	u32 *vaddr_rri;
1538c2ecf20Sopenharmony_ci	dma_addr_t paddr_rri;
1548c2ecf20Sopenharmony_ci};
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci/*==================Send====================*/
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci/* ath10k_ce_send flags */
1598c2ecf20Sopenharmony_ci#define CE_SEND_FLAG_BYTE_SWAP 1
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ci/*
1628c2ecf20Sopenharmony_ci * Queue a source buffer to be sent to an anonymous destination buffer.
1638c2ecf20Sopenharmony_ci *   ce         - which copy engine to use
1648c2ecf20Sopenharmony_ci *   buffer          - address of buffer
1658c2ecf20Sopenharmony_ci *   nbytes          - number of bytes to send
1668c2ecf20Sopenharmony_ci *   transfer_id     - arbitrary ID; reflected to destination
1678c2ecf20Sopenharmony_ci *   flags           - CE_SEND_FLAG_* values
1688c2ecf20Sopenharmony_ci * Returns 0 on success; otherwise an error status.
1698c2ecf20Sopenharmony_ci *
1708c2ecf20Sopenharmony_ci * Note: If no flags are specified, use CE's default data swap mode.
1718c2ecf20Sopenharmony_ci *
1728c2ecf20Sopenharmony_ci * Implementation note: pushes 1 buffer to Source ring
1738c2ecf20Sopenharmony_ci */
1748c2ecf20Sopenharmony_ciint ath10k_ce_send(struct ath10k_ce_pipe *ce_state,
1758c2ecf20Sopenharmony_ci		   void *per_transfer_send_context,
1768c2ecf20Sopenharmony_ci		   dma_addr_t buffer,
1778c2ecf20Sopenharmony_ci		   unsigned int nbytes,
1788c2ecf20Sopenharmony_ci		   /* 14 bits */
1798c2ecf20Sopenharmony_ci		   unsigned int transfer_id,
1808c2ecf20Sopenharmony_ci		   unsigned int flags);
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ciint ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state,
1838c2ecf20Sopenharmony_ci			  void *per_transfer_context,
1848c2ecf20Sopenharmony_ci			  dma_addr_t buffer,
1858c2ecf20Sopenharmony_ci			  unsigned int nbytes,
1868c2ecf20Sopenharmony_ci			  unsigned int transfer_id,
1878c2ecf20Sopenharmony_ci			  unsigned int flags);
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_civoid __ath10k_ce_send_revert(struct ath10k_ce_pipe *pipe);
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ciint ath10k_ce_num_free_src_entries(struct ath10k_ce_pipe *pipe);
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_ci/*==================Recv=======================*/
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ciint __ath10k_ce_rx_num_free_bufs(struct ath10k_ce_pipe *pipe);
1968c2ecf20Sopenharmony_ciint ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx,
1978c2ecf20Sopenharmony_ci			  dma_addr_t paddr);
1988c2ecf20Sopenharmony_civoid ath10k_ce_rx_update_write_idx(struct ath10k_ce_pipe *pipe, u32 nentries);
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci/* recv flags */
2018c2ecf20Sopenharmony_ci/* Data is byte-swapped */
2028c2ecf20Sopenharmony_ci#define CE_RECV_FLAG_SWAPPED	1
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ci/*
2058c2ecf20Sopenharmony_ci * Supply data for the next completed unprocessed receive descriptor.
2068c2ecf20Sopenharmony_ci * Pops buffer from Dest ring.
2078c2ecf20Sopenharmony_ci */
2088c2ecf20Sopenharmony_ciint ath10k_ce_completed_recv_next(struct ath10k_ce_pipe *ce_state,
2098c2ecf20Sopenharmony_ci				  void **per_transfer_contextp,
2108c2ecf20Sopenharmony_ci				  unsigned int *nbytesp);
2118c2ecf20Sopenharmony_ci/*
2128c2ecf20Sopenharmony_ci * Supply data for the next completed unprocessed send descriptor.
2138c2ecf20Sopenharmony_ci * Pops 1 completed send buffer from Source ring.
2148c2ecf20Sopenharmony_ci */
2158c2ecf20Sopenharmony_ciint ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state,
2168c2ecf20Sopenharmony_ci				  void **per_transfer_contextp);
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ciint ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
2198c2ecf20Sopenharmony_ci					 void **per_transfer_contextp);
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_ci/*==================CE Engine Initialization=======================*/
2228c2ecf20Sopenharmony_ci
2238c2ecf20Sopenharmony_ciint ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id,
2248c2ecf20Sopenharmony_ci			const struct ce_attr *attr);
2258c2ecf20Sopenharmony_civoid ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id);
2268c2ecf20Sopenharmony_ciint ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
2278c2ecf20Sopenharmony_ci			 const struct ce_attr *attr);
2288c2ecf20Sopenharmony_civoid ath10k_ce_free_pipe(struct ath10k *ar, int ce_id);
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_ci/*==================CE Engine Shutdown=======================*/
2318c2ecf20Sopenharmony_ci/*
2328c2ecf20Sopenharmony_ci * Support clean shutdown by allowing the caller to revoke
2338c2ecf20Sopenharmony_ci * receive buffers.  Target DMA must be stopped before using
2348c2ecf20Sopenharmony_ci * this API.
2358c2ecf20Sopenharmony_ci */
2368c2ecf20Sopenharmony_ciint ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state,
2378c2ecf20Sopenharmony_ci			       void **per_transfer_contextp,
2388c2ecf20Sopenharmony_ci			       dma_addr_t *bufferp);
2398c2ecf20Sopenharmony_ci
2408c2ecf20Sopenharmony_ciint ath10k_ce_completed_recv_next_nolock(struct ath10k_ce_pipe *ce_state,
2418c2ecf20Sopenharmony_ci					 void **per_transfer_contextp,
2428c2ecf20Sopenharmony_ci					 unsigned int *nbytesp);
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ci/*
2458c2ecf20Sopenharmony_ci * Support clean shutdown by allowing the caller to cancel
2468c2ecf20Sopenharmony_ci * pending sends.  Target DMA must be stopped before using
2478c2ecf20Sopenharmony_ci * this API.
2488c2ecf20Sopenharmony_ci */
2498c2ecf20Sopenharmony_ciint ath10k_ce_cancel_send_next(struct ath10k_ce_pipe *ce_state,
2508c2ecf20Sopenharmony_ci			       void **per_transfer_contextp,
2518c2ecf20Sopenharmony_ci			       dma_addr_t *bufferp,
2528c2ecf20Sopenharmony_ci			       unsigned int *nbytesp,
2538c2ecf20Sopenharmony_ci			       unsigned int *transfer_idp);
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_ci/*==================CE Interrupt Handlers====================*/
2568c2ecf20Sopenharmony_civoid ath10k_ce_per_engine_service_any(struct ath10k *ar);
2578c2ecf20Sopenharmony_civoid ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id);
2588c2ecf20Sopenharmony_civoid ath10k_ce_disable_interrupt(struct ath10k *ar, int ce_id);
2598c2ecf20Sopenharmony_civoid ath10k_ce_disable_interrupts(struct ath10k *ar);
2608c2ecf20Sopenharmony_civoid ath10k_ce_enable_interrupt(struct ath10k *ar, int ce_id);
2618c2ecf20Sopenharmony_civoid ath10k_ce_enable_interrupts(struct ath10k *ar);
2628c2ecf20Sopenharmony_civoid ath10k_ce_dump_registers(struct ath10k *ar,
2638c2ecf20Sopenharmony_ci			      struct ath10k_fw_crash_data *crash_data);
2648c2ecf20Sopenharmony_ci
2658c2ecf20Sopenharmony_civoid ath10k_ce_alloc_rri(struct ath10k *ar);
2668c2ecf20Sopenharmony_civoid ath10k_ce_free_rri(struct ath10k *ar);
2678c2ecf20Sopenharmony_ci
2688c2ecf20Sopenharmony_ci/* ce_attr.flags values */
2698c2ecf20Sopenharmony_ci/* Use NonSnooping PCIe accesses? */
2708c2ecf20Sopenharmony_ci#define CE_ATTR_NO_SNOOP		BIT(0)
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_ci/* Byte swap data words */
2738c2ecf20Sopenharmony_ci#define CE_ATTR_BYTE_SWAP_DATA		BIT(1)
2748c2ecf20Sopenharmony_ci
2758c2ecf20Sopenharmony_ci/* Swizzle descriptors? */
2768c2ecf20Sopenharmony_ci#define CE_ATTR_SWIZZLE_DESCRIPTORS	BIT(2)
2778c2ecf20Sopenharmony_ci
2788c2ecf20Sopenharmony_ci/* no interrupt on copy completion */
2798c2ecf20Sopenharmony_ci#define CE_ATTR_DIS_INTR		BIT(3)
2808c2ecf20Sopenharmony_ci
2818c2ecf20Sopenharmony_ci/* no interrupt, only polling */
2828c2ecf20Sopenharmony_ci#define CE_ATTR_POLL			BIT(4)
2838c2ecf20Sopenharmony_ci
2848c2ecf20Sopenharmony_ci/* Attributes of an instance of a Copy Engine */
2858c2ecf20Sopenharmony_cistruct ce_attr {
2868c2ecf20Sopenharmony_ci	/* CE_ATTR_* values */
2878c2ecf20Sopenharmony_ci	unsigned int flags;
2888c2ecf20Sopenharmony_ci
2898c2ecf20Sopenharmony_ci	/* #entries in source ring - Must be a power of 2 */
2908c2ecf20Sopenharmony_ci	unsigned int src_nentries;
2918c2ecf20Sopenharmony_ci
2928c2ecf20Sopenharmony_ci	/*
2938c2ecf20Sopenharmony_ci	 * Max source send size for this CE.
2948c2ecf20Sopenharmony_ci	 * This is also the minimum size of a destination buffer.
2958c2ecf20Sopenharmony_ci	 */
2968c2ecf20Sopenharmony_ci	unsigned int src_sz_max;
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ci	/* #entries in destination ring - Must be a power of 2 */
2998c2ecf20Sopenharmony_ci	unsigned int dest_nentries;
3008c2ecf20Sopenharmony_ci
3018c2ecf20Sopenharmony_ci	void (*send_cb)(struct ath10k_ce_pipe *);
3028c2ecf20Sopenharmony_ci	void (*recv_cb)(struct ath10k_ce_pipe *);
3038c2ecf20Sopenharmony_ci};
3048c2ecf20Sopenharmony_ci
3058c2ecf20Sopenharmony_cistruct ath10k_ce_ops {
3068c2ecf20Sopenharmony_ci	struct ath10k_ce_ring *(*ce_alloc_src_ring)(struct ath10k *ar,
3078c2ecf20Sopenharmony_ci						    u32 ce_id,
3088c2ecf20Sopenharmony_ci						    const struct ce_attr *attr);
3098c2ecf20Sopenharmony_ci	struct ath10k_ce_ring *(*ce_alloc_dst_ring)(struct ath10k *ar,
3108c2ecf20Sopenharmony_ci						    u32 ce_id,
3118c2ecf20Sopenharmony_ci						    const struct ce_attr *attr);
3128c2ecf20Sopenharmony_ci	int (*ce_rx_post_buf)(struct ath10k_ce_pipe *pipe, void *ctx,
3138c2ecf20Sopenharmony_ci			      dma_addr_t paddr);
3148c2ecf20Sopenharmony_ci	int (*ce_completed_recv_next_nolock)(struct ath10k_ce_pipe *ce_state,
3158c2ecf20Sopenharmony_ci					     void **per_transfer_contextp,
3168c2ecf20Sopenharmony_ci					     u32 *nbytesp);
3178c2ecf20Sopenharmony_ci	int (*ce_revoke_recv_next)(struct ath10k_ce_pipe *ce_state,
3188c2ecf20Sopenharmony_ci				   void **per_transfer_contextp,
3198c2ecf20Sopenharmony_ci				   dma_addr_t *nbytesp);
3208c2ecf20Sopenharmony_ci	void (*ce_extract_desc_data)(struct ath10k *ar,
3218c2ecf20Sopenharmony_ci				     struct ath10k_ce_ring *src_ring,
3228c2ecf20Sopenharmony_ci				     u32 sw_index, dma_addr_t *bufferp,
3238c2ecf20Sopenharmony_ci				     u32 *nbytesp, u32 *transfer_idp);
3248c2ecf20Sopenharmony_ci	void (*ce_free_pipe)(struct ath10k *ar, int ce_id);
3258c2ecf20Sopenharmony_ci	int (*ce_send_nolock)(struct ath10k_ce_pipe *pipe,
3268c2ecf20Sopenharmony_ci			      void *per_transfer_context,
3278c2ecf20Sopenharmony_ci			      dma_addr_t buffer, u32 nbytes,
3288c2ecf20Sopenharmony_ci			      u32 transfer_id, u32 flags);
3298c2ecf20Sopenharmony_ci	void (*ce_set_src_ring_base_addr_hi)(struct ath10k *ar,
3308c2ecf20Sopenharmony_ci					     u32 ce_ctrl_addr,
3318c2ecf20Sopenharmony_ci					     u64 addr);
3328c2ecf20Sopenharmony_ci	void (*ce_set_dest_ring_base_addr_hi)(struct ath10k *ar,
3338c2ecf20Sopenharmony_ci					      u32 ce_ctrl_addr,
3348c2ecf20Sopenharmony_ci					      u64 addr);
3358c2ecf20Sopenharmony_ci	int (*ce_completed_send_next_nolock)(struct ath10k_ce_pipe *ce_state,
3368c2ecf20Sopenharmony_ci					     void **per_transfer_contextp);
3378c2ecf20Sopenharmony_ci};
3388c2ecf20Sopenharmony_ci
3398c2ecf20Sopenharmony_cistatic inline u32 ath10k_ce_base_address(struct ath10k *ar, unsigned int ce_id)
3408c2ecf20Sopenharmony_ci{
3418c2ecf20Sopenharmony_ci	return CE0_BASE_ADDRESS + (CE1_BASE_ADDRESS - CE0_BASE_ADDRESS) * ce_id;
3428c2ecf20Sopenharmony_ci}
3438c2ecf20Sopenharmony_ci
3448c2ecf20Sopenharmony_ci#define COPY_ENGINE_ID(COPY_ENGINE_BASE_ADDRESS) (((COPY_ENGINE_BASE_ADDRESS) \
3458c2ecf20Sopenharmony_ci		- CE0_BASE_ADDRESS) / (CE1_BASE_ADDRESS - CE0_BASE_ADDRESS))
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_ci#define CE_SRC_RING_TO_DESC(baddr, idx) \
3488c2ecf20Sopenharmony_ci	(&(((struct ce_desc *)baddr)[idx]))
3498c2ecf20Sopenharmony_ci
3508c2ecf20Sopenharmony_ci#define CE_DEST_RING_TO_DESC(baddr, idx) \
3518c2ecf20Sopenharmony_ci	(&(((struct ce_desc *)baddr)[idx]))
3528c2ecf20Sopenharmony_ci
3538c2ecf20Sopenharmony_ci#define CE_SRC_RING_TO_DESC_64(baddr, idx) \
3548c2ecf20Sopenharmony_ci	(&(((struct ce_desc_64 *)baddr)[idx]))
3558c2ecf20Sopenharmony_ci
3568c2ecf20Sopenharmony_ci#define CE_DEST_RING_TO_DESC_64(baddr, idx) \
3578c2ecf20Sopenharmony_ci	(&(((struct ce_desc_64 *)baddr)[idx]))
3588c2ecf20Sopenharmony_ci
3598c2ecf20Sopenharmony_ci/* Ring arithmetic (modulus number of entries in ring, which is a pwr of 2). */
3608c2ecf20Sopenharmony_ci#define CE_RING_DELTA(nentries_mask, fromidx, toidx) \
3618c2ecf20Sopenharmony_ci	(((int)(toidx) - (int)(fromidx)) & (nentries_mask))
3628c2ecf20Sopenharmony_ci
3638c2ecf20Sopenharmony_ci#define CE_RING_IDX_INCR(nentries_mask, idx) (((idx) + 1) & (nentries_mask))
3648c2ecf20Sopenharmony_ci#define CE_RING_IDX_ADD(nentries_mask, idx, num) \
3658c2ecf20Sopenharmony_ci		(((idx) + (num)) & (nentries_mask))
3668c2ecf20Sopenharmony_ci
3678c2ecf20Sopenharmony_ci#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB \
3688c2ecf20Sopenharmony_ci				ar->regs->ce_wrap_intr_sum_host_msi_lsb
3698c2ecf20Sopenharmony_ci#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK \
3708c2ecf20Sopenharmony_ci				ar->regs->ce_wrap_intr_sum_host_msi_mask
3718c2ecf20Sopenharmony_ci#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET(x) \
3728c2ecf20Sopenharmony_ci	(((x) & CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK) >> \
3738c2ecf20Sopenharmony_ci		CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB)
3748c2ecf20Sopenharmony_ci#define CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS			0x0000
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_cistatic inline u32 ath10k_ce_interrupt_summary(struct ath10k *ar)
3778c2ecf20Sopenharmony_ci{
3788c2ecf20Sopenharmony_ci	struct ath10k_ce *ce = ath10k_ce_priv(ar);
3798c2ecf20Sopenharmony_ci
3808c2ecf20Sopenharmony_ci	return CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET(
3818c2ecf20Sopenharmony_ci		ce->bus_ops->read32((ar), CE_WRAPPER_BASE_ADDRESS +
3828c2ecf20Sopenharmony_ci		CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS));
3838c2ecf20Sopenharmony_ci}
3848c2ecf20Sopenharmony_ci
3858c2ecf20Sopenharmony_ci/* Host software's Copy Engine configuration. */
3868c2ecf20Sopenharmony_ci#define CE_ATTR_FLAGS 0
3878c2ecf20Sopenharmony_ci
3888c2ecf20Sopenharmony_ci/*
3898c2ecf20Sopenharmony_ci * Configuration information for a Copy Engine pipe.
3908c2ecf20Sopenharmony_ci * Passed from Host to Target during startup (one per CE).
3918c2ecf20Sopenharmony_ci *
3928c2ecf20Sopenharmony_ci * NOTE: Structure is shared between Host software and Target firmware!
3938c2ecf20Sopenharmony_ci */
3948c2ecf20Sopenharmony_cistruct ce_pipe_config {
3958c2ecf20Sopenharmony_ci	__le32 pipenum;
3968c2ecf20Sopenharmony_ci	__le32 pipedir;
3978c2ecf20Sopenharmony_ci	__le32 nentries;
3988c2ecf20Sopenharmony_ci	__le32 nbytes_max;
3998c2ecf20Sopenharmony_ci	__le32 flags;
4008c2ecf20Sopenharmony_ci	__le32 reserved;
4018c2ecf20Sopenharmony_ci};
4028c2ecf20Sopenharmony_ci
4038c2ecf20Sopenharmony_ci/*
4048c2ecf20Sopenharmony_ci * Directions for interconnect pipe configuration.
4058c2ecf20Sopenharmony_ci * These definitions may be used during configuration and are shared
4068c2ecf20Sopenharmony_ci * between Host and Target.
4078c2ecf20Sopenharmony_ci *
4088c2ecf20Sopenharmony_ci * Pipe Directions are relative to the Host, so PIPEDIR_IN means
4098c2ecf20Sopenharmony_ci * "coming IN over air through Target to Host" as with a WiFi Rx operation.
4108c2ecf20Sopenharmony_ci * Conversely, PIPEDIR_OUT means "going OUT from Host through Target over air"
4118c2ecf20Sopenharmony_ci * as with a WiFi Tx operation. This is somewhat awkward for the "middle-man"
4128c2ecf20Sopenharmony_ci * Target since things that are "PIPEDIR_OUT" are coming IN to the Target
4138c2ecf20Sopenharmony_ci * over the interconnect.
4148c2ecf20Sopenharmony_ci */
4158c2ecf20Sopenharmony_ci#define PIPEDIR_NONE    0
4168c2ecf20Sopenharmony_ci#define PIPEDIR_IN      1  /* Target-->Host, WiFi Rx direction */
4178c2ecf20Sopenharmony_ci#define PIPEDIR_OUT     2  /* Host->Target, WiFi Tx direction */
4188c2ecf20Sopenharmony_ci#define PIPEDIR_INOUT   3  /* bidirectional */
4198c2ecf20Sopenharmony_ci
4208c2ecf20Sopenharmony_ci/* Establish a mapping between a service/direction and a pipe. */
4218c2ecf20Sopenharmony_cistruct ce_service_to_pipe {
4228c2ecf20Sopenharmony_ci	__le32 service_id;
4238c2ecf20Sopenharmony_ci	__le32 pipedir;
4248c2ecf20Sopenharmony_ci	__le32 pipenum;
4258c2ecf20Sopenharmony_ci};
4268c2ecf20Sopenharmony_ci
4278c2ecf20Sopenharmony_ci#endif /* _CE_H_ */
428