blob: 5b56c65a873c7d700fdeb3b543df77df77480e05 [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
30/*===========================================================================
31 INCLUDE FILES
32===========================================================================*/
33
34#include "glink_os_utils.h"
35#include "glink.h"
36#include "glink_internal.h"
Sridhar Parasurambf391322015-01-23 09:29:07 -080037
Sridhar Parasurambf391322015-01-23 09:29:07 -080038#define FEATURE_CH_MIGRATION_FREE
39
Sridhar Parasuram3b058122015-05-11 16:15:03 -070040/*===========================================================================
41 GLOBAL FUNCTION DECLARATIONS
Steven Cahail964ff2f2015-08-20 19:01:56 -060042===========================================================================*/
Sridhar Parasurambf391322015-01-23 09:29:07 -080043/*===========================================================================
44 LOCAL FUNCTION DEFINITIONS
45===========================================================================*/
46/*===========================================================================
Sridhar Parasuram3b058122015-05-11 16:15:03 -070047 FUNCTION glink_process_negotiation_complete
Sridhar Parasurambf391322015-01-23 09:29:07 -080048===========================================================================*/
49/**
50
51 This is called when negotiation is complete.
52 It will set the version and call link up callback to notify
53
54
55 @param[in] xport_ctx transport context
56
57 @param[in] if_ptr Pointer to interface instance; must be unique
58 for each edge
59
60 @param[in] version negotiated version
61
62 @param[in] features negotiated with local side
63
64 @return None
65 @sideeffects None.
66 @dependencies None.
67*/
68/*=========================================================================*/
69static void glink_process_negotiation_complete
70(
Sridhar Parasurambf391322015-01-23 09:29:07 -080071 glink_transport_if_type *if_ptr,
72 uint32 version,
73 uint32 features
74)
75{
Sridhar Parasuram3b058122015-05-11 16:15:03 -070076 glink_core_xport_ctx_type *xport_ctx = if_ptr->glink_core_priv;
Sridhar Parasurambf391322015-01-23 09:29:07 -080077 /* Version/Feautre can be negotiated both in ver_req and ver_ack
78 * Only go through process once in case they are negotiated
79 * in ver_req before receiving ver_ack */
Sridhar Parasuram3b058122015-05-11 16:15:03 -070080
Steven Cahail964ff2f2015-08-20 19:01:56 -060081 if (glinki_xport_linkup(if_ptr))
Sridhar Parasurambf391322015-01-23 09:29:07 -080082 {
83 return;
84 }
85
86 /* setup core based on transport capabilities*/
87 xport_ctx->xport_capabilities = if_ptr->set_version( if_ptr,
88 version,
89 features );
90 glink_core_setup(if_ptr);
91
92 /* transport is ready to open channels */
Sridhar Parasuram3b058122015-05-11 16:15:03 -070093 glink_os_cs_acquire( &xport_ctx->status_cs );
Sridhar Parasurambf391322015-01-23 09:29:07 -080094 if_ptr->glink_core_priv->status = GLINK_XPORT_LINK_UP;
Steven Cahail964ff2f2015-08-20 19:01:56 -060095 glink_os_cs_release(&xport_ctx->status_cs);
Sridhar Parasurambf391322015-01-23 09:29:07 -080096
97 /* Scan the notification list to check is we have to let any registered
Sridhar Parasuram3b058122015-05-11 16:15:03 -070098 * clients know that link came online */
Sridhar Parasurambf391322015-01-23 09:29:07 -080099 glinki_scan_notif_list_and_notify(if_ptr, GLINK_LINK_STATE_UP);
100}
101
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700102/*===========================================================================
103 FUNCTION glink_clean_channel_ctx
104===========================================================================*/
105/**
106
Steven Cahail79783352015-08-20 15:24:04 -0600107 This is called when channel is fully closed.
108 Clean up the context and redeem channel id if possible.
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700109
110 @param[in] xport_ctx transport context
111 @param[in] channel_ctx channel context
112
113
Steven Cahail79783352015-08-20 15:24:04 -0600114 @return None.
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700115 @sideeffects None.
116 @dependencies This function needs to be called in safe context
117 which is critical sections locked - channel_q_cs
118*/
119/*=========================================================================*/
120static void glink_clean_channel_ctx
Sridhar Parasurambf391322015-01-23 09:29:07 -0800121(
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700122 glink_core_xport_ctx_type *xport_ctx,
123 glink_channel_ctx_type *channel_ctx
Sridhar Parasurambf391322015-01-23 09:29:07 -0800124)
125{
Steven Cahailb850bb62015-08-21 14:39:38 -0600126 /* If logging was enabled for this channel reset the logging filter */
127 glinki_update_logging_filter(channel_ctx, TRUE);
128
Steven Cahail79783352015-08-20 15:24:04 -0600129 smem_list_delete(&xport_ctx->open_list, channel_ctx);
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700130
131 if( channel_ctx->lcid == ( xport_ctx->free_lcid - 1 ) )
132 {
133 /* If channel being closed is the last opened channel
134 re-use the lcid of this channel for any new channels */
135 xport_ctx->free_lcid--;
136 }
137
Steven Cahail79783352015-08-20 15:24:04 -0600138 xport_ctx->channel_cleanup(channel_ctx);
Sridhar Parasurambf391322015-01-23 09:29:07 -0800139}
140
141/*===========================================================================
Steven Cahail964ff2f2015-08-20 19:01:56 -0600142 FUNCTION glink_get_current_version
143===========================================================================*/
144/**
145
146 Get current version/feature. This is necessarily highest version.
147
148 @param[in] xport_ctx transport context
149
150 @return pointer to version/feature if available.
151 NULL otherwise.
152
153 @sideeffects None.
154 @dependencies None.
155*/
156/*=========================================================================*/
157static const glink_core_version_type *glink_get_current_version
158(
159 glink_core_xport_ctx_type *xport_ctx
160)
161{
Steven Cahaila136c102015-08-21 13:29:10 -0600162 const glink_core_version_type *ver;
Steven Cahail964ff2f2015-08-20 19:01:56 -0600163
Steven Cahaila136c102015-08-21 13:29:10 -0600164 ver = &xport_ctx->version_array[xport_ctx->version_indx];
Steven Cahail964ff2f2015-08-20 19:01:56 -0600165 ASSERT(ver);
166
167 return ver;
168}
169
170/*===========================================================================
Steven Cahail338e2f22015-08-24 15:11:53 -0600171 FUNCTION glink_is_local_ch_closed
172===========================================================================*/
173/**
174
175 Check if local channel is fully closed
176
177 @param[in] local_state local channel state
178
179 @return TRUE, if local channel is closed
180
181 @sideeffects None.
182 @dependencies None.
183*/
184/*=========================================================================*/
185static boolean glink_is_local_ch_closed
186(
187 glink_local_state_type local_state
188)
189{
190 return local_state == GLINK_LOCAL_CH_INIT ||
191 local_state == GLINK_LOCAL_CH_CLOSED;
192}
193
194/*===========================================================================
195 FUNCTION glink_is_remote_ch_closed
196===========================================================================*/
197/**
198
199 Check if remote channel is fully closed.
200 This doesn't chek GLINK_REMOTE_CH_CLEANUP state as channel ctx shouldn't be
201 destroyed yet
202
203 @param[in] ch_ctx channel ctx
204
205 @return TRUE, if remote channel is closed
206
207 @sideeffects None.
208 @dependencies None.
209*/
210/*=========================================================================*/
211static boolean glink_is_remote_ch_closed
212(
213 glink_remote_state_type remote_state
214)
215{
216 return remote_state == GLINK_REMOTE_CH_INIT ||
217 remote_state == GLINK_REMOTE_CH_CLOSED ||
218 remote_state == GLINK_REMOTE_CH_SSR_RESET;
219}
220
221/*===========================================================================
Sridhar Parasurambf391322015-01-23 09:29:07 -0800222 EXTERNAL FUNCTION DEFINITIONS
223===========================================================================*/
224/*===========================================================================
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700225 FUNCTION glink_link_up
Sridhar Parasurambf391322015-01-23 09:29:07 -0800226===========================================================================*/
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700227/**
228 Indicates that transport is now ready to start negotiation
229 using the v0 configuration
230
231 @param[in] if_ptr Pointer to interface instance; must be unique
232 for each edge
233
234 @return None
235 @sideeffects None.
236 @dependencies None.
237*/
238/*=========================================================================*/
Sridhar Parasurambf391322015-01-23 09:29:07 -0800239void glink_link_up
240(
241 glink_transport_if_type *if_ptr
242)
243{
Sridhar Parasurambf391322015-01-23 09:29:07 -0800244 glink_core_xport_ctx_type *xport_ctx;
Steven Cahail964ff2f2015-08-20 19:01:56 -0600245 const glink_core_version_type *version_array;
Sridhar Parasurambf391322015-01-23 09:29:07 -0800246
247 xport_ctx = if_ptr->glink_core_priv;
248
Steven Cahail964ff2f2015-08-20 19:01:56 -0600249 version_array = glink_get_current_version(xport_ctx);
Sridhar Parasurambf391322015-01-23 09:29:07 -0800250
251 /* Update the transport state */
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700252 glink_os_cs_acquire(&if_ptr->glink_core_priv->status_cs);
Sridhar Parasurambf391322015-01-23 09:29:07 -0800253 if_ptr->glink_core_priv->status = GLINK_XPORT_NEGOTIATING;
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700254 glink_os_cs_release(&if_ptr->glink_core_priv->status_cs);
Sridhar Parasurambf391322015-01-23 09:29:07 -0800255
256 /* Start the negtiation */
Steven Cahail964ff2f2015-08-20 19:01:56 -0600257 if_ptr->tx_cmd_version(if_ptr,
258 version_array->version,
Sridhar Parasurambf391322015-01-23 09:29:07 -0800259 version_array->features);
260
Steven Cahailb850bb62015-08-21 14:39:38 -0600261 GLINK_LOG_EVENT_NO_FILTER( GLINK_EVENT_LINK_UP, "",
262 xport_ctx->xport,
263 xport_ctx->remote_ss,
264 GLINK_STATUS_SUCCESS);
Sridhar Parasurambf391322015-01-23 09:29:07 -0800265}
266
267/*===========================================================================
268FUNCTION glink_rx_cmd_version
269
270DESCRIPTION Receive transport version for remote-initiated version
271 negotiation
272
273ARGUMENTS *if_ptr Pointer to interface instance; must be unique
274 for each edge
275
276 version Remote Version
277
278 features Remote Features
279
280RETURN VALUE None.
281
282SIDE EFFECTS None
283===========================================================================*/
284void glink_rx_cmd_version
285(
286 glink_transport_if_type *if_ptr,
287 uint32 version,
288 uint32 features
289)
290{
291 const glink_core_version_type *ver;
292 uint32 negotiated_features;
293 glink_core_xport_ctx_type *xport_ctx;
294
Sridhar Parasurambf391322015-01-23 09:29:07 -0800295 xport_ctx = if_ptr->glink_core_priv;
296
Steven Cahail964ff2f2015-08-20 19:01:56 -0600297 ver = glink_get_current_version(xport_ctx);
298
Sridhar Parasurambf391322015-01-23 09:29:07 -0800299 /* The version to use must be a subset of supported version and features
300 * on this host and remote host */
Sridhar Parasurambf391322015-01-23 09:29:07 -0800301 if (version == ver->version)
302 {
303 /* Call the transport's negotiation function */
304 negotiated_features = ver->negotiate_features(if_ptr, ver, features);
305
Steven Cahail964ff2f2015-08-20 19:01:56 -0600306 if_ptr->tx_cmd_version_ack(if_ptr, version, negotiated_features);
307
Sridhar Parasurambf391322015-01-23 09:29:07 -0800308 /* If negotiated features match the provided features, version nogetiation
309 * is complete */
310 if(negotiated_features == features)
311 {
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700312 glink_process_negotiation_complete( if_ptr, version, features );
Sridhar Parasurambf391322015-01-23 09:29:07 -0800313 }
314 }
315 else
316 {
Sridhar Parasurambf391322015-01-23 09:29:07 -0800317 /* Versions don't match, return ACK with the feature set that we support */
318 if_ptr->tx_cmd_version_ack(if_ptr, ver->version, ver->features);
319 }
320}
321
322/*===========================================================================
323FUNCTION glink_rx_cmd_version_ack
324
325DESCRIPTION Receive ACK to previous glink_transport_if::tx_cmd_version
326 command
327
328ARGUMENTS *if_ptr Pointer to interface instance; must be unique
329 for each edge
330
331 version Remote Version
332
333 features Remote Features
334
335RETURN VALUE None.
336
337SIDE EFFECTS None
338===========================================================================*/
339void glink_rx_cmd_version_ack
340(
341 glink_transport_if_type *if_ptr,
342 uint32 version,
343 uint32 features
344)
345{
346 const glink_core_version_type* ver;
347 uint32 negotiated_features;
348 glink_core_xport_ctx_type *xport_ctx;
349
Sridhar Parasurambf391322015-01-23 09:29:07 -0800350 xport_ctx = if_ptr->glink_core_priv;
351
352 /* Check to see if version returned by remote end is supported by
353 * this host. Remote side would have acked only when the version/features
354 * sent by this host did not match the remote */
Steven Cahail964ff2f2015-08-20 19:01:56 -0600355 ver = glink_get_current_version(xport_ctx);
Sridhar Parasurambf391322015-01-23 09:29:07 -0800356
357 if (ver->version == version)
358 {
359 /* Call the transport's negotiation function */
360 negotiated_features = ver->negotiate_features(if_ptr, ver, features);
361
Steven Cahail964ff2f2015-08-20 19:01:56 -0600362 if(negotiated_features == features)
363 {
364 glink_process_negotiation_complete( if_ptr, version, features );
365 }
366 else
Sridhar Parasurambf391322015-01-23 09:29:07 -0800367 {
368 /* Continue negotiating */
369 if_ptr->tx_cmd_version(if_ptr, version, negotiated_features);
370 }
Sridhar Parasurambf391322015-01-23 09:29:07 -0800371 }
372 else
373 {
Steven Cahail964ff2f2015-08-20 19:01:56 -0600374 while (ver->version > version && xport_ctx->version_indx > 0)
Sridhar Parasurambf391322015-01-23 09:29:07 -0800375 {
376 /* Next time use older version */
Sridhar Parasurambf391322015-01-23 09:29:07 -0800377 xport_ctx->version_indx--;
378 ver = &xport_ctx->version_array[xport_ctx->version_indx];
379 }
380
381 /* Versions don't match, return ACK with the feature set that we support */
382 if_ptr->tx_cmd_version(if_ptr, ver->version, ver->features);
383 }
384}
385
386/*===========================================================================
387FUNCTION glink_rx_cmd_ch_remote_open
Sridhar Parasurambf391322015-01-23 09:29:07 -0800388===========================================================================*/
Steven Cahail89c6dc82015-08-20 14:36:56 -0600389/**
390 * Receive remote channel open request;
391 * Calls glink_transport_if:: tx_cmd_ch_remote_open_ack as a result
392 *
393 * @param[in] if_ptr Pointer to interface instance; must be unique
394 for each edge
395 * @param[in] rcid Remote Channel ID
396 * @param[in] name String name for logical channel
397 * @param[in] priority xport priority requested by remote side
398 *
399 * @return None
400 *
401 * @sideeffects NONE
402 */
403/*=========================================================================*/
Sridhar Parasurambf391322015-01-23 09:29:07 -0800404void glink_rx_cmd_ch_remote_open
405(
406 glink_transport_if_type *if_ptr,
407 uint32 rcid,
408 const char *name,
409 glink_xport_priority priority
410)
411{
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700412 glink_channel_ctx_type *remote_ch_ctx = NULL;
413 glink_channel_ctx_type *allocated_ch_ctx;
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700414 glink_err_type status;
Sridhar Parasurambf391322015-01-23 09:29:07 -0800415
Steven Cahaila136c102015-08-21 13:29:10 -0600416 GLINK_OS_UNREFERENCED_PARAM( priority );
417
Sridhar Parasurambf391322015-01-23 09:29:07 -0800418 /* Allocate and initialize channel info structure */
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700419 remote_ch_ctx = glink_os_calloc( sizeof( glink_channel_ctx_type ) );
420 if(remote_ch_ctx == NULL)
421 {
Steven Cahailb850bb62015-08-21 14:39:38 -0600422 GLINK_LOG_ERROR_EVENT( GLINK_EVENT_RM_CH_OPEN,
Steven Cahail89c6dc82015-08-20 14:36:56 -0600423 name,
424 if_ptr->glink_core_priv->xport,
425 if_ptr->glink_core_priv->remote_ss,
426 GLINK_STATUS_OUT_OF_RESOURCES );
Sridhar Parasurambf391322015-01-23 09:29:07 -0800427 ASSERT(0);
428 }
429
430 /* Fill in the channel info structure */
431 glink_os_string_copy(remote_ch_ctx->name, name, sizeof(remote_ch_ctx->name));
432 remote_ch_ctx->rcid = rcid;
433
Steven Cahail89c6dc82015-08-20 14:36:56 -0600434 status = glinki_add_ch_to_xport( if_ptr,
435 remote_ch_ctx,
436 &allocated_ch_ctx,
437 FALSE,
438 if_ptr->glink_priority );
Sridhar Parasurambf391322015-01-23 09:29:07 -0800439
Steven Cahailb850bb62015-08-21 14:39:38 -0600440 GLINK_LOG_EVENT( allocated_ch_ctx,
441 GLINK_EVENT_RM_CH_OPEN,
Steven Cahailba780a82015-08-19 17:57:09 -0600442 name,
Steven Cahail89c6dc82015-08-20 14:36:56 -0600443 if_ptr->glink_core_priv->xport,
444 if_ptr->glink_core_priv->remote_ss,
Steven Cahail338e2f22015-08-24 15:11:53 -0600445 status );
446
447 ASSERT(GLINK_STATUS_SUCCESS == status);
Sridhar Parasurambf391322015-01-23 09:29:07 -0800448}
449
450/*===========================================================================
451FUNCTION glink_rx_cmd_ch_open_ack
Sridhar Parasurambf391322015-01-23 09:29:07 -0800452===========================================================================*/
Steven Cahail89c6dc82015-08-20 14:36:56 -0600453/**
454 * This function is invoked by the transport
455 * in response to glink_transport_if:: tx_cmd_ch_open
456 *
457 * @param[in] if_ptr Pointer to interface instance; must be unique
458 * for each edge
459 * @param[in] lcid Local Channel ID
460 * @param[in] migrated_ch_prio Negotiated xport priority from remote side
461 *
462 * @return None
463 *
464 * @sideeffects NONE
465 */
466/*=========================================================================*/
Sridhar Parasurambf391322015-01-23 09:29:07 -0800467void glink_rx_cmd_ch_open_ack
468(
469 glink_transport_if_type *if_ptr,
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700470 uint32 lcid,
471 glink_xport_priority migrated_ch_prio
Sridhar Parasurambf391322015-01-23 09:29:07 -0800472)
473{
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700474 glink_channel_ctx_type *open_ch_ctx;
Sridhar Parasurambf391322015-01-23 09:29:07 -0800475 glink_core_xport_ctx_type *xport_ctx;
Steven Cahail964ff2f2015-08-20 19:01:56 -0600476 glink_remote_state_type remote_state;
Sridhar Parasurambf391322015-01-23 09:29:07 -0800477
Steven Cahaila136c102015-08-21 13:29:10 -0600478 GLINK_OS_UNREFERENCED_PARAM( migrated_ch_prio );
479
Sridhar Parasurambf391322015-01-23 09:29:07 -0800480 xport_ctx = if_ptr->glink_core_priv;
481
482 /* Move to closed state. Implies we clean up the channel from the
483 * open list */
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700484 glink_os_cs_acquire(&xport_ctx->channel_q_cs);
Steven Cahail964ff2f2015-08-20 19:01:56 -0600485
486 open_ch_ctx = glinki_find_ch_ctx_by_lcid(xport_ctx, lcid);
487
Steven Cahail89c6dc82015-08-20 14:36:56 -0600488 if( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSING )
489 {
490 /* Client called glink_close before gettng open ack.
491 * Ignore open ack and go for closing sequence */
Steven Cahail89c6dc82015-08-20 14:36:56 -0600492 glink_os_cs_release( &xport_ctx->channel_q_cs );
493 return;
494 }
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700495
Steven Cahail40d2f512015-08-24 18:02:08 -0600496 ASSERT(open_ch_ctx->local_state == GLINK_LOCAL_CH_OPENING);
497
Steven Cahail89c6dc82015-08-20 14:36:56 -0600498 open_ch_ctx->local_state = GLINK_LOCAL_CH_OPENED;
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700499
Steven Cahail964ff2f2015-08-20 19:01:56 -0600500 remote_state = open_ch_ctx->remote_state;
Steven Cahail964ff2f2015-08-20 19:01:56 -0600501 glink_os_cs_release(&xport_ctx->channel_q_cs);
502
503 if (remote_state == GLINK_REMOTE_CH_OPENED)
Steven Cahail89c6dc82015-08-20 14:36:56 -0600504 {
505 /* remote channel is open on same xport as current xport.
506 * change channel state to GLINK_CH_STATE_OPEN and notify client */
Steven Cahail89c6dc82015-08-20 14:36:56 -0600507 open_ch_ctx->notify_state( open_ch_ctx,
508 open_ch_ctx->priv,
509 GLINK_CONNECTED );
510 }
Sridhar Parasurambf391322015-01-23 09:29:07 -0800511
Steven Cahailb850bb62015-08-21 14:39:38 -0600512 GLINK_LOG_EVENT( open_ch_ctx,
513 GLINK_EVENT_CH_OPEN_ACK,
514 open_ch_ctx->name,
515 xport_ctx->xport,
516 xport_ctx->remote_ss,
517 lcid );
Sridhar Parasurambf391322015-01-23 09:29:07 -0800518}
519
520/*===========================================================================
521FUNCTION glink_rx_cmd_ch_close_ack
Sridhar Parasurambf391322015-01-23 09:29:07 -0800522===========================================================================*/
Steven Cahail964ff2f2015-08-20 19:01:56 -0600523/**
524 * This function is invoked by the transport in response to
525 * glink_transport_if_type:: tx_cmd_ch_close
526 *
527 * @param[in] if_ptr Pointer to interface instance; must be unique
528 * for each edge
529 * @param[in] lcid Local Channel ID
530 *
531 * @return None
532 *
533 * @sideeffects NONE
534 */
535/*=========================================================================*/
Sridhar Parasurambf391322015-01-23 09:29:07 -0800536void glink_rx_cmd_ch_close_ack
537(
Steven Cahail964ff2f2015-08-20 19:01:56 -0600538 glink_transport_if_type *if_ptr,
539 uint32 lcid
Sridhar Parasurambf391322015-01-23 09:29:07 -0800540)
541{
542 glink_channel_ctx_type *open_ch_ctx;
543 glink_core_xport_ctx_type *xport_ctx;
544
Sridhar Parasurambf391322015-01-23 09:29:07 -0800545 xport_ctx = if_ptr->glink_core_priv;
546
Sridhar Parasurambf391322015-01-23 09:29:07 -0800547 glink_os_cs_acquire(&xport_ctx->channel_q_cs);
Steven Cahail964ff2f2015-08-20 19:01:56 -0600548
549 open_ch_ctx = glinki_find_ch_ctx_by_lcid(xport_ctx, lcid);
550
Steven Cahailb850bb62015-08-21 14:39:38 -0600551 GLINK_LOG_EVENT( open_ch_ctx,
552 GLINK_EVENT_CH_CLOSE_ACK,
553 open_ch_ctx->name,
554 xport_ctx->xport,
555 xport_ctx->remote_ss,
556 lcid);
Sridhar Parasurambf391322015-01-23 09:29:07 -0800557
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700558 ASSERT( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSING );
Sridhar Parasurambf391322015-01-23 09:29:07 -0800559
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700560 open_ch_ctx->local_state = GLINK_LOCAL_CH_CLOSED;
Steven Cahail338e2f22015-08-24 15:11:53 -0600561 open_ch_ctx->lcid = GLINK_INVALID_CID;
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700562
Steven Cahail338e2f22015-08-24 15:11:53 -0600563 if ( glink_is_remote_ch_closed( open_ch_ctx->remote_state ) )
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700564 {
565 glink_clean_channel_ctx( xport_ctx, open_ch_ctx );
Sridhar Parasurambf391322015-01-23 09:29:07 -0800566 }
567
568 glink_os_cs_release(&xport_ctx->channel_q_cs);
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700569
570 open_ch_ctx->notify_state( open_ch_ctx,
571 open_ch_ctx->priv,
572 GLINK_LOCAL_DISCONNECTED );
573
Steven Cahail338e2f22015-08-24 15:11:53 -0600574 if ( glink_is_remote_ch_closed( open_ch_ctx->remote_state ) )
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700575 {
576 glink_os_free( open_ch_ctx );
577 }
Sridhar Parasurambf391322015-01-23 09:29:07 -0800578}
579
580/*===========================================================================
581FUNCTION glink_rx_cmd_ch_remote_close
Sridhar Parasurambf391322015-01-23 09:29:07 -0800582===========================================================================*/
Steven Cahail964ff2f2015-08-20 19:01:56 -0600583/**
584 * Remote channel close request; will result in sending
585 * glink_transport_if_type:: tx_cmd_ch_remote_close_ack
586 *
587 * @param[in] if_ptr Pointer to interface instance; must be unique
588 * for each edge
589 * @param[in] rcid Remote Channel ID
590 *
591 * @return None.
592 *
593 * @sideeffects None.
594 */
595/*=========================================================================*/
Sridhar Parasurambf391322015-01-23 09:29:07 -0800596void glink_rx_cmd_ch_remote_close
597(
Steven Cahail964ff2f2015-08-20 19:01:56 -0600598 glink_transport_if_type *if_ptr,
599 uint32 rcid
Sridhar Parasurambf391322015-01-23 09:29:07 -0800600)
601{
602 glink_channel_ctx_type *open_ch_ctx;
603 glink_core_xport_ctx_type *xport_ctx;
Steven Cahail964ff2f2015-08-20 19:01:56 -0600604 glink_remote_state_type remote_state;
Sridhar Parasurambf391322015-01-23 09:29:07 -0800605
606 xport_ctx = if_ptr->glink_core_priv;
607
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700608 glink_os_cs_acquire( &xport_ctx->channel_q_cs );
609
Steven Cahail964ff2f2015-08-20 19:01:56 -0600610 open_ch_ctx = glinki_find_ch_ctx_by_rcid(xport_ctx, rcid);
Steven Cahail79783352015-08-20 15:24:04 -0600611
Steven Cahailb850bb62015-08-21 14:39:38 -0600612 GLINK_LOG_EVENT( open_ch_ctx,
613 GLINK_EVENT_CH_REMOTE_CLOSE,
614 open_ch_ctx->name,
615 xport_ctx->xport,
616 xport_ctx->remote_ss,
617 rcid );
Sridhar Parasurambf391322015-01-23 09:29:07 -0800618
Steven Cahail19f044e2015-08-24 17:36:25 -0600619 /* It is possible that the remote subsystem sending close might crash
620 before we handle the close request from it */
621 if (open_ch_ctx->remote_state == GLINK_REMOTE_CH_SSR_RESET)
622 {
623 glink_os_cs_release(&xport_ctx->channel_q_cs);
624 return;
625 }
626
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700627 ASSERT( open_ch_ctx->remote_state == GLINK_REMOTE_CH_OPENED );
Sridhar Parasurambf391322015-01-23 09:29:07 -0800628
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700629 open_ch_ctx->remote_state = GLINK_REMOTE_CH_CLOSED;
Steven Cahail338e2f22015-08-24 15:11:53 -0600630 open_ch_ctx->rcid = GLINK_INVALID_CID;
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700631
Steven Cahail338e2f22015-08-24 15:11:53 -0600632 if ( glink_is_local_ch_closed( open_ch_ctx->local_state ) )
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700633 {
634 /* Local side never opened the channel OR it opened it but closed it */
635 /* Free channel resources */
636 glink_clean_channel_ctx( xport_ctx, open_ch_ctx );
637 }
638
Steven Cahail79783352015-08-20 15:24:04 -0600639 remote_state = open_ch_ctx->remote_state;
640
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700641 glink_os_cs_release(&xport_ctx->channel_q_cs);
642
643 /* Send the remote close ACK back to the other side */
Steven Cahail338e2f22015-08-24 15:11:53 -0600644 if_ptr->tx_cmd_ch_remote_close_ack(if_ptr, rcid);
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700645
Steven Cahail338e2f22015-08-24 15:11:53 -0600646 if ( glink_is_local_ch_closed( open_ch_ctx->local_state ) )
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700647 {
Steven Cahail338e2f22015-08-24 15:11:53 -0600648 /* Destroy channel context only if there isn't any pending intents */
Steven Cahail79783352015-08-20 15:24:04 -0600649 if (remote_state != GLINK_REMOTE_CH_CLEANUP)
650 {
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700651 glink_os_free(open_ch_ctx);
652 }
Steven Cahail79783352015-08-20 15:24:04 -0600653 }
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700654 else
655 {
Sridhar Parasurambf391322015-01-23 09:29:07 -0800656 /* Inform the client */
Steven Cahail964ff2f2015-08-20 19:01:56 -0600657 open_ch_ctx->notify_state(open_ch_ctx,
658 open_ch_ctx->priv,
Sridhar Parasurambf391322015-01-23 09:29:07 -0800659 GLINK_REMOTE_DISCONNECTED);
Sridhar Parasurambf391322015-01-23 09:29:07 -0800660 }
Sridhar Parasurambf391322015-01-23 09:29:07 -0800661}
662
663/*===========================================================================
664FUNCTION glink_rx_put_pkt_ctx
Sridhar Parasurambf391322015-01-23 09:29:07 -0800665===========================================================================*/
Steven Cahail964ff2f2015-08-20 19:01:56 -0600666/**
667 * Transport invokes this call to receive a packet fragment (must
668 * have previously received an rx_cmd_rx_data packet)
669 *
670 * @param[in] if_ptr Pointer to interface instance; must be unique
671 * for each edge
672 * @param[in] rcid Remote Channel ID
673 * @param[in] intent_ptr Pointer to the intent fragment
674 * @param[in] complete True if pkt is complete
675 *
676 * @return None.
677 *
678 * @sideeffects None.
679 */
680/*=========================================================================*/
Sridhar Parasurambf391322015-01-23 09:29:07 -0800681void glink_rx_put_pkt_ctx
682(
Steven Cahail964ff2f2015-08-20 19:01:56 -0600683 glink_transport_if_type *if_ptr,
684 uint32 rcid,
685 glink_rx_intent_type *intent_ptr,
686 boolean complete
Sridhar Parasurambf391322015-01-23 09:29:07 -0800687)
688{
689 glink_channel_ctx_type *open_ch_ctx;
690 glink_core_xport_ctx_type *xport_ctx;
691
Steven Cahaila136c102015-08-21 13:29:10 -0600692 GLINK_OS_UNREFERENCED_PARAM( complete );
693
Steven Cahail964ff2f2015-08-20 19:01:56 -0600694 ASSERT(intent_ptr);
Sridhar Parasurambf391322015-01-23 09:29:07 -0800695
696 xport_ctx = if_ptr->glink_core_priv;
697
698 /* Find channel in the open_list */
Steven Cahail964ff2f2015-08-20 19:01:56 -0600699 glink_os_cs_acquire(&xport_ctx->channel_q_cs);
700 open_ch_ctx = glinki_find_ch_ctx_by_rcid(xport_ctx, rcid);
701 glink_os_cs_release(&xport_ctx->channel_q_cs);
702
Steven Cahailb850bb62015-08-21 14:39:38 -0600703 GLINK_LOG_EVENT( open_ch_ctx,
704 GLINK_EVENT_CH_PUT_PKT_CTX,
705 open_ch_ctx->name,
706 xport_ctx->xport,
707 xport_ctx->remote_ss,
708 intent_ptr->iid);
Sridhar Parasurambf391322015-01-23 09:29:07 -0800709
710 xport_ctx->channel_receive_pkt(open_ch_ctx, intent_ptr);
Sridhar Parasurambf391322015-01-23 09:29:07 -0800711}
712
713/*===========================================================================
714FUNCTION glink_rx_cmd_remote_sigs
715
716DESCRIPTION Transport invokes this call to inform GLink of remote side
717 changing its control signals
718
719ARGUMENTS *if_ptr Pointer to interface instance; must be unique
720 for each edge
721
722 rcid Remote Channel ID
723
724 remote_sigs Remote signal state.
725
726RETURN VALUE None.
727
728SIDE EFFECTS None
729===========================================================================*/
730void glink_rx_cmd_remote_sigs
731(
732 glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
733 uint32 rcid, /* Remote channel ID */
734 uint32 remote_sigs /* Remote control signals */
735)
736{
Steven Cahail964ff2f2015-08-20 19:01:56 -0600737 glink_core_xport_ctx_type *xport_ctx;
Sridhar Parasurambf391322015-01-23 09:29:07 -0800738 glink_channel_ctx_type *open_ch_ctx;
739 uint32 prev_sigs;
740
Steven Cahail964ff2f2015-08-20 19:01:56 -0600741 xport_ctx = if_ptr->glink_core_priv;
Steven Cahailba780a82015-08-19 17:57:09 -0600742
Steven Cahail964ff2f2015-08-20 19:01:56 -0600743 glink_os_cs_acquire(&xport_ctx->channel_q_cs);
744 open_ch_ctx = glinki_find_ch_ctx_by_rcid(xport_ctx, rcid);
745 glink_os_cs_release( &xport_ctx->channel_q_cs );
Steven Cahailba780a82015-08-19 17:57:09 -0600746
Steven Cahail964ff2f2015-08-20 19:01:56 -0600747 if (!glinki_channel_fully_opened(open_ch_ctx))
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700748 {
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700749 ASSERT(0);
Sridhar Parasuram3b058122015-05-11 16:15:03 -0700750 }
Steven Cahail964ff2f2015-08-20 19:01:56 -0600751
Sridhar Parasurambf391322015-01-23 09:29:07 -0800752 /* Found channel, let client know of new remote signal state */
753 prev_sigs = open_ch_ctx->remote_sigs;
754 open_ch_ctx->remote_sigs = remote_sigs;
Steven Cahail964ff2f2015-08-20 19:01:56 -0600755 open_ch_ctx->notify_rx_sigs(open_ch_ctx,
756 open_ch_ctx->priv,
757 prev_sigs,
758 remote_sigs);
Sridhar Parasurambf391322015-01-23 09:29:07 -0800759 }
760