/* Copyright (c) 2014-2015, 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_H_ #define _SOC_QCOM_GLINK_H_ #include /* Maximum size (including null) for channel, edge, or transport names */ #define GLINK_NAME_SIZE 32 /* Maximum packet size for TX and RX */ #define GLINK_MAX_PKT_SIZE SZ_1M /** * G-Link Port State Notification Values */ enum { GLINK_CONNECTED, GLINK_LOCAL_DISCONNECTED, GLINK_REMOTE_DISCONNECTED, }; /** * G-Link Open Options * * Used to define the glink_open_config::options field which is passed into * glink_open(). */ enum { GLINK_OPT_INITIAL_XPORT = BIT(0), GLINK_OPT_RX_INTENT_NOTIF = BIT(1), }; /** * Open configuration. * * priv: Private data passed into user callbacks * options: Open option flags * rx_intent_req_timeout_ms: Timeout for requesting an RX intent, in * milliseconds; if set to 0, timeout is infinite * notify_rx: Receive notification function (required) * notify_tx_done: Transmit-done notification function (required) * notify_state: State-change notification (required) * notify_rx_intent_req: Receive intent request (optional) * notify_rxv: Receive notification function for vector buffers * (required if notify_rx is not provided) * notify_sig: Signal-change notification (optional) * notify_rx_tracer_pkt: Receive notification for tracer packet * notify_remote_rx_intent: Receive notification for remote-queued RX intent * * This structure is passed into the glink_open() call to setup * configuration handles. All unused fields should be set to 0. * * The structure is copied internally before the call to glink_open() returns. */ struct glink_open_config { void *priv; uint32_t options; const char *transport; const char *edge; const char *name; unsigned int rx_intent_req_timeout_ms; void (*notify_rx)(void *handle, const void *priv, const void *pkt_priv, const void *ptr, size_t size); void (*notify_tx_done)(void *handle, const void *priv, const void *pkt_priv, const void *ptr); void (*notify_state)(void *handle, const void *priv, unsigned event); bool (*notify_rx_intent_req)(void *handle, const void *priv, size_t req_size); void (*notify_rxv)(void *handle, const void *priv, const void *pkt_priv, void *iovec, size_t size, void * (*vbuf_provider)(void *iovec, size_t offset, size_t *size), void * (*pbuf_provider)(void *iovec, size_t offset, size_t *size)); void (*notify_rx_sigs)(void *handle, const void *priv, uint32_t old_sigs, uint32_t new_sigs); void (*notify_rx_abort)(void *handle, const void *priv, const void *pkt_priv); void (*notify_tx_abort)(void *handle, const void *priv, const void *pkt_priv); void (*notify_rx_tracer_pkt)(void *handle, const void *priv, const void *pkt_priv, const void *ptr, size_t size); void (*notify_remote_rx_intent)(void *handle, const void *priv, size_t size); }; enum glink_link_state { GLINK_LINK_STATE_UP, GLINK_LINK_STATE_DOWN, }; /** * Data structure containing information during Link State callback * transport: String identifying the transport. * edge: String identifying the edge. * link_state: Link state(UP?DOWN). */ struct glink_link_state_cb_info { const char *transport; const char *edge; enum glink_link_state link_state; }; /** * Data structure containing information for link state registration * transport: String identifying the transport. * edge: String identifying the edge. * glink_link_state_notif_cb: Callback function used to pass the event. */ struct glink_link_info { const char *transport; const char *edge; void (*glink_link_state_notif_cb)( struct glink_link_state_cb_info *cb_info, void *priv); }; enum tx_flags { GLINK_TX_REQ_INTENT = 0x1, GLINK_TX_SINGLE_THREADED = 0x2, GLINK_TX_TRACER_PKT = 0x4, GLINK_TX_ATOMIC = 0x8, }; #ifdef CONFIG_MSM_GLINK /** * Open GLINK channel. * * @cfg_ptr: Open configuration structure (the structure is copied before * glink_open returns). All unused fields should be zero-filled. * * This should not be called from link state callback context by clients. * It is recommended that client should invoke this function from their own * thread. * * Return: Pointer to channel on success, PTR_ERR() with standard Linux * error code on failure. */ void *glink_open(const struct glink_open_config *cfg_ptr); /** * glink_close() - Close a previously opened channel. * * @handle: handle to close * * Once the closing process has been completed, the GLINK_LOCAL_DISCONNECTED * state event will be sent and the channel can be reopened. * * Return: 0 on success; -EINVAL for invalid handle, -EBUSY is close is * already in progress, standard Linux Error code otherwise. */ int glink_close(void *handle); /** * glink_tx() - Transmit packet. * * @handle: handle returned by glink_open() * @pkt_priv: opaque data value that will be returned to client with * notify_tx_done notification * @data: pointer to the data * @size: size of data * @tx_flags: Flags to specify transmit specific options * * Return: -EINVAL for invalid handle; -EBUSY if channel isn't ready for * transmit operation (not fully opened); -EAGAIN if remote side * has not provided a receive intent that is big enough. */ int glink_tx(void *handle, void *pkt_priv, void *data, size_t size, uint32_t tx_flags); /** * glink_queue_rx_intent() - Register an intent to receive data. * * @handle: handle returned by glink_open() * @pkt_priv: opaque data type that is returned when a packet is received * size: maximum size of data to receive * * Return: 0 for success; standard Linux error code for failure case */ int glink_queue_rx_intent(void *handle, const void *pkt_priv, size_t size); /** * glink_rx_intent_exists() - Check if an intent of size exists. * * @handle: handle returned by glink_open() * @size: size of an intent to check or 0 for any intent * * Return: TRUE if an intent exists with greater than or equal to the size * else FALSE */ bool glink_rx_intent_exists(void *handle, size_t size); /** * glink_rx_done() - Return receive buffer to remote side. * * @handle: handle returned by glink_open() * @ptr: data pointer provided in the notify_rx() call * @reuse: if true, receive intent is re-used * * Return: 0 for success; standard Linux error code for failure case */ int glink_rx_done(void *handle, const void *ptr, bool reuse); /** * glink_txv() - Transmit a packet in vector form. * * @handle: handle returned by glink_open() * @pkt_priv: opaque data value that will be returned to client with * notify_tx_done notification * @iovec: pointer to the vector (must remain valid until notify_tx_done * notification) * @size: size of data/vector * @vbuf_provider: Client provided helper function to iterate the vector * in physical address space * @pbuf_provider: Client provided helper function to iterate the vector * in virtual address space * @tx_flags: Flags to specify transmit specific options * * Return: -EINVAL for invalid handle; -EBUSY if channel isn't ready for * transmit operation (not fully opened); -EAGAIN if remote side has * not provided a receive intent that is big enough. */ int glink_txv(void *handle, void *pkt_priv, void *iovec, size_t size, void * (*vbuf_provider)(void *iovec, size_t offset, size_t *size), void * (*pbuf_provider)(void *iovec, size_t offset, size_t *size), uint32_t tx_flags); /** * glink_sigs_set() - Set the local signals for the GLINK channel * * @handle: handle returned by glink_open() * @sigs: modified signal value * * Return: 0 for success; standard Linux error code for failure case */ int glink_sigs_set(void *handle, uint32_t sigs); /** * glink_sigs_local_get() - Get the local signals for the GLINK channel * * handle: handle returned by glink_open() * sigs: Pointer to hold the signals * * Return: 0 for success; standard Linux error code for failure case */ int glink_sigs_local_get(void *handle, uint32_t *sigs); /** * glink_sigs_remote_get() - Get the Remote signals for the GLINK channel * * handle: handle returned by glink_open() * sigs: Pointer to hold the signals * * Return: 0 for success; standard Linux error code for failure case */ int glink_sigs_remote_get(void *handle, uint32_t *sigs); /** * glink_register_link_state_cb() - Register for link state notification * @link_info: Data structure containing the link identification and callback. * @priv: Private information to be passed with the callback. * * This function is used to register a notifier to receive the updates about a * link's/transport's state. This notifier needs to be registered first before * an attempt to open a channel. * * Return: a reference to the notifier handle. */ void *glink_register_link_state_cb(struct glink_link_info *link_info, void *priv); /** * glink_unregister_link_state_cb() - Unregister the link state notification * notif_handle: Handle to be unregistered. * * This function is used to unregister a notifier to stop receiving the updates * about a link's/transport's state. */ void glink_unregister_link_state_cb(void *notif_handle); /** * glink_qos_latency() - Register the latency QoS requirement * @handle: Channel handle in which the latency is required. * @latency_us: Latency requirement in units of micro-seconds. * @pkt_size: Worst case packet size for which the latency is required. * * This function is used to register the latency requirement for a channel * and ensures that the latency requirement for this channel is met without * impacting the existing latency requirements of other channels. * * Return: 0 if QoS request is achievable, standard Linux error codes on error */ int glink_qos_latency(void *handle, unsigned long latency_us, size_t pkt_size); /** * glink_qos_cancel() - Cancel or unregister the QoS request * @handle: Channel handle for which the QoS request is cancelled. * * This function is used to cancel/unregister the QoS requests for a channel. * * Return: 0 on success, standard Linux error codes on failure */ int glink_qos_cancel(void *handle); /** * glink_qos_start() - Start of the transmission requiring QoS * @handle: Channel handle in which the transmit activity is performed. * * This function is called by the clients to indicate G-Link regarding the * start of the transmission which requires a certain QoS. The clients * must account for the QoS ramp time to ensure meeting the QoS. * * Return: 0 on success, standard Linux error codes on failure */ int glink_qos_start(void *handle); /** * glink_qos_get_ramp_time() - Get the QoS ramp time * @handle: Channel handle for which the QoS ramp time is required. * @pkt_size: Worst case packet size. * * This function is called by the clients to obtain the ramp time required * to meet the QoS requirements. * * Return: QoS ramp time is returned in units of micro-seconds */ unsigned long glink_qos_get_ramp_time(void *handle, size_t pkt_size); #else /* CONFIG_MSM_GLINK */ static inline void *glink_open(const struct glink_open_config *cfg_ptr) { return NULL; } static inline int glink_close(void *handle) { return -ENODEV; } static inline int glink_tx(void *handle, void *pkt_priv, void *data, size_t size, uint32_t tx_flags) { return -ENODEV; } static inline int glink_queue_rx_intent(void *handle, const void *pkt_priv, size_t size) { return -ENODEV; } static inline bool glink_rx_intent_exists(void *handle, size_t size) { return -ENODEV; } static inline int glink_rx_done(void *handle, const void *ptr, bool reuse) { return -ENODEV; } static inline int glink_txv(void *handle, void *pkt_priv, void *iovec, size_t size, void * (*vbuf_provider)(void *iovec, size_t offset, size_t *size), void * (*pbuf_provider)(void *iovec, size_t offset, size_t *size), uint32_t tx_flags) { return -ENODEV; } static inline int glink_sigs_set(void *handle, uint32_t sigs) { return -ENODEV; } static inline int glink_sigs_local_get(void *handle, uint32_t *sigs) { return -ENODEV; } static inline int glink_sigs_remote_get(void *handle, uint32_t *sigs) { return -ENODEV; } static inline void *glink_register_link_state_cb( struct glink_link_info *link_info, void *priv) { return NULL; } static inline void glink_unregister_link_state_cb(void *notif_handle) { } static inline int glink_qos_latency(void *handle, unsigned long latency_us, size_t pkt_size) { return -ENODEV; } static inline int glink_qos_cancel(void *handle) { return -ENODEV; } static inline int glink_qos_start(void *handle) { return -ENODEV; } static inline unsigned long glink_qos_get_ramp_time(void *handle, size_t pkt_size) { return 0; } #endif /* CONFIG_MSM_GLINK */ #endif /* _SOC_QCOM_GLINK_H_ */