| /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 and |
| * only version 2 as published by the Free Software Foundation. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| */ |
| #ifndef _SOC_QCOM_GLINK_XPRT_IF_H_ |
| #define _SOC_QCOM_GLINK_XPRT_IF_H_ |
| |
| #include <linux/bitops.h> |
| #include <linux/list.h> |
| #include <linux/types.h> |
| |
| struct glink_core_xprt_ctx; |
| struct glink_core_if; |
| struct channel_ctx; |
| struct glink_core_rx_intent; |
| |
| enum buf_type { |
| LINEAR = 0, |
| VECTOR, |
| }; |
| |
| enum xprt_ids { |
| SMEM_XPRT_ID = 100, |
| SPIV2_XPRT_ID = SMEM_XPRT_ID, |
| SMD_TRANS_XPRT_ID = 200, |
| LLOOP_XPRT_ID = 300, |
| MOCK_XPRT_HIGH_ID = 390, |
| MOCK_XPRT_ID = 400, |
| MOCK_XPRT_LOW_ID = 410, |
| }; |
| |
| #define GCAP_SIGNALS BIT(0) |
| #define GCAP_INTENTLESS BIT(1) |
| #define GCAP_TRACER_PKT BIT(2) |
| #define GCAP_AUTO_QUEUE_RX_INT BIT(3) |
| |
| /** |
| * struct glink_core_tx_pkt - Transmit Packet information |
| * @list_done: Index to the channel's transmit queue. |
| * @list_done: Index to the channel's acknowledgment queue. |
| * @pkt_priv: Private information specific to the packet. |
| * @data: Pointer to the buffer containing the data. |
| * @riid: Remote receive intent used to transmit the packet. |
| * @rcid: Remote channel receiving the packet. |
| * @size: Total size of the data in the packet. |
| * @tx_len: Data length to transmit in the current transmit slot. |
| * @size_remaining: Remaining size of the data in the packet. |
| * @intent_size: Receive intent size queued by the remote side. |
| * @tracer_pkt: Flag to indicate if the packet is a tracer packet. |
| * @iovec: Pointer to the vector buffer packet. |
| * @vprovider: Packet-specific virtual buffer provider function. |
| * @pprovider: Packet-specific physical buffer provider function. |
| * @cookie: Transport-specific cookie |
| * @pkt_ref: Active references to the packet. |
| */ |
| struct glink_core_tx_pkt { |
| struct list_head list_node; |
| struct list_head list_done; |
| const void *pkt_priv; |
| const void *data; |
| uint32_t riid; |
| uint32_t rcid; |
| uint32_t size; |
| uint32_t tx_len; |
| uint32_t size_remaining; |
| size_t intent_size; |
| bool tracer_pkt; |
| void *iovec; |
| void * (*vprovider)(void *iovec, size_t offset, size_t *size); |
| void * (*pprovider)(void *iovec, size_t offset, size_t *size); |
| void *cookie; |
| struct rwref_lock pkt_ref; |
| }; |
| |
| /** |
| * Note - each call to register the interface must pass a unique |
| * instance of this data. |
| */ |
| struct glink_transport_if { |
| /* Negotiation */ |
| void (*tx_cmd_version)(struct glink_transport_if *if_ptr, |
| uint32_t version, |
| uint32_t features); |
| void (*tx_cmd_version_ack)(struct glink_transport_if *if_ptr, |
| uint32_t version, |
| uint32_t features); |
| uint32_t (*set_version)(struct glink_transport_if *if_ptr, |
| uint32_t version, |
| uint32_t features); |
| |
| /* channel state */ |
| int (*tx_cmd_ch_open)(struct glink_transport_if *if_ptr, uint32_t lcid, |
| const char *name, uint16_t req_xprt); |
| int (*tx_cmd_ch_close)(struct glink_transport_if *if_ptr, |
| uint32_t lcid); |
| void (*tx_cmd_ch_remote_open_ack)(struct glink_transport_if *if_ptr, |
| uint32_t rcid, uint16_t xprt_resp); |
| void (*tx_cmd_ch_remote_close_ack)(struct glink_transport_if *if_ptr, |
| uint32_t rcid); |
| int (*ssr)(struct glink_transport_if *if_ptr); |
| |
| /* channel data */ |
| int (*allocate_rx_intent)(struct glink_transport_if *if_ptr, |
| size_t size, |
| struct glink_core_rx_intent *intent); |
| int (*deallocate_rx_intent)(struct glink_transport_if *if_ptr, |
| struct glink_core_rx_intent *intent); |
| /* Optional */ |
| int (*reuse_rx_intent)(struct glink_transport_if *if_ptr, |
| struct glink_core_rx_intent *intent); |
| |
| int (*tx_cmd_local_rx_intent)(struct glink_transport_if *if_ptr, |
| uint32_t lcid, size_t size, uint32_t liid); |
| void (*tx_cmd_local_rx_done)(struct glink_transport_if *if_ptr, |
| uint32_t lcid, uint32_t liid, bool reuse); |
| int (*tx)(struct glink_transport_if *if_ptr, uint32_t lcid, |
| struct glink_core_tx_pkt *pctx); |
| int (*tx_cmd_rx_intent_req)(struct glink_transport_if *if_ptr, |
| uint32_t lcid, size_t size); |
| int (*tx_cmd_remote_rx_intent_req_ack)( |
| struct glink_transport_if *if_ptr, |
| uint32_t lcid, bool granted); |
| int (*tx_cmd_set_sigs)(struct glink_transport_if *if_ptr, |
| uint32_t lcid, uint32_t sigs); |
| |
| /* Optional. If NULL at xprt registration, dummies will be used */ |
| int (*poll)(struct glink_transport_if *if_ptr, uint32_t lcid); |
| int (*mask_rx_irq)(struct glink_transport_if *if_ptr, uint32_t lcid, |
| bool mask, void *pstruct); |
| int (*wait_link_down)(struct glink_transport_if *if_ptr); |
| int (*tx_cmd_tracer_pkt)(struct glink_transport_if *if_ptr, |
| uint32_t lcid, struct glink_core_tx_pkt *pctx); |
| unsigned long (*get_power_vote_ramp_time)( |
| struct glink_transport_if *if_ptr, uint32_t state); |
| int (*power_vote)(struct glink_transport_if *if_ptr, uint32_t state); |
| int (*power_unvote)(struct glink_transport_if *if_ptr); |
| int (*rx_rt_vote)(struct glink_transport_if *if_ptr); |
| int (*rx_rt_unvote)(struct glink_transport_if *if_ptr); |
| /* |
| * Keep data pointers at the end of the structure after all function |
| * pointer to allow for in-place initialization. |
| */ |
| |
| /* private pointer for core */ |
| struct glink_core_xprt_ctx *glink_core_priv; |
| |
| /* core pointer (set during transport registration) */ |
| struct glink_core_if *glink_core_if_ptr; |
| }; |
| |
| #ifdef CONFIG_MSM_GLINK |
| |
| /** |
| * get_tx_vaddr() - Get the virtual address from which the tx has to be done |
| * @pctx: transmit packet context. |
| * @offset: offset into the packet. |
| * @tx_size: pointer to hold the length of the contiguous buffer |
| * space. |
| * |
| * Return: Address from which the tx has to be done. |
| */ |
| static inline void *get_tx_vaddr(struct glink_core_tx_pkt *pctx, size_t offset, |
| size_t *tx_size) |
| { |
| void *pdata; |
| |
| if (pctx->vprovider) { |
| return pctx->vprovider((void *)pctx->iovec, offset, tx_size); |
| } else if (pctx->pprovider) { |
| pdata = pctx->pprovider((void *)pctx->iovec, offset, tx_size); |
| return phys_to_virt((unsigned long)pdata); |
| } |
| return NULL; |
| } |
| |
| /** |
| * glink_xprt_name_to_id() - convert transport name to id |
| * @name: Name of the transport. |
| * @id: Assigned id. |
| * |
| * Return: 0 on success or standard Linux error code. |
| */ |
| int glink_xprt_name_to_id(const char *name, uint16_t *id); |
| |
| |
| #else /* CONFIG_MSM_GLINK */ |
| static inline void *get_tx_vaddr(struct glink_core_tx_pkt *pctx, size_t offset, |
| size_t *tx_size) |
| { |
| return NULL; |
| } |
| |
| static inline int glink_xprt_name_to_id(const char *name, uint16_t *id) |
| { |
| return -ENODEV; |
| } |
| |
| #endif /* CONFIG_MSM_GLINK */ |
| #endif /* _SOC_QCOM_GLINK_XPRT_IF_H_ */ |