| /* |
| * Copyright (c) 2013-2014, 2016-2017 The Linux Foundation. All rights reserved. |
| * |
| * Previously licensed under the ISC license by Qualcomm Atheros, Inc. |
| * |
| * |
| * Permission to use, copy, modify, and/or distribute this software for |
| * any purpose with or without fee is hereby granted, provided that the |
| * above copyright notice and this permission notice appear in all |
| * copies. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL |
| * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE |
| * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL |
| * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR |
| * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
| * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
| * PERFORMANCE OF THIS SOFTWARE. |
| */ |
| |
| /* |
| * This file was originally distributed by Qualcomm Atheros, Inc. |
| * under proprietary terms before Copyright ownership was assigned |
| * to the Linux Foundation. |
| */ |
| |
| #ifndef __COPY_ENGINE_API_H__ |
| #define __COPY_ENGINE_API_H__ |
| |
| #if defined(CONFIG_COPY_ENGINE_SUPPORT) |
| |
| /* TBDXXX: Use int return values for consistency with Target */ |
| |
| /* TBDXXX: Perhaps merge Host/Target-->common */ |
| |
| /* |
| * Copy Engine support: low-level Target-side Copy Engine API. |
| * This is a hardware access layer used by code that understands |
| * how to use copy engines. |
| */ |
| |
| /* |
| * A "struct CE_handle *" serves as an opaque pointer-sized |
| * handle to a specific copy engine. |
| */ |
| struct CE_handle; |
| |
| /* |
| * "Send Completion" callback type for Send Completion Notification. |
| * |
| * If a Send Completion callback is registered and one or more sends |
| * have completed, the callback is invoked. |
| * |
| * per_CE_send_context is a context supplied by the calling layer |
| * (via CE_send_cb_register). It is associated with a copy engine. |
| * |
| * per_transfer_send_context is context supplied by the calling layer |
| * (via the "send" call). It may be different for each invocation |
| * of send. |
| * |
| * The buffer parameter is the first byte sent of the first buffer |
| * sent (if more than one buffer). |
| * |
| * nbytes is the number of bytes of that buffer that were sent. |
| * |
| * transfer_id matches the value used when the buffer or |
| * buf_list was sent. |
| * |
| * Implementation note: Pops 1 completed send buffer from Source ring |
| */ |
| typedef void (* CE_send_cb)(struct CE_handle *copyeng, |
| void *per_CE_send_context, |
| void *per_transfer_send_context, |
| CE_addr_t buffer, |
| unsigned int nbytes, |
| unsigned int transfer_id, |
| unsigned int sw_index, |
| unsigned int hw_index); |
| |
| /* |
| * "Buffer Received" callback type for Buffer Received Notification. |
| * |
| * Implementation note: Pops 1 completed recv buffer from Dest ring |
| */ |
| typedef void (* CE_recv_cb)(struct CE_handle *copyeng, |
| void *per_CE_recv_context, |
| void *per_transfer_recv_context, |
| CE_addr_t buffer, |
| unsigned int nbytes, |
| unsigned int transfer_id, |
| unsigned int flags); |
| |
| /* |
| * Copy Engine Watermark callback type. |
| * |
| * Allows upper layers to be notified when watermarks are reached: |
| * space is available and/or running short in a source ring |
| * buffers are exhausted and/or abundant in a destination ring |
| * |
| * The flags parameter indicates which condition triggered this |
| * callback. See CE_WM_FLAG_*. |
| * |
| * Watermark APIs are provided to allow upper layers "batch" |
| * descriptor processing and to allow upper layers to |
| * throttle/unthrottle. |
| */ |
| typedef void (* CE_watermark_cb)(struct CE_handle *copyeng, |
| void *per_CE_wm_context, |
| unsigned int flags); |
| |
| #define CE_WM_FLAG_SEND_HIGH 1 |
| #define CE_WM_FLAG_SEND_LOW 2 |
| #define CE_WM_FLAG_RECV_HIGH 4 |
| #define CE_WM_FLAG_RECV_LOW 8 |
| |
| /* A list of buffers to be gathered and sent */ |
| struct CE_sendlist; |
| |
| /* Copy Engine settable attributes */ |
| struct CE_attr; |
| |
| /*==================Send======================================================*/ |
| |
| /* CE_send flags */ |
| /* disable ring's byte swap, even if the default policy is to swap */ |
| #define CE_SEND_FLAG_SWAP_DISABLE 1 |
| |
| /* |
| * Queue a source buffer to be sent to an anonymous destination buffer. |
| * copyeng - which copy engine to use |
| * buffer - address of buffer |
| * nbytes - number of bytes to send |
| * transfer_id - arbitrary ID; reflected to destination |
| * flags - CE_SEND_FLAG_* values |
| * Returns 0 on success; otherwise an error status. |
| * |
| * Note: If no flags are specified, use CE's default data swap mode. |
| * |
| * Implementation note: pushes 1 buffer to Source ring |
| */ |
| int CE_send(struct CE_handle *copyeng, |
| void *per_transfer_send_context, |
| CE_addr_t buffer, |
| unsigned int nbytes, |
| unsigned int transfer_id, /* 14 bits */ |
| unsigned int flags); |
| |
| |
| /* |
| * Register a Send Callback function. |
| * This function is called as soon as the contents of a Send |
| * have reached the destination, unless disable_interrupts is |
| * requested. In this case, the callback is invoked when the |
| * send status is polled, shortly after the send completes. |
| */ |
| void CE_send_cb_register(struct CE_handle *copyeng, |
| CE_send_cb fn_ptr, |
| void *per_CE_send_context, |
| int disable_interrupts); |
| |
| /* |
| * Return the size of a SendList. This allows the caller to allocate |
| * a SendList while the SendList structure remains opaque. |
| */ |
| unsigned int CE_sendlist_sizeof(void); |
| |
| /* Initialize a sendlist */ |
| void CE_sendlist_init(struct CE_sendlist *sendlist); |
| |
| /* Append a simple buffer (address/length) to a sendlist. */ |
| int CE_sendlist_buf_add(struct CE_sendlist *sendlist, |
| CE_addr_t buffer, |
| unsigned int nbytes, |
| u_int32_t flags /* OR-ed with internal flags */); |
| |
| /* |
| * Queue a "sendlist" of buffers to be sent using gather to a single |
| * anonymous destination buffer |
| * copyeng - 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 CE_sendlist_send(struct CE_handle *copyeng, |
| void *per_transfer_send_context, |
| struct CE_sendlist *sendlist, |
| unsigned int transfer_id); /* 14 bits */ |
| |
| /*==================Recv======================================================*/ |
| |
| /* |
| * Make a buffer available to receive. The buffer must be at least of a |
| * minimal size appropriate for this copy engine (src_sz_max attribute). |
| * copyeng - which copy engine to use |
| * per_transfer_recv_context - context passed back to caller's recv_cb |
| * buffer - address of buffer in CE space |
| * Returns 0 on success; otherwise an error status. |
| * |
| * Implemenation note: Pushes a buffer to Dest ring. |
| */ |
| int CE_recv_buf_enqueue(struct CE_handle *copyeng, |
| void *per_transfer_recv_context, |
| CE_addr_t buffer); |
| |
| /* |
| * Register a Receive Callback function. |
| * This function is called as soon as data is received |
| * from the source. |
| */ |
| void CE_recv_cb_register(struct CE_handle *copyeng, |
| CE_recv_cb fn_ptr, |
| void *per_CE_recv_context, |
| int disable_interrupts); |
| |
| /*==================CE Watermark==============================================*/ |
| |
| /* |
| * Register a Watermark Callback function. |
| * This function is called as soon as a watermark level |
| * is crossed. A Watermark Callback function is free to |
| * handle received data "en masse"; but then some coordination |
| * is required with a registered Receive Callback function. |
| * [Suggestion: Either handle Receives in a Receive Callback |
| * or en masse in a Watermark Callback; but not both.] |
| */ |
| void CE_watermark_cb_register(struct CE_handle *copyeng, |
| CE_watermark_cb fn_ptr, |
| void *per_CE_wm_context); |
| |
| /* |
| * Set low/high watermarks for the send/source side of a copy engine. |
| * |
| * Typically, the destination side CPU manages watermarks for |
| * the receive side and the source side CPU manages watermarks |
| * for the send side. |
| * |
| * A low watermark of 0 is never hit (so the watermark function |
| * will never be called for a Low Watermark condition). |
| * |
| * A high watermark equal to nentries is never hit (so the |
| * watermark function will never be called for a High Watermark |
| * condition). |
| */ |
| void CE_send_watermarks_set(struct CE_handle *copyeng, |
| unsigned int low_alert_nentries, |
| unsigned int high_alert_nentries); |
| |
| /* Set low/high watermarks for the receive/destination side of a copy engine. */ |
| void CE_recv_watermarks_set(struct CE_handle *copyeng, |
| unsigned int low_alert_nentries, |
| unsigned int high_alert_nentries); |
| |
| /* |
| * Return the number of entries that can be queued |
| * to a ring at an instant in time. |
| * |
| * For source ring, does not imply that destination-side |
| * buffers are available; merely indicates descriptor space |
| * in the source ring. |
| * |
| * For destination ring, does not imply that previously |
| * received buffers have been processed; merely indicates |
| * descriptor space in destination ring. |
| * |
| * Mainly for use with CE Watermark callback. |
| */ |
| unsigned int CE_send_entries_avail(struct CE_handle *copyeng); |
| unsigned int CE_recv_entries_avail(struct CE_handle *copyeng); |
| |
| /* |
| * Return the number of entries in the ring that are ready |
| * to be processed by software. |
| * |
| * For source ring, the number of descriptors that have |
| * been completed and can now be overwritten with new send |
| * descriptors. |
| * |
| * For destination ring, the number of descriptors that |
| * are available to be processed (newly received buffers). |
| */ |
| unsigned int CE_send_entries_done(struct CE_handle *copyeng); |
| unsigned int CE_recv_entries_done(struct CE_handle *copyeng); |
| |
| /* recv flags */ |
| /* Data is byte-swapped */ |
| #define CE_RECV_FLAG_SWAPPED 1 |
| |
| /* |
| * Supply data for the next completed unprocessed receive descriptor. |
| * |
| * For use |
| * with CE Watermark callback, |
| * in a recv_cb function when processing buf_lists |
| * in a recv_cb function in order to mitigate recv_cb's. |
| * |
| * Implemenation note: Pops buffer from Dest ring. |
| */ |
| int CE_completed_recv_next(struct CE_handle *copyeng, |
| void **per_CE_contextp, |
| void **per_transfer_contextp, |
| CE_addr_t *bufferp, |
| unsigned int *nbytesp, |
| unsigned int *transfer_idp, |
| unsigned int *flagsp); |
| |
| /* |
| * Supply data for the next completed unprocessed send descriptor. |
| * |
| * For use |
| * with CE Watermark callback |
| * in a send_cb function in order to mitigate send_cb's. |
| * |
| * Implementation note: Pops 1 completed send buffer from Source ring |
| */ |
| int CE_completed_send_next(struct CE_handle *copyeng, |
| void **per_CE_contextp, |
| void **per_transfer_contextp, |
| CE_addr_t *bufferp, |
| unsigned int *nbytesp, |
| unsigned int *transfer_idp, |
| unsigned int *sw_idx, |
| unsigned int *hw_idx); |
| |
| |
| /*==================CE Engine Initialization==================================*/ |
| |
| /* Initialize an instance of a CE */ |
| struct CE_handle *CE_init(struct hif_pci_softc *sc, |
| unsigned int CE_id, |
| struct CE_attr *attr); |
| |
| |
| /*==================CE Engine Shutdown========================================*/ |
| /* |
| * Support clean shutdown by allowing the caller to revoke |
| * receive buffers. Target DMA must be stopped before using |
| * this API. |
| */ |
| A_STATUS |
| CE_revoke_recv_next(struct CE_handle *copyeng, |
| void **per_CE_contextp, |
| void **per_transfer_contextp, |
| CE_addr_t *bufferp); |
| |
| /* |
| * Support clean shutdown by allowing the caller to cancel |
| * pending sends. Target DMA must be stopped before using |
| * this API. |
| */ |
| A_STATUS |
| CE_cancel_send_next(struct CE_handle *copyeng, |
| void **per_CE_contextp, |
| void **per_transfer_contextp, |
| CE_addr_t *bufferp, |
| unsigned int *nbytesp, |
| unsigned int *transfer_idp); |
| |
| void CE_fini(struct CE_handle *copyeng); |
| |
| /*==================CE Interrupt Handlers=====================================*/ |
| void CE_per_engine_service_any(int irq, void *arg); |
| void CE_per_engine_service(struct hif_pci_softc *sc, unsigned int CE_id); |
| void CE_per_engine_servicereap(struct hif_pci_softc *sc, unsigned int CE_id); |
| |
| /*===================CE cmpl interrupt Enable/Disable ============================*/ |
| void CE_disable_any_copy_compl_intr(struct hif_pci_softc *sc); |
| void CE_enable_any_copy_compl_intr(struct hif_pci_softc *sc); |
| void CE_disable_any_copy_compl_intr_nolock(struct hif_pci_softc *sc); |
| void CE_enable_any_copy_compl_intr_nolock(struct hif_pci_softc *sc); |
| |
| /* API to check if any of the copy engine pipes has pending frames for prcoessing */ |
| bool CE_get_rx_pending(struct hif_pci_softc *sc); |
| |
| int get_next_record_index(atomic_t *table_index, int array_size); |
| |
| /** |
| * ce_target_reset() - Trigger SSR |
| * @sc: hif layer handle |
| * |
| * Once hw error is hit, SSR would be triggered. |
| */ |
| void ce_target_reset(struct hif_pci_softc *sc); |
| |
| /* CE_attr.flags values */ |
| #define CE_ATTR_NO_SNOOP 0x01 /* Use NonSnooping PCIe accesses? */ |
| #define CE_ATTR_BYTE_SWAP_DATA 0x02 /* Byte swap data words */ |
| #define CE_ATTR_SWIZZLE_DESCRIPTORS 0x04 /* Swizzle descriptors? */ |
| #define CE_ATTR_DISABLE_INTR 0x08 /* no interrupt on copy completion */ |
| #define CE_ATTR_ENABLE_POLL 0x10 /* poll for residue descriptors */ |
| |
| /* Attributes of an instance of a Copy Engine */ |
| struct CE_attr { |
| unsigned int flags; /* CE_ATTR_* values */ |
| |
| unsigned int priority; /* TBD */ |
| |
| unsigned int src_nentries; /* #entries in source ring - |
| Must be a power of 2 */ |
| |
| unsigned int src_sz_max; /* Max source send size for this CE. |
| This is also the minimum size of |
| a destination buffer. */ |
| |
| unsigned int dest_nentries; /* #entries in destination ring - |
| Must be a power of 2 */ |
| |
| void *reserved; /* Future use */ |
| }; |
| |
| /* |
| * 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) |
| |
| /* |
| * This is an opaque type that is at least large enough to hold |
| * a sendlist. A sendlist can only be accessed through CE APIs, |
| * but this allows a sendlist to be allocated on the run-time |
| * stack. TBDXXX: un-opaque would be simpler... |
| */ |
| struct CE_sendlist { |
| unsigned int word[62]; |
| }; |
| |
| #define ATH_ISR_NOSCHED 0x0000 /* Do not schedule bottom half/DPC */ |
| #define ATH_ISR_SCHED 0x0001 /* Schedule the bottom half for execution */ |
| #define ATH_ISR_NOTMINE 0x0002 /* This was not my interrupt - for shared IRQ's */ |
| |
| #ifdef IPA_UC_OFFLOAD |
| /* |
| * Copy engine should release resource to micro controller |
| * Micro controller needs |
| - Copy engine source descriptor base address |
| - Copy engine source descriptor size |
| - PCI BAR address to access copy engine regiser |
| */ |
| void CE_ipaGetResource(struct CE_handle *ce, |
| a_uint32_t *ce_sr_base_paddr, |
| a_uint32_t *ce_sr_ring_size, |
| a_uint32_t *ce_reg_paddr); |
| #endif /* IPA_UC_OFFLOAD */ |
| |
| #endif /* CONFIG_COPY_ENGINE_SUPPORT */ |
| #endif /* __COPY_ENGINE_API_H__ */ |