blob: 67cd10649721cb491dd90f1e7c8a801e082c83e9 [file] [log] [blame]
Sridhar Parasurambf391322015-01-23 09:29:07 -08001/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
2
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions are
5met:
6 * Redistributions of source code must retain the above copyright
7 notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above
9 copyright notice, this list of conditions and the following
10 disclaimer in the documentation and/or other materials provided
11 with the distribution.
12 * Neither the name of The Linux Foundation nor the names of its
13 contributors may be used to endorse or promote products derived
14 from this software without specific prior written permission.
15
16THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*/
28
29#ifndef GLINK_CORE_IF_H
30#define GLINK_CORE_IF_H
31
32/**
33 * @file glink_core_if.h
34 *
35 * Public API for the transport abstraction layer to call into GLINK Core
36 */
37
38#ifdef __cplusplus
39extern "C" {
40#endif
41
42/*===========================================================================
43 INCLUDE FILES
44===========================================================================*/
45
46#include "smem_list.h"
47#include "glink.h"
48#include "glink_transport_if.h"
49#include "glink_os_utils.h"
50
51/*===========================================================================
52 MACRO DECLARATIONS
53===========================================================================*/
54
55/*===========================================================================
56 TYPE DECLARATIONS
57===========================================================================*/
58typedef struct glink_core_version glink_core_version_type;
59
Sridhar Parasurambf391322015-01-23 09:29:07 -080060/**
61 * Transport status
62 */
63typedef enum {
64 GLINK_XPORT_REGISTERED = 0,
65 GLINK_XPORT_NEGOTIATING,
66 GLINK_XPORT_LINK_UP,
67
68}glink_transport_status_type;
69
70struct glink_rx_intent {
71 /* Link needed for use with list APIs. Must be at the head of the struct */
72 smem_list_link_type link;
73
74 void *data; /* Pointer to the data buffer to be transmitted */
75 const void *pkt_priv; /* Per packet private data */
76 size_t size; /* Size of data buffer */
77 size_t used; /* Actual valid data in *data field */
78 size_t pkt_sz; /* Size of the packet */
79 uint32 iid; /* Intent ID */
80 void *iovec; /* Pointer to the data buffer to be transmitted */
Sridhar Parasuram3b058122015-05-11 16:15:03 -070081 boolean tracer_pkt; /* Specify if this intent is for tracer packet */
Sridhar Parasurambf391322015-01-23 09:29:07 -080082 glink_buffer_provider_fn vprovider; /* Buffer provider for virtual space */
83 glink_buffer_provider_fn pprovider; /* Buffer provider for physical space */
84};
Sridhar Parasurambf391322015-01-23 09:29:07 -080085
Sridhar Parasuram3b058122015-05-11 16:15:03 -070086/** Context of Tx activity for a transport */
87typedef struct glink_tx_xport_ctx_s {
88 os_event_type event; /* Event to signal Tx thread */
89 os_cs_type tx_q_cs; /* Lock to protect Tx queue */
90 smem_list_type tx_q; /* Tx channel queue */
91} glink_tx_xport_ctx_type;
Sridhar Parasurambf391322015-01-23 09:29:07 -080092
Sridhar Parasuram3b058122015-05-11 16:15:03 -070093/** G-Link Local channel states */
94typedef enum
95{
96 /** Local G-Link channel is fully closed */
97 GLINK_LOCAL_CH_CLOSED,
Sridhar Parasurambf391322015-01-23 09:29:07 -080098
Sridhar Parasuram3b058122015-05-11 16:15:03 -070099 /** Local G-Link channel opened channel and waiting for ACK from remote */
100 GLINK_LOCAL_CH_OPENING,
Sridhar Parasurambf391322015-01-23 09:29:07 -0800101
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700102 /** Local G-Link channel is fully opened */
103 GLINK_LOCAL_CH_OPENED,
Sridhar Parasurambf391322015-01-23 09:29:07 -0800104
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700105 /** Local G-Link channel closed the channel and waiting for ACK from remote */
106 GLINK_LOCAL_CH_CLOSING
Sridhar Parasurambf391322015-01-23 09:29:07 -0800107
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700108}glink_local_state_type;
Sridhar Parasurambf391322015-01-23 09:29:07 -0800109
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700110/** G-Link Remote channel states */
111typedef enum
112{
113 /** Remote G-Link channel is closed */
114 GLINK_REMOTE_CH_CLOSED,
115
116 /** Remote G-Link channel is opened */
117 GLINK_REMOTE_CH_OPENED,
118
119 /* Glink channel state when SSR is received from remote sub-system */
120 GLINK_REMOTE_CH_SSR_RESET
121
122}glink_remote_state_type;
Sridhar Parasurambf391322015-01-23 09:29:07 -0800123
124/** Indicates that transport is now ready to start negotiation using the
125 * v0 configuration. */
126typedef void (*link_up_fn)
127(
128 glink_transport_if_type *if_ptr /* Pointer to the interface instance */
129);
130
131/** Receive transport version for remote-initiated version negotiation */
132typedef void (*rx_cmd_version_fn)
133(
134 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
135 uint32 version, /* Version */
136 uint32 features /* Features */
137);
138
139/** Receive ACK to previous glink_transport_if_type::tx_cmd_version command */
140typedef void (*rx_cmd_version_ack_fn)
141(
142 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
143 uint32 version, /* Version */
144 uint32 features /* Features */
145);
146
147/** Sets the core version used by the transport; called after completing
148 * negotiation.*/
149typedef void (*set_core_version_fn)
150(
151 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
152 uint32 version /* Version */
153);
154
155/** Receive remote channel open request; expected response is
156 * glink_transport_if_type:: tx_cmd_ch_remote_open_ack */
157typedef void (*rx_cmd_ch_remote_open_fn)
158(
159 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
160 uint32 rcid, /* Remote channel ID */
161 const char *name, /* String name for the logical channel */
162 glink_xport_priority prio /* priority of xport */
163);
164
165/** This function is invoked by the transport in response to
166 * glink_transport_if_type:: tx_cmd_ch_open */
167typedef void (*rx_cmd_ch_open_ack_fn)
168(
169 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
170 uint32 lcid, /* Local channel ID */
171 glink_xport_priority prio
172);
173
174/** This function is invoked by the transport in response to
175 * glink_transport_if_type:: tx_cmd_ch_close */
176typedef void (*rx_cmd_ch_close_ack_fn)
177(
178 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
179 uint32 lcid /* Local channel ID */
180);
181
182/** Remote channel close request; will result in sending
183 * glink_transport_if_type:: tx_cmd_ch_remote_close_ack */
184typedef void (*rx_cmd_ch_remote_close_fn)
185(
186 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
187 uint32 rcid /* Remote channel ID */
188);
189
Sridhar Parasurambf391322015-01-23 09:29:07 -0800190/** Transport invokes this call on receiving remote RX intent */
191typedef void (*rx_cmd_remote_rx_intent_put_fn)
192(
193 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
194 uint32 rcid, /* Remote channel ID */
195 uint32 riid, /* Remote intent ID */
196 size_t size /* Size of receive intent */
197);
198
199/** Get receive packet context (if successful, should be followed by call to
200 rx_put_pkt_ctx) */
201typedef glink_rx_intent_type* (*rx_get_pkt_ctx_fn)
202(
203 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
204 uint32 rcid, /* Remote channel ID */
205 uint32 liid /* Local intent ID */
206);
207
208/** Receive a packet fragment (must have previously received an rx_cmd_rx_data
209 packet). */
210typedef void (*rx_put_pkt_ctx_fn)
211(
212 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
213 uint32 rcid, /* Remote channel ID */
214 glink_rx_intent_type *intent_ptr, /* Fragment ptr */
215 boolean complete /* True if pkt is complete */
216);
217
218/** Transport invokes this call to inform GLink that remote side is
219 * done with previous transmitted packet. */
220typedef void (*rx_cmd_tx_done_fn)
221(
222 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
223 uint32 rcid, /* Remote channel ID */
224 uint32 riid, /* Remote intent ID */
225 boolean reuse /* Reuse intent */
226);
227
228/** Remote side is requesting an RX intent */
229typedef void (*rx_cmd_remote_rx_intent_req_fn)
230(
231 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
232 uint32 rcid, /* Remote channel ID */
233 size_t size /* Size of the requested intent */
234);
235
236/** ACK to RX Intent Request */
237typedef void (*rx_cmd_rx_intent_req_ack_fn)
238(
239 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
240 uint32 rcid, /* Remote channel ID */
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700241 boolean granted /* True if RX Intent will be queued, false
Sridhar Parasurambf391322015-01-23 09:29:07 -0800242 if request will not be granted. */
243);
244
245/** If transport was full and could not continue a transmit operation,
246 * then it will call this function to notify the core that it is ready to
247 * resume transmission. */
248typedef void (*tx_resume_fn)
249(
250 glink_transport_if_type *if_ptr /* Pointer to the interface instance */
251);
252
253/** Received 32-bit signals value from remote side. It is passed on to
254 * the client */
255typedef void (*rx_cmd_remote_sigs_fn)
256(
257 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
258 uint32 rcid, /* Remote channel ID */
259 uint32 remote_sigs /* Remote control signals */
260);
261
262/** Channel open config verification */
263typedef boolean(*verify_open_cfg_fn)
264(
265 glink_channel_ctx_type *ch_ctx /* Pointer to the channel context */
266);
267
268/** Channel initialization */
269typedef glink_err_type (*channel_init_fn)
270(
271 glink_channel_ctx_type *open_ch_ctx /* Pointer to the channel context */
272);
273
274/** Channel cleanup */
275typedef void (*channel_cleanup_fn)
276(
277 glink_channel_ctx_type *open_ch_ctx /* Pointer to the channel context */
278);
279
280/** Channel receive pkt */
281typedef void(*channel_receive_pkt_fn)
282(
283 glink_channel_ctx_type *open_ch_ctx, /* Pointer to the channel context */
284 glink_rx_intent_type *intent_ptr /* Pointer to the intent context */
285);
286
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700287/** Channel submit pkt */
288typedef glink_err_type(*channel_submit_pkt_fn)
Sridhar Parasurambf391322015-01-23 09:29:07 -0800289(
290 glink_channel_ctx_type *open_ch_ctx, /* Pointer to the channel context */
291 glink_core_tx_pkt_type *pctx, /* Pointer to the packet context */
292 boolean req_intent /* Request intent flag */
293);
294
295
296/** Transport specific data pointer that transport may choose fill in
297 * with some data */
298struct glink_core_xport_ctx
299{
300 /* Transport name */
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700301 const char *xport;
Sridhar Parasurambf391322015-01-23 09:29:07 -0800302
303 /* Remote subsystem name */
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700304 const char *remote_ss;
Sridhar Parasurambf391322015-01-23 09:29:07 -0800305
306 /** Keep track of version array index in use */
307 const glink_core_version_type *version_array;
308
309 /** Keep track of version array index in use */
310 uint32 version_indx;
311
312 /* Keeps track of the current status of the transport */
313 glink_transport_status_type status;
314
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700315 /* critical section to change/access xport status
316 * automically */
317 os_cs_type status_cs;
318
Sridhar Parasurambf391322015-01-23 09:29:07 -0800319 /* Transport's capabilities */
320 uint32 xport_capabilities;
321
322 /* Free lcid */
323 uint32 free_lcid;
324
325 /* Keeps track of the open channels for this transport/edge combination */
326 smem_list_type open_list;
327
328 /* Critical section to protect access to open_list */
329 os_cs_type channel_q_cs;
330
331 /* Local channel intents queued so far. This also helps determining liid
332 * when client queues new rx intents locally */
333 uint32 liid;
334
335 /* Critical section to protect access to liid allocation */
336 os_cs_type liid_cs;
337
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700338 /* Context of Tx activity for a transport */
339 glink_tx_xport_ctx_type *tx_ctx;
340
Sridhar Parasurambf391322015-01-23 09:29:07 -0800341 /* channel open config verification */
342 verify_open_cfg_fn verify_open_cfg;
343
344 /* channel init function */
345 channel_init_fn channel_init;
346
347 /* channel cleanup function */
348 channel_cleanup_fn channel_cleanup;
349
350 /* channel receive pkt */
351 channel_receive_pkt_fn channel_receive_pkt;
352
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700353 /* channel submit pkt */
354 channel_submit_pkt_fn channel_submit_pkt;
Sridhar Parasurambf391322015-01-23 09:29:07 -0800355};
356
357/**
358 * Data Structure for Transport abstraction layer to call into GLink Core
359 * for logical channel control state update and data Tx/Rx notifications.
360 */
361struct glink_core_if
362{
363 /** Indicates that transport is now ready to start negotiation using the
364 * v0 configuration. */
365 link_up_fn link_up;
366
367
368 /** Receive transport version for remote-initiated version negotiation */
369 rx_cmd_version_fn rx_cmd_version;
370
371
372 /** Receive ACK to previous glink_transport_if_type::tx_cmd_version command */
373 rx_cmd_version_ack_fn rx_cmd_version_ack;
374
375 /** Sets the core version used by the transport; called after completing
376 * negotiation.*/
377 set_core_version_fn set_core_version;
378
379 /** Receive remote channel open request; expected response is
380 * glink_transport_if_type:: tx_cmd_ch_remote_open_ack */
381 rx_cmd_ch_remote_open_fn rx_cmd_ch_remote_open;
382
Sridhar Parasurambf391322015-01-23 09:29:07 -0800383 /** This function is invoked by the transport in response to
384 * glink_transport_if_type:: tx_cmd_ch_open */
385 rx_cmd_ch_open_ack_fn rx_cmd_ch_open_ack;
386
Sridhar Parasurambf391322015-01-23 09:29:07 -0800387 /** This function is invoked by the transport in response to
388 * glink_transport_if_type:: tx_cmd_ch_close */
389 rx_cmd_ch_close_ack_fn rx_cmd_ch_close_ack;
390
Sridhar Parasurambf391322015-01-23 09:29:07 -0800391 /** Remote channel close request; will result in sending
392 * glink_transport_if_type:: tx_cmd_ch_remote_close_ack */
393 rx_cmd_ch_remote_close_fn rx_cmd_ch_remote_close;
394
Sridhar Parasurambf391322015-01-23 09:29:07 -0800395 /** Transport invokes this call on receiving remote RX intent */
396 rx_cmd_remote_rx_intent_put_fn rx_cmd_remote_rx_intent_put;
397
398 /** Get receive packet context (if successful, should be followed by call to
399 rx_put_pkt_ctx) */
400 rx_get_pkt_ctx_fn rx_get_pkt_ctx;
401
402 /** Receive a packet fragment (must have previously received an rx_cmd_rx_data
403 packet). */
404 rx_put_pkt_ctx_fn rx_put_pkt_ctx;
405
406 /** Transport invokes this call to inform GLink that remote side is
407 * done with previous transmitted packet. */
408 rx_cmd_tx_done_fn rx_cmd_tx_done;
409
410 /** Remote side is requesting an RX intent */
411 rx_cmd_remote_rx_intent_req_fn rx_cmd_remote_rx_intent_req;
412
413 /** ACK to RX Intent Request */
414 rx_cmd_rx_intent_req_ack_fn rx_cmd_rx_intent_req_ack;
415
416 /** Received 32-bit signals value from remote side. It is passed on to
417 * the client */
418 rx_cmd_remote_sigs_fn rx_cmd_remote_sigs;
419
420 /** If transport was full and could not continue a transmit operation,
421 * then it will call this function to notify the core that it is ready to
422 * resume transmission. */
423 tx_resume_fn tx_resume;
424};
425
426/** Feature negotiation function. The version negotiation starts out using
427 * the full feature set from the features element and then calls this
428 * function with a subset passed into the features argument. This
429 * function should filter passed in features with the supported feature
430 * set. For simple cases, a bitwise AND can be used, but for more
431 * complicated cases (such as when features are mutually exclusive),
432 * this function enables a more complex negotiation sequence.
433 */
434typedef uint32 (*negotiate_features_fn)
435(
436 glink_transport_if_type *if_ptr, /* Pointer to the interface
437 instance */
438 const glink_core_version_type *version_ptr, /* Version structure */
439 uint32 features /* Subset of features based on
440 negotiation */
441);
442
443/**
444 * Version structure
445 */
446struct glink_core_version {
447 uint32 version; /* Version number */
448 uint32 features; /* Set of features supported in
449 this version */
450
451 /** Feature negotiation function. The version negotiation starts out using
452 * the full feature set from the features element and then calls this
453 * function with a subset passed into the features argument. This
454 * function should filter passed in features with the supported feature
455 * set. For simple cases, a bitwise AND can be used, but for more
456 * complicated cases (such as when features are mutually exclusive),
457 * this function enables a more complex negotiation sequence.
458 */
459 negotiate_features_fn negotiate_features;
460};
461
462/**
463 * Data Structure for Transport abstraction layer to call into GLink Core
464 * while registering with GLink
465 */
466typedef struct {
467 const char *name; /* Name of the transport */
468 const char *remote_ss; /* Remote host name */
469 const glink_core_version_type *version; /* Array of supported versions */
470 size_t version_count; /* Number of elements in version[] */
471 uint32 max_cid; /* Max channel ID supported by
472 transport */
473 uint32 max_iid; /* Max Rx intent ID supported by
474 transport */
475}glink_core_transport_cfg_type;
476
477/*===========================================================================
478 PUBLIC FUNCTION DECLARATIONS
479===========================================================================*/
480/*===========================================================================
481FUNCTION glink_core_register_transport
482
483DESCRIPTION Transport calls this API to register its interface with GLINK
484 Core
485
486ARGUMENTS *if_ptr Pointer to interface instance; must be unique
487 for each edge
488
489 *cfg Pointer to transport configuration structure.
490
491RETURN VALUE Standard GLINK error codes.
492
493SIDE EFFECTS None
494===========================================================================*/
495
496glink_err_type glink_core_register_transport
497(
498 glink_transport_if_type *if_ptr,
499 glink_core_transport_cfg_type *cfg
500);
501
502#endif //GLINK_CORE_IF_H
503