blob: fd4d6be58631cb7ca60c6b6dee412617badd4238 [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===========================================================================*/
Sridhar Parasurambf391322015-01-23 09:29:07 -080045#include "smem_list.h"
46#include "glink.h"
47#include "glink_transport_if.h"
48#include "glink_os_utils.h"
49
50/*===========================================================================
51 MACRO DECLARATIONS
52===========================================================================*/
Steven Cahail7af13a02015-08-24 16:40:24 -060053/* Limit of the proportion of total QoS requests
54 =GLINK_QOS_RATE_LIMIT_COEFF_N / GLINK_QOS_RATE_LIMIT_COEFF_D
55 */
56#define GLINK_QOS_RATE_LIMIT_COEFF_N 7
57#define GLINK_QOS_RATE_LIMIT_COEFF_D 10
Steven Cahail79783352015-08-20 15:24:04 -060058
59/* Number of QoS tokens given at refill */
60#define GLINK_QOS_TOKENS (10)
61
62/* Number of QoS buckets */
63#define GLINK_QOS_BUCKETS (1)
Sridhar Parasurambf391322015-01-23 09:29:07 -080064
65/*===========================================================================
66 TYPE DECLARATIONS
67===========================================================================*/
68typedef struct glink_core_version glink_core_version_type;
69
Sridhar Parasurambf391322015-01-23 09:29:07 -080070/**
71 * Transport status
72 */
73typedef enum {
74 GLINK_XPORT_REGISTERED = 0,
75 GLINK_XPORT_NEGOTIATING,
76 GLINK_XPORT_LINK_UP,
77
78}glink_transport_status_type;
79
80struct glink_rx_intent {
81 /* Link needed for use with list APIs. Must be at the head of the struct */
82 smem_list_link_type link;
83
84 void *data; /* Pointer to the data buffer to be transmitted */
85 const void *pkt_priv; /* Per packet private data */
86 size_t size; /* Size of data buffer */
87 size_t used; /* Actual valid data in *data field */
88 size_t pkt_sz; /* Size of the packet */
89 uint32 iid; /* Intent ID */
90 void *iovec; /* Pointer to the data buffer to be transmitted */
Sridhar Parasuram3b058122015-05-11 16:15:03 -070091 boolean tracer_pkt; /* Specify if this intent is for tracer packet */
Sridhar Parasurambf391322015-01-23 09:29:07 -080092 glink_buffer_provider_fn vprovider; /* Buffer provider for virtual space */
93 glink_buffer_provider_fn pprovider; /* Buffer provider for physical space */
94};
Sridhar Parasurambf391322015-01-23 09:29:07 -080095
Sridhar Parasuram3b058122015-05-11 16:15:03 -070096/** Context of Tx activity for a transport */
97typedef struct glink_tx_xport_ctx_s {
98 os_event_type event; /* Event to signal Tx thread */
99 os_cs_type tx_q_cs; /* Lock to protect Tx queue */
100 smem_list_type tx_q; /* Tx channel queue */
Steven Cahail79783352015-08-20 15:24:04 -0600101 uint32 qos_rate_sum; /* Sum of rates of registered QoS requests */
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700102} glink_tx_xport_ctx_type;
Sridhar Parasurambf391322015-01-23 09:29:07 -0800103
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700104/** G-Link Local channel states */
105typedef enum
106{
Steven Cahail338e2f22015-08-24 15:11:53 -0600107 /** Initial State before entering channel state machine */
108 GLINK_LOCAL_CH_INIT,
109
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700110 /** Local G-Link channel is fully closed */
111 GLINK_LOCAL_CH_CLOSED,
Sridhar Parasurambf391322015-01-23 09:29:07 -0800112
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700113 /** Local G-Link channel opened channel and waiting for ACK from remote */
114 GLINK_LOCAL_CH_OPENING,
Sridhar Parasurambf391322015-01-23 09:29:07 -0800115
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700116 /** Local G-Link channel is fully opened */
117 GLINK_LOCAL_CH_OPENED,
Sridhar Parasurambf391322015-01-23 09:29:07 -0800118
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700119 /** Local G-Link channel closed the channel and waiting for ACK from remote */
120 GLINK_LOCAL_CH_CLOSING
Sridhar Parasurambf391322015-01-23 09:29:07 -0800121
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700122}glink_local_state_type;
Sridhar Parasurambf391322015-01-23 09:29:07 -0800123
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700124/** G-Link Remote channel states */
125typedef enum
126{
Steven Cahail338e2f22015-08-24 15:11:53 -0600127 /** Initial State before entering channel state machine */
128 GLINK_REMOTE_CH_INIT,
129
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700130 /** Remote G-Link channel is closed */
131 GLINK_REMOTE_CH_CLOSED,
132
133 /** Remote G-Link channel is opened */
134 GLINK_REMOTE_CH_OPENED,
135
136 /* Glink channel state when SSR is received from remote sub-system */
Steven Cahail79783352015-08-20 15:24:04 -0600137 GLINK_REMOTE_CH_SSR_RESET,
138
139 /** G-Link channel is pending cleanup.
140 This state is used for deferred channel cleanup in case
141 it sits in Tx scheduler queue */
Steven Cahail338e2f22015-08-24 15:11:53 -0600142 GLINK_REMOTE_CH_CLEANUP
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700143
144}glink_remote_state_type;
Sridhar Parasurambf391322015-01-23 09:29:07 -0800145
146/** Indicates that transport is now ready to start negotiation using the
147 * v0 configuration. */
148typedef void (*link_up_fn)
149(
150 glink_transport_if_type *if_ptr /* Pointer to the interface instance */
151);
152
153/** Receive transport version for remote-initiated version negotiation */
154typedef void (*rx_cmd_version_fn)
155(
156 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
157 uint32 version, /* Version */
158 uint32 features /* Features */
159);
160
161/** Receive ACK to previous glink_transport_if_type::tx_cmd_version command */
162typedef void (*rx_cmd_version_ack_fn)
163(
164 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
165 uint32 version, /* Version */
166 uint32 features /* Features */
167);
168
Sridhar Parasurambf391322015-01-23 09:29:07 -0800169/** Receive remote channel open request; expected response is
170 * glink_transport_if_type:: tx_cmd_ch_remote_open_ack */
171typedef void (*rx_cmd_ch_remote_open_fn)
172(
173 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
174 uint32 rcid, /* Remote channel ID */
175 const char *name, /* String name for the logical channel */
176 glink_xport_priority prio /* priority of xport */
177);
178
179/** This function is invoked by the transport in response to
180 * glink_transport_if_type:: tx_cmd_ch_open */
181typedef void (*rx_cmd_ch_open_ack_fn)
182(
183 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
184 uint32 lcid, /* Local channel ID */
185 glink_xport_priority prio
186);
187
188/** This function is invoked by the transport in response to
189 * glink_transport_if_type:: tx_cmd_ch_close */
190typedef void (*rx_cmd_ch_close_ack_fn)
191(
192 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
193 uint32 lcid /* Local channel ID */
194);
195
196/** Remote channel close request; will result in sending
197 * glink_transport_if_type:: tx_cmd_ch_remote_close_ack */
198typedef void (*rx_cmd_ch_remote_close_fn)
199(
200 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
201 uint32 rcid /* Remote channel ID */
202);
203
Sridhar Parasurambf391322015-01-23 09:29:07 -0800204/** Transport invokes this call on receiving remote RX intent */
205typedef void (*rx_cmd_remote_rx_intent_put_fn)
206(
207 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
208 uint32 rcid, /* Remote channel ID */
209 uint32 riid, /* Remote intent ID */
210 size_t size /* Size of receive intent */
211);
212
213/** Get receive packet context (if successful, should be followed by call to
214 rx_put_pkt_ctx) */
215typedef glink_rx_intent_type* (*rx_get_pkt_ctx_fn)
216(
217 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
218 uint32 rcid, /* Remote channel ID */
219 uint32 liid /* Local intent ID */
220);
221
222/** Receive a packet fragment (must have previously received an rx_cmd_rx_data
223 packet). */
224typedef void (*rx_put_pkt_ctx_fn)
225(
226 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
227 uint32 rcid, /* Remote channel ID */
228 glink_rx_intent_type *intent_ptr, /* Fragment ptr */
229 boolean complete /* True if pkt is complete */
230);
231
232/** Transport invokes this call to inform GLink that remote side is
233 * done with previous transmitted packet. */
234typedef void (*rx_cmd_tx_done_fn)
235(
236 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
237 uint32 rcid, /* Remote channel ID */
238 uint32 riid, /* Remote intent ID */
239 boolean reuse /* Reuse intent */
240);
241
242/** Remote side is requesting an RX intent */
243typedef void (*rx_cmd_remote_rx_intent_req_fn)
244(
245 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
246 uint32 rcid, /* Remote channel ID */
247 size_t size /* Size of the requested intent */
248);
249
250/** ACK to RX Intent Request */
251typedef void (*rx_cmd_rx_intent_req_ack_fn)
252(
253 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
254 uint32 rcid, /* Remote channel ID */
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700255 boolean granted /* True if RX Intent will be queued, false
Sridhar Parasurambf391322015-01-23 09:29:07 -0800256 if request will not be granted. */
257);
258
259/** If transport was full and could not continue a transmit operation,
260 * then it will call this function to notify the core that it is ready to
261 * resume transmission. */
262typedef void (*tx_resume_fn)
263(
264 glink_transport_if_type *if_ptr /* Pointer to the interface instance */
265);
266
267/** Received 32-bit signals value from remote side. It is passed on to
268 * the client */
269typedef void (*rx_cmd_remote_sigs_fn)
270(
271 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
272 uint32 rcid, /* Remote channel ID */
273 uint32 remote_sigs /* Remote control signals */
274);
275
276/** Channel open config verification */
277typedef boolean(*verify_open_cfg_fn)
278(
279 glink_channel_ctx_type *ch_ctx /* Pointer to the channel context */
280);
281
282/** Channel initialization */
283typedef glink_err_type (*channel_init_fn)
284(
285 glink_channel_ctx_type *open_ch_ctx /* Pointer to the channel context */
286);
287
288/** Channel cleanup */
289typedef void (*channel_cleanup_fn)
290(
291 glink_channel_ctx_type *open_ch_ctx /* Pointer to the channel context */
292);
293
294/** Channel receive pkt */
295typedef void(*channel_receive_pkt_fn)
296(
297 glink_channel_ctx_type *open_ch_ctx, /* Pointer to the channel context */
298 glink_rx_intent_type *intent_ptr /* Pointer to the intent context */
299);
300
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700301/** Channel submit pkt */
302typedef glink_err_type(*channel_submit_pkt_fn)
Sridhar Parasurambf391322015-01-23 09:29:07 -0800303(
304 glink_channel_ctx_type *open_ch_ctx, /* Pointer to the channel context */
305 glink_core_tx_pkt_type *pctx, /* Pointer to the packet context */
306 boolean req_intent /* Request intent flag */
307);
308
309
310/** Transport specific data pointer that transport may choose fill in
311 * with some data */
312struct glink_core_xport_ctx
313{
314 /* Transport name */
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700315 const char *xport;
Sridhar Parasurambf391322015-01-23 09:29:07 -0800316
317 /* Remote subsystem name */
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700318 const char *remote_ss;
Sridhar Parasurambf391322015-01-23 09:29:07 -0800319
320 /** Keep track of version array index in use */
321 const glink_core_version_type *version_array;
322
323 /** Keep track of version array index in use */
Steven Cahail7af13a02015-08-24 16:40:24 -0600324 int32 version_indx;
Sridhar Parasurambf391322015-01-23 09:29:07 -0800325
326 /* Keeps track of the current status of the transport */
327 glink_transport_status_type status;
328
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700329 /* critical section to change/access xport status
330 * automically */
331 os_cs_type status_cs;
332
Sridhar Parasurambf391322015-01-23 09:29:07 -0800333 /* Transport's capabilities */
334 uint32 xport_capabilities;
335
Steven Cahail79783352015-08-20 15:24:04 -0600336 /* Max lcid */
337 uint32 max_lcid;
338
Sridhar Parasurambf391322015-01-23 09:29:07 -0800339 /* Free lcid */
340 uint32 free_lcid;
341
342 /* Keeps track of the open channels for this transport/edge combination */
343 smem_list_type open_list;
344
Steven Cahailef08a382015-08-24 17:11:51 -0600345 /* Critical section to protect access to open_list and channel state of all
346 channels in that open_list */
Sridhar Parasurambf391322015-01-23 09:29:07 -0800347 os_cs_type channel_q_cs;
348
349 /* Local channel intents queued so far. This also helps determining liid
350 * when client queues new rx intents locally */
351 uint32 liid;
352
353 /* Critical section to protect access to liid allocation */
354 os_cs_type liid_cs;
355
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700356 /* Context of Tx activity for a transport */
357 glink_tx_xport_ctx_type *tx_ctx;
358
Sridhar Parasurambf391322015-01-23 09:29:07 -0800359 /* channel open config verification */
360 verify_open_cfg_fn verify_open_cfg;
361
362 /* channel init function */
363 channel_init_fn channel_init;
364
365 /* channel cleanup function */
366 channel_cleanup_fn channel_cleanup;
367
368 /* channel receive pkt */
369 channel_receive_pkt_fn channel_receive_pkt;
370
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700371 /* channel submit pkt */
372 channel_submit_pkt_fn channel_submit_pkt;
Sridhar Parasurambf391322015-01-23 09:29:07 -0800373};
374
375/**
376 * Data Structure for Transport abstraction layer to call into GLink Core
377 * for logical channel control state update and data Tx/Rx notifications.
378 */
379struct glink_core_if
380{
381 /** Indicates that transport is now ready to start negotiation using the
382 * v0 configuration. */
383 link_up_fn link_up;
384
385
386 /** Receive transport version for remote-initiated version negotiation */
387 rx_cmd_version_fn rx_cmd_version;
388
389
390 /** Receive ACK to previous glink_transport_if_type::tx_cmd_version command */
391 rx_cmd_version_ack_fn rx_cmd_version_ack;
392
Sridhar Parasurambf391322015-01-23 09:29:07 -0800393 /** Receive remote channel open request; expected response is
394 * glink_transport_if_type:: tx_cmd_ch_remote_open_ack */
395 rx_cmd_ch_remote_open_fn rx_cmd_ch_remote_open;
396
Sridhar Parasurambf391322015-01-23 09:29:07 -0800397 /** This function is invoked by the transport in response to
398 * glink_transport_if_type:: tx_cmd_ch_open */
399 rx_cmd_ch_open_ack_fn rx_cmd_ch_open_ack;
400
Sridhar Parasurambf391322015-01-23 09:29:07 -0800401 /** This function is invoked by the transport in response to
402 * glink_transport_if_type:: tx_cmd_ch_close */
403 rx_cmd_ch_close_ack_fn rx_cmd_ch_close_ack;
404
Sridhar Parasurambf391322015-01-23 09:29:07 -0800405 /** Remote channel close request; will result in sending
406 * glink_transport_if_type:: tx_cmd_ch_remote_close_ack */
407 rx_cmd_ch_remote_close_fn rx_cmd_ch_remote_close;
408
Sridhar Parasurambf391322015-01-23 09:29:07 -0800409 /** Transport invokes this call on receiving remote RX intent */
410 rx_cmd_remote_rx_intent_put_fn rx_cmd_remote_rx_intent_put;
411
412 /** Get receive packet context (if successful, should be followed by call to
413 rx_put_pkt_ctx) */
414 rx_get_pkt_ctx_fn rx_get_pkt_ctx;
415
416 /** Receive a packet fragment (must have previously received an rx_cmd_rx_data
417 packet). */
418 rx_put_pkt_ctx_fn rx_put_pkt_ctx;
419
420 /** Transport invokes this call to inform GLink that remote side is
421 * done with previous transmitted packet. */
422 rx_cmd_tx_done_fn rx_cmd_tx_done;
423
424 /** Remote side is requesting an RX intent */
425 rx_cmd_remote_rx_intent_req_fn rx_cmd_remote_rx_intent_req;
426
427 /** ACK to RX Intent Request */
428 rx_cmd_rx_intent_req_ack_fn rx_cmd_rx_intent_req_ack;
429
430 /** Received 32-bit signals value from remote side. It is passed on to
431 * the client */
432 rx_cmd_remote_sigs_fn rx_cmd_remote_sigs;
433
434 /** If transport was full and could not continue a transmit operation,
435 * then it will call this function to notify the core that it is ready to
436 * resume transmission. */
437 tx_resume_fn tx_resume;
438};
439
440/** Feature negotiation function. The version negotiation starts out using
441 * the full feature set from the features element and then calls this
442 * function with a subset passed into the features argument. This
443 * function should filter passed in features with the supported feature
444 * set. For simple cases, a bitwise AND can be used, but for more
445 * complicated cases (such as when features are mutually exclusive),
446 * this function enables a more complex negotiation sequence.
447 */
448typedef uint32 (*negotiate_features_fn)
449(
450 glink_transport_if_type *if_ptr, /* Pointer to the interface
451 instance */
452 const glink_core_version_type *version_ptr, /* Version structure */
453 uint32 features /* Subset of features based on
454 negotiation */
455);
456
457/**
458 * Version structure
459 */
460struct glink_core_version {
461 uint32 version; /* Version number */
462 uint32 features; /* Set of features supported in
463 this version */
464
465 /** Feature negotiation function. The version negotiation starts out using
466 * the full feature set from the features element and then calls this
467 * function with a subset passed into the features argument. This
468 * function should filter passed in features with the supported feature
469 * set. For simple cases, a bitwise AND can be used, but for more
470 * complicated cases (such as when features are mutually exclusive),
471 * this function enables a more complex negotiation sequence.
472 */
473 negotiate_features_fn negotiate_features;
474};
475
476/**
477 * Data Structure for Transport abstraction layer to call into GLink Core
478 * while registering with GLink
479 */
480typedef struct {
481 const char *name; /* Name of the transport */
482 const char *remote_ss; /* Remote host name */
483 const glink_core_version_type *version; /* Array of supported versions */
484 size_t version_count; /* Number of elements in version[] */
485 uint32 max_cid; /* Max channel ID supported by
486 transport */
487 uint32 max_iid; /* Max Rx intent ID supported by
488 transport */
489}glink_core_transport_cfg_type;
490
491/*===========================================================================
492 PUBLIC FUNCTION DECLARATIONS
493===========================================================================*/
494/*===========================================================================
495FUNCTION glink_core_register_transport
496
497DESCRIPTION Transport calls this API to register its interface with GLINK
498 Core
499
500ARGUMENTS *if_ptr Pointer to interface instance; must be unique
501 for each edge
502
503 *cfg Pointer to transport configuration structure.
504
505RETURN VALUE Standard GLINK error codes.
506
507SIDE EFFECTS None
508===========================================================================*/
509
510glink_err_type glink_core_register_transport
511(
512 glink_transport_if_type *if_ptr,
513 glink_core_transport_cfg_type *cfg
514);
515
516#endif //GLINK_CORE_IF_H
517