summaryrefslogtreecommitdiff
path: root/include/soc/qcom/glink.h
blob: cecd0c01d69ad69bde62f7877a01ad64d64af869 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
/* Copyright (c) 2014-2015,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_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 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);

/**
 * glink_start_rx_rt() - Vote for RT thread priority on RX.
 * @handle:	Channel handle for which transaction are occurring.
 *
 * Return: 0 on success, standard Linux error codes on failure
 */
int glink_start_rx_rt(void *handle);

/**
 * glink_end_rx_rt() - Vote for RT thread priority on RX.
 * @handle:	Channel handle for which transaction are occurring.
 *
 * Return: 0 on success, standard Linux error codes on failure
 */
int glink_end_rx_rt(void *handle);

#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;
}

static inline int glink_start_rx_rt(void *handle)
{
	return -ENODEV;
}

static inline int glink_end_rx_rt(void *handle)
{
	return -ENODEV;
}

#endif /* CONFIG_MSM_GLINK */
#endif /* _SOC_QCOM_GLINK_H_ */