blob: 7b864816f91f128d6eec5cc3efc379459bf1c60d [file] [log] [blame]
/* Copyright (c) 2014-2016, 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 <linux/types.h>
/* 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 int 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_ */