xref: /illumos-gate/usr/src/uts/common/io/ib/mgt/ibcm/ibcm_sm.c (revision f248c5e0)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5934f0bccShiremath  * Common Development and Distribution License (the "License").
6934f0bccShiremath  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22a23420cfSShantkumar Hiremath  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
237c478bd9Sstevel@tonic-gate  */
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate #include <sys/ib/mgt/ibcm/ibcm_impl.h>
267c478bd9Sstevel@tonic-gate #include <sys/callb.h>
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate /*
297c478bd9Sstevel@tonic-gate  * ibcm_sm.c
307c478bd9Sstevel@tonic-gate  *	These routines implement the CM state machine (both ACTIVE and PASSIVE)
317c478bd9Sstevel@tonic-gate  *
327c478bd9Sstevel@tonic-gate  * Points to Note :
337c478bd9Sstevel@tonic-gate  *
347c478bd9Sstevel@tonic-gate  * o  CM uses one ibcm_hca_info_t entry per HCA  to store all the
357c478bd9Sstevel@tonic-gate  *    connection state data belonging to that HCA in the AVL trees, etc.,
367c478bd9Sstevel@tonic-gate  *
377c478bd9Sstevel@tonic-gate  * o  There is one state structure per RC, referenced from three AVL trees
387c478bd9Sstevel@tonic-gate  *    ie. the HCA active AVL tree, and the HCA passive AVL tree and HCA
397c478bd9Sstevel@tonic-gate  *    passive comid tree
407c478bd9Sstevel@tonic-gate  *
417c478bd9Sstevel@tonic-gate  * o  SIDR state structures are stored in a linked list
427c478bd9Sstevel@tonic-gate  *
437c478bd9Sstevel@tonic-gate  * o  The term statep generally refers to RC, until explicitly mentioned
447c478bd9Sstevel@tonic-gate  *    in the notes below
457c478bd9Sstevel@tonic-gate  *
467c478bd9Sstevel@tonic-gate  * o  Any thread that may access statep increments the ref_cnt. This ensures
477c478bd9Sstevel@tonic-gate  *    that statep is not deleted when it is still being accessed and modified
487c478bd9Sstevel@tonic-gate  *    by other threads
497c478bd9Sstevel@tonic-gate  *
507c478bd9Sstevel@tonic-gate  * o  Any thread that may want to search the AVL tree(s) holds the hca state
517c478bd9Sstevel@tonic-gate  *    table reader lock. If it shall insert/delete a new state structure, then
527c478bd9Sstevel@tonic-gate  *    the lock held is writer lock.
537c478bd9Sstevel@tonic-gate  *
547c478bd9Sstevel@tonic-gate  * o  Incrementing and Decrementing the ref_cnt can happen only after acquiring
557c478bd9Sstevel@tonic-gate  *    statep mutex
567c478bd9Sstevel@tonic-gate  *
577c478bd9Sstevel@tonic-gate  * o  Deleting a statep can happen only by acquiring the hca state writer lock
587c478bd9Sstevel@tonic-gate  *    and statep mutex and if ref_cnt is zero.
597c478bd9Sstevel@tonic-gate  *
607c478bd9Sstevel@tonic-gate  * o  Statep mutexes are used to decrease the hca state table lock holding
617c478bd9Sstevel@tonic-gate  *    times. thus increasing more number of threads that can access hca
627c478bd9Sstevel@tonic-gate  *    global data structures
637c478bd9Sstevel@tonic-gate  *
647c478bd9Sstevel@tonic-gate  * o  Statep mutexes cannot be hold for long time. They are primarily used to
657c478bd9Sstevel@tonic-gate  *    check the state of statep, change it and exit the lock. Other threads
667c478bd9Sstevel@tonic-gate  *    checking this statep find statep's new state, and may exit without
677c478bd9Sstevel@tonic-gate  *    further processing (as the statep->state has changed).
687c478bd9Sstevel@tonic-gate  *
697c478bd9Sstevel@tonic-gate  * o  Statep mutex must be held while setting and unsetting the timer id
707c478bd9Sstevel@tonic-gate  *    values and during untimeout
717c478bd9Sstevel@tonic-gate  *
727c478bd9Sstevel@tonic-gate  * Re-stating, the overall purpose of these various locks are:
737c478bd9Sstevel@tonic-gate  *   - Minimize the time state table locks are held
747c478bd9Sstevel@tonic-gate  *   - Writer locks are held only while inserting/deleting into trees,
757c478bd9Sstevel@tonic-gate  *	so multiple readers can traverse data structures in parallel
767c478bd9Sstevel@tonic-gate  *   - Minimize the time statep mutex held, so other threads entering the same
777c478bd9Sstevel@tonic-gate  *	statep mutex are not held for long
787c478bd9Sstevel@tonic-gate  *
797c478bd9Sstevel@tonic-gate  * The CM state machine logic ensures that the statep is valid and exists
807c478bd9Sstevel@tonic-gate  * when timeout callback (ibcm_timeout_cb) is called. This is ensured by
817c478bd9Sstevel@tonic-gate  * cancelling timeouts on state changes, where appropriate
827c478bd9Sstevel@tonic-gate  *
837c478bd9Sstevel@tonic-gate  *
847c478bd9Sstevel@tonic-gate  * The timeout processing is handled in the context in which the
857c478bd9Sstevel@tonic-gate  * timeout callback is invoked.
867c478bd9Sstevel@tonic-gate  *
877c478bd9Sstevel@tonic-gate  * The CM STATE MACHINE logic flow:
887c478bd9Sstevel@tonic-gate  *
897c478bd9Sstevel@tonic-gate  * On an incoming MAD:-
907c478bd9Sstevel@tonic-gate  *
917c478bd9Sstevel@tonic-gate  * IBMF -> ibcm_process_incoming_mad
927c478bd9Sstevel@tonic-gate  *	Verify and branch to one of the below connection state routines.
937c478bd9Sstevel@tonic-gate  *	The callback arg from ibmf has the pointer to ibcm_hca_info_t
947c478bd9Sstevel@tonic-gate  *
957c478bd9Sstevel@tonic-gate  * 1. INCOMING REQ MAD
967c478bd9Sstevel@tonic-gate  *
977c478bd9Sstevel@tonic-gate  *	Acquire hca state table WRITER lock
987c478bd9Sstevel@tonic-gate  *	Do lookup in passive AVL tree by remote qpn and remote hca guid
997c478bd9Sstevel@tonic-gate  *
1007c478bd9Sstevel@tonic-gate  *	If (new lookup)
1017c478bd9Sstevel@tonic-gate  *
1027c478bd9Sstevel@tonic-gate  *	  create new statep, initialize key fields
1037c478bd9Sstevel@tonic-gate  *	  obtain new local com id, insert into hca state AVL tree
1047c478bd9Sstevel@tonic-gate  *	  release hca state table WRITER lock
1057c478bd9Sstevel@tonic-gate  *
1067c478bd9Sstevel@tonic-gate  *	  Initialize remaining fields
1077c478bd9Sstevel@tonic-gate  *	  If invalid service id,
1087c478bd9Sstevel@tonic-gate  *		send a REJ reply,
1097c478bd9Sstevel@tonic-gate  *		decr ref_cnt holding state mutex
1107c478bd9Sstevel@tonic-gate  *	  If existing peer conn, check guids, and break the tie
1117c478bd9Sstevel@tonic-gate  *	  Call the cep state transition function
1127c478bd9Sstevel@tonic-gate  *	  Send an RTU/REJ reply
1137c478bd9Sstevel@tonic-gate  *	  Check and handle for any incoming REJ's during REQ RCVD state
1147c478bd9Sstevel@tonic-gate  *
1157c478bd9Sstevel@tonic-gate  *    else if (existing lookup)
1167c478bd9Sstevel@tonic-gate  *
1177c478bd9Sstevel@tonic-gate  *	  increment refcnt holding state mutex
1187c478bd9Sstevel@tonic-gate  *	  release hca state table WRITER lock
1197c478bd9Sstevel@tonic-gate  *
1207c478bd9Sstevel@tonic-gate  *	  re-acquire the statep mutex
1217c478bd9Sstevel@tonic-gate  *	  if (statep->state is REP SENT/REJ SENT/ MRA SENT)
1227c478bd9Sstevel@tonic-gate  *		resend the mad
1237c478bd9Sstevel@tonic-gate  *	  else if established
1247c478bd9Sstevel@tonic-gate  *		handle the stale detection
1257c478bd9Sstevel@tonic-gate  *	  else
1267c478bd9Sstevel@tonic-gate  *		drop the mad (no processing required)
1277c478bd9Sstevel@tonic-gate  *	  decr statep->ref_cnt, release state mutex
1287c478bd9Sstevel@tonic-gate  *
1297c478bd9Sstevel@tonic-gate  *
1307c478bd9Sstevel@tonic-gate  * 2. INCOMING REP MAD
1317c478bd9Sstevel@tonic-gate  *
1327c478bd9Sstevel@tonic-gate  *    Acquire hca state READER lock
1337c478bd9Sstevel@tonic-gate  *    Do lookup in hca state tree by local com id
1347c478bd9Sstevel@tonic-gate  *    Release hca state table READER lock
1357c478bd9Sstevel@tonic-gate  *
1367c478bd9Sstevel@tonic-gate  *    if lookup does not exist
1377c478bd9Sstevel@tonic-gate  *	 return
1387c478bd9Sstevel@tonic-gate  *
1397c478bd9Sstevel@tonic-gate  *    if look up exists
1407c478bd9Sstevel@tonic-gate  *	 incr statep->ref_cnt holding state mutex
1417c478bd9Sstevel@tonic-gate  *
1427c478bd9Sstevel@tonic-gate  *    acquire the statep lock
1437c478bd9Sstevel@tonic-gate  *    if (state == ESTABLISHED or REJ SENt or MRA REP SENT)
1447c478bd9Sstevel@tonic-gate  *	  resend the MAD
1457c478bd9Sstevel@tonic-gate  *	  release state mutex, cancel req sent timer
1467c478bd9Sstevel@tonic-gate  *	  decrement ref_cnt holding the statep lock
1477c478bd9Sstevel@tonic-gate  *	  return
1487c478bd9Sstevel@tonic-gate  *
1497c478bd9Sstevel@tonic-gate  *    if (state == REQ_SENT or REP_WAIT)
1507c478bd9Sstevel@tonic-gate  *	  first, change state to REP_RCVD
1517c478bd9Sstevel@tonic-gate  *	  release statep lock
1527c478bd9Sstevel@tonic-gate  *	  cancel timers
1537c478bd9Sstevel@tonic-gate  *	  lookup in the passive tree by remote qpn and remote hca guid
1547c478bd9Sstevel@tonic-gate  *	  if entry already exists
1557c478bd9Sstevel@tonic-gate  *		 handle the stale detection
1567c478bd9Sstevel@tonic-gate  *	  else
1577c478bd9Sstevel@tonic-gate  *		add to the passive tree
1587c478bd9Sstevel@tonic-gate  *
1597c478bd9Sstevel@tonic-gate  *	  Initialize fields of statep
1607c478bd9Sstevel@tonic-gate  *	  Call the qp state transition function
1617c478bd9Sstevel@tonic-gate  *	  Post RTU/REJ reply
1627c478bd9Sstevel@tonic-gate  *	  Acquire the state mutex
1637c478bd9Sstevel@tonic-gate  *	  decrement the ref cnt
1647c478bd9Sstevel@tonic-gate  *	  release the statep lock
1657c478bd9Sstevel@tonic-gate  *
1667c478bd9Sstevel@tonic-gate  * 3. INCOMING MRA
1677c478bd9Sstevel@tonic-gate  *
1687c478bd9Sstevel@tonic-gate  *	Acquire hca state table READER lock
1697c478bd9Sstevel@tonic-gate  *	Do lookup in active hca state tree by local com id
1707c478bd9Sstevel@tonic-gate  *	Release hca state table READER lock
1717c478bd9Sstevel@tonic-gate  *
1727c478bd9Sstevel@tonic-gate  *	If lookup does not exist
1737c478bd9Sstevel@tonic-gate  *		return
1747c478bd9Sstevel@tonic-gate  *
1757c478bd9Sstevel@tonic-gate  *	if look up exists
1767c478bd9Sstevel@tonic-gate  *		 incr statep->ref_cnt holding state mutex
1777c478bd9Sstevel@tonic-gate  *
1787c478bd9Sstevel@tonic-gate  *	acquire state mutex
1797c478bd9Sstevel@tonic-gate  *	if (state is REQ_SENT or REP_SENT)
1807c478bd9Sstevel@tonic-gate  *	  change state to REP WAIT or MRA REP RCVD
1817c478bd9Sstevel@tonic-gate  *	  release state mutex
1827c478bd9Sstevel@tonic-gate  *	  cancel the current timer
1837c478bd9Sstevel@tonic-gate  *
1847c478bd9Sstevel@tonic-gate  *	  reacquire state mutex
1857c478bd9Sstevel@tonic-gate  *	  if (state is REP_WAIT or MRA_REP_RCVD)
1867c478bd9Sstevel@tonic-gate  *		set new timer, using service timeout for the first timeout
1877c478bd9Sstevel@tonic-gate  *    decr ref cnt, release state mutex
1887c478bd9Sstevel@tonic-gate  *
1897c478bd9Sstevel@tonic-gate  * 4. INCOMING RTU
1907c478bd9Sstevel@tonic-gate  *
1917c478bd9Sstevel@tonic-gate  *	Acquire hca state table READER lock
1927c478bd9Sstevel@tonic-gate  *	Do lookup in active hca state tree by local com id
1937c478bd9Sstevel@tonic-gate  *	Release hca state table READER lock
1947c478bd9Sstevel@tonic-gate  *
1957c478bd9Sstevel@tonic-gate  *	If lookup does not exist
1967c478bd9Sstevel@tonic-gate  *		return
1977c478bd9Sstevel@tonic-gate  *
1987c478bd9Sstevel@tonic-gate  *	 if look up exists
1997c478bd9Sstevel@tonic-gate  *		 incr statep->ref_cnt holding state mutex
2007c478bd9Sstevel@tonic-gate  *
2017c478bd9Sstevel@tonic-gate  *	acquire statep mutex
2027c478bd9Sstevel@tonic-gate  *	if (state == REP_SENT or MRA REP RCVD))
2037c478bd9Sstevel@tonic-gate  *	  change state to ESTABLISHED
2047c478bd9Sstevel@tonic-gate  *	  release statep mutex
2057c478bd9Sstevel@tonic-gate  *	  cancel timer
2067c478bd9Sstevel@tonic-gate  *
2077c478bd9Sstevel@tonic-gate  *	  Change QP state
2087c478bd9Sstevel@tonic-gate  *
2097c478bd9Sstevel@tonic-gate  *	  acquire the statep mutex
2107c478bd9Sstevel@tonic-gate  *	decrement the ref count
2117c478bd9Sstevel@tonic-gate  *	release statep mutex
2127c478bd9Sstevel@tonic-gate  *
2137c478bd9Sstevel@tonic-gate  * 5. INCOMING REJ
2147c478bd9Sstevel@tonic-gate  *
2157c478bd9Sstevel@tonic-gate  *	Acquire hca state table READER lock
2167c478bd9Sstevel@tonic-gate  *	Do lookup in active hca state tree by local com id
2177c478bd9Sstevel@tonic-gate  *	Release hca state table READER lock
2187c478bd9Sstevel@tonic-gate  *
2197c478bd9Sstevel@tonic-gate  *	If lookup does not exist
2207c478bd9Sstevel@tonic-gate  *		return
2217c478bd9Sstevel@tonic-gate  *
2227c478bd9Sstevel@tonic-gate  *	if look up exists
2237c478bd9Sstevel@tonic-gate  *		 incr statep->ref_cnt holding state mutex
2247c478bd9Sstevel@tonic-gate  *
2257c478bd9Sstevel@tonic-gate  *	if (state == REQ RCVD or REP RCVD MRA_SENT or MRA_REP_SNET)
2267c478bd9Sstevel@tonic-gate  *	  set statep->delete = true
2277c478bd9Sstevel@tonic-gate  *	  decrement the ref_cnt
2287c478bd9Sstevel@tonic-gate  *	  release statep mutex;
2297c478bd9Sstevel@tonic-gate  *
2307c478bd9Sstevel@tonic-gate  *    else if (state == REQ_SENT or REP SENT or MRA REP Rcvd)
2317c478bd9Sstevel@tonic-gate  *	 state = IBCM_STATE_DELETE
2327c478bd9Sstevel@tonic-gate  *	 Cancel running timers
2337c478bd9Sstevel@tonic-gate  *	 decrement the ref_cnt
2347c478bd9Sstevel@tonic-gate  *	 release state mutex
2357c478bd9Sstevel@tonic-gate  *	 Call the client QP handler
2367c478bd9Sstevel@tonic-gate  *	 delete the state data
2377c478bd9Sstevel@tonic-gate  *
2387c478bd9Sstevel@tonic-gate  * 6. INCOMING DREQ
2397c478bd9Sstevel@tonic-gate  *
2407c478bd9Sstevel@tonic-gate  *	Acquire hca state table READER lock
2417c478bd9Sstevel@tonic-gate  *	Do lookup in active hca state tree by local com id
2427c478bd9Sstevel@tonic-gate  *	Release hca state table READER lock
2437c478bd9Sstevel@tonic-gate  *
2447c478bd9Sstevel@tonic-gate  *	If lookup does not exist
2457c478bd9Sstevel@tonic-gate  *		return
2467c478bd9Sstevel@tonic-gate  *
2477c478bd9Sstevel@tonic-gate  *	if look up exists
2487c478bd9Sstevel@tonic-gate  *		 incr statep->ref_cnt holding state mutex
2497c478bd9Sstevel@tonic-gate  *
2507c478bd9Sstevel@tonic-gate  *	acquire state mutex
2517c478bd9Sstevel@tonic-gate  *	if (state is ESTABLISHED/DREQ SENT/TIMEWAIT)
2527c478bd9Sstevel@tonic-gate  *	  if state is ESTABLISHED/DREQ SENT,
2537c478bd9Sstevel@tonic-gate  *		change state to DREQ RECVD
2547c478bd9Sstevel@tonic-gate  *		start timers
2557c478bd9Sstevel@tonic-gate  *
2567c478bd9Sstevel@tonic-gate  *    send DREP reply
2577c478bd9Sstevel@tonic-gate  *    decr ref_cnt
2587c478bd9Sstevel@tonic-gate  *    release state mutex
2597c478bd9Sstevel@tonic-gate  *
2607c478bd9Sstevel@tonic-gate  * 7.  Incoming DREP
2617c478bd9Sstevel@tonic-gate  *
2627c478bd9Sstevel@tonic-gate  *	Acquire hca state table READER lock
2637c478bd9Sstevel@tonic-gate  *	Do lookup in active hca state tree by local com id
2647c478bd9Sstevel@tonic-gate  *	Release hca state table READER lock
2657c478bd9Sstevel@tonic-gate  *
2667c478bd9Sstevel@tonic-gate  *	If lookup does not exist
2677c478bd9Sstevel@tonic-gate  *		return
2687c478bd9Sstevel@tonic-gate  *
2697c478bd9Sstevel@tonic-gate  *	if look up exists
2707c478bd9Sstevel@tonic-gate  *		 incr statep->ref_cnt holding state mutex
2717c478bd9Sstevel@tonic-gate  *
2727c478bd9Sstevel@tonic-gate  *	acquire state mutex
2737c478bd9Sstevel@tonic-gate  *	if state is DREQ_SENT
2747c478bd9Sstevel@tonic-gate  *	  change state to DREP_RCVD
2757c478bd9Sstevel@tonic-gate  *	  cancel timer
2767c478bd9Sstevel@tonic-gate  *	  change state to TIMEWAIT
2777c478bd9Sstevel@tonic-gate  *	  set timewait timer
2787c478bd9Sstevel@tonic-gate  *    decr ref_cnt
2797c478bd9Sstevel@tonic-gate  *    release state mutex
2807c478bd9Sstevel@tonic-gate  *
2817c478bd9Sstevel@tonic-gate  * 8. Timeout handler
2827c478bd9Sstevel@tonic-gate  *
2837c478bd9Sstevel@tonic-gate  *  (for states REQ SENT/REP SENT/REJ SENT/DREQ SENT/DREP SENT/TIMEWAIT)
2847c478bd9Sstevel@tonic-gate  *
2857c478bd9Sstevel@tonic-gate  *	 acquire the statep mutex
2867c478bd9Sstevel@tonic-gate  *
2877c478bd9Sstevel@tonic-gate  *	 if (set state != stored_state)
2887c478bd9Sstevel@tonic-gate  *	    The thread that changed the state is responsible for any cleanup
2897c478bd9Sstevel@tonic-gate  *	    decrement ref cnt
2907c478bd9Sstevel@tonic-gate  *	    release statep mutex
2917c478bd9Sstevel@tonic-gate  *	    return
2927c478bd9Sstevel@tonic-gate  *	 else if (statep's state == REJ SENT)
2937c478bd9Sstevel@tonic-gate  *		change state to DELETE
2947c478bd9Sstevel@tonic-gate  *		decrement ref cnt
2957c478bd9Sstevel@tonic-gate  *		release statep mutex
2967c478bd9Sstevel@tonic-gate  *		delete statep
2977c478bd9Sstevel@tonic-gate  *		return
2987c478bd9Sstevel@tonic-gate  *	 else if (state == TIME WAIT)
2997c478bd9Sstevel@tonic-gate  *		do the time wait state processing
3007c478bd9Sstevel@tonic-gate  *		decrement ref cnt
3017c478bd9Sstevel@tonic-gate  *		change state to DELETE
3027c478bd9Sstevel@tonic-gate  *		release statep mutex
3037c478bd9Sstevel@tonic-gate  *		delete statep, and also QP
3047c478bd9Sstevel@tonic-gate  *	 else if (remaining retry cnt > 0)
3057c478bd9Sstevel@tonic-gate  *		resend the mad
3067c478bd9Sstevel@tonic-gate  *		decrement ref cnt
3077c478bd9Sstevel@tonic-gate  *		release statep mutex
3087c478bd9Sstevel@tonic-gate  *	 else if (state == rep sent or req sent or mra rep rcvd or rep wait)
3097c478bd9Sstevel@tonic-gate  *		(retry counter expired)
3107c478bd9Sstevel@tonic-gate  *		change state to REJ SENT (No one shall delete in REJ SENT)
3117c478bd9Sstevel@tonic-gate  *		decrement the ref_cnt
3127c478bd9Sstevel@tonic-gate  *		release the statep mutex
3137c478bd9Sstevel@tonic-gate  *		Post REJ MAD
3147c478bd9Sstevel@tonic-gate  *		cv_signal anyone blocking
3157c478bd9Sstevel@tonic-gate  *		Invoke client handler
3167c478bd9Sstevel@tonic-gate  *	 else if state == DREQ_SENT
3177c478bd9Sstevel@tonic-gate  *		change state to TIME WAIT
3187c478bd9Sstevel@tonic-gate  *		decrement the ref cnt
3197c478bd9Sstevel@tonic-gate  *		set a timer for time wait time
3207c478bd9Sstevel@tonic-gate  *		release the statep mutex
3217c478bd9Sstevel@tonic-gate  *
3227c478bd9Sstevel@tonic-gate  *
3237c478bd9Sstevel@tonic-gate  * SIDR processing
3247c478bd9Sstevel@tonic-gate  *
3257c478bd9Sstevel@tonic-gate  * 9. INCOMING SIDR_REQ MAD
3267c478bd9Sstevel@tonic-gate  *
3277c478bd9Sstevel@tonic-gate  *    Figure out LID/GID
3287c478bd9Sstevel@tonic-gate  *    Do lookup in SIDR LIST based on LID, GID, grh_exists and req_id
3297c478bd9Sstevel@tonic-gate  *    increment ud_statep->ud_ref_cnt
3307c478bd9Sstevel@tonic-gate  *
3317c478bd9Sstevel@tonic-gate  *    If (new lookup)
3327c478bd9Sstevel@tonic-gate  *
3337c478bd9Sstevel@tonic-gate  *	  validate service id, and the create new statep,
3347c478bd9Sstevel@tonic-gate  *	  initialize key fields
3357c478bd9Sstevel@tonic-gate  *	  do a lookup based on service id
3367c478bd9Sstevel@tonic-gate  *	  if service_id_lookup returns exists
3377c478bd9Sstevel@tonic-gate  *		set sidr_status to QPN_VALID
3387c478bd9Sstevel@tonic-gate  *	  else
3397c478bd9Sstevel@tonic-gate  *		set sidr_status to SID_INVALID
3407c478bd9Sstevel@tonic-gate  *	  post SIDR_REP mad
3417c478bd9Sstevel@tonic-gate  *	  decr ud_statep->ud_ref_cnt, release ud_state_mutex
3427c478bd9Sstevel@tonic-gate  *
3437c478bd9Sstevel@tonic-gate  *    else if (existing lookup)
3447c478bd9Sstevel@tonic-gate  *
3457c478bd9Sstevel@tonic-gate  *	  if (ud_statep->ud_state is SIDR_REP_SENT)
3467c478bd9Sstevel@tonic-gate  *		resend the mad
3477c478bd9Sstevel@tonic-gate  *
3487c478bd9Sstevel@tonic-gate  *	  decr ud_statep->ud_ref_cnt, release ud_state_mutex
3497c478bd9Sstevel@tonic-gate  *
3507c478bd9Sstevel@tonic-gate  *
3517c478bd9Sstevel@tonic-gate  * 10. INCOMING SIDR_REP MAD
3527c478bd9Sstevel@tonic-gate  *
3537c478bd9Sstevel@tonic-gate  *    Figure out LID/GID
3547c478bd9Sstevel@tonic-gate  *    Do lookup in SIDR LIST based on LID, GID, grh_exists and req_id
3557c478bd9Sstevel@tonic-gate  *    increment ud_statep->ud_ref_cnt
3567c478bd9Sstevel@tonic-gate  *
3577c478bd9Sstevel@tonic-gate  *    if look up doesn't exists
3587c478bd9Sstevel@tonic-gate  *	  return
3597c478bd9Sstevel@tonic-gate  *
3607c478bd9Sstevel@tonic-gate  *    if (state == SIDR_REQ_SENT)
3617c478bd9Sstevel@tonic-gate  *	  first, change state to SIDR_REP_RCVD
3627c478bd9Sstevel@tonic-gate  *	  release statep lock
3637c478bd9Sstevel@tonic-gate  *	  cancel timers
3647c478bd9Sstevel@tonic-gate  *	  cv_signal anyone blocking
3657c478bd9Sstevel@tonic-gate  *	  release the statep lock
3667c478bd9Sstevel@tonic-gate  *	  extract return args
3677c478bd9Sstevel@tonic-gate  *	  destroy the statep
3687c478bd9Sstevel@tonic-gate  *
3697c478bd9Sstevel@tonic-gate  * 11. Timeout handler
3707c478bd9Sstevel@tonic-gate  *
3717c478bd9Sstevel@tonic-gate  *  (for states SIDR_REQ_SENT/SIDR_REP_SENT)
3727c478bd9Sstevel@tonic-gate  *
3737c478bd9Sstevel@tonic-gate  *	 acquire the statep mutex
3747c478bd9Sstevel@tonic-gate  *
3757c478bd9Sstevel@tonic-gate  *	 if (statep's state == SIDR_REP_SENT SENT)
3767c478bd9Sstevel@tonic-gate  *		change state to DELETE
3777c478bd9Sstevel@tonic-gate  *		decrement ref cnt
3787c478bd9Sstevel@tonic-gate  *		release statep mutex
3797c478bd9Sstevel@tonic-gate  *		delete statep
3807c478bd9Sstevel@tonic-gate  *		return
3817c478bd9Sstevel@tonic-gate  *	 else if (remaining retry cnt > 0 and state is SIDR_REQ_SENT)
3827c478bd9Sstevel@tonic-gate  *		resend the mad
3837c478bd9Sstevel@tonic-gate  *		decrement ref cnt
3847c478bd9Sstevel@tonic-gate  *		release statep mutex
3857c478bd9Sstevel@tonic-gate  *	 else if (state == SIDR_REQ_SENT)
3867c478bd9Sstevel@tonic-gate  *		(retry counter expired)
3877c478bd9Sstevel@tonic-gate  *		change state to DELETE
3887c478bd9Sstevel@tonic-gate  *		decrement the ref_cnt
3897c478bd9Sstevel@tonic-gate  *		the statep mutex
3907c478bd9Sstevel@tonic-gate  *		cv_signal anyone blocking
3917c478bd9Sstevel@tonic-gate  *		Invoke client handler
3927c478bd9Sstevel@tonic-gate  *		delete statep
3937c478bd9Sstevel@tonic-gate  */
3947c478bd9Sstevel@tonic-gate 
3957c478bd9Sstevel@tonic-gate /* Function prototypes */
3967c478bd9Sstevel@tonic-gate static void		ibcm_set_primary_adds_vect(ibcm_state_data_t *,
3977c478bd9Sstevel@tonic-gate 			    ibt_adds_vect_t *, ibcm_req_msg_t *);
3987c478bd9Sstevel@tonic-gate static void		ibcm_set_alt_adds_vect(ibcm_state_data_t *,
3997c478bd9Sstevel@tonic-gate 			    ibt_adds_vect_t *, ibcm_req_msg_t *);
4007c478bd9Sstevel@tonic-gate static ibt_status_t	ibcm_set_primary_cep_path(ibcm_state_data_t *,
4017c478bd9Sstevel@tonic-gate 			    ibt_cep_path_t *, ibcm_req_msg_t *);
4027c478bd9Sstevel@tonic-gate static ibt_status_t	ibcm_set_alt_cep_path(ibcm_state_data_t *,
4037c478bd9Sstevel@tonic-gate 			    ibt_cep_path_t *, ibcm_req_msg_t *);
4047c478bd9Sstevel@tonic-gate static ibt_status_t	ibcm_invoke_qp_modify(ibcm_state_data_t *,
4057c478bd9Sstevel@tonic-gate 			    ibcm_req_msg_t *, ibcm_rep_msg_t *);
4067c478bd9Sstevel@tonic-gate static ibt_status_t	ibcm_invoke_rtu_qp_modify(ibcm_state_data_t *,
4077c478bd9Sstevel@tonic-gate 			    ib_time_t, ibcm_rep_msg_t *);
4087c478bd9Sstevel@tonic-gate static ibcm_status_t	ibcm_sidr_req_ud_handler(ibcm_ud_state_data_t *,
4097c478bd9Sstevel@tonic-gate 			    ibcm_sidr_req_msg_t *, ibcm_mad_addr_t *,
4107c478bd9Sstevel@tonic-gate 			    ibt_sidr_status_t *);
4117c478bd9Sstevel@tonic-gate static void		ibcm_sidr_rep_ud_handler(ibcm_ud_state_data_t *,
4127c478bd9Sstevel@tonic-gate 			    ibcm_sidr_rep_msg_t *);
4137c478bd9Sstevel@tonic-gate static void		ibcm_handler_conn_fail(ibcm_state_data_t *,
4147c478bd9Sstevel@tonic-gate 			    uint8_t cf_code, uint8_t cf_msg,
4157c478bd9Sstevel@tonic-gate 			    ibt_cm_reason_t rej_reason, uint8_t *,
4167c478bd9Sstevel@tonic-gate 			    ibt_priv_data_len_t);
4177c478bd9Sstevel@tonic-gate static void		ibcm_build_n_post_rej_mad(uint8_t *input_madp,
4187c478bd9Sstevel@tonic-gate 			    ib_com_id_t, ibcm_mad_addr_t *, int, uint16_t);
4197c478bd9Sstevel@tonic-gate static void		ibcm_post_drep_mad(ibcm_state_data_t *);
4207c478bd9Sstevel@tonic-gate 
4217c478bd9Sstevel@tonic-gate static ibcm_status_t	ibcm_verify_req_gids_and_svcid(
4227c478bd9Sstevel@tonic-gate 			    ibcm_state_data_t *statep,
4237c478bd9Sstevel@tonic-gate 			    ibcm_req_msg_t *cm_req_msgp);
4247c478bd9Sstevel@tonic-gate 
4257c478bd9Sstevel@tonic-gate static void		ibcm_timeout_client_cb(ibcm_state_data_t *statep);
4267c478bd9Sstevel@tonic-gate static void		ibcm_ud_timeout_client_cb(
4277c478bd9Sstevel@tonic-gate 			    ibcm_ud_state_data_t *ud_statep);
4287c478bd9Sstevel@tonic-gate 
4297c478bd9Sstevel@tonic-gate static void		ibcm_process_dreq_timeout(ibcm_state_data_t *statep);
4307c478bd9Sstevel@tonic-gate 
4317c478bd9Sstevel@tonic-gate static void		ibcm_fill_adds_from_lap(ibt_adds_vect_t *adds,
4327c478bd9Sstevel@tonic-gate 			    ibcm_lap_msg_t *lap_msg, ibcm_mode_t mode);
4337c478bd9Sstevel@tonic-gate 
4347c478bd9Sstevel@tonic-gate static void		ibcm_post_stored_apr_mad(ibcm_state_data_t *statep,
4357c478bd9Sstevel@tonic-gate 			    uint8_t *input_madp);
4367c478bd9Sstevel@tonic-gate 
4377c478bd9Sstevel@tonic-gate static ibcm_status_t	ibcm_set_qp_from_apr(ibcm_state_data_t *statep,
4387c478bd9Sstevel@tonic-gate 			    ibcm_lap_msg_t *lap_msg);
4397c478bd9Sstevel@tonic-gate 
4407c478bd9Sstevel@tonic-gate static boolean_t	ibcm_compare_prim_alt_paths(ibt_adds_vect_t *prim,
4417c478bd9Sstevel@tonic-gate 			    ibt_adds_vect_t *alt);
4427c478bd9Sstevel@tonic-gate 
4437c478bd9Sstevel@tonic-gate static void		ibcm_process_get_classport_info(ibcm_hca_info_t *hcap,
4447c478bd9Sstevel@tonic-gate 			    uint8_t *input_madp, ibcm_mad_addr_t *cm_mad_addr);
4457c478bd9Sstevel@tonic-gate 
4467c478bd9Sstevel@tonic-gate static void		ibcm_decode_classport_info(ibcm_hca_info_t *hcap,
4477c478bd9Sstevel@tonic-gate 			    uint8_t *input_madp, ibcm_mad_addr_t *cm_mad_addr);
4487c478bd9Sstevel@tonic-gate 
4497c478bd9Sstevel@tonic-gate static void		ibcm_post_rej_ver_mismatch(uint8_t *input_madp,
4507c478bd9Sstevel@tonic-gate 			    ibcm_mad_addr_t *cm_mad_addr);
4517c478bd9Sstevel@tonic-gate 
4527c478bd9Sstevel@tonic-gate static void		ibcm_init_clp_to_mad(ibcm_classportinfo_msg_t *clp,
4537c478bd9Sstevel@tonic-gate 			    ibt_redirect_info_t *rinfo);
4547c478bd9Sstevel@tonic-gate 
4557c478bd9Sstevel@tonic-gate static void		ibcm_init_clp_from_mad(ibcm_classportinfo_msg_t *clp,
4567c478bd9Sstevel@tonic-gate 			    ibt_redirect_info_t *rinfo);
4577c478bd9Sstevel@tonic-gate 
4587c478bd9Sstevel@tonic-gate static void		ibcm_copy_addl_rej(ibcm_state_data_t *statep,
4597c478bd9Sstevel@tonic-gate 			    ibcm_rej_msg_t *rej_msgp,
4607c478bd9Sstevel@tonic-gate 			    ibt_cm_conn_failed_t *failed);
4617c478bd9Sstevel@tonic-gate 
4627c478bd9Sstevel@tonic-gate static void		ibcm_return_open_data(ibcm_state_data_t *statep,
4637c478bd9Sstevel@tonic-gate 			    ibcm_rep_msg_t *rep_msgp,
4647c478bd9Sstevel@tonic-gate 			    ibt_cm_reason_t reject_reason);
4657c478bd9Sstevel@tonic-gate 
4667c478bd9Sstevel@tonic-gate /* limit the number of taskq threads to handle received MADs. */
4677c478bd9Sstevel@tonic-gate int ibcm_recv_tasks = 0;
4687c478bd9Sstevel@tonic-gate int ibcm_max_recv_tasks = 24;
4697c478bd9Sstevel@tonic-gate int ibcm_recv_timeouts = 0;
4707c478bd9Sstevel@tonic-gate 
471934f0bccShiremath /*
472934f0bccShiremath  * Tunable MAX MRA Service Timeout value in MicroSECONDS.
473934f0bccShiremath  *	0 - Tunable parameter not used.
474934f0bccShiremath  *
475934f0bccShiremath  *	Ex:   60000000 - Max MRA Service Delay is 60 Seconds.
476934f0bccShiremath  */
477934f0bccShiremath clock_t ibcm_mra_service_timeout_max = 0;
478934f0bccShiremath 
4797c478bd9Sstevel@tonic-gate #ifdef	DEBUG
4807c478bd9Sstevel@tonic-gate 
4817c478bd9Sstevel@tonic-gate static void			print_modify_qp(char *prefix,
4827c478bd9Sstevel@tonic-gate 				    ibt_qp_hdl_t ibt_qp,
4837c478bd9Sstevel@tonic-gate 				    ibt_cep_modify_flags_t flags,
4847c478bd9Sstevel@tonic-gate 				    ibt_qp_info_t *qp_attr);
4857c478bd9Sstevel@tonic-gate #endif
4867c478bd9Sstevel@tonic-gate 
4877c478bd9Sstevel@tonic-gate /*	Warlock annotations */
4887c478bd9Sstevel@tonic-gate 
_NOTE(READ_ONLY_DATA (ibt_arej_info_u))4897c478bd9Sstevel@tonic-gate _NOTE(READ_ONLY_DATA(ibt_arej_info_u))
4907c478bd9Sstevel@tonic-gate 
4917c478bd9Sstevel@tonic-gate /*
4927c478bd9Sstevel@tonic-gate  * ibcm_process_incoming_mad:
4937c478bd9Sstevel@tonic-gate  *	The CM callback that is invoked by IBMF, when a valid CM MAD arrives
4947c478bd9Sstevel@tonic-gate  *	on any of the registered ibmf handles by CM.
4957c478bd9Sstevel@tonic-gate  *
4967c478bd9Sstevel@tonic-gate  *	It is assumed that the incoming MAD (except for incoming REQ) belongs
4977c478bd9Sstevel@tonic-gate  *	to a connection on the HCA, on which the MAD is received.
4987c478bd9Sstevel@tonic-gate  *	The IBMF callback arg specifies ibcm_hca_info_t
4997c478bd9Sstevel@tonic-gate  *
5007c478bd9Sstevel@tonic-gate  * NOTE: IBMF always invokes ibcm_recv_cb() in a taskq. CM does some memory
5017c478bd9Sstevel@tonic-gate  * allocations and invoke ibcm_sm_funcs_tbl[i]() in the same taskq.
5027c478bd9Sstevel@tonic-gate  *
5037c478bd9Sstevel@tonic-gate  * INPUTS:
5047c478bd9Sstevel@tonic-gate  *	ibmf_handle	- IBMF Handle
5057c478bd9Sstevel@tonic-gate  *	args		- from IBMF. Is a ptr to ibcm_hca_info_t
5067c478bd9Sstevel@tonic-gate  *	status		- Callback status. Is mostly IBMF_SUCCESS
5077c478bd9Sstevel@tonic-gate  *	madbuf		- IBMF allocated MAD buffer (CM should free it)
5087c478bd9Sstevel@tonic-gate  *	madaddr		- IBMF MAD's address
5097c478bd9Sstevel@tonic-gate  *	grhvalid	- If GRH is valid or not
5107c478bd9Sstevel@tonic-gate  *
5117c478bd9Sstevel@tonic-gate  * RETURN VALUES: NONE
5127c478bd9Sstevel@tonic-gate  */
5137c478bd9Sstevel@tonic-gate void
5147c478bd9Sstevel@tonic-gate ibcm_process_incoming_mad(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
5157c478bd9Sstevel@tonic-gate     void *args)
5167c478bd9Sstevel@tonic-gate {
5177c478bd9Sstevel@tonic-gate 	uint8_t			method;		/* Method type in MAD hdr */
5187c478bd9Sstevel@tonic-gate 	ib_mad_hdr_t		*in_mad_hdr;	/* Incoming MAD's header */
5197c478bd9Sstevel@tonic-gate 	ibcm_hca_info_t		*hcap;		/* pointer to HCA entry */
5207c478bd9Sstevel@tonic-gate 	ibcm_port_info_t	*portp;
5217c478bd9Sstevel@tonic-gate 	ibcm_mad_addr_t		*cm_mad_addr;	/* MAD address information */
5227c478bd9Sstevel@tonic-gate 	ibcm_event_type_t	attr_id;	/* Attribute ID in MAD hdr */
5237c478bd9Sstevel@tonic-gate 	ibcm_mad_addr_t		loc_mad_addr;	/* MAD address information */
5247c478bd9Sstevel@tonic-gate 	ibcm_qp_list_t		*cm_qp_entry;
5257c478bd9Sstevel@tonic-gate 	int			ibmf_status;
5267c478bd9Sstevel@tonic-gate 
5277c478bd9Sstevel@tonic-gate 
5287c478bd9Sstevel@tonic-gate 	/* Noticed that IBMF always calls with IBMF_SUCCESS, but still check */
5297c478bd9Sstevel@tonic-gate 	if (msgp->im_msg_status != IBMF_SUCCESS) {
5307c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
5317c478bd9Sstevel@tonic-gate 		    "bad status %x", msgp->im_msg_status);
5327c478bd9Sstevel@tonic-gate 		/* IBMF allocates Input MAD, so free it here */
5337c478bd9Sstevel@tonic-gate 		if ((ibmf_status = ibmf_free_msg(ibmf_handle, &msgp)) !=
5347c478bd9Sstevel@tonic-gate 		    IBMF_SUCCESS)
5357c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
5367c478bd9Sstevel@tonic-gate 			    "ibmf_free_msg failed %d", ibmf_status);
5377c478bd9Sstevel@tonic-gate 		return;
5387c478bd9Sstevel@tonic-gate 	}
5397c478bd9Sstevel@tonic-gate 
5407c478bd9Sstevel@tonic-gate 	/* Get the HCA entry pointer */
5417c478bd9Sstevel@tonic-gate 	cm_qp_entry = (ibcm_qp_list_t *)args;
5427c478bd9Sstevel@tonic-gate 
543fde3102fShiremath 	IBTF_DPRINTF_L5(cmlog, "ibcm_process_incoming_mad: ibmf_hdl %p "
5447c478bd9Sstevel@tonic-gate 	    "msg %p args %p", ibmf_handle, msgp, args);
5457c478bd9Sstevel@tonic-gate 
5467c478bd9Sstevel@tonic-gate #ifdef	DEBUG
5477c478bd9Sstevel@tonic-gate 	if (ibcm_test_mode > 1)
5487c478bd9Sstevel@tonic-gate 		ibcm_query_qp(ibmf_handle, cm_qp_entry->qp_cm);
5497c478bd9Sstevel@tonic-gate #endif
5507c478bd9Sstevel@tonic-gate 
5517c478bd9Sstevel@tonic-gate 	portp = cm_qp_entry->qp_port;
5527c478bd9Sstevel@tonic-gate 	hcap = portp->port_hcap;
5537c478bd9Sstevel@tonic-gate 
5547c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_incoming_mad: CM MAD on "
5557c478bd9Sstevel@tonic-gate 	    "port %d", portp->port_num);
5567c478bd9Sstevel@tonic-gate 
5577c478bd9Sstevel@tonic-gate 	/* Increment hca ref cnt, if HCA is in attached state, else fail */
5587c478bd9Sstevel@tonic-gate 	if (ibcm_inc_hca_acc_cnt(hcap) != IBCM_SUCCESS) {
5597c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
5607c478bd9Sstevel@tonic-gate 		    "hca not in attach state");
5617c478bd9Sstevel@tonic-gate 		/* IBMF allocates Input MAD, and ibcm free's it */
5627c478bd9Sstevel@tonic-gate 		if ((ibmf_status = ibmf_free_msg(ibmf_handle, &msgp)) !=
5637c478bd9Sstevel@tonic-gate 		    IBMF_SUCCESS)
5647c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
5657c478bd9Sstevel@tonic-gate 			    "ibmf_free_msg failed %d", ibmf_status);
5667c478bd9Sstevel@tonic-gate 		return;
5677c478bd9Sstevel@tonic-gate 	}
5687c478bd9Sstevel@tonic-gate 
5697c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*cm_mad_addr))
5707c478bd9Sstevel@tonic-gate 
5717c478bd9Sstevel@tonic-gate 	/* allocate memory for internal MAD address buffer */
5727c478bd9Sstevel@tonic-gate 	cm_mad_addr = &loc_mad_addr;
5737c478bd9Sstevel@tonic-gate 	bzero(cm_mad_addr, sizeof (ibcm_mad_addr_t));
5747c478bd9Sstevel@tonic-gate 
5757c478bd9Sstevel@tonic-gate 	cm_mad_addr->port_num = portp->port_num;
5767c478bd9Sstevel@tonic-gate 
5777c478bd9Sstevel@tonic-gate 	/* initialize cm_mad_addr field(s) */
5787c478bd9Sstevel@tonic-gate 	in_mad_hdr = msgp->im_msgbufs_recv.im_bufs_mad_hdr;
5797c478bd9Sstevel@tonic-gate 
5807c478bd9Sstevel@tonic-gate 	if (in_mad_hdr->MgmtClass != MAD_MGMT_CLASS_COMM_MGT) {
5817c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
5827c478bd9Sstevel@tonic-gate 		    "bad mgmt class %x", in_mad_hdr->MgmtClass);
5837c478bd9Sstevel@tonic-gate 		if ((ibmf_status = ibmf_free_msg(ibmf_handle, &msgp)) !=
5847c478bd9Sstevel@tonic-gate 		    IBMF_SUCCESS)
5857c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
5867c478bd9Sstevel@tonic-gate 			    "ibmf_free_msg failed %d", ibmf_status);
5877c478bd9Sstevel@tonic-gate 		ibcm_dec_hca_acc_cnt(hcap);
5887c478bd9Sstevel@tonic-gate 		return;
5897c478bd9Sstevel@tonic-gate 	}
5907c478bd9Sstevel@tonic-gate 
5917c478bd9Sstevel@tonic-gate 	cm_mad_addr->rcvd_addr = msgp->im_local_addr;
5927c478bd9Sstevel@tonic-gate 	if (msgp->im_msg_flags & IBMF_MSG_FLAGS_GLOBAL_ADDRESS) {
5937c478bd9Sstevel@tonic-gate 		cm_mad_addr->grh_hdr = msgp->im_global_addr;
5947c478bd9Sstevel@tonic-gate 		cm_mad_addr->grh_exists = B_TRUE;
5957c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L3(cmlog, "ibcm_process_incoming_mad: "
5967c478bd9Sstevel@tonic-gate 		    "CM recv GID GUID %llX sender GID GUID %llX",
5977c478bd9Sstevel@tonic-gate 		    msgp->im_global_addr.ig_recver_gid.gid_guid,
5987c478bd9Sstevel@tonic-gate 		    msgp->im_global_addr.ig_sender_gid.gid_guid);
5997c478bd9Sstevel@tonic-gate 	}
6007c478bd9Sstevel@tonic-gate 
6017c478bd9Sstevel@tonic-gate 	/* Save IBMF handle and ibmf qp related information */
6027c478bd9Sstevel@tonic-gate 	cm_mad_addr->ibmf_hdl = ibmf_handle;
6037c478bd9Sstevel@tonic-gate 	cm_mad_addr->cm_qp_entry = cm_qp_entry;
6047c478bd9Sstevel@tonic-gate 
6057c478bd9Sstevel@tonic-gate 	/* IBMF does not initialize ia_p_key for non-QP1's */
6067c478bd9Sstevel@tonic-gate 	if (cm_qp_entry->qp_cm != IBMF_QP_HANDLE_DEFAULT)
6077c478bd9Sstevel@tonic-gate 		cm_mad_addr->rcvd_addr.ia_p_key = cm_qp_entry->qp_pkey;
6087c478bd9Sstevel@tonic-gate 
6097c478bd9Sstevel@tonic-gate 	if (cm_mad_addr->rcvd_addr.ia_p_key & 0x8000)
6107c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L5(cmlog, "ibcm_process_incoming_mad: PKEY %x",
6117c478bd9Sstevel@tonic-gate 		    cm_mad_addr->rcvd_addr.ia_p_key);
6127c478bd9Sstevel@tonic-gate 	else
6137c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: CM MAD "
6147c478bd9Sstevel@tonic-gate 		    "arrived from limited PKEY %x",
6157c478bd9Sstevel@tonic-gate 		    cm_mad_addr->rcvd_addr.ia_p_key);
6167c478bd9Sstevel@tonic-gate 
6177c478bd9Sstevel@tonic-gate 	/* Retrieve the method and Attr-Id from generic mad header */
6187c478bd9Sstevel@tonic-gate 	method = in_mad_hdr->R_Method;
6197c478bd9Sstevel@tonic-gate 	attr_id = b2h16(in_mad_hdr->AttributeID);
6207c478bd9Sstevel@tonic-gate 
6217c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_incoming_mad: "
6227c478bd9Sstevel@tonic-gate 	    "Method %x Attribute %x", method, attr_id);
6237c478bd9Sstevel@tonic-gate 
6247c478bd9Sstevel@tonic-gate 	if (in_mad_hdr->ClassVersion != IBCM_MAD_CLASS_VERSION) {
6257c478bd9Sstevel@tonic-gate 
6267c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
6277c478bd9Sstevel@tonic-gate 		    "unsupported ibcm class version %x",
6287c478bd9Sstevel@tonic-gate 		    in_mad_hdr->ClassVersion);
6297c478bd9Sstevel@tonic-gate 
6307c478bd9Sstevel@tonic-gate 		if (attr_id == (IBCM_INCOMING_REQ + IBCM_ATTR_BASE_ID))
6317c478bd9Sstevel@tonic-gate 			ibcm_post_rej_ver_mismatch(
6327c478bd9Sstevel@tonic-gate 			    (uint8_t *)IBCM_IN_HDRP(msgp), cm_mad_addr);
6337c478bd9Sstevel@tonic-gate 
6347c478bd9Sstevel@tonic-gate 		if ((ibmf_status = ibmf_free_msg(ibmf_handle, &msgp)) !=
6357c478bd9Sstevel@tonic-gate 		    IBMF_SUCCESS)
6367c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
6377c478bd9Sstevel@tonic-gate 			    "ibmf_free_msg failed %d", ibmf_status);
6387c478bd9Sstevel@tonic-gate 		ibcm_dec_hca_acc_cnt(hcap);
6397c478bd9Sstevel@tonic-gate 		return;
6407c478bd9Sstevel@tonic-gate 	}
6417c478bd9Sstevel@tonic-gate 
6427c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_incoming_mad: "
6437c478bd9Sstevel@tonic-gate 	    "Transaction Id 0x%llX", b2h64(in_mad_hdr->TransactionID));
6447c478bd9Sstevel@tonic-gate 
6457c478bd9Sstevel@tonic-gate #ifdef	DEBUG
6467c478bd9Sstevel@tonic-gate 	ibcm_decode_tranid(b2h64(in_mad_hdr->TransactionID), NULL);
6477c478bd9Sstevel@tonic-gate #endif
6487c478bd9Sstevel@tonic-gate 
6497c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*cm_mad_addr))
6507c478bd9Sstevel@tonic-gate 
6517c478bd9Sstevel@tonic-gate 	/*
6527c478bd9Sstevel@tonic-gate 	 * The following are valid combination of Method type
6537c478bd9Sstevel@tonic-gate 	 * and attribute id in the received MAD :-
6547c478bd9Sstevel@tonic-gate 	 *	o ClassPortInfo with Get method
6557c478bd9Sstevel@tonic-gate 	 *	o CM messages with Send method
6567c478bd9Sstevel@tonic-gate 	 */
6577c478bd9Sstevel@tonic-gate 	if ((attr_id == MAD_ATTR_ID_CLASSPORTINFO) &&
6587c478bd9Sstevel@tonic-gate 	    ((method == MAD_METHOD_GET) ||
6597c478bd9Sstevel@tonic-gate 	    (method == MAD_METHOD_GET_RESPONSE))) {
6607c478bd9Sstevel@tonic-gate 		if (method == MAD_METHOD_GET)
6617c478bd9Sstevel@tonic-gate 			ibcm_process_get_classport_info(hcap,
6627c478bd9Sstevel@tonic-gate 			    (uint8_t *)IBCM_IN_HDRP(msgp), cm_mad_addr);
6637c478bd9Sstevel@tonic-gate 		else if (method == MAD_METHOD_GET_RESPONSE)
6647c478bd9Sstevel@tonic-gate 			ibcm_decode_classport_info(hcap,
6657c478bd9Sstevel@tonic-gate 			    (uint8_t *)IBCM_IN_HDRP(msgp), cm_mad_addr);
6667c478bd9Sstevel@tonic-gate 	} else if ((attr_id >= IBCM_ATTR_BASE_ID) &&
6677c478bd9Sstevel@tonic-gate 	    (attr_id < (IBCM_ATTR_BASE_ID + IBCM_MAX_EVENTS)) &&
6687c478bd9Sstevel@tonic-gate 	    (method == MAD_METHOD_SEND)) {
6697c478bd9Sstevel@tonic-gate 
6707c478bd9Sstevel@tonic-gate 		attr_id -= IBCM_ATTR_BASE_ID;	/* figure out CM message id */
6717c478bd9Sstevel@tonic-gate 
6727c478bd9Sstevel@tonic-gate 		ASSERT(msgp->im_msgbufs_recv.im_bufs_mad_hdr != NULL);
6737c478bd9Sstevel@tonic-gate 
6747c478bd9Sstevel@tonic-gate 		/* Call the CM process connection state function */
6757c478bd9Sstevel@tonic-gate 		ibcm_sm_funcs_tbl[attr_id](hcap,
6767c478bd9Sstevel@tonic-gate 		    (uint8_t *)IBCM_IN_HDRP(msgp), cm_mad_addr);
6777c478bd9Sstevel@tonic-gate 	} else {
6787c478bd9Sstevel@tonic-gate 		/*
6797c478bd9Sstevel@tonic-gate 		 * Any other combination of method and attribute are invalid,
6807c478bd9Sstevel@tonic-gate 		 * hence drop the MAD
6817c478bd9Sstevel@tonic-gate 		 */
6827c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
6837c478bd9Sstevel@tonic-gate 		    "unknown Method %x or Attribute %x", method, attr_id);
6847c478bd9Sstevel@tonic-gate 	}
6857c478bd9Sstevel@tonic-gate 
6867c478bd9Sstevel@tonic-gate 	/* decrement the hcap access reference count */
6877c478bd9Sstevel@tonic-gate 	ibcm_dec_hca_acc_cnt(hcap);
6887c478bd9Sstevel@tonic-gate 
6897c478bd9Sstevel@tonic-gate 	/* ASSERT(NO_LOCKS_HELD); */
6907c478bd9Sstevel@tonic-gate 
6917c478bd9Sstevel@tonic-gate 	/* free up ibmf msgp  */
6927c478bd9Sstevel@tonic-gate 	if ((ibmf_status = ibmf_free_msg(ibmf_handle, &msgp)) != IBMF_SUCCESS)
6937c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
6947c478bd9Sstevel@tonic-gate 		    "ibmf_free_msg failed %d", ibmf_status);
6957c478bd9Sstevel@tonic-gate }
6967c478bd9Sstevel@tonic-gate 
6977c478bd9Sstevel@tonic-gate /*
6987c478bd9Sstevel@tonic-gate  * Structure to carry the arguments from ibcm_recv_cb() to
6997c478bd9Sstevel@tonic-gate  * ibcm_recv_incoming_mad() via taskq_dispatch
7007c478bd9Sstevel@tonic-gate  */
7017c478bd9Sstevel@tonic-gate typedef struct ibcm_taskq_args_s {
7027c478bd9Sstevel@tonic-gate 	ibmf_handle_t	tq_ibmf_handle;
7037c478bd9Sstevel@tonic-gate 	ibmf_msg_t	*tq_ibmf_msgp;
7047c478bd9Sstevel@tonic-gate 	void		*tq_args;
7057c478bd9Sstevel@tonic-gate } ibcm_taskq_args_t;
7067c478bd9Sstevel@tonic-gate 
707fde3102fShiremath #define	IBCM_RECV_MAX	128
7087c478bd9Sstevel@tonic-gate ibcm_taskq_args_t ibcm_recv_array[IBCM_RECV_MAX + 1];
7097c478bd9Sstevel@tonic-gate int ibcm_get, ibcm_put;
7107c478bd9Sstevel@tonic-gate int ibcm_recv_total;
7117c478bd9Sstevel@tonic-gate int ibcm_recv_queued;
7127c478bd9Sstevel@tonic-gate 
_NOTE(READ_ONLY_DATA (ibcm_taskq_args_t))7137c478bd9Sstevel@tonic-gate _NOTE(READ_ONLY_DATA(ibcm_taskq_args_t))
7147c478bd9Sstevel@tonic-gate 
7157c478bd9Sstevel@tonic-gate static int
7167c478bd9Sstevel@tonic-gate ibcm_recv_dequeue(ibmf_handle_t *ibmf_handlep, ibmf_msg_t **msgpp, void **argsp)
7177c478bd9Sstevel@tonic-gate {
7187c478bd9Sstevel@tonic-gate 	ibcm_taskq_args_t *tq;
7197c478bd9Sstevel@tonic-gate 
7207c478bd9Sstevel@tonic-gate 	if (ibcm_put == ibcm_get)
7217c478bd9Sstevel@tonic-gate 		return (0);
7227c478bd9Sstevel@tonic-gate 
7237c478bd9Sstevel@tonic-gate 	if (++ibcm_get >= IBCM_RECV_MAX)
7247c478bd9Sstevel@tonic-gate 		ibcm_get = 0;
7257c478bd9Sstevel@tonic-gate 	tq = ibcm_recv_array + ibcm_get;
7267c478bd9Sstevel@tonic-gate 	*ibmf_handlep = tq->tq_ibmf_handle;
7277c478bd9Sstevel@tonic-gate 	*msgpp = tq->tq_ibmf_msgp;
7287c478bd9Sstevel@tonic-gate 	*argsp = tq->tq_args;
7297c478bd9Sstevel@tonic-gate 	return (1);
7307c478bd9Sstevel@tonic-gate }
7317c478bd9Sstevel@tonic-gate 
7327c478bd9Sstevel@tonic-gate static int
ibcm_recv_enqueue(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)7337c478bd9Sstevel@tonic-gate ibcm_recv_enqueue(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, void *args)
7347c478bd9Sstevel@tonic-gate {
7357c478bd9Sstevel@tonic-gate 	int next;
7367c478bd9Sstevel@tonic-gate 	ibcm_taskq_args_t *tq;
7377c478bd9Sstevel@tonic-gate 
7387c478bd9Sstevel@tonic-gate 	ASSERT(MUTEX_HELD(&ibcm_recv_mutex));
7397c478bd9Sstevel@tonic-gate 	next = ibcm_put + 1;
7407c478bd9Sstevel@tonic-gate 	if (next >= IBCM_RECV_MAX)
7417c478bd9Sstevel@tonic-gate 		next = 0;
7427c478bd9Sstevel@tonic-gate 	if (next != ibcm_get) {
7437c478bd9Sstevel@tonic-gate 		ibcm_recv_queued++;
7447c478bd9Sstevel@tonic-gate 		ibcm_put = next;
7457c478bd9Sstevel@tonic-gate 		tq = ibcm_recv_array + next;
7467c478bd9Sstevel@tonic-gate 		_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*tq))
7477c478bd9Sstevel@tonic-gate 		tq->tq_ibmf_handle = ibmf_handle;
7487c478bd9Sstevel@tonic-gate 		tq->tq_ibmf_msgp = msgp;
7497c478bd9Sstevel@tonic-gate 		tq->tq_args = args;
7507c478bd9Sstevel@tonic-gate 		_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*tq))
7517c478bd9Sstevel@tonic-gate 		return (1);
7527c478bd9Sstevel@tonic-gate 	} else {
7537c478bd9Sstevel@tonic-gate 		return (0);
7547c478bd9Sstevel@tonic-gate 	}
7557c478bd9Sstevel@tonic-gate }
7567c478bd9Sstevel@tonic-gate 
7577c478bd9Sstevel@tonic-gate void
ibcm_drop_msg(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp)7587c478bd9Sstevel@tonic-gate ibcm_drop_msg(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp)
7597c478bd9Sstevel@tonic-gate {
7607c478bd9Sstevel@tonic-gate 	int ibmf_status;
7617c478bd9Sstevel@tonic-gate 
7627c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L2(cmlog, "ibcm_drop_msg: discarding MAD");
7637c478bd9Sstevel@tonic-gate 
7647c478bd9Sstevel@tonic-gate 	if ((ibmf_status = ibmf_free_msg(ibmf_handle, &msgp)) != IBMF_SUCCESS)
7657c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_drop_msg: "
7667c478bd9Sstevel@tonic-gate 		    "ibmf_free_msg failed %d", ibmf_status);
7677c478bd9Sstevel@tonic-gate }
7687c478bd9Sstevel@tonic-gate 
7697c478bd9Sstevel@tonic-gate /*
7707c478bd9Sstevel@tonic-gate  * Processing done in taskq thread.
7717c478bd9Sstevel@tonic-gate  *
7727c478bd9Sstevel@tonic-gate  * Calls ibcm_process_incoming_mad with all function arguments extracted
7737c478bd9Sstevel@tonic-gate  * from args.  Afterwards, check for queued requests.
7747c478bd9Sstevel@tonic-gate  */
7757c478bd9Sstevel@tonic-gate static void
ibcm_recv_task(void * args)7767c478bd9Sstevel@tonic-gate ibcm_recv_task(void *args)
7777c478bd9Sstevel@tonic-gate {
7787c478bd9Sstevel@tonic-gate 	ibcm_taskq_args_t *taskq_args;
7797c478bd9Sstevel@tonic-gate 	ibmf_handle_t ibmf_handle;
7807c478bd9Sstevel@tonic-gate 	ibmf_msg_t *msgp;
7817c478bd9Sstevel@tonic-gate 
7827c478bd9Sstevel@tonic-gate 	taskq_args = (ibcm_taskq_args_t *)args;
7837c478bd9Sstevel@tonic-gate 
7847c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_recv_task: Processing incoming MAD"
7857c478bd9Sstevel@tonic-gate 	    " via taskq");
7867c478bd9Sstevel@tonic-gate 
7877c478bd9Sstevel@tonic-gate 	ibcm_process_incoming_mad(taskq_args->tq_ibmf_handle,
7887c478bd9Sstevel@tonic-gate 	    taskq_args->tq_ibmf_msgp, taskq_args->tq_args);
7897c478bd9Sstevel@tonic-gate 
7907c478bd9Sstevel@tonic-gate 	kmem_free(taskq_args, sizeof (ibcm_taskq_args_t));
7917c478bd9Sstevel@tonic-gate 
7927c478bd9Sstevel@tonic-gate 	/* process queued entries before giving up this thread */
7937c478bd9Sstevel@tonic-gate 	mutex_enter(&ibcm_recv_mutex);
7947c478bd9Sstevel@tonic-gate 	while (ibcm_recv_dequeue(&ibmf_handle, &msgp, &args)) {
7957c478bd9Sstevel@tonic-gate 		mutex_exit(&ibcm_recv_mutex);
7967c478bd9Sstevel@tonic-gate 		ibcm_process_incoming_mad(ibmf_handle, msgp, args);
7977c478bd9Sstevel@tonic-gate 		mutex_enter(&ibcm_recv_mutex);
7987c478bd9Sstevel@tonic-gate 	}
7997c478bd9Sstevel@tonic-gate 	--ibcm_recv_tasks;
8007c478bd9Sstevel@tonic-gate 	mutex_exit(&ibcm_recv_mutex);
8017c478bd9Sstevel@tonic-gate }
8027c478bd9Sstevel@tonic-gate 
8037c478bd9Sstevel@tonic-gate static void
ibcm_recv_timeout_cb(void * args)8047c478bd9Sstevel@tonic-gate ibcm_recv_timeout_cb(void *args)
8057c478bd9Sstevel@tonic-gate {
8067c478bd9Sstevel@tonic-gate 	ibcm_taskq_args_t *tq = (ibcm_taskq_args_t *)args;
8077c478bd9Sstevel@tonic-gate 	int rv = 1;
8087c478bd9Sstevel@tonic-gate 
8097c478bd9Sstevel@tonic-gate 	mutex_enter(&ibcm_recv_mutex);
8107c478bd9Sstevel@tonic-gate 	ibcm_recv_timeouts--;
8117c478bd9Sstevel@tonic-gate 	if (ibcm_recv_tasks == 0) {
8127c478bd9Sstevel@tonic-gate 		ibcm_recv_tasks++;
8137c478bd9Sstevel@tonic-gate 		mutex_exit(&ibcm_recv_mutex);
8147c478bd9Sstevel@tonic-gate 		if (taskq_dispatch(ibcm_taskq, ibcm_recv_task, tq,
815fc8ae2ecSToomas Soome 		    TQ_NOQUEUE | TQ_NOSLEEP) == TASKQID_INVALID) {
8167c478bd9Sstevel@tonic-gate 			mutex_enter(&ibcm_recv_mutex);
8177c478bd9Sstevel@tonic-gate 			if (--ibcm_recv_tasks == 0) {
8187c478bd9Sstevel@tonic-gate 				(void) timeout(ibcm_recv_timeout_cb, tq, 1);
8197c478bd9Sstevel@tonic-gate 				ibcm_recv_timeouts++;
8207c478bd9Sstevel@tonic-gate 			} else {
8217c478bd9Sstevel@tonic-gate 				rv = ibcm_recv_enqueue(tq->tq_ibmf_handle,
8227c478bd9Sstevel@tonic-gate 				    tq->tq_ibmf_msgp, tq->tq_args);
8237c478bd9Sstevel@tonic-gate 				kmem_free(tq, sizeof (*tq));
8247c478bd9Sstevel@tonic-gate 			}
8257c478bd9Sstevel@tonic-gate 			mutex_exit(&ibcm_recv_mutex);
8267c478bd9Sstevel@tonic-gate 		}
8277c478bd9Sstevel@tonic-gate 	} else {
8287c478bd9Sstevel@tonic-gate 		/*
8297c478bd9Sstevel@tonic-gate 		 * one or more taskq threads are running now
8307c478bd9Sstevel@tonic-gate 		 * so just try to enqueue this one.
8317c478bd9Sstevel@tonic-gate 		 */
8327c478bd9Sstevel@tonic-gate 		rv = ibcm_recv_enqueue(tq->tq_ibmf_handle,
8337c478bd9Sstevel@tonic-gate 		    tq->tq_ibmf_msgp, tq->tq_args);
8347c478bd9Sstevel@tonic-gate 		kmem_free(tq, sizeof (*tq));
8357c478bd9Sstevel@tonic-gate 		mutex_exit(&ibcm_recv_mutex);
8367c478bd9Sstevel@tonic-gate 	}
8377c478bd9Sstevel@tonic-gate 	if (rv == 0)
8387c478bd9Sstevel@tonic-gate 		ibcm_drop_msg(tq->tq_ibmf_handle, tq->tq_ibmf_msgp);
8397c478bd9Sstevel@tonic-gate }
8407c478bd9Sstevel@tonic-gate 
8417c478bd9Sstevel@tonic-gate /*
8427c478bd9Sstevel@tonic-gate  * Dispatch to taskq if we're not using many, else just queue it
8437c478bd9Sstevel@tonic-gate  * and have the taskq thread pick it up.  Return 0 if we're dropping it.
8447c478bd9Sstevel@tonic-gate  */
8457c478bd9Sstevel@tonic-gate static int
ibcm_recv_add_one(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)8467c478bd9Sstevel@tonic-gate ibcm_recv_add_one(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, void *args)
8477c478bd9Sstevel@tonic-gate {
8487c478bd9Sstevel@tonic-gate 	int rv;
8497c478bd9Sstevel@tonic-gate 	ibcm_taskq_args_t *tq;
8507c478bd9Sstevel@tonic-gate 
8517c478bd9Sstevel@tonic-gate 	mutex_enter(&ibcm_recv_mutex);
8527c478bd9Sstevel@tonic-gate 	ibcm_recv_total++;
8537c478bd9Sstevel@tonic-gate 	if (ibcm_recv_tasks >= ibcm_max_recv_tasks) { /* just queue this one */
8547c478bd9Sstevel@tonic-gate 		rv = ibcm_recv_enqueue(ibmf_handle, msgp, args);
8557c478bd9Sstevel@tonic-gate 		mutex_exit(&ibcm_recv_mutex);
8567c478bd9Sstevel@tonic-gate 		return (rv);
8577c478bd9Sstevel@tonic-gate 	} else {
8587c478bd9Sstevel@tonic-gate 		ibcm_recv_tasks++; /* dispatch this one to a taskq thread */
8597c478bd9Sstevel@tonic-gate 		mutex_exit(&ibcm_recv_mutex);
8607c478bd9Sstevel@tonic-gate 		tq = kmem_alloc(sizeof (*tq), KM_NOSLEEP);
8617c478bd9Sstevel@tonic-gate 		if (tq == NULL) {
8627c478bd9Sstevel@tonic-gate 			mutex_enter(&ibcm_recv_mutex);
8637c478bd9Sstevel@tonic-gate 			if (--ibcm_recv_tasks > 0)
8647c478bd9Sstevel@tonic-gate 				rv = ibcm_recv_enqueue(ibmf_handle, msgp, args);
8657c478bd9Sstevel@tonic-gate 			else	/* don't enqueue if no threads are running */
8667c478bd9Sstevel@tonic-gate 				rv = 0;
8677c478bd9Sstevel@tonic-gate 			mutex_exit(&ibcm_recv_mutex);
8687c478bd9Sstevel@tonic-gate 			return (rv);
8697c478bd9Sstevel@tonic-gate 		}
8707c478bd9Sstevel@tonic-gate 		_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*tq))
8717c478bd9Sstevel@tonic-gate 		tq->tq_ibmf_handle = ibmf_handle;
8727c478bd9Sstevel@tonic-gate 		tq->tq_ibmf_msgp = msgp;
8737c478bd9Sstevel@tonic-gate 		tq->tq_args = args;
8747c478bd9Sstevel@tonic-gate 		_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*tq))
8757c478bd9Sstevel@tonic-gate 		if (taskq_dispatch(ibcm_taskq, ibcm_recv_task, tq,
876fc8ae2ecSToomas Soome 		    TQ_NOQUEUE | TQ_NOSLEEP) == TASKQID_INVALID) {
877fc8ae2ecSToomas Soome 			/* dispatch failed */
8787c478bd9Sstevel@tonic-gate 			mutex_enter(&ibcm_recv_mutex);
8797c478bd9Sstevel@tonic-gate 			if (--ibcm_recv_tasks == 0) {
8807c478bd9Sstevel@tonic-gate 				/* try the dispatch again, after a tick */
8817c478bd9Sstevel@tonic-gate 				(void) timeout(ibcm_recv_timeout_cb, tq, 1);
8827c478bd9Sstevel@tonic-gate 				ibcm_recv_timeouts++;
8837c478bd9Sstevel@tonic-gate 				rv = 1;	/* indicate success */
8847c478bd9Sstevel@tonic-gate 			} else {
8857c478bd9Sstevel@tonic-gate 				rv = ibcm_recv_enqueue(ibmf_handle, msgp, args);
8867c478bd9Sstevel@tonic-gate 				kmem_free(tq, sizeof (*tq));
8877c478bd9Sstevel@tonic-gate 			}
8887c478bd9Sstevel@tonic-gate 			mutex_exit(&ibcm_recv_mutex);
8897c478bd9Sstevel@tonic-gate 			return (rv);
8907c478bd9Sstevel@tonic-gate 		} else {
8917c478bd9Sstevel@tonic-gate 			return (1);
8927c478bd9Sstevel@tonic-gate 		}
8937c478bd9Sstevel@tonic-gate 	}
8947c478bd9Sstevel@tonic-gate }
8957c478bd9Sstevel@tonic-gate 
8967c478bd9Sstevel@tonic-gate /*
8977c478bd9Sstevel@tonic-gate  * ibcm_recv_cb:
8987c478bd9Sstevel@tonic-gate  *	The CM callback that is invoked by IBMF, when a valid CM MAD arrives
8997c478bd9Sstevel@tonic-gate  *	on any of the registered ibmf handles by CM.
9007c478bd9Sstevel@tonic-gate  *
9017c478bd9Sstevel@tonic-gate  * INPUTS:
9027c478bd9Sstevel@tonic-gate  *	ibmf_handle	- IBMF Handle
9037c478bd9Sstevel@tonic-gate  *	msgp		- IBMF msg containing the MAD (allocated by IBMF)
9047c478bd9Sstevel@tonic-gate  *	args		- Ptr to ibcm_hca_info_t
9057c478bd9Sstevel@tonic-gate  *
9067c478bd9Sstevel@tonic-gate  * RETURN VALUES: NONE
9077c478bd9Sstevel@tonic-gate  */
9087c478bd9Sstevel@tonic-gate void
ibcm_recv_cb(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)9097c478bd9Sstevel@tonic-gate ibcm_recv_cb(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, void *args)
9107c478bd9Sstevel@tonic-gate {
9117c478bd9Sstevel@tonic-gate 	if (ibcm_recv_add_one(ibmf_handle, msgp, args) == 0)
9127c478bd9Sstevel@tonic-gate 		ibcm_drop_msg(ibmf_handle, msgp);
9137c478bd9Sstevel@tonic-gate }
9147c478bd9Sstevel@tonic-gate 
9157c478bd9Sstevel@tonic-gate /*
9167c478bd9Sstevel@tonic-gate  * ibcm_process_req_msg:
9177c478bd9Sstevel@tonic-gate  *	PASSIVE SIDE CM
9187c478bd9Sstevel@tonic-gate  *	Called from ibcm_process_incoming_mad on reception of a REQ message
9197c478bd9Sstevel@tonic-gate  *
9207c478bd9Sstevel@tonic-gate  * Description:
921*f248c5e0SToomas Soome  *	If it a new REQ (not duplicate)
9227c478bd9Sstevel@tonic-gate  *		creates a new state structure in passive connection mode
9237c478bd9Sstevel@tonic-gate  *		populate state structure fields
9247c478bd9Sstevel@tonic-gate  *		inserts state structure in hca active and passive trees
9257c478bd9Sstevel@tonic-gate  *		validates service id
9267c478bd9Sstevel@tonic-gate  *		validates primary and alternate lid/gid in REQ,
9277c478bd9Sstevel@tonic-gate  *		calls QP state transition function
9287c478bd9Sstevel@tonic-gate  *		generates REP/REJ response
9297c478bd9Sstevel@tonic-gate  *		stores the response MAD in state structure for future re-sends
9307c478bd9Sstevel@tonic-gate  *		initializes timers as required
9317c478bd9Sstevel@tonic-gate  *	If a duplicate REQ, action depends upon current state in the state
9327c478bd9Sstevel@tonic-gate  *	structure
9337c478bd9Sstevel@tonic-gate  *
9347c478bd9Sstevel@tonic-gate  * INPUTS:
9357c478bd9Sstevel@tonic-gate  *	hcap		- HCA entry ptr
9367c478bd9Sstevel@tonic-gate  *	input_madp	- CM MAD that is input to this function
9377c478bd9Sstevel@tonic-gate  *	cm_mad_addr	- Address information for the MAD
9387c478bd9Sstevel@tonic-gate  *
9397c478bd9Sstevel@tonic-gate  * RETURN VALUE:
9407c478bd9Sstevel@tonic-gate  *	NONE
9417c478bd9Sstevel@tonic-gate  */
9427c478bd9Sstevel@tonic-gate void
ibcm_process_req_msg(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)9437c478bd9Sstevel@tonic-gate ibcm_process_req_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
9447c478bd9Sstevel@tonic-gate     ibcm_mad_addr_t *cm_mad_addr)
9457c478bd9Sstevel@tonic-gate {
9467c478bd9Sstevel@tonic-gate 	ibt_priv_data_len_t	arej_info_len = 0;
9477c478bd9Sstevel@tonic-gate 	ib_qpn_t		remote_qpn;
9487c478bd9Sstevel@tonic-gate 	ib_guid_t		remote_hca_guid;
9497c478bd9Sstevel@tonic-gate 	ib_com_id_t		remote_comid;
9507c478bd9Sstevel@tonic-gate 	ib_com_id_t		local_comid;
9517c478bd9Sstevel@tonic-gate 	ibcm_status_t		state_lookup_status;
9527c478bd9Sstevel@tonic-gate 	ibcm_status_t		comid_lookup_status;
9537c478bd9Sstevel@tonic-gate 	ibcm_status_t		response;
954015f8fffShiremath 	ibcm_req_msg_t		*req_msgp =
955015f8fffShiremath 	    (ibcm_req_msg_t *)&input_madp[IBCM_MAD_HDR_SIZE];
9567c478bd9Sstevel@tonic-gate 	ibt_cm_reason_t		reject_reason = IBT_CM_SUCCESS;
9577c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep;
9587c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*stale_statep = NULL;
9597c478bd9Sstevel@tonic-gate 	ibcm_status_t		svc_gid_check;
9607c478bd9Sstevel@tonic-gate 	uint32_t		psn24_timeout5_retry3;
9617c478bd9Sstevel@tonic-gate 	ibt_tran_srv_t		trans;
9627c478bd9Sstevel@tonic-gate 
9637c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "ibcm_process_req_msg(%p, %p, %p)",
9647c478bd9Sstevel@tonic-gate 	    hcap, input_madp, cm_mad_addr);
9657c478bd9Sstevel@tonic-gate 
9667c478bd9Sstevel@tonic-gate 	/*
9677c478bd9Sstevel@tonic-gate 	 * Lookup for an existing state structure or create a new state struct
9687c478bd9Sstevel@tonic-gate 	 * If there is no entry, the lookup function also allocates a new
9697c478bd9Sstevel@tonic-gate 	 * state structure and inserts in the table, initializes remote qpn
9707c478bd9Sstevel@tonic-gate 	 * and hca guid from REQ
9717c478bd9Sstevel@tonic-gate 	 */
9727c478bd9Sstevel@tonic-gate 	remote_hca_guid = b2h64(req_msgp->req_local_ca_guid);
9737c478bd9Sstevel@tonic-gate 	remote_qpn = b2h32(req_msgp->req_local_qpn_plus) >> 8;
9747c478bd9Sstevel@tonic-gate 	remote_comid = b2h32(req_msgp->req_local_comm_id);
9757c478bd9Sstevel@tonic-gate 
9767c478bd9Sstevel@tonic-gate 	IBCM_DUMP_RAW_MSG((uchar_t *)input_madp);
9777c478bd9Sstevel@tonic-gate 
9787c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: remote_comid = %x"
9797c478bd9Sstevel@tonic-gate 	    " remote_qpn = %x", remote_comid, remote_qpn);
9807c478bd9Sstevel@tonic-gate 
9817c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: remote_hcaguid = %llX",
9827c478bd9Sstevel@tonic-gate 	    remote_hca_guid);
9837c478bd9Sstevel@tonic-gate 
9847c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
9857c478bd9Sstevel@tonic-gate 
9867c478bd9Sstevel@tonic-gate new_req:
9877c478bd9Sstevel@tonic-gate 	/* allocate the local_comid before proceeding */
9887c478bd9Sstevel@tonic-gate 	if (ibcm_alloc_comid(hcap, &local_comid) != IBCM_SUCCESS) {
9897c478bd9Sstevel@tonic-gate 		ibcm_build_n_post_rej_mad(input_madp,
9907c478bd9Sstevel@tonic-gate 		    b2h32(req_msgp->req_local_comm_id), cm_mad_addr,
9917c478bd9Sstevel@tonic-gate 		    IBT_CM_FAILURE_REQ, IBT_CM_NO_RESC);
9927c478bd9Sstevel@tonic-gate 		return;
9937c478bd9Sstevel@tonic-gate 	}
9947c478bd9Sstevel@tonic-gate 
9957c478bd9Sstevel@tonic-gate 	/* allocate ibcm_state_data_t before grabbing the WRITER lock */
9967c478bd9Sstevel@tonic-gate 	statep = kmem_zalloc(sizeof (*statep), KM_SLEEP);
9977c478bd9Sstevel@tonic-gate 
9987c478bd9Sstevel@tonic-gate 	rw_enter(&hcap->hca_state_rwlock, RW_WRITER);
9997c478bd9Sstevel@tonic-gate 
10007c478bd9Sstevel@tonic-gate 	/* NOTE that only a writer lock is held here */
10017c478bd9Sstevel@tonic-gate 
10027c478bd9Sstevel@tonic-gate 	state_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_REQ,
10037c478bd9Sstevel@tonic-gate 	    local_comid, remote_qpn, remote_hca_guid, hcap, &statep);
10047c478bd9Sstevel@tonic-gate 
10057c478bd9Sstevel@tonic-gate 	if (state_lookup_status == IBCM_LOOKUP_NEW) {
10067c478bd9Sstevel@tonic-gate 		/* seeing the REQ request for the first time */
10077c478bd9Sstevel@tonic-gate 
10087c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
10097c478bd9Sstevel@tonic-gate 		/* Release the state table lock */
10107c478bd9Sstevel@tonic-gate 		rw_exit(&hcap->hca_state_rwlock);
10117c478bd9Sstevel@tonic-gate 
10127c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: New statep 0x%p"
10137c478bd9Sstevel@tonic-gate 		    " created", statep);
10147c478bd9Sstevel@tonic-gate 
10157c478bd9Sstevel@tonic-gate 		psn24_timeout5_retry3 = b2h32(req_msgp->req_starting_psn_plus);
10167c478bd9Sstevel@tonic-gate 
10177c478bd9Sstevel@tonic-gate 		_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
10187c478bd9Sstevel@tonic-gate 
10197c478bd9Sstevel@tonic-gate 		/* if ibmf msg allocation fails, delete the statep */
10207c478bd9Sstevel@tonic-gate 		if (ibcm_alloc_out_msg(cm_mad_addr->ibmf_hdl,
10217c478bd9Sstevel@tonic-gate 		    &statep->stored_msg, MAD_METHOD_SEND) != IBT_SUCCESS) {
10227c478bd9Sstevel@tonic-gate 
10237c478bd9Sstevel@tonic-gate 			IBCM_REF_CNT_DECR(statep);
10247c478bd9Sstevel@tonic-gate 			statep->state = IBCM_STATE_DELETE;
10257c478bd9Sstevel@tonic-gate 			mutex_exit(&statep->state_mutex);
10267c478bd9Sstevel@tonic-gate 			/* HCA res cnt decremented via ibcm_delete_state_data */
10277c478bd9Sstevel@tonic-gate 			ibcm_inc_hca_res_cnt(hcap);
10287c478bd9Sstevel@tonic-gate 			ibcm_delete_state_data(statep);
10297c478bd9Sstevel@tonic-gate 			return;
10307c478bd9Sstevel@tonic-gate 		}
10317c478bd9Sstevel@tonic-gate 
1032934f0bccShiremath 		/* Allocate dreq_msg buf to be used during teardown. */
1033934f0bccShiremath 		if (ibcm_alloc_out_msg(cm_mad_addr->ibmf_hdl,
1034934f0bccShiremath 		    &statep->dreq_msg, MAD_METHOD_SEND) != IBT_SUCCESS) {
1035934f0bccShiremath 
1036934f0bccShiremath 			IBCM_REF_CNT_DECR(statep);
1037934f0bccShiremath 			statep->state = IBCM_STATE_DELETE;
1038934f0bccShiremath 			mutex_exit(&statep->state_mutex);
1039934f0bccShiremath 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_msg: "
1040934f0bccShiremath 			    "statep 0x%p: Failed to allocate dreq_msg", statep);
1041934f0bccShiremath 
1042934f0bccShiremath 			/* HCA res cnt decremented via ibcm_delete_state_data */
1043934f0bccShiremath 			ibcm_inc_hca_res_cnt(hcap);
1044934f0bccShiremath 			ibcm_delete_state_data(statep);
1045934f0bccShiremath 			return;
1046934f0bccShiremath 		}
1047934f0bccShiremath 
10487c478bd9Sstevel@tonic-gate 		/* initialize some "statep" fields */
10497c478bd9Sstevel@tonic-gate 		statep->mode		= IBCM_PASSIVE_MODE;
10507c478bd9Sstevel@tonic-gate 		statep->hcap		= hcap;
10517c478bd9Sstevel@tonic-gate 		statep->remote_comid	= remote_comid;
10527c478bd9Sstevel@tonic-gate 		statep->svcid		= b2h64(req_msgp->req_svc_id);
10539c468ea9SPramod Gunjikar 		statep->local_qp_rnr_cnt =
10549c468ea9SPramod Gunjikar 		    req_msgp->req_mtu_plus & 0x7;
10557c478bd9Sstevel@tonic-gate 
10567c478bd9Sstevel@tonic-gate 		/*
10577c478bd9Sstevel@tonic-gate 		 * get the remote_ack_delay, etc.
10587c478bd9Sstevel@tonic-gate 		 */
10597c478bd9Sstevel@tonic-gate 		statep->remote_ack_delay =
10607c478bd9Sstevel@tonic-gate 		    ibt_ib2usec(req_msgp->req_primary_localtime_plus >> 3);
10617c478bd9Sstevel@tonic-gate 		statep->cep_retry_cnt = psn24_timeout5_retry3 & 0x7;
10627c478bd9Sstevel@tonic-gate 
10637c478bd9Sstevel@tonic-gate 		/*
10647c478bd9Sstevel@tonic-gate 		 * get the req_max_cm_retries
10657c478bd9Sstevel@tonic-gate 		 */
10667c478bd9Sstevel@tonic-gate 		statep->max_cm_retries = req_msgp->req_max_cm_retries_plus >> 4;
10677c478bd9Sstevel@tonic-gate 		statep->remaining_retry_cnt = statep->max_cm_retries;
10687c478bd9Sstevel@tonic-gate 
10697c478bd9Sstevel@tonic-gate 		/* Approximate pkt life time for now */
10707c478bd9Sstevel@tonic-gate 		statep->pkt_life_time = statep->remote_ack_delay/2;
10717c478bd9Sstevel@tonic-gate 
10727c478bd9Sstevel@tonic-gate 		/* Passive side timer is set to LocalCMRespTime in REQ */
10737c478bd9Sstevel@tonic-gate 		statep->timer_value =
10747c478bd9Sstevel@tonic-gate 		    ibt_ib2usec(psn24_timeout5_retry3 >> 3 & 0x1f);
10757c478bd9Sstevel@tonic-gate 
10767c478bd9Sstevel@tonic-gate 		statep->starting_psn = psn24_timeout5_retry3 >> 8;
10777c478bd9Sstevel@tonic-gate 
10787c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: statep 0x%p "
10797c478bd9Sstevel@tonic-gate 		    "active cep timeout(usec) = %u",
10807c478bd9Sstevel@tonic-gate 		    statep, statep->remote_ack_delay);
10817c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: "
10827c478bd9Sstevel@tonic-gate 		    "passive timer(usec) = %u", statep->timer_value);
10837c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: "
10847c478bd9Sstevel@tonic-gate 		    "approx pkt lt(usec)= %u ", statep->pkt_life_time);
10857c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: "
10867c478bd9Sstevel@tonic-gate 		    "max cm retries %u", statep->max_cm_retries);
10877c478bd9Sstevel@tonic-gate 
10887c478bd9Sstevel@tonic-gate 		/* The reply ie., REP/REJ transaction id copied from REQ */
10897c478bd9Sstevel@tonic-gate 		IBCM_OUT_HDRP(statep->stored_msg)->TransactionID =
10907c478bd9Sstevel@tonic-gate 		    ((ib_mad_hdr_t *)(input_madp))->TransactionID;
10917c478bd9Sstevel@tonic-gate 
10927c478bd9Sstevel@tonic-gate 		/*
10937c478bd9Sstevel@tonic-gate 		 * Initialize the stale clock. Any other REQ
10947c478bd9Sstevel@tonic-gate 		 * messages on this statep are considered as duplicate
10957c478bd9Sstevel@tonic-gate 		 * if they arrive within stale clock
10967c478bd9Sstevel@tonic-gate 		 * ibcm_adj_btime is used to offset for retry REQ's
10977c478bd9Sstevel@tonic-gate 		 * arriving  just after expected retry clock
10987c478bd9Sstevel@tonic-gate 		 */
10997c478bd9Sstevel@tonic-gate 		statep->stale_clock = gethrtime() +
1100fde3102fShiremath 		    (hrtime_t)(ibcm_adj_btime  * 1000000000) +
1101fde3102fShiremath 		    (hrtime_t)statep->remote_ack_delay *
1102fde3102fShiremath 		    (statep->max_cm_retries * (1000 / 2));
11037c478bd9Sstevel@tonic-gate 
11047c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
11057c478bd9Sstevel@tonic-gate 
11067c478bd9Sstevel@tonic-gate 		ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_REQ);
11077c478bd9Sstevel@tonic-gate 
11087c478bd9Sstevel@tonic-gate 		/* Increment the hca's resource count */
11097c478bd9Sstevel@tonic-gate 		ibcm_inc_hca_res_cnt(hcap);
11107c478bd9Sstevel@tonic-gate 
11117c478bd9Sstevel@tonic-gate 		ibcm_build_reply_mad_addr(cm_mad_addr,
11127c478bd9Sstevel@tonic-gate 		    &statep->stored_reply_addr);
11137c478bd9Sstevel@tonic-gate 
11147c478bd9Sstevel@tonic-gate 		if (statep->stored_reply_addr.cm_qp_entry == NULL) {
11157c478bd9Sstevel@tonic-gate 
11167c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_msg: "
11177c478bd9Sstevel@tonic-gate 			    "statep 0x%p cm_qp_entry alloc failed", statep);
11187c478bd9Sstevel@tonic-gate 
11197c478bd9Sstevel@tonic-gate 			/*
11207c478bd9Sstevel@tonic-gate 			 * Not much choice. CM MADs cannot go on QP1, not even
11217c478bd9Sstevel@tonic-gate 			 * REJ. Hence delete state data and go away silently.
11227c478bd9Sstevel@tonic-gate 			 * The remote will timeout after repeated attempts
11237c478bd9Sstevel@tonic-gate 			 */
11247c478bd9Sstevel@tonic-gate 			mutex_enter(&statep->state_mutex);
11257c478bd9Sstevel@tonic-gate 			IBCM_REF_CNT_DECR(statep);
11267c478bd9Sstevel@tonic-gate 			statep->state = IBCM_STATE_DELETE;
11277c478bd9Sstevel@tonic-gate 			mutex_exit(&statep->state_mutex);
11287c478bd9Sstevel@tonic-gate 
11297c478bd9Sstevel@tonic-gate 			ibcm_delete_state_data(statep);
11307c478bd9Sstevel@tonic-gate 			return;
11317c478bd9Sstevel@tonic-gate 		}
11327c478bd9Sstevel@tonic-gate 
11337c478bd9Sstevel@tonic-gate 		stale_statep = statep;
11347c478bd9Sstevel@tonic-gate 		rw_enter(&hcap->hca_state_rwlock, RW_WRITER);
11357c478bd9Sstevel@tonic-gate 		comid_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_REQ_STALE,
11367c478bd9Sstevel@tonic-gate 		    remote_comid, 0, remote_hca_guid, hcap, &stale_statep);
11377c478bd9Sstevel@tonic-gate 		rw_exit(&hcap->hca_state_rwlock);
11387c478bd9Sstevel@tonic-gate 
11397c478bd9Sstevel@tonic-gate 		if (comid_lookup_status == IBCM_LOOKUP_EXISTS) {
11407c478bd9Sstevel@tonic-gate 
11417c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_msg: "
11427c478bd9Sstevel@tonic-gate 			    "dup comid %x stale_statep 0x%p statep 0x%p",
11437c478bd9Sstevel@tonic-gate 			    remote_comid, stale_statep, statep);
11447c478bd9Sstevel@tonic-gate 
11457c478bd9Sstevel@tonic-gate 			ibcm_insert_trace(stale_statep,
11467c478bd9Sstevel@tonic-gate 			    IBCM_TRACE_STALE_DETECT);
11477c478bd9Sstevel@tonic-gate 
11487c478bd9Sstevel@tonic-gate 			/* Send a REJ with duplicate com id */
11497c478bd9Sstevel@tonic-gate 			ibcm_post_rej_mad(statep, IBT_CM_DUP_COM_ID,
11507c478bd9Sstevel@tonic-gate 			    IBT_CM_FAILURE_REQ, NULL, 0);
11517c478bd9Sstevel@tonic-gate 
11527c478bd9Sstevel@tonic-gate 			/*
11537c478bd9Sstevel@tonic-gate 			 * Don't free the ibmf msg, if stale_statep is not in
11547c478bd9Sstevel@tonic-gate 			 * ESTABLISHED state, because probability is very less.
11557c478bd9Sstevel@tonic-gate 			 * ibmf msg shall be deleted along with statep
11567c478bd9Sstevel@tonic-gate 			 */
11577c478bd9Sstevel@tonic-gate 
11587c478bd9Sstevel@tonic-gate 			/*
11597c478bd9Sstevel@tonic-gate 			 * if stale_statep is in established state, process
11607c478bd9Sstevel@tonic-gate 			 * stale connection handling on stale_statep
11617c478bd9Sstevel@tonic-gate 			 */
11627c478bd9Sstevel@tonic-gate 			mutex_enter(&stale_statep->state_mutex);
11637c478bd9Sstevel@tonic-gate 			if (stale_statep->state == IBCM_STATE_ESTABLISHED) {
11647c478bd9Sstevel@tonic-gate 
11657c478bd9Sstevel@tonic-gate 				stale_statep->state =
11667c478bd9Sstevel@tonic-gate 				    IBCM_STATE_TRANSIENT_DREQ_SENT;
11677c478bd9Sstevel@tonic-gate 				stale_statep->stale = B_TRUE;
11687c478bd9Sstevel@tonic-gate 
11697c478bd9Sstevel@tonic-gate 				/* Cancel pending ibt_set_alt_path */
11707c478bd9Sstevel@tonic-gate 				ibcm_sync_lapr_idle(stale_statep);
11717c478bd9Sstevel@tonic-gate 				/* The above call releases the state mutex */
11727c478bd9Sstevel@tonic-gate 
11737c478bd9Sstevel@tonic-gate 				if (stale_statep->dreq_msg == NULL)
11747c478bd9Sstevel@tonic-gate 					(void) ibcm_alloc_out_msg(stale_statep->
11757c478bd9Sstevel@tonic-gate 					    stored_reply_addr.ibmf_hdl,
11767c478bd9Sstevel@tonic-gate 					    &stale_statep->dreq_msg,
11777c478bd9Sstevel@tonic-gate 					    MAD_METHOD_SEND);
11787c478bd9Sstevel@tonic-gate 
11797c478bd9Sstevel@tonic-gate 				/*
11807c478bd9Sstevel@tonic-gate 				 * Spec says, post DREQ MAD on the stale
11817c478bd9Sstevel@tonic-gate 				 * channel. This moves channel into timewait
11827c478bd9Sstevel@tonic-gate 				 */
11837c478bd9Sstevel@tonic-gate 				if (stale_statep->dreq_msg != NULL) {
11847c478bd9Sstevel@tonic-gate 					ibcm_post_dreq_mad(stale_statep);
11857c478bd9Sstevel@tonic-gate 					mutex_enter(&stale_statep->state_mutex);
11867c478bd9Sstevel@tonic-gate 				} else {
11877c478bd9Sstevel@tonic-gate 					mutex_enter(&stale_statep->state_mutex);
11887c478bd9Sstevel@tonic-gate 					/* Set it back to original state. */
11897c478bd9Sstevel@tonic-gate 					stale_statep->state =
11907c478bd9Sstevel@tonic-gate 					    IBCM_STATE_ESTABLISHED;
11917c478bd9Sstevel@tonic-gate 					cv_broadcast(
11927c478bd9Sstevel@tonic-gate 					    &stale_statep->block_mad_cv);
11937c478bd9Sstevel@tonic-gate 				}
11947c478bd9Sstevel@tonic-gate 			}
11957c478bd9Sstevel@tonic-gate 
11967c478bd9Sstevel@tonic-gate 			IBCM_REF_CNT_DECR(stale_statep);
11977c478bd9Sstevel@tonic-gate 			mutex_exit(&stale_statep->state_mutex);
11987c478bd9Sstevel@tonic-gate 
11997c478bd9Sstevel@tonic-gate 			mutex_enter(&statep->state_mutex);
12007c478bd9Sstevel@tonic-gate 			IBCM_REF_CNT_DECR(statep);
12017c478bd9Sstevel@tonic-gate 			mutex_exit(&statep->state_mutex);
12027c478bd9Sstevel@tonic-gate 			return;
12037c478bd9Sstevel@tonic-gate 		}
12047c478bd9Sstevel@tonic-gate 
12057c478bd9Sstevel@tonic-gate 		/* If unknown service type, just post a REJ */
12067c478bd9Sstevel@tonic-gate 		trans = ((uint8_t *)&req_msgp->req_remote_eecn_plus)[3] >> 1 &
12077c478bd9Sstevel@tonic-gate 		    0x3;
12087c478bd9Sstevel@tonic-gate 		if ((trans != IBT_RC_SRV) && (trans != IBT_UC_SRV) &&
12097c478bd9Sstevel@tonic-gate 		    (trans != IBT_RD_SRV)) {
12107c478bd9Sstevel@tonic-gate 
12117c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_msg: "
12127c478bd9Sstevel@tonic-gate 			    "statep 0x%p invalid transport type %x", statep,
12137c478bd9Sstevel@tonic-gate 			    trans);
12147c478bd9Sstevel@tonic-gate 
12157c478bd9Sstevel@tonic-gate 			/* Send a REJ with invalid transport type */
12167c478bd9Sstevel@tonic-gate 			ibcm_post_rej_mad(statep, IBT_CM_INVALID_SRV_TYPE,
12177c478bd9Sstevel@tonic-gate 			    IBT_CM_FAILURE_REQ, NULL, 0);
12187c478bd9Sstevel@tonic-gate 
12197c478bd9Sstevel@tonic-gate 			mutex_enter(&statep->state_mutex);
12207c478bd9Sstevel@tonic-gate 			IBCM_REF_CNT_DECR(statep);
12217c478bd9Sstevel@tonic-gate 			mutex_exit(&statep->state_mutex);
12227c478bd9Sstevel@tonic-gate 			return;
12237c478bd9Sstevel@tonic-gate 		}
12247c478bd9Sstevel@tonic-gate 
12257c478bd9Sstevel@tonic-gate 		/* Validate the gids, lids and service id */
12267c478bd9Sstevel@tonic-gate 		svc_gid_check = ibcm_verify_req_gids_and_svcid(statep,
12277c478bd9Sstevel@tonic-gate 		    req_msgp);
12287c478bd9Sstevel@tonic-gate 
12297c478bd9Sstevel@tonic-gate 		if (svc_gid_check == IBCM_FAILURE) {
12307c478bd9Sstevel@tonic-gate 
12317c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L3(cmlog, "ibcm_process_req_msg: Either "
12327c478bd9Sstevel@tonic-gate 			    "gid or sid invalid for statep 0x%p", statep);
12337c478bd9Sstevel@tonic-gate 			mutex_enter(&statep->state_mutex);
12347c478bd9Sstevel@tonic-gate 			IBCM_REF_CNT_DECR(statep);
12357c478bd9Sstevel@tonic-gate 			mutex_exit(&statep->state_mutex);
12367c478bd9Sstevel@tonic-gate 
12377c478bd9Sstevel@tonic-gate 			/* REJ posted from ibcm_verify_req_gids_and_svcid */
12387c478bd9Sstevel@tonic-gate 			return;
12397c478bd9Sstevel@tonic-gate 		}
12407c478bd9Sstevel@tonic-gate 
12417c478bd9Sstevel@tonic-gate 		/* Call the QP state transition processing function */
12427c478bd9Sstevel@tonic-gate 		response = ibcm_cep_state_req(statep, req_msgp,
12437c478bd9Sstevel@tonic-gate 		    &reject_reason, &arej_info_len);
12447c478bd9Sstevel@tonic-gate 
12457c478bd9Sstevel@tonic-gate 		/* If defer, return holding the statep ref cnt */
12467c478bd9Sstevel@tonic-gate 		if (response == IBCM_DEFER) {
12477c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: "
12487c478bd9Sstevel@tonic-gate 			    "statep %0xp client returned DEFER response",
12497c478bd9Sstevel@tonic-gate 			    statep);
12507c478bd9Sstevel@tonic-gate 			return;
12517c478bd9Sstevel@tonic-gate 		}
12527c478bd9Sstevel@tonic-gate 
12537c478bd9Sstevel@tonic-gate 		/* statep ref cnt decremented in the func below */
12547c478bd9Sstevel@tonic-gate 		ibcm_handle_cep_req_response(statep, response,
12557c478bd9Sstevel@tonic-gate 		    reject_reason, arej_info_len);
12567c478bd9Sstevel@tonic-gate 
12577c478bd9Sstevel@tonic-gate 		_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*statep))
12587c478bd9Sstevel@tonic-gate 
12597c478bd9Sstevel@tonic-gate 		return;
12607c478bd9Sstevel@tonic-gate 
12617c478bd9Sstevel@tonic-gate 	} else {
12627c478bd9Sstevel@tonic-gate 		rw_exit(&hcap->hca_state_rwlock);
12637c478bd9Sstevel@tonic-gate 		ibcm_free_comid(hcap, local_comid);
12647c478bd9Sstevel@tonic-gate 	}
12657c478bd9Sstevel@tonic-gate 
12667c478bd9Sstevel@tonic-gate 	if (state_lookup_status == IBCM_LOOKUP_EXISTS) {
12677c478bd9Sstevel@tonic-gate 		hrtime_t	cur_time;
12687c478bd9Sstevel@tonic-gate 
12697c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
12707c478bd9Sstevel@tonic-gate 
12717c478bd9Sstevel@tonic-gate 		/*
12727c478bd9Sstevel@tonic-gate 		 * There is an existing state structure entry
12737c478bd9Sstevel@tonic-gate 		 * with the same active comid
12747c478bd9Sstevel@tonic-gate 		 * Resending REP MAD is necessary only for REP/REJ/MRA Sent
12757c478bd9Sstevel@tonic-gate 		 * states
12767c478bd9Sstevel@tonic-gate 		 * Any other state implies the active has already received
12777c478bd9Sstevel@tonic-gate 		 * the REP/REJ response, and this REQ is an old MAD popping
12787c478bd9Sstevel@tonic-gate 		 * out of the fabric, hence no resend is required
12797c478bd9Sstevel@tonic-gate 		 */
12807c478bd9Sstevel@tonic-gate 		cur_time = gethrtime();
12817c478bd9Sstevel@tonic-gate 
12827c478bd9Sstevel@tonic-gate 		if ((remote_comid == statep->remote_comid) &&
12837c478bd9Sstevel@tonic-gate 		    (IBCM_OUT_HDRP(statep->stored_msg)->TransactionID ==
12847c478bd9Sstevel@tonic-gate 		    ((ib_mad_hdr_t *)(input_madp))->TransactionID) &&
12857c478bd9Sstevel@tonic-gate 		    (cur_time <= statep->stale_clock)) {
12867c478bd9Sstevel@tonic-gate 
12877c478bd9Sstevel@tonic-gate 			ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_REQ);
12887c478bd9Sstevel@tonic-gate 
12897c478bd9Sstevel@tonic-gate 			if (statep->state == IBCM_STATE_REP_SENT)
12907c478bd9Sstevel@tonic-gate 				ibcm_resend_rep_mad(statep);
12917c478bd9Sstevel@tonic-gate 			else if (statep->state == IBCM_STATE_REJ_SENT)
12927c478bd9Sstevel@tonic-gate 				ibcm_resend_rej_mad(statep);
12937c478bd9Sstevel@tonic-gate 			else if (statep->state == IBCM_STATE_MRA_SENT)
12947c478bd9Sstevel@tonic-gate 				ibcm_resend_mra_mad(statep);
12957c478bd9Sstevel@tonic-gate 
12967c478bd9Sstevel@tonic-gate 			/* decrementing ref cnt and returning from below */
12977c478bd9Sstevel@tonic-gate 
12987c478bd9Sstevel@tonic-gate 		} else if ((statep->state == IBCM_STATE_REJ_SENT) &&
12997c478bd9Sstevel@tonic-gate 		    remote_comid != statep->remote_comid) {
13007c478bd9Sstevel@tonic-gate 			timeout_id_t		timer_val;
13017c478bd9Sstevel@tonic-gate 
13027c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_msg: "
13037c478bd9Sstevel@tonic-gate 			    "statep 0x%p being retired, REMOTE_QPN %x",
13047c478bd9Sstevel@tonic-gate 			    statep, remote_qpn);
13057c478bd9Sstevel@tonic-gate 			/*
13067c478bd9Sstevel@tonic-gate 			 * OK, this is reuse of the QPN on the active side
13077c478bd9Sstevel@tonic-gate 			 * that was not connected last time.  This REQ is
13087c478bd9Sstevel@tonic-gate 			 * considered NEW.  We delete the statep here,
13097c478bd9Sstevel@tonic-gate 			 * then start over from the top.
13107c478bd9Sstevel@tonic-gate 			 */
13117c478bd9Sstevel@tonic-gate 			statep->state = IBCM_STATE_DELETE;
13127c478bd9Sstevel@tonic-gate 			timer_val = statep->timerid;
13137c478bd9Sstevel@tonic-gate 			statep->timerid = 0;
13147c478bd9Sstevel@tonic-gate 			mutex_exit(&statep->state_mutex);
13157c478bd9Sstevel@tonic-gate 			if (timer_val)
13167c478bd9Sstevel@tonic-gate 				(void) untimeout(timer_val);
13177c478bd9Sstevel@tonic-gate 			IBCM_REF_CNT_DECR(statep);
13187c478bd9Sstevel@tonic-gate 			ibcm_delete_state_data(statep);
13197c478bd9Sstevel@tonic-gate 			goto new_req;
13207c478bd9Sstevel@tonic-gate 
13217c478bd9Sstevel@tonic-gate 		/*
13227c478bd9Sstevel@tonic-gate 		 * The statep is stale in the following cases :-
13237c478bd9Sstevel@tonic-gate 		 *  1) if incoming REQ's comid's doesn't match with what is
13247c478bd9Sstevel@tonic-gate 		 *	stored in statep
13257c478bd9Sstevel@tonic-gate 		 *  2) incoming REQ's local comid matches with statep's
13267c478bd9Sstevel@tonic-gate 		 *	remote comid, but the REQ is for a new connection.
13277c478bd9Sstevel@tonic-gate 		 *	This is verified that by comparing the current time
13287c478bd9Sstevel@tonic-gate 		 *	with stale clock in statep
13297c478bd9Sstevel@tonic-gate 		 */
13307c478bd9Sstevel@tonic-gate 		} else {
13317c478bd9Sstevel@tonic-gate 			/* This is a stale connection on passive side */
13327c478bd9Sstevel@tonic-gate 
13337c478bd9Sstevel@tonic-gate 			ibcm_insert_trace(statep, IBCM_TRACE_STALE_DETECT);
13347c478bd9Sstevel@tonic-gate 
13357c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_msg: "
13367c478bd9Sstevel@tonic-gate 			    "stale detected statep %p state %x",
13377c478bd9Sstevel@tonic-gate 			    statep, statep->state);
13387c478bd9Sstevel@tonic-gate 
13397c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: "
13407c478bd9Sstevel@tonic-gate 			    "cur_time 0x%llX stale_clock 0x%llX", cur_time,
13417c478bd9Sstevel@tonic-gate 			    statep->stale_clock);
13427c478bd9Sstevel@tonic-gate 
13437c478bd9Sstevel@tonic-gate 			if (statep->state == IBCM_STATE_ESTABLISHED) {
13447c478bd9Sstevel@tonic-gate 
13457c478bd9Sstevel@tonic-gate 				statep->state = IBCM_STATE_TRANSIENT_DREQ_SENT;
13467c478bd9Sstevel@tonic-gate 				statep->stale = B_TRUE;
13477c478bd9Sstevel@tonic-gate 
13487c478bd9Sstevel@tonic-gate 				/* Cancel pending ibt_set_alt_path */
13497c478bd9Sstevel@tonic-gate 				ibcm_sync_lapr_idle(statep);
13507c478bd9Sstevel@tonic-gate 				/* The above call releases the state mutex */
13517c478bd9Sstevel@tonic-gate 
13527c478bd9Sstevel@tonic-gate 				if (statep->dreq_msg == NULL)
13537c478bd9Sstevel@tonic-gate 					(void) ibcm_alloc_out_msg(
13547c478bd9Sstevel@tonic-gate 					    statep->stored_reply_addr.ibmf_hdl,
13557c478bd9Sstevel@tonic-gate 					    &statep->dreq_msg, MAD_METHOD_SEND);
13567c478bd9Sstevel@tonic-gate 
13577c478bd9Sstevel@tonic-gate 				/*
13587c478bd9Sstevel@tonic-gate 				 * Spec says, post DREQ MAD on the stale
13597c478bd9Sstevel@tonic-gate 				 * channel. This moves channel into timewait
13607c478bd9Sstevel@tonic-gate 				 */
13617c478bd9Sstevel@tonic-gate 				if (statep->dreq_msg != NULL)
13627c478bd9Sstevel@tonic-gate 					ibcm_post_dreq_mad(statep);
13637c478bd9Sstevel@tonic-gate 				else {
13647c478bd9Sstevel@tonic-gate 					mutex_enter(&statep->state_mutex);
13657c478bd9Sstevel@tonic-gate 					statep->state = IBCM_STATE_ESTABLISHED;
13667c478bd9Sstevel@tonic-gate 					cv_broadcast(&statep->block_mad_cv);
13677c478bd9Sstevel@tonic-gate 					mutex_exit(&statep->state_mutex);
13687c478bd9Sstevel@tonic-gate 				}
13697c478bd9Sstevel@tonic-gate 			} else {
13707c478bd9Sstevel@tonic-gate 				/*
13717c478bd9Sstevel@tonic-gate 				 * If not in established state, the CM
13727c478bd9Sstevel@tonic-gate 				 * protocol would timeout and delete the
13737c478bd9Sstevel@tonic-gate 				 * statep that is stale, eventually
13747c478bd9Sstevel@tonic-gate 				 */
13757c478bd9Sstevel@tonic-gate 				mutex_exit(&statep->state_mutex);
13767c478bd9Sstevel@tonic-gate 			}
13777c478bd9Sstevel@tonic-gate 
13787c478bd9Sstevel@tonic-gate 			/* Post a REJ MAD to the incoming REQ's sender */
13797c478bd9Sstevel@tonic-gate 			ibcm_build_n_post_rej_mad(input_madp,
13807c478bd9Sstevel@tonic-gate 			    b2h32(req_msgp->req_local_comm_id),
13817c478bd9Sstevel@tonic-gate 			    cm_mad_addr, IBT_CM_FAILURE_REQ, IBT_CM_CONN_STALE);
13827c478bd9Sstevel@tonic-gate 
13837c478bd9Sstevel@tonic-gate 			mutex_enter(&statep->state_mutex);
13847c478bd9Sstevel@tonic-gate 		}
13857c478bd9Sstevel@tonic-gate 		IBCM_REF_CNT_DECR(statep); /* decrement the ref count */
13867c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
13877c478bd9Sstevel@tonic-gate 	}
13887c478bd9Sstevel@tonic-gate }
13897c478bd9Sstevel@tonic-gate 
13907c478bd9Sstevel@tonic-gate /*
13917c478bd9Sstevel@tonic-gate  * ibcm_handle_cep_req_response:
13927c478bd9Sstevel@tonic-gate  *	Processes the response from ibcm_cep_state_req. Called holding a
13937c478bd9Sstevel@tonic-gate  *	statep ref cnt. The statep ref cnt is decremented before returning.
13947c478bd9Sstevel@tonic-gate  */
13957c478bd9Sstevel@tonic-gate void
ibcm_handle_cep_req_response(ibcm_state_data_t * statep,ibcm_status_t response,ibt_cm_reason_t reject_reason,uint8_t arej_info_len)13967c478bd9Sstevel@tonic-gate ibcm_handle_cep_req_response(ibcm_state_data_t *statep, ibcm_status_t response,
13977c478bd9Sstevel@tonic-gate     ibt_cm_reason_t reject_reason, uint8_t arej_info_len)
13987c478bd9Sstevel@tonic-gate {
13997c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
14007c478bd9Sstevel@tonic-gate 
14017c478bd9Sstevel@tonic-gate 	if (response == IBCM_SEND_REP)
14027c478bd9Sstevel@tonic-gate 		ibcm_post_rep_mad(statep);
14037c478bd9Sstevel@tonic-gate 	else {
14047c478bd9Sstevel@tonic-gate 		ASSERT(response == IBCM_SEND_REJ);
14057c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_handle_cep_req_response: statep %p"
140624b28d04Shiremath 		    " posting REJ reject_reason = %d", statep, reject_reason);
14077c478bd9Sstevel@tonic-gate 
14087c478bd9Sstevel@tonic-gate 		ibcm_post_rej_mad(statep,
14097c478bd9Sstevel@tonic-gate 		    reject_reason, IBT_CM_FAILURE_REQ,
14107c478bd9Sstevel@tonic-gate 		    NULL, arej_info_len);
14117c478bd9Sstevel@tonic-gate 	}
14127c478bd9Sstevel@tonic-gate 
14137c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*statep))
14147c478bd9Sstevel@tonic-gate 
14157c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
14167c478bd9Sstevel@tonic-gate 	IBCM_REF_CNT_DECR(statep);
14177c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
14187c478bd9Sstevel@tonic-gate }
14197c478bd9Sstevel@tonic-gate 
14207c478bd9Sstevel@tonic-gate 
14217c478bd9Sstevel@tonic-gate /*
14227c478bd9Sstevel@tonic-gate  * ibcm_process_rep_msg:
14237c478bd9Sstevel@tonic-gate  *	ACTIVE SIDE CM
14247c478bd9Sstevel@tonic-gate  *	Called from ibcm_process_incoming_mad on reception of a REP message
14257c478bd9Sstevel@tonic-gate  *
14267c478bd9Sstevel@tonic-gate  * INPUTS:
14277c478bd9Sstevel@tonic-gate  *	hcap		- HCA entry pointer
14287c478bd9Sstevel@tonic-gate  *	input_madp	- CM MAD that is input to this function
14297c478bd9Sstevel@tonic-gate  *	cm_mad_addr	- Address information for the MAD
14307c478bd9Sstevel@tonic-gate  *
14317c478bd9Sstevel@tonic-gate  * RETURN VALUE:	NONE
14327c478bd9Sstevel@tonic-gate  */
14337c478bd9Sstevel@tonic-gate void
ibcm_process_rep_msg(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)14347c478bd9Sstevel@tonic-gate ibcm_process_rep_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
14357c478bd9Sstevel@tonic-gate     ibcm_mad_addr_t *cm_mad_addr)
14367c478bd9Sstevel@tonic-gate {
14377c478bd9Sstevel@tonic-gate 	ibt_priv_data_len_t	arej_info_len = 0;
14387c478bd9Sstevel@tonic-gate 	ib_com_id_t		local_comid;
14397c478bd9Sstevel@tonic-gate 	timeout_id_t		timer_val;
14407c478bd9Sstevel@tonic-gate 	ibcm_status_t		lookup_status;	/* state lookup status */
14417c478bd9Sstevel@tonic-gate 	ibcm_status_t		stale_lookup_status;
14427c478bd9Sstevel@tonic-gate 	ibcm_status_t		stale_comid_lookup_status;
14437c478bd9Sstevel@tonic-gate 	ibcm_status_t		response;
14447c478bd9Sstevel@tonic-gate 	ibcm_rep_msg_t		*rep_msgp;	/* Response REP mesg */
14457c478bd9Sstevel@tonic-gate 	ibt_cm_reason_t		reject_reason;
14467c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep = NULL;
14477c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*stale_qpn = NULL;
14487c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*stale_comid = NULL;
14497c478bd9Sstevel@tonic-gate 	ib_guid_t		remote_ca_guid;
14507c478bd9Sstevel@tonic-gate 
14517c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(cmlog, "ibcm_process_rep_msg:");
14527c478bd9Sstevel@tonic-gate 
14537c478bd9Sstevel@tonic-gate 	/* Lookup for an existing state structure */
14547c478bd9Sstevel@tonic-gate 	rep_msgp = (ibcm_rep_msg_t *)(&input_madp[IBCM_MAD_HDR_SIZE]);
14557c478bd9Sstevel@tonic-gate 
14569c468ea9SPramod Gunjikar 	IBCM_DUMP_RAW_MSG((uchar_t *)input_madp);
14579c468ea9SPramod Gunjikar 
14587c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "ibcm_process_rep_msg: active comid: %x",
14597c478bd9Sstevel@tonic-gate 	    rep_msgp->rep_remote_comm_id);
14607c478bd9Sstevel@tonic-gate 
14617c478bd9Sstevel@tonic-gate 	local_comid = b2h32(rep_msgp->rep_remote_comm_id);
14627c478bd9Sstevel@tonic-gate 
14637c478bd9Sstevel@tonic-gate 	/* lookup message holding a reader lock */
14647c478bd9Sstevel@tonic-gate 	rw_enter(&hcap->hca_state_rwlock, RW_READER);
14657c478bd9Sstevel@tonic-gate 	lookup_status = ibcm_lookup_msg(IBCM_INCOMING_REP, local_comid, 0, 0,
14667c478bd9Sstevel@tonic-gate 	    hcap, &statep);
14677c478bd9Sstevel@tonic-gate 	rw_exit(&hcap->hca_state_rwlock);
14687c478bd9Sstevel@tonic-gate 
14697c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_rep_msg: lkup status %x, "
14707c478bd9Sstevel@tonic-gate 	    "statep 0x%p active comid %x", lookup_status, statep, local_comid);
14717c478bd9Sstevel@tonic-gate 
14727c478bd9Sstevel@tonic-gate 	if (lookup_status == IBCM_LOOKUP_FAIL) {
14737c478bd9Sstevel@tonic-gate 		ibcm_build_n_post_rej_mad(input_madp,
14747c478bd9Sstevel@tonic-gate 		    b2h32(rep_msgp->rep_local_comm_id), cm_mad_addr,
14757c478bd9Sstevel@tonic-gate 		    IBT_CM_FAILURE_REP, IBT_CM_INVALID_CID);
14767c478bd9Sstevel@tonic-gate 
14777c478bd9Sstevel@tonic-gate 		return;
14787c478bd9Sstevel@tonic-gate 	}
14797c478bd9Sstevel@tonic-gate 
14807c478bd9Sstevel@tonic-gate 	/* if transaction id is not as expected, drop the REP mad */
14817c478bd9Sstevel@tonic-gate 	if (IBCM_OUT_HDRP(statep->stored_msg)->TransactionID !=
14827c478bd9Sstevel@tonic-gate 	    ((ib_mad_hdr_t *)(input_madp))->TransactionID) {
14837c478bd9Sstevel@tonic-gate 
14847c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L3(cmlog, "ibcm_process_rep_msg: statep 0x%p, "
14857c478bd9Sstevel@tonic-gate 		    "An REP MAD with tid expected 0x%llX tid found 0x%llX ",
14867c478bd9Sstevel@tonic-gate 		    statep,
14877c478bd9Sstevel@tonic-gate 		    b2h64(IBCM_OUT_HDRP(statep->stored_msg)->TransactionID),
14887c478bd9Sstevel@tonic-gate 		    b2h64(((ib_mad_hdr_t *)(input_madp))->TransactionID));
14897c478bd9Sstevel@tonic-gate 
14907c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
14917c478bd9Sstevel@tonic-gate 		IBCM_REF_CNT_DECR(statep);
14927c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
14937c478bd9Sstevel@tonic-gate 		return;
14947c478bd9Sstevel@tonic-gate 	}
14957c478bd9Sstevel@tonic-gate 
14967c478bd9Sstevel@tonic-gate 	ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_REP);
14977c478bd9Sstevel@tonic-gate 
14987c478bd9Sstevel@tonic-gate 	/* grab mutex first */
14997c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
15007c478bd9Sstevel@tonic-gate 
15017c478bd9Sstevel@tonic-gate 	/*
15027c478bd9Sstevel@tonic-gate 	 * There is a state structure entry with active comid
15037c478bd9Sstevel@tonic-gate 	 * First, handle the re-send cases
15047c478bd9Sstevel@tonic-gate 	 * The resend routines below release the state mutex
15057c478bd9Sstevel@tonic-gate 	 */
1506fde3102fShiremath 	if (statep->state == IBCM_STATE_ESTABLISHED ||
1507fde3102fShiremath 	    statep->state == IBCM_STATE_DREQ_SENT)
15087c478bd9Sstevel@tonic-gate 		ibcm_resend_rtu_mad(statep);
15097c478bd9Sstevel@tonic-gate 	else if (statep->state == IBCM_STATE_REJ_SENT)
15107c478bd9Sstevel@tonic-gate 		ibcm_resend_rej_mad(statep);
15117c478bd9Sstevel@tonic-gate 	else if (statep->state == IBCM_STATE_MRA_REP_SENT)
15127c478bd9Sstevel@tonic-gate 		ibcm_resend_mra_mad(statep);
15137c478bd9Sstevel@tonic-gate 	else if ((statep->state == IBCM_STATE_REQ_SENT) ||
15147c478bd9Sstevel@tonic-gate 	    (statep->state == IBCM_STATE_REP_WAIT)) {
15157c478bd9Sstevel@tonic-gate 
15167c478bd9Sstevel@tonic-gate 		/* change state */
15177c478bd9Sstevel@tonic-gate 		statep->state = IBCM_STATE_REP_RCVD;
15187c478bd9Sstevel@tonic-gate 		statep->clnt_proceed = IBCM_BLOCK;
15199c468ea9SPramod Gunjikar 		statep->local_qp_rnr_cnt =
15209c468ea9SPramod Gunjikar 		    rep_msgp->rep_rnr_retry_cnt_plus >> 5;
15217c478bd9Sstevel@tonic-gate 
15227c478bd9Sstevel@tonic-gate 		/* cancel the REQ timer */
15237c478bd9Sstevel@tonic-gate 		if (statep->timerid != 0) {
15247c478bd9Sstevel@tonic-gate 			timer_val = statep->timerid;
15257c478bd9Sstevel@tonic-gate 			statep->timerid = 0;
15267c478bd9Sstevel@tonic-gate 			mutex_exit(&statep->state_mutex);
15277c478bd9Sstevel@tonic-gate 			(void) untimeout(timer_val);
15287c478bd9Sstevel@tonic-gate 		} else {
15297c478bd9Sstevel@tonic-gate 			mutex_exit(&statep->state_mutex);
15307c478bd9Sstevel@tonic-gate 		}
15317c478bd9Sstevel@tonic-gate 
15327c478bd9Sstevel@tonic-gate 		_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
15337c478bd9Sstevel@tonic-gate 
15347c478bd9Sstevel@tonic-gate 		/* Initialize the remote destination QPN for further MADs */
15357c478bd9Sstevel@tonic-gate 		statep->stored_reply_addr.rcvd_addr.ia_remote_qno =
15367c478bd9Sstevel@tonic-gate 		    cm_mad_addr->rcvd_addr.ia_remote_qno;
15377c478bd9Sstevel@tonic-gate 		statep->remote_qpn = b2h32(rep_msgp->rep_local_qpn_plus) >> 8;
15387c478bd9Sstevel@tonic-gate 		statep->remote_comid = b2h32(rep_msgp->rep_local_comm_id);
15397c478bd9Sstevel@tonic-gate 		bcopy(rep_msgp->rep_local_ca_guid, &remote_ca_guid,
15407c478bd9Sstevel@tonic-gate 		    sizeof (ib_guid_t));
15417c478bd9Sstevel@tonic-gate 		statep->remote_hca_guid = b2h64(remote_ca_guid);
15427c478bd9Sstevel@tonic-gate 
15437c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_process_rep_msg: statep 0x%p "
15447c478bd9Sstevel@tonic-gate 		    "passive cid = %x passive qpn = %x", statep,
15457c478bd9Sstevel@tonic-gate 		    statep->remote_comid, statep->remote_qpn);
15467c478bd9Sstevel@tonic-gate 
15477c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_process_rep_msg: statep 0x%p "
15487c478bd9Sstevel@tonic-gate 		    "passive hcaguid = %llX", statep, statep->remote_hca_guid);
15497c478bd9Sstevel@tonic-gate 
15507c478bd9Sstevel@tonic-gate 		stale_qpn = statep;
15517c478bd9Sstevel@tonic-gate 		stale_comid = statep;
15527c478bd9Sstevel@tonic-gate 
15537c478bd9Sstevel@tonic-gate 		/* Handle stale connection detection on active side */
15547c478bd9Sstevel@tonic-gate 		rw_enter(&hcap->hca_state_rwlock, RW_WRITER);
15557c478bd9Sstevel@tonic-gate 
15567c478bd9Sstevel@tonic-gate 		stale_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_REP_STALE,
15577c478bd9Sstevel@tonic-gate 		    0, statep->remote_qpn, statep->remote_hca_guid, hcap,
15587c478bd9Sstevel@tonic-gate 		    &stale_qpn);
15597c478bd9Sstevel@tonic-gate 
15607c478bd9Sstevel@tonic-gate 		stale_comid_lookup_status = ibcm_lookup_msg(
15617c478bd9Sstevel@tonic-gate 		    IBCM_INCOMING_REQ_STALE, statep->remote_comid, 0,
15627c478bd9Sstevel@tonic-gate 		    statep->remote_hca_guid, hcap, &stale_comid);
15637c478bd9Sstevel@tonic-gate 
15647c478bd9Sstevel@tonic-gate 		rw_exit(&hcap->hca_state_rwlock);
15657c478bd9Sstevel@tonic-gate 
15667c478bd9Sstevel@tonic-gate 		/*
15677c478bd9Sstevel@tonic-gate 		 * Check for other side reusing QPN that was attempted
15687c478bd9Sstevel@tonic-gate 		 * to be used, but somehow we sent a REJ.
15697c478bd9Sstevel@tonic-gate 		 */
15707c478bd9Sstevel@tonic-gate 		mutex_enter(&stale_qpn->state_mutex);
15717c478bd9Sstevel@tonic-gate 		if ((stale_lookup_status == IBCM_LOOKUP_EXISTS) &&
15727c478bd9Sstevel@tonic-gate 		    (stale_comid_lookup_status != IBCM_LOOKUP_EXISTS) &&
15737c478bd9Sstevel@tonic-gate 		    (stale_qpn->state == IBCM_STATE_REJ_SENT)) {
15747c478bd9Sstevel@tonic-gate 
15757c478bd9Sstevel@tonic-gate 			timeout_id_t		timer_val;
15767c478bd9Sstevel@tonic-gate 
15777c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L3(cmlog, "ibcm_process_rep_msg: "
15787c478bd9Sstevel@tonic-gate 			    "statep 0x%p being retired, REMOTE_QPN %x",
15797c478bd9Sstevel@tonic-gate 			    stale_qpn, statep->remote_qpn);
15807c478bd9Sstevel@tonic-gate 			/*
15817c478bd9Sstevel@tonic-gate 			 * OK, this is reuse of the QPN on the active side
15827c478bd9Sstevel@tonic-gate 			 * that was not connected last time.  This REQ is
15837c478bd9Sstevel@tonic-gate 			 * considered NEW.  We delete the statep here,
15847c478bd9Sstevel@tonic-gate 			 * then start over from the top.
15857c478bd9Sstevel@tonic-gate 			 */
15867c478bd9Sstevel@tonic-gate 			stale_qpn->state = IBCM_STATE_DELETE;
15877c478bd9Sstevel@tonic-gate 			timer_val = stale_qpn->timerid;
15887c478bd9Sstevel@tonic-gate 			stale_qpn->timerid = 0;
15897c478bd9Sstevel@tonic-gate 			mutex_exit(&stale_qpn->state_mutex);
15907c478bd9Sstevel@tonic-gate 			if (timer_val)
15917c478bd9Sstevel@tonic-gate 				(void) untimeout(timer_val);
15927c478bd9Sstevel@tonic-gate 			IBCM_REF_CNT_DECR(stale_qpn);
15937c478bd9Sstevel@tonic-gate 			ibcm_delete_state_data(stale_qpn);
15947c478bd9Sstevel@tonic-gate 			stale_qpn = statep;
15957c478bd9Sstevel@tonic-gate 			rw_enter(&hcap->hca_state_rwlock, RW_WRITER);
15967c478bd9Sstevel@tonic-gate 			stale_lookup_status = ibcm_lookup_msg(
15977c478bd9Sstevel@tonic-gate 			    IBCM_INCOMING_REP_STALE, 0, statep->remote_qpn,
15987c478bd9Sstevel@tonic-gate 			    statep->remote_hca_guid, hcap, &stale_qpn);
15997c478bd9Sstevel@tonic-gate 			rw_exit(&hcap->hca_state_rwlock);
16007c478bd9Sstevel@tonic-gate 			/* OK to continue now */
16017c478bd9Sstevel@tonic-gate 		} else
16027c478bd9Sstevel@tonic-gate 			mutex_exit(&stale_qpn->state_mutex);
16037c478bd9Sstevel@tonic-gate 
16047c478bd9Sstevel@tonic-gate 		/*
16057c478bd9Sstevel@tonic-gate 		 * lookup exists implies that there is already an entry with
16067c478bd9Sstevel@tonic-gate 		 * the remote qpn/comid and remote hca guid
16077c478bd9Sstevel@tonic-gate 		 */
16087c478bd9Sstevel@tonic-gate 		if ((stale_lookup_status == IBCM_LOOKUP_EXISTS) ||
16097c478bd9Sstevel@tonic-gate 		    (stale_comid_lookup_status == IBCM_LOOKUP_EXISTS)) {
16107c478bd9Sstevel@tonic-gate 
16117c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_rep_msg: "
16127c478bd9Sstevel@tonic-gate 			    "statep 0x%p stale detected "
16137c478bd9Sstevel@tonic-gate 			    "qpn_lkup %d comid_lkup %d", statep,
16147c478bd9Sstevel@tonic-gate 			    stale_lookup_status, stale_comid_lookup_status);
16157c478bd9Sstevel@tonic-gate 
16167c478bd9Sstevel@tonic-gate 			/* Disassociate statep and QP */
16177c478bd9Sstevel@tonic-gate 			IBCM_SET_CHAN_PRIVATE(statep->channel, NULL);
16187c478bd9Sstevel@tonic-gate 
16197c478bd9Sstevel@tonic-gate 			if (stale_lookup_status == IBCM_LOOKUP_EXISTS)
16207c478bd9Sstevel@tonic-gate 				reject_reason = IBT_CM_CONN_STALE;
16217c478bd9Sstevel@tonic-gate 			else
16227c478bd9Sstevel@tonic-gate 				reject_reason = IBT_CM_DUP_COM_ID;
16237c478bd9Sstevel@tonic-gate 
16247c478bd9Sstevel@tonic-gate 			ibcm_handler_conn_fail(statep,
16257c478bd9Sstevel@tonic-gate 			    IBT_CM_FAILURE_REJ_SENT, IBT_CM_FAILURE_REP,
16267c478bd9Sstevel@tonic-gate 			    reject_reason,
16277c478bd9Sstevel@tonic-gate 			    IBCM_REJ_PRIV(statep->stored_msg),
16287c478bd9Sstevel@tonic-gate 			    IBT_REJ_PRIV_DATA_SZ);
16297c478bd9Sstevel@tonic-gate 
16307c478bd9Sstevel@tonic-gate 			/* Send a REJ with stale reason for statep */
16317c478bd9Sstevel@tonic-gate 			ibcm_post_rej_mad(statep, reject_reason,
16327c478bd9Sstevel@tonic-gate 			    IBT_CM_FAILURE_REP, NULL, 0);
16337c478bd9Sstevel@tonic-gate 
16347c478bd9Sstevel@tonic-gate 			/* Now let's handle the logic for stale connections */
16357c478bd9Sstevel@tonic-gate 			/* If in established state, stale_statep is stale */
16367c478bd9Sstevel@tonic-gate 			if (stale_lookup_status == IBCM_LOOKUP_EXISTS) {
16377c478bd9Sstevel@tonic-gate 
16387c478bd9Sstevel@tonic-gate 				IBTF_DPRINTF_L2(cmlog, "ibcm_process_rep_msg: "
16397c478bd9Sstevel@tonic-gate 				    "state_qpn 0x%p stale QPN detected "
16407c478bd9Sstevel@tonic-gate 				    "state %X", stale_qpn, stale_qpn->state);
16417c478bd9Sstevel@tonic-gate 
16427c478bd9Sstevel@tonic-gate 				ibcm_insert_trace(stale_qpn,
16437c478bd9Sstevel@tonic-gate 				    IBCM_TRACE_STALE_DETECT);
16447c478bd9Sstevel@tonic-gate 
16457c478bd9Sstevel@tonic-gate 				mutex_enter(&stale_qpn->state_mutex);
16467c478bd9Sstevel@tonic-gate 				if (stale_qpn->state ==
16477c478bd9Sstevel@tonic-gate 				    IBCM_STATE_ESTABLISHED) {
16487c478bd9Sstevel@tonic-gate 					/* change state to DREQ sent */
16497c478bd9Sstevel@tonic-gate 					stale_qpn->state =
16507c478bd9Sstevel@tonic-gate 					    IBCM_STATE_TRANSIENT_DREQ_SENT;
16517c478bd9Sstevel@tonic-gate 					stale_qpn->stale = B_TRUE;
16527c478bd9Sstevel@tonic-gate 
16537c478bd9Sstevel@tonic-gate 					/* wait for/cancel pending LAP/APR */
16547c478bd9Sstevel@tonic-gate 					ibcm_sync_lapr_idle(stale_qpn);
16557c478bd9Sstevel@tonic-gate 					/* above call releases state mutex */
16567c478bd9Sstevel@tonic-gate 
16577c478bd9Sstevel@tonic-gate 					if (stale_qpn->dreq_msg == NULL)
16587c478bd9Sstevel@tonic-gate 						(void) ibcm_alloc_out_msg(
16597c478bd9Sstevel@tonic-gate 						    stale_qpn->
16607c478bd9Sstevel@tonic-gate 						    stored_reply_addr.ibmf_hdl,
16617c478bd9Sstevel@tonic-gate 						    &stale_qpn->dreq_msg,
16627c478bd9Sstevel@tonic-gate 						    MAD_METHOD_SEND);
16637c478bd9Sstevel@tonic-gate 
16647c478bd9Sstevel@tonic-gate 					if (stale_qpn->dreq_msg != NULL) {
16657c478bd9Sstevel@tonic-gate 						ibcm_post_dreq_mad(stale_qpn);
16667c478bd9Sstevel@tonic-gate 						mutex_enter(
16677c478bd9Sstevel@tonic-gate 						    &stale_qpn->state_mutex);
16687c478bd9Sstevel@tonic-gate 					} else {
16697c478bd9Sstevel@tonic-gate 						mutex_enter(
16707c478bd9Sstevel@tonic-gate 						    &stale_qpn->state_mutex);
16717c478bd9Sstevel@tonic-gate 						stale_qpn->state =
16727c478bd9Sstevel@tonic-gate 						    IBCM_STATE_ESTABLISHED;
16737c478bd9Sstevel@tonic-gate 						cv_broadcast(
16747c478bd9Sstevel@tonic-gate 						    &stale_qpn->block_mad_cv);
16757c478bd9Sstevel@tonic-gate 					}
16767c478bd9Sstevel@tonic-gate 				}
16777c478bd9Sstevel@tonic-gate 				IBCM_REF_CNT_DECR(stale_qpn);
16787c478bd9Sstevel@tonic-gate 				mutex_exit(&stale_qpn->state_mutex);
16797c478bd9Sstevel@tonic-gate 			}
16807c478bd9Sstevel@tonic-gate 
16817c478bd9Sstevel@tonic-gate 			if (stale_comid_lookup_status == IBCM_LOOKUP_EXISTS) {
16827c478bd9Sstevel@tonic-gate 
16837c478bd9Sstevel@tonic-gate 				IBTF_DPRINTF_L2(cmlog, "ibcm_process_rep_msg: "
16847c478bd9Sstevel@tonic-gate 				    "state_comid 0x%p stale COMID detected "
16857c478bd9Sstevel@tonic-gate 				    "state %X", stale_comid,
16867c478bd9Sstevel@tonic-gate 				    stale_comid->state);
16877c478bd9Sstevel@tonic-gate 
16887c478bd9Sstevel@tonic-gate 				mutex_enter(&stale_comid->state_mutex);
16897c478bd9Sstevel@tonic-gate 				if (!((stale_lookup_status ==
16907c478bd9Sstevel@tonic-gate 				    IBCM_LOOKUP_EXISTS) &&
16917c478bd9Sstevel@tonic-gate 				    (stale_qpn == stale_comid)) &&
16927c478bd9Sstevel@tonic-gate 				    (stale_comid->state ==
16937c478bd9Sstevel@tonic-gate 				    IBCM_STATE_ESTABLISHED)) {
16947c478bd9Sstevel@tonic-gate 
16957c478bd9Sstevel@tonic-gate 					ibcm_insert_trace(stale_comid,
16967c478bd9Sstevel@tonic-gate 					    IBCM_TRACE_STALE_DETECT);
16977c478bd9Sstevel@tonic-gate 
16987c478bd9Sstevel@tonic-gate 					/* change state to DREQ sent */
16997c478bd9Sstevel@tonic-gate 					stale_comid->state =
17007c478bd9Sstevel@tonic-gate 					    IBCM_STATE_TRANSIENT_DREQ_SENT;
17017c478bd9Sstevel@tonic-gate 					stale_comid->stale = B_TRUE;
17027c478bd9Sstevel@tonic-gate 
17037c478bd9Sstevel@tonic-gate 					/* wait for/cancel pending LAP/APR */
17047c478bd9Sstevel@tonic-gate 					ibcm_sync_lapr_idle(stale_comid);
17057c478bd9Sstevel@tonic-gate 
17067c478bd9Sstevel@tonic-gate 					/* above call releases state mutex */
17077c478bd9Sstevel@tonic-gate 
17087c478bd9Sstevel@tonic-gate 					if (stale_comid->dreq_msg == NULL)
17097c478bd9Sstevel@tonic-gate 						(void) ibcm_alloc_out_msg(
17107c478bd9Sstevel@tonic-gate 						    stale_comid->
17117c478bd9Sstevel@tonic-gate 						    stored_reply_addr.ibmf_hdl,
17127c478bd9Sstevel@tonic-gate 						    &stale_comid->dreq_msg,
17137c478bd9Sstevel@tonic-gate 						    MAD_METHOD_SEND);
17147c478bd9Sstevel@tonic-gate 
17157c478bd9Sstevel@tonic-gate 					if (stale_comid->dreq_msg != NULL) {
17167c478bd9Sstevel@tonic-gate 						ibcm_post_dreq_mad(stale_comid);
17177c478bd9Sstevel@tonic-gate 						mutex_enter(
17187c478bd9Sstevel@tonic-gate 						    &stale_comid->state_mutex);
17197c478bd9Sstevel@tonic-gate 					} else {
17207c478bd9Sstevel@tonic-gate 						mutex_enter(
17217c478bd9Sstevel@tonic-gate 						    &stale_comid->state_mutex);
17227c478bd9Sstevel@tonic-gate 						stale_comid->state =
17237c478bd9Sstevel@tonic-gate 						    IBCM_STATE_ESTABLISHED;
17247c478bd9Sstevel@tonic-gate 						cv_broadcast(
17257c478bd9Sstevel@tonic-gate 						    &stale_comid->block_mad_cv);
17267c478bd9Sstevel@tonic-gate 					}
17277c478bd9Sstevel@tonic-gate 				}
17287c478bd9Sstevel@tonic-gate 				IBCM_REF_CNT_DECR(stale_comid);
17297c478bd9Sstevel@tonic-gate 				mutex_exit(&stale_comid->state_mutex);
17307c478bd9Sstevel@tonic-gate 			}
17317c478bd9Sstevel@tonic-gate 			ibcm_return_open_data(statep, rep_msgp, reject_reason);
17327c478bd9Sstevel@tonic-gate 			return;
17337c478bd9Sstevel@tonic-gate 		}
17347c478bd9Sstevel@tonic-gate 
17357c478bd9Sstevel@tonic-gate 		/*
17367c478bd9Sstevel@tonic-gate 		 * No need to handle out of memory conditions as we called
17377c478bd9Sstevel@tonic-gate 		 * ibcm_lookup_msg() with IBT_CHAN_BLOCKING flags.
17387c478bd9Sstevel@tonic-gate 		 */
17397c478bd9Sstevel@tonic-gate 		ASSERT(stale_lookup_status == IBCM_LOOKUP_NEW);
17407c478bd9Sstevel@tonic-gate 
17417c478bd9Sstevel@tonic-gate 		/* Initialize the remote ack delay */
17427c478bd9Sstevel@tonic-gate 		statep->remote_ack_delay =
17437c478bd9Sstevel@tonic-gate 		    ibt_ib2usec(rep_msgp->rep_target_delay_plus >> 3);
17447c478bd9Sstevel@tonic-gate 
17457c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_process_rep_msg: statep 0x%p"
17467c478bd9Sstevel@tonic-gate 		    " passive hca_ack_delay= %x ", statep,
17477c478bd9Sstevel@tonic-gate 		    statep->remote_ack_delay);
17487c478bd9Sstevel@tonic-gate 
17497c478bd9Sstevel@tonic-gate 		response = ibcm_cep_state_rep(statep, rep_msgp,
17507c478bd9Sstevel@tonic-gate 		    &reject_reason, &arej_info_len);
17517c478bd9Sstevel@tonic-gate 
17527c478bd9Sstevel@tonic-gate 		if (response == IBCM_DEFER) {
17537c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L4(cmlog, "ibcm_process_rep_msg: "
17547c478bd9Sstevel@tonic-gate 			    "statep 0x%p client returned DEFER response",
17557c478bd9Sstevel@tonic-gate 			    statep);
17567c478bd9Sstevel@tonic-gate 			return;
17577c478bd9Sstevel@tonic-gate 		}
17587c478bd9Sstevel@tonic-gate 		ibcm_handle_cep_rep_response(statep, response,
17597c478bd9Sstevel@tonic-gate 		    reject_reason, arej_info_len, rep_msgp);
17607c478bd9Sstevel@tonic-gate 
17617c478bd9Sstevel@tonic-gate 		_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*statep))
17627c478bd9Sstevel@tonic-gate 
17637c478bd9Sstevel@tonic-gate 		return;
17647c478bd9Sstevel@tonic-gate 
17657c478bd9Sstevel@tonic-gate 	} else if (statep->state == IBCM_STATE_DELETE) {
17667c478bd9Sstevel@tonic-gate 
17677c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
17687c478bd9Sstevel@tonic-gate 		ibcm_build_n_post_rej_mad(input_madp,
17697c478bd9Sstevel@tonic-gate 		    b2h32(rep_msgp->rep_local_comm_id), cm_mad_addr,
17707c478bd9Sstevel@tonic-gate 		    IBT_CM_FAILURE_REP, IBT_CM_INVALID_CID);
17717c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
17727c478bd9Sstevel@tonic-gate 	} else {
17737c478bd9Sstevel@tonic-gate 
17747c478bd9Sstevel@tonic-gate #ifdef DEBUG
17757c478bd9Sstevel@tonic-gate 		if (ibcm_test_mode > 0)
17767c478bd9Sstevel@tonic-gate 			if (statep->state == IBCM_STATE_REP_RCVD)
17777c478bd9Sstevel@tonic-gate 				IBTF_DPRINTF_L2(cmlog, "ibcm_process_rep_msg: "
17787c478bd9Sstevel@tonic-gate 				    "REP re-send from passive for statep 0x%p"
17797c478bd9Sstevel@tonic-gate 				    " in state %d", statep, statep->state);
17807c478bd9Sstevel@tonic-gate 			else
17817c478bd9Sstevel@tonic-gate 				IBTF_DPRINTF_L2(cmlog, "ibcm_process_rep_msg: "
17827c478bd9Sstevel@tonic-gate 				    "Unexpected REP for statep 0x%p in "
17837c478bd9Sstevel@tonic-gate 				    "state %d", statep, statep->state);
17847c478bd9Sstevel@tonic-gate #endif
17857c478bd9Sstevel@tonic-gate 	}
17867c478bd9Sstevel@tonic-gate 	/* decrement ref count and return for LOOKUP_EXISTS */
17877c478bd9Sstevel@tonic-gate 	IBCM_REF_CNT_DECR(statep);
17887c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
17897c478bd9Sstevel@tonic-gate 
17907c478bd9Sstevel@tonic-gate }
17917c478bd9Sstevel@tonic-gate 
17927c478bd9Sstevel@tonic-gate /*
17937c478bd9Sstevel@tonic-gate  * ibcm_handle_cep_req_response:
17947c478bd9Sstevel@tonic-gate  *	Processes the response from ibcm_cep_state_rep. Called holding a
17957c478bd9Sstevel@tonic-gate  *	statep ref cnt. The statep ref cnt is decremented before returning.
17967c478bd9Sstevel@tonic-gate  */
17977c478bd9Sstevel@tonic-gate void
ibcm_handle_cep_rep_response(ibcm_state_data_t * statep,ibcm_status_t response,ibt_cm_reason_t reject_reason,uint8_t arej_info_len,ibcm_rep_msg_t * rep_msgp)17987c478bd9Sstevel@tonic-gate ibcm_handle_cep_rep_response(ibcm_state_data_t *statep, ibcm_status_t response,
17997c478bd9Sstevel@tonic-gate     ibt_cm_reason_t reject_reason, uint8_t arej_info_len,
18007c478bd9Sstevel@tonic-gate     ibcm_rep_msg_t *rep_msgp)
18017c478bd9Sstevel@tonic-gate {
18027c478bd9Sstevel@tonic-gate 	/* wait until the send completion callback is invoked for REQ post */
18037c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
18047c478bd9Sstevel@tonic-gate 	while (statep->send_mad_flags & IBCM_REQ_POST_BUSY)
18057c478bd9Sstevel@tonic-gate 		cv_wait(&statep->block_mad_cv, &statep->state_mutex);
18067c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
18077c478bd9Sstevel@tonic-gate 
18087c478bd9Sstevel@tonic-gate 	if (response == IBCM_SEND_RTU) {
18097c478bd9Sstevel@tonic-gate 		/* if connection aborted, return */
18107c478bd9Sstevel@tonic-gate 		if (ibcm_post_rtu_mad(statep) != IBCM_SUCCESS) {
18117c478bd9Sstevel@tonic-gate 			mutex_enter(&statep->state_mutex);
18127c478bd9Sstevel@tonic-gate 			IBCM_REF_CNT_DECR(statep);
18137c478bd9Sstevel@tonic-gate 			mutex_exit(&statep->state_mutex);
18147c478bd9Sstevel@tonic-gate 			return;
18157c478bd9Sstevel@tonic-gate 		}
18167c478bd9Sstevel@tonic-gate 
18177c478bd9Sstevel@tonic-gate 		/*
18187c478bd9Sstevel@tonic-gate 		 * Call client handler with cm event  IBT_CM_EVENT_CONN_EST to
18197c478bd9Sstevel@tonic-gate 		 * indicate RTU posted
18207c478bd9Sstevel@tonic-gate 		 */
18217c478bd9Sstevel@tonic-gate 		ibcm_cep_send_rtu(statep);
18227c478bd9Sstevel@tonic-gate 	} else {
1823fde3102fShiremath 		IBTF_DPRINTF_L4(cmlog, "ibcm_handle_cep_rep_response: statep %p"
182424b28d04Shiremath 		    " posting REJ reject_reason = %d", statep, reject_reason);
18257c478bd9Sstevel@tonic-gate 
18267c478bd9Sstevel@tonic-gate 		ASSERT(response == IBCM_SEND_REJ);
18277c478bd9Sstevel@tonic-gate 		ibcm_post_rej_mad(statep, reject_reason, IBT_CM_FAILURE_REP,
18287c478bd9Sstevel@tonic-gate 		    NULL, arej_info_len);
18297c478bd9Sstevel@tonic-gate 	}
18307c478bd9Sstevel@tonic-gate 
18317c478bd9Sstevel@tonic-gate 	ibcm_return_open_data(statep, rep_msgp, reject_reason);
18327c478bd9Sstevel@tonic-gate }
18337c478bd9Sstevel@tonic-gate 
18347c478bd9Sstevel@tonic-gate /*
18357c478bd9Sstevel@tonic-gate  * ibcm_return_open_data:
18367c478bd9Sstevel@tonic-gate  *	Initializes the ibt_open_rc_channel return data. The statep ref cnt is
18377c478bd9Sstevel@tonic-gate  *	decremented before returning.
18387c478bd9Sstevel@tonic-gate  */
18397c478bd9Sstevel@tonic-gate static void
ibcm_return_open_data(ibcm_state_data_t * statep,ibcm_rep_msg_t * rep_msgp,ibt_cm_reason_t reject_reason)18407c478bd9Sstevel@tonic-gate ibcm_return_open_data(ibcm_state_data_t *statep, ibcm_rep_msg_t *rep_msgp,
18417c478bd9Sstevel@tonic-gate     ibt_cm_reason_t reject_reason)
18427c478bd9Sstevel@tonic-gate {
18437c478bd9Sstevel@tonic-gate 	/* signal waiting CV - blocking in ibt_open_channel() */
18447c478bd9Sstevel@tonic-gate 	if (statep->open_return_data != NULL) {
18457c478bd9Sstevel@tonic-gate 		if (statep->open_return_data->rc_priv_data_len > 0)
18467c478bd9Sstevel@tonic-gate 			bcopy(rep_msgp->rep_private_data,
18477c478bd9Sstevel@tonic-gate 			    statep->open_return_data->rc_priv_data,
18487c478bd9Sstevel@tonic-gate 			    statep->open_return_data->rc_priv_data_len);
18497c478bd9Sstevel@tonic-gate 		statep->open_return_data->rc_rdma_ra_in =
1850015f8fffShiremath 		    rep_msgp->rep_initiator_depth;
18515c42ea03Shiremath 		statep->open_return_data->rc_rdma_ra_out =
18525c42ea03Shiremath 		    rep_msgp->rep_resp_resources;
18537c478bd9Sstevel@tonic-gate 		statep->open_return_data->rc_failover_status =
1854015f8fffShiremath 		    rep_msgp->rep_target_delay_plus >> 1 & 3;
18557c478bd9Sstevel@tonic-gate 		statep->open_return_data->rc_status = reject_reason;
18567c478bd9Sstevel@tonic-gate 
18577c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
18587c478bd9Sstevel@tonic-gate 		statep->open_done = B_TRUE;
18597c478bd9Sstevel@tonic-gate 		cv_broadcast(&statep->block_client_cv);
18607c478bd9Sstevel@tonic-gate 	} else mutex_enter(&statep->state_mutex);
18617c478bd9Sstevel@tonic-gate 
18627c478bd9Sstevel@tonic-gate 	/* decrement ref count and return for LOOKUP_EXISTS */
18637c478bd9Sstevel@tonic-gate 	IBCM_REF_CNT_DECR(statep);
18647c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
18657c478bd9Sstevel@tonic-gate }
18667c478bd9Sstevel@tonic-gate 
18677c478bd9Sstevel@tonic-gate 
18687c478bd9Sstevel@tonic-gate /*
18697c478bd9Sstevel@tonic-gate  * ibcm_process_mra_msg:
18707c478bd9Sstevel@tonic-gate  *	Called from ibcm_process_incoming_mad on reception of a MRA message
18717c478bd9Sstevel@tonic-gate  *
18727c478bd9Sstevel@tonic-gate  *	Cancels existing timer, and sets a new timer based on timeout
18737c478bd9Sstevel@tonic-gate  *	value from MRA message. The remaining retry count of statep is
18747c478bd9Sstevel@tonic-gate  *	not changed, and timer value for the remaining retry timers is
18757c478bd9Sstevel@tonic-gate  *	also not changed
18767c478bd9Sstevel@tonic-gate  *
18777c478bd9Sstevel@tonic-gate  * INPUTS:
18787c478bd9Sstevel@tonic-gate  *	hcap		- HCA entry pointer
18797c478bd9Sstevel@tonic-gate  *	input_madp	- CM MAD that is input to this function
18807c478bd9Sstevel@tonic-gate  *	cm_mad_addr	- Address information for the MAD
18817c478bd9Sstevel@tonic-gate  *
18827c478bd9Sstevel@tonic-gate  * RETURN VALUE:	NONE
18837c478bd9Sstevel@tonic-gate  */
18847c478bd9Sstevel@tonic-gate void
ibcm_process_mra_msg(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)18857c478bd9Sstevel@tonic-gate ibcm_process_mra_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
18867c478bd9Sstevel@tonic-gate     ibcm_mad_addr_t *cm_mad_addr)
18877c478bd9Sstevel@tonic-gate {
18887c478bd9Sstevel@tonic-gate 	ibcm_status_t		state_lookup_status;
1889015f8fffShiremath 	ibcm_mra_msg_t		*mra_msgp =
1890015f8fffShiremath 	    (ibcm_mra_msg_t *)(&input_madp[IBCM_MAD_HDR_SIZE]);
18917c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep = NULL;
18927c478bd9Sstevel@tonic-gate 	uint8_t			mra_msg;
18937c478bd9Sstevel@tonic-gate 
18947c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_mra_msg:");
18957c478bd9Sstevel@tonic-gate 
18967c478bd9Sstevel@tonic-gate 	/* Lookup for an existing state structure (as a READER) */
18977c478bd9Sstevel@tonic-gate 	rw_enter(&hcap->hca_state_rwlock, RW_READER);
18987c478bd9Sstevel@tonic-gate 	state_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_MRA,
18997c478bd9Sstevel@tonic-gate 	    b2h32(mra_msgp->mra_remote_comm_id), 0, 0, hcap, &statep);
19007c478bd9Sstevel@tonic-gate 	rw_exit(&hcap->hca_state_rwlock);
19017c478bd9Sstevel@tonic-gate 
19027c478bd9Sstevel@tonic-gate 	/* if state doesn't exist just return */
19037c478bd9Sstevel@tonic-gate 	if (state_lookup_status != IBCM_LOOKUP_EXISTS) {
19047c478bd9Sstevel@tonic-gate 		ibcm_build_n_post_rej_mad(input_madp,
19057c478bd9Sstevel@tonic-gate 		    b2h32(mra_msgp->mra_local_comm_id), cm_mad_addr,
19067c478bd9Sstevel@tonic-gate 		    IBT_CM_FAILURE_UNKNOWN, IBT_CM_INVALID_CID);
19077c478bd9Sstevel@tonic-gate 		return;
19087c478bd9Sstevel@tonic-gate 	}
19097c478bd9Sstevel@tonic-gate 
19107c478bd9Sstevel@tonic-gate 	if (IBCM_OUT_HDRP(statep->stored_msg)->TransactionID !=
19117c478bd9Sstevel@tonic-gate 	    ((ib_mad_hdr_t *)(input_madp))->TransactionID) {
19127c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
19137c478bd9Sstevel@tonic-gate 		IBCM_REF_CNT_DECR(statep);
19147c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
1915fde3102fShiremath 		IBTF_DPRINTF_L3(cmlog, "ibcm_process_mra_msg: statep 0x%p "
19167c478bd9Sstevel@tonic-gate 		    "MRA MAD with tid expected 0x%llX tid found 0x%llX "
19177c478bd9Sstevel@tonic-gate 		    "com id 0x%x arrived", statep,
19187c478bd9Sstevel@tonic-gate 		    b2h64(IBCM_OUT_HDRP(statep->stored_msg)->TransactionID),
19197c478bd9Sstevel@tonic-gate 		    b2h64(((ib_mad_hdr_t *)(input_madp))->TransactionID),
19207c478bd9Sstevel@tonic-gate 		    b2h32(mra_msgp->mra_local_comm_id));
19217c478bd9Sstevel@tonic-gate 		return;
19227c478bd9Sstevel@tonic-gate 	}
19237c478bd9Sstevel@tonic-gate 
19247c478bd9Sstevel@tonic-gate 	ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_MRA);
19257c478bd9Sstevel@tonic-gate 
19267c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
19277c478bd9Sstevel@tonic-gate 
19287c478bd9Sstevel@tonic-gate 	/*
19297c478bd9Sstevel@tonic-gate 	 * Only allow for REQ/REP "mra_msg_typ" ONLY
19307c478bd9Sstevel@tonic-gate 	 * (to validate MRA message received)?
19317c478bd9Sstevel@tonic-gate 	 */
19327c478bd9Sstevel@tonic-gate 	mra_msg = mra_msgp->mra_message_type_plus >> 6;
19337c478bd9Sstevel@tonic-gate 	if ((mra_msg != IBT_CM_MRA_TYPE_REQ) &&
19347c478bd9Sstevel@tonic-gate 	    (mra_msg != IBT_CM_MRA_TYPE_REP) &&
19357c478bd9Sstevel@tonic-gate 	    (mra_msg != IBT_CM_MRA_TYPE_LAP)) {
19367c478bd9Sstevel@tonic-gate 
19377c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_process_mra_msg: statep 0x%p "
19387c478bd9Sstevel@tonic-gate 		    "Unexpected MRA MSG Type %x", statep, mra_msg);
19397c478bd9Sstevel@tonic-gate 		IBCM_REF_CNT_DECR(statep);
19407c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
19417c478bd9Sstevel@tonic-gate 		return;
19427c478bd9Sstevel@tonic-gate 	}
19437c478bd9Sstevel@tonic-gate 
19447c478bd9Sstevel@tonic-gate 	if ((statep->state == IBCM_STATE_REQ_SENT) ||
19457c478bd9Sstevel@tonic-gate 	    (statep->state == IBCM_STATE_REP_SENT) ||
19467c478bd9Sstevel@tonic-gate 	    ((statep->state == IBCM_STATE_ESTABLISHED) &&
19477c478bd9Sstevel@tonic-gate 	    (statep->ap_state == IBCM_AP_STATE_LAP_SENT))) {
19487c478bd9Sstevel@tonic-gate 		timeout_id_t	timer_val = statep->timerid;
1949934f0bccShiremath 		clock_t		service_timeout;
19507c478bd9Sstevel@tonic-gate 
19517c478bd9Sstevel@tonic-gate 		if (statep->state == IBCM_STATE_REQ_SENT) {
19527c478bd9Sstevel@tonic-gate 			mra_msg = IBT_CM_MRA_TYPE_REQ;
19537c478bd9Sstevel@tonic-gate 			statep->state = IBCM_STATE_REP_WAIT;
19547c478bd9Sstevel@tonic-gate 		} else if (statep->state == IBCM_STATE_REP_SENT) {
19557c478bd9Sstevel@tonic-gate 			mra_msg = IBT_CM_MRA_TYPE_REP;
19567c478bd9Sstevel@tonic-gate 			statep->state = IBCM_STATE_MRA_REP_RCVD;
19577c478bd9Sstevel@tonic-gate 		} else { /* statep->state == IBCM_STATE_LAP_SENT */
19587c478bd9Sstevel@tonic-gate 			mra_msg = IBT_CM_MRA_TYPE_LAP;
19597c478bd9Sstevel@tonic-gate 			statep->ap_state = IBCM_AP_STATE_MRA_LAP_RCVD;
19607c478bd9Sstevel@tonic-gate 		}
19617c478bd9Sstevel@tonic-gate 
19627c478bd9Sstevel@tonic-gate 		/* cancel the timer */
19637c478bd9Sstevel@tonic-gate 		statep->timerid = 0;
19647c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
19657c478bd9Sstevel@tonic-gate 
19667c478bd9Sstevel@tonic-gate 		(void) untimeout(timer_val);
19677c478bd9Sstevel@tonic-gate 
1968934f0bccShiremath 		service_timeout =
1969934f0bccShiremath 		    ibt_ib2usec(mra_msgp->mra_service_timeout_plus >> 3);
1970934f0bccShiremath 
1971934f0bccShiremath 		/*
1972934f0bccShiremath 		 * If tunable MAX MRA Service Timeout parameter is set, then
1973934f0bccShiremath 		 * verify whether the requested timer value exceeds the MAX
1974934f0bccShiremath 		 * value and reset the timer value to the MAX value.
1975934f0bccShiremath 		 */
1976934f0bccShiremath 		if (ibcm_mra_service_timeout_max &&
1977934f0bccShiremath 		    ibcm_mra_service_timeout_max < service_timeout) {
1978934f0bccShiremath 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_mra_msg: "
1979934f0bccShiremath 			    "Unexpected MRA Service Timeout value (%ld), Max "
1980934f0bccShiremath 			    "allowed is (%ld)", service_timeout,
1981934f0bccShiremath 			    ibcm_mra_service_timeout_max);
1982934f0bccShiremath 			service_timeout = ibcm_mra_service_timeout_max;
1983934f0bccShiremath 		}
1984934f0bccShiremath 
19857c478bd9Sstevel@tonic-gate 		/*
19867c478bd9Sstevel@tonic-gate 		 * Invoke client handler to pass the MRA private data
19877c478bd9Sstevel@tonic-gate 		 */
19887c478bd9Sstevel@tonic-gate 		if (statep->cm_handler != NULL) {
19897c478bd9Sstevel@tonic-gate 			ibt_cm_event_t	event;
19907c478bd9Sstevel@tonic-gate 
19917c478bd9Sstevel@tonic-gate 			bzero(&event, sizeof (event));
19927c478bd9Sstevel@tonic-gate 
19937c478bd9Sstevel@tonic-gate 			event.cm_type = IBT_CM_EVENT_MRA_RCV;
19947c478bd9Sstevel@tonic-gate 			event.cm_channel = statep->channel;
19957c478bd9Sstevel@tonic-gate 			event.cm_session_id = NULL;
19967c478bd9Sstevel@tonic-gate 			event.cm_priv_data = mra_msgp->mra_private_data;
19977c478bd9Sstevel@tonic-gate 			event.cm_priv_data_len = IBT_MRA_PRIV_DATA_SZ;
19987c478bd9Sstevel@tonic-gate 
19997c478bd9Sstevel@tonic-gate 			event.cm_event.mra.mra_msg_type = mra_msg;
20007c478bd9Sstevel@tonic-gate 
2001934f0bccShiremath 			event.cm_event.mra.mra_service_time = service_timeout;
20027c478bd9Sstevel@tonic-gate 
20037c478bd9Sstevel@tonic-gate 			/* Client cannot return private data */
20047c478bd9Sstevel@tonic-gate 			(void) statep->cm_handler(statep->state_cm_private,
20057c478bd9Sstevel@tonic-gate 			    &event, NULL, NULL, 0);
20067c478bd9Sstevel@tonic-gate 		}
20077c478bd9Sstevel@tonic-gate 
20087c478bd9Sstevel@tonic-gate 		/*
20097c478bd9Sstevel@tonic-gate 		 * Must re-check state, as an RTU could have come
20107c478bd9Sstevel@tonic-gate 		 * after the above mutex_exit and mutex_enter below
20117c478bd9Sstevel@tonic-gate 		 */
20127c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
20137c478bd9Sstevel@tonic-gate 		if ((statep->state == IBCM_STATE_REP_WAIT) ||
20147c478bd9Sstevel@tonic-gate 		    (statep->state == IBCM_STATE_MRA_REP_RCVD) ||
20157c478bd9Sstevel@tonic-gate 		    (statep->ap_state == IBCM_AP_STATE_MRA_LAP_RCVD)) {
20167c478bd9Sstevel@tonic-gate 
20177c478bd9Sstevel@tonic-gate 			statep->remaining_retry_cnt = statep->max_cm_retries;
20187c478bd9Sstevel@tonic-gate 
20197c478bd9Sstevel@tonic-gate 			/*
20207c478bd9Sstevel@tonic-gate 			 * The timeout interval is changed only for the first
20217c478bd9Sstevel@tonic-gate 			 * retry.  The later retries use the timeout from
20227c478bd9Sstevel@tonic-gate 			 * statep->timer_value
20237c478bd9Sstevel@tonic-gate 			 */
20247c478bd9Sstevel@tonic-gate 			statep->timer_stored_state = statep->state;
202524b28d04Shiremath 			statep->timer_value = statep->pkt_life_time +
2026934f0bccShiremath 			    service_timeout;
202724b28d04Shiremath 			statep->timerid = IBCM_TIMEOUT(statep,
202824b28d04Shiremath 			    statep->timer_value);
20297c478bd9Sstevel@tonic-gate 		}
20307c478bd9Sstevel@tonic-gate 
20317c478bd9Sstevel@tonic-gate 	} else if (statep->state == IBCM_STATE_DELETE) {
20327c478bd9Sstevel@tonic-gate 
20337c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
20347c478bd9Sstevel@tonic-gate 		ibcm_build_n_post_rej_mad(input_madp,
20357c478bd9Sstevel@tonic-gate 		    b2h32(mra_msgp->mra_local_comm_id), cm_mad_addr,
20367c478bd9Sstevel@tonic-gate 		    IBT_CM_FAILURE_UNKNOWN, IBT_CM_INVALID_CID);
20377c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
20387c478bd9Sstevel@tonic-gate 	} else {
20397c478bd9Sstevel@tonic-gate 
20407c478bd9Sstevel@tonic-gate #ifdef DEBUG
20417c478bd9Sstevel@tonic-gate 		if (ibcm_test_mode > 0)
20427c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_mra_msg: "
20437c478bd9Sstevel@tonic-gate 			    "Unexpected mra for statep 0x%p in state %d",
20447c478bd9Sstevel@tonic-gate 			    statep, statep->state);
20457c478bd9Sstevel@tonic-gate #endif
20467c478bd9Sstevel@tonic-gate 	}
20477c478bd9Sstevel@tonic-gate 
20487c478bd9Sstevel@tonic-gate 	IBCM_REF_CNT_DECR(statep);
20497c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
20507c478bd9Sstevel@tonic-gate }
20517c478bd9Sstevel@tonic-gate 
20527c478bd9Sstevel@tonic-gate 
20537c478bd9Sstevel@tonic-gate /*
20547c478bd9Sstevel@tonic-gate  * ibcm_process_rtu_msg:
20557c478bd9Sstevel@tonic-gate  *	Called from ibcm_process_incoming_mad on reception of a RTU message
20567c478bd9Sstevel@tonic-gate  *
20577c478bd9Sstevel@tonic-gate  *	Changes connection state to established if in REP SENT state
20587c478bd9Sstevel@tonic-gate  *
20597c478bd9Sstevel@tonic-gate  * INPUTS:
20607c478bd9Sstevel@tonic-gate  *	hcap		- HCA entry pointer
20617c478bd9Sstevel@tonic-gate  *	input_madp	- CM MAD that is input to this function
20627c478bd9Sstevel@tonic-gate  *	cm_mad_addr	- Address information for the MAD
20637c478bd9Sstevel@tonic-gate  *
20647c478bd9Sstevel@tonic-gate  * RETURN VALUE:	NONE
20657c478bd9Sstevel@tonic-gate  */
20667c478bd9Sstevel@tonic-gate void
ibcm_process_rtu_msg(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)20677c478bd9Sstevel@tonic-gate ibcm_process_rtu_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
20687c478bd9Sstevel@tonic-gate     ibcm_mad_addr_t *cm_mad_addr)
20697c478bd9Sstevel@tonic-gate {
20707c478bd9Sstevel@tonic-gate 	timeout_id_t		timer_val;
20717c478bd9Sstevel@tonic-gate 	ibcm_status_t		status;
2072015f8fffShiremath 	ibcm_rtu_msg_t		*rtu_msg =
2073015f8fffShiremath 	    (ibcm_rtu_msg_t *)(&input_madp[IBCM_MAD_HDR_SIZE]);
20747c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep = NULL;
20757c478bd9Sstevel@tonic-gate 
20767c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_rtu_msg:");
20777c478bd9Sstevel@tonic-gate 
20787c478bd9Sstevel@tonic-gate 	/* Lookup for an existing state structure - using a reader lock */
20797c478bd9Sstevel@tonic-gate 	rw_enter(&hcap->hca_state_rwlock, RW_READER);
20807c478bd9Sstevel@tonic-gate 	status = ibcm_lookup_msg(IBCM_INCOMING_RTU,
20817c478bd9Sstevel@tonic-gate 	    b2h32(rtu_msg->rtu_remote_comm_id), 0, 0, hcap, &statep);
20827c478bd9Sstevel@tonic-gate 	rw_exit(&hcap->hca_state_rwlock);
20837c478bd9Sstevel@tonic-gate 
20847c478bd9Sstevel@tonic-gate 	/* if state doesn't exist just return */
20857c478bd9Sstevel@tonic-gate 	if (status != IBCM_LOOKUP_EXISTS) {
20867c478bd9Sstevel@tonic-gate 		ibcm_build_n_post_rej_mad(input_madp,
20877c478bd9Sstevel@tonic-gate 		    b2h32(rtu_msg->rtu_local_comm_id), cm_mad_addr,
20887c478bd9Sstevel@tonic-gate 		    IBT_CM_FAILURE_UNKNOWN, IBT_CM_INVALID_CID);
20897c478bd9Sstevel@tonic-gate 		return;
20907c478bd9Sstevel@tonic-gate 	}
20917c478bd9Sstevel@tonic-gate 
20927c478bd9Sstevel@tonic-gate 	if (IBCM_OUT_HDRP(statep->stored_msg)->TransactionID !=
20937c478bd9Sstevel@tonic-gate 	    ((ib_mad_hdr_t *)(input_madp))->TransactionID) {
20947c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
20957c478bd9Sstevel@tonic-gate 		IBCM_REF_CNT_DECR(statep);
20967c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
2097fde3102fShiremath 		IBTF_DPRINTF_L3(cmlog, "ibcm_process_rtu_msg: statep 0x%p "
20987c478bd9Sstevel@tonic-gate 		    "An RTU MAD with tid expected 0x%llX tid found 0x%llX "
20997c478bd9Sstevel@tonic-gate 		    "com id 0x%x arrived", statep,
21007c478bd9Sstevel@tonic-gate 		    b2h64(IBCM_OUT_HDRP(statep->stored_msg)->TransactionID),
21017c478bd9Sstevel@tonic-gate 		    b2h64(((ib_mad_hdr_t *)(input_madp))->TransactionID),
21027c478bd9Sstevel@tonic-gate 		    b2h32(rtu_msg->rtu_remote_comm_id));
21037c478bd9Sstevel@tonic-gate 		return;
21047c478bd9Sstevel@tonic-gate 	}
21057c478bd9Sstevel@tonic-gate 
21067c478bd9Sstevel@tonic-gate 	ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_RTU);
21077c478bd9Sstevel@tonic-gate 
21087c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
21097c478bd9Sstevel@tonic-gate 
21107c478bd9Sstevel@tonic-gate 	if ((statep->state == IBCM_STATE_REP_SENT) ||
21117c478bd9Sstevel@tonic-gate 	    (statep->state == IBCM_STATE_MRA_REP_RCVD)) {
21127c478bd9Sstevel@tonic-gate 
21137c478bd9Sstevel@tonic-gate 		/* transient until ibt_modify_qp succeeds to RTS */
21147c478bd9Sstevel@tonic-gate 		statep->state = IBCM_STATE_TRANSIENT_ESTABLISHED;
21157c478bd9Sstevel@tonic-gate 
21167c478bd9Sstevel@tonic-gate 		timer_val = statep->timerid;
21177c478bd9Sstevel@tonic-gate 		statep->timerid = 0;
21187c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
21197c478bd9Sstevel@tonic-gate 
21207c478bd9Sstevel@tonic-gate 		(void) untimeout(timer_val);
21217c478bd9Sstevel@tonic-gate 
21227c478bd9Sstevel@tonic-gate 		ibcm_cep_state_rtu(statep, rtu_msg);
21237c478bd9Sstevel@tonic-gate 
21247c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
21257c478bd9Sstevel@tonic-gate 
21267c478bd9Sstevel@tonic-gate 	} else if (statep->state == IBCM_STATE_REJ_SENT) {
21277c478bd9Sstevel@tonic-gate 		ibcm_resend_rej_mad(statep);
21287c478bd9Sstevel@tonic-gate 	} else if (statep->state == IBCM_STATE_DELETE) {
21297c478bd9Sstevel@tonic-gate 
21307c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
21317c478bd9Sstevel@tonic-gate 		ibcm_build_n_post_rej_mad(input_madp,
21327c478bd9Sstevel@tonic-gate 		    b2h32(rtu_msg->rtu_local_comm_id), cm_mad_addr,
21337c478bd9Sstevel@tonic-gate 		    IBT_CM_FAILURE_UNKNOWN, IBT_CM_INVALID_CID);
21347c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
21357c478bd9Sstevel@tonic-gate 	} else {
21367c478bd9Sstevel@tonic-gate 
21377c478bd9Sstevel@tonic-gate #ifdef DEBUG
21387c478bd9Sstevel@tonic-gate 		if ((ibcm_test_mode > 0) &&
21397c478bd9Sstevel@tonic-gate 		    (statep->state != IBCM_STATE_ESTABLISHED))
21407c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_rtu_msg: "
21417c478bd9Sstevel@tonic-gate 			    "Unexpected rtu for statep 0x%p in state %d",
21427c478bd9Sstevel@tonic-gate 			    statep, statep->state);
21437c478bd9Sstevel@tonic-gate #endif
21447c478bd9Sstevel@tonic-gate 	}
21457c478bd9Sstevel@tonic-gate 
21467c478bd9Sstevel@tonic-gate 	IBCM_REF_CNT_DECR(statep);
21477c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
21487c478bd9Sstevel@tonic-gate }
21497c478bd9Sstevel@tonic-gate 
21507c478bd9Sstevel@tonic-gate 
21517c478bd9Sstevel@tonic-gate /*
21527c478bd9Sstevel@tonic-gate  * ibcm_process_rej_msg:
21537c478bd9Sstevel@tonic-gate  *	Called from ibcm_process_incoming_mad on reception of a REJ message.
21547c478bd9Sstevel@tonic-gate  *
21557c478bd9Sstevel@tonic-gate  * INPUTS:
21567c478bd9Sstevel@tonic-gate  *	hcap		- HCA entry pointer
21577c478bd9Sstevel@tonic-gate  *	input_madp	- CM MAD that is input to this function
21587c478bd9Sstevel@tonic-gate  *	cm_mad_addr	- Address information for the MAD
21597c478bd9Sstevel@tonic-gate  *
21607c478bd9Sstevel@tonic-gate  * RETURN VALUE:	NONE
21617c478bd9Sstevel@tonic-gate  */
21627c478bd9Sstevel@tonic-gate /* ARGSUSED */
21637c478bd9Sstevel@tonic-gate void
ibcm_process_rej_msg(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)21647c478bd9Sstevel@tonic-gate ibcm_process_rej_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
21657c478bd9Sstevel@tonic-gate     ibcm_mad_addr_t *cm_mad_addr)
21667c478bd9Sstevel@tonic-gate {
21677c478bd9Sstevel@tonic-gate 	ibcm_status_t		state_lookup_status;
2168015f8fffShiremath 	ibcm_rej_msg_t		*rej_msg =
2169015f8fffShiremath 	    (ibcm_rej_msg_t *)(&input_madp[IBCM_MAD_HDR_SIZE]);
21707c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep = NULL;
21717c478bd9Sstevel@tonic-gate 	ib_guid_t		remote_hca_guid;
21727c478bd9Sstevel@tonic-gate 	ibcm_conn_state_t	rej_state;
21737c478bd9Sstevel@tonic-gate 
21747c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_rej_msg:");
21757c478bd9Sstevel@tonic-gate 
21767c478bd9Sstevel@tonic-gate 	/* Lookup for an existing state structure */
21777c478bd9Sstevel@tonic-gate 	rw_enter(&hcap->hca_state_rwlock, RW_READER);	/* grab READER lock */
21787c478bd9Sstevel@tonic-gate 
21797c478bd9Sstevel@tonic-gate 	if ((b2h32(rej_msg->rej_remote_comm_id) == 0) &&
21807c478bd9Sstevel@tonic-gate 	    ((rej_msg->rej_reject_info_len_plus >> 1) >= sizeof (ib_guid_t)) &&
21817c478bd9Sstevel@tonic-gate 	    (b2h16(rej_msg->rej_rejection_reason) == IBT_CM_TIMEOUT)) {
21827c478bd9Sstevel@tonic-gate 		bcopy(rej_msg->rej_addl_rej_info, &remote_hca_guid,
21837c478bd9Sstevel@tonic-gate 		    sizeof (ib_guid_t));
21847c478bd9Sstevel@tonic-gate 		remote_hca_guid = b2h64(remote_hca_guid);
21857c478bd9Sstevel@tonic-gate 
21867c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_process_rej_msg: "
21877c478bd9Sstevel@tonic-gate 		    "hca guid in REJ's ARI =  %llX", remote_hca_guid);
21887c478bd9Sstevel@tonic-gate 
21897c478bd9Sstevel@tonic-gate 		state_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_REJ_RCOMID,
21907c478bd9Sstevel@tonic-gate 		    b2h32(rej_msg->rej_local_comm_id), 0, remote_hca_guid,
21917c478bd9Sstevel@tonic-gate 		    hcap, &statep);
21927c478bd9Sstevel@tonic-gate 	} else
21937c478bd9Sstevel@tonic-gate 		state_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_REJ,
21947c478bd9Sstevel@tonic-gate 		    b2h32(rej_msg->rej_remote_comm_id), 0, 0, hcap, &statep);
21957c478bd9Sstevel@tonic-gate 
21967c478bd9Sstevel@tonic-gate 	rw_exit(&hcap->hca_state_rwlock);
21977c478bd9Sstevel@tonic-gate 
21987c478bd9Sstevel@tonic-gate 
21997c478bd9Sstevel@tonic-gate 	/* if state doesn't exist just return */
22007c478bd9Sstevel@tonic-gate 	if (state_lookup_status != IBCM_LOOKUP_EXISTS) {
22017c478bd9Sstevel@tonic-gate 
22027c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_process_rej_msg: no statep with "
22037c478bd9Sstevel@tonic-gate 		    "local com id %x remote com id %x reason %d",
22047c478bd9Sstevel@tonic-gate 		    b2h32(rej_msg->rej_remote_comm_id),
22057c478bd9Sstevel@tonic-gate 		    b2h32(rej_msg->rej_local_comm_id),
22067c478bd9Sstevel@tonic-gate 		    b2h16(rej_msg->rej_rejection_reason));
22077c478bd9Sstevel@tonic-gate 
22087c478bd9Sstevel@tonic-gate 		/* Do NOT respond with invalid comid REJ */
22097c478bd9Sstevel@tonic-gate 		return;
22107c478bd9Sstevel@tonic-gate 	}
22117c478bd9Sstevel@tonic-gate 
22125974a6fcShiremath 	IBTF_DPRINTF_L2(cmlog, "ibcm_process_rej_msg: statep 0x%p INCOMING_REJ",
22139d3d2ed0Shiremath 	    statep);
22147c478bd9Sstevel@tonic-gate 	ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_REJ);
22157c478bd9Sstevel@tonic-gate 	if (ibcm_enable_trace & 2)
22167c478bd9Sstevel@tonic-gate 		ibcm_dump_conn_trace(statep);
22177c478bd9Sstevel@tonic-gate 
22187c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
22197c478bd9Sstevel@tonic-gate 
22207c478bd9Sstevel@tonic-gate 	rej_state = statep->state;
22217c478bd9Sstevel@tonic-gate 
22227c478bd9Sstevel@tonic-gate 	if ((statep->state == IBCM_STATE_REP_SENT) ||
22237c478bd9Sstevel@tonic-gate 	    (statep->state == IBCM_STATE_REQ_SENT) ||
22247c478bd9Sstevel@tonic-gate 	    (statep->state == IBCM_STATE_REP_WAIT) ||
22257c478bd9Sstevel@tonic-gate 	    (statep->state == IBCM_STATE_MRA_REP_RCVD)) {
22267c478bd9Sstevel@tonic-gate 		timeout_id_t	timer_val = statep->timerid;
22277c478bd9Sstevel@tonic-gate 
22287c478bd9Sstevel@tonic-gate 		statep->state = IBCM_STATE_DELETE;
22297c478bd9Sstevel@tonic-gate 
22307c478bd9Sstevel@tonic-gate 		/* cancel the REQ/REP timer */
22317c478bd9Sstevel@tonic-gate 		if (timer_val != 0) {
22327c478bd9Sstevel@tonic-gate 			statep->timerid = 0;
22337c478bd9Sstevel@tonic-gate 			mutex_exit(&statep->state_mutex);
22347c478bd9Sstevel@tonic-gate 
22357c478bd9Sstevel@tonic-gate 			(void) untimeout(timer_val);
22367c478bd9Sstevel@tonic-gate 		} else {
22377c478bd9Sstevel@tonic-gate 			mutex_exit(&statep->state_mutex);
22387c478bd9Sstevel@tonic-gate 		}
22397c478bd9Sstevel@tonic-gate 
22407c478bd9Sstevel@tonic-gate 		/*
22417c478bd9Sstevel@tonic-gate 		 * Call the QP state transition processing function
22427c478bd9Sstevel@tonic-gate 		 * NOTE: Input MAD is the REJ received, there is no output MAD
22437c478bd9Sstevel@tonic-gate 		 */
22447c478bd9Sstevel@tonic-gate 		ibcm_cep_state_rej(statep, rej_msg, rej_state);
22457c478bd9Sstevel@tonic-gate 
22467c478bd9Sstevel@tonic-gate 		/* signal waiting CV - blocking in ibt_open_channel() */
22477c478bd9Sstevel@tonic-gate 		if (statep->open_return_data != NULL) {
22487c478bd9Sstevel@tonic-gate 			statep->open_return_data->rc_status =
22497c478bd9Sstevel@tonic-gate 			    b2h16(rej_msg->rej_rejection_reason);
22507c478bd9Sstevel@tonic-gate 
22517c478bd9Sstevel@tonic-gate 			if (statep->open_return_data->rc_priv_data_len > 0)
22527c478bd9Sstevel@tonic-gate 				bcopy(rej_msg->rej_private_data,
22537c478bd9Sstevel@tonic-gate 				    statep->open_return_data->rc_priv_data,
22547c478bd9Sstevel@tonic-gate 				    min(
22557c478bd9Sstevel@tonic-gate 				    statep->open_return_data->rc_priv_data_len,
22567c478bd9Sstevel@tonic-gate 				    IBT_REJ_PRIV_DATA_SZ));
22577c478bd9Sstevel@tonic-gate 			mutex_enter(&statep->state_mutex);
22587c478bd9Sstevel@tonic-gate 			statep->open_done = B_TRUE;
22597c478bd9Sstevel@tonic-gate 			cv_broadcast(&statep->block_client_cv);
22607c478bd9Sstevel@tonic-gate 		} else {
22617c478bd9Sstevel@tonic-gate 			mutex_enter(&statep->state_mutex);
22627c478bd9Sstevel@tonic-gate 		}
22637c478bd9Sstevel@tonic-gate 
22647c478bd9Sstevel@tonic-gate 		IBCM_REF_CNT_DECR(statep);
22657c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
22667c478bd9Sstevel@tonic-gate 
22677c478bd9Sstevel@tonic-gate 		/* Now delete the statep */
22687c478bd9Sstevel@tonic-gate 		ibcm_delete_state_data(statep);
22697c478bd9Sstevel@tonic-gate 
22707c478bd9Sstevel@tonic-gate 	} else if ((statep->state == IBCM_STATE_ESTABLISHED) &&
22717c478bd9Sstevel@tonic-gate 	    (statep->mode == IBCM_ACTIVE_MODE)) {
22727c478bd9Sstevel@tonic-gate 
2273fde3102fShiremath 		IBTF_DPRINTF_L4(cmlog, "ibcm_process_rej_msg: statep 0x%p "
22747c478bd9Sstevel@tonic-gate 		    "REJ in established state", statep);
22757c478bd9Sstevel@tonic-gate 
22767c478bd9Sstevel@tonic-gate 		statep->state = IBCM_STATE_TIMEWAIT;
22777c478bd9Sstevel@tonic-gate 
22787c478bd9Sstevel@tonic-gate 		/* wait for/cancel pending LAP/APR, release state mutex */
22797c478bd9Sstevel@tonic-gate 		ibcm_sync_lapr_idle(statep);
22807c478bd9Sstevel@tonic-gate 
22817c478bd9Sstevel@tonic-gate 		/* wait until client is informed CONN EST event */
22827c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
22837c478bd9Sstevel@tonic-gate 		while (statep->cep_in_rts == IBCM_BLOCK)
22847c478bd9Sstevel@tonic-gate 			cv_wait(&statep->block_mad_cv, &statep->state_mutex);
22857c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
22867c478bd9Sstevel@tonic-gate 
22877c478bd9Sstevel@tonic-gate 		/*
22887c478bd9Sstevel@tonic-gate 		 * Call the QP state transition processing function
22897c478bd9Sstevel@tonic-gate 		 * NOTE: Input MAD is the REJ received, there is no output MAD
22907c478bd9Sstevel@tonic-gate 		 */
22917c478bd9Sstevel@tonic-gate 		ibcm_cep_state_rej_est(statep);
22927c478bd9Sstevel@tonic-gate 
22937c478bd9Sstevel@tonic-gate 		/*
22947c478bd9Sstevel@tonic-gate 		 * Start the timewait state timer, as connection is in
22957c478bd9Sstevel@tonic-gate 		 * established state
22967c478bd9Sstevel@tonic-gate 		 */
22977c478bd9Sstevel@tonic-gate 
22987c478bd9Sstevel@tonic-gate 		/*
22997c478bd9Sstevel@tonic-gate 		 * For passive side CM set it to remote_ack_delay
23007c478bd9Sstevel@tonic-gate 		 * For active side CM add the pkt_life_time * 2
23017c478bd9Sstevel@tonic-gate 		 */
23027c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
23037c478bd9Sstevel@tonic-gate 		statep->timer_value = statep->remote_ack_delay;
23047c478bd9Sstevel@tonic-gate 		/* statep->mode == IBCM_ACTIVE_MODE) */
23057c478bd9Sstevel@tonic-gate 		statep->timer_value += (2 * statep->pkt_life_time);
23067c478bd9Sstevel@tonic-gate 
23077c478bd9Sstevel@tonic-gate 		statep->remaining_retry_cnt = 0;
23087c478bd9Sstevel@tonic-gate 		statep->timer_stored_state = statep->state;
23097c478bd9Sstevel@tonic-gate 
23107c478bd9Sstevel@tonic-gate 		statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
23117c478bd9Sstevel@tonic-gate 
23127c478bd9Sstevel@tonic-gate 		IBCM_REF_CNT_DECR(statep);
23137c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
23147c478bd9Sstevel@tonic-gate 
23157c478bd9Sstevel@tonic-gate 	} else if (((statep->state == IBCM_STATE_REQ_RCVD) ||
23167c478bd9Sstevel@tonic-gate 	    (statep->state == IBCM_STATE_REP_RCVD) ||
23177c478bd9Sstevel@tonic-gate 	    (statep->state == IBCM_STATE_MRA_SENT) ||
23187c478bd9Sstevel@tonic-gate 	    (statep->state == IBCM_STATE_MRA_REP_SENT)) &&
23197c478bd9Sstevel@tonic-gate 	    (b2h16(rej_msg->rej_rejection_reason) == IBT_CM_TIMEOUT)) {
23207c478bd9Sstevel@tonic-gate 
23217c478bd9Sstevel@tonic-gate 		if (statep->abort_flag == IBCM_ABORT_INIT)
23227c478bd9Sstevel@tonic-gate 			statep->abort_flag = IBCM_ABORT_REJ;
23237c478bd9Sstevel@tonic-gate 
23247c478bd9Sstevel@tonic-gate 		IBCM_REF_CNT_DECR(statep);
23257c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
23267c478bd9Sstevel@tonic-gate 	} else {
23277c478bd9Sstevel@tonic-gate 
23287c478bd9Sstevel@tonic-gate #ifdef DEBUG
23297c478bd9Sstevel@tonic-gate 		if ((ibcm_test_mode > 0) &&
23307c478bd9Sstevel@tonic-gate 		    (statep->state != IBCM_STATE_DELETE))
23317c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_rej_msg: "
23327c478bd9Sstevel@tonic-gate 			    "Unexpected rej for statep 0x%p in state %d",
23337c478bd9Sstevel@tonic-gate 			    statep, statep->state);
23347c478bd9Sstevel@tonic-gate #endif
23357c478bd9Sstevel@tonic-gate 		IBCM_REF_CNT_DECR(statep);
23367c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
23377c478bd9Sstevel@tonic-gate 	}
23387c478bd9Sstevel@tonic-gate }
23397c478bd9Sstevel@tonic-gate 
23407c478bd9Sstevel@tonic-gate 
23417c478bd9Sstevel@tonic-gate /*
23427c478bd9Sstevel@tonic-gate  * ibcm_process_dreq_msg:
23437c478bd9Sstevel@tonic-gate  *	Processes incoming DREQ message on active/passive side
23447c478bd9Sstevel@tonic-gate  *
23457c478bd9Sstevel@tonic-gate  * INPUTS:
23467c478bd9Sstevel@tonic-gate  *	hcap		- HCA entry pointer
23477c478bd9Sstevel@tonic-gate  *	input_madp	- CM MAD that is input to this function
23487c478bd9Sstevel@tonic-gate  *	cm_mad_addr	- Address information for the MAD
23497c478bd9Sstevel@tonic-gate  *
23507c478bd9Sstevel@tonic-gate  * RETURN VALUE:	NONE
23517c478bd9Sstevel@tonic-gate  */
23527c478bd9Sstevel@tonic-gate /*ARGSUSED*/
23537c478bd9Sstevel@tonic-gate void
ibcm_process_dreq_msg(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)23547c478bd9Sstevel@tonic-gate ibcm_process_dreq_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
23557c478bd9Sstevel@tonic-gate     ibcm_mad_addr_t *cm_mad_addr)
23567c478bd9Sstevel@tonic-gate {
23577c478bd9Sstevel@tonic-gate 	void			*priv_data = NULL;
23587c478bd9Sstevel@tonic-gate 	ibcm_status_t		state_lookup_status;
23597c478bd9Sstevel@tonic-gate 	ib_qpn_t		local_qpn;
2360015f8fffShiremath 	ibcm_dreq_msg_t		*dreq_msgp =
2361015f8fffShiremath 	    (ibcm_dreq_msg_t *)(&input_madp[IBCM_MAD_HDR_SIZE]);
23627c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep = NULL;
23637c478bd9Sstevel@tonic-gate 	uint8_t			close_event_type;
23647c478bd9Sstevel@tonic-gate 	ibt_cm_status_t		cb_status;
23657c478bd9Sstevel@tonic-gate 
23667c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_dreq_msg:");
23677c478bd9Sstevel@tonic-gate 
23687c478bd9Sstevel@tonic-gate 	/* Lookup for an existing state structure */
23697c478bd9Sstevel@tonic-gate 	rw_enter(&hcap->hca_state_rwlock, RW_READER);
23707c478bd9Sstevel@tonic-gate 
23717c478bd9Sstevel@tonic-gate 	state_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_DREQ,
23727c478bd9Sstevel@tonic-gate 	    b2h32(dreq_msgp->dreq_remote_comm_id), 0, 0, hcap, &statep);
23737c478bd9Sstevel@tonic-gate 	rw_exit(&hcap->hca_state_rwlock);
23747c478bd9Sstevel@tonic-gate 
23757c478bd9Sstevel@tonic-gate 	local_qpn = b2h32(dreq_msgp->dreq_remote_qpn_eecn_plus) >> 8;
23767c478bd9Sstevel@tonic-gate 
23777c478bd9Sstevel@tonic-gate 	if (state_lookup_status != IBCM_LOOKUP_EXISTS) {
2378fde3102fShiremath 		IBTF_DPRINTF_L3(cmlog, "ibcm_process_dreq_msg: no statep with"
23797c478bd9Sstevel@tonic-gate 		    "com id %x", b2h32(dreq_msgp->dreq_remote_comm_id));
23807c478bd9Sstevel@tonic-gate 		/* implies a bogus message */
23817c478bd9Sstevel@tonic-gate 		return;
23827c478bd9Sstevel@tonic-gate 	}
23837c478bd9Sstevel@tonic-gate 
23847c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_dreq_msg: statep 0x%p "
23857c478bd9Sstevel@tonic-gate 	    "lookup status %x dreq qpn = %x", statep, state_lookup_status,
23867c478bd9Sstevel@tonic-gate 	    local_qpn);
23877c478bd9Sstevel@tonic-gate 
23887c478bd9Sstevel@tonic-gate 	/*
23897c478bd9Sstevel@tonic-gate 	 * Local QPN check is necessary. There could be a DREQ from
23907c478bd9Sstevel@tonic-gate 	 * a remote stale connection processing with the same com id, but
23917c478bd9Sstevel@tonic-gate 	 * not intended for this statep
23927c478bd9Sstevel@tonic-gate 	 */
2393fde3102fShiremath 	mutex_enter(&statep->state_mutex);
23947c478bd9Sstevel@tonic-gate 	if ((statep->local_qpn != local_qpn) ||
23957c478bd9Sstevel@tonic-gate 	    (statep->remote_comid != b2h32(dreq_msgp->dreq_local_comm_id))) {
23967c478bd9Sstevel@tonic-gate 
23977c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L3(cmlog, "ibcm_process_dreq_msg:"
23987c478bd9Sstevel@tonic-gate 		    "statep->local_qpn = %x qpn in dreq = %x"
23997c478bd9Sstevel@tonic-gate 		    "statep->remote_comid = %x local comid in dreq = %x",
24007c478bd9Sstevel@tonic-gate 		    statep->local_qpn, local_qpn, statep->remote_comid,
24017c478bd9Sstevel@tonic-gate 		    b2h32(dreq_msgp->dreq_local_comm_id));
24027c478bd9Sstevel@tonic-gate 
24037c478bd9Sstevel@tonic-gate 		IBCM_REF_CNT_DECR(statep);
24047c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
24057c478bd9Sstevel@tonic-gate 		return;
24067c478bd9Sstevel@tonic-gate 	}
2407fde3102fShiremath 	/*
2408fde3102fShiremath 	 * If another thread is processing a copy of this same DREQ,
2409fde3102fShiremath 	 * bail out here.
2410fde3102fShiremath 	 */
24119d3d2ed0Shiremath 	if (statep->state == IBCM_STATE_TRANSIENT_DREQ_SENT ||
24129d3d2ed0Shiremath 	    statep->drep_in_progress) {
2413fde3102fShiremath 		IBCM_REF_CNT_DECR(statep);
2414fde3102fShiremath 		mutex_exit(&statep->state_mutex);
2415fde3102fShiremath 		return;
2416fde3102fShiremath 	}
2417fde3102fShiremath 	switch (statep->state) {
2418fde3102fShiremath 	case IBCM_STATE_ESTABLISHED:
2419fde3102fShiremath 	case IBCM_STATE_DREQ_SENT:
2420fde3102fShiremath 	case IBCM_STATE_TIMEWAIT:
2421fde3102fShiremath 		break;
2422fde3102fShiremath 	default:
2423fde3102fShiremath 		/* All other states ignore DREQ */
2424fde3102fShiremath 		IBCM_REF_CNT_DECR(statep);
2425fde3102fShiremath 		mutex_exit(&statep->state_mutex);
2426fde3102fShiremath 		return;
2427fde3102fShiremath 	}
2428fde3102fShiremath 	statep->drep_in_progress = 1;
24297c478bd9Sstevel@tonic-gate 
24307c478bd9Sstevel@tonic-gate 	/*
24317c478bd9Sstevel@tonic-gate 	 * If drep msg wasn't really required, it shall be deleted finally
24327c478bd9Sstevel@tonic-gate 	 * when statep goes away
24337c478bd9Sstevel@tonic-gate 	 */
24347c478bd9Sstevel@tonic-gate 	if (statep->drep_msg == NULL) {
2435fde3102fShiremath 		mutex_exit(&statep->state_mutex);
24367c478bd9Sstevel@tonic-gate 		if (ibcm_alloc_out_msg(statep->stored_reply_addr.ibmf_hdl,
24377c478bd9Sstevel@tonic-gate 		    &statep->drep_msg, MAD_METHOD_SEND) != IBT_SUCCESS) {
24387c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_dreq_msg: "
24397c478bd9Sstevel@tonic-gate 			    "statep 0x%p ibcm_alloc_out_msg failed", statep);
24407c478bd9Sstevel@tonic-gate 			mutex_enter(&statep->state_mutex);
2441fde3102fShiremath 			statep->drep_in_progress = 0;
24427c478bd9Sstevel@tonic-gate 			IBCM_REF_CNT_DECR(statep);
24437c478bd9Sstevel@tonic-gate 			mutex_exit(&statep->state_mutex);
24447c478bd9Sstevel@tonic-gate 			return;
24457c478bd9Sstevel@tonic-gate 		}
2446fde3102fShiremath 		mutex_enter(&statep->state_mutex);
24477c478bd9Sstevel@tonic-gate 	}
24487c478bd9Sstevel@tonic-gate 
24499d3d2ed0Shiremath 	if (statep->state == IBCM_STATE_TRANSIENT_DREQ_SENT) {
24509d3d2ed0Shiremath 		IBCM_REF_CNT_DECR(statep);
24519d3d2ed0Shiremath 		statep->drep_in_progress = 0;
24529d3d2ed0Shiremath 		mutex_exit(&statep->state_mutex);
24539d3d2ed0Shiremath 		return;
24549d3d2ed0Shiremath 	}
24557c478bd9Sstevel@tonic-gate 
24567c478bd9Sstevel@tonic-gate 	/*
24577c478bd9Sstevel@tonic-gate 	 * Need to generate drep, as time wait can be reached either by an
24587c478bd9Sstevel@tonic-gate 	 * outgoing dreq or an incoming dreq
24597c478bd9Sstevel@tonic-gate 	 */
24607c478bd9Sstevel@tonic-gate 	if ((statep->state == IBCM_STATE_ESTABLISHED) ||
24617c478bd9Sstevel@tonic-gate 	    (statep->state == IBCM_STATE_DREQ_SENT)) {
24627c478bd9Sstevel@tonic-gate 		timeout_id_t	timer_val = statep->timerid;
24637c478bd9Sstevel@tonic-gate 
24647c478bd9Sstevel@tonic-gate 		if (statep->state == IBCM_STATE_DREQ_SENT) {
24657c478bd9Sstevel@tonic-gate 			statep->state = IBCM_STATE_DREQ_RCVD;
24667c478bd9Sstevel@tonic-gate 			statep->timerid = 0;
24679d3d2ed0Shiremath 			ibcm_close_done(statep, 0);
24687c478bd9Sstevel@tonic-gate 			mutex_exit(&statep->state_mutex);
24697c478bd9Sstevel@tonic-gate 
24707c478bd9Sstevel@tonic-gate 			close_event_type = IBT_CM_CLOSED_DUP;
24717c478bd9Sstevel@tonic-gate 			if (timer_val != 0) {
24727c478bd9Sstevel@tonic-gate 				/* Cancel the timer set for DREP reception */
24737c478bd9Sstevel@tonic-gate 				(void) untimeout(timer_val);
24747c478bd9Sstevel@tonic-gate 			}
24757c478bd9Sstevel@tonic-gate 		} else {	/* In ESTABLISHED State */
24769c468ea9SPramod Gunjikar 			boolean_t	is_ofuv = statep->is_this_ofuv_chan;
24779c468ea9SPramod Gunjikar 
24787c478bd9Sstevel@tonic-gate 			statep->state = IBCM_STATE_DREQ_RCVD;
24797c478bd9Sstevel@tonic-gate 			statep->clnt_proceed = IBCM_BLOCK;
24807c478bd9Sstevel@tonic-gate 
24817c478bd9Sstevel@tonic-gate 			/* Cancel or wait for LAP/APR to complete */
24827c478bd9Sstevel@tonic-gate 			ibcm_sync_lapr_idle(statep);
24837c478bd9Sstevel@tonic-gate 			/* The above function releases the state mutex */
24847c478bd9Sstevel@tonic-gate 
24857c478bd9Sstevel@tonic-gate 			/* wait until client knows CONN EST event */
24867c478bd9Sstevel@tonic-gate 			mutex_enter(&statep->state_mutex);
24877c478bd9Sstevel@tonic-gate 			while (statep->cep_in_rts == IBCM_BLOCK)
24887c478bd9Sstevel@tonic-gate 				cv_wait(&statep->block_mad_cv,
24897c478bd9Sstevel@tonic-gate 				    &statep->state_mutex);
24907c478bd9Sstevel@tonic-gate 			mutex_exit(&statep->state_mutex);
24917c478bd9Sstevel@tonic-gate 
24927c478bd9Sstevel@tonic-gate 			close_event_type = IBT_CM_CLOSED_DREQ_RCVD;
24937c478bd9Sstevel@tonic-gate 			/* Move CEP to error state */
24949c468ea9SPramod Gunjikar 			if (is_ofuv == B_FALSE) /* Skip for OFUV channel */
24959c468ea9SPramod Gunjikar 				(void) ibcm_cep_to_error_state(statep);
24967c478bd9Sstevel@tonic-gate 		}
2497fde3102fShiremath 		mutex_enter(&statep->state_mutex);
2498fde3102fShiremath 		statep->drep_in_progress = 0;
24997c478bd9Sstevel@tonic-gate 
25007c478bd9Sstevel@tonic-gate 		IBCM_OUT_HDRP(statep->drep_msg)->TransactionID =
25017c478bd9Sstevel@tonic-gate 		    ((ib_mad_hdr_t *)(input_madp))->TransactionID;
25027c478bd9Sstevel@tonic-gate 
25037c478bd9Sstevel@tonic-gate 		priv_data = &(((ibcm_drep_msg_t *)
25047c478bd9Sstevel@tonic-gate 		    IBCM_OUT_MSGP(statep->drep_msg))->drep_private_data[0]);
25057c478bd9Sstevel@tonic-gate 
25067c478bd9Sstevel@tonic-gate 		if (statep->close_ret_status)
25077c478bd9Sstevel@tonic-gate 			*statep->close_ret_status = close_event_type;
25087c478bd9Sstevel@tonic-gate 
25097c478bd9Sstevel@tonic-gate 		if (statep->close_nocb_state != IBCM_FAIL) {
25107c478bd9Sstevel@tonic-gate 			ibtl_cm_chan_is_closing(statep->channel);
25117c478bd9Sstevel@tonic-gate 			statep->close_nocb_state = IBCM_BLOCK;
25127c478bd9Sstevel@tonic-gate 		}
25137c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
25147c478bd9Sstevel@tonic-gate 
25157c478bd9Sstevel@tonic-gate 		/*
25167c478bd9Sstevel@tonic-gate 		 * if close_nocb_state is IBCM_FAIL, then cm_handler is NULL
25177c478bd9Sstevel@tonic-gate 		 * if close_nocb_state is IBCM_BLOCK, client cannot go away
25187c478bd9Sstevel@tonic-gate 		 */
25197c478bd9Sstevel@tonic-gate 		if (statep->cm_handler != NULL) {
25207c478bd9Sstevel@tonic-gate 			ibt_cm_event_t		event;
25217c478bd9Sstevel@tonic-gate 			ibt_cm_return_args_t	ret_args;
25227c478bd9Sstevel@tonic-gate 
25237c478bd9Sstevel@tonic-gate 			bzero(&event, sizeof (event));
25247c478bd9Sstevel@tonic-gate 			bzero(&ret_args, sizeof (ret_args));
25257c478bd9Sstevel@tonic-gate 
25267c478bd9Sstevel@tonic-gate 			event.cm_type = IBT_CM_EVENT_CONN_CLOSED;
25277c478bd9Sstevel@tonic-gate 			event.cm_channel = statep->channel;
25287c478bd9Sstevel@tonic-gate 			event.cm_session_id = statep;
25297c478bd9Sstevel@tonic-gate 			event.cm_priv_data = dreq_msgp->dreq_private_data;
25307c478bd9Sstevel@tonic-gate 			event.cm_priv_data_len = IBT_DREQ_PRIV_DATA_SZ;
25317c478bd9Sstevel@tonic-gate 			event.cm_event.closed = close_event_type;
25327c478bd9Sstevel@tonic-gate 
25337c478bd9Sstevel@tonic-gate 			ibcm_insert_trace(statep,
25347c478bd9Sstevel@tonic-gate 			    IBCM_TRACE_CALLED_CONN_CLOSE_EVENT);
25357c478bd9Sstevel@tonic-gate 
25367c478bd9Sstevel@tonic-gate 			cb_status = statep->cm_handler(statep->state_cm_private,
25377c478bd9Sstevel@tonic-gate 			    &event, &ret_args, priv_data,
25387c478bd9Sstevel@tonic-gate 			    IBT_DREP_PRIV_DATA_SZ);
25397c478bd9Sstevel@tonic-gate 
25407c478bd9Sstevel@tonic-gate 			ibcm_insert_trace(statep,
25417c478bd9Sstevel@tonic-gate 			    IBCM_TRACE_RET_CONN_CLOSE_EVENT);
25427c478bd9Sstevel@tonic-gate 
25437c478bd9Sstevel@tonic-gate 			if (cb_status == IBT_CM_DEFER) {
25447c478bd9Sstevel@tonic-gate 				mutex_enter(&statep->state_mutex);
25457c478bd9Sstevel@tonic-gate 				statep->clnt_proceed =
25467c478bd9Sstevel@tonic-gate 				    IBCM_UNBLOCK;
25477c478bd9Sstevel@tonic-gate 				cv_broadcast(&statep->block_client_cv);
25487c478bd9Sstevel@tonic-gate 				mutex_exit(&statep->state_mutex);
25497c478bd9Sstevel@tonic-gate 
25507c478bd9Sstevel@tonic-gate 				IBTF_DPRINTF_L4(cmlog, "ibcm_process_dreq_msg:"
25517c478bd9Sstevel@tonic-gate 				    " statep 0x%p client returned DEFER "
25527c478bd9Sstevel@tonic-gate 				    "response", statep);
25537c478bd9Sstevel@tonic-gate 				return;
25547c478bd9Sstevel@tonic-gate 			}
25557c478bd9Sstevel@tonic-gate 		}
25567c478bd9Sstevel@tonic-gate 
25577c478bd9Sstevel@tonic-gate 		/* fail/resume any blocked cm api call */
25587c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
25597c478bd9Sstevel@tonic-gate 
25607c478bd9Sstevel@tonic-gate 		/* Signal for cm proceed api */
25617c478bd9Sstevel@tonic-gate 		statep->clnt_proceed = IBCM_FAIL;
25627c478bd9Sstevel@tonic-gate 
25637c478bd9Sstevel@tonic-gate 		/* Signal for close with no callbacks */
25647c478bd9Sstevel@tonic-gate 		statep->close_nocb_state = IBCM_FAIL;
25657c478bd9Sstevel@tonic-gate 
25667c478bd9Sstevel@tonic-gate 		/* Signal any waiting close channel thread */
25677c478bd9Sstevel@tonic-gate 		statep->close_done = B_TRUE;
25687c478bd9Sstevel@tonic-gate 
25697c478bd9Sstevel@tonic-gate 		cv_broadcast(&statep->block_client_cv);
25707c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
25717c478bd9Sstevel@tonic-gate 
25727c478bd9Sstevel@tonic-gate 		ibcm_handle_cep_dreq_response(statep, NULL, 0);
25737c478bd9Sstevel@tonic-gate 
25747c478bd9Sstevel@tonic-gate 	} else if (statep->state == IBCM_STATE_TIMEWAIT) {
2575fde3102fShiremath 		statep->drep_in_progress = 0;
25767c478bd9Sstevel@tonic-gate 		if (statep->send_mad_flags & IBCM_DREP_POST_BUSY) {
25777c478bd9Sstevel@tonic-gate 			IBCM_REF_CNT_DECR(statep);
25787c478bd9Sstevel@tonic-gate 			mutex_exit(&statep->state_mutex);
25797c478bd9Sstevel@tonic-gate 			return;
25807c478bd9Sstevel@tonic-gate 		}
25817c478bd9Sstevel@tonic-gate 		statep->send_mad_flags |= IBCM_DREP_POST_BUSY;
25827c478bd9Sstevel@tonic-gate 
25837c478bd9Sstevel@tonic-gate 		/* Release statep mutex before posting the MAD */
25847c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
25857c478bd9Sstevel@tonic-gate 
25867c478bd9Sstevel@tonic-gate 		IBCM_OUT_HDRP(statep->drep_msg)->TransactionID =
25877c478bd9Sstevel@tonic-gate 		    ((ib_mad_hdr_t *)(input_madp))->TransactionID;
25887c478bd9Sstevel@tonic-gate 
25897c478bd9Sstevel@tonic-gate 		ibcm_post_drep_mad(statep);
25907c478bd9Sstevel@tonic-gate 		/* ref cnt decremented in ibcm_post_drep_complete */
25917c478bd9Sstevel@tonic-gate 	} else {
25927c478bd9Sstevel@tonic-gate #ifdef DEBUG
25937c478bd9Sstevel@tonic-gate 		if ((ibcm_test_mode > 0) &&
25947c478bd9Sstevel@tonic-gate 		    (statep->state != IBCM_STATE_DELETE))
25957c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_dreq_msg: "
25967c478bd9Sstevel@tonic-gate 			    "Unexpected dreq for statep 0x%p in state %d",
25977c478bd9Sstevel@tonic-gate 			    statep, statep->state);
25987c478bd9Sstevel@tonic-gate #endif
25997c478bd9Sstevel@tonic-gate 		IBCM_REF_CNT_DECR(statep);
2600fde3102fShiremath 		statep->drep_in_progress = 0;
26017c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
26027c478bd9Sstevel@tonic-gate 	}
26037c478bd9Sstevel@tonic-gate }
26047c478bd9Sstevel@tonic-gate 
26057c478bd9Sstevel@tonic-gate /*
26067c478bd9Sstevel@tonic-gate  * ibcm_handle_cep_dreq_response:
26077c478bd9Sstevel@tonic-gate  *	Processes the response from client handler for an incoming DREQ.
26087c478bd9Sstevel@tonic-gate  *	The statep ref cnt is decremented before returning.
26097c478bd9Sstevel@tonic-gate  */
26107c478bd9Sstevel@tonic-gate void
ibcm_handle_cep_dreq_response(ibcm_state_data_t * statep,void * priv_data,ibt_priv_data_len_t priv_data_len)26117c478bd9Sstevel@tonic-gate ibcm_handle_cep_dreq_response(ibcm_state_data_t *statep, void *priv_data,
26127c478bd9Sstevel@tonic-gate     ibt_priv_data_len_t priv_data_len)
26137c478bd9Sstevel@tonic-gate {
26147c478bd9Sstevel@tonic-gate 	if ((priv_data != NULL) && (priv_data_len > 0))
26157c478bd9Sstevel@tonic-gate 		bcopy(priv_data,
26167c478bd9Sstevel@tonic-gate 		    &(((ibcm_drep_msg_t *)
26177c478bd9Sstevel@tonic-gate 		    IBCM_OUT_MSGP(statep->drep_msg))->drep_private_data[0]),
26187c478bd9Sstevel@tonic-gate 		    min(priv_data_len, IBT_DREP_PRIV_DATA_SZ));
26197c478bd9Sstevel@tonic-gate 
26207c478bd9Sstevel@tonic-gate 	ibcm_post_drep_mad(statep);
26217c478bd9Sstevel@tonic-gate }
26227c478bd9Sstevel@tonic-gate 
26237c478bd9Sstevel@tonic-gate 
26247c478bd9Sstevel@tonic-gate /*
26257c478bd9Sstevel@tonic-gate  * ibcm_post_dreq_mad:
26267c478bd9Sstevel@tonic-gate  *	Posts a DREQ MAD
26277c478bd9Sstevel@tonic-gate  * Post DREQ now for TIMEWAIT state and DREQ_RCVD
26287c478bd9Sstevel@tonic-gate  *
26297c478bd9Sstevel@tonic-gate  * INPUTS:
26307c478bd9Sstevel@tonic-gate  *	statep		- state pointer
26317c478bd9Sstevel@tonic-gate  *
26327c478bd9Sstevel@tonic-gate  * RETURN VALUE:
26337c478bd9Sstevel@tonic-gate  *	NONE
26347c478bd9Sstevel@tonic-gate  */
26357c478bd9Sstevel@tonic-gate void
ibcm_post_dreq_mad(void * vstatep)26367c478bd9Sstevel@tonic-gate ibcm_post_dreq_mad(void *vstatep)
26377c478bd9Sstevel@tonic-gate {
26387c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep = vstatep;
26397c478bd9Sstevel@tonic-gate 	ibcm_dreq_msg_t		*dreq_msgp;
26407c478bd9Sstevel@tonic-gate 
26417c478bd9Sstevel@tonic-gate 	ASSERT(statep->dreq_msg != NULL);
26427c478bd9Sstevel@tonic-gate 
26437c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*dreq_msgp))
26447c478bd9Sstevel@tonic-gate 
26457c478bd9Sstevel@tonic-gate 	/* Fill in the DREQ message */
26467c478bd9Sstevel@tonic-gate 	dreq_msgp = (ibcm_dreq_msg_t *)IBCM_OUT_MSGP(statep->dreq_msg);
26477c478bd9Sstevel@tonic-gate 	dreq_msgp->dreq_local_comm_id = h2b32(statep->local_comid);
26487c478bd9Sstevel@tonic-gate 	dreq_msgp->dreq_remote_comm_id = h2b32(statep->remote_comid);
26497c478bd9Sstevel@tonic-gate 	dreq_msgp->dreq_remote_qpn_eecn_plus = h2b32(statep->remote_qpn << 8);
26507c478bd9Sstevel@tonic-gate 
26517c478bd9Sstevel@tonic-gate 	IBCM_OUT_HDRP(statep->dreq_msg)->AttributeID =
26527c478bd9Sstevel@tonic-gate 	    h2b16(IBCM_INCOMING_DREQ + IBCM_ATTR_BASE_ID);
26537c478bd9Sstevel@tonic-gate 
26547c478bd9Sstevel@tonic-gate 	/* wait until client knows CONN EST event */
26557c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
26567c478bd9Sstevel@tonic-gate 	while (statep->cep_in_rts == IBCM_BLOCK)
26577c478bd9Sstevel@tonic-gate 		cv_wait(&statep->block_mad_cv, &statep->state_mutex);
26587c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
26597c478bd9Sstevel@tonic-gate 
26607c478bd9Sstevel@tonic-gate 	/* Transition QP/EEC state to ERROR state */
26617c478bd9Sstevel@tonic-gate 	(void) ibcm_cep_to_error_state(statep);
26627c478bd9Sstevel@tonic-gate 
26637c478bd9Sstevel@tonic-gate 	IBCM_OUT_HDRP(statep->dreq_msg)->TransactionID =
26647c478bd9Sstevel@tonic-gate 	    h2b64(ibcm_generate_tranid(IBCM_INCOMING_DREQ, statep->local_comid,
26657c478bd9Sstevel@tonic-gate 	    0));
26667c478bd9Sstevel@tonic-gate 
26677c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*dreq_msgp))
26687c478bd9Sstevel@tonic-gate 
26697c478bd9Sstevel@tonic-gate 	/* post the first DREQ via timeout callback */
26707c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
26717c478bd9Sstevel@tonic-gate 
26727c478bd9Sstevel@tonic-gate 	statep->state = IBCM_STATE_DREQ_SENT;
26737c478bd9Sstevel@tonic-gate 	cv_broadcast(&statep->block_mad_cv);
26747c478bd9Sstevel@tonic-gate 
26757c478bd9Sstevel@tonic-gate 	statep->timer_stored_state = statep->state;
26767c478bd9Sstevel@tonic-gate 	/* client cannot specify more than 16 retries */
2677fde3102fShiremath 	statep->timer_value = statep->remote_ack_delay;
2678fde3102fShiremath 	if (statep->mode == IBCM_ACTIVE_MODE) {
2679fde3102fShiremath 		statep->timer_value += (2 * statep->pkt_life_time);
2680fde3102fShiremath 	}
26817c478bd9Sstevel@tonic-gate 	statep->remaining_retry_cnt = statep->max_cm_retries + 1;
26827c478bd9Sstevel@tonic-gate 	statep->timerid = IBCM_TIMEOUT(statep, 0);
26837c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
26847c478bd9Sstevel@tonic-gate }
26857c478bd9Sstevel@tonic-gate 
26867c478bd9Sstevel@tonic-gate /*
26877c478bd9Sstevel@tonic-gate  * ibcm_post_drep_mad:
26887c478bd9Sstevel@tonic-gate  *	Posts a DREP MAD
26897c478bd9Sstevel@tonic-gate  * Post DREP now for TIMEWAIT state and DREQ_RCVD
26907c478bd9Sstevel@tonic-gate  *
26917c478bd9Sstevel@tonic-gate  * INPUTS:
26927c478bd9Sstevel@tonic-gate  *	statep		- state pointer
26937c478bd9Sstevel@tonic-gate  *
26947c478bd9Sstevel@tonic-gate  * RETURN VALUE:
26957c478bd9Sstevel@tonic-gate  *	NONE
26967c478bd9Sstevel@tonic-gate  */
26977c478bd9Sstevel@tonic-gate static void
ibcm_post_drep_mad(ibcm_state_data_t * statep)26987c478bd9Sstevel@tonic-gate ibcm_post_drep_mad(ibcm_state_data_t *statep)
26997c478bd9Sstevel@tonic-gate {
27007c478bd9Sstevel@tonic-gate 	ibcm_drep_msg_t	*drep_msgp;
27017c478bd9Sstevel@tonic-gate 
27027c478bd9Sstevel@tonic-gate 	drep_msgp = (ibcm_drep_msg_t *)IBCM_OUT_MSGP(statep->drep_msg);
27037c478bd9Sstevel@tonic-gate 
27047c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*drep_msgp))
27057c478bd9Sstevel@tonic-gate 
2706fde3102fShiremath 	IBTF_DPRINTF_L4(cmlog, "ibcm_post_drep_mad:");
27077c478bd9Sstevel@tonic-gate 
27087c478bd9Sstevel@tonic-gate 	/* Fill up DREP fields */
27097c478bd9Sstevel@tonic-gate 	drep_msgp->drep_local_comm_id = h2b32(statep->local_comid);
27107c478bd9Sstevel@tonic-gate 	drep_msgp->drep_remote_comm_id = h2b32(statep->remote_comid);
27117c478bd9Sstevel@tonic-gate 	IBCM_OUT_HDRP(statep->drep_msg)->AttributeID =
27127c478bd9Sstevel@tonic-gate 	    h2b16(IBCM_INCOMING_DREP + IBCM_ATTR_BASE_ID);
27137c478bd9Sstevel@tonic-gate 
27147c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*drep_msgp))
27157c478bd9Sstevel@tonic-gate 
27167c478bd9Sstevel@tonic-gate 	ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_DREP);
27177c478bd9Sstevel@tonic-gate 
27187c478bd9Sstevel@tonic-gate 	/* Post the DREP MAD now.  */
27197c478bd9Sstevel@tonic-gate 	ibcm_post_rc_mad(statep, statep->drep_msg, ibcm_post_drep_complete,
27207c478bd9Sstevel@tonic-gate 	    statep);
27217c478bd9Sstevel@tonic-gate }
27227c478bd9Sstevel@tonic-gate 
27237c478bd9Sstevel@tonic-gate /*
27247c478bd9Sstevel@tonic-gate  * ibcm_process_drep_msg:
27257c478bd9Sstevel@tonic-gate  *	Processes incoming DREP message on active/passive side
27267c478bd9Sstevel@tonic-gate  *
27277c478bd9Sstevel@tonic-gate  * INPUTS:
27287c478bd9Sstevel@tonic-gate  *	hcap		- HCA entry pointer
27297c478bd9Sstevel@tonic-gate  *	input_madp	- CM MAD that is input to this function
27307c478bd9Sstevel@tonic-gate  *	cm_mad_addr	- Address information for the MAD
27317c478bd9Sstevel@tonic-gate  *
27327c478bd9Sstevel@tonic-gate  * RETURN VALUE: NONE
27337c478bd9Sstevel@tonic-gate  */
27347c478bd9Sstevel@tonic-gate /* ARGSUSED */
27357c478bd9Sstevel@tonic-gate void
ibcm_process_drep_msg(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)27367c478bd9Sstevel@tonic-gate ibcm_process_drep_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
27377c478bd9Sstevel@tonic-gate     ibcm_mad_addr_t *cm_mad_addr)
27387c478bd9Sstevel@tonic-gate {
27397c478bd9Sstevel@tonic-gate 	ibcm_status_t		state_lookup_status;
2740015f8fffShiremath 	ibcm_drep_msg_t		*drep_msgp =
2741015f8fffShiremath 	    (ibcm_drep_msg_t *)(&input_madp[IBCM_MAD_HDR_SIZE]);
27427c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep = NULL;
27437c478bd9Sstevel@tonic-gate 
27447c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_drep_msg:");
27457c478bd9Sstevel@tonic-gate 
27467c478bd9Sstevel@tonic-gate 	/* Lookup for an existing state structure */
27477c478bd9Sstevel@tonic-gate 	rw_enter(&hcap->hca_state_rwlock, RW_READER);
27487c478bd9Sstevel@tonic-gate 
27497c478bd9Sstevel@tonic-gate 	state_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_DREP,
27507c478bd9Sstevel@tonic-gate 	    b2h32(drep_msgp->drep_remote_comm_id), 0, 0, hcap, &statep);
27517c478bd9Sstevel@tonic-gate 	rw_exit(&hcap->hca_state_rwlock);
27527c478bd9Sstevel@tonic-gate 
27537c478bd9Sstevel@tonic-gate 	if (state_lookup_status != IBCM_LOOKUP_EXISTS) {
27547c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L3(cmlog, "ibcm_process_drep_msg: no statep with"
27557c478bd9Sstevel@tonic-gate 		    "com id %x", b2h32(drep_msgp->drep_remote_comm_id));
27567c478bd9Sstevel@tonic-gate 		return;
27577c478bd9Sstevel@tonic-gate 	}
27587c478bd9Sstevel@tonic-gate 
27597c478bd9Sstevel@tonic-gate 	/* if transaction id is not as expected, drop the DREP mad */
27607c478bd9Sstevel@tonic-gate 	if (IBCM_OUT_HDRP(statep->dreq_msg)->TransactionID !=
27617c478bd9Sstevel@tonic-gate 	    ((ib_mad_hdr_t *)(input_madp))->TransactionID) {
27627c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
27637c478bd9Sstevel@tonic-gate 		IBCM_REF_CNT_DECR(statep);
27647c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
2765fde3102fShiremath 		IBTF_DPRINTF_L3(cmlog, "ibcm_process_drep_msg: statep 0x%p "
2766fde3102fShiremath 		    "DREP with tid expected 0x%llX tid found 0x%llX", statep,
27677c478bd9Sstevel@tonic-gate 		    b2h64(IBCM_OUT_HDRP(statep->dreq_msg)->TransactionID),
27687c478bd9Sstevel@tonic-gate 		    b2h64(((ib_mad_hdr_t *)(input_madp))->TransactionID));
27697c478bd9Sstevel@tonic-gate 		return;
27707c478bd9Sstevel@tonic-gate 	}
27717c478bd9Sstevel@tonic-gate 
27727c478bd9Sstevel@tonic-gate 	ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_DREP);
27737c478bd9Sstevel@tonic-gate 
27747c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
27757c478bd9Sstevel@tonic-gate 
27767c478bd9Sstevel@tonic-gate 	if (statep->state == IBCM_STATE_DREQ_SENT) {
27777c478bd9Sstevel@tonic-gate 		timeout_id_t	timer_val = statep->timerid;
27787c478bd9Sstevel@tonic-gate 
27797c478bd9Sstevel@tonic-gate 		statep->state = IBCM_STATE_DREP_RCVD;
27807c478bd9Sstevel@tonic-gate 
27817c478bd9Sstevel@tonic-gate 		statep->timerid = 0;
27827c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
27837c478bd9Sstevel@tonic-gate 		(void) untimeout(timer_val);
27847c478bd9Sstevel@tonic-gate 
27857c478bd9Sstevel@tonic-gate 		if (statep->stale == B_TRUE)
27867c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_drep_msg: "
27877c478bd9Sstevel@tonic-gate 			    "statep 0x%p Unexpected DREP received for a stale "
27887c478bd9Sstevel@tonic-gate 			    "DREQ sent", statep);
27897c478bd9Sstevel@tonic-gate 
27907c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
27917c478bd9Sstevel@tonic-gate 		/* allow free qp, if close channel with NOCALLBACKS didn't */
27927c478bd9Sstevel@tonic-gate 		if (statep->close_nocb_state != IBCM_FAIL) {
27937c478bd9Sstevel@tonic-gate 			ibtl_cm_chan_is_closing(statep->channel);
27947c478bd9Sstevel@tonic-gate 			statep->close_nocb_state = IBCM_BLOCK;
27957c478bd9Sstevel@tonic-gate 		}
27967c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
27977c478bd9Sstevel@tonic-gate 
27987c478bd9Sstevel@tonic-gate 		/* if close_nocb_state is IBCM_FAIL, then cm_handler is NULL */
27997c478bd9Sstevel@tonic-gate 		if (statep->cm_handler != NULL) {
28007c478bd9Sstevel@tonic-gate 			ibt_cm_event_t		event;
28017c478bd9Sstevel@tonic-gate 			ibt_cm_return_args_t	ret_args;
28027c478bd9Sstevel@tonic-gate 
28037c478bd9Sstevel@tonic-gate 			bzero(&event, sizeof (event));
28047c478bd9Sstevel@tonic-gate 			bzero(&ret_args, sizeof (ret_args));
28057c478bd9Sstevel@tonic-gate 
28067c478bd9Sstevel@tonic-gate 			event.cm_type = IBT_CM_EVENT_CONN_CLOSED;
28077c478bd9Sstevel@tonic-gate 			event.cm_channel = statep->channel;
28087c478bd9Sstevel@tonic-gate 			event.cm_session_id = NULL;
28097c478bd9Sstevel@tonic-gate 
28107c478bd9Sstevel@tonic-gate 			if (statep->stale == B_TRUE) {
28117c478bd9Sstevel@tonic-gate 				event.cm_event.closed = IBT_CM_CLOSED_STALE;
28127c478bd9Sstevel@tonic-gate 				event.cm_priv_data = NULL;
28137c478bd9Sstevel@tonic-gate 				event.cm_priv_data_len = 0;
28147c478bd9Sstevel@tonic-gate 			} else {
28157c478bd9Sstevel@tonic-gate 				event.cm_event.closed = IBT_CM_CLOSED_DREP_RCVD;
28167c478bd9Sstevel@tonic-gate 				event.cm_priv_data =
28177c478bd9Sstevel@tonic-gate 				    drep_msgp->drep_private_data;
28187c478bd9Sstevel@tonic-gate 				event.cm_priv_data_len = IBT_DREP_PRIV_DATA_SZ;
28197c478bd9Sstevel@tonic-gate 			}
28207c478bd9Sstevel@tonic-gate 
28217c478bd9Sstevel@tonic-gate 			ibcm_insert_trace(statep,
28227c478bd9Sstevel@tonic-gate 			    IBCM_TRACE_CALLED_CONN_CLOSE_EVENT);
28237c478bd9Sstevel@tonic-gate 
28247c478bd9Sstevel@tonic-gate 			(void) statep->cm_handler(statep->state_cm_private,
28257c478bd9Sstevel@tonic-gate 			    &event, &ret_args, NULL, 0);
28267c478bd9Sstevel@tonic-gate 
28277c478bd9Sstevel@tonic-gate 			ibcm_insert_trace(statep,
28287c478bd9Sstevel@tonic-gate 			    IBCM_TRACE_RET_CONN_CLOSE_EVENT);
28297c478bd9Sstevel@tonic-gate 		}
28307c478bd9Sstevel@tonic-gate 
28317c478bd9Sstevel@tonic-gate 		/* copy the private to close channel, if specified */
2832934f0bccShiremath 		if ((statep->close_ret_priv_data != NULL) &&
2833934f0bccShiremath 		    (statep->close_ret_priv_data_len != NULL) &&
2834934f0bccShiremath 		    (*statep->close_ret_priv_data_len > 0)) {
28357c478bd9Sstevel@tonic-gate 			bcopy(drep_msgp->drep_private_data,
2836934f0bccShiremath 			    statep->close_ret_priv_data,
2837934f0bccShiremath 			    min(*statep->close_ret_priv_data_len,
2838015f8fffShiremath 			    IBT_DREP_PRIV_DATA_SZ));
28397c478bd9Sstevel@tonic-gate 		}
28407c478bd9Sstevel@tonic-gate 
28417c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
28427c478bd9Sstevel@tonic-gate 		if (statep->close_ret_status)
28437c478bd9Sstevel@tonic-gate 			*statep->close_ret_status = IBT_CM_CLOSED_DREP_RCVD;
28447c478bd9Sstevel@tonic-gate 		/* signal waiting CV - blocking in ibt_close_channel() */
28457c478bd9Sstevel@tonic-gate 		statep->close_done = B_TRUE;
28467c478bd9Sstevel@tonic-gate 
28477c478bd9Sstevel@tonic-gate 		/* signal any blocked close channels with no callbacks */
28487c478bd9Sstevel@tonic-gate 		statep->close_nocb_state = IBCM_FAIL;
28497c478bd9Sstevel@tonic-gate 
28507c478bd9Sstevel@tonic-gate 		cv_broadcast(&statep->block_client_cv);
28517c478bd9Sstevel@tonic-gate 
28527c478bd9Sstevel@tonic-gate 		/* Set the timer wait state timer */
28537c478bd9Sstevel@tonic-gate 		statep->state = statep->timer_stored_state =
28547c478bd9Sstevel@tonic-gate 		    IBCM_STATE_TIMEWAIT;
28559d3d2ed0Shiremath 		ibcm_close_done(statep, 0);
28567c478bd9Sstevel@tonic-gate 
28577c478bd9Sstevel@tonic-gate 		statep->remaining_retry_cnt = 0;
28587c478bd9Sstevel@tonic-gate 		/*
28597c478bd9Sstevel@tonic-gate 		 * For passive side CM set it to remote_ack_delay
28607c478bd9Sstevel@tonic-gate 		 * For active side CM add the pkt_life_time * 2
28617c478bd9Sstevel@tonic-gate 		 */
28627c478bd9Sstevel@tonic-gate 		statep->timer_value = statep->remote_ack_delay;
28637c478bd9Sstevel@tonic-gate 		if (statep->mode == IBCM_ACTIVE_MODE) {
28647c478bd9Sstevel@tonic-gate 			statep->timer_value += (2 * statep->pkt_life_time);
28657c478bd9Sstevel@tonic-gate 		}
28667c478bd9Sstevel@tonic-gate 
28677c478bd9Sstevel@tonic-gate 		/* start TIMEWAIT processing */
28687c478bd9Sstevel@tonic-gate 		statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
28697c478bd9Sstevel@tonic-gate 	}
28707c478bd9Sstevel@tonic-gate 
28717c478bd9Sstevel@tonic-gate 	/* There is no processing required for other states */
28727c478bd9Sstevel@tonic-gate 	IBCM_REF_CNT_DECR(statep);
28737c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
28747c478bd9Sstevel@tonic-gate }
28757c478bd9Sstevel@tonic-gate 
28767c478bd9Sstevel@tonic-gate /*
28777c478bd9Sstevel@tonic-gate  * Following are the routines used to resend various CM MADs as a response to
28787c478bd9Sstevel@tonic-gate  * incoming MADs
28797c478bd9Sstevel@tonic-gate  */
28807c478bd9Sstevel@tonic-gate void
ibcm_resend_rtu_mad(ibcm_state_data_t * statep)28817c478bd9Sstevel@tonic-gate ibcm_resend_rtu_mad(ibcm_state_data_t *statep)
28827c478bd9Sstevel@tonic-gate {
28837c478bd9Sstevel@tonic-gate 	ASSERT(MUTEX_HELD(&statep->state_mutex));
28847c478bd9Sstevel@tonic-gate 
28857c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(cmlog, "ibcm_resend_rtu_mad statep %p ", statep);
28867c478bd9Sstevel@tonic-gate 
28877c478bd9Sstevel@tonic-gate 	/* don't care, if timer is running or not. Timer may be from LAP */
28887c478bd9Sstevel@tonic-gate 
28897c478bd9Sstevel@tonic-gate 	if (!(statep->send_mad_flags & IBCM_RTU_POST_BUSY)) {
28907c478bd9Sstevel@tonic-gate 		statep->send_mad_flags |= IBCM_RTU_POST_BUSY;
28917c478bd9Sstevel@tonic-gate 		IBCM_REF_CNT_INCR(statep);	/* for non-blocking RTU post */
28927c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
28937c478bd9Sstevel@tonic-gate 
28947c478bd9Sstevel@tonic-gate 		ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_RTU);
28957c478bd9Sstevel@tonic-gate 
28967c478bd9Sstevel@tonic-gate 		ibcm_post_rc_mad(statep, statep->stored_msg,
28977c478bd9Sstevel@tonic-gate 		    ibcm_post_rtu_complete, statep);
28987c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
28997c478bd9Sstevel@tonic-gate 	}
29007c478bd9Sstevel@tonic-gate 	/* ref cnt is decremented in ibcm_post_rtu_complete */
29017c478bd9Sstevel@tonic-gate }
29027c478bd9Sstevel@tonic-gate 
29037c478bd9Sstevel@tonic-gate void
ibcm_resend_rej_mad(ibcm_state_data_t * statep)29047c478bd9Sstevel@tonic-gate ibcm_resend_rej_mad(ibcm_state_data_t *statep)
29057c478bd9Sstevel@tonic-gate {
29067c478bd9Sstevel@tonic-gate 	timeout_id_t		timer_val = statep->timerid;
29077c478bd9Sstevel@tonic-gate 
29087c478bd9Sstevel@tonic-gate 	ASSERT(MUTEX_HELD(&statep->state_mutex));
29097c478bd9Sstevel@tonic-gate 
29107c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(cmlog, "ibcm_resend_rej_mad statep %p ", statep);
29117c478bd9Sstevel@tonic-gate 
29127c478bd9Sstevel@tonic-gate 	/* It's a too fast of a REQ or REP */
29137c478bd9Sstevel@tonic-gate 	if (timer_val == 0)
29147c478bd9Sstevel@tonic-gate 		return;
29157c478bd9Sstevel@tonic-gate 
29167c478bd9Sstevel@tonic-gate 	statep->timerid = 0;
29177c478bd9Sstevel@tonic-gate 	if (!(statep->send_mad_flags & IBCM_REJ_POST_BUSY)) {
29187c478bd9Sstevel@tonic-gate 		statep->send_mad_flags |= IBCM_REJ_POST_BUSY;
29197c478bd9Sstevel@tonic-gate 		IBCM_REF_CNT_INCR(statep);	/* for nonblocking REJ post */
29207c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
29217c478bd9Sstevel@tonic-gate 		(void) untimeout(timer_val);
29227c478bd9Sstevel@tonic-gate 
29237c478bd9Sstevel@tonic-gate 		ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_REJ);
29247c478bd9Sstevel@tonic-gate 		if (ibcm_enable_trace & 2)
29257c478bd9Sstevel@tonic-gate 			ibcm_dump_conn_trace(statep);
29265974a6fcShiremath 		else
29275974a6fcShiremath 			IBTF_DPRINTF_L2(cmlog, "ibcm_resend_rej_mad statep %p "
29285974a6fcShiremath 			    "OUTGOING_REJ", statep);
29297c478bd9Sstevel@tonic-gate 
29307c478bd9Sstevel@tonic-gate 		ibcm_post_rc_mad(statep, statep->stored_msg,
29317c478bd9Sstevel@tonic-gate 		    ibcm_post_rej_complete, statep);
29327c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
29337c478bd9Sstevel@tonic-gate 	}
29347c478bd9Sstevel@tonic-gate 	/* return, holding the state mutex */
29357c478bd9Sstevel@tonic-gate }
29367c478bd9Sstevel@tonic-gate 
29377c478bd9Sstevel@tonic-gate void
ibcm_resend_rep_mad(ibcm_state_data_t * statep)29387c478bd9Sstevel@tonic-gate ibcm_resend_rep_mad(ibcm_state_data_t *statep)
29397c478bd9Sstevel@tonic-gate {
29407c478bd9Sstevel@tonic-gate 	timeout_id_t		timer_val = statep->timerid;
29417c478bd9Sstevel@tonic-gate 
29427c478bd9Sstevel@tonic-gate 	ASSERT(MUTEX_HELD(&statep->state_mutex));
29437c478bd9Sstevel@tonic-gate 
29447c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(cmlog, "ibcm_resend_rep_mad statep %p ", statep);
29457c478bd9Sstevel@tonic-gate 
29467c478bd9Sstevel@tonic-gate 	/* REP timer that is set by ibcm_post_rep_mad */
29477c478bd9Sstevel@tonic-gate 	if (timer_val != 0) {
29487c478bd9Sstevel@tonic-gate 		/* Re-start REP timeout */
29497c478bd9Sstevel@tonic-gate 		statep->remaining_retry_cnt = statep->max_cm_retries;
29507c478bd9Sstevel@tonic-gate 		if (!(statep->send_mad_flags & IBCM_REP_POST_BUSY)) {
29517c478bd9Sstevel@tonic-gate 			statep->send_mad_flags |= IBCM_REP_POST_BUSY;
29527c478bd9Sstevel@tonic-gate 			/* for nonblocking REP post */
29537c478bd9Sstevel@tonic-gate 			IBCM_REF_CNT_INCR(statep);
29547c478bd9Sstevel@tonic-gate 			mutex_exit(&statep->state_mutex);
29557c478bd9Sstevel@tonic-gate 
29569d3d2ed0Shiremath 			ibcm_insert_trace(statep, IBCM_TRACE_OUT_REP_RETRY);
29577c478bd9Sstevel@tonic-gate 
29587c478bd9Sstevel@tonic-gate 			ibcm_post_rc_mad(statep, statep->stored_msg,
29597c478bd9Sstevel@tonic-gate 			    ibcm_resend_post_rep_complete, statep);
29607c478bd9Sstevel@tonic-gate 			mutex_enter(&statep->state_mutex);
29617c478bd9Sstevel@tonic-gate 		}
29627c478bd9Sstevel@tonic-gate 	}
29637c478bd9Sstevel@tonic-gate 
29647c478bd9Sstevel@tonic-gate 	/*
29657c478bd9Sstevel@tonic-gate 	 * else, timer is not yet set by ibcm_post_rep_mad. This is too fast
29667c478bd9Sstevel@tonic-gate 	 * of a REQ being re-transmitted.
29677c478bd9Sstevel@tonic-gate 	 */
29687c478bd9Sstevel@tonic-gate }
29697c478bd9Sstevel@tonic-gate 
29707c478bd9Sstevel@tonic-gate void
ibcm_resend_mra_mad(ibcm_state_data_t * statep)29717c478bd9Sstevel@tonic-gate ibcm_resend_mra_mad(ibcm_state_data_t *statep)
29727c478bd9Sstevel@tonic-gate {
29737c478bd9Sstevel@tonic-gate 	ASSERT(MUTEX_HELD(&statep->state_mutex));
29747c478bd9Sstevel@tonic-gate 
29757c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(cmlog, "ibcm_resend_mra_mad statep %p ", statep);
29767c478bd9Sstevel@tonic-gate 
29777c478bd9Sstevel@tonic-gate 	if (statep->send_mad_flags & IBCM_MRA_POST_BUSY)
29787c478bd9Sstevel@tonic-gate 		return;
29797c478bd9Sstevel@tonic-gate 
29807c478bd9Sstevel@tonic-gate 	statep->send_mad_flags |= IBCM_MRA_POST_BUSY;
29817c478bd9Sstevel@tonic-gate 
29829d3d2ed0Shiremath 	statep->mra_time = gethrtime();
2983*f248c5e0SToomas Soome 	IBCM_REF_CNT_INCR(statep);	/* for non-blocking MRA post */
29847c478bd9Sstevel@tonic-gate 	/* Exit the statep mutex, before sending the MAD */
29857c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
29867c478bd9Sstevel@tonic-gate 
29877c478bd9Sstevel@tonic-gate 	ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_MRA);
29887c478bd9Sstevel@tonic-gate 
29897c478bd9Sstevel@tonic-gate 	/* Always resend the response MAD to the original reply destination */
29907c478bd9Sstevel@tonic-gate 	ibcm_post_rc_mad(statep, statep->mra_msg, ibcm_post_mra_complete,
29917c478bd9Sstevel@tonic-gate 	    statep);
29927c478bd9Sstevel@tonic-gate 
29937c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
29947c478bd9Sstevel@tonic-gate 
29957c478bd9Sstevel@tonic-gate 	/* return, holding the state mutex */
29967c478bd9Sstevel@tonic-gate }
29977c478bd9Sstevel@tonic-gate 
29987c478bd9Sstevel@tonic-gate 
29997c478bd9Sstevel@tonic-gate /*
30007c478bd9Sstevel@tonic-gate  * ibcm_post_rej_mad:
30017c478bd9Sstevel@tonic-gate  *	Posts a REJ MAD and starts timer
30027c478bd9Sstevel@tonic-gate  *
30037c478bd9Sstevel@tonic-gate  * INPUTS:
30047c478bd9Sstevel@tonic-gate  *	statep		- state pointer
30057c478bd9Sstevel@tonic-gate  *	which_msg	- which message is being MRAed
30067c478bd9Sstevel@tonic-gate  *	reject_reason	- Rejection reason See Section 12.6.7.2 rev1.0a IB Spec
30077c478bd9Sstevel@tonic-gate  *	addl_rej_info	- Additional rej Information
30087c478bd9Sstevel@tonic-gate  *	arej_info_len	- Additional rej Info length
30097c478bd9Sstevel@tonic-gate  *
30107c478bd9Sstevel@tonic-gate  * RETURN VALUE:
30117c478bd9Sstevel@tonic-gate  *	NONE
30127c478bd9Sstevel@tonic-gate  * Notes
30137c478bd9Sstevel@tonic-gate  *  There is no need to hold the statep->mutex and call ibcm_post_rej_mad
30147c478bd9Sstevel@tonic-gate  *  REJ can be posted either in IBCM_STATE_REQ_RCVD or IBCM_STATE_REP_RCVD
30157c478bd9Sstevel@tonic-gate  *  In these states, there is no timer active, and an incoming REJ shall
30167c478bd9Sstevel@tonic-gate  *  not modify the state or cancel timers
30177c478bd9Sstevel@tonic-gate  *  An incoming REJ doesn't affect statep in state = IBCM_STATE_REJ_SENT/BUSY
30187c478bd9Sstevel@tonic-gate  */
30197c478bd9Sstevel@tonic-gate void
ibcm_post_rej_mad(ibcm_state_data_t * statep,ibt_cm_reason_t reject_reason,int which_msg,void * addl_rej_info,ibt_priv_data_len_t arej_info_len)30207c478bd9Sstevel@tonic-gate ibcm_post_rej_mad(ibcm_state_data_t *statep, ibt_cm_reason_t reject_reason,
30217c478bd9Sstevel@tonic-gate     int which_msg, void *addl_rej_info, ibt_priv_data_len_t arej_info_len)
30227c478bd9Sstevel@tonic-gate {
3023015f8fffShiremath 	ibcm_rej_msg_t	*rej_msg =
3024015f8fffShiremath 	    (ibcm_rej_msg_t *)IBCM_OUT_MSGP(statep->stored_msg);
30257c478bd9Sstevel@tonic-gate 
30267c478bd9Sstevel@tonic-gate 	/* Message printed if connection gets REJed */
30277c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(cmlog, "ibcm_post_rej_mad: "
302824b28d04Shiremath 	    "statep = %p, reject_reason = %d", statep, reject_reason);
30297c478bd9Sstevel@tonic-gate 
30307c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rej_msg))
30317c478bd9Sstevel@tonic-gate 
30327c478bd9Sstevel@tonic-gate 	/* Initialize rej_msg fields */
30337c478bd9Sstevel@tonic-gate 	rej_msg->rej_local_comm_id = h2b32(statep->local_comid);
30347c478bd9Sstevel@tonic-gate 	rej_msg->rej_remote_comm_id = h2b32(statep->remote_comid);
30357c478bd9Sstevel@tonic-gate 	rej_msg->rej_msg_type_plus = (which_msg & 0x3) << 6;
30367c478bd9Sstevel@tonic-gate 	rej_msg->rej_reject_info_len_plus = arej_info_len << 1;
30377c478bd9Sstevel@tonic-gate 	rej_msg->rej_rejection_reason = h2b16((uint16_t)reject_reason);
30387c478bd9Sstevel@tonic-gate 
30397c478bd9Sstevel@tonic-gate 	if ((arej_info_len != 0) && (addl_rej_info != NULL))
30407c478bd9Sstevel@tonic-gate 		bcopy(addl_rej_info, rej_msg->rej_addl_rej_info, arej_info_len);
30417c478bd9Sstevel@tonic-gate 
30427c478bd9Sstevel@tonic-gate 	IBCM_OUT_HDRP(statep->stored_msg)->AttributeID =
30437c478bd9Sstevel@tonic-gate 	    h2b16(IBCM_INCOMING_REJ + IBCM_ATTR_BASE_ID);
30447c478bd9Sstevel@tonic-gate 
30457c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rej_msg))
30467c478bd9Sstevel@tonic-gate 
30477c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
30487c478bd9Sstevel@tonic-gate 
30497c478bd9Sstevel@tonic-gate 	/* signal any waiting close channels with blocking or no callbacks  */
30507c478bd9Sstevel@tonic-gate 	statep->close_done = B_TRUE;
30517c478bd9Sstevel@tonic-gate 	statep->close_nocb_state = IBCM_FAIL;
30527c478bd9Sstevel@tonic-gate 
30537c478bd9Sstevel@tonic-gate 	cv_signal(&statep->block_client_cv);
30547c478bd9Sstevel@tonic-gate 
30557c478bd9Sstevel@tonic-gate 	statep->timer_stored_state = statep->state = IBCM_STATE_REJ_SENT;
30567c478bd9Sstevel@tonic-gate 	statep->send_mad_flags |= IBCM_REJ_POST_BUSY;
30577c478bd9Sstevel@tonic-gate 
30587c478bd9Sstevel@tonic-gate 	IBCM_REF_CNT_INCR(statep); /* for non-blocking post */
30597c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
30607c478bd9Sstevel@tonic-gate 
30617c478bd9Sstevel@tonic-gate 	ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_REJ);
30627c478bd9Sstevel@tonic-gate 	if (ibcm_enable_trace & 2)
30637c478bd9Sstevel@tonic-gate 		ibcm_dump_conn_trace(statep);
30645974a6fcShiremath 	else
30655974a6fcShiremath 		IBTF_DPRINTF_L2(cmlog, "ibcm_post_rej_mad statep %p "
30665974a6fcShiremath 		    "OUTGOING_REJ", statep);
30677c478bd9Sstevel@tonic-gate 
30687c478bd9Sstevel@tonic-gate 	ibcm_post_rc_mad(statep, statep->stored_msg, ibcm_post_rej_complete,
30697c478bd9Sstevel@tonic-gate 	    statep);
30707c478bd9Sstevel@tonic-gate }
30717c478bd9Sstevel@tonic-gate 
30727c478bd9Sstevel@tonic-gate 
30737c478bd9Sstevel@tonic-gate /*
30747c478bd9Sstevel@tonic-gate  * ibcm_build_n_post_rej_mad:
30757c478bd9Sstevel@tonic-gate  *	Builds and posts a REJ MAD for "reject_reason"
30767c478bd9Sstevel@tonic-gate  *	Doesn't set a timer, and doesn't need statep
30777c478bd9Sstevel@tonic-gate  *
30787c478bd9Sstevel@tonic-gate  * INPUTS:
30797c478bd9Sstevel@tonic-gate  *	input_madp	- Incoming MAD
30807c478bd9Sstevel@tonic-gate  *	remote_comid	- Local comid in the message being rejected
30817c478bd9Sstevel@tonic-gate  *	cm_mad_addr	- Address information for the MAD to be posted
30827c478bd9Sstevel@tonic-gate  *	which_msg	- REJ message type ie., REJ for REQ/REP
30837c478bd9Sstevel@tonic-gate  *
30847c478bd9Sstevel@tonic-gate  * RETURN VALUE:
30857c478bd9Sstevel@tonic-gate  *	NONE
30867c478bd9Sstevel@tonic-gate  */
30877c478bd9Sstevel@tonic-gate static void
ibcm_build_n_post_rej_mad(uint8_t * input_madp,ib_com_id_t remote_comid,ibcm_mad_addr_t * cm_mad_addr,int which_msg,uint16_t reject_reason)30887c478bd9Sstevel@tonic-gate ibcm_build_n_post_rej_mad(uint8_t *input_madp, ib_com_id_t remote_comid,
30897c478bd9Sstevel@tonic-gate     ibcm_mad_addr_t *cm_mad_addr, int which_msg, uint16_t reject_reason)
30907c478bd9Sstevel@tonic-gate {
30917c478bd9Sstevel@tonic-gate 	ibcm_rej_msg_t	*rej_msg;
30927c478bd9Sstevel@tonic-gate 	ibmf_msg_t	*cm_rej_msg;
30937c478bd9Sstevel@tonic-gate 	ibcm_mad_addr_t	rej_reply_addr;
30947c478bd9Sstevel@tonic-gate 
30957c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(cmlog, "ibcm_build_n_post_rej_mad: "
309624b28d04Shiremath 	    "remote_comid: %x reject_reason %d", remote_comid, reject_reason);
30977c478bd9Sstevel@tonic-gate 
30987c478bd9Sstevel@tonic-gate 	if (ibcm_alloc_out_msg(cm_mad_addr->ibmf_hdl, &cm_rej_msg,
30997c478bd9Sstevel@tonic-gate 	    MAD_METHOD_SEND) != IBT_SUCCESS) {
31007c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_build_n_post_rej_mad: "
31017c478bd9Sstevel@tonic-gate 		    "ibcm_alloc_out_msg failed");
31027c478bd9Sstevel@tonic-gate 		return;
31037c478bd9Sstevel@tonic-gate 	}
31047c478bd9Sstevel@tonic-gate 
31057c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rej_msg))
31067c478bd9Sstevel@tonic-gate 
31077c478bd9Sstevel@tonic-gate 	IBCM_OUT_HDRP(cm_rej_msg)->TransactionID =
31087c478bd9Sstevel@tonic-gate 	    ((ib_mad_hdr_t *)(input_madp))->TransactionID;
31097c478bd9Sstevel@tonic-gate 
31107c478bd9Sstevel@tonic-gate 	/* Initialize rej_msg fields */
31117c478bd9Sstevel@tonic-gate 	rej_msg = (ibcm_rej_msg_t *)IBCM_OUT_MSGP(cm_rej_msg);
31127c478bd9Sstevel@tonic-gate 	rej_msg->rej_local_comm_id = 0;
31137c478bd9Sstevel@tonic-gate 	rej_msg->rej_remote_comm_id = h2b32(remote_comid);
3114fde3102fShiremath 	rej_msg->rej_msg_type_plus = (which_msg & 0x3) << 6;
31157c478bd9Sstevel@tonic-gate 	rej_msg->rej_reject_info_len_plus = 0;
31167c478bd9Sstevel@tonic-gate 	rej_msg->rej_rejection_reason = h2b16(reject_reason);
31177c478bd9Sstevel@tonic-gate 
31187c478bd9Sstevel@tonic-gate 	IBCM_OUT_HDRP(cm_rej_msg)->AttributeID =
31197c478bd9Sstevel@tonic-gate 	    h2b16(IBCM_INCOMING_REJ + IBCM_ATTR_BASE_ID);
31207c478bd9Sstevel@tonic-gate 
31217c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rej_msg))
31227c478bd9Sstevel@tonic-gate 
31237c478bd9Sstevel@tonic-gate 	ibcm_build_reply_mad_addr(cm_mad_addr, &rej_reply_addr);
31247c478bd9Sstevel@tonic-gate 
31257c478bd9Sstevel@tonic-gate 	if (rej_reply_addr.cm_qp_entry != NULL) {
31267c478bd9Sstevel@tonic-gate 		(void) ibcm_post_mad(cm_rej_msg, &rej_reply_addr, NULL, NULL);
31277c478bd9Sstevel@tonic-gate 		ibcm_release_qp(rej_reply_addr.cm_qp_entry);
31287c478bd9Sstevel@tonic-gate 	}
31297c478bd9Sstevel@tonic-gate 
31307c478bd9Sstevel@tonic-gate 	(void) ibcm_free_out_msg(cm_mad_addr->ibmf_hdl, &cm_rej_msg);
31317c478bd9Sstevel@tonic-gate }
31327c478bd9Sstevel@tonic-gate 
31337c478bd9Sstevel@tonic-gate /* posts a REJ for an incoming REQ with unsupported class version */
31347c478bd9Sstevel@tonic-gate 
31357c478bd9Sstevel@tonic-gate static void
ibcm_post_rej_ver_mismatch(uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)31367c478bd9Sstevel@tonic-gate ibcm_post_rej_ver_mismatch(uint8_t *input_madp, ibcm_mad_addr_t *cm_mad_addr)
31377c478bd9Sstevel@tonic-gate {
3138015f8fffShiremath 	ibcm_req_msg_t	*req_msgp =
3139015f8fffShiremath 	    (ibcm_req_msg_t *)&input_madp[IBCM_MAD_HDR_SIZE];
31407c478bd9Sstevel@tonic-gate 	ibcm_rej_msg_t	*rej_msg;
31417c478bd9Sstevel@tonic-gate 	ibmf_msg_t	*cm_rej_msg;
31427c478bd9Sstevel@tonic-gate 	ibcm_mad_addr_t	rej_reply_addr;
31437c478bd9Sstevel@tonic-gate 
31447c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(cmlog, "ibcm_post_rej_ver_mismatch: remote comid %x",
31457c478bd9Sstevel@tonic-gate 	    b2h32(req_msgp->req_local_comm_id));
31467c478bd9Sstevel@tonic-gate 
31477c478bd9Sstevel@tonic-gate 	if (ibcm_alloc_out_msg(cm_mad_addr->ibmf_hdl, &cm_rej_msg,
31487c478bd9Sstevel@tonic-gate 	    MAD_METHOD_SEND) != IBT_SUCCESS) {
31497c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_post_rej_ver_mismatch: "
31507c478bd9Sstevel@tonic-gate 		    "ibcm_alloc_out_msg failed");
31517c478bd9Sstevel@tonic-gate 		return;
31527c478bd9Sstevel@tonic-gate 	}
31537c478bd9Sstevel@tonic-gate 
31547c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rej_msg))
31557c478bd9Sstevel@tonic-gate 
31567c478bd9Sstevel@tonic-gate 	IBCM_OUT_HDRP(cm_rej_msg)->TransactionID =
31577c478bd9Sstevel@tonic-gate 	    ((ib_mad_hdr_t *)(input_madp))->TransactionID;
31587c478bd9Sstevel@tonic-gate 
31597c478bd9Sstevel@tonic-gate 	/* Initialize rej_msg fields */
31607c478bd9Sstevel@tonic-gate 	rej_msg = (ibcm_rej_msg_t *)IBCM_OUT_MSGP(cm_rej_msg);
31617c478bd9Sstevel@tonic-gate 	rej_msg->rej_local_comm_id = 0;
31627c478bd9Sstevel@tonic-gate 	rej_msg->rej_remote_comm_id = req_msgp->req_local_comm_id;
31637c478bd9Sstevel@tonic-gate 	rej_msg->rej_msg_type_plus = IBT_CM_FAILURE_REQ << 6;
31647c478bd9Sstevel@tonic-gate 	rej_msg->rej_rejection_reason = h2b16(IBT_CM_CLASS_NO_SUPPORT);
31657c478bd9Sstevel@tonic-gate 	rej_msg->rej_reject_info_len_plus = 1 << 1;
31667c478bd9Sstevel@tonic-gate 	rej_msg->rej_addl_rej_info[0] = IBCM_MAD_CLASS_VERSION;
31677c478bd9Sstevel@tonic-gate 
31687c478bd9Sstevel@tonic-gate 	IBCM_OUT_HDRP(cm_rej_msg)->AttributeID =
3169015f8fffShiremath 	    h2b16(IBCM_INCOMING_REJ + IBCM_ATTR_BASE_ID);
31707c478bd9Sstevel@tonic-gate 	IBCM_OUT_HDRP(cm_rej_msg)->Status = h2b16(MAD_STATUS_BAD_VERSION);
31717c478bd9Sstevel@tonic-gate 
31727c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rej_msg))
31737c478bd9Sstevel@tonic-gate 
31747c478bd9Sstevel@tonic-gate 	ibcm_build_reply_mad_addr(cm_mad_addr, &rej_reply_addr);
31757c478bd9Sstevel@tonic-gate 	if (rej_reply_addr.cm_qp_entry != NULL) {
31767c478bd9Sstevel@tonic-gate 		(void) ibcm_post_mad(cm_rej_msg, &rej_reply_addr, NULL, NULL);
31777c478bd9Sstevel@tonic-gate 		ibcm_release_qp(rej_reply_addr.cm_qp_entry);
31787c478bd9Sstevel@tonic-gate 	}
31797c478bd9Sstevel@tonic-gate 	(void) ibcm_free_out_msg(cm_mad_addr->ibmf_hdl, &cm_rej_msg);
31807c478bd9Sstevel@tonic-gate }
31817c478bd9Sstevel@tonic-gate 
31827c478bd9Sstevel@tonic-gate 
31837c478bd9Sstevel@tonic-gate /*
31847c478bd9Sstevel@tonic-gate  * ibcm_post_rep_mad:
31857c478bd9Sstevel@tonic-gate  *	Posts a REP MAD and starts timer
31867c478bd9Sstevel@tonic-gate  *
31877c478bd9Sstevel@tonic-gate  * INPUTS:
31887c478bd9Sstevel@tonic-gate  *	statep		- state pointer
31897c478bd9Sstevel@tonic-gate  *
31907c478bd9Sstevel@tonic-gate  * RETURN VALUE:
31917c478bd9Sstevel@tonic-gate  *	NONE
31927c478bd9Sstevel@tonic-gate  */
31937c478bd9Sstevel@tonic-gate void
ibcm_post_rep_mad(ibcm_state_data_t * statep)31947c478bd9Sstevel@tonic-gate ibcm_post_rep_mad(ibcm_state_data_t *statep)
31957c478bd9Sstevel@tonic-gate {
3196015f8fffShiremath 	ibcm_rep_msg_t	*rep_msgp =
3197015f8fffShiremath 	    (ibcm_rep_msg_t *)IBCM_OUT_MSGP(statep->stored_msg);
31987c478bd9Sstevel@tonic-gate 	ibmf_msg_t	*mra_msg = NULL;
31997c478bd9Sstevel@tonic-gate 	boolean_t	ret = B_FALSE;
32007c478bd9Sstevel@tonic-gate 
32017c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_post_rep_mad: statep 0x%p", statep);
32027c478bd9Sstevel@tonic-gate 
32037c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rep_msgp))
32047c478bd9Sstevel@tonic-gate 
32057c478bd9Sstevel@tonic-gate 	/*
32067c478bd9Sstevel@tonic-gate 	 * All other REP fields, other that the 2 below, are filled in
32077c478bd9Sstevel@tonic-gate 	 * the ibcm_cep_state_req() function.
32087c478bd9Sstevel@tonic-gate 	 */
32097c478bd9Sstevel@tonic-gate 	rep_msgp->rep_local_comm_id = h2b32(statep->local_comid);
32107c478bd9Sstevel@tonic-gate 	rep_msgp->rep_remote_comm_id = h2b32(statep->remote_comid);
32117c478bd9Sstevel@tonic-gate 	IBCM_OUT_HDRP(statep->stored_msg)->AttributeID =
32127c478bd9Sstevel@tonic-gate 	    h2b16(IBCM_INCOMING_REP + IBCM_ATTR_BASE_ID);
32137c478bd9Sstevel@tonic-gate 
32147c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rep_msgp))
32157c478bd9Sstevel@tonic-gate 
32167c478bd9Sstevel@tonic-gate 	/*
32177c478bd9Sstevel@tonic-gate 	 * Changing state and attempt to delete the mra msg must be done
32187c478bd9Sstevel@tonic-gate 	 * together holding the state_mutex
32197c478bd9Sstevel@tonic-gate 	 */
32207c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
32217c478bd9Sstevel@tonic-gate 
32227c478bd9Sstevel@tonic-gate 	/* Now, attempt to delete the mra_msg, if there is one allocated */
32237c478bd9Sstevel@tonic-gate 	if (statep->mra_msg != NULL) {
32247c478bd9Sstevel@tonic-gate 		if (!(statep->send_mad_flags & IBCM_MRA_POST_BUSY)) {
32257c478bd9Sstevel@tonic-gate 			mra_msg = statep->mra_msg;
32267c478bd9Sstevel@tonic-gate 			statep->mra_msg = NULL;
32277c478bd9Sstevel@tonic-gate 		} else statep->delete_mra_msg = B_TRUE;
32287c478bd9Sstevel@tonic-gate 	}
32297c478bd9Sstevel@tonic-gate 
32307c478bd9Sstevel@tonic-gate 	if (statep->abort_flag == IBCM_ABORT_CLIENT) {
32317c478bd9Sstevel@tonic-gate 		statep->state = IBCM_STATE_ABORTED;
32327c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
32337c478bd9Sstevel@tonic-gate 		ibcm_process_abort(statep);
32347c478bd9Sstevel@tonic-gate 
32357c478bd9Sstevel@tonic-gate 		/* Now post a REJ MAD, rej reason consumer abort */
32367c478bd9Sstevel@tonic-gate 		ibcm_post_rej_mad(statep, IBT_CM_CONSUMER, IBT_CM_FAILURE_REQ,
32377c478bd9Sstevel@tonic-gate 		    NULL, 0);
32387c478bd9Sstevel@tonic-gate 		ret = B_TRUE;
32397c478bd9Sstevel@tonic-gate 	} else if (statep->abort_flag & IBCM_ABORT_REJ) {
32407c478bd9Sstevel@tonic-gate 
32417c478bd9Sstevel@tonic-gate 		statep->state = IBCM_STATE_DELETE;
32427c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
32437c478bd9Sstevel@tonic-gate 
32447c478bd9Sstevel@tonic-gate 		ibcm_process_abort(statep);
32457c478bd9Sstevel@tonic-gate 		ibcm_delete_state_data(statep);
32467c478bd9Sstevel@tonic-gate 		ret = B_TRUE;
32477c478bd9Sstevel@tonic-gate 	} else {
32487c478bd9Sstevel@tonic-gate 
32497c478bd9Sstevel@tonic-gate 		statep->state = statep->timer_stored_state =
32507c478bd9Sstevel@tonic-gate 		    IBCM_STATE_REP_SENT;
32517c478bd9Sstevel@tonic-gate 		statep->remaining_retry_cnt = statep->max_cm_retries;
32527c478bd9Sstevel@tonic-gate 		statep->send_mad_flags |= IBCM_REP_POST_BUSY;
32537c478bd9Sstevel@tonic-gate 		IBCM_REF_CNT_INCR(statep);	/* for nonblocking REP Post */
32547c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
32557c478bd9Sstevel@tonic-gate 	}
32567c478bd9Sstevel@tonic-gate 
32577c478bd9Sstevel@tonic-gate 	if (mra_msg != NULL)
32587c478bd9Sstevel@tonic-gate 		(void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl,
32597c478bd9Sstevel@tonic-gate 		    &mra_msg);
32607c478bd9Sstevel@tonic-gate 	if (ret == B_TRUE)
32617c478bd9Sstevel@tonic-gate 		return;
32627c478bd9Sstevel@tonic-gate 
32637c478bd9Sstevel@tonic-gate 	ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_REP);
32647c478bd9Sstevel@tonic-gate 
32657c478bd9Sstevel@tonic-gate 	ibcm_post_rc_mad(statep, statep->stored_msg, ibcm_post_rep_complete,
32667c478bd9Sstevel@tonic-gate 	    statep);
32677c478bd9Sstevel@tonic-gate }
32687c478bd9Sstevel@tonic-gate 
32697c478bd9Sstevel@tonic-gate 
32707c478bd9Sstevel@tonic-gate /*
32717c478bd9Sstevel@tonic-gate  * ibcm_post_rtu_mad:
32727c478bd9Sstevel@tonic-gate  *	From active side post RTU MAD
32737c478bd9Sstevel@tonic-gate  *
32747c478bd9Sstevel@tonic-gate  * INPUTS:
32757c478bd9Sstevel@tonic-gate  *	statep		- state pointer
32767c478bd9Sstevel@tonic-gate  *
32777c478bd9Sstevel@tonic-gate  * RETURN VALUE: NONE
32787c478bd9Sstevel@tonic-gate  *
32797c478bd9Sstevel@tonic-gate  * NOTE: No timer set after posting RTU
32807c478bd9Sstevel@tonic-gate  */
32817c478bd9Sstevel@tonic-gate ibcm_status_t
ibcm_post_rtu_mad(ibcm_state_data_t * statep)32827c478bd9Sstevel@tonic-gate ibcm_post_rtu_mad(ibcm_state_data_t *statep)
32837c478bd9Sstevel@tonic-gate {
32847c478bd9Sstevel@tonic-gate 	ibcm_rtu_msg_t	*rtu_msg;
32857c478bd9Sstevel@tonic-gate 	ibmf_msg_t	*mra_msg = NULL;
32867c478bd9Sstevel@tonic-gate 	boolean_t	ret = B_FALSE;
32877c478bd9Sstevel@tonic-gate 
32887c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_post_rtu_mad: statep 0x%p", statep);
32897c478bd9Sstevel@tonic-gate 
32907c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rtu_msg))
32917c478bd9Sstevel@tonic-gate 
32927c478bd9Sstevel@tonic-gate 	rtu_msg = (ibcm_rtu_msg_t *)IBCM_OUT_MSGP(statep->stored_msg);
32937c478bd9Sstevel@tonic-gate 
32947c478bd9Sstevel@tonic-gate 	rtu_msg->rtu_local_comm_id = h2b32(statep->local_comid);
32957c478bd9Sstevel@tonic-gate 	rtu_msg->rtu_remote_comm_id = h2b32(statep->remote_comid);
32967c478bd9Sstevel@tonic-gate 	IBCM_OUT_HDRP(statep->stored_msg)->AttributeID =
32977c478bd9Sstevel@tonic-gate 	    h2b16(IBCM_INCOMING_RTU + IBCM_ATTR_BASE_ID);
32987c478bd9Sstevel@tonic-gate 
32997c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rtu_msg))
33007c478bd9Sstevel@tonic-gate 
33017c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
33027c478bd9Sstevel@tonic-gate 
33037c478bd9Sstevel@tonic-gate 	/* Now, attempt to delete the mra_msg, if there is one allocated */
33047c478bd9Sstevel@tonic-gate 	if (statep->mra_msg != NULL) {
33057c478bd9Sstevel@tonic-gate 		if (!(statep->send_mad_flags & IBCM_MRA_POST_BUSY)) {
33067c478bd9Sstevel@tonic-gate 			mra_msg = statep->mra_msg;
33077c478bd9Sstevel@tonic-gate 			statep->mra_msg = NULL;
33087c478bd9Sstevel@tonic-gate 		} else statep->delete_mra_msg = B_TRUE;
33097c478bd9Sstevel@tonic-gate 	}
33107c478bd9Sstevel@tonic-gate 
33117c478bd9Sstevel@tonic-gate 	if (statep->abort_flag == IBCM_ABORT_CLIENT) {
33127c478bd9Sstevel@tonic-gate 		statep->state = IBCM_STATE_ABORTED;
33137c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
33147c478bd9Sstevel@tonic-gate 
33157c478bd9Sstevel@tonic-gate 		ibcm_process_abort(statep);
33167c478bd9Sstevel@tonic-gate 
33177c478bd9Sstevel@tonic-gate 		/* Now post a REJ MAD */
33187c478bd9Sstevel@tonic-gate 		ibcm_post_rej_mad(statep, IBT_CM_CONSUMER, IBT_CM_FAILURE_REP,
33197c478bd9Sstevel@tonic-gate 		    NULL, 0);
33207c478bd9Sstevel@tonic-gate 		ret = B_TRUE;
33217c478bd9Sstevel@tonic-gate 	} else if (statep->abort_flag & IBCM_ABORT_REJ) {
33227c478bd9Sstevel@tonic-gate 		statep->state = IBCM_STATE_DELETE;
33237c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
33247c478bd9Sstevel@tonic-gate 
33257c478bd9Sstevel@tonic-gate 		ibcm_process_abort(statep);
33267c478bd9Sstevel@tonic-gate 		ibcm_delete_state_data(statep);
33277c478bd9Sstevel@tonic-gate 		ret = B_TRUE;
33287c478bd9Sstevel@tonic-gate 	} else {
33297c478bd9Sstevel@tonic-gate 		statep->state = IBCM_STATE_ESTABLISHED;
33307c478bd9Sstevel@tonic-gate 		ibtl_cm_chan_is_open(statep->channel);
33317c478bd9Sstevel@tonic-gate 		statep->send_mad_flags |= IBCM_RTU_POST_BUSY;
33327c478bd9Sstevel@tonic-gate 		IBCM_REF_CNT_INCR(statep);	/* for nonblocking RTU post */
33337c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
33347c478bd9Sstevel@tonic-gate 	}
33357c478bd9Sstevel@tonic-gate 
33367c478bd9Sstevel@tonic-gate 	if (mra_msg != NULL)
33377c478bd9Sstevel@tonic-gate 		(void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl,
33387c478bd9Sstevel@tonic-gate 		    &mra_msg);
33397c478bd9Sstevel@tonic-gate 
33407c478bd9Sstevel@tonic-gate 	if (ret == B_TRUE)	/* Abort case, no RTU posted */
33417c478bd9Sstevel@tonic-gate 		return (IBCM_FAILURE);
33427c478bd9Sstevel@tonic-gate 
33437c478bd9Sstevel@tonic-gate 	ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_RTU);
33447c478bd9Sstevel@tonic-gate 
33457c478bd9Sstevel@tonic-gate 	ibcm_post_rc_mad(statep, statep->stored_msg, ibcm_post_rtu_complete,
33467c478bd9Sstevel@tonic-gate 	    statep);
33477c478bd9Sstevel@tonic-gate 	return (IBCM_SUCCESS);
33487c478bd9Sstevel@tonic-gate }
33497c478bd9Sstevel@tonic-gate 
33507c478bd9Sstevel@tonic-gate 
33517c478bd9Sstevel@tonic-gate /*
33527c478bd9Sstevel@tonic-gate  * ibcm_process_abort:
3353*f248c5e0SToomas Soome  *	Processes abort, if client requested abort connection attempt
33547c478bd9Sstevel@tonic-gate  *
33557c478bd9Sstevel@tonic-gate  * INPUTS:
33567c478bd9Sstevel@tonic-gate  *	statep	- pointer to ibcm_state_data_t is passed
33577c478bd9Sstevel@tonic-gate  *
33587c478bd9Sstevel@tonic-gate  * RETURN VALUES: None
33597c478bd9Sstevel@tonic-gate  */
33607c478bd9Sstevel@tonic-gate void
ibcm_process_abort(ibcm_state_data_t * statep)33617c478bd9Sstevel@tonic-gate ibcm_process_abort(ibcm_state_data_t *statep)
33627c478bd9Sstevel@tonic-gate {
33637c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(cmlog, "ibcm_process_abort: statep 0x%p", statep);
33647c478bd9Sstevel@tonic-gate 
33657c478bd9Sstevel@tonic-gate 	/* move CEP to error state, before calling client handler */
33667c478bd9Sstevel@tonic-gate 	(void) ibcm_cep_to_error_state(statep);
33677c478bd9Sstevel@tonic-gate 
33687c478bd9Sstevel@tonic-gate 	/* Now disassociate the link between statep and qp */
33697c478bd9Sstevel@tonic-gate 	IBCM_SET_CHAN_PRIVATE(statep->channel, NULL);
33707c478bd9Sstevel@tonic-gate 
33717c478bd9Sstevel@tonic-gate 	/* invoke cm handler, for non-blocking open/close rc channel calls */
33727c478bd9Sstevel@tonic-gate 	if (statep->cm_handler) { /* cannot be NULL, but still .. */
33737c478bd9Sstevel@tonic-gate 		ibt_cm_event_t		event;
33747c478bd9Sstevel@tonic-gate 		ibt_cm_return_args_t	ret_args;
33757c478bd9Sstevel@tonic-gate 
33767c478bd9Sstevel@tonic-gate 		bzero(&event, sizeof (event));
33777c478bd9Sstevel@tonic-gate 		bzero(&ret_args, sizeof (ret_args));
33787c478bd9Sstevel@tonic-gate 
33797c478bd9Sstevel@tonic-gate 		if (statep->abort_flag & IBCM_ABORT_REJ)
33807c478bd9Sstevel@tonic-gate 			ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_RCV,
33817c478bd9Sstevel@tonic-gate 			    IBT_CM_FAILURE_UNKNOWN, IBT_CM_TIMEOUT, NULL, 0);
33827c478bd9Sstevel@tonic-gate 		else {
3383fde3102fShiremath 			ibcm_path_cache_purge();
3384fde3102fShiremath 
33857c478bd9Sstevel@tonic-gate 			event.cm_type = IBT_CM_EVENT_CONN_CLOSED;
33867c478bd9Sstevel@tonic-gate 			event.cm_channel = statep->channel;
33877c478bd9Sstevel@tonic-gate 			event.cm_event.closed = IBT_CM_CLOSED_ABORT;
33887c478bd9Sstevel@tonic-gate 
33897c478bd9Sstevel@tonic-gate 			ibcm_insert_trace(statep,
33907c478bd9Sstevel@tonic-gate 			    IBCM_TRACE_CALLED_CONN_CLOSE_EVENT);
33917c478bd9Sstevel@tonic-gate 
3392ea46d761SPramod Gunjikar 			if (statep->channel)
3393ea46d761SPramod Gunjikar 				ibtl_cm_chan_open_is_aborted(statep->channel);
3394a23420cfSShantkumar Hiremath 
33957c478bd9Sstevel@tonic-gate 			(void) statep->cm_handler(statep->state_cm_private,
33967c478bd9Sstevel@tonic-gate 			    &event, &ret_args, NULL, 0);
33977c478bd9Sstevel@tonic-gate 
33987c478bd9Sstevel@tonic-gate 			ibcm_insert_trace(statep,
33997c478bd9Sstevel@tonic-gate 			    IBCM_TRACE_RET_CONN_CLOSE_EVENT);
34007c478bd9Sstevel@tonic-gate 
34019d3d2ed0Shiremath 			mutex_enter(&statep->state_mutex);
34029d3d2ed0Shiremath 			ibcm_open_done(statep);
34039d3d2ed0Shiremath 			mutex_exit(&statep->state_mutex);
34047c478bd9Sstevel@tonic-gate 		}
34057c478bd9Sstevel@tonic-gate 	}
34067c478bd9Sstevel@tonic-gate 
34077c478bd9Sstevel@tonic-gate 	/*
34087c478bd9Sstevel@tonic-gate 	 * Unblock an ibt_open_rc_channel called in a blocking mode, though
34097c478bd9Sstevel@tonic-gate 	 * it is an unlikely scenario
34107c478bd9Sstevel@tonic-gate 	 */
34117c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
34127c478bd9Sstevel@tonic-gate 
34139d3d2ed0Shiremath 	statep->cm_retries++; /* cause connection trace to be printed */
34147c478bd9Sstevel@tonic-gate 	statep->open_done = B_TRUE;
34157c478bd9Sstevel@tonic-gate 	statep->close_done = B_TRUE;
34167c478bd9Sstevel@tonic-gate 	statep->close_nocb_state = IBCM_FAIL; /* sanity sake */
34177c478bd9Sstevel@tonic-gate 
34187c478bd9Sstevel@tonic-gate 	if (statep->open_return_data != NULL) {
34197c478bd9Sstevel@tonic-gate 		/* REJ came first, and then client aborted connection */
34207c478bd9Sstevel@tonic-gate 		if (statep->abort_flag & IBCM_ABORT_REJ)
34217c478bd9Sstevel@tonic-gate 			statep->open_return_data->rc_status = IBT_CM_TIMEOUT;
34227c478bd9Sstevel@tonic-gate 		else statep->open_return_data->rc_status = IBT_CM_ABORT;
34237c478bd9Sstevel@tonic-gate 	}
34247c478bd9Sstevel@tonic-gate 
34257c478bd9Sstevel@tonic-gate 	cv_broadcast(&statep->block_client_cv);
34267c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
34279d3d2ed0Shiremath 	if (ibcm_enable_trace != 0)
34289d3d2ed0Shiremath 		ibcm_dump_conn_trace(statep);
34297c478bd9Sstevel@tonic-gate }
34307c478bd9Sstevel@tonic-gate 
34317c478bd9Sstevel@tonic-gate /*
34327c478bd9Sstevel@tonic-gate  * ibcm_timeout_cb:
34337c478bd9Sstevel@tonic-gate  *	Called when the timer expires
34347c478bd9Sstevel@tonic-gate  *
34357c478bd9Sstevel@tonic-gate  * INPUTS:
34367c478bd9Sstevel@tonic-gate  *	arg	- ibcm_state_data_t is passed
34377c478bd9Sstevel@tonic-gate  *
34387c478bd9Sstevel@tonic-gate  * RETURN VALUES: NONE
34397c478bd9Sstevel@tonic-gate  */
34407c478bd9Sstevel@tonic-gate void
ibcm_timeout_cb(void * arg)34417c478bd9Sstevel@tonic-gate ibcm_timeout_cb(void *arg)
34427c478bd9Sstevel@tonic-gate {
34437c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep = (ibcm_state_data_t *)arg;
34447c478bd9Sstevel@tonic-gate 
34457c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
34467c478bd9Sstevel@tonic-gate 
34477c478bd9Sstevel@tonic-gate 	/*
34487c478bd9Sstevel@tonic-gate 	 * The blocking operations are handled in a separate thread.
34497c478bd9Sstevel@tonic-gate 	 * All other non-blocking operations, including ibmf non-blocking
34507c478bd9Sstevel@tonic-gate 	 * posts are done from timeout context
34517c478bd9Sstevel@tonic-gate 	 */
34527c478bd9Sstevel@tonic-gate 
34537c478bd9Sstevel@tonic-gate 	if ((statep->timer_stored_state != statep->state) ||
34547c478bd9Sstevel@tonic-gate 	    ((statep->timer_stored_state == IBCM_STATE_ESTABLISHED) &&
34557c478bd9Sstevel@tonic-gate 	    (statep->ap_state != statep->timer_stored_ap_state))) {
34567c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
34577c478bd9Sstevel@tonic-gate 		return;
34587c478bd9Sstevel@tonic-gate 	}
34597c478bd9Sstevel@tonic-gate 
34607c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(cmlog, "ibcm_timeout_cb: statep 0x%p state %x "
34617c478bd9Sstevel@tonic-gate 	    "ap_state %x", statep, statep->state, statep->ap_state);
34627c478bd9Sstevel@tonic-gate 
34637c478bd9Sstevel@tonic-gate 	/* Processing depends upon current state */
34647c478bd9Sstevel@tonic-gate 
34657c478bd9Sstevel@tonic-gate 	if (statep->state == IBCM_STATE_REJ_SENT) {
34667c478bd9Sstevel@tonic-gate 		statep->state = IBCM_STATE_DELETE;
34677c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
34687c478bd9Sstevel@tonic-gate 
34697c478bd9Sstevel@tonic-gate 		/* Deallocate the CM state structure */
34707c478bd9Sstevel@tonic-gate 		ibcm_delete_state_data(statep);
34717c478bd9Sstevel@tonic-gate 		return;
34727c478bd9Sstevel@tonic-gate 
34737c478bd9Sstevel@tonic-gate 	} else if (statep->state == IBCM_STATE_TIMEWAIT) {
34747c478bd9Sstevel@tonic-gate 		statep->state = IBCM_STATE_DELETE;
34757c478bd9Sstevel@tonic-gate 
34767c478bd9Sstevel@tonic-gate 		/* TIME_WAIT timer expired, so cleanup */
34777c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
34787c478bd9Sstevel@tonic-gate 
34797c478bd9Sstevel@tonic-gate 		if (statep->channel)
34807c478bd9Sstevel@tonic-gate 			ibtl_cm_chan_is_closed(statep->channel);
34817c478bd9Sstevel@tonic-gate 
34827c478bd9Sstevel@tonic-gate 		if (statep->recycle_arg) {
34837c478bd9Sstevel@tonic-gate 			struct ibcm_taskq_recycle_arg_s *recycle_arg;
34847c478bd9Sstevel@tonic-gate 
34857c478bd9Sstevel@tonic-gate 			recycle_arg = statep->recycle_arg;
34867c478bd9Sstevel@tonic-gate 
34877c478bd9Sstevel@tonic-gate 			_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(
34887c478bd9Sstevel@tonic-gate 			    statep->recycle_arg))
34897c478bd9Sstevel@tonic-gate 			statep->recycle_arg = NULL;
34907c478bd9Sstevel@tonic-gate 			_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(statep->recycle_arg))
34917c478bd9Sstevel@tonic-gate 
34927c478bd9Sstevel@tonic-gate 			/* if possible, do not slow down calling recycle func */
34937c478bd9Sstevel@tonic-gate 			if (taskq_dispatch(ibcm_taskq, ibcm_process_rc_recycle,
3494fc8ae2ecSToomas Soome 			    recycle_arg, TQ_NOQUEUE | TQ_NOSLEEP) ==
3495fc8ae2ecSToomas Soome 			    TASKQID_INVALID) {
34967c478bd9Sstevel@tonic-gate 
34977c478bd9Sstevel@tonic-gate 				_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(
34987c478bd9Sstevel@tonic-gate 				    statep->recycle_arg))
34997c478bd9Sstevel@tonic-gate 				statep->recycle_arg = recycle_arg;
35007c478bd9Sstevel@tonic-gate 				_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(
35017c478bd9Sstevel@tonic-gate 				    statep->recycle_arg))
35027c478bd9Sstevel@tonic-gate 				ibcm_add_tlist(statep);
35037c478bd9Sstevel@tonic-gate 				return;
35047c478bd9Sstevel@tonic-gate 			}
35057c478bd9Sstevel@tonic-gate 		}
35067c478bd9Sstevel@tonic-gate 
35077c478bd9Sstevel@tonic-gate 		ibcm_delete_state_data(statep);
35087c478bd9Sstevel@tonic-gate 		return;
35097c478bd9Sstevel@tonic-gate 	} else if (statep->remaining_retry_cnt > 0) {
35107c478bd9Sstevel@tonic-gate 		ibcm_conn_state_t	stored_state;
35117c478bd9Sstevel@tonic-gate 		ibcm_ap_state_t		stored_ap_state;
35127c478bd9Sstevel@tonic-gate 
35137c478bd9Sstevel@tonic-gate 		statep->remaining_retry_cnt--;
3514fde3102fShiremath 		IBTF_DPRINTF_L3(cmlog, "ibcm_timeout_cb: statep 0x%p "
35157c478bd9Sstevel@tonic-gate 		    "attr-id= 0x%x, retries remaining = 0x%x", statep,
35167c478bd9Sstevel@tonic-gate 		    b2h16(IBCM_OUT_HDRP(statep->stored_msg)->AttributeID),
35177c478bd9Sstevel@tonic-gate 		    statep->remaining_retry_cnt);
35187c478bd9Sstevel@tonic-gate 
35197c478bd9Sstevel@tonic-gate 		/*
35207c478bd9Sstevel@tonic-gate 		 * REP could be resent, either because of timeout or an
35217c478bd9Sstevel@tonic-gate 		 * incoming REQ. Any other MAD below can be resent, because
35227c478bd9Sstevel@tonic-gate 		 * of timeout only, hence send_mad_flag manipulation not
35237c478bd9Sstevel@tonic-gate 		 * required for those cases.
35247c478bd9Sstevel@tonic-gate 		 * If REP is already being retransmitted, then just set the
35257c478bd9Sstevel@tonic-gate 		 * timer and return. Else post REP in non-blocking mode
35267c478bd9Sstevel@tonic-gate 		 */
35277c478bd9Sstevel@tonic-gate 		if (statep->timer_stored_state == IBCM_STATE_REP_SENT) {
35287c478bd9Sstevel@tonic-gate 			if (statep->send_mad_flags & IBCM_REP_POST_BUSY) {
35297c478bd9Sstevel@tonic-gate 				statep->timerid = IBCM_TIMEOUT(statep,
35307c478bd9Sstevel@tonic-gate 				    statep->timer_value);
35317c478bd9Sstevel@tonic-gate 				mutex_exit(&statep->state_mutex);
35327c478bd9Sstevel@tonic-gate 				ibcm_insert_trace(statep,
35337c478bd9Sstevel@tonic-gate 				    IBCM_TRACE_TIMEOUT_REP);
35347c478bd9Sstevel@tonic-gate 				return;
35357c478bd9Sstevel@tonic-gate 			}
35367c478bd9Sstevel@tonic-gate 
35377c478bd9Sstevel@tonic-gate 			/*
35387c478bd9Sstevel@tonic-gate 			 * Set REP  busy flag, so any incoming REQ's will not
35397c478bd9Sstevel@tonic-gate 			 * initiate new REP transmissions
35407c478bd9Sstevel@tonic-gate 			 */
35417c478bd9Sstevel@tonic-gate 			statep->send_mad_flags |= IBCM_REP_POST_BUSY;
35427c478bd9Sstevel@tonic-gate 
35437c478bd9Sstevel@tonic-gate 		/* Since REQ/RTU/REJ on active side use same MAD, synchronize */
35447c478bd9Sstevel@tonic-gate 		} else if (statep->timer_stored_state == IBCM_STATE_REQ_SENT) {
35457c478bd9Sstevel@tonic-gate 			ASSERT((statep->send_mad_flags & IBCM_REQ_POST_BUSY)
35467c478bd9Sstevel@tonic-gate 			    == 0);
35477c478bd9Sstevel@tonic-gate 			statep->send_mad_flags |= IBCM_REQ_POST_BUSY;
35487c478bd9Sstevel@tonic-gate 		}
35497c478bd9Sstevel@tonic-gate 
35507c478bd9Sstevel@tonic-gate 		IBCM_REF_CNT_INCR(statep);	/* for non-blocking post */
35517c478bd9Sstevel@tonic-gate 		stored_state = statep->timer_stored_state;
35527c478bd9Sstevel@tonic-gate 		stored_ap_state = statep->timer_stored_ap_state;
35537c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
35547c478bd9Sstevel@tonic-gate 
35557c478bd9Sstevel@tonic-gate 		/* Post REQ MAD in non-blocking mode */
35567c478bd9Sstevel@tonic-gate 		if (stored_state == IBCM_STATE_REQ_SENT) {
35579d3d2ed0Shiremath 			ibcm_insert_trace(statep, IBCM_TRACE_OUT_REQ_RETRY);
35587c478bd9Sstevel@tonic-gate 			ibcm_post_rc_mad(statep, statep->stored_msg,
35597c478bd9Sstevel@tonic-gate 			    ibcm_post_req_complete, statep);
35607c478bd9Sstevel@tonic-gate 		/* Post REQ MAD in non-blocking mode */
35617c478bd9Sstevel@tonic-gate 		} else if (stored_state == IBCM_STATE_REP_WAIT) {
35629d3d2ed0Shiremath 			ibcm_insert_trace(statep, IBCM_TRACE_OUT_REQ_RETRY);
35637c478bd9Sstevel@tonic-gate 			ibcm_post_rc_mad(statep, statep->stored_msg,
35647c478bd9Sstevel@tonic-gate 			    ibcm_post_rep_wait_complete, statep);
35657c478bd9Sstevel@tonic-gate 		/* Post REP MAD in non-blocking mode */
35667c478bd9Sstevel@tonic-gate 		} else if (stored_state == IBCM_STATE_REP_SENT) {
35679d3d2ed0Shiremath 			ibcm_insert_trace(statep, IBCM_TRACE_OUT_REP_RETRY);
35687c478bd9Sstevel@tonic-gate 			ibcm_post_rc_mad(statep, statep->stored_msg,
35697c478bd9Sstevel@tonic-gate 			    ibcm_post_rep_complete, statep);
35707c478bd9Sstevel@tonic-gate 		/* Post REP MAD in non-blocking mode */
35717c478bd9Sstevel@tonic-gate 		} else if (stored_state == IBCM_STATE_MRA_REP_RCVD) {
35729d3d2ed0Shiremath 			ibcm_insert_trace(statep, IBCM_TRACE_OUT_REP_RETRY);
35739d3d2ed0Shiremath 			mutex_enter(&statep->state_mutex);
35749d3d2ed0Shiremath 			statep->mra_time = gethrtime();
35759d3d2ed0Shiremath 			mutex_exit(&statep->state_mutex);
35767c478bd9Sstevel@tonic-gate 			ibcm_post_rc_mad(statep, statep->stored_msg,
35777c478bd9Sstevel@tonic-gate 			    ibcm_post_mra_rep_complete, statep);
35787c478bd9Sstevel@tonic-gate 		/* Post DREQ MAD in non-blocking mode */
35797c478bd9Sstevel@tonic-gate 		} else if (stored_state == IBCM_STATE_DREQ_SENT) {
35809d3d2ed0Shiremath 			mutex_enter(&statep->state_mutex);
35819d3d2ed0Shiremath 			if (statep->remaining_retry_cnt ==
35829d3d2ed0Shiremath 			    statep->max_cm_retries)
35839d3d2ed0Shiremath 				ibcm_insert_trace(statep,
35849d3d2ed0Shiremath 				    IBCM_TRACE_OUTGOING_DREQ);
35859d3d2ed0Shiremath 			else {
35869d3d2ed0Shiremath 				ibcm_insert_trace(statep,
35879d3d2ed0Shiremath 				    IBCM_TRACE_OUT_DREQ_RETRY);
35889d3d2ed0Shiremath 				statep->cm_retries++;
35899d3d2ed0Shiremath 				ibcm_close_done(statep, 0);
35909d3d2ed0Shiremath 			}
35919d3d2ed0Shiremath 			mutex_exit(&statep->state_mutex);
35927c478bd9Sstevel@tonic-gate 			ibcm_post_rc_mad(statep, statep->dreq_msg,
35937c478bd9Sstevel@tonic-gate 			    ibcm_post_dreq_complete, statep);
35947c478bd9Sstevel@tonic-gate 		/* post LAP MAD in non-blocking mode */
35957c478bd9Sstevel@tonic-gate 		} else if (stored_ap_state == IBCM_AP_STATE_LAP_SENT) {
35969d3d2ed0Shiremath 			ibcm_insert_trace(statep, IBCM_TRACE_OUT_LAP_RETRY);
35977c478bd9Sstevel@tonic-gate 			ibcm_post_rc_mad(statep, statep->lapr_msg,
35987c478bd9Sstevel@tonic-gate 			    ibcm_post_lap_complete, statep);
35997c478bd9Sstevel@tonic-gate 		/* post LAP MAD in non-blocking mode */
36007c478bd9Sstevel@tonic-gate 		} else if (stored_ap_state == IBCM_AP_STATE_MRA_LAP_RCVD) {
36019d3d2ed0Shiremath 			ibcm_insert_trace(statep, IBCM_TRACE_OUT_LAP_RETRY);
36029d3d2ed0Shiremath 			mutex_enter(&statep->state_mutex);
36039d3d2ed0Shiremath 			statep->mra_time = gethrtime();
36049d3d2ed0Shiremath 			mutex_exit(&statep->state_mutex);
36057c478bd9Sstevel@tonic-gate 			ibcm_post_rc_mad(statep, statep->lapr_msg,
36067c478bd9Sstevel@tonic-gate 			    ibcm_post_mra_lap_complete, statep);
36077c478bd9Sstevel@tonic-gate 		}
36087c478bd9Sstevel@tonic-gate 		return;
36097c478bd9Sstevel@tonic-gate 
36107c478bd9Sstevel@tonic-gate 	} else if ((statep->state == IBCM_STATE_REQ_SENT) ||
36117c478bd9Sstevel@tonic-gate 	    (statep->state == IBCM_STATE_REP_SENT) ||
36127c478bd9Sstevel@tonic-gate 	    (statep->state == IBCM_STATE_MRA_REP_RCVD) ||
36137c478bd9Sstevel@tonic-gate 	    (statep->state == IBCM_STATE_REP_WAIT)) {
36147c478bd9Sstevel@tonic-gate 
36157c478bd9Sstevel@tonic-gate 		/*
36167c478bd9Sstevel@tonic-gate 		 * MAX retries reached, send a REJ to the remote,
36177c478bd9Sstevel@tonic-gate 		 * and close the connection
36187c478bd9Sstevel@tonic-gate 		 */
36197c478bd9Sstevel@tonic-gate 		statep->timedout_state = statep->state;
36207c478bd9Sstevel@tonic-gate 		statep->state = IBCM_STATE_TIMED_OUT;
36217c478bd9Sstevel@tonic-gate 
36227c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L3(cmlog, "ibcm_timeout_cb: "
36237c478bd9Sstevel@tonic-gate 		    "max retries done for statep 0x%p", statep);
36249d3d2ed0Shiremath 		statep->cm_retries++; /* cause conn trace to print */
36257c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
36267c478bd9Sstevel@tonic-gate 
36277c478bd9Sstevel@tonic-gate 		if ((statep->timedout_state == IBCM_STATE_REP_SENT) ||
36287c478bd9Sstevel@tonic-gate 		    (statep->timedout_state == IBCM_STATE_MRA_REP_RCVD))
36297c478bd9Sstevel@tonic-gate 			(void) ibcm_cep_to_error_state(statep);
36307c478bd9Sstevel@tonic-gate 
36317c478bd9Sstevel@tonic-gate 		/* Disassociate statep from QP */
36327c478bd9Sstevel@tonic-gate 		IBCM_SET_CHAN_PRIVATE(statep->channel, NULL);
36337c478bd9Sstevel@tonic-gate 
36347c478bd9Sstevel@tonic-gate 		/*
36357c478bd9Sstevel@tonic-gate 		 * statep is in REJ SENT state, the only way to get deleted is
36367c478bd9Sstevel@tonic-gate 		 * the timeout callback that is set after posting REJ
36377c478bd9Sstevel@tonic-gate 		 * The thread processing is required where cm handler is
36387c478bd9Sstevel@tonic-gate 		 * specified
36397c478bd9Sstevel@tonic-gate 		 */
36407c478bd9Sstevel@tonic-gate 
36417c478bd9Sstevel@tonic-gate 		if (statep->cm_handler != NULL) {
36427c478bd9Sstevel@tonic-gate 			/* Attach the statep to timeout list */
36437c478bd9Sstevel@tonic-gate 			ibcm_add_tlist(statep);
36447c478bd9Sstevel@tonic-gate 		} else {
36457c478bd9Sstevel@tonic-gate 			ib_guid_t local_hca_guid;
36467c478bd9Sstevel@tonic-gate 
36477c478bd9Sstevel@tonic-gate 			mutex_enter(&statep->state_mutex);
36487c478bd9Sstevel@tonic-gate 
36497c478bd9Sstevel@tonic-gate 			/*
36507c478bd9Sstevel@tonic-gate 			 * statep->open_return_data is set for blocking
36517c478bd9Sstevel@tonic-gate 			 * No handler specified, hence signal blocked
36527c478bd9Sstevel@tonic-gate 			 * ibt_open_rc_channel from here
36537c478bd9Sstevel@tonic-gate 			 */
36547c478bd9Sstevel@tonic-gate 			if (statep->open_return_data != NULL) {
36557c478bd9Sstevel@tonic-gate 				statep->open_return_data->rc_status =
36567c478bd9Sstevel@tonic-gate 				    IBT_CM_TIMEOUT;
36577c478bd9Sstevel@tonic-gate 				statep->open_done = B_TRUE;
36587c478bd9Sstevel@tonic-gate 				cv_broadcast(&statep->block_client_cv);
36597c478bd9Sstevel@tonic-gate 			}
36607c478bd9Sstevel@tonic-gate 
36617c478bd9Sstevel@tonic-gate 			mutex_exit(&statep->state_mutex);
36627c478bd9Sstevel@tonic-gate 
36637c478bd9Sstevel@tonic-gate 			local_hca_guid = h2b64(statep->local_hca_guid);
36647c478bd9Sstevel@tonic-gate 			ibcm_post_rej_mad(statep, IBT_CM_TIMEOUT,
36657c478bd9Sstevel@tonic-gate 			    (statep->timedout_state == IBCM_STATE_REP_SENT ||
36667c478bd9Sstevel@tonic-gate 			    statep->timedout_state == IBCM_STATE_MRA_REP_RCVD) ?
36677c478bd9Sstevel@tonic-gate 			    IBT_CM_FAILURE_REP: IBT_CM_FAILURE_REQ,
36687c478bd9Sstevel@tonic-gate 			    &local_hca_guid, sizeof (ib_guid_t));
36697c478bd9Sstevel@tonic-gate 		}
36707c478bd9Sstevel@tonic-gate 
36717c478bd9Sstevel@tonic-gate 	} else if ((statep->ap_state == IBCM_AP_STATE_LAP_SENT) ||
36727c478bd9Sstevel@tonic-gate 	    (statep->ap_state == IBCM_AP_STATE_MRA_LAP_RCVD)) {
36737c478bd9Sstevel@tonic-gate 
3674fde3102fShiremath 		IBTF_DPRINTF_L4(cmlog, "ibcm_timeout_cb: statep 0x%p "
36757c478bd9Sstevel@tonic-gate 		    "LAP timed out",  statep);
36767c478bd9Sstevel@tonic-gate 		statep->timedout_state = statep->state;
36777c478bd9Sstevel@tonic-gate 		/*
36787c478bd9Sstevel@tonic-gate 		 * This state setting ensures that the processing of DREQ is
36797c478bd9Sstevel@tonic-gate 		 * sequentialized, once this ap_state is set. If statep is
36807c478bd9Sstevel@tonic-gate 		 * attached to timeout list, it cannot be re-attached as long
36817c478bd9Sstevel@tonic-gate 		 * as in this state
36827c478bd9Sstevel@tonic-gate 		 */
36837c478bd9Sstevel@tonic-gate 		statep->ap_state = IBCM_AP_STATE_TIMED_OUT;
36849d3d2ed0Shiremath 		ibcm_open_done(statep);
36857c478bd9Sstevel@tonic-gate 
36867c478bd9Sstevel@tonic-gate 		if (statep->cm_handler != NULL) {
36877c478bd9Sstevel@tonic-gate 			/* Attach statep to timeout list - thread handling */
36887c478bd9Sstevel@tonic-gate 			ibcm_add_tlist(statep);
36897c478bd9Sstevel@tonic-gate 		} else if (statep->ap_return_data != NULL) {
36907c478bd9Sstevel@tonic-gate 			/*
36917c478bd9Sstevel@tonic-gate 			 * statep->ap_return_data is initialized for blocking in
36927c478bd9Sstevel@tonic-gate 			 * ibt_set_alt_path(), signal the waiting CV
36937c478bd9Sstevel@tonic-gate 			 */
36947c478bd9Sstevel@tonic-gate 			statep->ap_return_data->ap_status = IBT_CM_AP_TIMEOUT;
36957c478bd9Sstevel@tonic-gate 			statep->ap_done = B_TRUE;
36967c478bd9Sstevel@tonic-gate 			cv_broadcast(&statep->block_client_cv);
36977c478bd9Sstevel@tonic-gate 
36987c478bd9Sstevel@tonic-gate 			statep->ap_state = IBCM_AP_STATE_IDLE;
36997c478bd9Sstevel@tonic-gate 			/* Wake up threads waiting for LAP/APR to complete */
37007c478bd9Sstevel@tonic-gate 			cv_broadcast(&statep->block_mad_cv);
37017c478bd9Sstevel@tonic-gate 		}
37027c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
37037c478bd9Sstevel@tonic-gate 
37047c478bd9Sstevel@tonic-gate 	} else if (statep->state == IBCM_STATE_DREQ_SENT) {
37057c478bd9Sstevel@tonic-gate 
37067c478bd9Sstevel@tonic-gate 		statep->timedout_state = statep->state;
37077c478bd9Sstevel@tonic-gate 		statep->state = IBCM_STATE_TIMED_OUT;
37087c478bd9Sstevel@tonic-gate 
37097c478bd9Sstevel@tonic-gate 		/*
37107c478bd9Sstevel@tonic-gate 		 * The logic below is necessary, for a race situation between
37117c478bd9Sstevel@tonic-gate 		 * ibt_close_rc_channel with no callbacks option and CM's
37127c478bd9Sstevel@tonic-gate 		 * internal stale connection handling on the same connection
37137c478bd9Sstevel@tonic-gate 		 */
37147c478bd9Sstevel@tonic-gate 		if (statep->close_nocb_state != IBCM_FAIL) {
37157c478bd9Sstevel@tonic-gate 			ASSERT(statep->close_nocb_state == IBCM_UNBLOCK);
37167c478bd9Sstevel@tonic-gate 			ibtl_cm_chan_is_closing(statep->channel);
37177c478bd9Sstevel@tonic-gate 			statep->close_nocb_state = IBCM_BLOCK;
37187c478bd9Sstevel@tonic-gate 		}
37197c478bd9Sstevel@tonic-gate 
37207c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
37217c478bd9Sstevel@tonic-gate 
37227c478bd9Sstevel@tonic-gate 		/*
37237c478bd9Sstevel@tonic-gate 		 * If cm handler is specified, then invoke handler for
37247c478bd9Sstevel@tonic-gate 		 * the DREQ timeout
37257c478bd9Sstevel@tonic-gate 		 */
37267c478bd9Sstevel@tonic-gate 		if (statep->cm_handler != NULL) {
37277c478bd9Sstevel@tonic-gate 			ibcm_add_tlist(statep);
37287c478bd9Sstevel@tonic-gate 			return;
37297c478bd9Sstevel@tonic-gate 		}
37307c478bd9Sstevel@tonic-gate 
37317c478bd9Sstevel@tonic-gate 		ibcm_process_dreq_timeout(statep);
37327c478bd9Sstevel@tonic-gate 	} else {
37337c478bd9Sstevel@tonic-gate 
37347c478bd9Sstevel@tonic-gate #ifdef DEBUG
37357c478bd9Sstevel@tonic-gate 		if (ibcm_test_mode > 0)
37367c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_timeout_cb: "
37377c478bd9Sstevel@tonic-gate 			    "Unexpected unhandled timeout  for statep 0x%p "
37387c478bd9Sstevel@tonic-gate 			    "state %d", statep, statep->state);
37397c478bd9Sstevel@tonic-gate #endif
37407c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
37417c478bd9Sstevel@tonic-gate 	}
37427c478bd9Sstevel@tonic-gate }
37437c478bd9Sstevel@tonic-gate 
37447c478bd9Sstevel@tonic-gate /*
37457c478bd9Sstevel@tonic-gate  * Following are set of ibmf send callback routines that are used when posting
37467c478bd9Sstevel@tonic-gate  * various CM MADs in non-blocking post mode
37477c478bd9Sstevel@tonic-gate  */
37487c478bd9Sstevel@tonic-gate 
37497c478bd9Sstevel@tonic-gate /*ARGSUSED*/
37507c478bd9Sstevel@tonic-gate void
ibcm_post_req_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)37517c478bd9Sstevel@tonic-gate ibcm_post_req_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, void *args)
37527c478bd9Sstevel@tonic-gate {
37537c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep = (ibcm_state_data_t *)args;
37547c478bd9Sstevel@tonic-gate 
37557c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_post_req_complete statep %p ", statep);
37567c478bd9Sstevel@tonic-gate 
37579d3d2ed0Shiremath 	mutex_enter(&statep->state_mutex);
37589d3d2ed0Shiremath 	ibcm_flow_dec(statep->post_time, "REQ");
37597c478bd9Sstevel@tonic-gate 	ibcm_insert_trace(statep, IBCM_TRACE_REQ_POST_COMPLETE);
37607c478bd9Sstevel@tonic-gate 
37617c478bd9Sstevel@tonic-gate 	statep->send_mad_flags &= ~IBCM_REQ_POST_BUSY;
37627c478bd9Sstevel@tonic-gate 
37637c478bd9Sstevel@tonic-gate 	/* signal any waiting threads for REQ MAD to become available */
37647c478bd9Sstevel@tonic-gate 	cv_signal(&statep->block_mad_cv);
37657c478bd9Sstevel@tonic-gate 
37667c478bd9Sstevel@tonic-gate 	if (statep->state == IBCM_STATE_REQ_SENT)
37677c478bd9Sstevel@tonic-gate 		statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
37687c478bd9Sstevel@tonic-gate 
37697c478bd9Sstevel@tonic-gate 	IBCM_REF_CNT_DECR(statep);
37707c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
37717c478bd9Sstevel@tonic-gate }
37727c478bd9Sstevel@tonic-gate 
37737c478bd9Sstevel@tonic-gate /*ARGSUSED*/
37747c478bd9Sstevel@tonic-gate void
ibcm_post_rep_wait_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)37757c478bd9Sstevel@tonic-gate ibcm_post_rep_wait_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
37767c478bd9Sstevel@tonic-gate     void *args)
37777c478bd9Sstevel@tonic-gate {
37787c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep = (ibcm_state_data_t *)args;
37797c478bd9Sstevel@tonic-gate 
37807c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_post_rep_wait_complete statep %p", statep);
37817c478bd9Sstevel@tonic-gate 
37827c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
37839d3d2ed0Shiremath 	ibcm_flow_dec(statep->post_time, "REQ_RETRY");
37849d3d2ed0Shiremath 	ibcm_insert_trace(statep, IBCM_TRACE_REQ_POST_COMPLETE);
37857c478bd9Sstevel@tonic-gate 	if (statep->state == IBCM_STATE_REP_WAIT)
37867c478bd9Sstevel@tonic-gate 		statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
37877c478bd9Sstevel@tonic-gate 	IBCM_REF_CNT_DECR(statep);
37887c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
37897c478bd9Sstevel@tonic-gate }
37907c478bd9Sstevel@tonic-gate 
37917c478bd9Sstevel@tonic-gate /*ARGSUSED*/
37927c478bd9Sstevel@tonic-gate void
ibcm_post_rep_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)37937c478bd9Sstevel@tonic-gate ibcm_post_rep_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, void *args)
37947c478bd9Sstevel@tonic-gate {
37957c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep = (ibcm_state_data_t *)args;
37967c478bd9Sstevel@tonic-gate 
37977c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_post_rep_complete statep %p", statep);
37987c478bd9Sstevel@tonic-gate 
37997c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
38009d3d2ed0Shiremath 	ibcm_flow_dec(statep->post_time, "REP");
38019d3d2ed0Shiremath 	ibcm_insert_trace(statep, IBCM_TRACE_REP_POST_COMPLETE);
38027c478bd9Sstevel@tonic-gate 	statep->send_mad_flags &= ~IBCM_REP_POST_BUSY;
38037c478bd9Sstevel@tonic-gate 	if (statep->state == IBCM_STATE_REP_SENT)
38047c478bd9Sstevel@tonic-gate 		statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
38057c478bd9Sstevel@tonic-gate 	IBCM_REF_CNT_DECR(statep);
38067c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
38077c478bd9Sstevel@tonic-gate }
38087c478bd9Sstevel@tonic-gate 
38097c478bd9Sstevel@tonic-gate /*ARGSUSED*/
38107c478bd9Sstevel@tonic-gate void
ibcm_resend_post_rep_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)38117c478bd9Sstevel@tonic-gate ibcm_resend_post_rep_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
38127c478bd9Sstevel@tonic-gate     void *args)
38137c478bd9Sstevel@tonic-gate {
38147c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep = (ibcm_state_data_t *)args;
38157c478bd9Sstevel@tonic-gate 
3816fde3102fShiremath 	IBTF_DPRINTF_L4(cmlog, "ibcm_resend_post_rep_complete(%p)", statep);
38177c478bd9Sstevel@tonic-gate 
38187c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
38199d3d2ed0Shiremath 	ibcm_flow_dec(statep->post_time, "REP_RETRY");
38209d3d2ed0Shiremath 	ibcm_insert_trace(statep, IBCM_TRACE_REP_POST_COMPLETE);
38217c478bd9Sstevel@tonic-gate 	statep->send_mad_flags &= ~IBCM_REP_POST_BUSY;
38227c478bd9Sstevel@tonic-gate 
38237c478bd9Sstevel@tonic-gate 	/* No new timeout is set for resending a REP MAD for an incoming REQ */
38247c478bd9Sstevel@tonic-gate 	IBCM_REF_CNT_DECR(statep);
38257c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
38267c478bd9Sstevel@tonic-gate }
38277c478bd9Sstevel@tonic-gate 
38287c478bd9Sstevel@tonic-gate /*ARGSUSED*/
38297c478bd9Sstevel@tonic-gate void
ibcm_post_mra_rep_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)38307c478bd9Sstevel@tonic-gate ibcm_post_mra_rep_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
38317c478bd9Sstevel@tonic-gate     void *args)
38327c478bd9Sstevel@tonic-gate {
38337c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep = (ibcm_state_data_t *)args;
38347c478bd9Sstevel@tonic-gate 
38357c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_post_mra_rep_complete statep %p", statep);
38367c478bd9Sstevel@tonic-gate 
38377c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
38389d3d2ed0Shiremath 	ibcm_flow_dec(statep->mra_time, "MRA_REP");
38399d3d2ed0Shiremath 	ibcm_insert_trace(statep, IBCM_TRACE_REP_POST_COMPLETE);
38407c478bd9Sstevel@tonic-gate 	if (statep->state == IBCM_STATE_MRA_REP_RCVD)
38417c478bd9Sstevel@tonic-gate 		statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
38427c478bd9Sstevel@tonic-gate 	IBCM_REF_CNT_DECR(statep);
38437c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
38447c478bd9Sstevel@tonic-gate }
38457c478bd9Sstevel@tonic-gate 
38467c478bd9Sstevel@tonic-gate 
38477c478bd9Sstevel@tonic-gate /*ARGSUSED*/
38487c478bd9Sstevel@tonic-gate void
ibcm_post_mra_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)38497c478bd9Sstevel@tonic-gate ibcm_post_mra_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
38507c478bd9Sstevel@tonic-gate     void *args)
38517c478bd9Sstevel@tonic-gate {
38527c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep = (ibcm_state_data_t *)args;
38537c478bd9Sstevel@tonic-gate 
38547c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_post_mra_complete statep %p", statep);
38557c478bd9Sstevel@tonic-gate 
38567c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
38579d3d2ed0Shiremath 	ibcm_flow_dec(statep->mra_time, "MRA");
38589d3d2ed0Shiremath 	ibcm_insert_trace(statep, IBCM_TRACE_MRA_POST_COMPLETE);
38597c478bd9Sstevel@tonic-gate 
38607c478bd9Sstevel@tonic-gate 	if (statep->delete_mra_msg == B_TRUE) {
38617c478bd9Sstevel@tonic-gate 		ibmf_msg_t	*mra_msg;
38627c478bd9Sstevel@tonic-gate 
38637c478bd9Sstevel@tonic-gate 		mra_msg = statep->mra_msg;
38647c478bd9Sstevel@tonic-gate 		statep->mra_msg = NULL;
38657c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
38667c478bd9Sstevel@tonic-gate 		(void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl,
38677c478bd9Sstevel@tonic-gate 		    &mra_msg);
38687c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
38697c478bd9Sstevel@tonic-gate 	}
38707c478bd9Sstevel@tonic-gate 	statep->send_mad_flags &= ~IBCM_MRA_POST_BUSY;
38717c478bd9Sstevel@tonic-gate 	IBCM_REF_CNT_DECR(statep);
38727c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
38737c478bd9Sstevel@tonic-gate }
38747c478bd9Sstevel@tonic-gate 
38757c478bd9Sstevel@tonic-gate /*ARGSUSED*/
38767c478bd9Sstevel@tonic-gate void
ibcm_post_dreq_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)38777c478bd9Sstevel@tonic-gate ibcm_post_dreq_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, void *args)
38787c478bd9Sstevel@tonic-gate {
38797c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep = (ibcm_state_data_t *)args;
38807c478bd9Sstevel@tonic-gate 
38817c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_post_dreq_complete statep %p", statep);
38827c478bd9Sstevel@tonic-gate 
38837c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
38849d3d2ed0Shiremath 	ibcm_flow_dec(statep->post_time, "DREQ");
38859d3d2ed0Shiremath 	ibcm_insert_trace(statep, IBCM_TRACE_DREQ_POST_COMPLETE);
38867c478bd9Sstevel@tonic-gate 	if (statep->state == IBCM_STATE_DREQ_SENT)
38877c478bd9Sstevel@tonic-gate 		statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
38889d3d2ed0Shiremath 	ibcm_close_done(statep, 1);
38897c478bd9Sstevel@tonic-gate 	IBCM_REF_CNT_DECR(statep);
38907c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
38917c478bd9Sstevel@tonic-gate }
38927c478bd9Sstevel@tonic-gate 
38937c478bd9Sstevel@tonic-gate /*ARGSUSED*/
38947c478bd9Sstevel@tonic-gate void
ibcm_post_lap_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)38957c478bd9Sstevel@tonic-gate ibcm_post_lap_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, void *args)
38967c478bd9Sstevel@tonic-gate {
38977c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep = (ibcm_state_data_t *)args;
38987c478bd9Sstevel@tonic-gate 
38997c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_post_lap_complete statep %p", statep);
39007c478bd9Sstevel@tonic-gate 
39017c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
39029d3d2ed0Shiremath 	ibcm_flow_dec(statep->post_time, "LAP");
39039d3d2ed0Shiremath 	ibcm_insert_trace(statep, IBCM_TRACE_LAP_POST_COMPLETE);
39047c478bd9Sstevel@tonic-gate 	if (statep->ap_state == IBCM_AP_STATE_LAP_SENT)
39057c478bd9Sstevel@tonic-gate 		statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
39067c478bd9Sstevel@tonic-gate 	IBCM_REF_CNT_DECR(statep);
39077c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
39087c478bd9Sstevel@tonic-gate }
39097c478bd9Sstevel@tonic-gate 
39107c478bd9Sstevel@tonic-gate /*ARGSUSED*/
39117c478bd9Sstevel@tonic-gate void
ibcm_post_mra_lap_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)39127c478bd9Sstevel@tonic-gate ibcm_post_mra_lap_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
39137c478bd9Sstevel@tonic-gate     void *args)
39147c478bd9Sstevel@tonic-gate {
39157c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep = (ibcm_state_data_t *)args;
39167c478bd9Sstevel@tonic-gate 
39177c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_post_mra_lap_complete statep %p", statep);
39187c478bd9Sstevel@tonic-gate 
39197c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
39209d3d2ed0Shiremath 	ibcm_flow_dec(statep->mra_time, "MRA_LAP");
39219d3d2ed0Shiremath 	ibcm_insert_trace(statep, IBCM_TRACE_LAP_POST_COMPLETE);
39227c478bd9Sstevel@tonic-gate 	if (statep->ap_state == IBCM_AP_STATE_MRA_LAP_RCVD)
39237c478bd9Sstevel@tonic-gate 		statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
39247c478bd9Sstevel@tonic-gate 	IBCM_REF_CNT_DECR(statep);
39257c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
39267c478bd9Sstevel@tonic-gate }
39277c478bd9Sstevel@tonic-gate 
39287c478bd9Sstevel@tonic-gate /*ARGSUSED*/
39297c478bd9Sstevel@tonic-gate void
ibcm_post_rej_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)39307c478bd9Sstevel@tonic-gate ibcm_post_rej_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
39317c478bd9Sstevel@tonic-gate     void *args)
39327c478bd9Sstevel@tonic-gate {
39337c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep = (ibcm_state_data_t *)args;
39347c478bd9Sstevel@tonic-gate 
39357c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_post_rej_complete statep %p", statep);
39367c478bd9Sstevel@tonic-gate 
39377c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
39389d3d2ed0Shiremath 	ibcm_flow_dec(statep->post_time, "REJ");
39399d3d2ed0Shiremath 	ibcm_insert_trace(statep, IBCM_TRACE_REJ_POST_COMPLETE);
39407c478bd9Sstevel@tonic-gate 	statep->send_mad_flags &= ~IBCM_REJ_POST_BUSY;
39417c478bd9Sstevel@tonic-gate 	if (statep->state == IBCM_STATE_REJ_SENT) {
39427c478bd9Sstevel@tonic-gate 		statep->remaining_retry_cnt = 0;
39437c478bd9Sstevel@tonic-gate 
39447c478bd9Sstevel@tonic-gate 		/* wait until all possible retransmits of REQ/REP happened */
39457c478bd9Sstevel@tonic-gate 		statep->timerid = IBCM_TIMEOUT(statep,
39467c478bd9Sstevel@tonic-gate 		    statep->timer_value * statep->max_cm_retries);
39477c478bd9Sstevel@tonic-gate 	}
39487c478bd9Sstevel@tonic-gate 
39497c478bd9Sstevel@tonic-gate 	IBCM_REF_CNT_DECR(statep);
39507c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
39517c478bd9Sstevel@tonic-gate }
39527c478bd9Sstevel@tonic-gate 
39537c478bd9Sstevel@tonic-gate /*ARGSUSED*/
39547c478bd9Sstevel@tonic-gate void
ibcm_post_rtu_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)39557c478bd9Sstevel@tonic-gate ibcm_post_rtu_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
39567c478bd9Sstevel@tonic-gate     void *args)
39577c478bd9Sstevel@tonic-gate {
39587c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep = (ibcm_state_data_t *)args;
39597c478bd9Sstevel@tonic-gate 
39607c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_post_rtu_complete statep %p", statep);
39617c478bd9Sstevel@tonic-gate 
39627c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
39639d3d2ed0Shiremath 	ibcm_flow_dec(statep->post_time, "RTU");
39649d3d2ed0Shiremath 	ibcm_insert_trace(statep, IBCM_TRACE_RTU_POST_COMPLETE);
39657c478bd9Sstevel@tonic-gate 	statep->send_mad_flags &= ~IBCM_RTU_POST_BUSY;
39667c478bd9Sstevel@tonic-gate 	IBCM_REF_CNT_DECR(statep);
39679d3d2ed0Shiremath 	ibcm_open_done(statep);
39687c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
39697c478bd9Sstevel@tonic-gate }
39707c478bd9Sstevel@tonic-gate 
39717c478bd9Sstevel@tonic-gate /*ARGSUSED*/
39727c478bd9Sstevel@tonic-gate void
ibcm_post_apr_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)39737c478bd9Sstevel@tonic-gate ibcm_post_apr_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
39747c478bd9Sstevel@tonic-gate     void *args)
39757c478bd9Sstevel@tonic-gate {
39767c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep = (ibcm_state_data_t *)args;
39777c478bd9Sstevel@tonic-gate 
39787c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_post_apr_complete statep %p", statep);
39797c478bd9Sstevel@tonic-gate 
39809d3d2ed0Shiremath 	mutex_enter(&statep->state_mutex);
39819d3d2ed0Shiremath 	ibcm_flow_dec(statep->post_time, "APR");
39827c478bd9Sstevel@tonic-gate 	ibcm_insert_trace(statep, IBCM_TRACE_APR_POST_COMPLETE);
39837c478bd9Sstevel@tonic-gate 	/* As long as one APR mad in transit, no retransmits are allowed */
39847c478bd9Sstevel@tonic-gate 	statep->ap_state = IBCM_AP_STATE_IDLE;
39857c478bd9Sstevel@tonic-gate 
39867c478bd9Sstevel@tonic-gate 	/* unblock any DREQ threads and close channels */
39877c478bd9Sstevel@tonic-gate 	cv_broadcast(&statep->block_mad_cv);
39887c478bd9Sstevel@tonic-gate 	IBCM_REF_CNT_DECR(statep); /* decrement the ref count */
39897c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
39907c478bd9Sstevel@tonic-gate 
39917c478bd9Sstevel@tonic-gate }
39927c478bd9Sstevel@tonic-gate 
39937c478bd9Sstevel@tonic-gate /*ARGSUSED*/
39947c478bd9Sstevel@tonic-gate void
ibcm_post_stored_apr_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)39957c478bd9Sstevel@tonic-gate ibcm_post_stored_apr_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
39967c478bd9Sstevel@tonic-gate     void *args)
39977c478bd9Sstevel@tonic-gate {
39987c478bd9Sstevel@tonic-gate 	ibmf_msg_t	*ibmf_apr_msg = (ibmf_msg_t *)args;
39997c478bd9Sstevel@tonic-gate 
40007c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_post_stored_apr_complete args %p", args);
40017c478bd9Sstevel@tonic-gate 
40029d3d2ed0Shiremath 	ibcm_flow_dec(0, "APR_RESEND");
40037c478bd9Sstevel@tonic-gate 	(void) ibcm_free_out_msg(ibmf_handle, &ibmf_apr_msg);
40047c478bd9Sstevel@tonic-gate }
40057c478bd9Sstevel@tonic-gate 
40067c478bd9Sstevel@tonic-gate /*ARGSUSED*/
40077c478bd9Sstevel@tonic-gate void
ibcm_post_drep_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)40087c478bd9Sstevel@tonic-gate ibcm_post_drep_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
40097c478bd9Sstevel@tonic-gate     void *args)
40107c478bd9Sstevel@tonic-gate {
40117c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep = (ibcm_state_data_t *)args;
40127c478bd9Sstevel@tonic-gate 
40137c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_post_drep_complete statep %p", statep);
40147c478bd9Sstevel@tonic-gate 
40157c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
40169d3d2ed0Shiremath 	ibcm_flow_dec(statep->post_time, "DREP");
40179d3d2ed0Shiremath 	ibcm_insert_trace(statep, IBCM_TRACE_DREP_POST_COMPLETE);
40187c478bd9Sstevel@tonic-gate 	statep->send_mad_flags &= ~IBCM_REJ_POST_BUSY;
40197c478bd9Sstevel@tonic-gate 
40207c478bd9Sstevel@tonic-gate 	if (statep->state == IBCM_STATE_DREQ_RCVD) {
40217c478bd9Sstevel@tonic-gate 
40229d3d2ed0Shiremath 		ibcm_close_done(statep, 1);
40237c478bd9Sstevel@tonic-gate 		statep->state = IBCM_STATE_TIMEWAIT;
40247c478bd9Sstevel@tonic-gate 
40257c478bd9Sstevel@tonic-gate 		/*
40267c478bd9Sstevel@tonic-gate 		 * For passive side CM set it to remote_ack_delay
40277c478bd9Sstevel@tonic-gate 		 * For active side CM add the pkt_life_time * 2
40287c478bd9Sstevel@tonic-gate 		 */
40297c478bd9Sstevel@tonic-gate 		statep->timer_value = statep->remote_ack_delay;
40307c478bd9Sstevel@tonic-gate 		if (statep->mode == IBCM_ACTIVE_MODE)
40317c478bd9Sstevel@tonic-gate 			statep->timer_value += (2 * statep->pkt_life_time);
40327c478bd9Sstevel@tonic-gate 		statep->remaining_retry_cnt = 0;
40337c478bd9Sstevel@tonic-gate 		statep->timer_stored_state = statep->state;
40347c478bd9Sstevel@tonic-gate 		statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
40357c478bd9Sstevel@tonic-gate 	}
40367c478bd9Sstevel@tonic-gate 
40377c478bd9Sstevel@tonic-gate 	IBCM_REF_CNT_DECR(statep);
40387c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
40397c478bd9Sstevel@tonic-gate }
40407c478bd9Sstevel@tonic-gate 
40417c478bd9Sstevel@tonic-gate /*ARGSUSED*/
40427c478bd9Sstevel@tonic-gate void
ibcm_post_sidr_rep_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)40437c478bd9Sstevel@tonic-gate ibcm_post_sidr_rep_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
40447c478bd9Sstevel@tonic-gate     void *args)
40457c478bd9Sstevel@tonic-gate {
40467c478bd9Sstevel@tonic-gate 	ibcm_ud_state_data_t	*ud_statep = (ibcm_ud_state_data_t *)args;
40477c478bd9Sstevel@tonic-gate 
40487c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_post_sidr_rep_complete ud_statep %p",
40497c478bd9Sstevel@tonic-gate 	    ud_statep);
40507c478bd9Sstevel@tonic-gate 
40519d3d2ed0Shiremath 	ibcm_flow_dec(0, "SIDR_REP");
40527c478bd9Sstevel@tonic-gate 	mutex_enter(&ud_statep->ud_state_mutex);
40537c478bd9Sstevel@tonic-gate 	ud_statep->ud_send_mad_flags &= ~IBCM_SREP_POST_BUSY;
40547c478bd9Sstevel@tonic-gate 	ud_statep->ud_remaining_retry_cnt = 0;
40557c478bd9Sstevel@tonic-gate 	if (ud_statep->ud_state == IBCM_STATE_SIDR_REP_SENT)
40567c478bd9Sstevel@tonic-gate 		ud_statep->ud_timerid = IBCM_UD_TIMEOUT(ud_statep,
40577c478bd9Sstevel@tonic-gate 		    ud_statep->ud_timer_value);
40587c478bd9Sstevel@tonic-gate 	IBCM_UD_REF_CNT_DECR(ud_statep);
40597c478bd9Sstevel@tonic-gate 	mutex_exit(&ud_statep->ud_state_mutex);
40607c478bd9Sstevel@tonic-gate 
40617c478bd9Sstevel@tonic-gate }
40627c478bd9Sstevel@tonic-gate 
40637c478bd9Sstevel@tonic-gate /*ARGSUSED*/
40647c478bd9Sstevel@tonic-gate void
ibcm_post_sidr_req_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)40657c478bd9Sstevel@tonic-gate ibcm_post_sidr_req_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
40667c478bd9Sstevel@tonic-gate     void *args)
40677c478bd9Sstevel@tonic-gate {
40687c478bd9Sstevel@tonic-gate 	ibcm_ud_state_data_t	*ud_statep = (ibcm_ud_state_data_t *)args;
40697c478bd9Sstevel@tonic-gate 
40707c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_post_sidr_req_complete ud_statep %p",
40717c478bd9Sstevel@tonic-gate 	    ud_statep);
40727c478bd9Sstevel@tonic-gate 
40739d3d2ed0Shiremath 	ibcm_flow_dec(0, "SIDR_REQ");
40747c478bd9Sstevel@tonic-gate 	mutex_enter(&ud_statep->ud_state_mutex);
40757c478bd9Sstevel@tonic-gate 	if (ud_statep->ud_state == IBCM_STATE_SIDR_REQ_SENT)
40767c478bd9Sstevel@tonic-gate 		ud_statep->ud_timerid = IBCM_UD_TIMEOUT(ud_statep,
40777c478bd9Sstevel@tonic-gate 		    ud_statep->ud_timer_value);
40787c478bd9Sstevel@tonic-gate 	IBCM_UD_REF_CNT_DECR(ud_statep);
40797c478bd9Sstevel@tonic-gate 	mutex_exit(&ud_statep->ud_state_mutex);
40807c478bd9Sstevel@tonic-gate 
40817c478bd9Sstevel@tonic-gate }
40827c478bd9Sstevel@tonic-gate 
40837c478bd9Sstevel@tonic-gate /*
40847c478bd9Sstevel@tonic-gate  * ibcm_process_dreq_timeout:
40857c478bd9Sstevel@tonic-gate  *	Called when the timer expires on DREP
40867c478bd9Sstevel@tonic-gate  *
40877c478bd9Sstevel@tonic-gate  * INPUTS:
40887c478bd9Sstevel@tonic-gate  *	arg	- ibcm_state_data_t is passed
40897c478bd9Sstevel@tonic-gate  *
40907c478bd9Sstevel@tonic-gate  * RETURN VALUES: NONE
40917c478bd9Sstevel@tonic-gate  */
40927c478bd9Sstevel@tonic-gate void
ibcm_process_dreq_timeout(ibcm_state_data_t * statep)40937c478bd9Sstevel@tonic-gate ibcm_process_dreq_timeout(ibcm_state_data_t *statep)
40947c478bd9Sstevel@tonic-gate {
40957c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
40967c478bd9Sstevel@tonic-gate 
40977c478bd9Sstevel@tonic-gate 	/* Max retries reached, move to the time wait state */
40987c478bd9Sstevel@tonic-gate 	statep->state = statep->timer_stored_state =
40997c478bd9Sstevel@tonic-gate 	    IBCM_STATE_TIMEWAIT;
41009d3d2ed0Shiremath 	ibcm_close_done(statep, 0);
41017c478bd9Sstevel@tonic-gate 
41027c478bd9Sstevel@tonic-gate 	/* Set the TIME_WAIT state timer value */
41037c478bd9Sstevel@tonic-gate 	statep->timer_value = statep->remote_ack_delay;
41047c478bd9Sstevel@tonic-gate 	if (statep->mode == IBCM_ACTIVE_MODE) {
41057c478bd9Sstevel@tonic-gate 		statep->timer_value += (2 * statep->pkt_life_time);
41067c478bd9Sstevel@tonic-gate 	}
41077c478bd9Sstevel@tonic-gate 
41087c478bd9Sstevel@tonic-gate 	statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
41097c478bd9Sstevel@tonic-gate 
41107c478bd9Sstevel@tonic-gate 	if (statep->close_ret_status)
41117c478bd9Sstevel@tonic-gate 		if (statep->stale == B_TRUE)
41127c478bd9Sstevel@tonic-gate 			*statep->close_ret_status = IBT_CM_CLOSED_STALE;
41137c478bd9Sstevel@tonic-gate 		else *statep->close_ret_status = IBT_CM_CLOSED_DREQ_TIMEOUT;
41147c478bd9Sstevel@tonic-gate 
41157c478bd9Sstevel@tonic-gate 	/* signal waiting CVs - blocking in ibt_close_channel() */
41167c478bd9Sstevel@tonic-gate 	statep->close_done = B_TRUE;
4117934f0bccShiremath 	if (statep->close_ret_priv_data_len != NULL)
4118934f0bccShiremath 		*statep->close_ret_priv_data_len = 0;
41197c478bd9Sstevel@tonic-gate 
41207c478bd9Sstevel@tonic-gate 	/* unblock any close channel with no callbacks option */
41217c478bd9Sstevel@tonic-gate 	statep->close_nocb_state = IBCM_FAIL;
41227c478bd9Sstevel@tonic-gate 
41237c478bd9Sstevel@tonic-gate 	cv_broadcast(&statep->block_client_cv);
41247c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
41257c478bd9Sstevel@tonic-gate }
41267c478bd9Sstevel@tonic-gate 
41277c478bd9Sstevel@tonic-gate /*
41287c478bd9Sstevel@tonic-gate  * ibcm_add_tlist:
41297c478bd9Sstevel@tonic-gate  *	Adds the given RC statep to timeout list
41307c478bd9Sstevel@tonic-gate  *
41317c478bd9Sstevel@tonic-gate  * INPUTS:
41327c478bd9Sstevel@tonic-gate  *	arg	- ibcm_state_data_t is passed
41337c478bd9Sstevel@tonic-gate  *
41347c478bd9Sstevel@tonic-gate  * RETURN VALUES: NONE
41357c478bd9Sstevel@tonic-gate  */
41367c478bd9Sstevel@tonic-gate void
ibcm_add_tlist(ibcm_state_data_t * statep)41377c478bd9Sstevel@tonic-gate ibcm_add_tlist(ibcm_state_data_t *statep)
41387c478bd9Sstevel@tonic-gate {
41397c478bd9Sstevel@tonic-gate 	mutex_enter(&ibcm_timeout_list_lock);
41407c478bd9Sstevel@tonic-gate 
41417c478bd9Sstevel@tonic-gate 	statep->timeout_next = NULL;
41427c478bd9Sstevel@tonic-gate 	if (ibcm_timeout_list_hdr == NULL) {
41437c478bd9Sstevel@tonic-gate 		ibcm_timeout_list_hdr = statep;
41447c478bd9Sstevel@tonic-gate 	} else {
41457c478bd9Sstevel@tonic-gate 		ibcm_timeout_list_tail->timeout_next = statep;
41467c478bd9Sstevel@tonic-gate 	}
41477c478bd9Sstevel@tonic-gate 
41487c478bd9Sstevel@tonic-gate 	ibcm_timeout_list_tail = statep;
41497c478bd9Sstevel@tonic-gate 
41507c478bd9Sstevel@tonic-gate 	cv_signal(&ibcm_timeout_list_cv);
41517c478bd9Sstevel@tonic-gate 
41527c478bd9Sstevel@tonic-gate 	mutex_exit(&ibcm_timeout_list_lock);
41537c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(cmlog, "ibcm_add_tlist: "
41547c478bd9Sstevel@tonic-gate 	    "attached state = %p to timeout list", statep);
41557c478bd9Sstevel@tonic-gate }
41567c478bd9Sstevel@tonic-gate 
41579d3d2ed0Shiremath void
ibcm_run_tlist_thread(void)41589d3d2ed0Shiremath ibcm_run_tlist_thread(void)
41599d3d2ed0Shiremath {
41609d3d2ed0Shiremath 	mutex_enter(&ibcm_timeout_list_lock);
41619d3d2ed0Shiremath 	cv_signal(&ibcm_timeout_list_cv);
41629d3d2ed0Shiremath 	mutex_exit(&ibcm_timeout_list_lock);
41639d3d2ed0Shiremath }
41647c478bd9Sstevel@tonic-gate 
41657c478bd9Sstevel@tonic-gate /*
41667c478bd9Sstevel@tonic-gate  * ibcm_add_ud_tlist:
41677c478bd9Sstevel@tonic-gate  *	Adds the given UD statep to timeout list
41687c478bd9Sstevel@tonic-gate  *
41697c478bd9Sstevel@tonic-gate  * INPUTS:
41707c478bd9Sstevel@tonic-gate  *	arg	- ibcm_ud_state_data_t is passed
41717c478bd9Sstevel@tonic-gate  *
41727c478bd9Sstevel@tonic-gate  * RETURN VALUES: NONE
41737c478bd9Sstevel@tonic-gate  */
41747c478bd9Sstevel@tonic-gate void
ibcm_add_ud_tlist(ibcm_ud_state_data_t * ud_statep)41757c478bd9Sstevel@tonic-gate ibcm_add_ud_tlist(ibcm_ud_state_data_t *ud_statep)
41767c478bd9Sstevel@tonic-gate {
41777c478bd9Sstevel@tonic-gate 	mutex_enter(&ibcm_timeout_list_lock);
41787c478bd9Sstevel@tonic-gate 
41797c478bd9Sstevel@tonic-gate 	ud_statep->ud_timeout_next = NULL;
41807c478bd9Sstevel@tonic-gate 	if (ibcm_ud_timeout_list_hdr == NULL) {
41817c478bd9Sstevel@tonic-gate 		ibcm_ud_timeout_list_hdr = ud_statep;
41827c478bd9Sstevel@tonic-gate 	} else {
41837c478bd9Sstevel@tonic-gate 		ibcm_ud_timeout_list_tail->ud_timeout_next = ud_statep;
41847c478bd9Sstevel@tonic-gate 	}
41857c478bd9Sstevel@tonic-gate 
41867c478bd9Sstevel@tonic-gate 	ibcm_ud_timeout_list_tail = ud_statep;
41877c478bd9Sstevel@tonic-gate 
41887c478bd9Sstevel@tonic-gate 	cv_signal(&ibcm_timeout_list_cv);
41897c478bd9Sstevel@tonic-gate 
41907c478bd9Sstevel@tonic-gate 	mutex_exit(&ibcm_timeout_list_lock);
41917c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(cmlog, "ibcm_add_ud_tlist: "
41927c478bd9Sstevel@tonic-gate 	    "attached state = %p to ud timeout list", ud_statep);
41937c478bd9Sstevel@tonic-gate }
41947c478bd9Sstevel@tonic-gate 
41957c478bd9Sstevel@tonic-gate /*
41967c478bd9Sstevel@tonic-gate  * ibcm_process_tlist:
41977c478bd9Sstevel@tonic-gate  *	Thread that processes all the RC and UD statep's from
41987c478bd9Sstevel@tonic-gate  *	the appropriate lists
41997c478bd9Sstevel@tonic-gate  *
42007c478bd9Sstevel@tonic-gate  * INPUTS:
42017c478bd9Sstevel@tonic-gate  *	NONE
42027c478bd9Sstevel@tonic-gate  *
42037c478bd9Sstevel@tonic-gate  * RETURN VALUES: NONE
42047c478bd9Sstevel@tonic-gate  */
42057c478bd9Sstevel@tonic-gate void
ibcm_process_tlist()42067c478bd9Sstevel@tonic-gate ibcm_process_tlist()
42077c478bd9Sstevel@tonic-gate {
4208*f248c5e0SToomas Soome 	ibcm_state_data_t	*statep;
4209*f248c5e0SToomas Soome 	ibcm_ud_state_data_t	*ud_statep;
42107c478bd9Sstevel@tonic-gate 	callb_cpr_t		cprinfo;
42117c478bd9Sstevel@tonic-gate 
42127c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "ibcm_process_tlist: thread started");
42137c478bd9Sstevel@tonic-gate 
42147c478bd9Sstevel@tonic-gate 	mutex_enter(&ibcm_timeout_list_lock);
42157c478bd9Sstevel@tonic-gate 
42167c478bd9Sstevel@tonic-gate 	CALLB_CPR_INIT(&cprinfo, &ibcm_timeout_list_lock, callb_generic_cpr,
42177c478bd9Sstevel@tonic-gate 	    "ibcm_process_tlist");
42187c478bd9Sstevel@tonic-gate 
42197c478bd9Sstevel@tonic-gate 	for (;;) {
42207c478bd9Sstevel@tonic-gate 		if (ibcm_timeout_list_flags & IBCM_TIMEOUT_THREAD_EXIT) {
42217c478bd9Sstevel@tonic-gate 			/* The thread needs to exit */
42227c478bd9Sstevel@tonic-gate 			cv_signal(&ibcm_timeout_thread_done_cv);
42237c478bd9Sstevel@tonic-gate 			break;
42247c478bd9Sstevel@tonic-gate 		}
42259d3d2ed0Shiremath 		mutex_exit(&ibcm_timeout_list_lock);
42269d3d2ed0Shiremath 		ibcm_check_for_opens();
4227934f0bccShiremath 		ibcm_check_for_async_close();
42289d3d2ed0Shiremath 		mutex_enter(&ibcm_timeout_list_lock);
42297c478bd9Sstevel@tonic-gate 
42307c478bd9Sstevel@tonic-gate 		/* First, handle pending RC statep's, followed by UD's */
42317c478bd9Sstevel@tonic-gate 		if (ibcm_timeout_list_hdr != NULL) {
42327c478bd9Sstevel@tonic-gate 			statep = ibcm_timeout_list_hdr;
42337c478bd9Sstevel@tonic-gate 			ibcm_timeout_list_hdr = statep->timeout_next;
42347c478bd9Sstevel@tonic-gate 
42357c478bd9Sstevel@tonic-gate 			if (ibcm_timeout_list_hdr == NULL)
4236015f8fffShiremath 				ibcm_timeout_list_tail = NULL;
42377c478bd9Sstevel@tonic-gate 
42387c478bd9Sstevel@tonic-gate 			statep->timeout_next = NULL;
42397c478bd9Sstevel@tonic-gate 
42407c478bd9Sstevel@tonic-gate 			mutex_exit(&ibcm_timeout_list_lock);
42417c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L3(cmlog, "ibcm_process_tlist: "
42427c478bd9Sstevel@tonic-gate 			    "scheduling state = %p", statep);
42437c478bd9Sstevel@tonic-gate 			ibcm_timeout_client_cb(statep);
42447c478bd9Sstevel@tonic-gate 			mutex_enter(&ibcm_timeout_list_lock);
42457c478bd9Sstevel@tonic-gate 		} else if (ibcm_ud_timeout_list_hdr != NULL) {
42467c478bd9Sstevel@tonic-gate 			ud_statep = ibcm_ud_timeout_list_hdr;
42477c478bd9Sstevel@tonic-gate 			ibcm_ud_timeout_list_hdr = ud_statep->ud_timeout_next;
42487c478bd9Sstevel@tonic-gate 
42497c478bd9Sstevel@tonic-gate 			if (ibcm_ud_timeout_list_hdr == NULL)
4250015f8fffShiremath 				ibcm_ud_timeout_list_tail = NULL;
42517c478bd9Sstevel@tonic-gate 
42527c478bd9Sstevel@tonic-gate 			ud_statep->ud_timeout_next = NULL;
42537c478bd9Sstevel@tonic-gate 
42547c478bd9Sstevel@tonic-gate 			mutex_exit(&ibcm_timeout_list_lock);
42557c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L3(cmlog, "ibcm_process_tlist: "
42567c478bd9Sstevel@tonic-gate 			    "ud scheduling state = %p", ud_statep);
42577c478bd9Sstevel@tonic-gate 			ibcm_ud_timeout_client_cb(ud_statep);
42587c478bd9Sstevel@tonic-gate 			mutex_enter(&ibcm_timeout_list_lock);
42597c478bd9Sstevel@tonic-gate 		} else {
42607c478bd9Sstevel@tonic-gate 			CALLB_CPR_SAFE_BEGIN(&cprinfo);
42617c478bd9Sstevel@tonic-gate 			cv_wait(&ibcm_timeout_list_cv, &ibcm_timeout_list_lock);
42627c478bd9Sstevel@tonic-gate 			CALLB_CPR_SAFE_END(&cprinfo, &ibcm_timeout_list_lock);
42637c478bd9Sstevel@tonic-gate 		}
42647c478bd9Sstevel@tonic-gate 	}
42657c478bd9Sstevel@tonic-gate 
42667c478bd9Sstevel@tonic-gate #ifndef	__lock_lint
42677c478bd9Sstevel@tonic-gate 	CALLB_CPR_EXIT(&cprinfo);	/* mutex_exit */
42687c478bd9Sstevel@tonic-gate #endif
42697c478bd9Sstevel@tonic-gate }
42707c478bd9Sstevel@tonic-gate 
42717c478bd9Sstevel@tonic-gate 
42727c478bd9Sstevel@tonic-gate /*
42737c478bd9Sstevel@tonic-gate  * ibcm_timeout_client_cb:
42747c478bd9Sstevel@tonic-gate  *	Called from timeout thread processing
42757c478bd9Sstevel@tonic-gate  *	Primary purpose is to call client handler
42767c478bd9Sstevel@tonic-gate  *
42777c478bd9Sstevel@tonic-gate  * INPUTS:
42787c478bd9Sstevel@tonic-gate  *	arg	- ibcm_state_data_t is passed
42797c478bd9Sstevel@tonic-gate  *
42807c478bd9Sstevel@tonic-gate  * RETURN VALUES: NONE
42817c478bd9Sstevel@tonic-gate  */
42827c478bd9Sstevel@tonic-gate void
ibcm_timeout_client_cb(ibcm_state_data_t * statep)42837c478bd9Sstevel@tonic-gate ibcm_timeout_client_cb(ibcm_state_data_t *statep)
42847c478bd9Sstevel@tonic-gate {
42857c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
42867c478bd9Sstevel@tonic-gate 
42877c478bd9Sstevel@tonic-gate 	if ((statep->state == IBCM_STATE_DELETE) &&
42887c478bd9Sstevel@tonic-gate 	    (statep->recycle_arg != NULL)) {
42897c478bd9Sstevel@tonic-gate 		struct ibcm_taskq_recycle_arg_s *recycle_arg;
42907c478bd9Sstevel@tonic-gate 
42917c478bd9Sstevel@tonic-gate 		recycle_arg = statep->recycle_arg;
42927c478bd9Sstevel@tonic-gate 		_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(statep->recycle_arg))
42937c478bd9Sstevel@tonic-gate 		statep->recycle_arg = NULL;
42947c478bd9Sstevel@tonic-gate 		_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(statep->recycle_arg))
42957c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
42967c478bd9Sstevel@tonic-gate 		(void) ibcm_process_rc_recycle(recycle_arg);
42977c478bd9Sstevel@tonic-gate 		ibcm_delete_state_data(statep);
42987c478bd9Sstevel@tonic-gate 		return;
42997c478bd9Sstevel@tonic-gate 	}
43007c478bd9Sstevel@tonic-gate 
43017c478bd9Sstevel@tonic-gate 	if ((statep->state == IBCM_STATE_DELETE) &&
43027c478bd9Sstevel@tonic-gate 	    (statep->delete_state_data == B_TRUE)) {
43037c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
43047c478bd9Sstevel@tonic-gate 		ibcm_dealloc_state_data(statep);
43057c478bd9Sstevel@tonic-gate 		return;
43067c478bd9Sstevel@tonic-gate 	}
43077c478bd9Sstevel@tonic-gate 
43087c478bd9Sstevel@tonic-gate 	/* Else, it must be in TIMEOUT state, do the necessary processing */
43097c478bd9Sstevel@tonic-gate 	if (statep->state == IBCM_STATE_TIMED_OUT) {
43107c478bd9Sstevel@tonic-gate 		void		*data;
43117c478bd9Sstevel@tonic-gate 		uint8_t		cf_msg;
43127c478bd9Sstevel@tonic-gate 		ib_guid_t	local_hca_guid;
43137c478bd9Sstevel@tonic-gate 
43147c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
43157c478bd9Sstevel@tonic-gate 
43167c478bd9Sstevel@tonic-gate 		if (statep->timedout_state == IBCM_STATE_DREQ_SENT) {
43177c478bd9Sstevel@tonic-gate 			ibt_cm_event_t		event;
43187c478bd9Sstevel@tonic-gate 			ibt_cm_return_args_t	ret_args;
43197c478bd9Sstevel@tonic-gate 
43207c478bd9Sstevel@tonic-gate 			bzero(&event, sizeof (event));
43217c478bd9Sstevel@tonic-gate 			bzero(&ret_args, sizeof (ret_args));
43227c478bd9Sstevel@tonic-gate 
43237c478bd9Sstevel@tonic-gate 			event.cm_type = IBT_CM_EVENT_CONN_CLOSED;
43247c478bd9Sstevel@tonic-gate 			event.cm_channel = statep->channel;
43257c478bd9Sstevel@tonic-gate 			event.cm_session_id = NULL;
43267c478bd9Sstevel@tonic-gate 			event.cm_priv_data = NULL;
43277c478bd9Sstevel@tonic-gate 			event.cm_priv_data_len = 0;
43287c478bd9Sstevel@tonic-gate 
43297c478bd9Sstevel@tonic-gate 			if (statep->stale == B_TRUE)
43307c478bd9Sstevel@tonic-gate 				event.cm_event.closed = IBT_CM_CLOSED_STALE;
43317c478bd9Sstevel@tonic-gate 			else event.cm_event.closed = IBT_CM_CLOSED_DREQ_TIMEOUT;
43327c478bd9Sstevel@tonic-gate 
43337c478bd9Sstevel@tonic-gate 			/*
43347c478bd9Sstevel@tonic-gate 			 * cm handler cannot be non-NULL, as that check is
43357c478bd9Sstevel@tonic-gate 			 * already made in ibcm_timeout_cb
43367c478bd9Sstevel@tonic-gate 			 */
43377c478bd9Sstevel@tonic-gate 			ibcm_insert_trace(statep,
43387c478bd9Sstevel@tonic-gate 			    IBCM_TRACE_CALLED_CONN_CLOSE_EVENT);
43397c478bd9Sstevel@tonic-gate 
43407c478bd9Sstevel@tonic-gate 			(void) statep->cm_handler(statep->state_cm_private,
43417c478bd9Sstevel@tonic-gate 			    &event, &ret_args, NULL, 0);
43427c478bd9Sstevel@tonic-gate 
43437c478bd9Sstevel@tonic-gate 			ibcm_insert_trace(statep,
43447c478bd9Sstevel@tonic-gate 			    IBCM_TRACE_RET_CONN_CLOSE_EVENT);
43457c478bd9Sstevel@tonic-gate 
43467c478bd9Sstevel@tonic-gate 			ibcm_process_dreq_timeout(statep);
43477c478bd9Sstevel@tonic-gate 			return;
43487c478bd9Sstevel@tonic-gate 		}
43497c478bd9Sstevel@tonic-gate 
43507c478bd9Sstevel@tonic-gate 		data = ((ibcm_rej_msg_t *)
43517c478bd9Sstevel@tonic-gate 		    IBCM_OUT_MSGP(statep->stored_msg))->rej_private_data;
43527c478bd9Sstevel@tonic-gate 
43537c478bd9Sstevel@tonic-gate 		if ((statep->timedout_state == IBCM_STATE_REQ_SENT) ||
43547c478bd9Sstevel@tonic-gate 		    (statep->timedout_state == IBCM_STATE_REP_WAIT)) {
43557c478bd9Sstevel@tonic-gate 			cf_msg = IBT_CM_FAILURE_REQ;
43567c478bd9Sstevel@tonic-gate 		} else {
43577c478bd9Sstevel@tonic-gate 			ASSERT(
43587c478bd9Sstevel@tonic-gate 			    (statep->timedout_state == IBCM_STATE_REP_SENT) ||
43597c478bd9Sstevel@tonic-gate 			    (statep->timedout_state ==
43607c478bd9Sstevel@tonic-gate 			    IBCM_STATE_MRA_REP_RCVD));
43617c478bd9Sstevel@tonic-gate 			cf_msg = IBT_CM_FAILURE_REP;
43627c478bd9Sstevel@tonic-gate 		}
43637c478bd9Sstevel@tonic-gate 
43647c478bd9Sstevel@tonic-gate 		/*
43657c478bd9Sstevel@tonic-gate 		 * Invoke the CM handler w/ event IBT_CM_EVENT_TIMEOUT
43667c478bd9Sstevel@tonic-gate 		 * This callback happens for only active non blocking or
43677c478bd9Sstevel@tonic-gate 		 * passive client
43687c478bd9Sstevel@tonic-gate 		 */
43697c478bd9Sstevel@tonic-gate 		ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_TIMEOUT,
43707c478bd9Sstevel@tonic-gate 		    cf_msg, IBT_CM_TIMEOUT, data, IBT_REJ_PRIV_DATA_SZ);
43717c478bd9Sstevel@tonic-gate 
43727c478bd9Sstevel@tonic-gate 		/* signal the blocked ibt_open_rc_channel */
43737c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
43747c478bd9Sstevel@tonic-gate 
43757c478bd9Sstevel@tonic-gate 		/*
43767c478bd9Sstevel@tonic-gate 		 * statep->open_return_data is set for blocking
43777c478bd9Sstevel@tonic-gate 		 * signal the blocked ibt_open_rc_channel
43787c478bd9Sstevel@tonic-gate 		 */
43797c478bd9Sstevel@tonic-gate 		if (statep->open_return_data != NULL) {
43807c478bd9Sstevel@tonic-gate 			statep->open_return_data->rc_status = IBT_CM_TIMEOUT;
43817c478bd9Sstevel@tonic-gate 			statep->open_done = B_TRUE;
43827c478bd9Sstevel@tonic-gate 			cv_broadcast(&statep->block_client_cv);
43837c478bd9Sstevel@tonic-gate 		}
43847c478bd9Sstevel@tonic-gate 
43857c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
43867c478bd9Sstevel@tonic-gate 
43877c478bd9Sstevel@tonic-gate 		local_hca_guid = h2b64(statep->local_hca_guid);
43887c478bd9Sstevel@tonic-gate 		ibcm_post_rej_mad(statep, IBT_CM_TIMEOUT,
43897c478bd9Sstevel@tonic-gate 		    IBT_CM_FAILURE_UNKNOWN, &local_hca_guid,
43907c478bd9Sstevel@tonic-gate 		    sizeof (ib_guid_t));
43917c478bd9Sstevel@tonic-gate 	} else if (statep->ap_state == IBCM_AP_STATE_TIMED_OUT) {
43927c478bd9Sstevel@tonic-gate 
43937c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
43947c478bd9Sstevel@tonic-gate 
43957c478bd9Sstevel@tonic-gate 		ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_TIMEOUT,
43967c478bd9Sstevel@tonic-gate 		    IBT_CM_FAILURE_LAP, IBT_CM_TIMEOUT, NULL, 0);
43977c478bd9Sstevel@tonic-gate 
43987c478bd9Sstevel@tonic-gate 		/* Now wake up threads waiting for LAP/APR to complete */
43997c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
44007c478bd9Sstevel@tonic-gate 		/*
44017c478bd9Sstevel@tonic-gate 		 * statep->ap_return_data is initialized for blocking in
44027c478bd9Sstevel@tonic-gate 		 * ibt_set_alt_path(), signal the waiting CV
44037c478bd9Sstevel@tonic-gate 		 */
44047c478bd9Sstevel@tonic-gate 		if (statep->ap_return_data != NULL) {
44057c478bd9Sstevel@tonic-gate 			statep->ap_return_data->ap_status = IBT_CM_AP_TIMEOUT;
44067c478bd9Sstevel@tonic-gate 			statep->ap_done = B_TRUE;
44077c478bd9Sstevel@tonic-gate 			cv_broadcast(&statep->block_client_cv);
44087c478bd9Sstevel@tonic-gate 		}
44097c478bd9Sstevel@tonic-gate 		statep->ap_state = IBCM_AP_STATE_IDLE;
44107c478bd9Sstevel@tonic-gate 		cv_broadcast(&statep->block_mad_cv);
44117c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
44127c478bd9Sstevel@tonic-gate 	} else {
44137c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_timeout_client_cb "
44147c478bd9Sstevel@tonic-gate 		    "Unexpected else path statep %p state %d ap_state %d",
44157c478bd9Sstevel@tonic-gate 		    statep, statep->state, statep->ap_state);
44167c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
44177c478bd9Sstevel@tonic-gate 
44187c478bd9Sstevel@tonic-gate 	}
44197c478bd9Sstevel@tonic-gate }
44207c478bd9Sstevel@tonic-gate 
44217c478bd9Sstevel@tonic-gate /*
44227c478bd9Sstevel@tonic-gate  * ibcm_ud_timeout_client_cb:
44237c478bd9Sstevel@tonic-gate  *	Called from UD timeout thread processing
44247c478bd9Sstevel@tonic-gate  *	Primary purpose is to call client handler
44257c478bd9Sstevel@tonic-gate  *
44267c478bd9Sstevel@tonic-gate  * INPUTS:
44277c478bd9Sstevel@tonic-gate  *	arg	- ibcm_ud_state_data_t is passed
44287c478bd9Sstevel@tonic-gate  *
44297c478bd9Sstevel@tonic-gate  * RETURN VALUES: NONE
44307c478bd9Sstevel@tonic-gate  */
44317c478bd9Sstevel@tonic-gate void
ibcm_ud_timeout_client_cb(ibcm_ud_state_data_t * ud_statep)44327c478bd9Sstevel@tonic-gate ibcm_ud_timeout_client_cb(ibcm_ud_state_data_t *ud_statep)
44337c478bd9Sstevel@tonic-gate {
44347c478bd9Sstevel@tonic-gate 	ibt_cm_ud_event_t	ud_event;
44357c478bd9Sstevel@tonic-gate 
44367c478bd9Sstevel@tonic-gate 	mutex_enter(&ud_statep->ud_state_mutex);
44377c478bd9Sstevel@tonic-gate 
44387c478bd9Sstevel@tonic-gate 	if ((ud_statep->ud_state == IBCM_STATE_DELETE) &&
44397c478bd9Sstevel@tonic-gate 	    (ud_statep->ud_delete_state_data == B_TRUE)) {
44407c478bd9Sstevel@tonic-gate 
44417c478bd9Sstevel@tonic-gate 		mutex_exit(&ud_statep->ud_state_mutex);
44427c478bd9Sstevel@tonic-gate 		ibcm_dealloc_ud_state_data(ud_statep);
44437c478bd9Sstevel@tonic-gate 		return;
44447c478bd9Sstevel@tonic-gate 	} else
44457c478bd9Sstevel@tonic-gate 		mutex_exit(&ud_statep->ud_state_mutex);
44467c478bd9Sstevel@tonic-gate 
44477c478bd9Sstevel@tonic-gate 	/* Fill in ibt_cm_ud_event_t */
44487c478bd9Sstevel@tonic-gate 	ud_event.cm_type = IBT_CM_UD_EVENT_SIDR_REP;
44497c478bd9Sstevel@tonic-gate 	ud_event.cm_session_id = NULL;
44507c478bd9Sstevel@tonic-gate 	ud_event.cm_event.sidr_rep.srep_status = IBT_CM_SREP_TIMEOUT;
44517c478bd9Sstevel@tonic-gate 
44527c478bd9Sstevel@tonic-gate 	(void) ud_statep->ud_cm_handler(ud_statep->ud_state_cm_private,
44537c478bd9Sstevel@tonic-gate 	    &ud_event, NULL, NULL, 0);
44547c478bd9Sstevel@tonic-gate 
44557c478bd9Sstevel@tonic-gate 	/* Delete UD state data now, finally done with it */
44567c478bd9Sstevel@tonic-gate 	ibcm_delete_ud_state_data(ud_statep);
44577c478bd9Sstevel@tonic-gate }
44587c478bd9Sstevel@tonic-gate 
44597c478bd9Sstevel@tonic-gate 
44607c478bd9Sstevel@tonic-gate /*
44617c478bd9Sstevel@tonic-gate  * ibcm_process_sidr_req_msg:
44627c478bd9Sstevel@tonic-gate  *	This call processes an incoming SIDR REQ
44637c478bd9Sstevel@tonic-gate  *
44647c478bd9Sstevel@tonic-gate  * INPUTS:
44657c478bd9Sstevel@tonic-gate  *	hcap		- HCA entry pointer
44667c478bd9Sstevel@tonic-gate  *	input_madp	- Incoming CM SIDR REQ MAD
44677c478bd9Sstevel@tonic-gate  *	cm_mad_addr	- Address information for the MAD to be posted
44687c478bd9Sstevel@tonic-gate  *
44697c478bd9Sstevel@tonic-gate  * RETURN VALUE:
44707c478bd9Sstevel@tonic-gate  *	NONE
44717c478bd9Sstevel@tonic-gate  */
44727c478bd9Sstevel@tonic-gate void
ibcm_process_sidr_req_msg(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)44737c478bd9Sstevel@tonic-gate ibcm_process_sidr_req_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
44747c478bd9Sstevel@tonic-gate     ibcm_mad_addr_t *cm_mad_addr)
44757c478bd9Sstevel@tonic-gate {
44767c478bd9Sstevel@tonic-gate 	ib_gid_t		gid;
44777c478bd9Sstevel@tonic-gate 	ib_lid_t		lid;
44787c478bd9Sstevel@tonic-gate 	uint32_t		req_id;
44797c478bd9Sstevel@tonic-gate 	ibcm_status_t		state_lookup_status;
44807c478bd9Sstevel@tonic-gate 	ibcm_status_t		cm_status;
44817c478bd9Sstevel@tonic-gate 	ibt_sidr_status_t	sidr_status;
44827c478bd9Sstevel@tonic-gate 	ibcm_svc_info_t		*svc_infop;
44837c478bd9Sstevel@tonic-gate 	ibcm_svc_bind_t		*svc_bindp;
44847c478bd9Sstevel@tonic-gate 	ibcm_svc_bind_t		*tmp_bindp;
44857c478bd9Sstevel@tonic-gate 	ibcm_sidr_req_msg_t	*sidr_reqp = (ibcm_sidr_req_msg_t *)
4486015f8fffShiremath 	    (&input_madp[IBCM_MAD_HDR_SIZE]);
44877c478bd9Sstevel@tonic-gate 	ibcm_ud_state_data_t	*ud_statep = NULL;
44887c478bd9Sstevel@tonic-gate 	ibcm_sidr_srch_t	srch_sidr;
44897c478bd9Sstevel@tonic-gate 	ib_pkey_t		pkey;
44907c478bd9Sstevel@tonic-gate 	uint8_t			port_num;
44917c478bd9Sstevel@tonic-gate 	ib_guid_t		hca_guid;
44927c478bd9Sstevel@tonic-gate 
44937c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_sidr_req_msg:");
44947c478bd9Sstevel@tonic-gate 
44957c478bd9Sstevel@tonic-gate 	hca_guid = hcap->hca_guid;
44967c478bd9Sstevel@tonic-gate 	port_num = cm_mad_addr->port_num;
44977c478bd9Sstevel@tonic-gate 
44987c478bd9Sstevel@tonic-gate 	/* Figure out LID, GID, RequestId for svc_id lookup */
44997c478bd9Sstevel@tonic-gate 	lid = cm_mad_addr->rcvd_addr.ia_remote_lid;
45007c478bd9Sstevel@tonic-gate 	req_id = b2h32(sidr_reqp->sidr_req_request_id);
45017c478bd9Sstevel@tonic-gate 	pkey = b2h16(sidr_reqp->sidr_req_pkey);
45027c478bd9Sstevel@tonic-gate 	if (cm_mad_addr->grh_exists == B_TRUE)
45037c478bd9Sstevel@tonic-gate 		gid = cm_mad_addr->grh_hdr.ig_sender_gid;
45047c478bd9Sstevel@tonic-gate 	else
45057c478bd9Sstevel@tonic-gate 		gid.gid_prefix = gid.gid_guid = 0;
45067c478bd9Sstevel@tonic-gate 
45077c478bd9Sstevel@tonic-gate 	/*
45087c478bd9Sstevel@tonic-gate 	 * Lookup for an existing state structure
45097c478bd9Sstevel@tonic-gate 	 * - if lookup fails it creates a new ud_state struct
45107c478bd9Sstevel@tonic-gate 	 * No need to hold a lock across the call to ibcm_find_sidr_entry() as
45117c478bd9Sstevel@tonic-gate 	 * the list lock is held in that function to find the matching entry.
45127c478bd9Sstevel@tonic-gate 	 */
45137c478bd9Sstevel@tonic-gate 
45147c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(srch_sidr))
45157c478bd9Sstevel@tonic-gate 
45167c478bd9Sstevel@tonic-gate 	srch_sidr.srch_lid = lid;
45177c478bd9Sstevel@tonic-gate 	srch_sidr.srch_gid = gid;
45187c478bd9Sstevel@tonic-gate 	srch_sidr.srch_grh_exists = cm_mad_addr->grh_exists;
45197c478bd9Sstevel@tonic-gate 	srch_sidr.srch_req_id = req_id;
45207c478bd9Sstevel@tonic-gate 	srch_sidr.srch_mode = IBCM_PASSIVE_MODE;
45217c478bd9Sstevel@tonic-gate 
45227c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(srch_sidr))
45237c478bd9Sstevel@tonic-gate 
45247c478bd9Sstevel@tonic-gate 	rw_enter(&hcap->hca_sidr_list_lock, RW_WRITER);
45257c478bd9Sstevel@tonic-gate 	state_lookup_status = ibcm_find_sidr_entry(&srch_sidr, hcap, &ud_statep,
45267c478bd9Sstevel@tonic-gate 	    IBCM_FLAG_LOOKUP_AND_ADD);
45277c478bd9Sstevel@tonic-gate 	rw_exit(&hcap->hca_sidr_list_lock);
45287c478bd9Sstevel@tonic-gate 
45297c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_sidr_req_msg: ud_statep 0x%p "
45307c478bd9Sstevel@tonic-gate 	    "lookup status %x", ud_statep, state_lookup_status);
45317c478bd9Sstevel@tonic-gate 
45327c478bd9Sstevel@tonic-gate 	if (state_lookup_status == IBCM_LOOKUP_NEW) {
45337c478bd9Sstevel@tonic-gate 
45347c478bd9Sstevel@tonic-gate 		/* Increment hca's resource count */
45357c478bd9Sstevel@tonic-gate 		ibcm_inc_hca_res_cnt(hcap);
45367c478bd9Sstevel@tonic-gate 
45377c478bd9Sstevel@tonic-gate 		_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ud_statep))
45387c478bd9Sstevel@tonic-gate 
45397c478bd9Sstevel@tonic-gate 		/*
45407c478bd9Sstevel@tonic-gate 		 * Allocate CM MAD for a response
45417c478bd9Sstevel@tonic-gate 		 * This MAD is deallocated on state structure delete
45427c478bd9Sstevel@tonic-gate 		 * and re-used for all outgoing MADs for this connection.
45437c478bd9Sstevel@tonic-gate 		 * If MAD allocation fails, delete the ud statep
45447c478bd9Sstevel@tonic-gate 		 */
45457c478bd9Sstevel@tonic-gate 		if (ibcm_alloc_out_msg(cm_mad_addr->ibmf_hdl,
45467c478bd9Sstevel@tonic-gate 		    &ud_statep->ud_stored_msg, MAD_METHOD_SEND) !=
45477c478bd9Sstevel@tonic-gate 		    IBT_SUCCESS) {
45487c478bd9Sstevel@tonic-gate 			mutex_enter(&ud_statep->ud_state_mutex);
45497c478bd9Sstevel@tonic-gate 			IBCM_UD_REF_CNT_DECR(ud_statep);
45507c478bd9Sstevel@tonic-gate 			mutex_exit(&ud_statep->ud_state_mutex);
45517c478bd9Sstevel@tonic-gate 			ibcm_delete_ud_state_data(ud_statep);
45527c478bd9Sstevel@tonic-gate 			return;
45537c478bd9Sstevel@tonic-gate 		}
45547c478bd9Sstevel@tonic-gate 
45557c478bd9Sstevel@tonic-gate 		/* Lookup for service */
45567c478bd9Sstevel@tonic-gate 		ud_statep->ud_svc_id = b2h64(sidr_reqp->sidr_req_service_id);
45577c478bd9Sstevel@tonic-gate 		ud_statep->ud_state  = IBCM_STATE_SIDR_REQ_RCVD;
45587c478bd9Sstevel@tonic-gate 		ud_statep->ud_clnt_proceed = IBCM_BLOCK;
45597c478bd9Sstevel@tonic-gate 
45607c478bd9Sstevel@tonic-gate 		mutex_enter(&ibcm_svc_info_lock);
45617c478bd9Sstevel@tonic-gate 
45627c478bd9Sstevel@tonic-gate 		svc_infop = ibcm_find_svc_entry(ud_statep->ud_svc_id);
45637c478bd9Sstevel@tonic-gate 
45647c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_process_sidr_req_msg: "
45657c478bd9Sstevel@tonic-gate 		    " ud_statep 0x%p svc_info %p", ud_statep, svc_infop);
45667c478bd9Sstevel@tonic-gate 
45677c478bd9Sstevel@tonic-gate 		/*
45687c478bd9Sstevel@tonic-gate 		 * No need to hold the ud state mutex, as no other thread
45697c478bd9Sstevel@tonic-gate 		 * modifies ud statep in IBCM_STATE_SIDR_REQ_RCVD state
45707c478bd9Sstevel@tonic-gate 		 */
45717c478bd9Sstevel@tonic-gate 
45727c478bd9Sstevel@tonic-gate 		if (svc_infop != NULL) {
45737c478bd9Sstevel@tonic-gate 			/* find the "bind" entry that enables this port */
45747c478bd9Sstevel@tonic-gate 
45757c478bd9Sstevel@tonic-gate 			svc_bindp = NULL;
45767c478bd9Sstevel@tonic-gate 			tmp_bindp = svc_infop->svc_bind_list;
45777c478bd9Sstevel@tonic-gate 			while (tmp_bindp) {
45787c478bd9Sstevel@tonic-gate 				if (tmp_bindp->sbind_hcaguid == hca_guid &&
45797c478bd9Sstevel@tonic-gate 				    tmp_bindp->sbind_port == port_num) {
45807c478bd9Sstevel@tonic-gate 					if (gid.gid_guid ==
45817c478bd9Sstevel@tonic-gate 					    tmp_bindp->sbind_gid.gid_guid &&
45827c478bd9Sstevel@tonic-gate 					    gid.gid_prefix ==
45837c478bd9Sstevel@tonic-gate 					    tmp_bindp->sbind_gid.gid_prefix) {
45847c478bd9Sstevel@tonic-gate 						/* a really good match */
45857c478bd9Sstevel@tonic-gate 						svc_bindp = tmp_bindp;
45867c478bd9Sstevel@tonic-gate 						if (pkey ==
45877c478bd9Sstevel@tonic-gate 						    tmp_bindp->sbind_pkey)
45887c478bd9Sstevel@tonic-gate 							/* absolute best */
45897c478bd9Sstevel@tonic-gate 							break;
45907c478bd9Sstevel@tonic-gate 					} else if (svc_bindp == NULL) {
45917c478bd9Sstevel@tonic-gate 						/* port match => a good match */
45927c478bd9Sstevel@tonic-gate 						svc_bindp = tmp_bindp;
45937c478bd9Sstevel@tonic-gate 					}
45947c478bd9Sstevel@tonic-gate 				}
45957c478bd9Sstevel@tonic-gate 				tmp_bindp = tmp_bindp->sbind_link;
45967c478bd9Sstevel@tonic-gate 			}
45977c478bd9Sstevel@tonic-gate 			if (svc_bindp == NULL) {
45987c478bd9Sstevel@tonic-gate 				svc_infop = NULL;
45997c478bd9Sstevel@tonic-gate 			}
46007c478bd9Sstevel@tonic-gate 		}
46017c478bd9Sstevel@tonic-gate 
46027c478bd9Sstevel@tonic-gate 		IBCM_OUT_HDRP(ud_statep->ud_stored_msg)->TransactionID =
46037c478bd9Sstevel@tonic-gate 		    ((ib_mad_hdr_t *)(input_madp))->TransactionID;
46047c478bd9Sstevel@tonic-gate 
46057c478bd9Sstevel@tonic-gate 		ibcm_build_reply_mad_addr(cm_mad_addr,
46067c478bd9Sstevel@tonic-gate 		    &ud_statep->ud_stored_reply_addr);
46077c478bd9Sstevel@tonic-gate 
46087c478bd9Sstevel@tonic-gate 		if (ud_statep->ud_stored_reply_addr.cm_qp_entry == NULL) {
46097c478bd9Sstevel@tonic-gate 
46107c478bd9Sstevel@tonic-gate 			mutex_exit(&ibcm_svc_info_lock);
46117c478bd9Sstevel@tonic-gate 
46127c478bd9Sstevel@tonic-gate 			/* Not much choice. CM MADs cannot go on QP1 */
46137c478bd9Sstevel@tonic-gate 			mutex_enter(&ud_statep->ud_state_mutex);
46147c478bd9Sstevel@tonic-gate 			IBCM_UD_REF_CNT_DECR(ud_statep);
46157c478bd9Sstevel@tonic-gate 			ud_statep->ud_state = IBCM_STATE_DELETE;
46167c478bd9Sstevel@tonic-gate 			mutex_exit(&ud_statep->ud_state_mutex);
46177c478bd9Sstevel@tonic-gate 
46187c478bd9Sstevel@tonic-gate 			ibcm_delete_ud_state_data(ud_statep);
46197c478bd9Sstevel@tonic-gate 			return;
46207c478bd9Sstevel@tonic-gate 		}
46217c478bd9Sstevel@tonic-gate 
46227c478bd9Sstevel@tonic-gate 		if (svc_infop == NULL || svc_infop->svc_ud_handler == NULL) {
46237c478bd9Sstevel@tonic-gate 			/*
46247c478bd9Sstevel@tonic-gate 			 * Don't have a record of Service ID in CM's
46257c478bd9Sstevel@tonic-gate 			 * internal list registered at this gid/lid.
46267c478bd9Sstevel@tonic-gate 			 * So, send out Service ID not supported SIDR REP msg
46277c478bd9Sstevel@tonic-gate 			 */
46287c478bd9Sstevel@tonic-gate 			sidr_status = IBT_CM_SREP_SID_INVALID;
46297c478bd9Sstevel@tonic-gate 		} else {
46307c478bd9Sstevel@tonic-gate 			ud_statep->ud_cm_handler = svc_infop->svc_ud_handler;
46317c478bd9Sstevel@tonic-gate 			ud_statep->ud_state_cm_private =
46327c478bd9Sstevel@tonic-gate 			    svc_bindp->sbind_cm_private;
46337c478bd9Sstevel@tonic-gate 			IBCM_SVC_INCR(svc_infop);
46347c478bd9Sstevel@tonic-gate 			mutex_exit(&ibcm_svc_info_lock);
46357c478bd9Sstevel@tonic-gate 
46367c478bd9Sstevel@tonic-gate 			/* Call Client's UD handler */
46377c478bd9Sstevel@tonic-gate 			cm_status = ibcm_sidr_req_ud_handler(ud_statep,
46387c478bd9Sstevel@tonic-gate 			    sidr_reqp, cm_mad_addr, &sidr_status);
46397c478bd9Sstevel@tonic-gate 
46407c478bd9Sstevel@tonic-gate 			mutex_enter(&ibcm_svc_info_lock);
46417c478bd9Sstevel@tonic-gate 			IBCM_SVC_DECR(svc_infop);
46427c478bd9Sstevel@tonic-gate 		}
46437c478bd9Sstevel@tonic-gate 
46447c478bd9Sstevel@tonic-gate 		mutex_exit(&ibcm_svc_info_lock);
46457c478bd9Sstevel@tonic-gate 
46467c478bd9Sstevel@tonic-gate 		if (cm_status == IBCM_DEFER) {
46477c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L4(cmlog, "ibcm_process_sidr_req_msg: "
46487c478bd9Sstevel@tonic-gate 			    "ud_statep 0x%p client returned DEFER response",
46497c478bd9Sstevel@tonic-gate 			    ud_statep);
46507c478bd9Sstevel@tonic-gate 			return;
46517c478bd9Sstevel@tonic-gate 		}
46527c478bd9Sstevel@tonic-gate 
46537c478bd9Sstevel@tonic-gate 		ibcm_post_sidr_rep_mad(ud_statep, sidr_status);
46547c478bd9Sstevel@tonic-gate 
46557c478bd9Sstevel@tonic-gate 		_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*ud_statep))
46567c478bd9Sstevel@tonic-gate 
46577c478bd9Sstevel@tonic-gate 		mutex_enter(&ud_statep->ud_state_mutex);
46587c478bd9Sstevel@tonic-gate 		IBCM_UD_REF_CNT_DECR(ud_statep);
46597c478bd9Sstevel@tonic-gate 		mutex_exit(&ud_statep->ud_state_mutex);
46607c478bd9Sstevel@tonic-gate 	} else {
46617c478bd9Sstevel@tonic-gate 		ASSERT(state_lookup_status == IBCM_LOOKUP_EXISTS);
46627c478bd9Sstevel@tonic-gate 
46637c478bd9Sstevel@tonic-gate 		mutex_enter(&ud_statep->ud_state_mutex);
46647c478bd9Sstevel@tonic-gate 
46657c478bd9Sstevel@tonic-gate 		if (ud_statep->ud_state == IBCM_STATE_SIDR_REP_SENT)
46667c478bd9Sstevel@tonic-gate 			ibcm_resend_srep_mad(ud_statep);
46677c478bd9Sstevel@tonic-gate 
46687c478bd9Sstevel@tonic-gate 		IBCM_UD_REF_CNT_DECR(ud_statep);
46697c478bd9Sstevel@tonic-gate 		mutex_exit(&ud_statep->ud_state_mutex);
46707c478bd9Sstevel@tonic-gate 	}
46717c478bd9Sstevel@tonic-gate }
46727c478bd9Sstevel@tonic-gate 
46737c478bd9Sstevel@tonic-gate 
46747c478bd9Sstevel@tonic-gate /*
46757c478bd9Sstevel@tonic-gate  * ibcm_process_sidr_rep_msg:
46767c478bd9Sstevel@tonic-gate  *	This call processes an incoming SIDR REP
46777c478bd9Sstevel@tonic-gate  *
46787c478bd9Sstevel@tonic-gate  * INPUTS:
46797c478bd9Sstevel@tonic-gate  *	hcap		- HCA entry pointer
46807c478bd9Sstevel@tonic-gate  *	input_madp	- incoming CM SIDR REP MAD
46817c478bd9Sstevel@tonic-gate  *	cm_mad_addr	- Address information for the MAD to be posted
46827c478bd9Sstevel@tonic-gate  *
46837c478bd9Sstevel@tonic-gate  * RETURN VALUE:
46847c478bd9Sstevel@tonic-gate  *	NONE
46857c478bd9Sstevel@tonic-gate  */
46867c478bd9Sstevel@tonic-gate void
ibcm_process_sidr_rep_msg(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)46877c478bd9Sstevel@tonic-gate ibcm_process_sidr_rep_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
46887c478bd9Sstevel@tonic-gate     ibcm_mad_addr_t *cm_mad_addr)
46897c478bd9Sstevel@tonic-gate {
46907c478bd9Sstevel@tonic-gate 	ib_lid_t		lid;
46917c478bd9Sstevel@tonic-gate 	ib_gid_t		gid;
46927c478bd9Sstevel@tonic-gate 	ibcm_status_t		status;
46937c478bd9Sstevel@tonic-gate 	ib_svc_id_t		tmp_svc_id;
46947c478bd9Sstevel@tonic-gate 	ibcm_sidr_rep_msg_t	*sidr_repp = (ibcm_sidr_rep_msg_t *)
4695015f8fffShiremath 	    (&input_madp[IBCM_MAD_HDR_SIZE]);
46967c478bd9Sstevel@tonic-gate 	ibcm_ud_state_data_t	*ud_statep = NULL;
46977c478bd9Sstevel@tonic-gate 	ibcm_sidr_srch_t	srch_sidr;
46987c478bd9Sstevel@tonic-gate 
46997c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_sidr_rep_msg:");
47007c478bd9Sstevel@tonic-gate 
47017c478bd9Sstevel@tonic-gate 	lid = cm_mad_addr->rcvd_addr.ia_local_lid;
47027c478bd9Sstevel@tonic-gate 	if (cm_mad_addr->grh_exists == B_TRUE)
47037c478bd9Sstevel@tonic-gate 		gid = cm_mad_addr->grh_hdr.ig_recver_gid;
47047c478bd9Sstevel@tonic-gate 	else
47057c478bd9Sstevel@tonic-gate 		gid.gid_prefix = gid.gid_guid = 0;
47067c478bd9Sstevel@tonic-gate 
47077c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(cmlog, "ibcm_process_sidr_rep_msg: QPN rcvd = %x",
47087c478bd9Sstevel@tonic-gate 	    h2b32(sidr_repp->sidr_rep_qpn_plus) >> 8);
47097c478bd9Sstevel@tonic-gate 
47107c478bd9Sstevel@tonic-gate 	/*
47117c478bd9Sstevel@tonic-gate 	 * Lookup for an existing state structure.
47127c478bd9Sstevel@tonic-gate 	 * No need to hold a lock as ibcm_find_sidr_entry() holds the
47137c478bd9Sstevel@tonic-gate 	 * list lock to find the matching entry.
47147c478bd9Sstevel@tonic-gate 	 */
47157c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_sidr_rep: lid=%x, (%llX, %llX), "
47167c478bd9Sstevel@tonic-gate 	    "grh = %x, id = %x", lid, gid.gid_prefix, gid.gid_guid,
47177c478bd9Sstevel@tonic-gate 	    cm_mad_addr->grh_exists, sidr_repp->sidr_rep_request_id);
47187c478bd9Sstevel@tonic-gate 
47197c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(srch_sidr))
47207c478bd9Sstevel@tonic-gate 
47217c478bd9Sstevel@tonic-gate 	srch_sidr.srch_lid = lid;
47227c478bd9Sstevel@tonic-gate 	srch_sidr.srch_gid = gid;
47237c478bd9Sstevel@tonic-gate 	srch_sidr.srch_grh_exists = cm_mad_addr->grh_exists;
47247c478bd9Sstevel@tonic-gate 	srch_sidr.srch_req_id = b2h32(sidr_repp->sidr_rep_request_id);
47257c478bd9Sstevel@tonic-gate 	srch_sidr.srch_mode = IBCM_ACTIVE_MODE;
47267c478bd9Sstevel@tonic-gate 
47277c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(srch_sidr))
47287c478bd9Sstevel@tonic-gate 
47297c478bd9Sstevel@tonic-gate 	rw_enter(&hcap->hca_sidr_list_lock, RW_READER);
47307c478bd9Sstevel@tonic-gate 	status = ibcm_find_sidr_entry(&srch_sidr, hcap, &ud_statep,
47317c478bd9Sstevel@tonic-gate 	    IBCM_FLAG_LOOKUP);
47327c478bd9Sstevel@tonic-gate 	rw_exit(&hcap->hca_sidr_list_lock);
47337c478bd9Sstevel@tonic-gate 
4734fde3102fShiremath 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_sidr_rep_msg: ud_statep 0x%p "
47357c478bd9Sstevel@tonic-gate 	    "find sidr entry status = %x", ud_statep, status);
47367c478bd9Sstevel@tonic-gate 
47377c478bd9Sstevel@tonic-gate 	if (status != IBCM_LOOKUP_EXISTS) {
47387c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_process_sidr_rep_msg: "
47397c478bd9Sstevel@tonic-gate 		    "No matching ud_statep for SIDR REP");
47407c478bd9Sstevel@tonic-gate 		return;
47417c478bd9Sstevel@tonic-gate 	}
47427c478bd9Sstevel@tonic-gate 
47437c478bd9Sstevel@tonic-gate 	if (IBCM_OUT_HDRP(ud_statep->ud_stored_msg)->TransactionID !=
47447c478bd9Sstevel@tonic-gate 	    ((ib_mad_hdr_t *)(input_madp))->TransactionID) {
47457c478bd9Sstevel@tonic-gate 		mutex_enter(&ud_statep->ud_state_mutex);
47467c478bd9Sstevel@tonic-gate 		IBCM_UD_REF_CNT_DECR(ud_statep);
47477c478bd9Sstevel@tonic-gate 		mutex_exit(&ud_statep->ud_state_mutex);
47487c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_process_sidr_rep_msg: "
47497c478bd9Sstevel@tonic-gate 		    "ud_statep 0x%p. A SIDR REP MAD with tid expected 0x%llX "
47507c478bd9Sstevel@tonic-gate 		    "tid found 0x%llX req_id %x arrived", ud_statep,
47517c478bd9Sstevel@tonic-gate 		    b2h64(
47527c478bd9Sstevel@tonic-gate 		    IBCM_OUT_HDRP(ud_statep->ud_stored_msg)->TransactionID),
47537c478bd9Sstevel@tonic-gate 		    b2h64(((ib_mad_hdr_t *)(input_madp))->TransactionID),
47547c478bd9Sstevel@tonic-gate 		    b2h32(sidr_repp->sidr_rep_request_id));
47557c478bd9Sstevel@tonic-gate 		return;
47567c478bd9Sstevel@tonic-gate 	}
47577c478bd9Sstevel@tonic-gate 
47587c478bd9Sstevel@tonic-gate 	mutex_enter(&ud_statep->ud_state_mutex);
47597c478bd9Sstevel@tonic-gate 
47607c478bd9Sstevel@tonic-gate 	/*
47617c478bd9Sstevel@tonic-gate 	 * We need to check service ID received against the one sent?
47627c478bd9Sstevel@tonic-gate 	 * If they don't match just return.
47637c478bd9Sstevel@tonic-gate 	 */
47647c478bd9Sstevel@tonic-gate 	bcopy(sidr_repp->sidr_rep_service_id, &tmp_svc_id, sizeof (tmp_svc_id));
47657c478bd9Sstevel@tonic-gate 	bcopy(&tmp_svc_id, sidr_repp->sidr_rep_service_id, sizeof (tmp_svc_id));
47667c478bd9Sstevel@tonic-gate 	if (ud_statep->ud_svc_id != b2h64(tmp_svc_id)) {
47677c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_process_sidr_rep_msg: "
47689d3d2ed0Shiremath 		    "ud_statep -0x%p svcids do not match %llx %llx",
47697c478bd9Sstevel@tonic-gate 		    ud_statep, ud_statep->ud_svc_id, b2h64(tmp_svc_id));
47707c478bd9Sstevel@tonic-gate 
47717c478bd9Sstevel@tonic-gate 		IBCM_UD_REF_CNT_DECR(ud_statep);
47727c478bd9Sstevel@tonic-gate 		mutex_exit(&ud_statep->ud_state_mutex);
47737c478bd9Sstevel@tonic-gate 		return;
47747c478bd9Sstevel@tonic-gate 	}
47757c478bd9Sstevel@tonic-gate 
47767c478bd9Sstevel@tonic-gate 	if (ud_statep->ud_state == IBCM_STATE_SIDR_REQ_SENT) {
47777c478bd9Sstevel@tonic-gate 		timeout_id_t	timer_val = ud_statep->ud_timerid;
47787c478bd9Sstevel@tonic-gate 
47797c478bd9Sstevel@tonic-gate 		ud_statep->ud_state = IBCM_STATE_SIDR_REP_RCVD;
47807c478bd9Sstevel@tonic-gate 		ud_statep->ud_timerid = 0;
47817c478bd9Sstevel@tonic-gate 		mutex_exit(&ud_statep->ud_state_mutex);
47827c478bd9Sstevel@tonic-gate 
47837c478bd9Sstevel@tonic-gate 		/* Cancel timer set after sending SIDR REQ */
47847c478bd9Sstevel@tonic-gate 		(void) untimeout(timer_val);
47857c478bd9Sstevel@tonic-gate 
47867c478bd9Sstevel@tonic-gate 		/*
47877c478bd9Sstevel@tonic-gate 		 * Call Client's UD handler
47887c478bd9Sstevel@tonic-gate 		 */
47897c478bd9Sstevel@tonic-gate 		ibcm_sidr_rep_ud_handler(ud_statep, sidr_repp);
47907c478bd9Sstevel@tonic-gate 
47917c478bd9Sstevel@tonic-gate 		mutex_enter(&ud_statep->ud_state_mutex);
47927c478bd9Sstevel@tonic-gate 
47937c478bd9Sstevel@tonic-gate 		ud_statep->ud_state = IBCM_STATE_DELETE;
47947c478bd9Sstevel@tonic-gate 
47957c478bd9Sstevel@tonic-gate 		/*
47967c478bd9Sstevel@tonic-gate 		 * ud_statep->ud_return_data is initialized for blocking in
47977c478bd9Sstevel@tonic-gate 		 * ibt_ud_get_dqpn(). Initialize its fields and
47987c478bd9Sstevel@tonic-gate 		 * signal the blocking call in ibt_ud_get_dqpn().
47997c478bd9Sstevel@tonic-gate 		 */
48007c478bd9Sstevel@tonic-gate 		if (ud_statep->ud_return_data != NULL) {
48017c478bd9Sstevel@tonic-gate 			/* get rep_qpn and rep_status */
48027c478bd9Sstevel@tonic-gate 			ibt_priv_data_len_t len;
48037c478bd9Sstevel@tonic-gate 
48047c478bd9Sstevel@tonic-gate 			/* Copy the SIDR private data */
48057c478bd9Sstevel@tonic-gate 			len = min(ud_statep->ud_return_data->ud_priv_data_len,
48067c478bd9Sstevel@tonic-gate 			    IBT_SIDR_REP_PRIV_DATA_SZ);
48077c478bd9Sstevel@tonic-gate 
48087c478bd9Sstevel@tonic-gate 			if ((ud_statep->ud_return_data->ud_priv_data != NULL) &&
48097c478bd9Sstevel@tonic-gate 			    (len > 0)) {
48107c478bd9Sstevel@tonic-gate 				bcopy(sidr_repp->sidr_rep_private_data,
48117c478bd9Sstevel@tonic-gate 				    ud_statep->ud_return_data->ud_priv_data,
48127c478bd9Sstevel@tonic-gate 				    len);
48137c478bd9Sstevel@tonic-gate 			}
48147c478bd9Sstevel@tonic-gate 
48157c478bd9Sstevel@tonic-gate 			/* get status first */
48167c478bd9Sstevel@tonic-gate 			ud_statep->ud_return_data->ud_status =
48177c478bd9Sstevel@tonic-gate 			    sidr_repp->sidr_rep_rep_status;
48187c478bd9Sstevel@tonic-gate 
48197c478bd9Sstevel@tonic-gate 			if (ud_statep->ud_return_data->ud_status ==
48207c478bd9Sstevel@tonic-gate 			    IBT_CM_SREP_QPN_VALID) {
48217c478bd9Sstevel@tonic-gate 				ud_statep->ud_return_data->ud_dqpn =
48227c478bd9Sstevel@tonic-gate 				    h2b32(sidr_repp->sidr_rep_qpn_plus) >> 8;
48237c478bd9Sstevel@tonic-gate 				ud_statep->ud_return_data->ud_qkey =
48247c478bd9Sstevel@tonic-gate 				    b2h32(sidr_repp->sidr_rep_qkey);
48257c478bd9Sstevel@tonic-gate 			}
48267c478bd9Sstevel@tonic-gate 
48277c478bd9Sstevel@tonic-gate 			ud_statep->ud_blocking_done = B_TRUE;
48287c478bd9Sstevel@tonic-gate 			cv_broadcast(&ud_statep->ud_block_client_cv);
48297c478bd9Sstevel@tonic-gate 		}
48307c478bd9Sstevel@tonic-gate 
48317c478bd9Sstevel@tonic-gate 		IBCM_UD_REF_CNT_DECR(ud_statep);
48327c478bd9Sstevel@tonic-gate 		mutex_exit(&ud_statep->ud_state_mutex);
48337c478bd9Sstevel@tonic-gate 
48347c478bd9Sstevel@tonic-gate 		/* Delete UD state data now, finally done with it */
48357c478bd9Sstevel@tonic-gate 		ibcm_delete_ud_state_data(ud_statep);
48367c478bd9Sstevel@tonic-gate 	} else {
48377c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L3(cmlog, "ibcm_process_sidr_rep_msg: "
48387c478bd9Sstevel@tonic-gate 		    "ud state is = 0x%x", ud_statep->ud_state);
48397c478bd9Sstevel@tonic-gate 		IBCM_UD_REF_CNT_DECR(ud_statep);
48407c478bd9Sstevel@tonic-gate 		mutex_exit(&ud_statep->ud_state_mutex);
48417c478bd9Sstevel@tonic-gate 	}
48427c478bd9Sstevel@tonic-gate }
48437c478bd9Sstevel@tonic-gate 
48447c478bd9Sstevel@tonic-gate 
48457c478bd9Sstevel@tonic-gate /*
48467c478bd9Sstevel@tonic-gate  * ibcm_post_sidr_rep_mad:
48477c478bd9Sstevel@tonic-gate  *	This call posts a SIDR REP MAD
48487c478bd9Sstevel@tonic-gate  *
48497c478bd9Sstevel@tonic-gate  * INPUTS:
48507c478bd9Sstevel@tonic-gate  *	ud_statep	- pointer to ibcm_ud_state_data_t
48517c478bd9Sstevel@tonic-gate  *	status		- Status information
48527c478bd9Sstevel@tonic-gate  *
48537c478bd9Sstevel@tonic-gate  * RETURN VALUE: NONE
48547c478bd9Sstevel@tonic-gate  */
48557c478bd9Sstevel@tonic-gate void
ibcm_post_sidr_rep_mad(ibcm_ud_state_data_t * ud_statep,ibt_sidr_status_t status)48567c478bd9Sstevel@tonic-gate ibcm_post_sidr_rep_mad(ibcm_ud_state_data_t *ud_statep,
48577c478bd9Sstevel@tonic-gate     ibt_sidr_status_t status)
48587c478bd9Sstevel@tonic-gate {
48597c478bd9Sstevel@tonic-gate 	ib_svc_id_t		tmp_svc_id;
48607c478bd9Sstevel@tonic-gate 	ibcm_sidr_rep_msg_t	*sidr_repp =
48617c478bd9Sstevel@tonic-gate 	    (ibcm_sidr_rep_msg_t *)IBCM_OUT_MSGP(ud_statep->ud_stored_msg);
48627c478bd9Sstevel@tonic-gate 	clock_t			timer_value;
48637c478bd9Sstevel@tonic-gate 
48647c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "ibcm_post_sidr_rep_mad:");
48657c478bd9Sstevel@tonic-gate 
48667c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sidr_repp))
48677c478bd9Sstevel@tonic-gate 
48687c478bd9Sstevel@tonic-gate 	IBCM_OUT_HDRP(ud_statep->ud_stored_msg)->AttributeID =
48697c478bd9Sstevel@tonic-gate 	    h2b16(IBCM_INCOMING_SIDR_REP + IBCM_ATTR_BASE_ID);
48707c478bd9Sstevel@tonic-gate 
48717c478bd9Sstevel@tonic-gate 	/*
48727c478bd9Sstevel@tonic-gate 	 * Initialize SIDR REP message. (Other fields were
48737c478bd9Sstevel@tonic-gate 	 * already filled up in ibcm_sidr_req_ud_handler()
48747c478bd9Sstevel@tonic-gate 	 */
48757c478bd9Sstevel@tonic-gate 	sidr_repp->sidr_rep_request_id = h2b32(ud_statep->ud_req_id);
48767c478bd9Sstevel@tonic-gate 	tmp_svc_id = h2b64(ud_statep->ud_svc_id);
48777c478bd9Sstevel@tonic-gate 	bcopy(&tmp_svc_id, sidr_repp->sidr_rep_service_id, sizeof (tmp_svc_id));
48787c478bd9Sstevel@tonic-gate 
48797c478bd9Sstevel@tonic-gate 	sidr_repp->sidr_rep_rep_status = (uint8_t)status;
48807c478bd9Sstevel@tonic-gate 
48817c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*sidr_repp))
48827c478bd9Sstevel@tonic-gate 
48837c478bd9Sstevel@tonic-gate 	/* post the SIDR REP MAD */
48847c478bd9Sstevel@tonic-gate 	ibcm_post_ud_mad(ud_statep, ud_statep->ud_stored_msg, NULL, NULL);
48857c478bd9Sstevel@tonic-gate 
48867c478bd9Sstevel@tonic-gate 	timer_value = ibt_ib2usec(ibcm_max_sidr_rep_store_time);
48877c478bd9Sstevel@tonic-gate 	/*
48887c478bd9Sstevel@tonic-gate 	 * Hold the statep lock, as a SIDR REQ may come in after setting state
48897c478bd9Sstevel@tonic-gate 	 * but before timeout. This can result in a dangling timeout ie.,
48907c478bd9Sstevel@tonic-gate 	 * the incoming SIDR REQ would be unable to cancel this timeout
48917c478bd9Sstevel@tonic-gate 	 */
48927c478bd9Sstevel@tonic-gate 	mutex_enter(&ud_statep->ud_state_mutex);
48937c478bd9Sstevel@tonic-gate 
48947c478bd9Sstevel@tonic-gate 	ud_statep->ud_remaining_retry_cnt = 1;
48957c478bd9Sstevel@tonic-gate 	ud_statep->ud_timer_value = timer_value;
48967c478bd9Sstevel@tonic-gate 
48977c478bd9Sstevel@tonic-gate 	ud_statep->ud_timer_stored_state = ud_statep->ud_state =
48987c478bd9Sstevel@tonic-gate 	    IBCM_STATE_SIDR_REP_SENT;
48997c478bd9Sstevel@tonic-gate 	ud_statep->ud_timerid = IBCM_UD_TIMEOUT(ud_statep,
49007c478bd9Sstevel@tonic-gate 	    ud_statep->ud_timer_value);
49017c478bd9Sstevel@tonic-gate 
49027c478bd9Sstevel@tonic-gate 	mutex_exit(&ud_statep->ud_state_mutex);
49037c478bd9Sstevel@tonic-gate }
49047c478bd9Sstevel@tonic-gate 
49057c478bd9Sstevel@tonic-gate 
49067c478bd9Sstevel@tonic-gate /*
49077c478bd9Sstevel@tonic-gate  * ibcm_sidr_timeout_cb:
49087c478bd9Sstevel@tonic-gate  *	Called when the timer expires on SIDR request
49097c478bd9Sstevel@tonic-gate  *
49107c478bd9Sstevel@tonic-gate  * INPUTS:
49117c478bd9Sstevel@tonic-gate  *	arg	-	ibcm_ud_state_data_t with all the info
49127c478bd9Sstevel@tonic-gate  *
49137c478bd9Sstevel@tonic-gate  * RETURN VALUE: NONE
49147c478bd9Sstevel@tonic-gate  */
49157c478bd9Sstevel@tonic-gate void
ibcm_sidr_timeout_cb(void * arg)49167c478bd9Sstevel@tonic-gate ibcm_sidr_timeout_cb(void *arg)
49177c478bd9Sstevel@tonic-gate {
49187c478bd9Sstevel@tonic-gate 	ibcm_ud_state_data_t	*ud_statep = (ibcm_ud_state_data_t *)arg;
49197c478bd9Sstevel@tonic-gate 
49207c478bd9Sstevel@tonic-gate 	mutex_enter(&ud_statep->ud_state_mutex);
4921f07a6d2aSShantkumar Hiremath 	ud_statep->ud_timerid = 0;
49227c478bd9Sstevel@tonic-gate 
49237c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(cmlog, "ibcm_sidr_timeout_cb: ud_statep 0x%p "
49247c478bd9Sstevel@tonic-gate 	    "state = 0x%x", ud_statep, ud_statep->ud_state);
49257c478bd9Sstevel@tonic-gate 
49267c478bd9Sstevel@tonic-gate 	/* Processing depends upon current state */
49277c478bd9Sstevel@tonic-gate 	if (ud_statep->ud_state == IBCM_STATE_SIDR_REP_SENT) {
49287c478bd9Sstevel@tonic-gate 		ud_statep->ud_state = IBCM_STATE_DELETE;
49297c478bd9Sstevel@tonic-gate 
49307c478bd9Sstevel@tonic-gate 		mutex_exit(&ud_statep->ud_state_mutex);
49317c478bd9Sstevel@tonic-gate 
49327c478bd9Sstevel@tonic-gate 		/* Deallocate the CM state structure */
49337c478bd9Sstevel@tonic-gate 		ibcm_delete_ud_state_data(ud_statep);
49347c478bd9Sstevel@tonic-gate 
49357c478bd9Sstevel@tonic-gate 	} else if ((ud_statep->ud_remaining_retry_cnt > 0) &&
49367c478bd9Sstevel@tonic-gate 	    (ud_statep->ud_state == IBCM_STATE_SIDR_REQ_SENT)) {
49377c478bd9Sstevel@tonic-gate 
49387c478bd9Sstevel@tonic-gate 		ud_statep->ud_remaining_retry_cnt--;
49397c478bd9Sstevel@tonic-gate 		IBCM_UD_REF_CNT_INCR(ud_statep); /* for non-blocking post */
49407c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_sidr_timeout_cb: "
49417c478bd9Sstevel@tonic-gate 		    "ud_statep = %p, retries remaining = 0x%x",
49427c478bd9Sstevel@tonic-gate 		    ud_statep, ud_statep->ud_remaining_retry_cnt);
49437c478bd9Sstevel@tonic-gate 		mutex_exit(&ud_statep->ud_state_mutex);
49447c478bd9Sstevel@tonic-gate 
49457c478bd9Sstevel@tonic-gate 		/* Post mad in non blocking mode */
49467c478bd9Sstevel@tonic-gate 		ibcm_post_ud_mad(ud_statep, ud_statep->ud_stored_msg,
49477c478bd9Sstevel@tonic-gate 		    ibcm_post_sidr_req_complete, ud_statep);
49487c478bd9Sstevel@tonic-gate 
49497c478bd9Sstevel@tonic-gate 	} else if (ud_statep->ud_state == IBCM_STATE_SIDR_REQ_SENT) {
49507c478bd9Sstevel@tonic-gate 
49517c478bd9Sstevel@tonic-gate 		/* This is on SIDR REQ Sender side processing */
49527c478bd9Sstevel@tonic-gate 
49537c478bd9Sstevel@tonic-gate 		/* set state to IBCM_STATE_DELETE */
49547c478bd9Sstevel@tonic-gate 		ud_statep->ud_state = IBCM_STATE_DELETE;
49557c478bd9Sstevel@tonic-gate 
49567c478bd9Sstevel@tonic-gate 		/*
49577c478bd9Sstevel@tonic-gate 		 * retry counter expired, clean up
49587c478bd9Sstevel@tonic-gate 		 *
49597c478bd9Sstevel@tonic-gate 		 * Invoke the client/server handler with a "status" of
49607c478bd9Sstevel@tonic-gate 		 * IBT_CM_SREP_TIMEOUT.
49617c478bd9Sstevel@tonic-gate 		 */
49627c478bd9Sstevel@tonic-gate 
49637c478bd9Sstevel@tonic-gate 		if (ud_statep->ud_return_data != NULL) {
49647c478bd9Sstevel@tonic-gate 			ud_statep->ud_return_data->ud_status =
4965015f8fffShiremath 			    IBT_CM_SREP_TIMEOUT;
49667c478bd9Sstevel@tonic-gate 			ud_statep->ud_blocking_done = B_TRUE;
49677c478bd9Sstevel@tonic-gate 			cv_broadcast(&ud_statep->ud_block_client_cv);
49687c478bd9Sstevel@tonic-gate 		}
49697c478bd9Sstevel@tonic-gate 
49707c478bd9Sstevel@tonic-gate 		mutex_exit(&ud_statep->ud_state_mutex);
49717c478bd9Sstevel@tonic-gate 
49727c478bd9Sstevel@tonic-gate 		/* Invoke the client handler in a separate thread */
49737c478bd9Sstevel@tonic-gate 		if (ud_statep->ud_cm_handler != NULL) {
49747c478bd9Sstevel@tonic-gate 			/* UD state data is delete in timeout thread */
49757c478bd9Sstevel@tonic-gate 			ibcm_add_ud_tlist(ud_statep);
49767c478bd9Sstevel@tonic-gate 			return;
49777c478bd9Sstevel@tonic-gate 		}
49787c478bd9Sstevel@tonic-gate 
49797c478bd9Sstevel@tonic-gate 		/* Delete UD state data now, finally done with it */
49807c478bd9Sstevel@tonic-gate 		ibcm_delete_ud_state_data(ud_statep);
49817c478bd9Sstevel@tonic-gate 	} else {
49827c478bd9Sstevel@tonic-gate 
49837c478bd9Sstevel@tonic-gate #ifdef DEBUG
49847c478bd9Sstevel@tonic-gate 		if (ibcm_test_mode > 0)
49857c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_sidr_timeout_cb: "
49867c478bd9Sstevel@tonic-gate 			    "Nop timeout  for ud_statep 0x%p in ud_state %d",
49877c478bd9Sstevel@tonic-gate 			    ud_statep, ud_statep->ud_state);
49887c478bd9Sstevel@tonic-gate #endif
49897c478bd9Sstevel@tonic-gate 		mutex_exit(&ud_statep->ud_state_mutex);
49907c478bd9Sstevel@tonic-gate 	}
49917c478bd9Sstevel@tonic-gate }
49927c478bd9Sstevel@tonic-gate 
49937c478bd9Sstevel@tonic-gate 
49947c478bd9Sstevel@tonic-gate /*
49957c478bd9Sstevel@tonic-gate  * ibcm_resend_srep_mad:
49967c478bd9Sstevel@tonic-gate  *	Called on a duplicate incoming SIDR REQ on server side
49977c478bd9Sstevel@tonic-gate  *	Posts the stored MAD from ud state structure using ud_stored_reply_addr
49987c478bd9Sstevel@tonic-gate  *	Cancels any running timer, and then re-starts the timer
49997c478bd9Sstevel@tonic-gate  *	This routine must be called with state structure table lock held
50007c478bd9Sstevel@tonic-gate  *
50017c478bd9Sstevel@tonic-gate  * INPUTS:
50027c478bd9Sstevel@tonic-gate  *	ud_statep	-	ibcm_ud_state_data_t
50037c478bd9Sstevel@tonic-gate  *
50047c478bd9Sstevel@tonic-gate  * RETURN VALUE: NONE
50057c478bd9Sstevel@tonic-gate  */
50067c478bd9Sstevel@tonic-gate void
ibcm_resend_srep_mad(ibcm_ud_state_data_t * ud_statep)50077c478bd9Sstevel@tonic-gate ibcm_resend_srep_mad(ibcm_ud_state_data_t *ud_statep)
50087c478bd9Sstevel@tonic-gate {
50097c478bd9Sstevel@tonic-gate 	timeout_id_t		timer_val;
50107c478bd9Sstevel@tonic-gate 
50117c478bd9Sstevel@tonic-gate 	ASSERT(MUTEX_HELD(&ud_statep->ud_state_mutex));
50127c478bd9Sstevel@tonic-gate 
50137c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(cmlog, "ibcm_resend_srep_mad: ud_statep 0x%p",
50147c478bd9Sstevel@tonic-gate 	    ud_statep);
50157c478bd9Sstevel@tonic-gate 
50167c478bd9Sstevel@tonic-gate 	if (ud_statep->ud_send_mad_flags & IBCM_SREP_POST_BUSY)
50177c478bd9Sstevel@tonic-gate 		return;
50187c478bd9Sstevel@tonic-gate 
50197c478bd9Sstevel@tonic-gate 	ud_statep->ud_send_mad_flags |= IBCM_SREP_POST_BUSY;
50207c478bd9Sstevel@tonic-gate 
50217c478bd9Sstevel@tonic-gate 	/* for nonblocking SIDR REP Post */
50227c478bd9Sstevel@tonic-gate 	IBCM_UD_REF_CNT_INCR(ud_statep);
50237c478bd9Sstevel@tonic-gate 
50247c478bd9Sstevel@tonic-gate 	/* Cancel currently running timer */
50257c478bd9Sstevel@tonic-gate 	timer_val = ud_statep->ud_timerid;
50267c478bd9Sstevel@tonic-gate 
50277c478bd9Sstevel@tonic-gate 	if (ud_statep->ud_timerid != 0) {
50287c478bd9Sstevel@tonic-gate 		ud_statep->ud_timerid = 0;
50297c478bd9Sstevel@tonic-gate 		mutex_exit(&ud_statep->ud_state_mutex);
50307c478bd9Sstevel@tonic-gate 		(void) untimeout(timer_val);
50317c478bd9Sstevel@tonic-gate 	} else {
50327c478bd9Sstevel@tonic-gate 		mutex_exit(&ud_statep->ud_state_mutex);
50337c478bd9Sstevel@tonic-gate 	}
50347c478bd9Sstevel@tonic-gate 
50357c478bd9Sstevel@tonic-gate 	/* Always resend the response MAD to the original reply destination */
50367c478bd9Sstevel@tonic-gate 	ibcm_post_ud_mad(ud_statep, ud_statep->ud_stored_msg,
50377c478bd9Sstevel@tonic-gate 	    ibcm_post_sidr_rep_complete, ud_statep);
50387c478bd9Sstevel@tonic-gate 
50397c478bd9Sstevel@tonic-gate 	mutex_enter(&ud_statep->ud_state_mutex);
50407c478bd9Sstevel@tonic-gate }
50417c478bd9Sstevel@tonic-gate 
50427c478bd9Sstevel@tonic-gate 
50437c478bd9Sstevel@tonic-gate /*
50447c478bd9Sstevel@tonic-gate  * ibcm_build_reply_mad_addr:
50457c478bd9Sstevel@tonic-gate  *	Forms the reply MAD address based on "incoming mad addr" that is
50467c478bd9Sstevel@tonic-gate  *	supplied as an arg.
50477c478bd9Sstevel@tonic-gate  *
50487c478bd9Sstevel@tonic-gate  *	Swaps the source and destination gids in ib_grh_t
50497c478bd9Sstevel@tonic-gate  *
50507c478bd9Sstevel@tonic-gate  * INPUTS:
50517c478bd9Sstevel@tonic-gate  * inp_mad_addr:	Address information in the incoming MAD
50527c478bd9Sstevel@tonic-gate  * out_mad_addr:	Derived address for the reply MAD
50537c478bd9Sstevel@tonic-gate  *			The reply MAD address is derived based
50547c478bd9Sstevel@tonic-gate  *			address information of incoming CM MAD
50557c478bd9Sstevel@tonic-gate  * RETURN VALUE: NONE
50567c478bd9Sstevel@tonic-gate  */
50577c478bd9Sstevel@tonic-gate void
ibcm_build_reply_mad_addr(ibcm_mad_addr_t * inp_mad_addr,ibcm_mad_addr_t * out_mad_addr)50587c478bd9Sstevel@tonic-gate ibcm_build_reply_mad_addr(ibcm_mad_addr_t *inp_mad_addr,
50597c478bd9Sstevel@tonic-gate     ibcm_mad_addr_t *out_mad_addr)
50607c478bd9Sstevel@tonic-gate {
50617c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "ibcm_build_reply_mad_addr:");
50627c478bd9Sstevel@tonic-gate 
50637c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*out_mad_addr))
50647c478bd9Sstevel@tonic-gate 
50657c478bd9Sstevel@tonic-gate 	bcopy(inp_mad_addr, out_mad_addr, sizeof (ibcm_mad_addr_t));
50667c478bd9Sstevel@tonic-gate 
50677c478bd9Sstevel@tonic-gate 	/* Swap the GIDs in the GRH */
50687c478bd9Sstevel@tonic-gate 	if (inp_mad_addr->grh_exists == B_TRUE) {
50697c478bd9Sstevel@tonic-gate 		ib_gid_t sgid = inp_mad_addr->grh_hdr.ig_sender_gid;
50707c478bd9Sstevel@tonic-gate 
50717c478bd9Sstevel@tonic-gate 		/* swap the SGID and DGID */
50727c478bd9Sstevel@tonic-gate 		out_mad_addr->grh_hdr.ig_sender_gid =
50737c478bd9Sstevel@tonic-gate 		    inp_mad_addr->grh_hdr.ig_recver_gid;
50747c478bd9Sstevel@tonic-gate 		out_mad_addr->grh_hdr.ig_recver_gid = sgid;
50757c478bd9Sstevel@tonic-gate 	}
50767c478bd9Sstevel@tonic-gate 
50777c478bd9Sstevel@tonic-gate 	/*
50787c478bd9Sstevel@tonic-gate 	 * CM posts response MAD on a new/existing internal QP on the same port
50797c478bd9Sstevel@tonic-gate 	 * and pkey
50807c478bd9Sstevel@tonic-gate 	 */
50817c478bd9Sstevel@tonic-gate 	out_mad_addr->cm_qp_entry =
50827c478bd9Sstevel@tonic-gate 	    ibcm_find_qp(inp_mad_addr->cm_qp_entry->qp_port->port_hcap,
50837c478bd9Sstevel@tonic-gate 	    inp_mad_addr->port_num, inp_mad_addr->rcvd_addr.ia_p_key);
50847c478bd9Sstevel@tonic-gate 
50857c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*out_mad_addr))
50867c478bd9Sstevel@tonic-gate }
50877c478bd9Sstevel@tonic-gate 
50887c478bd9Sstevel@tonic-gate 
50897c478bd9Sstevel@tonic-gate /*
50907c478bd9Sstevel@tonic-gate  * ibcm_post_rc_mad
50917c478bd9Sstevel@tonic-gate  *	Posts a CM MAD associated with a RC statep
50927c478bd9Sstevel@tonic-gate  *
50937c478bd9Sstevel@tonic-gate  * INPUTS:
50947c478bd9Sstevel@tonic-gate  * statep	: RC statep associated with the post
50957c478bd9Sstevel@tonic-gate  * msgp		: CM MAD to be posted
50967c478bd9Sstevel@tonic-gate  * post_cb	: non-NULL callback address implies non-blocking post
50977c478bd9Sstevel@tonic-gate  * args		: Args to ibmf send callback
50987c478bd9Sstevel@tonic-gate  *
50997c478bd9Sstevel@tonic-gate  * RETURN VALUE: based on ibmf_send_mad
51007c478bd9Sstevel@tonic-gate  */
51017c478bd9Sstevel@tonic-gate void
ibcm_post_rc_mad(ibcm_state_data_t * statep,ibmf_msg_t * msgp,ibmf_msg_cb_t post_cb,void * args)51027c478bd9Sstevel@tonic-gate ibcm_post_rc_mad(ibcm_state_data_t *statep, ibmf_msg_t *msgp,
51037c478bd9Sstevel@tonic-gate     ibmf_msg_cb_t post_cb, void *args)
51047c478bd9Sstevel@tonic-gate {
51057c478bd9Sstevel@tonic-gate 	ibt_status_t	status;
51067c478bd9Sstevel@tonic-gate 
51079d3d2ed0Shiremath 	mutex_enter(&statep->state_mutex);
51089d3d2ed0Shiremath 	statep->post_time = gethrtime();
51099d3d2ed0Shiremath 	mutex_exit(&statep->state_mutex);
51107c478bd9Sstevel@tonic-gate 	status = ibcm_post_mad(msgp, &statep->stored_reply_addr, post_cb,
51117c478bd9Sstevel@tonic-gate 	    args);
51127c478bd9Sstevel@tonic-gate 	if ((status != IBT_SUCCESS) && (post_cb != NULL))
51137c478bd9Sstevel@tonic-gate 		/* Call ibmf callback directly */
51147c478bd9Sstevel@tonic-gate 		(*post_cb)(NULL, msgp, args);
51157c478bd9Sstevel@tonic-gate }
51167c478bd9Sstevel@tonic-gate 
51177c478bd9Sstevel@tonic-gate 
51187c478bd9Sstevel@tonic-gate /*
51197c478bd9Sstevel@tonic-gate  * ibcm_post_ud_mad
51207c478bd9Sstevel@tonic-gate  *	Posts a CM MAD associated with a UD statep
51217c478bd9Sstevel@tonic-gate  *
51227c478bd9Sstevel@tonic-gate  * INPUTS:
51237c478bd9Sstevel@tonic-gate  * ud_statep	: UD statep associated with the post
51247c478bd9Sstevel@tonic-gate  * msgp		: CM MAD to be posted
51257c478bd9Sstevel@tonic-gate  * post_cb	: non-NULL callback address implies non-blocking post
51267c478bd9Sstevel@tonic-gate  * args		: Args to ibmf send callback
51277c478bd9Sstevel@tonic-gate  *
51287c478bd9Sstevel@tonic-gate  * RETURN VALUE: based on ibmf_send_mad
51297c478bd9Sstevel@tonic-gate  */
51307c478bd9Sstevel@tonic-gate void
ibcm_post_ud_mad(ibcm_ud_state_data_t * ud_statep,ibmf_msg_t * msgp,ibmf_msg_cb_t ud_post_cb,void * args)51317c478bd9Sstevel@tonic-gate ibcm_post_ud_mad(ibcm_ud_state_data_t *ud_statep, ibmf_msg_t *msgp,
51327c478bd9Sstevel@tonic-gate     ibmf_msg_cb_t ud_post_cb, void *args)
51337c478bd9Sstevel@tonic-gate {
51347c478bd9Sstevel@tonic-gate 	ibt_status_t	status;
51357c478bd9Sstevel@tonic-gate 	status = ibcm_post_mad(msgp, &ud_statep->ud_stored_reply_addr,
51367c478bd9Sstevel@tonic-gate 	    ud_post_cb, args);
51377c478bd9Sstevel@tonic-gate 	if ((status != IBT_SUCCESS) && (ud_post_cb != NULL))
51387c478bd9Sstevel@tonic-gate 		/* Call ibmf callback directly */
51397c478bd9Sstevel@tonic-gate 		(*ud_post_cb)(NULL, msgp, args);
51407c478bd9Sstevel@tonic-gate }
51417c478bd9Sstevel@tonic-gate 
51427c478bd9Sstevel@tonic-gate /*
51437c478bd9Sstevel@tonic-gate  * ibcm_post_mad:
51447c478bd9Sstevel@tonic-gate  *	Posts CM MAD using IBMF in blocking mode
51457c478bd9Sstevel@tonic-gate  *
51467c478bd9Sstevel@tonic-gate  * INPUTS:
51477c478bd9Sstevel@tonic-gate  * msgp		: CM MAD to be posted
51487c478bd9Sstevel@tonic-gate  * cm_mad_addr	: Address information for the MAD to be posted
51497c478bd9Sstevel@tonic-gate  * post_cb	: non-NULL callback address implies non-blocking post
51507c478bd9Sstevel@tonic-gate  * args		: Args to ibmf send callback
51517c478bd9Sstevel@tonic-gate  *
51527c478bd9Sstevel@tonic-gate  * RETURN VALUE: based on ibmf_send_mad
51537c478bd9Sstevel@tonic-gate  */
51547c478bd9Sstevel@tonic-gate ibt_status_t
ibcm_post_mad(ibmf_msg_t * msgp,ibcm_mad_addr_t * cm_mad_addr,ibmf_msg_cb_t post_cb,void * args)51557c478bd9Sstevel@tonic-gate ibcm_post_mad(ibmf_msg_t *msgp, ibcm_mad_addr_t *cm_mad_addr,
51567c478bd9Sstevel@tonic-gate     ibmf_msg_cb_t post_cb, void *args)
51577c478bd9Sstevel@tonic-gate {
51587c478bd9Sstevel@tonic-gate 	int	post_status;
51597c478bd9Sstevel@tonic-gate 
51607c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "ibcm_post_mad: "
51617c478bd9Sstevel@tonic-gate 	    "ibmf_msg_t = %p, cm_madd_adr = %p", msgp, cm_mad_addr);
51627c478bd9Sstevel@tonic-gate 
51637c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_post_mad: dlid = %x, d_qno= %x",
51647c478bd9Sstevel@tonic-gate 	    cm_mad_addr->rcvd_addr.ia_remote_lid,
51657c478bd9Sstevel@tonic-gate 	    cm_mad_addr->rcvd_addr.ia_remote_qno);
51667c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_post_mad: p_key = %x, q_key = %x, "
51677c478bd9Sstevel@tonic-gate 	    "sl = %x, grh_exists = %x",
51687c478bd9Sstevel@tonic-gate 	    cm_mad_addr->rcvd_addr.ia_p_key, cm_mad_addr->rcvd_addr.ia_q_key,
51697c478bd9Sstevel@tonic-gate 	    cm_mad_addr->rcvd_addr.ia_service_level, cm_mad_addr->grh_exists);
51707c478bd9Sstevel@tonic-gate 
51717c478bd9Sstevel@tonic-gate 	/* Copy local addressing info */
51727c478bd9Sstevel@tonic-gate 	msgp->im_local_addr = cm_mad_addr->rcvd_addr;
51737c478bd9Sstevel@tonic-gate 
51747c478bd9Sstevel@tonic-gate 	/* Copy global/GRH addressing info */
51757c478bd9Sstevel@tonic-gate 	if (cm_mad_addr->grh_exists == B_TRUE)
51767c478bd9Sstevel@tonic-gate 		msgp->im_global_addr = cm_mad_addr->grh_hdr;
51777c478bd9Sstevel@tonic-gate 
51789d3d2ed0Shiremath 	if (post_cb)
51799d3d2ed0Shiremath 		ibcm_flow_inc();
51807c478bd9Sstevel@tonic-gate 	post_status = ibmf_msg_transport(
51817c478bd9Sstevel@tonic-gate 	    cm_mad_addr->ibmf_hdl, cm_mad_addr->cm_qp_entry->qp_cm, msgp,
51827c478bd9Sstevel@tonic-gate 	    NULL, post_cb, args, 0);
51837c478bd9Sstevel@tonic-gate 	if (post_status != IBMF_SUCCESS) {
51849d3d2ed0Shiremath 		IBTF_DPRINTF_L2(cmlog, "ibcm_post_mad: ibmf_msg_transport "
51859d3d2ed0Shiremath 		    "failed: status %d, cb = %p", post_status, post_cb);
51867c478bd9Sstevel@tonic-gate 		/* Analyze the reason for failure */
51877c478bd9Sstevel@tonic-gate 		return (ibcm_ibmf_analyze_error(post_status));
51887c478bd9Sstevel@tonic-gate 	}
51897c478bd9Sstevel@tonic-gate 
51907c478bd9Sstevel@tonic-gate 	return (IBT_SUCCESS);
51917c478bd9Sstevel@tonic-gate }
51927c478bd9Sstevel@tonic-gate 
51937c478bd9Sstevel@tonic-gate 
51947c478bd9Sstevel@tonic-gate /*
51957c478bd9Sstevel@tonic-gate  * ibcm_process_get_classport_info:
51967c478bd9Sstevel@tonic-gate  *	Get classportinfo
51977c478bd9Sstevel@tonic-gate  *
51987c478bd9Sstevel@tonic-gate  * INPUTS:
51997c478bd9Sstevel@tonic-gate  *	hcap		- HCA entry pointer
52007c478bd9Sstevel@tonic-gate  *	input_madp	- Input MAD pointer
52017c478bd9Sstevel@tonic-gate  *	cm_mad_addr	- Address information for the MAD to be posted
52027c478bd9Sstevel@tonic-gate  *
52037c478bd9Sstevel@tonic-gate  * RETURN VALUE: NONE
52047c478bd9Sstevel@tonic-gate  */
52057c478bd9Sstevel@tonic-gate static void
ibcm_process_get_classport_info(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)52067c478bd9Sstevel@tonic-gate ibcm_process_get_classport_info(ibcm_hca_info_t *hcap, uint8_t *input_madp,
52077c478bd9Sstevel@tonic-gate     ibcm_mad_addr_t *cm_mad_addr)
52087c478bd9Sstevel@tonic-gate {
52097c478bd9Sstevel@tonic-gate 	ibmf_msg_t		*msgp;
52107c478bd9Sstevel@tonic-gate 
52117c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "ibcm_process_get_classport_info: (%p, %p, %p)",
52127c478bd9Sstevel@tonic-gate 	    hcap, input_madp, cm_mad_addr);
52137c478bd9Sstevel@tonic-gate 
52147c478bd9Sstevel@tonic-gate 	if (ibcm_alloc_out_msg(cm_mad_addr->ibmf_hdl, &msgp,
52157c478bd9Sstevel@tonic-gate 	    MAD_METHOD_GET_RESPONSE) != IBT_SUCCESS) {
52167c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_process_get_classport_info: "
52177c478bd9Sstevel@tonic-gate 		    "ibcm_alloc_out_msg failed");
52187c478bd9Sstevel@tonic-gate 		return;
52197c478bd9Sstevel@tonic-gate 	}
52207c478bd9Sstevel@tonic-gate 
52217c478bd9Sstevel@tonic-gate 	/* copy the transaction id from input get mad */
52227c478bd9Sstevel@tonic-gate 	IBCM_OUT_HDRP(msgp)->TransactionID =
52237c478bd9Sstevel@tonic-gate 	    ((ib_mad_hdr_t *)(input_madp))->TransactionID;
52247c478bd9Sstevel@tonic-gate 	IBCM_OUT_HDRP(msgp)->AttributeID = h2b16(MAD_ATTR_ID_CLASSPORTINFO);
52257c478bd9Sstevel@tonic-gate 
52267c478bd9Sstevel@tonic-gate 	bcopy(&ibcm_clpinfo, IBCM_OUT_MSGP(msgp), sizeof (ibcm_clpinfo));
52277c478bd9Sstevel@tonic-gate 
52287c478bd9Sstevel@tonic-gate 	(void) ibcm_post_mad(msgp, cm_mad_addr, NULL, NULL);
52297c478bd9Sstevel@tonic-gate 	(void) ibcm_free_out_msg(cm_mad_addr->ibmf_hdl, &msgp);
52307c478bd9Sstevel@tonic-gate 
52317c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_get_classport_info: done");
52327c478bd9Sstevel@tonic-gate }
52337c478bd9Sstevel@tonic-gate 
52347c478bd9Sstevel@tonic-gate /*
52357c478bd9Sstevel@tonic-gate  * ibcm_decode_classport_info:
52367c478bd9Sstevel@tonic-gate  *	Decode classportinfo
52377c478bd9Sstevel@tonic-gate  *
52387c478bd9Sstevel@tonic-gate  * INPUTS:
52397c478bd9Sstevel@tonic-gate  *	hcap		- HCA entry pointer
52407c478bd9Sstevel@tonic-gate  *	cm_mad_addr	- Address information for the MAD to be posted
52417c478bd9Sstevel@tonic-gate  *	input_madp	- Input MAD pointer
52427c478bd9Sstevel@tonic-gate  *
52437c478bd9Sstevel@tonic-gate  * RETURN VALUE: NONE
52447c478bd9Sstevel@tonic-gate  */
52457c478bd9Sstevel@tonic-gate static void
ibcm_decode_classport_info(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)52467c478bd9Sstevel@tonic-gate ibcm_decode_classport_info(ibcm_hca_info_t *hcap, uint8_t *input_madp,
52477c478bd9Sstevel@tonic-gate     ibcm_mad_addr_t *cm_mad_addr)
52487c478bd9Sstevel@tonic-gate {
52497c478bd9Sstevel@tonic-gate 	ibcm_classportinfo_msg_t *portinfop = (ibcm_classportinfo_msg_t *)
5250015f8fffShiremath 	    (&input_madp[IBCM_MAD_HDR_SIZE]);
52517c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "ibcm_decode_classport_info: (%p, %p, %p)",
52527c478bd9Sstevel@tonic-gate 	    hcap, input_madp, cm_mad_addr);
52537c478bd9Sstevel@tonic-gate 
52547c478bd9Sstevel@tonic-gate 	/* Print various fields of received classportinfo in debuf buf */
52557c478bd9Sstevel@tonic-gate 
52567c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_decode_classport_info: "
52577c478bd9Sstevel@tonic-gate 	    "Base version %d Class version %d", portinfop->BaseVersion,
52587c478bd9Sstevel@tonic-gate 	    portinfop->ClassVersion);
52597c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_decode_classport_info: "
52607c478bd9Sstevel@tonic-gate 	    "Cap Mask %d Resp Time %d", portinfop->CapabilityMask,
52617c478bd9Sstevel@tonic-gate 	    portinfop->RespTimeValue_plus);
52627c478bd9Sstevel@tonic-gate }
52637c478bd9Sstevel@tonic-gate 
52647c478bd9Sstevel@tonic-gate 
52657c478bd9Sstevel@tonic-gate /*
52667c478bd9Sstevel@tonic-gate  * ibcm_handler_conn_fail:
52677c478bd9Sstevel@tonic-gate  *	Helper function used to call client handler for Conn fail event
52687c478bd9Sstevel@tonic-gate  *
52697c478bd9Sstevel@tonic-gate  * INPUTS:
52707c478bd9Sstevel@tonic-gate  *	statep:			The connection state pointer
52717c478bd9Sstevel@tonic-gate  *	rej_type:		Message being rejected
52727c478bd9Sstevel@tonic-gate  *	rej_reason:		Reason why CM is sending the REJ message
52737c478bd9Sstevel@tonic-gate  *	client_data:		Private data returned by the client for REJ
52747c478bd9Sstevel@tonic-gate  *	client_data_len:	Length of above client's private data.
52757c478bd9Sstevel@tonic-gate  *
52767c478bd9Sstevel@tonic-gate  * RETURN VALUE:	Client Handler's return status
52777c478bd9Sstevel@tonic-gate  */
52787c478bd9Sstevel@tonic-gate static void
ibcm_handler_conn_fail(ibcm_state_data_t * statep,uint8_t cf_code,uint8_t cf_msg,ibt_cm_reason_t cf_reason,uint8_t * client_data,ibt_priv_data_len_t client_data_len)52797c478bd9Sstevel@tonic-gate ibcm_handler_conn_fail(ibcm_state_data_t *statep, uint8_t cf_code,
52807c478bd9Sstevel@tonic-gate     uint8_t cf_msg, ibt_cm_reason_t cf_reason, uint8_t *client_data,
52817c478bd9Sstevel@tonic-gate     ibt_priv_data_len_t client_data_len)
52827c478bd9Sstevel@tonic-gate {
52837c478bd9Sstevel@tonic-gate 	ibt_cm_event_t	event;
52847c478bd9Sstevel@tonic-gate 
5285fde3102fShiremath 	ibcm_path_cache_purge();
5286fde3102fShiremath 
5287ea46d761SPramod Gunjikar 	if (statep->channel)
5288ea46d761SPramod Gunjikar 		ibtl_cm_chan_open_is_aborted(statep->channel);
5289a23420cfSShantkumar Hiremath 
52907c478bd9Sstevel@tonic-gate 	/* Invoke CM handler w/ event passed as arg */
52917c478bd9Sstevel@tonic-gate 	if (statep->cm_handler != NULL) {
52927c478bd9Sstevel@tonic-gate 		bzero(&event, sizeof (ibt_cm_event_t));
52937c478bd9Sstevel@tonic-gate 
52947c478bd9Sstevel@tonic-gate 		event.cm_type = IBT_CM_EVENT_FAILURE;
52957c478bd9Sstevel@tonic-gate 		event.cm_channel = statep->channel;
52967c478bd9Sstevel@tonic-gate 		event.cm_session_id = NULL;
52977c478bd9Sstevel@tonic-gate 		event.cm_priv_data = NULL;
52987c478bd9Sstevel@tonic-gate 		event.cm_priv_data_len = 0;
52997c478bd9Sstevel@tonic-gate 
53007c478bd9Sstevel@tonic-gate 		event.cm_event.failed.cf_code = cf_code;
53017c478bd9Sstevel@tonic-gate 		event.cm_event.failed.cf_msg =  cf_msg;
53027c478bd9Sstevel@tonic-gate 		event.cm_event.failed.cf_reason =  cf_reason;
53037c478bd9Sstevel@tonic-gate 
53047c478bd9Sstevel@tonic-gate 		ibcm_insert_trace(statep, IBCM_TRACE_CALLED_CONN_FAIL_EVENT);
53057c478bd9Sstevel@tonic-gate 
53067c478bd9Sstevel@tonic-gate 		(void) statep->cm_handler(statep->state_cm_private, &event,
53077c478bd9Sstevel@tonic-gate 		    NULL, client_data, client_data_len);
53087c478bd9Sstevel@tonic-gate 
53097c478bd9Sstevel@tonic-gate 		ibcm_insert_trace(statep, IBCM_TRACE_RET_CONN_FAIL_EVENT);
53107c478bd9Sstevel@tonic-gate 	}
53117c478bd9Sstevel@tonic-gate 	if (ibcm_enable_trace != 0)
53127c478bd9Sstevel@tonic-gate 		ibcm_dump_conn_trace(statep);
53139d3d2ed0Shiremath 	mutex_enter(&statep->state_mutex);
53149d3d2ed0Shiremath 	ibcm_open_done(statep);
53159d3d2ed0Shiremath 	mutex_exit(&statep->state_mutex);
53167c478bd9Sstevel@tonic-gate }
53177c478bd9Sstevel@tonic-gate 
53187c478bd9Sstevel@tonic-gate /*
53197c478bd9Sstevel@tonic-gate  * QP State transition functions here
53207c478bd9Sstevel@tonic-gate  *
53217c478bd9Sstevel@tonic-gate  * The brief description of these functions :
53227c478bd9Sstevel@tonic-gate  *	Validate QP related attributes in the messages
53237c478bd9Sstevel@tonic-gate  *	Call client/server callback handlers
53247c478bd9Sstevel@tonic-gate  *	Change QP state
53257c478bd9Sstevel@tonic-gate  *	Set QP attributes (modify QP)
53267c478bd9Sstevel@tonic-gate  *	Fill up the response MADs
53277c478bd9Sstevel@tonic-gate  */
53287c478bd9Sstevel@tonic-gate 
53297c478bd9Sstevel@tonic-gate /*
53307c478bd9Sstevel@tonic-gate  * ibcm_set_primary_adds_vect:
53317c478bd9Sstevel@tonic-gate  *	Helper function used to fill up ibt_adds_vect_t PRIMARY PATH
53327c478bd9Sstevel@tonic-gate  *	(called from ibcm_cep_state_*() functions)
53337c478bd9Sstevel@tonic-gate  *
53347c478bd9Sstevel@tonic-gate  * INPUTS:
53357c478bd9Sstevel@tonic-gate  * statep	: The connection state pointer
53367c478bd9Sstevel@tonic-gate  * adds_vectp	: The ibt_adds_vect_t ptr that is being filled up
53377c478bd9Sstevel@tonic-gate  * msgp		: CM REQ message that is the source of information
53387c478bd9Sstevel@tonic-gate  *
53397c478bd9Sstevel@tonic-gate  * RETURN VALUE:	NONE
53407c478bd9Sstevel@tonic-gate  */
53417c478bd9Sstevel@tonic-gate static void
ibcm_set_primary_adds_vect(ibcm_state_data_t * statep,ibt_adds_vect_t * adds_vectp,ibcm_req_msg_t * msgp)53427c478bd9Sstevel@tonic-gate ibcm_set_primary_adds_vect(ibcm_state_data_t *statep,
53437c478bd9Sstevel@tonic-gate     ibt_adds_vect_t *adds_vectp, ibcm_req_msg_t *msgp)
53447c478bd9Sstevel@tonic-gate {
53457c478bd9Sstevel@tonic-gate 	uint32_t flow_label20_res6_rate6;
53467c478bd9Sstevel@tonic-gate 
53477c478bd9Sstevel@tonic-gate 	flow_label20_res6_rate6 = b2h32(msgp->req_primary_flow_label_plus);
53487c478bd9Sstevel@tonic-gate 
53497c478bd9Sstevel@tonic-gate 	/* first setup the srvl, srate, dlid and dgid */
53507c478bd9Sstevel@tonic-gate 	adds_vectp->av_srvl = msgp->req_primary_sl_plus >> 4;
53517c478bd9Sstevel@tonic-gate 	adds_vectp->av_src_path = statep->prim_src_path_bits;
53527c478bd9Sstevel@tonic-gate 
53537c478bd9Sstevel@tonic-gate 	if (statep->mode == IBCM_PASSIVE_MODE) {
53547c478bd9Sstevel@tonic-gate 		adds_vectp->av_dlid = b2h16(msgp->req_primary_l_port_lid);
53557c478bd9Sstevel@tonic-gate 		adds_vectp->av_dgid.gid_prefix =
5356015f8fffShiremath 		    b2h64(msgp->req_primary_l_port_gid.gid_prefix);
53577c478bd9Sstevel@tonic-gate 		adds_vectp->av_dgid.gid_guid =
5358015f8fffShiremath 		    b2h64(msgp->req_primary_l_port_gid.gid_guid);
53597c478bd9Sstevel@tonic-gate 		adds_vectp->av_sgid.gid_prefix =
5360015f8fffShiremath 		    b2h64(msgp->req_primary_r_port_gid.gid_prefix);
53617c478bd9Sstevel@tonic-gate 		adds_vectp->av_sgid.gid_guid =
5362015f8fffShiremath 		    b2h64(msgp->req_primary_r_port_gid.gid_guid);
53637c478bd9Sstevel@tonic-gate 		adds_vectp->av_srate = flow_label20_res6_rate6 & 0x3f;
53647c478bd9Sstevel@tonic-gate 	} else {
53657c478bd9Sstevel@tonic-gate 		adds_vectp->av_dlid = b2h16(msgp->req_primary_r_port_lid);
53667c478bd9Sstevel@tonic-gate 		adds_vectp->av_dgid.gid_prefix =
5367015f8fffShiremath 		    b2h64(msgp->req_primary_r_port_gid.gid_prefix);
53687c478bd9Sstevel@tonic-gate 		adds_vectp->av_dgid.gid_guid =
5369015f8fffShiremath 		    b2h64(msgp->req_primary_r_port_gid.gid_guid);
53707c478bd9Sstevel@tonic-gate 		adds_vectp->av_sgid.gid_prefix =
5371015f8fffShiremath 		    b2h64(msgp->req_primary_l_port_gid.gid_prefix);
53727c478bd9Sstevel@tonic-gate 		adds_vectp->av_sgid.gid_guid =
5373015f8fffShiremath 		    b2h64(msgp->req_primary_l_port_gid.gid_guid);
53747c478bd9Sstevel@tonic-gate 		adds_vectp->av_srate = statep->local_srate;
53757c478bd9Sstevel@tonic-gate 	}
53767c478bd9Sstevel@tonic-gate 
53777c478bd9Sstevel@tonic-gate 	/* next copy off the GRH info if it exists  */
53787c478bd9Sstevel@tonic-gate 	if ((msgp->req_primary_sl_plus & 0x8) == 0) {
53797c478bd9Sstevel@tonic-gate 		adds_vectp->av_send_grh = B_TRUE;
53807c478bd9Sstevel@tonic-gate 		adds_vectp->av_flow = flow_label20_res6_rate6 >> 12;
53817c478bd9Sstevel@tonic-gate 		adds_vectp->av_tclass = msgp->req_primary_traffic_class;
53827c478bd9Sstevel@tonic-gate 		adds_vectp->av_hop = msgp->req_primary_hop_limit;
53837c478bd9Sstevel@tonic-gate 	} else {
53847c478bd9Sstevel@tonic-gate 		adds_vectp->av_send_grh = B_FALSE;
53857c478bd9Sstevel@tonic-gate 	}
53867c478bd9Sstevel@tonic-gate }
53877c478bd9Sstevel@tonic-gate 
53887c478bd9Sstevel@tonic-gate 
53897c478bd9Sstevel@tonic-gate /*
53907c478bd9Sstevel@tonic-gate  * ibcm_set_alt_adds_vect:
53917c478bd9Sstevel@tonic-gate  *	Helper function used to fill up ibt_adds_vect_t ALTERNATE PATH
53927c478bd9Sstevel@tonic-gate  *	(called from ibcm_cep_state_*() functions)
53937c478bd9Sstevel@tonic-gate  *
53947c478bd9Sstevel@tonic-gate  * INPUTS:
53957c478bd9Sstevel@tonic-gate  * statep	: The connection state pointer
53967c478bd9Sstevel@tonic-gate  * adds_vectp	: The ibt_adds_vect_t ptr that is being filled up
53977c478bd9Sstevel@tonic-gate  * msgp		: CM REQ message that is the source of information
53987c478bd9Sstevel@tonic-gate  *
53997c478bd9Sstevel@tonic-gate  * RETURN VALUE:	NONE
54007c478bd9Sstevel@tonic-gate  */
54017c478bd9Sstevel@tonic-gate static void
ibcm_set_alt_adds_vect(ibcm_state_data_t * statep,ibt_adds_vect_t * adds_vectp,ibcm_req_msg_t * msgp)54027c478bd9Sstevel@tonic-gate ibcm_set_alt_adds_vect(ibcm_state_data_t *statep,
54037c478bd9Sstevel@tonic-gate     ibt_adds_vect_t *adds_vectp, ibcm_req_msg_t *msgp)
54047c478bd9Sstevel@tonic-gate {
54057c478bd9Sstevel@tonic-gate 	ib_gid_t dgid;
54067c478bd9Sstevel@tonic-gate 	ib_gid_t sgid;
54077c478bd9Sstevel@tonic-gate 	uint32_t flow_label20_res6_rate6;
54087c478bd9Sstevel@tonic-gate 
54097c478bd9Sstevel@tonic-gate 	flow_label20_res6_rate6 = b2h32(msgp->req_alt_flow_label_plus);
54107c478bd9Sstevel@tonic-gate 
54117c478bd9Sstevel@tonic-gate 	/* first setup the srvl, srate, dlid and dgid */
54127c478bd9Sstevel@tonic-gate 	adds_vectp->av_srvl = msgp->req_alt_sl_plus >> 4;
54137c478bd9Sstevel@tonic-gate 	adds_vectp->av_src_path = statep->alt_src_path_bits;
54147c478bd9Sstevel@tonic-gate 
54157c478bd9Sstevel@tonic-gate 	if (statep->mode == IBCM_PASSIVE_MODE) {
54167c478bd9Sstevel@tonic-gate 		adds_vectp->av_dlid = b2h16(msgp->req_alt_l_port_lid);
54177c478bd9Sstevel@tonic-gate 		bcopy(&msgp->req_alt_l_port_gid[0], &dgid, sizeof (ib_gid_t));
54187c478bd9Sstevel@tonic-gate 		bcopy(&msgp->req_alt_r_port_gid[0], &sgid, sizeof (ib_gid_t));
54197c478bd9Sstevel@tonic-gate 		adds_vectp->av_srate = flow_label20_res6_rate6 & 0x3f;
54207c478bd9Sstevel@tonic-gate 	} else {
54217c478bd9Sstevel@tonic-gate 		adds_vectp->av_dlid = b2h16(msgp->req_alt_r_port_lid);
54227c478bd9Sstevel@tonic-gate 		bcopy(&msgp->req_alt_r_port_gid[0], &dgid, sizeof (ib_gid_t));
54237c478bd9Sstevel@tonic-gate 		bcopy(&msgp->req_alt_l_port_gid[0], &sgid, sizeof (ib_gid_t));
54247c478bd9Sstevel@tonic-gate 		adds_vectp->av_srate = statep->local_alt_srate;
54257c478bd9Sstevel@tonic-gate 	}
54267c478bd9Sstevel@tonic-gate 	adds_vectp->av_dgid.gid_prefix = b2h64(dgid.gid_prefix);
54277c478bd9Sstevel@tonic-gate 	adds_vectp->av_dgid.gid_guid = b2h64(dgid.gid_guid);
54287c478bd9Sstevel@tonic-gate 	adds_vectp->av_sgid.gid_prefix = b2h64(sgid.gid_prefix);
54297c478bd9Sstevel@tonic-gate 	adds_vectp->av_sgid.gid_guid = b2h64(sgid.gid_guid);
54307c478bd9Sstevel@tonic-gate 
54317c478bd9Sstevel@tonic-gate 	/* next copy off the GRH info if it exists  */
54327c478bd9Sstevel@tonic-gate 	if ((msgp->req_alt_sl_plus & 0x8) == 0) {
54337c478bd9Sstevel@tonic-gate 		adds_vectp->av_send_grh = B_TRUE;
54347c478bd9Sstevel@tonic-gate 		adds_vectp->av_flow = flow_label20_res6_rate6 >> 12;
54357c478bd9Sstevel@tonic-gate 		adds_vectp->av_tclass = msgp->req_alt_traffic_class;
54367c478bd9Sstevel@tonic-gate 		adds_vectp->av_hop = msgp->req_alt_hop_limit;
54377c478bd9Sstevel@tonic-gate 	} else {
54387c478bd9Sstevel@tonic-gate 		adds_vectp->av_send_grh = B_FALSE;	/* no GRH */
54397c478bd9Sstevel@tonic-gate 	}
54407c478bd9Sstevel@tonic-gate }
54417c478bd9Sstevel@tonic-gate 
54427c478bd9Sstevel@tonic-gate 
54437c478bd9Sstevel@tonic-gate /*
54447c478bd9Sstevel@tonic-gate  * ibcm_set_primary_cep_path:
54457c478bd9Sstevel@tonic-gate  *	Helper function used to fill up ibt_cep_path_t PRIMARY PATH
54467c478bd9Sstevel@tonic-gate  *	(called from ibcm_cep_state_*() functions)
54477c478bd9Sstevel@tonic-gate  *
54487c478bd9Sstevel@tonic-gate  * INPUTS:
54497c478bd9Sstevel@tonic-gate  * statep	: The connection state pointer
54507c478bd9Sstevel@tonic-gate  * adds_vectp	: The ibt_cep_path_t ptr that is being filled up
54517c478bd9Sstevel@tonic-gate  * msgp		: CM REQ message that is the source of information
54527c478bd9Sstevel@tonic-gate  *
54537c478bd9Sstevel@tonic-gate  * RETURN VALUE:	NONE
54547c478bd9Sstevel@tonic-gate  */
54557c478bd9Sstevel@tonic-gate static ibt_status_t
ibcm_set_primary_cep_path(ibcm_state_data_t * statep,ibt_cep_path_t * pathp,ibcm_req_msg_t * msgp)54567c478bd9Sstevel@tonic-gate ibcm_set_primary_cep_path(ibcm_state_data_t *statep, ibt_cep_path_t *pathp,
54577c478bd9Sstevel@tonic-gate     ibcm_req_msg_t *msgp)
54587c478bd9Sstevel@tonic-gate {
54597c478bd9Sstevel@tonic-gate 	ibt_status_t		status;
54607c478bd9Sstevel@tonic-gate 
54617c478bd9Sstevel@tonic-gate 	/* validate the PKEY in REQ for prim port */
54627c478bd9Sstevel@tonic-gate 	status = ibt_pkey2index_byguid(statep->local_hca_guid,
54637c478bd9Sstevel@tonic-gate 	    statep->prim_port, b2h16(msgp->req_part_key), &pathp->cep_pkey_ix);
54647c478bd9Sstevel@tonic-gate 
54657c478bd9Sstevel@tonic-gate 	if (status != IBT_SUCCESS) {
54667c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_set_primary_cep_path: "
54677c478bd9Sstevel@tonic-gate 		    "statep 0x%p pkey %x prim_port %d ", statep,
54687c478bd9Sstevel@tonic-gate 		    b2h16(msgp->req_part_key), statep->prim_port);
54697c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_set_primary_cep_path: "
54707c478bd9Sstevel@tonic-gate 		    "statep 0x%p Invalid PKEY on prim_port, status %d ",
54717c478bd9Sstevel@tonic-gate 		    statep, status);
54727c478bd9Sstevel@tonic-gate 		return (status);
54737c478bd9Sstevel@tonic-gate 	}
54747c478bd9Sstevel@tonic-gate 	statep->pkey = b2h16(msgp->req_part_key);
54757c478bd9Sstevel@tonic-gate 	ibcm_set_primary_adds_vect(statep, &pathp->cep_adds_vect, msgp);
54767c478bd9Sstevel@tonic-gate 	return (IBT_SUCCESS);
54777c478bd9Sstevel@tonic-gate }
54787c478bd9Sstevel@tonic-gate 
54797c478bd9Sstevel@tonic-gate 
54807c478bd9Sstevel@tonic-gate /*
54817c478bd9Sstevel@tonic-gate  * ibcm_set_alt_cep_path:
54827c478bd9Sstevel@tonic-gate  *	Helper function used to fill up ibt_cep_path_t ALTERNATE PATH
54837c478bd9Sstevel@tonic-gate  *	(called from ibcm_cep_state_*() functions)
54847c478bd9Sstevel@tonic-gate  *
54857c478bd9Sstevel@tonic-gate  * INPUTS:
54867c478bd9Sstevel@tonic-gate  * statep	: The connection state pointer
54877c478bd9Sstevel@tonic-gate  * adds_vectp	: The ibt_cep_path_t ptr that is being filled up
54887c478bd9Sstevel@tonic-gate  * msgp		: CM REQ message that is the source of information
54897c478bd9Sstevel@tonic-gate  *
54907c478bd9Sstevel@tonic-gate  * RETURN VALUE:	NONE
54917c478bd9Sstevel@tonic-gate  */
54927c478bd9Sstevel@tonic-gate static ibt_status_t
ibcm_set_alt_cep_path(ibcm_state_data_t * statep,ibt_cep_path_t * pathp,ibcm_req_msg_t * msgp)54937c478bd9Sstevel@tonic-gate ibcm_set_alt_cep_path(ibcm_state_data_t *statep, ibt_cep_path_t *pathp,
54947c478bd9Sstevel@tonic-gate     ibcm_req_msg_t *msgp)
54957c478bd9Sstevel@tonic-gate {
54967c478bd9Sstevel@tonic-gate 	ibt_status_t		status;
54977c478bd9Sstevel@tonic-gate 
54987c478bd9Sstevel@tonic-gate 	if (b2h16(msgp->req_alt_l_port_lid) == 0) {
54997c478bd9Sstevel@tonic-gate 		/* no alternate path specified */
55007c478bd9Sstevel@tonic-gate 		return (IBT_SUCCESS);
55017c478bd9Sstevel@tonic-gate 	}
55027c478bd9Sstevel@tonic-gate 
55037c478bd9Sstevel@tonic-gate 	/* validate the PKEY in REQ for alt port */
55047c478bd9Sstevel@tonic-gate 	status = ibt_pkey2index_byguid(statep->local_hca_guid,
55057c478bd9Sstevel@tonic-gate 	    statep->alt_port, b2h16(msgp->req_part_key), &pathp->cep_pkey_ix);
55067c478bd9Sstevel@tonic-gate 
55077c478bd9Sstevel@tonic-gate 	if (status != IBT_SUCCESS) {
55087c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_set_alt_cep_path: "
55097c478bd9Sstevel@tonic-gate 		    "statep 0x%p pkey %x alt_port %d ", statep,
55107c478bd9Sstevel@tonic-gate 		    b2h16(msgp->req_part_key), statep->alt_port);
55117c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_set_alt_cep_path: "
55127c478bd9Sstevel@tonic-gate 		    "statep 0x%p Invalid PKEY on alt_port, status %d ",
55137c478bd9Sstevel@tonic-gate 		    statep, status);
55147c478bd9Sstevel@tonic-gate 		return (status);
55157c478bd9Sstevel@tonic-gate 	}
55167c478bd9Sstevel@tonic-gate 	pathp->cep_hca_port_num = statep->alt_port;
55177c478bd9Sstevel@tonic-gate 	ibcm_set_alt_adds_vect(statep, &pathp->cep_adds_vect, msgp);
55187c478bd9Sstevel@tonic-gate 	return (IBT_SUCCESS);
55197c478bd9Sstevel@tonic-gate 
55207c478bd9Sstevel@tonic-gate }
55217c478bd9Sstevel@tonic-gate 
55227c478bd9Sstevel@tonic-gate /*
55237c478bd9Sstevel@tonic-gate  * ibcm_compare_prim_alt_paths:
55247c478bd9Sstevel@tonic-gate  *	Helper function used to find if primary and alternate paths are
55257c478bd9Sstevel@tonic-gate  *	identical
55267c478bd9Sstevel@tonic-gate  *	(called from ibcm_cep_state_req)
55277c478bd9Sstevel@tonic-gate  *
55287c478bd9Sstevel@tonic-gate  * INPUTS:
55297c478bd9Sstevel@tonic-gate  * req:			Pointer to ibt_cm_req_rcv_t, filled before invoking
55307c478bd9Sstevel@tonic-gate  *			the function
55317c478bd9Sstevel@tonic-gate  *
55327c478bd9Sstevel@tonic-gate  * RETURN VALUE:	NONE
55337c478bd9Sstevel@tonic-gate  */
55347c478bd9Sstevel@tonic-gate 
55357c478bd9Sstevel@tonic-gate static boolean_t
ibcm_compare_prim_alt_paths(ibt_adds_vect_t * prim,ibt_adds_vect_t * alt)55367c478bd9Sstevel@tonic-gate ibcm_compare_prim_alt_paths(ibt_adds_vect_t *prim, ibt_adds_vect_t *alt)
55377c478bd9Sstevel@tonic-gate {
55387c478bd9Sstevel@tonic-gate 
55397c478bd9Sstevel@tonic-gate 	if ((alt->av_dlid == prim->av_dlid) &&
55407c478bd9Sstevel@tonic-gate 	    (alt->av_dgid.gid_prefix == prim->av_dgid.gid_prefix) &&
55417c478bd9Sstevel@tonic-gate 	    (alt->av_dgid.gid_guid == prim->av_dgid.gid_guid) &&
55427c478bd9Sstevel@tonic-gate 	    (alt->av_sgid.gid_prefix == prim->av_sgid.gid_prefix) &&
55437c478bd9Sstevel@tonic-gate 	    (alt->av_sgid.gid_guid == prim->av_sgid.gid_guid) &&
55447c478bd9Sstevel@tonic-gate 	    (alt->av_src_path == prim->av_src_path)) {
55457c478bd9Sstevel@tonic-gate 
55467c478bd9Sstevel@tonic-gate 		return (B_TRUE);
55477c478bd9Sstevel@tonic-gate 	}
55487c478bd9Sstevel@tonic-gate 	return (B_FALSE);
55497c478bd9Sstevel@tonic-gate }
55507c478bd9Sstevel@tonic-gate 
55517c478bd9Sstevel@tonic-gate 
55527c478bd9Sstevel@tonic-gate /*
55537c478bd9Sstevel@tonic-gate  * ibcm_invoke_qp_modify:
55547c478bd9Sstevel@tonic-gate  *	Helper function used to call ibt_modify_qp()
55557c478bd9Sstevel@tonic-gate  *	called from ibcm_cep_state_req()/ibcm_cep_state_rep()
55567c478bd9Sstevel@tonic-gate  *	It sets up qp_info/eec_info
55577c478bd9Sstevel@tonic-gate  *
55587c478bd9Sstevel@tonic-gate  *	Sets state to RTR as well.
55597c478bd9Sstevel@tonic-gate  *
55607c478bd9Sstevel@tonic-gate  *
55617c478bd9Sstevel@tonic-gate  * INPUTS:
55627c478bd9Sstevel@tonic-gate  *	statep:		The connection state pointer
55637c478bd9Sstevel@tonic-gate  *	req_msgp:	The CM REQ message
55647c478bd9Sstevel@tonic-gate  *
55657c478bd9Sstevel@tonic-gate  * RETURN VALUE:
55667c478bd9Sstevel@tonic-gate  *	IBT_SUCCESS	-	call succeeded
55677c478bd9Sstevel@tonic-gate  */
55687c478bd9Sstevel@tonic-gate static ibt_status_t
ibcm_invoke_qp_modify(ibcm_state_data_t * statep,ibcm_req_msg_t * req_msgp,ibcm_rep_msg_t * rep_msgp)55697c478bd9Sstevel@tonic-gate ibcm_invoke_qp_modify(ibcm_state_data_t *statep, ibcm_req_msg_t *req_msgp,
55707c478bd9Sstevel@tonic-gate     ibcm_rep_msg_t *rep_msgp)
55717c478bd9Sstevel@tonic-gate {
55727c478bd9Sstevel@tonic-gate 	ibt_status_t		status;
55737c478bd9Sstevel@tonic-gate 	ibt_qp_info_t		qp_info;
55747c478bd9Sstevel@tonic-gate 	ibt_cep_modify_flags_t	cep_flags;
55757c478bd9Sstevel@tonic-gate 	ibt_tran_srv_t		trans;
55767c478bd9Sstevel@tonic-gate 
55777c478bd9Sstevel@tonic-gate 	cep_flags = IBT_CEP_SET_INIT_RTR | IBT_CEP_SET_PKEY_IX;
55787c478bd9Sstevel@tonic-gate 	trans = ((uint8_t *)&req_msgp->req_remote_eecn_plus)[3] >> 1 & 0x3;
55797c478bd9Sstevel@tonic-gate 
55807c478bd9Sstevel@tonic-gate 	ASSERT(statep->channel != NULL);
55817c478bd9Sstevel@tonic-gate 
55827c478bd9Sstevel@tonic-gate 	/*
55837c478bd9Sstevel@tonic-gate 	 * If alternate path is present in REQ message then
55847c478bd9Sstevel@tonic-gate 	 * OR in IBT_CEP_SET_ALT_PATH, if APM supported on hca
55857c478bd9Sstevel@tonic-gate 	 */
55867c478bd9Sstevel@tonic-gate 	if (b2h16(req_msgp->req_alt_l_port_lid) != 0) {
55877c478bd9Sstevel@tonic-gate 
55887c478bd9Sstevel@tonic-gate 		if (statep->hcap->hca_caps & IBT_HCA_AUTO_PATH_MIG)
55897c478bd9Sstevel@tonic-gate 			cep_flags |= IBT_CEP_SET_ALT_PATH;
55907c478bd9Sstevel@tonic-gate 			/* default value of rep_failover is ACCEPT */
55917c478bd9Sstevel@tonic-gate 		else {
55927c478bd9Sstevel@tonic-gate 			rep_msgp->rep_target_delay_plus |=
55937c478bd9Sstevel@tonic-gate 			    IBT_CM_FAILOVER_REJ_NOTSUPP << 1;
55947c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L3(cmlog, "ibcm_invoke_qp_modify"
55957c478bd9Sstevel@tonic-gate 			    " Alt Path specified in REQ, but not supported");
55967c478bd9Sstevel@tonic-gate 		}
55977c478bd9Sstevel@tonic-gate 	}
55987c478bd9Sstevel@tonic-gate 
55997c478bd9Sstevel@tonic-gate 	/* If transport type is RD OR in IBC_CEP_SET_QKEY */
56007c478bd9Sstevel@tonic-gate 	if (trans == IBT_RD_SRV) {
56017c478bd9Sstevel@tonic-gate 		cep_flags |= IBT_CEP_SET_QKEY;
56027c478bd9Sstevel@tonic-gate 	}
56037c478bd9Sstevel@tonic-gate 
56047c478bd9Sstevel@tonic-gate 	/* Start filling up ibt_qp_info_t.  */
56057c478bd9Sstevel@tonic-gate 	bzero(&qp_info, sizeof (qp_info));
56067c478bd9Sstevel@tonic-gate 	qp_info.qp_trans = trans;
56077c478bd9Sstevel@tonic-gate 	qp_info.qp_state = IBT_STATE_RTR;
56087c478bd9Sstevel@tonic-gate 	qp_info.qp_flags = IBT_CEP_NO_FLAGS;
56097c478bd9Sstevel@tonic-gate 
56107c478bd9Sstevel@tonic-gate 	switch (trans) {
56117c478bd9Sstevel@tonic-gate 	case IBT_RC_SRV:
56127c478bd9Sstevel@tonic-gate 
56137c478bd9Sstevel@tonic-gate 		if (statep->mode == IBCM_ACTIVE_MODE) {
56147c478bd9Sstevel@tonic-gate 			/* Setting PSN on RQ */
56157c478bd9Sstevel@tonic-gate 
56167c478bd9Sstevel@tonic-gate 			IBCM_QPINFO_RC(qp_info).rc_rq_psn =
56177c478bd9Sstevel@tonic-gate 			    b2h32(req_msgp->req_starting_psn_plus) >> 8;
56187c478bd9Sstevel@tonic-gate 
56197c478bd9Sstevel@tonic-gate 			IBCM_QPINFO_RC(qp_info).rc_dst_qpn =
56207c478bd9Sstevel@tonic-gate 			    b2h32(rep_msgp->rep_local_qpn_plus) >> 8;
56217c478bd9Sstevel@tonic-gate 
56227c478bd9Sstevel@tonic-gate 			/* RDMA resources taken from negotiated REP values */
56237c478bd9Sstevel@tonic-gate 			IBCM_QPINFO_RC(qp_info).rc_rdma_ra_in =
56247c478bd9Sstevel@tonic-gate 			    rep_msgp->rep_initiator_depth;
56257c478bd9Sstevel@tonic-gate 
56267c478bd9Sstevel@tonic-gate 		} else { /* Passive side CM */
56277c478bd9Sstevel@tonic-gate 			/* Setting PSN on SQ and RQ */
56289c468ea9SPramod Gunjikar 			IBCM_QPINFO_RC(qp_info).rc_sq_psn =
56299c468ea9SPramod Gunjikar 			    IBCM_QPINFO_RC(qp_info).rc_rq_psn =
56307c478bd9Sstevel@tonic-gate 			    b2h32(rep_msgp->rep_starting_psn_plus) >> 8;
56317c478bd9Sstevel@tonic-gate 
56327c478bd9Sstevel@tonic-gate 			IBCM_QPINFO_RC(qp_info).rc_dst_qpn =
56337c478bd9Sstevel@tonic-gate 			    b2h32(req_msgp->req_local_qpn_plus) >> 8;
56347c478bd9Sstevel@tonic-gate 
56357c478bd9Sstevel@tonic-gate 			/* RDMA resources taken from negotiated REP values */
56367c478bd9Sstevel@tonic-gate 			IBCM_QPINFO_RC(qp_info).rc_rdma_ra_in =
56377c478bd9Sstevel@tonic-gate 			    rep_msgp->rep_resp_resources;
56387c478bd9Sstevel@tonic-gate 		}
56397c478bd9Sstevel@tonic-gate 
56407c478bd9Sstevel@tonic-gate 		/* XXX, Oh!, ibtl doesn't have interface for setting this */
56417c478bd9Sstevel@tonic-gate 		IBCM_QPINFO_RC(qp_info).rc_min_rnr_nak =
56427c478bd9Sstevel@tonic-gate 		    ibcm_default_rnr_nak_time;
56437c478bd9Sstevel@tonic-gate 		IBCM_QPINFO_RC(qp_info).rc_path_mtu =
56447c478bd9Sstevel@tonic-gate 		    req_msgp->req_mtu_plus >> 4;
56457c478bd9Sstevel@tonic-gate 		IBCM_QPINFO_RC(qp_info).rc_retry_cnt =
56467c478bd9Sstevel@tonic-gate 		    ((uint8_t *)&req_msgp->req_starting_psn_plus)[3] & 0x7;
56477c478bd9Sstevel@tonic-gate 		IBCM_QPINFO_RC(qp_info).rc_rnr_retry_cnt =
56487c478bd9Sstevel@tonic-gate 		    req_msgp->req_mtu_plus & 0x7;
56497c478bd9Sstevel@tonic-gate 
56507c478bd9Sstevel@tonic-gate 		if ((status = ibcm_set_primary_cep_path(statep,
56517c478bd9Sstevel@tonic-gate 		    &IBCM_QPINFO_RC(qp_info).rc_path, req_msgp)) !=
56527c478bd9Sstevel@tonic-gate 		    IBT_SUCCESS)
56537c478bd9Sstevel@tonic-gate 			return (status);
56547c478bd9Sstevel@tonic-gate 
56557c478bd9Sstevel@tonic-gate 		if ((status = ibcm_set_alt_cep_path(statep,
56567c478bd9Sstevel@tonic-gate 		    &IBCM_QPINFO_RC(qp_info).rc_alt_path, req_msgp)) !=
56577c478bd9Sstevel@tonic-gate 		    IBT_SUCCESS)
56587c478bd9Sstevel@tonic-gate 			return (status);
56597c478bd9Sstevel@tonic-gate 
56607c478bd9Sstevel@tonic-gate 		break;
56617c478bd9Sstevel@tonic-gate 	case IBT_RD_SRV:
56627c478bd9Sstevel@tonic-gate 		if (statep->mode == IBCM_ACTIVE_MODE) { /* look at REP msg */
56637c478bd9Sstevel@tonic-gate 			IBCM_QPINFO(qp_info).rd.rd_qkey =
5664015f8fffShiremath 			    b2h32(rep_msgp->rep_local_qkey);
56657c478bd9Sstevel@tonic-gate 		} else {
56667c478bd9Sstevel@tonic-gate 			IBCM_QPINFO(qp_info).rd.rd_qkey =
5667015f8fffShiremath 			    b2h32(req_msgp->req_local_qkey);
56687c478bd9Sstevel@tonic-gate 		}
56697c478bd9Sstevel@tonic-gate 
56707c478bd9Sstevel@tonic-gate 		break;
56717c478bd9Sstevel@tonic-gate 
56727c478bd9Sstevel@tonic-gate 	case IBT_UC_SRV:
56737c478bd9Sstevel@tonic-gate 		if (statep->mode == IBCM_ACTIVE_MODE) { /* look at REP msg */
56749c468ea9SPramod Gunjikar 			IBCM_QPINFO_UC(qp_info).uc_sq_psn =
56757c478bd9Sstevel@tonic-gate 			    b2h32(req_msgp->req_starting_psn_plus) >> 8;
56767c478bd9Sstevel@tonic-gate 			IBCM_QPINFO_UC(qp_info).uc_dst_qpn =
56777c478bd9Sstevel@tonic-gate 			    b2h32(rep_msgp->rep_local_qpn_plus) >> 8;
56787c478bd9Sstevel@tonic-gate 		} else {
56797c478bd9Sstevel@tonic-gate 			IBCM_QPINFO_UC(qp_info).uc_rq_psn =
56809c468ea9SPramod Gunjikar 			    IBCM_QPINFO_UC(qp_info).uc_sq_psn =
56817c478bd9Sstevel@tonic-gate 			    b2h32(rep_msgp->rep_starting_psn_plus) >> 8;
56827c478bd9Sstevel@tonic-gate 			IBCM_QPINFO_UC(qp_info).uc_dst_qpn =
56837c478bd9Sstevel@tonic-gate 			    b2h32(req_msgp->req_local_qpn_plus) >> 8;
56847c478bd9Sstevel@tonic-gate 		}
56857c478bd9Sstevel@tonic-gate 		IBCM_QPINFO_UC(qp_info).uc_path_mtu =
56867c478bd9Sstevel@tonic-gate 		    req_msgp->req_mtu_plus >> 4;
56877c478bd9Sstevel@tonic-gate 
56887c478bd9Sstevel@tonic-gate 		if ((status = ibcm_set_primary_cep_path(statep,
56897c478bd9Sstevel@tonic-gate 		    &IBCM_QPINFO_UC(qp_info).uc_path, req_msgp)) !=
56907c478bd9Sstevel@tonic-gate 		    IBT_SUCCESS)
56917c478bd9Sstevel@tonic-gate 			return (status);
56927c478bd9Sstevel@tonic-gate 
56937c478bd9Sstevel@tonic-gate 		if ((status = ibcm_set_alt_cep_path(statep,
56947c478bd9Sstevel@tonic-gate 		    &IBCM_QPINFO_UC(qp_info).uc_alt_path, req_msgp)) !=
56957c478bd9Sstevel@tonic-gate 		    IBT_SUCCESS)
56967c478bd9Sstevel@tonic-gate 			return (status);
56977c478bd9Sstevel@tonic-gate 
56987c478bd9Sstevel@tonic-gate 		break;
56997c478bd9Sstevel@tonic-gate 	default:
57007c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_invoke_qp_modify: "
57017c478bd9Sstevel@tonic-gate 		    "unknown svc_type = %x", trans);
57027c478bd9Sstevel@tonic-gate 		break;
57037c478bd9Sstevel@tonic-gate 	}
57047c478bd9Sstevel@tonic-gate 
57057c478bd9Sstevel@tonic-gate 	/* Call modify_qp */
57067c478bd9Sstevel@tonic-gate 	status = ibt_modify_qp(statep->channel, cep_flags, &qp_info, NULL);
57077c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_invoke_qp_modify: statep 0x%p"
57087c478bd9Sstevel@tonic-gate 	    " ibt_modify_qp() Init to RTR returned = %d", statep, status);
57097c478bd9Sstevel@tonic-gate 
57107c478bd9Sstevel@tonic-gate 	if (status == IBT_SUCCESS)
57117c478bd9Sstevel@tonic-gate 		ibcm_insert_trace(statep, IBCM_TRACE_INIT_RTR);
57127c478bd9Sstevel@tonic-gate 	else
57137c478bd9Sstevel@tonic-gate 		ibcm_insert_trace(statep, IBCM_TRACE_INIT_RTR_FAIL);
57147c478bd9Sstevel@tonic-gate 
57157c478bd9Sstevel@tonic-gate #ifdef	DEBUG
57167c478bd9Sstevel@tonic-gate 
57177c478bd9Sstevel@tonic-gate 	print_modify_qp("Init to RTR", statep->channel, cep_flags, &qp_info);
57187c478bd9Sstevel@tonic-gate 
57197c478bd9Sstevel@tonic-gate 	if (statep->channel != NULL) {
57207c478bd9Sstevel@tonic-gate 		ibt_qp_query_attr_t	qp_attrs;
57217c478bd9Sstevel@tonic-gate 
57227c478bd9Sstevel@tonic-gate 		(void) ibt_query_qp(statep->channel, &qp_attrs);
57237c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_invoke_qp_modify: "
57247c478bd9Sstevel@tonic-gate 		    "qp_info.qp_state = %x", qp_attrs.qp_info.qp_state);
57257c478bd9Sstevel@tonic-gate 	}
57267c478bd9Sstevel@tonic-gate #endif
57277c478bd9Sstevel@tonic-gate 
57287c478bd9Sstevel@tonic-gate 	return (status);
57297c478bd9Sstevel@tonic-gate }
57307c478bd9Sstevel@tonic-gate 
57317c478bd9Sstevel@tonic-gate 
57327c478bd9Sstevel@tonic-gate /*
57337c478bd9Sstevel@tonic-gate  * ibcm_verify_req_gids_and_svcid
57347c478bd9Sstevel@tonic-gate  *	Validation of LIDs, GIDs and SVC ID
57357c478bd9Sstevel@tonic-gate  *
57367c478bd9Sstevel@tonic-gate  * INPUTS:
57377c478bd9Sstevel@tonic-gate  *	statep		- state pointer
57387c478bd9Sstevel@tonic-gate  *	cm_req_msgp	- REQ message pointer
57397c478bd9Sstevel@tonic-gate  *
57407c478bd9Sstevel@tonic-gate  * RETURN VALUE: IBCM_SUCCESS/IBCM_FAILURE
57417c478bd9Sstevel@tonic-gate  *
57427c478bd9Sstevel@tonic-gate  */
57437c478bd9Sstevel@tonic-gate ibcm_status_t
ibcm_verify_req_gids_and_svcid(ibcm_state_data_t * statep,ibcm_req_msg_t * cm_req_msgp)57447c478bd9Sstevel@tonic-gate ibcm_verify_req_gids_and_svcid(ibcm_state_data_t *statep,
57457c478bd9Sstevel@tonic-gate     ibcm_req_msg_t *cm_req_msgp)
57467c478bd9Sstevel@tonic-gate {
57477c478bd9Sstevel@tonic-gate 	ib_gid_t		gid;
57487c478bd9Sstevel@tonic-gate 	ib_gid_t		agid;
57497c478bd9Sstevel@tonic-gate 	ib_lid_t		lid;
57507c478bd9Sstevel@tonic-gate 	ibt_status_t		status;
57517c478bd9Sstevel@tonic-gate 	ibtl_cm_hca_port_t	port;
57527c478bd9Sstevel@tonic-gate 	ibt_cm_reason_t		reject_reason = IBT_CM_SUCCESS;
57537c478bd9Sstevel@tonic-gate 	ibcm_svc_info_t		*svc_infop;
57547c478bd9Sstevel@tonic-gate 	ibcm_svc_bind_t		*svc_bindp;
57557c478bd9Sstevel@tonic-gate 	ibcm_svc_bind_t		*tmp_bindp;
57567c478bd9Sstevel@tonic-gate 	ib_pkey_t		pkey;
57577c478bd9Sstevel@tonic-gate 	uint8_t			port_num;
57587c478bd9Sstevel@tonic-gate 	ib_guid_t		hca_guid;
5759015f8fffShiremath 	ibcm_ip_pvtdata_t	*ip_data;
57607c478bd9Sstevel@tonic-gate 
57617c478bd9Sstevel@tonic-gate 	/* Verify LID and GID of primary port */
57627c478bd9Sstevel@tonic-gate 
57637c478bd9Sstevel@tonic-gate 	gid.gid_prefix = b2h64(cm_req_msgp->req_primary_r_port_gid.gid_prefix);
57647c478bd9Sstevel@tonic-gate 	gid.gid_guid = b2h64(cm_req_msgp->req_primary_r_port_gid.gid_guid);
57657c478bd9Sstevel@tonic-gate 
57667c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: statep 0x%p"
57677c478bd9Sstevel@tonic-gate 	    " PRIM _r_gid (%llx, %llx)", statep, gid.gid_prefix,
57687c478bd9Sstevel@tonic-gate 	    gid.gid_guid);
57697c478bd9Sstevel@tonic-gate 
57707c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: statep 0x%p "
57717c478bd9Sstevel@tonic-gate 	    "PRIM passive lid %x", statep,
57727c478bd9Sstevel@tonic-gate 	    b2h16(cm_req_msgp->req_primary_r_port_lid));
57737c478bd9Sstevel@tonic-gate 
57747c478bd9Sstevel@tonic-gate 	/* Verify GID validity, if specified */
57757c478bd9Sstevel@tonic-gate 	if ((status = ibtl_cm_get_hca_port(gid, 0, &port)) == IBT_SUCCESS) {
57767c478bd9Sstevel@tonic-gate 
57777c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: statep 0x%p "
57787c478bd9Sstevel@tonic-gate 		    "prim_port_num %d", statep, port.hp_port);
57797c478bd9Sstevel@tonic-gate 
57807c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: statep 0x%p "
57817c478bd9Sstevel@tonic-gate 		    "passive hca_guid 0x%llX", statep, port.hp_hca_guid);
57827c478bd9Sstevel@tonic-gate 
57837c478bd9Sstevel@tonic-gate 		port_num = port.hp_port;
57847c478bd9Sstevel@tonic-gate 		hca_guid = port.hp_hca_guid;
57857c478bd9Sstevel@tonic-gate 	}
57867c478bd9Sstevel@tonic-gate 
57877c478bd9Sstevel@tonic-gate 	if (status != IBT_SUCCESS) {
57887c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_verify_req_gids: statep 0x%p "
57897c478bd9Sstevel@tonic-gate 		    "ibtl_cm_get_hca_port() primary port failed = %d", statep,
57907c478bd9Sstevel@tonic-gate 		    status);
57917c478bd9Sstevel@tonic-gate 		reject_reason = IBT_CM_PRIM_GID;
57927c478bd9Sstevel@tonic-gate 		/* we will search for an acceptable GID to this port */
57937c478bd9Sstevel@tonic-gate 		port_num = statep->stored_reply_addr.port_num;
57947c478bd9Sstevel@tonic-gate 		hca_guid = statep->hcap->hca_guid;
57957c478bd9Sstevel@tonic-gate 
57967c478bd9Sstevel@tonic-gate 	} else if (port.hp_base_lid !=
5797015f8fffShiremath 	    (b2h16(cm_req_msgp->req_primary_r_port_lid) &
5798015f8fffShiremath 	    (~((1 << port.hp_lmc) - 1)))) {
57997c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_verify_req_gids: statep 0x%p "
58007c478bd9Sstevel@tonic-gate 		    "primary port lid invalid (%x, %x, %x)", statep,
58017c478bd9Sstevel@tonic-gate 		    port.hp_base_lid,
58027c478bd9Sstevel@tonic-gate 		    b2h16(cm_req_msgp->req_primary_r_port_lid), port.hp_lmc);
58037c478bd9Sstevel@tonic-gate 		reject_reason = IBT_CM_PRIM_LID;
58047c478bd9Sstevel@tonic-gate 	} else {
58057c478bd9Sstevel@tonic-gate 
58067c478bd9Sstevel@tonic-gate 		statep->local_hca_guid = port.hp_hca_guid;
58077c478bd9Sstevel@tonic-gate 		statep->prim_port = port.hp_port;
58087c478bd9Sstevel@tonic-gate 		statep->prim_src_path_bits =
58097c478bd9Sstevel@tonic-gate 		    b2h16(cm_req_msgp->req_primary_r_port_lid) -
58107c478bd9Sstevel@tonic-gate 		    port.hp_base_lid;
58117c478bd9Sstevel@tonic-gate 
58127c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: "
58137c478bd9Sstevel@tonic-gate 		    "statep 0x%p prim_port_path_bits %d ",
58147c478bd9Sstevel@tonic-gate 		    statep, statep->prim_src_path_bits);
58157c478bd9Sstevel@tonic-gate 
58167c478bd9Sstevel@tonic-gate 		/* Verify LID and GID  of alternate port. Post REJ if invalid */
58177c478bd9Sstevel@tonic-gate 
58187c478bd9Sstevel@tonic-gate 		/* Need a bcopy, as alt port gid is unaligned in req message */
58197c478bd9Sstevel@tonic-gate 		bcopy(&cm_req_msgp->req_alt_r_port_gid[0], &agid,
58207c478bd9Sstevel@tonic-gate 		    sizeof (ib_gid_t));
58217c478bd9Sstevel@tonic-gate 		agid.gid_prefix = b2h64(agid.gid_prefix);
58227c478bd9Sstevel@tonic-gate 		agid.gid_guid = b2h64(agid.gid_guid);
58237c478bd9Sstevel@tonic-gate 
58247c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: statep 0x%p"
58257c478bd9Sstevel@tonic-gate 		    " Alt port_gid is (%llX:%llX)", statep, agid.gid_prefix,
58267c478bd9Sstevel@tonic-gate 		    agid.gid_guid);
58277c478bd9Sstevel@tonic-gate 
58287c478bd9Sstevel@tonic-gate 		if ((agid.gid_prefix != 0) || (agid.gid_guid != 0)) {
58297c478bd9Sstevel@tonic-gate 
58307c478bd9Sstevel@tonic-gate 			/* Verify GID validity, if specified */
58317c478bd9Sstevel@tonic-gate 			if ((status = ibtl_cm_get_hca_port(agid,
58327c478bd9Sstevel@tonic-gate 			    statep->local_hca_guid, &port)) != IBT_SUCCESS) {
58337c478bd9Sstevel@tonic-gate 				IBTF_DPRINTF_L2(cmlog,
58347c478bd9Sstevel@tonic-gate 				    "ibcm_verify_req_gids: ibtl_cm_get_hca_port"
58357c478bd9Sstevel@tonic-gate 				    " statep 0x%p alternate port failed = %d",
58367c478bd9Sstevel@tonic-gate 				    statep, status);
58377c478bd9Sstevel@tonic-gate 				reject_reason = IBT_CM_ALT_GID;
58387c478bd9Sstevel@tonic-gate 
58397c478bd9Sstevel@tonic-gate 			} else if (port.hp_base_lid !=
58407c478bd9Sstevel@tonic-gate 			    (b2h16(cm_req_msgp->req_alt_r_port_lid) &
58417c478bd9Sstevel@tonic-gate 			    (~((1 << port.hp_lmc) - 1)))) {
58427c478bd9Sstevel@tonic-gate 
58437c478bd9Sstevel@tonic-gate 				IBTF_DPRINTF_L2(cmlog,
58447c478bd9Sstevel@tonic-gate 				    "ibcm_verify_req_gids: statep 0x%p "
58457c478bd9Sstevel@tonic-gate 				    "alternate port lid invalid (%x, %x, %x)",
58467c478bd9Sstevel@tonic-gate 				    statep, port.hp_base_lid,
58477c478bd9Sstevel@tonic-gate 				    cm_req_msgp->req_alt_r_port_lid,
58487c478bd9Sstevel@tonic-gate 				    port.hp_lmc);
58497c478bd9Sstevel@tonic-gate 				reject_reason = IBT_CM_ALT_LID;
58507c478bd9Sstevel@tonic-gate 			} else { /* Alt LID and GID are valid */
58517c478bd9Sstevel@tonic-gate 				statep->alt_port = port.hp_port;
58527c478bd9Sstevel@tonic-gate 				statep->alt_src_path_bits =
58537c478bd9Sstevel@tonic-gate 				    b2h16(cm_req_msgp->req_alt_r_port_lid) -
58547c478bd9Sstevel@tonic-gate 				    port.hp_base_lid;
58557c478bd9Sstevel@tonic-gate 
58567c478bd9Sstevel@tonic-gate 				IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: "
58577c478bd9Sstevel@tonic-gate 				    "statep 0x%p alt_port_num %d "
58587c478bd9Sstevel@tonic-gate 				    "alt_rc_hca_guid 0x%llX", statep,
58597c478bd9Sstevel@tonic-gate 				    port.hp_port, port.hp_hca_guid);
58607c478bd9Sstevel@tonic-gate 
58617c478bd9Sstevel@tonic-gate 				IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: "
58627c478bd9Sstevel@tonic-gate 				    "statep 0x%p alt_port_path_bits %d ",
58637c478bd9Sstevel@tonic-gate 				    statep, statep->alt_src_path_bits);
58647c478bd9Sstevel@tonic-gate 			}
58657c478bd9Sstevel@tonic-gate 		}
58667c478bd9Sstevel@tonic-gate 	}
58677c478bd9Sstevel@tonic-gate 
58687c478bd9Sstevel@tonic-gate 	mutex_enter(&ibcm_svc_info_lock);
58697c478bd9Sstevel@tonic-gate 	svc_infop = ibcm_find_svc_entry(statep->svcid);
58707c478bd9Sstevel@tonic-gate 
58717c478bd9Sstevel@tonic-gate 	/*
58727c478bd9Sstevel@tonic-gate 	 * Note: When we return SUCCESS, the reader lock won't get dropped
58737c478bd9Sstevel@tonic-gate 	 * until after the cm_handler is called from ibcm_cep_state_req().
58747c478bd9Sstevel@tonic-gate 	 */
58757c478bd9Sstevel@tonic-gate 
58767c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: "
58777c478bd9Sstevel@tonic-gate 	    "ibcm_find_svc_entry found svc_infop %p", svc_infop);
58787c478bd9Sstevel@tonic-gate 
58797c478bd9Sstevel@tonic-gate 	/*
58807c478bd9Sstevel@tonic-gate 	 * Send REJ with reject reason "invalid service id" for the
58817c478bd9Sstevel@tonic-gate 	 * the following cases :-
58827c478bd9Sstevel@tonic-gate 	 * Service id is valid, but not available at gid/lid of REQ
58837c478bd9Sstevel@tonic-gate 	 * Service id is invalid
58847c478bd9Sstevel@tonic-gate 	 */
58857c478bd9Sstevel@tonic-gate 
58867c478bd9Sstevel@tonic-gate 	if (svc_infop == NULL || svc_infop->svc_bind_list == NULL) {
58877c478bd9Sstevel@tonic-gate 		mutex_exit(&ibcm_svc_info_lock);
58887c478bd9Sstevel@tonic-gate 
58897c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_verify_req_gids_and_svcid: "
58907c478bd9Sstevel@tonic-gate 		    "statep 0x%p svc_id %llX svc_infop NULL", statep,
58917c478bd9Sstevel@tonic-gate 		    statep->svcid);
58927c478bd9Sstevel@tonic-gate 
58937c478bd9Sstevel@tonic-gate 		/* Send a REJ with invalid SID reason */
58947c478bd9Sstevel@tonic-gate 		ibcm_post_rej_mad(statep,
58957c478bd9Sstevel@tonic-gate 		    IBT_CM_INVALID_SID, IBT_CM_FAILURE_REQ, NULL, 0);
58967c478bd9Sstevel@tonic-gate 		return (IBCM_FAILURE);
58977c478bd9Sstevel@tonic-gate 	}
58987c478bd9Sstevel@tonic-gate 
58997c478bd9Sstevel@tonic-gate 	if (svc_infop->svc_rc_handler == NULL) {
59007c478bd9Sstevel@tonic-gate 		mutex_exit(&ibcm_svc_info_lock);
59017c478bd9Sstevel@tonic-gate 
59027c478bd9Sstevel@tonic-gate 		/* Send a REJ with invalid SID reason */
59037c478bd9Sstevel@tonic-gate 		ibcm_post_rej_mad(statep,
59047c478bd9Sstevel@tonic-gate 		    IBT_CM_INVALID_SRV_TYPE, IBT_CM_FAILURE_REQ, NULL, 0);
59057c478bd9Sstevel@tonic-gate 		return (IBCM_FAILURE);
59067c478bd9Sstevel@tonic-gate 	}
59077c478bd9Sstevel@tonic-gate 
5908015f8fffShiremath 	/*
5909015f8fffShiremath 	 * Check if ServiceID is in RDMA IP CM SID range, if yes, we parse
5910015f8fffShiremath 	 * the REQ's Private Data and verify for it's goodness.
5911015f8fffShiremath 	 */
5912015f8fffShiremath 	if (((statep->svcid & IB_SID_IPADDR_PREFIX_MASK) == 0) &&
5913015f8fffShiremath 	    (statep->svcid & IB_SID_IPADDR_PREFIX)) {
5914015f8fffShiremath 		ibt_ari_ip_t	ari_ip;
5915015f8fffShiremath 		boolean_t	rdma_rej_mad = B_FALSE;
5916015f8fffShiremath 
5917015f8fffShiremath 		ip_data = (ibcm_ip_pvtdata_t *)cm_req_msgp->req_private_data;
5918015f8fffShiremath 
5919015f8fffShiremath 		bzero(&ari_ip, sizeof (ibt_ari_ip_t));
5920015f8fffShiremath 
5921015f8fffShiremath 		/* RDMA IP CM Layer Rejects this */
5922015f8fffShiremath 		if (ip_data->ip_MajV != IBT_CM_IP_MAJ_VER) {
5923015f8fffShiremath 			IBTF_DPRINTF_L2(cmlog, "ibcm_verify_req_gids_and_svcid:"
5924015f8fffShiremath 			    "IP MajorVer mis-match %d", ip_data->ip_MajV);
5925015f8fffShiremath 			ari_ip.ip_reason = IBT_ARI_IP_MAJOR_VERSION;
5926015f8fffShiremath 			ari_ip.ip_suggested_version = IBT_CM_IP_MAJ_VER;
5927015f8fffShiremath 			ari_ip.ip_suggested = B_TRUE;
5928015f8fffShiremath 			rdma_rej_mad = B_TRUE;
5929015f8fffShiremath 		} else if (ip_data->ip_MinV != IBT_CM_IP_MIN_VER) {
5930015f8fffShiremath 			IBTF_DPRINTF_L2(cmlog, "ibcm_verify_req_gids_and_svcid:"
5931015f8fffShiremath 			    "IP MinorVer mis-match %d", ip_data->ip_MinV);
5932015f8fffShiremath 			ari_ip.ip_reason = IBT_ARI_IP_MINOR_VERSION;
5933015f8fffShiremath 			ari_ip.ip_suggested_version = IBT_CM_IP_MIN_VER;
5934015f8fffShiremath 			ari_ip.ip_suggested = B_TRUE;
5935015f8fffShiremath 			rdma_rej_mad = B_TRUE;
5936015f8fffShiremath 		} else if ((ip_data->ip_ipv != IBT_CM_IP_IPV_V4) &&
5937015f8fffShiremath 		    (ip_data->ip_ipv != IBT_CM_IP_IPV_V6)) {
5938015f8fffShiremath 			IBTF_DPRINTF_L2(cmlog, "ibcm_verify_req_gids_and_svcid:"
5939015f8fffShiremath 			    " Invalid IPV specified %d", ip_data->ip_ipv);
5940015f8fffShiremath 			ari_ip.ip_reason = IBT_ARI_IP_IPV;
5941015f8fffShiremath 			ari_ip.ip_suggested_version = IBT_CM_IP_IPV_V4;
5942015f8fffShiremath 			ari_ip.ip_suggested = B_TRUE;
5943015f8fffShiremath 			rdma_rej_mad = B_TRUE;
5944015f8fffShiremath 		} else {
5945015f8fffShiremath 			/*
5946015f8fffShiremath 			 * Validate whether ip_addr specified are non-NULL.
5947015f8fffShiremath 			 *
5948015f8fffShiremath 			 * NOTE:
5949015f8fffShiremath 			 * RDMA ULP which is servicing this SID, should validate
5950015f8fffShiremath 			 * the correctness of srcip/dstip and accordingly post
5951015f8fffShiremath 			 * REJ related to ibt_ari_ip_reason_t of
5952015f8fffShiremath 			 * IBT_ARI_IP_SRC_ADDR, IBT_ARI_IP_DST_ADDR and
5953015f8fffShiremath 			 * IBT_ARI_IP_UNKNOWN_ADDR.
5954015f8fffShiremath 			 */
5955015f8fffShiremath 			if (ip_data->ip_ipv == IBT_CM_IP_IPV_V4) {
5956015f8fffShiremath 				if (ip_data->ip_srcv4 == 0) {
5957015f8fffShiremath 					IBTF_DPRINTF_L2(cmlog,
5958015f8fffShiremath 					    "ibcm_verify_req_gids_and_svcid: "
5959015f8fffShiremath 					    "Invalid NULL V4 SrcIp specified");
5960015f8fffShiremath 					rdma_rej_mad = B_TRUE;
5961015f8fffShiremath 					ari_ip.ip_reason = IBT_ARI_IP_SRC_ADDR;
5962015f8fffShiremath 					ari_ip.ip_suggested = B_TRUE;
5963015f8fffShiremath 					ari_ip.ip_suggested_version =
5964015f8fffShiremath 					    IBT_CM_IP_IPV_V4;
5965015f8fffShiremath 				} else if (ip_data->ip_dstv4 == 0) {
5966015f8fffShiremath 					IBTF_DPRINTF_L2(cmlog,
5967015f8fffShiremath 					    "ibcm_verify_req_gids_and_svcid: "
5968015f8fffShiremath 					    "Invalid NULL V4 DstIp specified");
5969015f8fffShiremath 					rdma_rej_mad = B_TRUE;
5970015f8fffShiremath 					ari_ip.ip_reason = IBT_ARI_IP_DST_ADDR;
5971015f8fffShiremath 					ari_ip.ip_suggested = B_TRUE;
5972015f8fffShiremath 					ari_ip.ip_suggested_version =
5973015f8fffShiremath 					    IBT_CM_IP_IPV_V4;
5974015f8fffShiremath 				}
5975015f8fffShiremath 			} else if (ip_data->ip_ipv == IBT_CM_IP_IPV_V6) {
5976015f8fffShiremath 				if (IN6_IS_ADDR_UNSPECIFIED(
5977015f8fffShiremath 				    &ip_data->ip_srcv6)) {
5978015f8fffShiremath 					IBTF_DPRINTF_L2(cmlog,
5979015f8fffShiremath 					    "ibcm_verify_req_gids_and_svcid: "
5980015f8fffShiremath 					    "Invalid NULL V6 SrcIp specified");
5981015f8fffShiremath 					rdma_rej_mad = B_TRUE;
5982015f8fffShiremath 					ari_ip.ip_reason = IBT_ARI_IP_SRC_ADDR;
5983015f8fffShiremath 					ari_ip.ip_suggested = B_TRUE;
5984015f8fffShiremath 					ari_ip.ip_suggested_version =
5985015f8fffShiremath 					    IBT_CM_IP_IPV_V6;
5986015f8fffShiremath 				} else if (IN6_IS_ADDR_UNSPECIFIED(
5987015f8fffShiremath 				    &ip_data->ip_dstv6)) {
5988015f8fffShiremath 					IBTF_DPRINTF_L2(cmlog,
5989015f8fffShiremath 					    "ibcm_verify_req_gids_and_svcid: "
5990015f8fffShiremath 					    "Invalid NULL V6 DstIp specified");
5991015f8fffShiremath 					rdma_rej_mad = B_TRUE;
5992015f8fffShiremath 					ari_ip.ip_reason = IBT_ARI_IP_DST_ADDR;
5993015f8fffShiremath 					ari_ip.ip_suggested = B_TRUE;
5994015f8fffShiremath 					ari_ip.ip_suggested_version =
5995015f8fffShiremath 					    IBT_CM_IP_IPV_V6;
5996015f8fffShiremath 				}
5997015f8fffShiremath 			}
5998015f8fffShiremath 			/* TBD: IBT_ARI_IP_UNKNOWN_ADDR */
5999015f8fffShiremath 		}
6000015f8fffShiremath 		if (rdma_rej_mad == B_TRUE) {
6001015f8fffShiremath 			ibt_ari_con_t	cons_rej;
6002015f8fffShiremath 
6003015f8fffShiremath 			mutex_exit(&ibcm_svc_info_lock);
6004015f8fffShiremath 
6005015f8fffShiremath 			cons_rej.rej_ari_len = 1 + sizeof (ibt_ari_ip_t);
6006015f8fffShiremath 			cons_rej.rej_ari[0] = 0; /* Rejected by CM Layer */
6007015f8fffShiremath 			bcopy(&ari_ip, &cons_rej.rej_ari[1],
6008015f8fffShiremath 			    sizeof (ibt_ari_ip_t));
6009015f8fffShiremath 			/* Send a REJ with CONSUMER REJ */
6010015f8fffShiremath 			ibcm_post_rej_mad(statep, IBT_CM_CONSUMER,
6011015f8fffShiremath 			    IBT_CM_FAILURE_REQ, &cons_rej,
6012015f8fffShiremath 			    sizeof (ibt_ari_con_t));
6013015f8fffShiremath 			return (IBCM_FAILURE);
6014015f8fffShiremath 		}
6015015f8fffShiremath 	}
6016015f8fffShiremath 
60177c478bd9Sstevel@tonic-gate 	/* find the best "bind" entry that enables this port */
60187c478bd9Sstevel@tonic-gate 
60197c478bd9Sstevel@tonic-gate 	pkey = b2h16(cm_req_msgp->req_part_key);
60207c478bd9Sstevel@tonic-gate 	svc_bindp = NULL;
60217c478bd9Sstevel@tonic-gate 	tmp_bindp = svc_infop->svc_bind_list;
60227c478bd9Sstevel@tonic-gate 	while (tmp_bindp) {
60237c478bd9Sstevel@tonic-gate 		if (tmp_bindp->sbind_hcaguid == hca_guid &&
60247c478bd9Sstevel@tonic-gate 		    tmp_bindp->sbind_port == port_num) {
60257c478bd9Sstevel@tonic-gate 			if (gid.gid_guid ==
60267c478bd9Sstevel@tonic-gate 			    tmp_bindp->sbind_gid.gid_guid &&
60277c478bd9Sstevel@tonic-gate 			    gid.gid_prefix ==
60287c478bd9Sstevel@tonic-gate 			    tmp_bindp->sbind_gid.gid_prefix) {
60297c478bd9Sstevel@tonic-gate 				/* gid match => really good match */
60307c478bd9Sstevel@tonic-gate 				svc_bindp = tmp_bindp;
60317c478bd9Sstevel@tonic-gate 				if (pkey == tmp_bindp->sbind_pkey)
60327c478bd9Sstevel@tonic-gate 					/* absolute best match */
60337c478bd9Sstevel@tonic-gate 					break;
60347c478bd9Sstevel@tonic-gate 			} else if (svc_bindp == NULL) {
60357c478bd9Sstevel@tonic-gate 				/* port match => a good match */
60367c478bd9Sstevel@tonic-gate 				svc_bindp = tmp_bindp;
60377c478bd9Sstevel@tonic-gate 			}
60387c478bd9Sstevel@tonic-gate 		}
60397c478bd9Sstevel@tonic-gate 		tmp_bindp = tmp_bindp->sbind_link;
60407c478bd9Sstevel@tonic-gate 	}
60417c478bd9Sstevel@tonic-gate 	if (svc_bindp == NULL) { /* port not enabled for this SID */
60427c478bd9Sstevel@tonic-gate 		mutex_exit(&ibcm_svc_info_lock);
60437c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog,
60447c478bd9Sstevel@tonic-gate 		    "ibcm_verify_req_gids_and_svcid: statep 0x%p "
60457c478bd9Sstevel@tonic-gate 		    "no binding found", statep);
60467c478bd9Sstevel@tonic-gate 		ibcm_post_rej_mad(statep,
60477c478bd9Sstevel@tonic-gate 		    IBT_CM_INVALID_SID, IBT_CM_FAILURE_REQ, NULL, 0);
60487c478bd9Sstevel@tonic-gate 		return (IBCM_FAILURE);
60497c478bd9Sstevel@tonic-gate 	}
60507c478bd9Sstevel@tonic-gate 	/* copy the GID in case we need it in REJ below */
60517c478bd9Sstevel@tonic-gate 	gid.gid_prefix = b2h64(svc_bindp->sbind_gid.gid_prefix);
60527c478bd9Sstevel@tonic-gate 	gid.gid_guid = b2h64(svc_bindp->sbind_gid.gid_guid);
60537c478bd9Sstevel@tonic-gate 
60547c478bd9Sstevel@tonic-gate 	statep->state_cm_private = svc_bindp->sbind_cm_private;
60557c478bd9Sstevel@tonic-gate 	statep->state_svc_infop = svc_infop;
60567c478bd9Sstevel@tonic-gate 	statep->cm_handler = svc_infop->svc_rc_handler;
60577c478bd9Sstevel@tonic-gate 	if (reject_reason == IBT_CM_SUCCESS)
60587c478bd9Sstevel@tonic-gate 		IBCM_SVC_INCR(svc_infop);
60597c478bd9Sstevel@tonic-gate 	mutex_exit(&ibcm_svc_info_lock);
60607c478bd9Sstevel@tonic-gate 
60617c478bd9Sstevel@tonic-gate 	/*
60627c478bd9Sstevel@tonic-gate 	 * If the service id is valid, but gid in REQ is invalid,
60637c478bd9Sstevel@tonic-gate 	 * then send a REJ with invalid gid
60647c478bd9Sstevel@tonic-gate 	 * For Invalid primary gid, the ARI field is filled with
60657c478bd9Sstevel@tonic-gate 	 * with gid from svcinfo
60667c478bd9Sstevel@tonic-gate 	 * For invalid prim/alt gid reject, CM uses one of the gids
60677c478bd9Sstevel@tonic-gate 	 * registered in ARI.
60687c478bd9Sstevel@tonic-gate 	 * For invalid prim/alt lid reject, CM uses the base lid in ARI
60697c478bd9Sstevel@tonic-gate 	 */
60707c478bd9Sstevel@tonic-gate 	if (reject_reason != IBT_CM_SUCCESS) {
60717c478bd9Sstevel@tonic-gate 
60727c478bd9Sstevel@tonic-gate 		switch (reject_reason) {
60737c478bd9Sstevel@tonic-gate 
60747c478bd9Sstevel@tonic-gate 		case IBT_CM_PRIM_GID :
60757c478bd9Sstevel@tonic-gate 		case IBT_CM_ALT_GID :
60767c478bd9Sstevel@tonic-gate 			ibcm_post_rej_mad(statep,
60777c478bd9Sstevel@tonic-gate 			    reject_reason, IBT_CM_FAILURE_REQ,
60787c478bd9Sstevel@tonic-gate 			    &gid, sizeof (ib_gid_t));
60797c478bd9Sstevel@tonic-gate 			break;
60807c478bd9Sstevel@tonic-gate 
60817c478bd9Sstevel@tonic-gate 		case IBT_CM_PRIM_LID :
60827c478bd9Sstevel@tonic-gate 		case IBT_CM_ALT_LID :
60837c478bd9Sstevel@tonic-gate 
60847c478bd9Sstevel@tonic-gate 			lid = h2b16(port.hp_base_lid);
60857c478bd9Sstevel@tonic-gate 			ibcm_post_rej_mad(statep,
60867c478bd9Sstevel@tonic-gate 			    reject_reason, IBT_CM_FAILURE_REQ,
60877c478bd9Sstevel@tonic-gate 			    &lid, sizeof (ib_lid_t));
60887c478bd9Sstevel@tonic-gate 			break;
60897c478bd9Sstevel@tonic-gate 		}
60907c478bd9Sstevel@tonic-gate 
60917c478bd9Sstevel@tonic-gate 		return (IBCM_FAILURE);
60927c478bd9Sstevel@tonic-gate 	}
60937c478bd9Sstevel@tonic-gate 
60947c478bd9Sstevel@tonic-gate 	/* Service, primary/alt gid and lid are all valid */
60957c478bd9Sstevel@tonic-gate 
60967c478bd9Sstevel@tonic-gate 	return (IBCM_SUCCESS);
60977c478bd9Sstevel@tonic-gate }
60987c478bd9Sstevel@tonic-gate 
60997c478bd9Sstevel@tonic-gate /*
61007c478bd9Sstevel@tonic-gate  * ibcm_cep_state_req:
61017c478bd9Sstevel@tonic-gate  *	QP state transition function called for an incoming REQ on passive side
61027c478bd9Sstevel@tonic-gate  *	LIDs and GIDs should be maintained and validated by the client handler
61037c478bd9Sstevel@tonic-gate  *
61047c478bd9Sstevel@tonic-gate  * INPUTS:
61057c478bd9Sstevel@tonic-gate  *	statep		- state pointer
61067c478bd9Sstevel@tonic-gate  *	cm_req_msgp	- REQ message pointer
61077c478bd9Sstevel@tonic-gate  *	reject_reason	- Rejection reason See Section 12.6.7.2 rev1.0a IB Spec
61087c478bd9Sstevel@tonic-gate  *	arej_info_len	- Additional Rejection reason info length
61097c478bd9Sstevel@tonic-gate  *
61107c478bd9Sstevel@tonic-gate  * RETURN VALUE: IBCM_SEND_REP/IBCM_SEND_REJ
61117c478bd9Sstevel@tonic-gate  */
61127c478bd9Sstevel@tonic-gate ibcm_status_t
ibcm_cep_state_req(ibcm_state_data_t * statep,ibcm_req_msg_t * cm_req_msgp,ibt_cm_reason_t * reject_reason,uint8_t * arej_len)61137c478bd9Sstevel@tonic-gate ibcm_cep_state_req(ibcm_state_data_t *statep, ibcm_req_msg_t *cm_req_msgp,
61147c478bd9Sstevel@tonic-gate     ibt_cm_reason_t *reject_reason, uint8_t *arej_len)
61157c478bd9Sstevel@tonic-gate {
61167c478bd9Sstevel@tonic-gate 	void			*priv_data = NULL;
61177c478bd9Sstevel@tonic-gate 	ibt_cm_event_t		event;
61187c478bd9Sstevel@tonic-gate 	ibt_cm_status_t		cb_status;
61197c478bd9Sstevel@tonic-gate 	ibcm_status_t		status;
61207c478bd9Sstevel@tonic-gate 	ibt_cm_return_args_t	ret_args;
61217c478bd9Sstevel@tonic-gate 	ibcm_clnt_reply_info_t	clnt_info;
61227c478bd9Sstevel@tonic-gate 
61237c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_req: statep 0x%p", statep);
6124f07a6d2aSShantkumar Hiremath 	IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_req: SID 0x%lX",
6125f07a6d2aSShantkumar Hiremath 	    b2h64(cm_req_msgp->req_svc_id));
61267c478bd9Sstevel@tonic-gate 	/* client handler should be valid */
61277c478bd9Sstevel@tonic-gate 	ASSERT(statep->cm_handler != NULL);
61287c478bd9Sstevel@tonic-gate 
61297c478bd9Sstevel@tonic-gate 	bzero(&event, sizeof (event));
61307c478bd9Sstevel@tonic-gate 
61317c478bd9Sstevel@tonic-gate 	/* Fill in ibt_cm_event_t */
61327c478bd9Sstevel@tonic-gate 	event.cm_type = IBT_CM_EVENT_REQ_RCV;
61337c478bd9Sstevel@tonic-gate 	event.cm_session_id = statep;
61347c478bd9Sstevel@tonic-gate 	IBCM_EVT_REQ(event).req_service_id = b2h64(cm_req_msgp->req_svc_id);
61357c478bd9Sstevel@tonic-gate 	IBCM_EVT_REQ(event).req_transport =
61367c478bd9Sstevel@tonic-gate 	    ((uint8_t *)&cm_req_msgp->req_remote_eecn_plus)[3] >> 1 & 0x3;
61377c478bd9Sstevel@tonic-gate 	IBCM_EVT_REQ(event).req_timeout = ibt_ib2usec(
61387c478bd9Sstevel@tonic-gate 	    (((uint8_t *)&cm_req_msgp->req_remote_eecn_plus)[3] >> 3) & 0x1F);
61397c478bd9Sstevel@tonic-gate 	IBCM_EVT_REQ(event).req_retry_cnt =
61407c478bd9Sstevel@tonic-gate 	    ((uint8_t *)&cm_req_msgp->req_starting_psn_plus)[3] & 0x7;
61417c478bd9Sstevel@tonic-gate 	IBCM_EVT_REQ(event).req_rnr_retry_cnt = cm_req_msgp->req_mtu_plus & 0x7;
61427c478bd9Sstevel@tonic-gate 	IBCM_EVT_REQ(event).req_pkey = b2h16(cm_req_msgp->req_part_key);
61437c478bd9Sstevel@tonic-gate 	IBCM_EVT_REQ(event).req_rdma_ra_in =
61447c478bd9Sstevel@tonic-gate 	    ((uint8_t *)&cm_req_msgp->req_local_qpn_plus)[3];
61457c478bd9Sstevel@tonic-gate 	IBCM_EVT_REQ(event).req_rdma_ra_out =
61467c478bd9Sstevel@tonic-gate 	    ((uint8_t *)&cm_req_msgp->req_local_eec_no_plus)[3];
61477c478bd9Sstevel@tonic-gate 
61485c42ea03Shiremath 	/* Check for HCA limits for RDMA Resources */
61495c42ea03Shiremath 	if (IBCM_EVT_REQ(event).req_rdma_ra_in >
61505c42ea03Shiremath 	    statep->hcap->hca_max_rdma_in_qp) {
61515c42ea03Shiremath 		IBTF_DPRINTF_L2(cmlog, "ibcm_cep_state_req: statep 0x%p, REQ "
61525c42ea03Shiremath 		    "req_rdma_ra_in %d is greater than HCA Limit %d, resetting"
61535c42ea03Shiremath 		    "it to HCA limit", statep,
61545c42ea03Shiremath 		    IBCM_EVT_REQ(event).req_rdma_ra_in,
61555c42ea03Shiremath 		    statep->hcap->hca_max_rdma_in_qp);
61565c42ea03Shiremath 		IBCM_EVT_REQ(event).req_rdma_ra_in =
61575c42ea03Shiremath 		    statep->hcap->hca_max_rdma_in_qp;
61585c42ea03Shiremath 	}
61595c42ea03Shiremath 
61605c42ea03Shiremath 	if (IBCM_EVT_REQ(event).req_rdma_ra_out >
61615c42ea03Shiremath 	    statep->hcap->hca_max_rdma_out_qp) {
61625c42ea03Shiremath 		IBTF_DPRINTF_L2(cmlog, "ibcm_cep_state_req: statep 0x%p, REQ "
61635c42ea03Shiremath 		    "req_rdma_ra_out %d is greater than HCA Limit %d, resetting"
61645c42ea03Shiremath 		    "it to HCA limit", statep,
61655c42ea03Shiremath 		    IBCM_EVT_REQ(event).req_rdma_ra_out,
61665c42ea03Shiremath 		    statep->hcap->hca_max_rdma_out_qp);
61675c42ea03Shiremath 		IBCM_EVT_REQ(event).req_rdma_ra_out =
61685c42ea03Shiremath 		    statep->hcap->hca_max_rdma_out_qp;
61695c42ea03Shiremath 	}
61705c42ea03Shiremath 
61717c478bd9Sstevel@tonic-gate 	/* Account for CM and other software delays */
61727c478bd9Sstevel@tonic-gate 	if (IBCM_EVT_REQ(event).req_timeout > ibcm_sw_delay) {
61737c478bd9Sstevel@tonic-gate 		IBCM_EVT_REQ(event).req_timeout -= ibcm_sw_delay;
61747c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L5(cmlog, "ibcm_cep_state_req: statep 0x%p"
61757c478bd9Sstevel@tonic-gate 		    "Avail resp time %d (usec)", statep,
61767c478bd9Sstevel@tonic-gate 		    IBCM_EVT_REQ(event).req_timeout);
61777c478bd9Sstevel@tonic-gate 	} else {
61787c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_cep_state_req: statep 0x%p "
61797c478bd9Sstevel@tonic-gate 		    "REQ rem_resp_time < local sw delay 0x%x", statep,
61807c478bd9Sstevel@tonic-gate 		    IBCM_EVT_REQ(event).req_timeout);
61817c478bd9Sstevel@tonic-gate 
61827c478bd9Sstevel@tonic-gate 		IBCM_EVT_REQ(event).req_timeout = 0;
61837c478bd9Sstevel@tonic-gate 	}
61847c478bd9Sstevel@tonic-gate 
61857c478bd9Sstevel@tonic-gate 	IBCM_EVT_REQ(event).req_prim_hca_port = statep->prim_port;
61867c478bd9Sstevel@tonic-gate 	IBCM_EVT_REQ(event).req_alt_hca_port = statep->alt_port;
61877c478bd9Sstevel@tonic-gate 	IBCM_EVT_REQ(event).req_hca_guid = statep->local_hca_guid;
61887c478bd9Sstevel@tonic-gate 	IBCM_EVT_REQ(event).req_remote_qpn = statep->remote_qpn;
61897c478bd9Sstevel@tonic-gate 
61907c478bd9Sstevel@tonic-gate 	if (((uint8_t *)&cm_req_msgp->req_remote_eecn_plus)[3] &
61917c478bd9Sstevel@tonic-gate 	    IBT_CM_FLOW_CONTROL)
61927c478bd9Sstevel@tonic-gate 		IBCM_EVT_REQ(event).req_flags |= IBT_CM_FLOW_CONTROL;
61937c478bd9Sstevel@tonic-gate 
61947c478bd9Sstevel@tonic-gate 	if ((cm_req_msgp->req_max_cm_retries_plus >> 3) & 0x1)
61957c478bd9Sstevel@tonic-gate 		IBCM_EVT_REQ(event).req_flags |= IBT_CM_SRQ_EXISTS;
61967c478bd9Sstevel@tonic-gate 
61977c478bd9Sstevel@tonic-gate 	/* Initialize req.req_prim_addr */
61987c478bd9Sstevel@tonic-gate 	ibcm_set_primary_adds_vect(statep, &IBCM_EVT_REQ(event).req_prim_addr,
61997c478bd9Sstevel@tonic-gate 	    cm_req_msgp);
62007c478bd9Sstevel@tonic-gate 
62017c478bd9Sstevel@tonic-gate 	/* Initialize req.req_alternate_path if they exist */
62027c478bd9Sstevel@tonic-gate 	if (b2h16(cm_req_msgp->req_alt_l_port_lid) != 0) {
62037c478bd9Sstevel@tonic-gate 		ibcm_set_alt_adds_vect(statep,
62047c478bd9Sstevel@tonic-gate 		    &IBCM_EVT_REQ(event).req_alt_addr, cm_req_msgp);
62057c478bd9Sstevel@tonic-gate 
62067c478bd9Sstevel@tonic-gate 		/* Verify, alt path is not same as primary */
62077c478bd9Sstevel@tonic-gate 		if (ibcm_compare_prim_alt_paths(
62087c478bd9Sstevel@tonic-gate 		    &event.cm_event.req.req_prim_addr,
62097c478bd9Sstevel@tonic-gate 		    &event.cm_event.req.req_alt_addr) == B_TRUE) {
62107c478bd9Sstevel@tonic-gate 			/* XXX New REJ code needed */
62117c478bd9Sstevel@tonic-gate 			*reject_reason = IBT_CM_NO_RESC;
62127c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_cep_state_req: statep 0x%p"
62137c478bd9Sstevel@tonic-gate 			    " Alt and prim paths are same", statep);
62147c478bd9Sstevel@tonic-gate 			mutex_enter(&ibcm_svc_info_lock);
62157c478bd9Sstevel@tonic-gate 			IBCM_SVC_DECR(statep->state_svc_infop);
62167c478bd9Sstevel@tonic-gate 			mutex_exit(&ibcm_svc_info_lock);
62177c478bd9Sstevel@tonic-gate 			return (IBCM_SEND_REJ);
62187c478bd9Sstevel@tonic-gate 		}
62197c478bd9Sstevel@tonic-gate 	}
62207c478bd9Sstevel@tonic-gate 
62217c478bd9Sstevel@tonic-gate #ifdef	NO_EEC_SUPPORT_YET
62227c478bd9Sstevel@tonic-gate 	IBCM_EVT_REQ(event).req_rdc_exists = cm_req_msgp->req_mtu_plus >> 3 & 1;
62237c478bd9Sstevel@tonic-gate 	IBCM_EVT_REQ(event).req_remote_eecn =
62247c478bd9Sstevel@tonic-gate 	    b2h32(cm_req_msgp->req_remote_eecn_plus) >> 8;
62257c478bd9Sstevel@tonic-gate 	IBCM_EVT_REQ(event).req_local_eecn =
62267c478bd9Sstevel@tonic-gate 	    b2h32(cm_req_msgp->req_local_eec_no_plus) >> 8;
62277c478bd9Sstevel@tonic-gate 	IBCM_EVT_REQ(event).req_remote_qkey =
62287c478bd9Sstevel@tonic-gate 	    b2h32(cm_req_msgp->req_local_qkey);
62297c478bd9Sstevel@tonic-gate #endif
62307c478bd9Sstevel@tonic-gate 
62317c478bd9Sstevel@tonic-gate 	/* cm_req_msgp->req_private_data to event.cm_event.cm_priv_data */
62327c478bd9Sstevel@tonic-gate 	event.cm_priv_data = cm_req_msgp->req_private_data;
62337c478bd9Sstevel@tonic-gate 
62347c478bd9Sstevel@tonic-gate 	event.cm_priv_data_len = IBT_REQ_PRIV_DATA_SZ;
62357c478bd9Sstevel@tonic-gate 
62367c478bd9Sstevel@tonic-gate 	/*
62377c478bd9Sstevel@tonic-gate 	 * Allocate priv_data of size IBT_MAX_PRIV_DATA_SZ
62387c478bd9Sstevel@tonic-gate 	 */
62397c478bd9Sstevel@tonic-gate 	priv_data = kmem_zalloc(IBT_MAX_PRIV_DATA_SZ, KM_SLEEP);
62407c478bd9Sstevel@tonic-gate 
62417c478bd9Sstevel@tonic-gate 	bzero(&ret_args, sizeof (ret_args));
62427c478bd9Sstevel@tonic-gate 
62437c478bd9Sstevel@tonic-gate 	/* Fill in the default values from REQ, that client can modify */
62447c478bd9Sstevel@tonic-gate 	ret_args.cm_ret.rep.cm_rdma_ra_in = IBCM_EVT_REQ(event).req_rdma_ra_out;
62457c478bd9Sstevel@tonic-gate 	ret_args.cm_ret.rep.cm_rdma_ra_out = IBCM_EVT_REQ(event).req_rdma_ra_in;
62467c478bd9Sstevel@tonic-gate 	ret_args.cm_ret.rep.cm_rnr_retry_cnt = cm_req_msgp->req_mtu_plus & 0x7;
62477c478bd9Sstevel@tonic-gate 
62487c478bd9Sstevel@tonic-gate 	ibcm_insert_trace(statep, IBCM_TRACE_CALLED_REQ_RCVD_EVENT);
62497c478bd9Sstevel@tonic-gate 
62507c478bd9Sstevel@tonic-gate 	/* Invoke the client handler */
6251f07a6d2aSShantkumar Hiremath 	statep->req_msgp = cm_req_msgp;
62527c478bd9Sstevel@tonic-gate 	cb_status = statep->cm_handler(statep->state_cm_private, &event,
62537c478bd9Sstevel@tonic-gate 	    &ret_args, priv_data, IBT_REP_PRIV_DATA_SZ);
6254f07a6d2aSShantkumar Hiremath 	statep->req_msgp = NULL;
62557c478bd9Sstevel@tonic-gate 
62567c478bd9Sstevel@tonic-gate 	ibcm_insert_trace(statep, IBCM_TRACE_RET_REQ_RCVD_EVENT);
62577c478bd9Sstevel@tonic-gate 
62587c478bd9Sstevel@tonic-gate 	mutex_enter(&ibcm_svc_info_lock);
62597c478bd9Sstevel@tonic-gate 	IBCM_SVC_DECR(statep->state_svc_infop);
62607c478bd9Sstevel@tonic-gate 	mutex_exit(&ibcm_svc_info_lock);
62617c478bd9Sstevel@tonic-gate 
62627c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_req: Client handler returned %d"
62637c478bd9Sstevel@tonic-gate 	    " statep 0x%p", cb_status, statep);
62647c478bd9Sstevel@tonic-gate 
62657c478bd9Sstevel@tonic-gate 	if (cb_status == IBT_CM_DEFER) {
62667c478bd9Sstevel@tonic-gate 
62677c478bd9Sstevel@tonic-gate 		_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(statep->defer_cm_msg))
62687c478bd9Sstevel@tonic-gate 
62697c478bd9Sstevel@tonic-gate 		if (statep->defer_cm_msg == NULL)
62707c478bd9Sstevel@tonic-gate 			statep->defer_cm_msg =
62717c478bd9Sstevel@tonic-gate 			    kmem_zalloc(IBCM_MSG_SIZE, KM_SLEEP);
62727c478bd9Sstevel@tonic-gate 		bcopy(cm_req_msgp, statep->defer_cm_msg, IBCM_MSG_SIZE);
62737c478bd9Sstevel@tonic-gate 
62747c478bd9Sstevel@tonic-gate 		_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(statep->defer_cm_msg))
62757c478bd9Sstevel@tonic-gate 
62767c478bd9Sstevel@tonic-gate 		/*
62777c478bd9Sstevel@tonic-gate 		 * unblock any blocked cm proceed api calls. Do not access
62787c478bd9Sstevel@tonic-gate 		 * statep after cv_signal
62797c478bd9Sstevel@tonic-gate 		 */
62807c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
62817c478bd9Sstevel@tonic-gate 		statep->clnt_proceed = IBCM_UNBLOCK;
62827c478bd9Sstevel@tonic-gate 		cv_broadcast(&statep->block_client_cv);
62837c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
62847c478bd9Sstevel@tonic-gate 
62857c478bd9Sstevel@tonic-gate 		kmem_free(priv_data, IBT_MAX_PRIV_DATA_SZ);
62867c478bd9Sstevel@tonic-gate 		return (IBCM_DEFER);
62877c478bd9Sstevel@tonic-gate 	}
62887c478bd9Sstevel@tonic-gate 
62897c478bd9Sstevel@tonic-gate 	/* fail any blocked cm proceed api call - client bug */
62907c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
62917c478bd9Sstevel@tonic-gate 	statep->clnt_proceed = IBCM_FAIL;
62927c478bd9Sstevel@tonic-gate 	cv_broadcast(&statep->block_client_cv);
62937c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
62947c478bd9Sstevel@tonic-gate 
62957c478bd9Sstevel@tonic-gate 	clnt_info.reply_event = (ibt_cm_proceed_reply_t *)&ret_args.cm_ret;
62967c478bd9Sstevel@tonic-gate 	clnt_info.priv_data = priv_data;
62977c478bd9Sstevel@tonic-gate 	clnt_info.priv_data_len = ret_args.cm_ret_len;
62987c478bd9Sstevel@tonic-gate 
62997c478bd9Sstevel@tonic-gate 	status =
6300015f8fffShiremath 	    ibcm_process_cep_req_cm_hdlr(statep, cb_status,
6301015f8fffShiremath 	    &clnt_info, reject_reason, arej_len, cm_req_msgp);
63027c478bd9Sstevel@tonic-gate 	kmem_free(priv_data, IBT_MAX_PRIV_DATA_SZ);
63037c478bd9Sstevel@tonic-gate 	return (status);
63047c478bd9Sstevel@tonic-gate }
63057c478bd9Sstevel@tonic-gate 
63067c478bd9Sstevel@tonic-gate /*
63077c478bd9Sstevel@tonic-gate  * ibcm_process_cep_req_cm_hdlr:
63087c478bd9Sstevel@tonic-gate  *	Processes the response from client handler for an incoming REQ.
63097c478bd9Sstevel@tonic-gate  */
63107c478bd9Sstevel@tonic-gate ibcm_status_t
ibcm_process_cep_req_cm_hdlr(ibcm_state_data_t * statep,ibt_cm_status_t cb_status,ibcm_clnt_reply_info_t * clnt_info,ibt_cm_reason_t * reject_reason,uint8_t * arej_len,ibcm_req_msg_t * cm_req_msg)63117c478bd9Sstevel@tonic-gate ibcm_process_cep_req_cm_hdlr(ibcm_state_data_t *statep,
63127c478bd9Sstevel@tonic-gate     ibt_cm_status_t cb_status, ibcm_clnt_reply_info_t *clnt_info,
63137c478bd9Sstevel@tonic-gate     ibt_cm_reason_t *reject_reason, uint8_t *arej_len,
63147c478bd9Sstevel@tonic-gate     ibcm_req_msg_t *cm_req_msg)
63157c478bd9Sstevel@tonic-gate {
63167c478bd9Sstevel@tonic-gate 	ibt_status_t		status;
63177c478bd9Sstevel@tonic-gate 	ibt_qp_query_attr_t	qp_attrs;
63187c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*old_statep;
63197c478bd9Sstevel@tonic-gate 	ibt_channel_hdl_t	channel;
63207c478bd9Sstevel@tonic-gate 	ib_guid_t		local_ca_guid;
63217c478bd9Sstevel@tonic-gate 	ibcm_rej_msg_t		*rej_msgp;
63227c478bd9Sstevel@tonic-gate #ifdef	NO_EEC_SUPPORT_YET
63237c478bd9Sstevel@tonic-gate 	ibt_eec_query_attr_t	eec_attrs;
63247c478bd9Sstevel@tonic-gate #endif
63257c478bd9Sstevel@tonic-gate 
63267c478bd9Sstevel@tonic-gate 	if (cb_status == IBT_CM_DEFAULT)
63277c478bd9Sstevel@tonic-gate 		cb_status = IBT_CM_REJECT;
63287c478bd9Sstevel@tonic-gate 
63297c478bd9Sstevel@tonic-gate 	/* verify status */
63307c478bd9Sstevel@tonic-gate 	if (cb_status == IBT_CM_ACCEPT) {
63317c478bd9Sstevel@tonic-gate 		*reject_reason = IBT_CM_SUCCESS;
63327c478bd9Sstevel@tonic-gate 	} else if (cb_status == IBT_CM_REJECT) {
63337c478bd9Sstevel@tonic-gate 		*reject_reason = IBT_CM_CONSUMER;
63347c478bd9Sstevel@tonic-gate 	} else if (cb_status == IBT_CM_REDIRECT_PORT) {
63357c478bd9Sstevel@tonic-gate 		*reject_reason = IBT_CM_PORT_REDIRECT;
63367c478bd9Sstevel@tonic-gate 	} else if (cb_status == IBT_CM_REDIRECT) {
63377c478bd9Sstevel@tonic-gate 		*reject_reason = IBT_CM_REDIRECT_CM;
63387c478bd9Sstevel@tonic-gate 	} else if (cb_status == IBT_CM_NO_CHANNEL) {
63397c478bd9Sstevel@tonic-gate 		*reject_reason = IBT_CM_NO_CHAN;
63407c478bd9Sstevel@tonic-gate 	} else if (cb_status == IBT_CM_NO_RESOURCE) {
63417c478bd9Sstevel@tonic-gate 		*reject_reason = IBT_CM_NO_RESC;
63427c478bd9Sstevel@tonic-gate 	} else {
63437c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_req_cm_hdlr: statep %p"
63447c478bd9Sstevel@tonic-gate 		    " Client handler unexpected return %x", statep, cb_status);
63457c478bd9Sstevel@tonic-gate 		*reject_reason = IBT_CM_CONSUMER;
63467c478bd9Sstevel@tonic-gate 	}
63477c478bd9Sstevel@tonic-gate 
63487c478bd9Sstevel@tonic-gate 	/* client handler gave CM ok */
63497c478bd9Sstevel@tonic-gate 	if (cb_status == IBT_CM_ACCEPT) {
63507c478bd9Sstevel@tonic-gate 		ibcm_rep_msg_t	*rep_msgp = (ibcm_rep_msg_t *)
6351015f8fffShiremath 		    IBCM_OUT_MSGP(statep->stored_msg);
63527c478bd9Sstevel@tonic-gate 
63537c478bd9Sstevel@tonic-gate 
63547c478bd9Sstevel@tonic-gate 		_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
63557c478bd9Sstevel@tonic-gate 		_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rep_msgp))
63567c478bd9Sstevel@tonic-gate 
63577c478bd9Sstevel@tonic-gate 		/*
63587c478bd9Sstevel@tonic-gate 		 * Check first if ret_args make sense. If not, bailout
63597c478bd9Sstevel@tonic-gate 		 * here rather than going along and panicing later.
63607c478bd9Sstevel@tonic-gate 		 */
63617c478bd9Sstevel@tonic-gate 		channel = clnt_info->reply_event->rep.cm_channel;
63627c478bd9Sstevel@tonic-gate 		if (IBCM_INVALID_CHANNEL(channel)) {
63637c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_req_cm_hdlr: "
63647c478bd9Sstevel@tonic-gate 			    "statep 0x%p server's QP handle is NULL", statep);
63657c478bd9Sstevel@tonic-gate 			*reject_reason = IBT_CM_NO_CHAN;
63667c478bd9Sstevel@tonic-gate 		}
63677c478bd9Sstevel@tonic-gate 
63687c478bd9Sstevel@tonic-gate 		IBCM_GET_CHAN_PRIVATE(channel, old_statep);
63697c478bd9Sstevel@tonic-gate 
63707c478bd9Sstevel@tonic-gate 		if ((*reject_reason == IBT_CM_SUCCESS) &&
63717c478bd9Sstevel@tonic-gate 		    (old_statep != NULL)) {
63727c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_req_cm_hdlr: "
63737c478bd9Sstevel@tonic-gate 			    "statep 0x%p Channel being re-used on passive side",
63747c478bd9Sstevel@tonic-gate 			    statep);
63757c478bd9Sstevel@tonic-gate 			*reject_reason = IBT_CM_NO_CHAN;
63767c478bd9Sstevel@tonic-gate 		}
63777c478bd9Sstevel@tonic-gate 		if (old_statep != NULL)
63787c478bd9Sstevel@tonic-gate 			IBCM_RELEASE_CHAN_PRIVATE(channel);
63797c478bd9Sstevel@tonic-gate 
63807c478bd9Sstevel@tonic-gate 		if (*reject_reason != IBT_CM_SUCCESS) {
63817c478bd9Sstevel@tonic-gate 			ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
63827c478bd9Sstevel@tonic-gate 			    IBT_CM_FAILURE_REQ, *reject_reason, NULL, 0);
63837c478bd9Sstevel@tonic-gate 			return (IBCM_SEND_REJ);
63847c478bd9Sstevel@tonic-gate 		}
63857c478bd9Sstevel@tonic-gate 
63867c478bd9Sstevel@tonic-gate 		statep->channel = channel;
63877c478bd9Sstevel@tonic-gate 		status = ibt_query_qp(channel, &qp_attrs);
63887c478bd9Sstevel@tonic-gate 
63897c478bd9Sstevel@tonic-gate 		if (status != IBT_SUCCESS) {
63907c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L3(cmlog, "ibcm_process_cep_req_cm_hdlr: "
63917c478bd9Sstevel@tonic-gate 			    "statep %p ibt_query_qp failed %d", statep, status);
63927c478bd9Sstevel@tonic-gate 			*reject_reason = IBT_CM_NO_RESC;
63937c478bd9Sstevel@tonic-gate 			ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
63947c478bd9Sstevel@tonic-gate 			    IBT_CM_FAILURE_REQ, IBT_CM_CI_FAILURE, NULL, 0);
63957c478bd9Sstevel@tonic-gate 			return (IBCM_SEND_REJ);
63967c478bd9Sstevel@tonic-gate 		}
63977c478bd9Sstevel@tonic-gate 
63987c478bd9Sstevel@tonic-gate 		if (qp_attrs.qp_info.qp_trans != IBT_RC_SRV) {
63997c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_req_cm_hdlr: "
64007c478bd9Sstevel@tonic-gate 			    "statep %p qp is not RC channel on server", statep);
64017c478bd9Sstevel@tonic-gate 			*reject_reason = IBT_CM_INVALID_SRV_TYPE;
64027c478bd9Sstevel@tonic-gate 			ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
64037c478bd9Sstevel@tonic-gate 			    IBT_CM_FAILURE_REQ, IBT_CM_CHAN_INVALID_STATE,
64047c478bd9Sstevel@tonic-gate 			    NULL, 0);
64057c478bd9Sstevel@tonic-gate 			return (IBCM_SEND_REJ);
64067c478bd9Sstevel@tonic-gate 		}
64077c478bd9Sstevel@tonic-gate 
6408f07a6d2aSShantkumar Hiremath 		if (qp_attrs.qp_info.qp_state != IBT_STATE_INIT &&
64099c468ea9SPramod Gunjikar 		    statep->is_this_ofuv_chan == B_FALSE) {
64107c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L3(cmlog, "ibcm_process_cep_req_cm_hdlr: "
64117c478bd9Sstevel@tonic-gate 			    "qp state != INIT on server");
64127c478bd9Sstevel@tonic-gate 			*reject_reason = IBT_CM_CHAN_INVALID_STATE;
64137c478bd9Sstevel@tonic-gate 			ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
64147c478bd9Sstevel@tonic-gate 			    IBT_CM_FAILURE_REQ, IBT_CM_CHAN_INVALID_STATE,
64157c478bd9Sstevel@tonic-gate 			    NULL, 0);
64167c478bd9Sstevel@tonic-gate 			return (IBCM_SEND_REJ);
64179c468ea9SPramod Gunjikar 		} else if (statep->is_this_ofuv_chan &&
64189c468ea9SPramod Gunjikar 		    qp_attrs.qp_info.qp_state != IBT_STATE_RTR &&
64199c468ea9SPramod Gunjikar 		    qp_attrs.qp_info.qp_state != IBT_STATE_INIT) {
6420f07a6d2aSShantkumar Hiremath 			IBTF_DPRINTF_L3(cmlog, "ibcm_process_cep_req_cm_hdlr: "
64219c468ea9SPramod Gunjikar 			    "qp state != INIT or RTR on server");
6422f07a6d2aSShantkumar Hiremath 			*reject_reason = IBT_CM_CHAN_INVALID_STATE;
6423f07a6d2aSShantkumar Hiremath 			ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
6424f07a6d2aSShantkumar Hiremath 			    IBT_CM_FAILURE_REQ, IBT_CM_CHAN_INVALID_STATE,
6425f07a6d2aSShantkumar Hiremath 			    NULL, 0);
6426f07a6d2aSShantkumar Hiremath 			return (IBCM_SEND_REJ);
64277c478bd9Sstevel@tonic-gate 		}
64287c478bd9Sstevel@tonic-gate 
64299c468ea9SPramod Gunjikar 		if (statep->is_this_ofuv_chan &&
64309c468ea9SPramod Gunjikar 		    qp_attrs.qp_info.qp_state == IBT_STATE_RTR &&
6431f07a6d2aSShantkumar Hiremath 		    qp_attrs.qp_info.qp_transport.rc.rc_path.cep_hca_port_num !=
6432f07a6d2aSShantkumar Hiremath 		    statep->prim_port) {
6433f07a6d2aSShantkumar Hiremath 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_req_cm_hdlr: "
6434f07a6d2aSShantkumar Hiremath 			    "QP port invalid");
6435f07a6d2aSShantkumar Hiremath 			*reject_reason = IBT_CM_CHAN_INVALID_STATE;
6436f07a6d2aSShantkumar Hiremath 			ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
6437f07a6d2aSShantkumar Hiremath 			    IBT_CM_FAILURE_REQ, IBT_CM_CHAN_INVALID_STATE,
6438f07a6d2aSShantkumar Hiremath 			    NULL, 0);
6439f07a6d2aSShantkumar Hiremath 			return (IBCM_SEND_REJ);
64409c468ea9SPramod Gunjikar 		} else if (statep->is_this_ofuv_chan &&
64419c468ea9SPramod Gunjikar 		    qp_attrs.qp_info.qp_state == IBT_STATE_RTR) {
6442f07a6d2aSShantkumar Hiremath 			goto skip_init_trans;
64439c468ea9SPramod Gunjikar 		}
6444f07a6d2aSShantkumar Hiremath 
64457c478bd9Sstevel@tonic-gate 		/* Init to Init, if required */
64467c478bd9Sstevel@tonic-gate 		if (qp_attrs.qp_info.qp_transport.rc.rc_path.cep_hca_port_num !=
64477c478bd9Sstevel@tonic-gate 		    statep->prim_port) {
64487c478bd9Sstevel@tonic-gate 
64497c478bd9Sstevel@tonic-gate 			ibt_qp_info_t		qp_info;
64507c478bd9Sstevel@tonic-gate 			ibt_cep_modify_flags_t	cep_flags;
64517c478bd9Sstevel@tonic-gate 
64527c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L5(cmlog, "ibcm_process_cep_req_cm_hdlr: "
64537c478bd9Sstevel@tonic-gate 			    "chan 0x%p chan port %d", channel,
64547c478bd9Sstevel@tonic-gate 			    qp_attrs.qp_info.qp_transport.rc.rc_path.\
64557c478bd9Sstevel@tonic-gate 			    cep_hca_port_num);
64567c478bd9Sstevel@tonic-gate 
64577c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L5(cmlog, "ibcm_process_cep_req_cm_hdlr: "
64587c478bd9Sstevel@tonic-gate 			    "chan 0x%p d path port %d", channel,
64597c478bd9Sstevel@tonic-gate 			    statep->prim_port);
64607c478bd9Sstevel@tonic-gate 
64617c478bd9Sstevel@tonic-gate 			bzero(&qp_info, sizeof (qp_info));
64627c478bd9Sstevel@tonic-gate 			qp_info.qp_trans = IBT_RC_SRV;
64637c478bd9Sstevel@tonic-gate 			qp_info.qp_state = IBT_STATE_INIT;
64647c478bd9Sstevel@tonic-gate 			qp_info.qp_transport.rc.rc_path.cep_hca_port_num =
64657c478bd9Sstevel@tonic-gate 			    statep->prim_port;
64667c478bd9Sstevel@tonic-gate 
64677c478bd9Sstevel@tonic-gate 			cep_flags = IBT_CEP_SET_STATE | IBT_CEP_SET_PORT;
64687c478bd9Sstevel@tonic-gate 
64697c478bd9Sstevel@tonic-gate 			status = ibt_modify_qp(statep->channel, cep_flags,
64707c478bd9Sstevel@tonic-gate 			    &qp_info, NULL);
64717c478bd9Sstevel@tonic-gate 
64727c478bd9Sstevel@tonic-gate 			if (status != IBT_SUCCESS) {
64737c478bd9Sstevel@tonic-gate 				IBTF_DPRINTF_L2(cmlog,
64747c478bd9Sstevel@tonic-gate 				    "ibcm_process_cep_req_cm_hdlr: "
64757c478bd9Sstevel@tonic-gate 				    "chan 0x%p ibt_modify_qp() = %d", channel,
64767c478bd9Sstevel@tonic-gate 				    status);
64777c478bd9Sstevel@tonic-gate 				*reject_reason = IBT_CM_NO_RESC;
64787c478bd9Sstevel@tonic-gate 
64797c478bd9Sstevel@tonic-gate 				ibcm_insert_trace(statep,
64807c478bd9Sstevel@tonic-gate 				    IBCM_TRACE_INIT_INIT_FAIL);
64817c478bd9Sstevel@tonic-gate 
64827c478bd9Sstevel@tonic-gate 				ibcm_handler_conn_fail(statep,
64837c478bd9Sstevel@tonic-gate 				    IBT_CM_FAILURE_REJ_SENT, IBT_CM_FAILURE_REQ,
64847c478bd9Sstevel@tonic-gate 				    IBT_CM_CI_FAILURE, NULL, 0);
64857c478bd9Sstevel@tonic-gate 				return (IBCM_SEND_REJ);
64867c478bd9Sstevel@tonic-gate 			} else {
64877c478bd9Sstevel@tonic-gate 				ibcm_insert_trace(statep,
64887c478bd9Sstevel@tonic-gate 				    IBCM_TRACE_INIT_INIT);
64897c478bd9Sstevel@tonic-gate 
64907c478bd9Sstevel@tonic-gate 				IBTF_DPRINTF_L5(cmlog,
64917c478bd9Sstevel@tonic-gate 				    "ibcm_process_cep_req_cm_hdlr: "
64927c478bd9Sstevel@tonic-gate 				    "chan 0x%p ibt_modify_qp() = %d", channel,
64937c478bd9Sstevel@tonic-gate 				    status);
64947c478bd9Sstevel@tonic-gate 			}
64957c478bd9Sstevel@tonic-gate 		}
6496f07a6d2aSShantkumar Hiremath skip_init_trans:
6497f07a6d2aSShantkumar Hiremath 		/* Do sanity tests even if we are skipping RTR */
64987c478bd9Sstevel@tonic-gate 
64997c478bd9Sstevel@tonic-gate 		/* fill in the REP msg based on ret_args from client */
65005c42ea03Shiremath 		if (clnt_info->reply_event->rep.cm_rdma_ra_out >
6501d22e11ebSBill Taylor 		    ((uint8_t *)&cm_req_msg->req_local_qpn_plus)[3]) {
65025c42ea03Shiremath 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_cm_hdlr "
65035c42ea03Shiremath 			    "statep 0x%p ERROR: InitiatorDepth(%d) is Greater "
65045c42ea03Shiremath 			    "than ResponderResource(%d)", statep,
65055c42ea03Shiremath 			    clnt_info->reply_event->rep.cm_rdma_ra_out,
6506d22e11ebSBill Taylor 			    ((uint8_t *)&cm_req_msg->req_local_qpn_plus)[3]);
65075c42ea03Shiremath 			*reject_reason = IBT_CM_NOT_SUPPORTED;
65085c42ea03Shiremath 			ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
65095c42ea03Shiremath 			    IBT_CM_FAILURE_REQ, IBT_CM_NOT_SUPPORTED, NULL, 0);
65105c42ea03Shiremath 			return (IBCM_SEND_REJ);
65115c42ea03Shiremath 		}
65125c42ea03Shiremath 
65135c42ea03Shiremath 		/* Check for HCA limits for RDMA Resources */
65145c42ea03Shiremath 		if (clnt_info->reply_event->rep.cm_rdma_ra_in >
65155c42ea03Shiremath 		    statep->hcap->hca_max_rdma_in_qp) {
65165c42ea03Shiremath 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_cm_hdlr: "
65175c42ea03Shiremath 			    "statep %p, ERROR: client specified rdma_ra_in %d "
65185c42ea03Shiremath 			    "is greater than HCA Limit %d, rejecting MAD",
65195c42ea03Shiremath 			    statep, clnt_info->reply_event->rep.cm_rdma_ra_in,
65205c42ea03Shiremath 			    statep->hcap->hca_max_rdma_in_qp);
65215c42ea03Shiremath 			*reject_reason = IBT_CM_NOT_SUPPORTED;
65225c42ea03Shiremath 			ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
65235c42ea03Shiremath 			    IBT_CM_FAILURE_REQ, IBT_CM_NOT_SUPPORTED, NULL, 0);
65245c42ea03Shiremath 			return (IBCM_SEND_REJ);
65255c42ea03Shiremath 		}
65265c42ea03Shiremath 
65275c42ea03Shiremath 		if (clnt_info->reply_event->rep.cm_rdma_ra_out >
65285c42ea03Shiremath 		    statep->hcap->hca_max_rdma_out_qp) {
65295c42ea03Shiremath 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_cm_hdlr: "
65305c42ea03Shiremath 			    "statep %p, ERROR: client specified rdma_ra_out %d "
65315c42ea03Shiremath 			    "is greater than HCA Limit %d, rejecting MAD",
65325c42ea03Shiremath 			    statep, clnt_info->reply_event->rep.cm_rdma_ra_out,
65335c42ea03Shiremath 			    statep->hcap->hca_max_rdma_out_qp);
65345c42ea03Shiremath 			*reject_reason = IBT_CM_NOT_SUPPORTED;
65355c42ea03Shiremath 			ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
65365c42ea03Shiremath 			    IBT_CM_FAILURE_REQ, IBT_CM_NOT_SUPPORTED, NULL, 0);
65375c42ea03Shiremath 			return (IBCM_SEND_REJ);
65385c42ea03Shiremath 		}
65395c42ea03Shiremath 
65407c478bd9Sstevel@tonic-gate 		rep_msgp->rep_resp_resources =
65417c478bd9Sstevel@tonic-gate 		    clnt_info->reply_event->rep.cm_rdma_ra_in;
65427c478bd9Sstevel@tonic-gate 		rep_msgp->rep_initiator_depth =
65437c478bd9Sstevel@tonic-gate 		    clnt_info->reply_event->rep.cm_rdma_ra_out;
65447c478bd9Sstevel@tonic-gate 
65457c478bd9Sstevel@tonic-gate 		/* IBT_CM_FLOW_CONTROL is always set by default. */
65467c478bd9Sstevel@tonic-gate 		rep_msgp->rep_target_delay_plus |= IBT_CM_FLOW_CONTROL;
65477c478bd9Sstevel@tonic-gate 
65487c478bd9Sstevel@tonic-gate 		rep_msgp->rep_rnr_retry_cnt_plus =
65497c478bd9Sstevel@tonic-gate 		    (clnt_info->reply_event->rep.cm_rnr_retry_cnt & 0x7) << 5;
65507c478bd9Sstevel@tonic-gate 
65517c478bd9Sstevel@tonic-gate 		/*
65527c478bd9Sstevel@tonic-gate 		 * Check out whether SRQ is associated with this channel.
65537c478bd9Sstevel@tonic-gate 		 * If yes, then set the appropriate bit.
65547c478bd9Sstevel@tonic-gate 		 */
65557c478bd9Sstevel@tonic-gate 		if (qp_attrs.qp_srq != NULL) {
65567c478bd9Sstevel@tonic-gate 			rep_msgp->rep_rnr_retry_cnt_plus |= (1 << 4);
65577c478bd9Sstevel@tonic-gate 		}
65587c478bd9Sstevel@tonic-gate 
65597c478bd9Sstevel@tonic-gate 		local_ca_guid = h2b64(statep->local_hca_guid);
65607c478bd9Sstevel@tonic-gate 		bcopy(&local_ca_guid, rep_msgp->rep_local_ca_guid,
65617c478bd9Sstevel@tonic-gate 		    sizeof (ib_guid_t));
65627c478bd9Sstevel@tonic-gate 
65639c468ea9SPramod Gunjikar 		if (statep->is_this_ofuv_chan &&
65649c468ea9SPramod Gunjikar 		    qp_attrs.qp_info.qp_state == IBT_STATE_RTR)
6565f07a6d2aSShantkumar Hiremath 			goto skip_rtr_trans;
6566f07a6d2aSShantkumar Hiremath 
65677c478bd9Sstevel@tonic-gate 		/* Transition QP from Init to RTR state */
65687c478bd9Sstevel@tonic-gate 		if (ibcm_invoke_qp_modify(statep, cm_req_msg, rep_msgp) !=
65697c478bd9Sstevel@tonic-gate 		    IBT_SUCCESS) {
65707c478bd9Sstevel@tonic-gate 
65717c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_cm_hdlr "
65727c478bd9Sstevel@tonic-gate 			    "statep 0x%p ibcm_invoke_qp_modify failed because "
65737c478bd9Sstevel@tonic-gate 			    "of invalid data", statep);
65747c478bd9Sstevel@tonic-gate 			*reject_reason = IBT_CM_NO_RESC;
65757c478bd9Sstevel@tonic-gate 			ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
65767c478bd9Sstevel@tonic-gate 			    IBT_CM_FAILURE_REQ, IBT_CM_CI_FAILURE, NULL, 0);
65777c478bd9Sstevel@tonic-gate 			return (IBCM_SEND_REJ);
65787c478bd9Sstevel@tonic-gate 		}
6579f07a6d2aSShantkumar Hiremath skip_rtr_trans:
65807c478bd9Sstevel@tonic-gate 
65817c478bd9Sstevel@tonic-gate 		/*
65827c478bd9Sstevel@tonic-gate 		 * Link statep and channel, once CM determines it is
65837c478bd9Sstevel@tonic-gate 		 * post REP definitely.
65847c478bd9Sstevel@tonic-gate 		 */
65857c478bd9Sstevel@tonic-gate 		IBCM_SET_CHAN_PRIVATE(statep->channel, statep);
65867c478bd9Sstevel@tonic-gate 
65877c478bd9Sstevel@tonic-gate 		/*
65887c478bd9Sstevel@tonic-gate 		 * Fill up the REP fields from ret_args
65897c478bd9Sstevel@tonic-gate 		 * failover status,  from ret_args
65907c478bd9Sstevel@tonic-gate 		 *
65917c478bd9Sstevel@tonic-gate 		 * Fill up local QPN and EECN from ret_args->channel
65927c478bd9Sstevel@tonic-gate 		 */
65937c478bd9Sstevel@tonic-gate 
65947c478bd9Sstevel@tonic-gate 		/* fill in REP msg bytes Qkey, Starting PSN, 12-15, and 16-19 */
65957c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_process_cep_req_cm_hdlr: "
65967c478bd9Sstevel@tonic-gate 		    "qp_info.qp_state = %x", qp_attrs.qp_info.qp_state);
65977c478bd9Sstevel@tonic-gate 
65987c478bd9Sstevel@tonic-gate 		rep_msgp->rep_local_qpn_plus = h2b32(qp_attrs.qp_qpn << 8);
65997c478bd9Sstevel@tonic-gate 
66007c478bd9Sstevel@tonic-gate 		statep->local_qpn = qp_attrs.qp_qpn;
66017c478bd9Sstevel@tonic-gate 
66027c478bd9Sstevel@tonic-gate 		switch (qp_attrs.qp_info.qp_trans) {
66037c478bd9Sstevel@tonic-gate 		case IBT_RD_SRV:
66047c478bd9Sstevel@tonic-gate 			rep_msgp->rep_local_qkey = h2b32(
66057c478bd9Sstevel@tonic-gate 			    qp_attrs.qp_info.qp_transport.rd.rd_qkey);
66067c478bd9Sstevel@tonic-gate 			break;
66077c478bd9Sstevel@tonic-gate 		case IBT_RC_SRV:
66087c478bd9Sstevel@tonic-gate 			rep_msgp->rep_starting_psn_plus =
66099c468ea9SPramod Gunjikar 			    h2b32(IBCM_QP_RC(qp_attrs).rc_rq_psn << 8);
66107c478bd9Sstevel@tonic-gate 			break;
66117c478bd9Sstevel@tonic-gate 		case IBT_UC_SRV:
66127c478bd9Sstevel@tonic-gate 			rep_msgp->rep_starting_psn_plus =
66137c478bd9Sstevel@tonic-gate 			    h2b32(IBCM_QP_UC(qp_attrs).uc_sq_psn << 8);
66147c478bd9Sstevel@tonic-gate 			break;
66157c478bd9Sstevel@tonic-gate 		}
66167c478bd9Sstevel@tonic-gate 
66177c478bd9Sstevel@tonic-gate #ifdef	NO_EEC_SUPPORT_YET
66187c478bd9Sstevel@tonic-gate 		if (ret_args.cm_channel.ch_eec != NULL) {
66197c478bd9Sstevel@tonic-gate 			status = ibt_query_eec(ret_args.cm_channel.ch_eec,
66207c478bd9Sstevel@tonic-gate 			    &eec_attrs);
66217c478bd9Sstevel@tonic-gate 			if (status == IBT_SUCCESS) {
66227c478bd9Sstevel@tonic-gate 				rep_msgp->rep_local_eecn_plus =
66237c478bd9Sstevel@tonic-gate 				    h2b32(((uint32_t)eec_attrs.eec_eecn << 8));
66247c478bd9Sstevel@tonic-gate 			}
66257c478bd9Sstevel@tonic-gate 		}
66267c478bd9Sstevel@tonic-gate #endif
66277c478bd9Sstevel@tonic-gate 
66287c478bd9Sstevel@tonic-gate 		/* figure out Target ACK delay */
66297c478bd9Sstevel@tonic-gate 		rep_msgp->rep_target_delay_plus |= (status == IBT_SUCCESS) ?
66307c478bd9Sstevel@tonic-gate 		    statep->hcap->hca_ack_delay << 3 : 0;
66317c478bd9Sstevel@tonic-gate 
66327c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_process_cep_req_cm_hdlr:statep %p "
66337c478bd9Sstevel@tonic-gate 		    "REP priv len %x", statep, clnt_info->priv_data_len);
66347c478bd9Sstevel@tonic-gate 		/* Copy PrivateData from priv_data */
66357c478bd9Sstevel@tonic-gate 		if (clnt_info->priv_data_len != 0) {
66367c478bd9Sstevel@tonic-gate 			bcopy(clnt_info->priv_data, rep_msgp->rep_private_data,
66377c478bd9Sstevel@tonic-gate 			    min(IBT_REP_PRIV_DATA_SZ,
66387c478bd9Sstevel@tonic-gate 			    clnt_info->priv_data_len));
66397c478bd9Sstevel@tonic-gate 		}
66407c478bd9Sstevel@tonic-gate 
66417c478bd9Sstevel@tonic-gate 		_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*statep))
66427c478bd9Sstevel@tonic-gate 		_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rep_msgp))
66437c478bd9Sstevel@tonic-gate 
66447c478bd9Sstevel@tonic-gate 		return (IBCM_SEND_REP);
66457c478bd9Sstevel@tonic-gate 	}
66467c478bd9Sstevel@tonic-gate 
66477c478bd9Sstevel@tonic-gate 	/* REJ message */
66487c478bd9Sstevel@tonic-gate 	rej_msgp = (ibcm_rej_msg_t *)IBCM_OUT_MSGP(statep->stored_msg);
66497c478bd9Sstevel@tonic-gate 
66507c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_cep_req_cm_hdlr: statep %p REJ "
66517c478bd9Sstevel@tonic-gate 	    "priv len %x", statep, clnt_info->priv_data_len);
66527c478bd9Sstevel@tonic-gate 
66537c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rej_msgp))
66547c478bd9Sstevel@tonic-gate 
66557c478bd9Sstevel@tonic-gate 	/* if priv_data_len != 0 use priv_data to copy back to rej_priv_data */
66567c478bd9Sstevel@tonic-gate 	if (clnt_info->priv_data_len != 0) {
66577c478bd9Sstevel@tonic-gate 		bcopy(clnt_info->priv_data, rej_msgp->rej_private_data,
66587c478bd9Sstevel@tonic-gate 		    min(IBT_REJ_PRIV_DATA_SZ, clnt_info->priv_data_len));
66597c478bd9Sstevel@tonic-gate 	}
66607c478bd9Sstevel@tonic-gate 
66617c478bd9Sstevel@tonic-gate 	if (cb_status == IBT_CM_REDIRECT_PORT) {
66627c478bd9Sstevel@tonic-gate 		ib_gid_t tgid;
66637c478bd9Sstevel@tonic-gate 
66647c478bd9Sstevel@tonic-gate 		tgid.gid_guid =
66657c478bd9Sstevel@tonic-gate 		    h2b64(clnt_info->reply_event->rej.ari_gid.gid_guid);
66667c478bd9Sstevel@tonic-gate 		tgid.gid_prefix =
66677c478bd9Sstevel@tonic-gate 		    h2b64(clnt_info->reply_event->rej.ari_gid.gid_prefix);
66687c478bd9Sstevel@tonic-gate 
66697c478bd9Sstevel@tonic-gate 		*arej_len = sizeof (ib_gid_t);
66707c478bd9Sstevel@tonic-gate 		bcopy(&tgid, &rej_msgp->rej_addl_rej_info, sizeof (ib_gid_t));
66717c478bd9Sstevel@tonic-gate 
667224b28d04Shiremath 		IBTF_DPRINTF_L3(cmlog, "ibcm_process_cep_req_cm_hdlr: ari_gid= "
667324b28d04Shiremath 		    "%llX:%llX", tgid.gid_prefix, tgid.gid_guid);
667424b28d04Shiremath 
66757c478bd9Sstevel@tonic-gate 	} else if (cb_status == IBT_CM_REDIRECT) {
66767c478bd9Sstevel@tonic-gate 		ibcm_classportinfo_msg_t	tclp;
66777c478bd9Sstevel@tonic-gate 
66787c478bd9Sstevel@tonic-gate 		ibcm_init_clp_to_mad(&tclp,
66797c478bd9Sstevel@tonic-gate 		    &clnt_info->reply_event->rej.ari_redirect);
66807c478bd9Sstevel@tonic-gate 		bcopy(&tclp, rej_msgp->rej_addl_rej_info, sizeof (tclp));
66817c478bd9Sstevel@tonic-gate 
66827c478bd9Sstevel@tonic-gate 		*arej_len = sizeof (ibcm_classportinfo_msg_t);
66837c478bd9Sstevel@tonic-gate 
66847c478bd9Sstevel@tonic-gate 	} else if (cb_status == IBT_CM_REJECT) {
66857c478bd9Sstevel@tonic-gate 
66867c478bd9Sstevel@tonic-gate 		/* Fill up the REJ fields, from ret_args */
66877c478bd9Sstevel@tonic-gate 		*arej_len = min(
66887c478bd9Sstevel@tonic-gate 		    clnt_info->reply_event->rej.ari_consumer.rej_ari_len,
66897c478bd9Sstevel@tonic-gate 		    IBT_CM_ADDL_REJ_LEN);
66907c478bd9Sstevel@tonic-gate 		bcopy(clnt_info->reply_event->rej.ari_consumer.rej_ari,
66917c478bd9Sstevel@tonic-gate 		    &rej_msgp->rej_addl_rej_info, *arej_len);
6692015f8fffShiremath 
6693015f8fffShiremath 		/*
6694015f8fffShiremath 		 * RDMA IP REQ was passed up to the ULP, the ULP decided to do
6695015f8fffShiremath 		 * a "normal" consumer REJ, by the returning IBT_CM_REJECT in
6696015f8fffShiremath 		 * the cm handler.
6697015f8fffShiremath 		 * CM has to do some extra stuff too, it has to
6698015f8fffShiremath 		 * a) return REJ code 28 (consumer) and b) put 0x1 in the first
6699015f8fffShiremath 		 * byte of the ARI data, to indicate that this is a RDMA aware
6700015f8fffShiremath 		 * ULP that is doing a consumer reject.  The ULP should have
6701015f8fffShiremath 		 * put its consumer specific data into ibt_arej_info_t(9s) at
6702015f8fffShiremath 		 * byte 1 of the rej_ari[] array.
6703015f8fffShiremath 		 */
6704015f8fffShiremath 		if (((statep->svcid & IB_SID_IPADDR_PREFIX_MASK) == 0) &&
6705015f8fffShiremath 		    (statep->svcid & IB_SID_IPADDR_PREFIX)) {
6706015f8fffShiremath 			rej_msgp->rej_addl_rej_info[0] = 1;
6707015f8fffShiremath 		}
67087c478bd9Sstevel@tonic-gate 	}
67097c478bd9Sstevel@tonic-gate 
67107c478bd9Sstevel@tonic-gate 	rej_msgp->rej_msg_type_plus = IBT_CM_FAILURE_REQ << 6;
67117c478bd9Sstevel@tonic-gate 
67127c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rej_msgp))
67137c478bd9Sstevel@tonic-gate 
67147c478bd9Sstevel@tonic-gate 	return (IBCM_SEND_REJ);
67157c478bd9Sstevel@tonic-gate }
67167c478bd9Sstevel@tonic-gate 
67177c478bd9Sstevel@tonic-gate /*
67187c478bd9Sstevel@tonic-gate  * ibcm_cep_state_rep:
67197c478bd9Sstevel@tonic-gate  *	QP state transition function called for an incoming REP on active side
67207c478bd9Sstevel@tonic-gate  *
67217c478bd9Sstevel@tonic-gate  * INPUTS:
67227c478bd9Sstevel@tonic-gate  *	statep		- state pointer
67237c478bd9Sstevel@tonic-gate  *	cm_rep_msg	- REP message pointer
67247c478bd9Sstevel@tonic-gate  *	reject_reason	- Rejection reason See Section 12.6.7.2 rev1.0a IB Spec
67257c478bd9Sstevel@tonic-gate  *
67267c478bd9Sstevel@tonic-gate  * RETURN VALUE:
67277c478bd9Sstevel@tonic-gate  */
67287c478bd9Sstevel@tonic-gate ibcm_status_t
ibcm_cep_state_rep(ibcm_state_data_t * statep,ibcm_rep_msg_t * cm_rep_msgp,ibt_cm_reason_t * reject_reason,uint8_t * arej_len)67297c478bd9Sstevel@tonic-gate ibcm_cep_state_rep(ibcm_state_data_t *statep, ibcm_rep_msg_t *cm_rep_msgp,
67307c478bd9Sstevel@tonic-gate     ibt_cm_reason_t *reject_reason, uint8_t *arej_len)
67317c478bd9Sstevel@tonic-gate {
67327c478bd9Sstevel@tonic-gate 	void			*priv_data = NULL;
67337c478bd9Sstevel@tonic-gate 	ibcm_status_t		rval = IBCM_SEND_RTU;
67347c478bd9Sstevel@tonic-gate 	ibt_cm_event_t		event;
67357c478bd9Sstevel@tonic-gate 	ibt_cm_status_t		cb_status = IBT_CM_ACCEPT;
67367c478bd9Sstevel@tonic-gate 	ibt_cm_return_args_t	ret_args;
67377c478bd9Sstevel@tonic-gate 	ibcm_clnt_reply_info_t	clnt_info;
67385c42ea03Shiremath 	uint8_t			req_init_depth;
67397c478bd9Sstevel@tonic-gate 
67407c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(cmlog, "ibcm_cep_state_rep: statep 0x%p", statep);
67417c478bd9Sstevel@tonic-gate 
67427c478bd9Sstevel@tonic-gate 	/* Check first if client handler is valid */
67437c478bd9Sstevel@tonic-gate 	if (statep->cm_handler != NULL) {
67447c478bd9Sstevel@tonic-gate 		/* initialize fields in ibt_cm_event_t */
67457c478bd9Sstevel@tonic-gate 		bzero(&event, sizeof (event));
67467c478bd9Sstevel@tonic-gate 		event.cm_type = IBT_CM_EVENT_REP_RCV;
67477c478bd9Sstevel@tonic-gate 		event.cm_channel = statep->channel;
67487c478bd9Sstevel@tonic-gate 		event.cm_session_id = statep;
67497c478bd9Sstevel@tonic-gate 
67507c478bd9Sstevel@tonic-gate 		IBCM_EVT_REP(event).rep_rdma_ra_in =
6751015f8fffShiremath 		    cm_rep_msgp->rep_initiator_depth;
67525c42ea03Shiremath 		req_init_depth =
67535c42ea03Shiremath 		    ((uint8_t *)&(((ibcm_req_msg_t *)IBCM_OUT_MSGP(
67545c42ea03Shiremath 		    statep->stored_msg))->req_local_eec_no_plus))[3];
67555c42ea03Shiremath 		IBCM_EVT_REP(event).rep_rdma_ra_out =
67565c42ea03Shiremath 		    min(cm_rep_msgp->rep_resp_resources, req_init_depth);
67575c42ea03Shiremath 
67585c42ea03Shiremath 		IBTF_DPRINTF_L3(cmlog, "ibcm_cep_state_rep: statep 0x%p, "
67595c42ea03Shiremath 		    "InitDepth %d, RespResr %d", statep,
67605c42ea03Shiremath 		    cm_rep_msgp->rep_initiator_depth,
67615c42ea03Shiremath 		    IBCM_EVT_REP(event).rep_rdma_ra_out);
67625c42ea03Shiremath 
67637c478bd9Sstevel@tonic-gate 		IBCM_EVT_REP(event).rep_service_time = ibt_ib2usec(
67647c478bd9Sstevel@tonic-gate 		    ((uint8_t *)&(((ibcm_req_msg_t *)IBCM_OUT_MSGP(
67657c478bd9Sstevel@tonic-gate 		    statep->stored_msg))->req_starting_psn_plus))[3] >> 3);
67667c478bd9Sstevel@tonic-gate 
67677c478bd9Sstevel@tonic-gate 		IBCM_EVT_REP(event).rep_service_time -=
67687c478bd9Sstevel@tonic-gate 		    2 * statep->pkt_life_time - ibcm_sw_delay;
67697c478bd9Sstevel@tonic-gate 
67707c478bd9Sstevel@tonic-gate 		IBCM_EVT_REP(event).rep_failover_status =
6771015f8fffShiremath 		    cm_rep_msgp->rep_target_delay_plus >> 1 & 3;
67727c478bd9Sstevel@tonic-gate 
67737c478bd9Sstevel@tonic-gate 		if (cm_rep_msgp->rep_target_delay_plus & 0x1)
67747c478bd9Sstevel@tonic-gate 			IBCM_EVT_REP(event).rep_flags |= IBT_CM_FLOW_CONTROL;
67757c478bd9Sstevel@tonic-gate 
67767c478bd9Sstevel@tonic-gate 		if ((cm_rep_msgp->rep_rnr_retry_cnt_plus >> 4) & 0x1)
67777c478bd9Sstevel@tonic-gate 			IBCM_EVT_REP(event).rep_flags |= IBT_CM_SRQ_EXISTS;
67787c478bd9Sstevel@tonic-gate 
6779fde3102fShiremath 		IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_rep: statep 0x%p "
67807c478bd9Sstevel@tonic-gate 		    "rep_service_time %d", statep,
67817c478bd9Sstevel@tonic-gate 		    IBCM_EVT_REP(event).rep_service_time);
67827c478bd9Sstevel@tonic-gate 
67837c478bd9Sstevel@tonic-gate 		event.cm_priv_data = &(cm_rep_msgp->rep_private_data[0]);
67847c478bd9Sstevel@tonic-gate 		event.cm_priv_data_len = IBT_REP_PRIV_DATA_SZ;
67857c478bd9Sstevel@tonic-gate 
67867c478bd9Sstevel@tonic-gate 		/*
67877c478bd9Sstevel@tonic-gate 		 * Allocate priv_data of size IBT_MAX_PRIV_DATA_SZ
67887c478bd9Sstevel@tonic-gate 		 */
67897c478bd9Sstevel@tonic-gate 		priv_data = kmem_zalloc(IBT_MAX_PRIV_DATA_SZ, KM_SLEEP);
67907c478bd9Sstevel@tonic-gate 		bzero(&ret_args, sizeof (ret_args));
67917c478bd9Sstevel@tonic-gate 
67927c478bd9Sstevel@tonic-gate 
67937c478bd9Sstevel@tonic-gate 		ibcm_insert_trace(statep, IBCM_TRACE_CALLED_REP_RCVD_EVENT);
67947c478bd9Sstevel@tonic-gate 
67957c478bd9Sstevel@tonic-gate 		/* invoke the CM handler */
67967c478bd9Sstevel@tonic-gate 		cb_status = statep->cm_handler(statep->state_cm_private, &event,
67977c478bd9Sstevel@tonic-gate 		    &ret_args, priv_data, IBT_RTU_PRIV_DATA_SZ);
67987c478bd9Sstevel@tonic-gate 
67997c478bd9Sstevel@tonic-gate 		ibcm_insert_trace(statep, IBCM_TRACE_RET_REP_RCVD_EVENT);
68007c478bd9Sstevel@tonic-gate 
6801fde3102fShiremath 		IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_rep: statep 0x%p "
68027c478bd9Sstevel@tonic-gate 		    "Client handler returned %x", statep, cb_status);
68037c478bd9Sstevel@tonic-gate 
68047c478bd9Sstevel@tonic-gate 		if (cb_status == IBT_CM_DEFER) {
68057c478bd9Sstevel@tonic-gate 			if (statep->defer_cm_msg == NULL)
68067c478bd9Sstevel@tonic-gate 				statep->defer_cm_msg =
68077c478bd9Sstevel@tonic-gate 				    kmem_zalloc(IBCM_MSG_SIZE, KM_SLEEP);
68087c478bd9Sstevel@tonic-gate 			bcopy(cm_rep_msgp, statep->defer_cm_msg, IBCM_MSG_SIZE);
68097c478bd9Sstevel@tonic-gate 
68107c478bd9Sstevel@tonic-gate 			/* unblock any blocked cm proceed api calls */
68117c478bd9Sstevel@tonic-gate 			mutex_enter(&statep->state_mutex);
68127c478bd9Sstevel@tonic-gate 			statep->clnt_proceed = IBCM_UNBLOCK;
68137c478bd9Sstevel@tonic-gate 			cv_broadcast(&statep->block_client_cv);
68147c478bd9Sstevel@tonic-gate 			mutex_exit(&statep->state_mutex);
68157c478bd9Sstevel@tonic-gate 
68167c478bd9Sstevel@tonic-gate 			kmem_free(priv_data, IBT_MAX_PRIV_DATA_SZ);
68177c478bd9Sstevel@tonic-gate 			return (IBCM_DEFER);
68187c478bd9Sstevel@tonic-gate 		}
68197c478bd9Sstevel@tonic-gate 	}
68207c478bd9Sstevel@tonic-gate 
68217c478bd9Sstevel@tonic-gate 	/* fail any blocked cm proceed api calls - client bug */
68227c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
68237c478bd9Sstevel@tonic-gate 	statep->clnt_proceed = IBCM_FAIL;
68247c478bd9Sstevel@tonic-gate 	cv_broadcast(&statep->block_client_cv);
68257c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
68267c478bd9Sstevel@tonic-gate 
68277c478bd9Sstevel@tonic-gate 	clnt_info.reply_event = (ibt_cm_proceed_reply_t *)&ret_args.cm_ret;
68287c478bd9Sstevel@tonic-gate 	clnt_info.priv_data = priv_data;
68297c478bd9Sstevel@tonic-gate 	clnt_info.priv_data_len = ret_args.cm_ret_len;
68307c478bd9Sstevel@tonic-gate 
68317c478bd9Sstevel@tonic-gate 	rval =
68327c478bd9Sstevel@tonic-gate 	    ibcm_process_cep_rep_cm_hdlr(statep, cb_status, &clnt_info,
68337c478bd9Sstevel@tonic-gate 	    reject_reason, arej_len, cm_rep_msgp);
68347c478bd9Sstevel@tonic-gate 
68357c478bd9Sstevel@tonic-gate 	if (priv_data != NULL)
68367c478bd9Sstevel@tonic-gate 		kmem_free(priv_data, IBT_MAX_PRIV_DATA_SZ);
68377c478bd9Sstevel@tonic-gate 	return (rval);
68387c478bd9Sstevel@tonic-gate }
68397c478bd9Sstevel@tonic-gate 
68407c478bd9Sstevel@tonic-gate 
68417c478bd9Sstevel@tonic-gate /*
68427c478bd9Sstevel@tonic-gate  * ibcm_process_cep_rep_cm_hdlr:
68437c478bd9Sstevel@tonic-gate  *	Processes the response from client handler for an incoming REP.
68447c478bd9Sstevel@tonic-gate  */
68457c478bd9Sstevel@tonic-gate ibcm_status_t
ibcm_process_cep_rep_cm_hdlr(ibcm_state_data_t * statep,ibt_cm_status_t cb_status,ibcm_clnt_reply_info_t * clnt_info,ibt_cm_reason_t * reject_reason,uint8_t * arej_len,ibcm_rep_msg_t * cm_rep_msgp)68467c478bd9Sstevel@tonic-gate ibcm_process_cep_rep_cm_hdlr(ibcm_state_data_t *statep,
68477c478bd9Sstevel@tonic-gate     ibt_cm_status_t cb_status, ibcm_clnt_reply_info_t *clnt_info,
68487c478bd9Sstevel@tonic-gate     ibt_cm_reason_t *reject_reason, uint8_t *arej_len,
68497c478bd9Sstevel@tonic-gate     ibcm_rep_msg_t *cm_rep_msgp)
68507c478bd9Sstevel@tonic-gate {
68517c478bd9Sstevel@tonic-gate 	ibcm_status_t		rval = IBCM_SEND_RTU;
68527c478bd9Sstevel@tonic-gate 	ibcm_rej_msg_t		*rej_msgp;
68537c478bd9Sstevel@tonic-gate 
68547c478bd9Sstevel@tonic-gate 	if (cb_status == IBT_CM_DEFAULT)
68557c478bd9Sstevel@tonic-gate 		cb_status = IBT_CM_ACCEPT;
68567c478bd9Sstevel@tonic-gate 
68577c478bd9Sstevel@tonic-gate 	if (cb_status == IBT_CM_REJECT) {
68587c478bd9Sstevel@tonic-gate 		*reject_reason = IBT_CM_CONSUMER;
68597c478bd9Sstevel@tonic-gate 	} else if (cb_status == IBT_CM_REDIRECT_PORT) {
68607c478bd9Sstevel@tonic-gate 		*reject_reason = IBT_CM_PORT_REDIRECT;
68617c478bd9Sstevel@tonic-gate 	} else if (cb_status == IBT_CM_REDIRECT) {
68627c478bd9Sstevel@tonic-gate 		*reject_reason = IBT_CM_REDIRECT_CM;
68637c478bd9Sstevel@tonic-gate 	} else if (cb_status == IBT_CM_NO_RESOURCE) {
68647c478bd9Sstevel@tonic-gate 		*reject_reason = IBT_CM_NO_RESC;
68657c478bd9Sstevel@tonic-gate 	} else if (cb_status != IBT_CM_ACCEPT) {
6866fde3102fShiremath 		IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_rep_cm_hdlr: statep "
6867fde3102fShiremath 		    "0x%p, Client handler returned unexpected value %d",
68687c478bd9Sstevel@tonic-gate 		    statep, cb_status);
68697c478bd9Sstevel@tonic-gate 		*reject_reason = IBT_CM_CONSUMER;
68707c478bd9Sstevel@tonic-gate 	} else
68717c478bd9Sstevel@tonic-gate 		*reject_reason = IBT_CM_SUCCESS;
68727c478bd9Sstevel@tonic-gate 
68737c478bd9Sstevel@tonic-gate 
68747c478bd9Sstevel@tonic-gate 	/* We come here if status is ACCEPT or CM handler is NULL */
68757c478bd9Sstevel@tonic-gate 	if (cb_status == IBT_CM_ACCEPT) {
68767c478bd9Sstevel@tonic-gate 		ib_time_t	time;
68777c478bd9Sstevel@tonic-gate 
68787c478bd9Sstevel@tonic-gate 		time = ibt_usec2ib(statep->pkt_life_time * 2 +
68797c478bd9Sstevel@tonic-gate 		    ibt_ib2usec(cm_rep_msgp->rep_target_delay_plus >> 3));
68807c478bd9Sstevel@tonic-gate 
6881fde3102fShiremath 		IBTF_DPRINTF_L5(cmlog, "ibcm_process_cep_rep_cm_hdlr: statep %p"
68827c478bd9Sstevel@tonic-gate 		    " active cep_timeout(usec) 0x%x ", statep, time);
68837c478bd9Sstevel@tonic-gate 
6884fde3102fShiremath 		IBTF_DPRINTF_L4(cmlog, "ibcm_process_cep_rep_cm_hdlr: statep %p"
68857c478bd9Sstevel@tonic-gate 		    " passive hca_ack_delay(ib_time) = 0x%x, ", statep,
68867c478bd9Sstevel@tonic-gate 		    cm_rep_msgp->rep_target_delay_plus >> 3);
68877c478bd9Sstevel@tonic-gate 
6888fde3102fShiremath 		IBTF_DPRINTF_L5(cmlog, "ibcm_process_cep_rep_cm_hdlr: statep %p"
68897c478bd9Sstevel@tonic-gate 		    " rnr_retry_cnt = 0x%x", statep,
68907c478bd9Sstevel@tonic-gate 		    cm_rep_msgp->rep_rnr_retry_cnt_plus >> 5);
68917c478bd9Sstevel@tonic-gate 
68927c478bd9Sstevel@tonic-gate 		_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
68937c478bd9Sstevel@tonic-gate 		statep->starting_psn =
68947c478bd9Sstevel@tonic-gate 		    b2h32(cm_rep_msgp->rep_starting_psn_plus) >> 8;
68957c478bd9Sstevel@tonic-gate 
68967c478bd9Sstevel@tonic-gate 		_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
68977c478bd9Sstevel@tonic-gate 
68987c478bd9Sstevel@tonic-gate 		/* Call IBTL CM's qp modify function from Init to RTR */
68997c478bd9Sstevel@tonic-gate 		if (ibcm_invoke_qp_modify(statep,
69007c478bd9Sstevel@tonic-gate 		    (ibcm_req_msg_t *)IBCM_OUT_MSGP(statep->stored_msg),
69017c478bd9Sstevel@tonic-gate 		    cm_rep_msgp) != IBT_SUCCESS) {
69027c478bd9Sstevel@tonic-gate 
6903fde3102fShiremath 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_rep_cm_hdlr: "
6904fde3102fShiremath 			    "statep %p, ibcm_invoke_qp_modify to RTR failed",
6905fde3102fShiremath 			    statep);
69067c478bd9Sstevel@tonic-gate 			*reject_reason = IBT_CM_NO_RESC;
69077c478bd9Sstevel@tonic-gate 		/*
69087c478bd9Sstevel@tonic-gate 		 * Call modify qp function from RTR to RTS
69097c478bd9Sstevel@tonic-gate 		 * RDMA initiator depth on active is same as negotiated
69107c478bd9Sstevel@tonic-gate 		 * passive REP's responder resources
69117c478bd9Sstevel@tonic-gate 		 */
69127c478bd9Sstevel@tonic-gate 		} else if (ibcm_invoke_rtu_qp_modify(statep, time, cm_rep_msgp)
69137c478bd9Sstevel@tonic-gate 		    != IBT_SUCCESS) {
69147c478bd9Sstevel@tonic-gate 
6915fde3102fShiremath 			IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_rep_cm_hdlr: "
6916fde3102fShiremath 			    "statep %p ibcm_invoke_rtu_qp_modify to RTS failed",
6917fde3102fShiremath 			    statep);
69187c478bd9Sstevel@tonic-gate 			(void) ibcm_cep_to_error_state(statep);
69197c478bd9Sstevel@tonic-gate 			*reject_reason = IBT_CM_NO_RESC;
69207c478bd9Sstevel@tonic-gate 		}
69217c478bd9Sstevel@tonic-gate 
69227c478bd9Sstevel@tonic-gate 		if (*reject_reason == IBT_CM_NO_RESC) {
69237c478bd9Sstevel@tonic-gate 
69247c478bd9Sstevel@tonic-gate 			/* Disassociate statep and QP */
69257c478bd9Sstevel@tonic-gate 			IBCM_SET_CHAN_PRIVATE(statep->channel, NULL);
69267c478bd9Sstevel@tonic-gate 
69277c478bd9Sstevel@tonic-gate 			ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
69287c478bd9Sstevel@tonic-gate 			    IBT_CM_FAILURE_REP, IBT_CM_CI_FAILURE, NULL, 0);
69297c478bd9Sstevel@tonic-gate 			return (IBCM_SEND_REJ);	/* send REJ */
69307c478bd9Sstevel@tonic-gate 		}
69317c478bd9Sstevel@tonic-gate 
69327c478bd9Sstevel@tonic-gate 		if (clnt_info->priv_data_len != 0) {
69337c478bd9Sstevel@tonic-gate 			ibcm_rtu_msg_t *rtu_msgp;
69347c478bd9Sstevel@tonic-gate 			rtu_msgp = (ibcm_rtu_msg_t *)
6935015f8fffShiremath 			    IBCM_OUT_MSGP(statep->stored_msg);
69367c478bd9Sstevel@tonic-gate 			bcopy(clnt_info->priv_data, rtu_msgp->rtu_private_data,
69377c478bd9Sstevel@tonic-gate 			    min(IBT_RTU_PRIV_DATA_SZ,
69387c478bd9Sstevel@tonic-gate 			    clnt_info->priv_data_len));
69397c478bd9Sstevel@tonic-gate 		}
69407c478bd9Sstevel@tonic-gate 
69417c478bd9Sstevel@tonic-gate 		*reject_reason = IBT_CM_SUCCESS;
69427c478bd9Sstevel@tonic-gate 		return (rval);
69437c478bd9Sstevel@tonic-gate 	}
69447c478bd9Sstevel@tonic-gate 
69457c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rej_msgp))
69467c478bd9Sstevel@tonic-gate 
69477c478bd9Sstevel@tonic-gate 	/* Fill up the REJ fields, from ret_args */
69487c478bd9Sstevel@tonic-gate 	rej_msgp = (ibcm_rej_msg_t *)IBCM_OUT_MSGP(statep->stored_msg);
69497c478bd9Sstevel@tonic-gate 	rej_msgp->rej_msg_type_plus = IBT_CM_FAILURE_REP << 6;
69507c478bd9Sstevel@tonic-gate 
69517c478bd9Sstevel@tonic-gate 	/* if priv_len != 0 use priv_data to copy back to rej_priv_data */
69527c478bd9Sstevel@tonic-gate 	if (clnt_info->priv_data_len != 0)
69537c478bd9Sstevel@tonic-gate 		bcopy(clnt_info->priv_data, rej_msgp->rej_private_data,
69547c478bd9Sstevel@tonic-gate 		    min(IBT_REJ_PRIV_DATA_SZ, clnt_info->priv_data_len));
69557c478bd9Sstevel@tonic-gate 
69567c478bd9Sstevel@tonic-gate 	if (clnt_info->reply_event != NULL)
69577c478bd9Sstevel@tonic-gate 		*arej_len =
69587c478bd9Sstevel@tonic-gate 		    min(clnt_info->reply_event->rej.ari_consumer.rej_ari_len,
69597c478bd9Sstevel@tonic-gate 		    IBT_CM_ADDL_REJ_LEN);
69607c478bd9Sstevel@tonic-gate 
69617c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(clnt_info->reply_event->rej))
69627c478bd9Sstevel@tonic-gate 
69637c478bd9Sstevel@tonic-gate 	if (*arej_len != 0)	/* asserts that clnt_info->reply_event != 0 */
69647c478bd9Sstevel@tonic-gate 		bcopy(clnt_info->reply_event->rej.ari_consumer.rej_ari,
69657c478bd9Sstevel@tonic-gate 		    &rej_msgp->rej_addl_rej_info, *arej_len);
69667c478bd9Sstevel@tonic-gate 
69677c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(clnt_info->reply_event->rej))
69687c478bd9Sstevel@tonic-gate 
69697c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rej_msgp))
69707c478bd9Sstevel@tonic-gate 
69717c478bd9Sstevel@tonic-gate 	rval = IBCM_SEND_REJ;
69727c478bd9Sstevel@tonic-gate 
69737c478bd9Sstevel@tonic-gate 	/* Disassociate statep and QP */
69747c478bd9Sstevel@tonic-gate 	IBCM_SET_CHAN_PRIVATE(statep->channel, NULL);
69757c478bd9Sstevel@tonic-gate 
69767c478bd9Sstevel@tonic-gate 	/* callback client, to enable client to do resource cleanup */
69777c478bd9Sstevel@tonic-gate 	ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
69787c478bd9Sstevel@tonic-gate 	    IBT_CM_FAILURE_REP, *reject_reason, NULL, 0);
69797c478bd9Sstevel@tonic-gate 
69807c478bd9Sstevel@tonic-gate 	return (rval);
69817c478bd9Sstevel@tonic-gate }
69827c478bd9Sstevel@tonic-gate 
69837c478bd9Sstevel@tonic-gate /*
69847c478bd9Sstevel@tonic-gate  * ibcm_invoke_rtu_qp_modify:
69857c478bd9Sstevel@tonic-gate  *	Helper function to modify QP for RTU only called from
69867c478bd9Sstevel@tonic-gate  *	ibcm_cep_state_rtu() and ibcm_cep_send_rtu()
69877c478bd9Sstevel@tonic-gate  *
69887c478bd9Sstevel@tonic-gate  * INPUTS:
69897c478bd9Sstevel@tonic-gate  *	statep		- connection state pointer
69907c478bd9Sstevel@tonic-gate  *
69917c478bd9Sstevel@tonic-gate  * RETURN VALUE:
69927c478bd9Sstevel@tonic-gate  */
69937c478bd9Sstevel@tonic-gate static ibt_status_t
ibcm_invoke_rtu_qp_modify(ibcm_state_data_t * statep,ib_time_t timeout,ibcm_rep_msg_t * rep_msg)69947c478bd9Sstevel@tonic-gate ibcm_invoke_rtu_qp_modify(ibcm_state_data_t *statep, ib_time_t timeout,
69957c478bd9Sstevel@tonic-gate     ibcm_rep_msg_t *rep_msg)
69967c478bd9Sstevel@tonic-gate {
69977c478bd9Sstevel@tonic-gate 	ibt_status_t		status;
69987c478bd9Sstevel@tonic-gate 	ibt_qp_info_t		qp_info;
69997c478bd9Sstevel@tonic-gate 	ibt_cep_modify_flags_t	cep_flags = IBT_CEP_SET_RTR_RTS;
70007c478bd9Sstevel@tonic-gate 
70017c478bd9Sstevel@tonic-gate 	/* Start filling up ibt_qp_info_t.  */
70027c478bd9Sstevel@tonic-gate 	bzero(&qp_info, sizeof (qp_info));
70037c478bd9Sstevel@tonic-gate 	qp_info.qp_trans = ibtl_cm_get_chan_type(statep->channel);
70047c478bd9Sstevel@tonic-gate 	qp_info.qp_current_state = IBT_STATE_RTR;
70057c478bd9Sstevel@tonic-gate 
70067c478bd9Sstevel@tonic-gate 	switch (qp_info.qp_trans) {
70077c478bd9Sstevel@tonic-gate 	case IBT_RC_SRV:
70087c478bd9Sstevel@tonic-gate 		IBCM_QPINFO_RC_PATH(qp_info).cep_timeout = timeout;
70097c478bd9Sstevel@tonic-gate 		IBCM_QPINFO_RC(qp_info).rc_retry_cnt = statep->cep_retry_cnt;
70107c478bd9Sstevel@tonic-gate 		IBCM_QPINFO_RC(qp_info).rc_rnr_retry_cnt =
70119c468ea9SPramod Gunjikar 		    statep->local_qp_rnr_cnt;
70127c478bd9Sstevel@tonic-gate 		IBCM_QPINFO_RC(qp_info).rc_sq_psn = statep->starting_psn;
70137c478bd9Sstevel@tonic-gate 
70147c478bd9Sstevel@tonic-gate 		if (statep->mode == IBCM_ACTIVE_MODE) {
70157c478bd9Sstevel@tonic-gate 			IBCM_QPINFO_RC(qp_info).rc_rdma_ra_out =
70167c478bd9Sstevel@tonic-gate 			    rep_msg->rep_resp_resources;
70177c478bd9Sstevel@tonic-gate 		} else {
70187c478bd9Sstevel@tonic-gate 			IBCM_QPINFO_RC(qp_info).rc_rdma_ra_out =
70197c478bd9Sstevel@tonic-gate 			    rep_msg->rep_initiator_depth;
70207c478bd9Sstevel@tonic-gate 		}
70217c478bd9Sstevel@tonic-gate 		if (statep->alt_port &&
70227c478bd9Sstevel@tonic-gate 		    (((rep_msg->rep_target_delay_plus >> 1) & 0x3) ==
70237c478bd9Sstevel@tonic-gate 		    IBT_CM_FAILOVER_ACCEPT)) {
70247c478bd9Sstevel@tonic-gate 			/* failover was accepted */
70257c478bd9Sstevel@tonic-gate 			cep_flags |= IBT_CEP_SET_MIG;
70267c478bd9Sstevel@tonic-gate 			IBCM_QPINFO_RC(qp_info).rc_mig_state =
70277c478bd9Sstevel@tonic-gate 			    IBT_STATE_REARMED;
70287c478bd9Sstevel@tonic-gate 		}
70297c478bd9Sstevel@tonic-gate 
70307c478bd9Sstevel@tonic-gate 		break;
70317c478bd9Sstevel@tonic-gate 	/* XXX RD? */
70327c478bd9Sstevel@tonic-gate 	case IBT_UC_SRV:
70337c478bd9Sstevel@tonic-gate 		IBCM_QPINFO_UC_PATH(qp_info).cep_timeout = timeout;
70347c478bd9Sstevel@tonic-gate 		break;
70357c478bd9Sstevel@tonic-gate 	default:
70367c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_invoke_rtu_qp_modify: "
70377c478bd9Sstevel@tonic-gate 		    "unknow svc_type = %x", qp_info.qp_trans);
70387c478bd9Sstevel@tonic-gate 		break;
70397c478bd9Sstevel@tonic-gate 	}
70407c478bd9Sstevel@tonic-gate 
70417c478bd9Sstevel@tonic-gate 	/* Call modify_qp */
70427c478bd9Sstevel@tonic-gate 	status = ibt_modify_qp(statep->channel, cep_flags, &qp_info, NULL);
70437c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_invoke_rtu_qp_modify: statep 0x%p "
70447c478bd9Sstevel@tonic-gate 	    "modify qp status = %d", statep, status);
70457c478bd9Sstevel@tonic-gate 
70467c478bd9Sstevel@tonic-gate 	if (status == IBT_SUCCESS)
70477c478bd9Sstevel@tonic-gate 		ibcm_insert_trace(statep, IBCM_TRACE_RTR_RTS);
70487c478bd9Sstevel@tonic-gate 	else
70497c478bd9Sstevel@tonic-gate 		ibcm_insert_trace(statep, IBCM_TRACE_RTR_RTS_FAIL);
70507c478bd9Sstevel@tonic-gate 
70517c478bd9Sstevel@tonic-gate #ifdef	DEBUG
70527c478bd9Sstevel@tonic-gate 	print_modify_qp("RTR to RTS", statep->channel, cep_flags, &qp_info);
70537c478bd9Sstevel@tonic-gate 
70547c478bd9Sstevel@tonic-gate 	if (statep->channel != NULL) {
70557c478bd9Sstevel@tonic-gate 		ibt_qp_query_attr_t	qp_attrs;
70567c478bd9Sstevel@tonic-gate 
70577c478bd9Sstevel@tonic-gate 		(void) ibt_query_qp(statep->channel, &qp_attrs);
70587c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_invoke_rtu_qp_modify: "
70597c478bd9Sstevel@tonic-gate 		    "qp_info.qp_state = %x", qp_attrs.qp_info.qp_state);
70607c478bd9Sstevel@tonic-gate 	}
70617c478bd9Sstevel@tonic-gate #endif
70627c478bd9Sstevel@tonic-gate 	return (status);
70637c478bd9Sstevel@tonic-gate }
70647c478bd9Sstevel@tonic-gate 
70657c478bd9Sstevel@tonic-gate 
70667c478bd9Sstevel@tonic-gate /*
70677c478bd9Sstevel@tonic-gate  * ibcm_cep_state_rtu:
70687c478bd9Sstevel@tonic-gate  *	QP state transition function called for an incoming RTU
70697c478bd9Sstevel@tonic-gate  *	on passive side.
70707c478bd9Sstevel@tonic-gate  *
70717c478bd9Sstevel@tonic-gate  * INPUTS:
70727c478bd9Sstevel@tonic-gate  *	statep		- connection state pointer
70737c478bd9Sstevel@tonic-gate  *	cm_rtu_msg	- RTU message pointer
70747c478bd9Sstevel@tonic-gate  *
70757c478bd9Sstevel@tonic-gate  */
70767c478bd9Sstevel@tonic-gate void
ibcm_cep_state_rtu(ibcm_state_data_t * statep,ibcm_rtu_msg_t * cm_rtu_msgp)70777c478bd9Sstevel@tonic-gate ibcm_cep_state_rtu(ibcm_state_data_t *statep, ibcm_rtu_msg_t *cm_rtu_msgp)
70787c478bd9Sstevel@tonic-gate {
70797c478bd9Sstevel@tonic-gate 	ibt_status_t	status;
70807c478bd9Sstevel@tonic-gate 	ibt_cm_event_t	event;
70817c478bd9Sstevel@tonic-gate 	ibcm_rep_msg_t	*rep_msgp = (ibcm_rep_msg_t *)
7082015f8fffShiremath 	    IBCM_OUT_MSGP(statep->stored_msg);
70837c478bd9Sstevel@tonic-gate 
70847c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_rtu: statep 0x%p", statep);
70857c478bd9Sstevel@tonic-gate 
70867c478bd9Sstevel@tonic-gate 	ASSERT(statep->channel != NULL);
70877c478bd9Sstevel@tonic-gate 
70887c478bd9Sstevel@tonic-gate 	/* RDMA initiator depth taken from negotiated REP values */
70897c478bd9Sstevel@tonic-gate 	status = ibcm_invoke_rtu_qp_modify(statep,
70907c478bd9Sstevel@tonic-gate 	    ibt_usec2ib(statep->remote_ack_delay), rep_msgp);
70917c478bd9Sstevel@tonic-gate 
70927c478bd9Sstevel@tonic-gate 	if (status != IBT_SUCCESS) {
70937c478bd9Sstevel@tonic-gate 
70947c478bd9Sstevel@tonic-gate 		(void) ibcm_cep_to_error_state(statep);
70957c478bd9Sstevel@tonic-gate 		/*
70967c478bd9Sstevel@tonic-gate 		 * Disassociate statep and QP, as there is a
70977c478bd9Sstevel@tonic-gate 		 * QP associated with this statep.
70987c478bd9Sstevel@tonic-gate 		 */
70997c478bd9Sstevel@tonic-gate 		IBCM_SET_CHAN_PRIVATE(statep->channel, NULL);
71007c478bd9Sstevel@tonic-gate 
71017c478bd9Sstevel@tonic-gate 		ibcm_post_rej_mad(statep, IBT_CM_NO_RESC,
71027c478bd9Sstevel@tonic-gate 		    IBT_CM_FAILURE_UNKNOWN, NULL, 0);
71037c478bd9Sstevel@tonic-gate 		/*
71047c478bd9Sstevel@tonic-gate 		 * Invoke CM handler, so client/server can do
71057c478bd9Sstevel@tonic-gate 		 * resource cleanup. No private data can be returned here
71067c478bd9Sstevel@tonic-gate 		 */
71077c478bd9Sstevel@tonic-gate 		ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
71087c478bd9Sstevel@tonic-gate 		    IBT_CM_FAILURE_UNKNOWN, IBT_CM_NO_RESC, NULL, 0);
71097c478bd9Sstevel@tonic-gate 
71107c478bd9Sstevel@tonic-gate 		/* unblock any pending DREQ threads */
71117c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
71127c478bd9Sstevel@tonic-gate 		statep->cep_in_rts = IBCM_FAIL;
71137c478bd9Sstevel@tonic-gate 		cv_broadcast(&statep->block_mad_cv);
71147c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
71157c478bd9Sstevel@tonic-gate 		return;
71167c478bd9Sstevel@tonic-gate 	}
71177c478bd9Sstevel@tonic-gate 
71187c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
71197c478bd9Sstevel@tonic-gate 	statep->state = IBCM_STATE_ESTABLISHED;
71207c478bd9Sstevel@tonic-gate 	ibtl_cm_chan_is_open(statep->channel);
71217c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
71227c478bd9Sstevel@tonic-gate 
71237c478bd9Sstevel@tonic-gate 	/* invoke the CM handler */
71247c478bd9Sstevel@tonic-gate 	ASSERT(statep->cm_handler != NULL);
71257c478bd9Sstevel@tonic-gate 
71267c478bd9Sstevel@tonic-gate 	bzero(&event, sizeof (event));
71277c478bd9Sstevel@tonic-gate 	event.cm_channel = statep->channel;
71287c478bd9Sstevel@tonic-gate 	event.cm_session_id = NULL;
71297c478bd9Sstevel@tonic-gate 
71307c478bd9Sstevel@tonic-gate 	event.cm_type = IBT_CM_EVENT_CONN_EST;
71317c478bd9Sstevel@tonic-gate 	if (cm_rtu_msgp != NULL) {
71327c478bd9Sstevel@tonic-gate 		event.cm_priv_data = &(cm_rtu_msgp->rtu_private_data[0]);
71337c478bd9Sstevel@tonic-gate 		event.cm_priv_data_len = IBT_RTU_PRIV_DATA_SZ;
71347c478bd9Sstevel@tonic-gate 	}
71357c478bd9Sstevel@tonic-gate 
71367c478bd9Sstevel@tonic-gate 	ibcm_insert_trace(statep, IBCM_TRACE_CALLED_CONN_EST_EVENT);
71377c478bd9Sstevel@tonic-gate 
71387c478bd9Sstevel@tonic-gate 	(void) statep->cm_handler(statep->state_cm_private, &event, NULL,
71397c478bd9Sstevel@tonic-gate 	    NULL, 0);
71407c478bd9Sstevel@tonic-gate 
71417c478bd9Sstevel@tonic-gate 	ibcm_insert_trace(statep, IBCM_TRACE_RET_CONN_EST_EVENT);
71427c478bd9Sstevel@tonic-gate 	if (ibcm_enable_trace & 4)
71437c478bd9Sstevel@tonic-gate 		ibcm_dump_conn_trace(statep);
71445974a6fcShiremath 	else
71455974a6fcShiremath 		IBTF_DPRINTF_L2(cmlog, "ibcm_cep_state_rtu CONN_EST Channel %p",
71465974a6fcShiremath 		    statep->channel);
71477c478bd9Sstevel@tonic-gate 
71487c478bd9Sstevel@tonic-gate 	/* unblock any pending DREQ threads */
71497c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
71507c478bd9Sstevel@tonic-gate 	statep->cep_in_rts = IBCM_UNBLOCK;
71517c478bd9Sstevel@tonic-gate 	cv_broadcast(&statep->block_mad_cv);
71527c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
71537c478bd9Sstevel@tonic-gate }
71547c478bd9Sstevel@tonic-gate 
71557c478bd9Sstevel@tonic-gate 
71567c478bd9Sstevel@tonic-gate /*
71577c478bd9Sstevel@tonic-gate  * ibcm_cep_send_rtu:
71587c478bd9Sstevel@tonic-gate  *	QP state transition function called for an outgoing RTU
71597c478bd9Sstevel@tonic-gate  *	on active side.
71607c478bd9Sstevel@tonic-gate  *
71617c478bd9Sstevel@tonic-gate  * INPUTS:
71627c478bd9Sstevel@tonic-gate  *	statep		- connection state pointer
71637c478bd9Sstevel@tonic-gate  *
71647c478bd9Sstevel@tonic-gate  * RETURN VALUE:
71657c478bd9Sstevel@tonic-gate  */
71667c478bd9Sstevel@tonic-gate void
ibcm_cep_send_rtu(ibcm_state_data_t * statep)71677c478bd9Sstevel@tonic-gate ibcm_cep_send_rtu(ibcm_state_data_t *statep)
71687c478bd9Sstevel@tonic-gate {
71697c478bd9Sstevel@tonic-gate 	/* invoke the CM handler */
71707c478bd9Sstevel@tonic-gate 	if (statep->cm_handler) {
71717c478bd9Sstevel@tonic-gate 		ibt_cm_event_t	event;
71727c478bd9Sstevel@tonic-gate 
71737c478bd9Sstevel@tonic-gate 		bzero(&event, sizeof (event));
71747c478bd9Sstevel@tonic-gate 		event.cm_type  = IBT_CM_EVENT_CONN_EST;
71757c478bd9Sstevel@tonic-gate 		event.cm_channel = statep->channel;
71767c478bd9Sstevel@tonic-gate 		event.cm_session_id = NULL;
71777c478bd9Sstevel@tonic-gate 		event.cm_priv_data = NULL;
71787c478bd9Sstevel@tonic-gate 		event.cm_priv_data_len = 0;
71797c478bd9Sstevel@tonic-gate 
71807c478bd9Sstevel@tonic-gate 		ibcm_insert_trace(statep, IBCM_TRACE_CALLED_CONN_EST_EVENT);
71817c478bd9Sstevel@tonic-gate 
71827c478bd9Sstevel@tonic-gate 		(void) statep->cm_handler(statep->state_cm_private, &event,
71837c478bd9Sstevel@tonic-gate 		    NULL, NULL, 0);
71847c478bd9Sstevel@tonic-gate 
71857c478bd9Sstevel@tonic-gate 		ibcm_insert_trace(statep, IBCM_TRACE_RET_CONN_EST_EVENT);
71867c478bd9Sstevel@tonic-gate 
71877c478bd9Sstevel@tonic-gate 	} else {
71887c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_cep_send_rtu: cm_handler NULL");
71897c478bd9Sstevel@tonic-gate 	}
71907c478bd9Sstevel@tonic-gate 	if (ibcm_enable_trace & 4)
71917c478bd9Sstevel@tonic-gate 		ibcm_dump_conn_trace(statep);
71925974a6fcShiremath 	else
71935974a6fcShiremath 		IBTF_DPRINTF_L2(cmlog, "ibcm_cep_send_rtu CONN_EST Channel %p",
71945974a6fcShiremath 		    statep->channel);
71957c478bd9Sstevel@tonic-gate 
71967c478bd9Sstevel@tonic-gate 	/* unblock any pending DREQ threads */
71977c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
71987c478bd9Sstevel@tonic-gate 	statep->cep_in_rts = IBCM_UNBLOCK;
71997c478bd9Sstevel@tonic-gate 	cv_broadcast(&statep->block_mad_cv);
72007c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
72017c478bd9Sstevel@tonic-gate }
72027c478bd9Sstevel@tonic-gate 
72037c478bd9Sstevel@tonic-gate 
72047c478bd9Sstevel@tonic-gate /*
72057c478bd9Sstevel@tonic-gate  * ibcm_cep_to_error_state:
72067c478bd9Sstevel@tonic-gate  *	CEP state transition function. Changes state to IBT_STATE_ERROR
72077c478bd9Sstevel@tonic-gate  *
72087c478bd9Sstevel@tonic-gate  * INPUTS:
72097c478bd9Sstevel@tonic-gate  *	statep		- connection state pointer
72107c478bd9Sstevel@tonic-gate  *
72117c478bd9Sstevel@tonic-gate  * RETURN VALUE:
72127c478bd9Sstevel@tonic-gate  *	IBT_SUCCESS	- if able to change state otherwise failure
72137c478bd9Sstevel@tonic-gate  */
72147c478bd9Sstevel@tonic-gate ibt_status_t
ibcm_cep_to_error_state(ibcm_state_data_t * statep)72157c478bd9Sstevel@tonic-gate ibcm_cep_to_error_state(ibcm_state_data_t *statep)
72167c478bd9Sstevel@tonic-gate {
72177c478bd9Sstevel@tonic-gate 	ibt_status_t		status = IBT_SUCCESS;
72187c478bd9Sstevel@tonic-gate 
72197c478bd9Sstevel@tonic-gate 	if (statep->channel != NULL) {
72207c478bd9Sstevel@tonic-gate 		ibt_qp_info_t	qp_info;
72217c478bd9Sstevel@tonic-gate 
72227c478bd9Sstevel@tonic-gate 		bzero(&qp_info, sizeof (qp_info));
72237c478bd9Sstevel@tonic-gate 		/* For now, set it to RC type */
72247c478bd9Sstevel@tonic-gate 		qp_info.qp_trans = IBT_RC_SRV;
72257c478bd9Sstevel@tonic-gate 		qp_info.qp_state = IBT_STATE_ERROR;
72267c478bd9Sstevel@tonic-gate 
72277c478bd9Sstevel@tonic-gate 		/* Call modify_qp to move to ERROR state */
72287c478bd9Sstevel@tonic-gate 		status = ibt_modify_qp(statep->channel, IBT_CEP_SET_STATE,
72297c478bd9Sstevel@tonic-gate 		    &qp_info, NULL);
72307c478bd9Sstevel@tonic-gate 
72317c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_cep_to_error_state: "
72327c478bd9Sstevel@tonic-gate 		    "statep %p ibt_modify_qp() = %d", statep, status);
72337c478bd9Sstevel@tonic-gate 
72347c478bd9Sstevel@tonic-gate 		if (status == IBT_SUCCESS)
72357c478bd9Sstevel@tonic-gate 			ibcm_insert_trace(statep, IBCM_TRACE_ERROR);
72367c478bd9Sstevel@tonic-gate 		else
72377c478bd9Sstevel@tonic-gate 			ibcm_insert_trace(statep, IBCM_TRACE_ERROR_FAIL);
72387c478bd9Sstevel@tonic-gate 
72397c478bd9Sstevel@tonic-gate 	}
72407c478bd9Sstevel@tonic-gate 
72417c478bd9Sstevel@tonic-gate #ifdef	NO_EEC_SUPPORT_YET
72427c478bd9Sstevel@tonic-gate 	if (statep->channel.ch_eec != NULL) {
72437c478bd9Sstevel@tonic-gate 		ibt_eec_info_t	eec_info;
72447c478bd9Sstevel@tonic-gate 
72457c478bd9Sstevel@tonic-gate 		bzero(&eec_info, sizeof (ibt_eec_info_t));
72467c478bd9Sstevel@tonic-gate 		eec_info.eec_state = what;
72477c478bd9Sstevel@tonic-gate 
72487c478bd9Sstevel@tonic-gate 		/* Call modify_eec */
72497c478bd9Sstevel@tonic-gate 		status = ibtl_cm_modify_eec(statep->channel.ch_eec, &eec_info,
72507c478bd9Sstevel@tonic-gate 		    IBT_CEP_SET_NOTHING);
72517c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_cep_to_error_state: "
72527c478bd9Sstevel@tonic-gate 		    "ibtl_cm_modify_eec() returned = %x", status);
72537c478bd9Sstevel@tonic-gate 	}
72547c478bd9Sstevel@tonic-gate #endif
72557c478bd9Sstevel@tonic-gate 
72567c478bd9Sstevel@tonic-gate 	return (status);
72577c478bd9Sstevel@tonic-gate }
72587c478bd9Sstevel@tonic-gate 
72597c478bd9Sstevel@tonic-gate 
72607c478bd9Sstevel@tonic-gate /*
72617c478bd9Sstevel@tonic-gate  * ibcm_cep_state_rej:
72627c478bd9Sstevel@tonic-gate  *	QP state transition function called for an incoming REJ
72637c478bd9Sstevel@tonic-gate  *	on active/passive side
72647c478bd9Sstevel@tonic-gate  *
72657c478bd9Sstevel@tonic-gate  * INPUTS:
72667c478bd9Sstevel@tonic-gate  *	statep		- connection state pointer
72677c478bd9Sstevel@tonic-gate  *	rej_msgp	- REJ message pointer
72687c478bd9Sstevel@tonic-gate  *	rej_state	- State where REJ processing began
72697c478bd9Sstevel@tonic-gate  *
72707c478bd9Sstevel@tonic-gate  * RETURN VALUE:
72717c478bd9Sstevel@tonic-gate  */
72727c478bd9Sstevel@tonic-gate void
ibcm_cep_state_rej(ibcm_state_data_t * statep,ibcm_rej_msg_t * rej_msgp,ibcm_conn_state_t rej_state)72737c478bd9Sstevel@tonic-gate ibcm_cep_state_rej(ibcm_state_data_t *statep, ibcm_rej_msg_t *rej_msgp,
72747c478bd9Sstevel@tonic-gate     ibcm_conn_state_t rej_state)
72757c478bd9Sstevel@tonic-gate {
72767c478bd9Sstevel@tonic-gate 	ibt_cm_event_t	event;
72777c478bd9Sstevel@tonic-gate 	ibt_status_t	status;
72787c478bd9Sstevel@tonic-gate 
72797c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_rej: statep 0x%p", statep);
72807c478bd9Sstevel@tonic-gate 
7281fde3102fShiremath 	ibcm_path_cache_purge();
7282fde3102fShiremath 
72837c478bd9Sstevel@tonic-gate 	if ((rej_state == IBCM_STATE_REP_SENT) ||
72847c478bd9Sstevel@tonic-gate 	    (rej_state == IBCM_STATE_MRA_REP_RCVD)) {
72857c478bd9Sstevel@tonic-gate 		status = ibcm_cep_to_error_state(statep);
7286fde3102fShiremath 		IBTF_DPRINTF_L5(cmlog, "ibcm_cep_state_rej: statep 0x%p "
72877c478bd9Sstevel@tonic-gate 		    "ibcm_cep_to_error_state returned %d", statep,
72887c478bd9Sstevel@tonic-gate 		    status);
72897c478bd9Sstevel@tonic-gate 	}
72907c478bd9Sstevel@tonic-gate 
7291ea46d761SPramod Gunjikar 	if (statep->channel)
7292ea46d761SPramod Gunjikar 		ibtl_cm_chan_open_is_aborted(statep->channel);
7293a23420cfSShantkumar Hiremath 
72947c478bd9Sstevel@tonic-gate 	/* Disassociate state structure and CM */
72957c478bd9Sstevel@tonic-gate 	IBCM_SET_CHAN_PRIVATE(statep->channel, NULL);
72967c478bd9Sstevel@tonic-gate 
72977c478bd9Sstevel@tonic-gate 	/* invoke the CM handler */
72987c478bd9Sstevel@tonic-gate 	bzero(&event, sizeof (event));
72997c478bd9Sstevel@tonic-gate 	if (statep->cm_handler) {
73007c478bd9Sstevel@tonic-gate 		event.cm_type = IBT_CM_EVENT_FAILURE;
73017c478bd9Sstevel@tonic-gate 		event.cm_channel = statep->channel;
73027c478bd9Sstevel@tonic-gate 		event.cm_session_id = NULL;
73037c478bd9Sstevel@tonic-gate 
73047c478bd9Sstevel@tonic-gate 		/*
73057c478bd9Sstevel@tonic-gate 		 * copy rej_msgp->rej_private_data to
73067c478bd9Sstevel@tonic-gate 		 * event.cm_event.cm_priv_data
73077c478bd9Sstevel@tonic-gate 		 */
73087c478bd9Sstevel@tonic-gate 		event.cm_priv_data = &(rej_msgp->rej_private_data[0]);
73097c478bd9Sstevel@tonic-gate 		event.cm_priv_data_len = IBT_REJ_PRIV_DATA_SZ;
73107c478bd9Sstevel@tonic-gate 
73117c478bd9Sstevel@tonic-gate 		event.cm_event.failed.cf_code = IBT_CM_FAILURE_REJ_RCV;
73127c478bd9Sstevel@tonic-gate 		event.cm_event.failed.cf_msg = rej_msgp->rej_msg_type_plus >> 6;
73137c478bd9Sstevel@tonic-gate 		event.cm_event.failed.cf_reason =
7314015f8fffShiremath 		    b2h16(rej_msgp->rej_rejection_reason);
73157c478bd9Sstevel@tonic-gate 
731624b28d04Shiremath 		IBTF_DPRINTF_L3(cmlog, "ibcm_cep_state_rej: rej_reason = %d",
73177c478bd9Sstevel@tonic-gate 		    event.cm_event.failed.cf_reason);
73187c478bd9Sstevel@tonic-gate 
73197c478bd9Sstevel@tonic-gate 		ibcm_copy_addl_rej(statep, rej_msgp, &event.cm_event.failed);
73207c478bd9Sstevel@tonic-gate 
73217c478bd9Sstevel@tonic-gate 		(void) statep->cm_handler(statep->state_cm_private, &event,
73227c478bd9Sstevel@tonic-gate 		    NULL, NULL, 0);
73237c478bd9Sstevel@tonic-gate 	}
73247c478bd9Sstevel@tonic-gate 
73257c478bd9Sstevel@tonic-gate 	if (statep->open_return_data != NULL)
73267c478bd9Sstevel@tonic-gate 		bcopy(&event.cm_event.failed.cf_additional,
73277c478bd9Sstevel@tonic-gate 		    &statep->open_return_data->rc_arej_info,
73287c478bd9Sstevel@tonic-gate 		    sizeof (ibt_arej_info_t));
73297c478bd9Sstevel@tonic-gate 	if (ibcm_enable_trace != 0)
73307c478bd9Sstevel@tonic-gate 		ibcm_dump_conn_trace(statep);
73319d3d2ed0Shiremath 	mutex_enter(&statep->state_mutex);
73329d3d2ed0Shiremath 	ibcm_open_done(statep);
73339d3d2ed0Shiremath 	mutex_exit(&statep->state_mutex);
73347c478bd9Sstevel@tonic-gate }
73357c478bd9Sstevel@tonic-gate 
73367c478bd9Sstevel@tonic-gate /* Used to initialize client args with addl rej information from REJ MAD */
73377c478bd9Sstevel@tonic-gate static void
ibcm_copy_addl_rej(ibcm_state_data_t * statep,ibcm_rej_msg_t * rej_msgp,ibt_cm_conn_failed_t * failed)73387c478bd9Sstevel@tonic-gate ibcm_copy_addl_rej(ibcm_state_data_t *statep, ibcm_rej_msg_t *rej_msgp,
73397c478bd9Sstevel@tonic-gate     ibt_cm_conn_failed_t *failed)
73407c478bd9Sstevel@tonic-gate {
7341*f248c5e0SToomas Soome 	uint16_t	rej_reason = b2h16(rej_msgp->rej_rejection_reason);
73425c42ea03Shiremath 	uint8_t		ari_len = rej_msgp->rej_reject_info_len_plus >> 1;
73437c478bd9Sstevel@tonic-gate 	ibcm_classportinfo_msg_t tclp;
73447c478bd9Sstevel@tonic-gate 	ibt_arej_info_t	*cf_addl = &failed->cf_additional;
73457c478bd9Sstevel@tonic-gate 
73467c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*cf_addl))
73477c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(failed->cf_arej_info_valid))
73487c478bd9Sstevel@tonic-gate 
73497c478bd9Sstevel@tonic-gate 	failed->cf_arej_info_valid = B_FALSE;
73507c478bd9Sstevel@tonic-gate 
735124b28d04Shiremath 	IBTF_DPRINTF_L3(cmlog, "ibcm_copy_addl_rej: rej_reason = %d "
735224b28d04Shiremath 	    "ari_len = %d", rej_reason, ari_len);
735324b28d04Shiremath 
73547c478bd9Sstevel@tonic-gate 	if ((statep->mode == IBCM_PASSIVE_MODE) &&
73557c478bd9Sstevel@tonic-gate 	    (rej_reason != IBT_CM_CONSUMER))
73567c478bd9Sstevel@tonic-gate 		return;
73577c478bd9Sstevel@tonic-gate 
73587c478bd9Sstevel@tonic-gate 	switch (rej_reason) {
73597c478bd9Sstevel@tonic-gate 	case IBT_CM_PRIM_GID:
73607c478bd9Sstevel@tonic-gate 	case IBT_CM_ALT_GID:
73617c478bd9Sstevel@tonic-gate 	case IBT_CM_PORT_REDIRECT:
73627c478bd9Sstevel@tonic-gate 		if (ari_len < sizeof (ib_gid_t))
73637c478bd9Sstevel@tonic-gate 			break;
73647c478bd9Sstevel@tonic-gate 		failed->cf_arej_info_valid = B_TRUE;
73657c478bd9Sstevel@tonic-gate 		bcopy(rej_msgp->rej_addl_rej_info, &cf_addl->ari_gid,
73667c478bd9Sstevel@tonic-gate 		    sizeof (ib_gid_t));
73677c478bd9Sstevel@tonic-gate 		cf_addl->ari_gid.gid_guid = b2h64(cf_addl->ari_gid.gid_guid);
73687c478bd9Sstevel@tonic-gate 		cf_addl->ari_gid.gid_prefix =
73697c478bd9Sstevel@tonic-gate 		    b2h64(cf_addl->ari_gid.gid_prefix);
737024b28d04Shiremath 
737124b28d04Shiremath 		IBTF_DPRINTF_L4(cmlog, "ibcm_copy_addl_rej: ari_gid= %llX:%llX",
737224b28d04Shiremath 		    cf_addl->ari_gid.gid_prefix, cf_addl->ari_gid.gid_guid);
737324b28d04Shiremath 
73747c478bd9Sstevel@tonic-gate 		break;
73757c478bd9Sstevel@tonic-gate 	case IBT_CM_PRIM_LID:
73767c478bd9Sstevel@tonic-gate 	case IBT_CM_ALT_LID:
73777c478bd9Sstevel@tonic-gate 		if (ari_len < sizeof (ib_lid_t))
73787c478bd9Sstevel@tonic-gate 			break;
73797c478bd9Sstevel@tonic-gate 		failed->cf_arej_info_valid = B_TRUE;
73807c478bd9Sstevel@tonic-gate 		bcopy(rej_msgp->rej_addl_rej_info, &cf_addl->ari_lid,
73817c478bd9Sstevel@tonic-gate 		    sizeof (ib_lid_t));
73827c478bd9Sstevel@tonic-gate 		cf_addl->ari_lid = b2h16(cf_addl->ari_lid);
738324b28d04Shiremath 		IBTF_DPRINTF_L4(cmlog, "ibcm_copy_addl_rej: ari_lid= 0x%lX",
738424b28d04Shiremath 		    cf_addl->ari_lid);
738524b28d04Shiremath 
73867c478bd9Sstevel@tonic-gate 		break;
73877c478bd9Sstevel@tonic-gate 	case IBT_CM_INVALID_PRIM_SL:
73887c478bd9Sstevel@tonic-gate 	case IBT_CM_INVALID_ALT_SL:
73897c478bd9Sstevel@tonic-gate 		if (ari_len < 1)
73907c478bd9Sstevel@tonic-gate 			break;
73917c478bd9Sstevel@tonic-gate 		failed->cf_arej_info_valid = B_TRUE;
73927c478bd9Sstevel@tonic-gate 		/* take the first 4 bits */
73937c478bd9Sstevel@tonic-gate 		cf_addl->ari_sl = rej_msgp->rej_addl_rej_info[0] >> 4;
73947c478bd9Sstevel@tonic-gate 		break;
73957c478bd9Sstevel@tonic-gate 	case IBT_CM_INVALID_PRIM_TC:
73967c478bd9Sstevel@tonic-gate 	case IBT_CM_INVALID_ALT_TC:
73977c478bd9Sstevel@tonic-gate 		if (ari_len < 1)
73987c478bd9Sstevel@tonic-gate 			break;
73997c478bd9Sstevel@tonic-gate 		failed->cf_arej_info_valid = B_TRUE;
74007c478bd9Sstevel@tonic-gate 		/* take the first byte */
74017c478bd9Sstevel@tonic-gate 		cf_addl->ari_tclass = rej_msgp->rej_addl_rej_info[0];
74027c478bd9Sstevel@tonic-gate 		break;
74037c478bd9Sstevel@tonic-gate 	case IBT_CM_INVALID_PRIM_HOP:
74047c478bd9Sstevel@tonic-gate 	case IBT_CM_INVALID_ALT_HOP:
74057c478bd9Sstevel@tonic-gate 		if (ari_len < 1)
74067c478bd9Sstevel@tonic-gate 			break;
74077c478bd9Sstevel@tonic-gate 		failed->cf_arej_info_valid = B_TRUE;
74087c478bd9Sstevel@tonic-gate 		/* take the first byte */
74097c478bd9Sstevel@tonic-gate 		cf_addl->ari_hop = rej_msgp->rej_addl_rej_info[0];
74107c478bd9Sstevel@tonic-gate 		break;
74117c478bd9Sstevel@tonic-gate 	case IBT_CM_INVALID_PRIM_RATE:
74127c478bd9Sstevel@tonic-gate 	case IBT_CM_INVALID_ALT_RATE:
74137c478bd9Sstevel@tonic-gate 		if (ari_len < 1)
74147c478bd9Sstevel@tonic-gate 			break;
74157c478bd9Sstevel@tonic-gate 		failed->cf_arej_info_valid = B_TRUE;
74167c478bd9Sstevel@tonic-gate 		/* take the first 6 bits */
74177c478bd9Sstevel@tonic-gate 		cf_addl->ari_rate = rej_msgp->rej_addl_rej_info[0] >> 2;
74187c478bd9Sstevel@tonic-gate 		break;
74197c478bd9Sstevel@tonic-gate 	case IBT_CM_REDIRECT_CM:
74207c478bd9Sstevel@tonic-gate 		if (ari_len < sizeof (ibcm_classportinfo_msg_t))
74217c478bd9Sstevel@tonic-gate 			break;
74227c478bd9Sstevel@tonic-gate 		failed->cf_arej_info_valid = B_TRUE;
74237c478bd9Sstevel@tonic-gate 		bcopy(rej_msgp->rej_addl_rej_info, &tclp, sizeof (tclp));
74247c478bd9Sstevel@tonic-gate 		ibcm_init_clp_from_mad(&tclp, &cf_addl->ari_redirect);
74257c478bd9Sstevel@tonic-gate 		break;
74267c478bd9Sstevel@tonic-gate 	case IBT_CM_INVALID_MTU:
74277c478bd9Sstevel@tonic-gate 		if (ari_len < 1)
74287c478bd9Sstevel@tonic-gate 			break;
74297c478bd9Sstevel@tonic-gate 		failed->cf_arej_info_valid = B_TRUE;
74307c478bd9Sstevel@tonic-gate 		/* take the first 4 bits */
74317c478bd9Sstevel@tonic-gate 		cf_addl->ari_mtu = rej_msgp->rej_addl_rej_info[0] >> 4;
74327c478bd9Sstevel@tonic-gate 		break;
74337c478bd9Sstevel@tonic-gate 	case IBT_CM_CONSUMER:
74347c478bd9Sstevel@tonic-gate 		if (ari_len == 0)
74357c478bd9Sstevel@tonic-gate 			break;
74367c478bd9Sstevel@tonic-gate 		failed->cf_arej_info_valid = B_TRUE;
74377c478bd9Sstevel@tonic-gate 		if (ari_len > IBT_CM_ADDL_REJ_LEN)
74387c478bd9Sstevel@tonic-gate 			ari_len = IBT_CM_ADDL_REJ_LEN;
74397c478bd9Sstevel@tonic-gate 		bcopy(&rej_msgp->rej_addl_rej_info,
74407c478bd9Sstevel@tonic-gate 		    cf_addl->ari_consumer.rej_ari, ari_len);
74417c478bd9Sstevel@tonic-gate 		cf_addl->ari_consumer.rej_ari_len = ari_len;
74427c478bd9Sstevel@tonic-gate 		break;
74437c478bd9Sstevel@tonic-gate 	case IBT_CM_INVALID_PRIM_FLOW:
74447c478bd9Sstevel@tonic-gate 	case IBT_CM_INVALID_ALT_FLOW:
74457c478bd9Sstevel@tonic-gate 		if (ari_len < 3)	/* 3 bytes needed for 20 bits */
74467c478bd9Sstevel@tonic-gate 			break;
74477c478bd9Sstevel@tonic-gate 		failed->cf_arej_info_valid = B_TRUE;
74487c478bd9Sstevel@tonic-gate 		/* take the first 20 bits */
74497c478bd9Sstevel@tonic-gate 		cf_addl->ari_flow =
74507c478bd9Sstevel@tonic-gate 		    b2h32(*(uint32_t *)&rej_msgp->rej_addl_rej_info) >> 12;
74517c478bd9Sstevel@tonic-gate 		break;
74527c478bd9Sstevel@tonic-gate 	default:
74537c478bd9Sstevel@tonic-gate 		break;
74547c478bd9Sstevel@tonic-gate 	}
74557c478bd9Sstevel@tonic-gate 
74567c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(failed->cf_arej_info_valid))
74577c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*cf_addl))
74587c478bd9Sstevel@tonic-gate }
74597c478bd9Sstevel@tonic-gate 
74607c478bd9Sstevel@tonic-gate 
74617c478bd9Sstevel@tonic-gate /* Used to copy classportinfo to MAD from client initialized args */
74627c478bd9Sstevel@tonic-gate static void
ibcm_init_clp_to_mad(ibcm_classportinfo_msg_t * clp,ibt_redirect_info_t * rinfo)74637c478bd9Sstevel@tonic-gate ibcm_init_clp_to_mad(ibcm_classportinfo_msg_t *clp, ibt_redirect_info_t *rinfo)
74647c478bd9Sstevel@tonic-gate {
74657c478bd9Sstevel@tonic-gate 
74667c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*clp))
74677c478bd9Sstevel@tonic-gate 
74687c478bd9Sstevel@tonic-gate 	bcopy(&ibcm_clpinfo, clp, sizeof (ibcm_clpinfo));
74697c478bd9Sstevel@tonic-gate 
74707c478bd9Sstevel@tonic-gate 	clp->RedirectGID_hi = h2b64(rinfo->rdi_gid.gid_prefix);
74717c478bd9Sstevel@tonic-gate 	clp->RedirectGID_lo = h2b64(rinfo->rdi_gid.gid_guid);
74727c478bd9Sstevel@tonic-gate 	clp->RedirectTC_plus =
74737c478bd9Sstevel@tonic-gate 	    h2b32((rinfo->rdi_tclass << 24) | (rinfo->rdi_sl << 20) |
74747c478bd9Sstevel@tonic-gate 	    (rinfo->rdi_flow & 0xfffff));
74757c478bd9Sstevel@tonic-gate 	clp->RedirectLID = h2b16(rinfo->rdi_dlid);
74767c478bd9Sstevel@tonic-gate 	clp->RedirectQP_plus = h2b32(rinfo->rdi_qpn & 0xffffff);
74777c478bd9Sstevel@tonic-gate 	clp->RedirectQ_Key = h2b32(rinfo->rdi_qkey);
74787c478bd9Sstevel@tonic-gate 	clp->RedirectP_Key = h2b16(rinfo->rdi_pkey);
74797c478bd9Sstevel@tonic-gate 
748024b28d04Shiremath 	IBTF_DPRINTF_L4(cmlog, "ibcm_init_clp_to_mad: RedirectGID= %llX:%llX,"
748124b28d04Shiremath 	    " RedirectLID= 0x%lX", clp->RedirectGID_hi, clp->RedirectGID_lo,
748224b28d04Shiremath 	    clp->RedirectLID);
748324b28d04Shiremath 
74847c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*clp))
74857c478bd9Sstevel@tonic-gate }
74867c478bd9Sstevel@tonic-gate 
74877c478bd9Sstevel@tonic-gate 
74887c478bd9Sstevel@tonic-gate /* Used to initialize classportinfo to be returned to clients, from MAD */
74897c478bd9Sstevel@tonic-gate static void
ibcm_init_clp_from_mad(ibcm_classportinfo_msg_t * clp,ibt_redirect_info_t * rinfo)74907c478bd9Sstevel@tonic-gate ibcm_init_clp_from_mad(ibcm_classportinfo_msg_t *clp,
74917c478bd9Sstevel@tonic-gate     ibt_redirect_info_t *rinfo)
74927c478bd9Sstevel@tonic-gate {
74937c478bd9Sstevel@tonic-gate 	uint32_t temp32;
74947c478bd9Sstevel@tonic-gate 
74957c478bd9Sstevel@tonic-gate 	rinfo->rdi_gid.gid_prefix = b2h64(clp->RedirectGID_hi);
74967c478bd9Sstevel@tonic-gate 	rinfo->rdi_gid.gid_guid = b2h64(clp->RedirectGID_lo);
74977c478bd9Sstevel@tonic-gate 	temp32 = b2h32(clp->RedirectTC_plus);
74987c478bd9Sstevel@tonic-gate 	rinfo->rdi_tclass = temp32 >> 24;
74997c478bd9Sstevel@tonic-gate 	rinfo->rdi_sl = (temp32 >> 20) & 0xf;
75007c478bd9Sstevel@tonic-gate 	rinfo->rdi_flow = temp32 & 0xffff;
75017c478bd9Sstevel@tonic-gate 	rinfo->rdi_dlid = b2h16(clp->RedirectLID);
75027c478bd9Sstevel@tonic-gate 	rinfo->rdi_qpn = b2h32(clp->RedirectQP_plus & 0xffffff);
75037c478bd9Sstevel@tonic-gate 	rinfo->rdi_qkey = b2h32(clp->RedirectQ_Key);
75047c478bd9Sstevel@tonic-gate 	rinfo->rdi_pkey = b2h16(clp->RedirectP_Key);
750524b28d04Shiremath 
750624b28d04Shiremath 	IBTF_DPRINTF_L4(cmlog, "ibcm_init_clp_from_mad: RedirectGID= %llX:%llX,"
750724b28d04Shiremath 	    " RedirectLID= 0x%lX", rinfo->rdi_gid.gid_prefix,
750824b28d04Shiremath 	    rinfo->rdi_gid.gid_guid, rinfo->rdi_dlid);
75097c478bd9Sstevel@tonic-gate }
75107c478bd9Sstevel@tonic-gate 
75117c478bd9Sstevel@tonic-gate 
75127c478bd9Sstevel@tonic-gate /*
75137c478bd9Sstevel@tonic-gate  * ibcm_cep_state_rej_est:
75147c478bd9Sstevel@tonic-gate  *	QP state transition function called for an incoming REJ
75157c478bd9Sstevel@tonic-gate  *	on active side in established state
75167c478bd9Sstevel@tonic-gate  *
75177c478bd9Sstevel@tonic-gate  * INPUTS:
75187c478bd9Sstevel@tonic-gate  *	statep		- connection state pointer
75197c478bd9Sstevel@tonic-gate  *
75207c478bd9Sstevel@tonic-gate  * RETURN VALUE:
75217c478bd9Sstevel@tonic-gate  */
75227c478bd9Sstevel@tonic-gate void
ibcm_cep_state_rej_est(ibcm_state_data_t * statep)75237c478bd9Sstevel@tonic-gate ibcm_cep_state_rej_est(ibcm_state_data_t *statep)
75247c478bd9Sstevel@tonic-gate {
75257c478bd9Sstevel@tonic-gate 	ibt_cm_event_t	event;
75267c478bd9Sstevel@tonic-gate 	ibt_status_t	status;
75277c478bd9Sstevel@tonic-gate 
75287c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(cmlog, "ibcm_cep_state_rej_est:");
75297c478bd9Sstevel@tonic-gate 
75307c478bd9Sstevel@tonic-gate 	status = ibcm_cep_to_error_state(statep);
75317c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_rej_est: statep 0x%p "
75327c478bd9Sstevel@tonic-gate 	    "ibcm_cep_to_error_state returned %d", statep, status);
75337c478bd9Sstevel@tonic-gate 
75347c478bd9Sstevel@tonic-gate 	/* Disassociate state structure and CM */
75357c478bd9Sstevel@tonic-gate 	IBCM_SET_CHAN_PRIVATE(statep->channel, NULL);
75367c478bd9Sstevel@tonic-gate 
75377c478bd9Sstevel@tonic-gate 	ibtl_cm_chan_is_closing(statep->channel);
75387c478bd9Sstevel@tonic-gate 
75397c478bd9Sstevel@tonic-gate 	/* invoke the CM handler */
75407c478bd9Sstevel@tonic-gate 	if (statep->cm_handler) {
75417c478bd9Sstevel@tonic-gate 		bzero(&event, sizeof (event));
75427c478bd9Sstevel@tonic-gate 		event.cm_type = IBT_CM_EVENT_CONN_CLOSED;
75437c478bd9Sstevel@tonic-gate 		event.cm_channel = statep->channel;
75447c478bd9Sstevel@tonic-gate 		event.cm_session_id = NULL;
75457c478bd9Sstevel@tonic-gate 
75467c478bd9Sstevel@tonic-gate 		event.cm_priv_data = NULL;
75477c478bd9Sstevel@tonic-gate 		event.cm_priv_data_len = 0;
75487c478bd9Sstevel@tonic-gate 
75497c478bd9Sstevel@tonic-gate 		event.cm_event.closed = IBT_CM_CLOSED_REJ_RCVD;
75507c478bd9Sstevel@tonic-gate 
75517c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_rej_est: "
7552fde3102fShiremath 		    "rej_reason = %d", event.cm_event.failed.cf_reason);
75537c478bd9Sstevel@tonic-gate 
75547c478bd9Sstevel@tonic-gate 		ibcm_insert_trace(statep, IBCM_TRACE_CALLED_CONN_CLOSE_EVENT);
75557c478bd9Sstevel@tonic-gate 
75567c478bd9Sstevel@tonic-gate 		(void) statep->cm_handler(statep->state_cm_private, &event,
75577c478bd9Sstevel@tonic-gate 		    NULL, NULL, 0);
75587c478bd9Sstevel@tonic-gate 
75597c478bd9Sstevel@tonic-gate 		ibcm_insert_trace(statep, IBCM_TRACE_RET_CONN_CLOSE_EVENT);
75607c478bd9Sstevel@tonic-gate 
75617c478bd9Sstevel@tonic-gate 	}
75627c478bd9Sstevel@tonic-gate }
75637c478bd9Sstevel@tonic-gate 
75647c478bd9Sstevel@tonic-gate 
75657c478bd9Sstevel@tonic-gate /*
75667c478bd9Sstevel@tonic-gate  * ibcm_sidr_req_ud_handler:
75677c478bd9Sstevel@tonic-gate  *	Invoke Client's UD handler For SIDR_REQ msg
75687c478bd9Sstevel@tonic-gate  *
75697c478bd9Sstevel@tonic-gate  * INPUTS:
75707c478bd9Sstevel@tonic-gate  *	ud_statep	- ud_state pointer
75717c478bd9Sstevel@tonic-gate  *	sidr_reqp	- SIDR_REQ message pointer
75727c478bd9Sstevel@tonic-gate  *
75737c478bd9Sstevel@tonic-gate  * RETURN VALUE: IBCM_SEND_REP/IBCM_SEND_REJ
75747c478bd9Sstevel@tonic-gate  */
75757c478bd9Sstevel@tonic-gate static ibcm_status_t
ibcm_sidr_req_ud_handler(ibcm_ud_state_data_t * ud_statep,ibcm_sidr_req_msg_t * sidr_reqp,ibcm_mad_addr_t * cm_mad_addr,ibt_sidr_status_t * sidr_status)75767c478bd9Sstevel@tonic-gate ibcm_sidr_req_ud_handler(ibcm_ud_state_data_t *ud_statep,
75777c478bd9Sstevel@tonic-gate     ibcm_sidr_req_msg_t *sidr_reqp, ibcm_mad_addr_t *cm_mad_addr,
75787c478bd9Sstevel@tonic-gate     ibt_sidr_status_t *sidr_status)
75797c478bd9Sstevel@tonic-gate {
75807c478bd9Sstevel@tonic-gate 	void			*priv_data = NULL;
75817c478bd9Sstevel@tonic-gate 	ibt_cm_ud_event_t	ud_event;
75827c478bd9Sstevel@tonic-gate 	ibcm_sidr_rep_msg_t	*sidr_repp;
75837c478bd9Sstevel@tonic-gate 	ibt_cm_ud_return_args_t	ud_ret_args;
75847c478bd9Sstevel@tonic-gate 	ibt_cm_status_t		cb_status;
75857c478bd9Sstevel@tonic-gate 	ibt_qp_query_attr_t	qp_attr;
75867c478bd9Sstevel@tonic-gate 	ibt_status_t		retval;
75877c478bd9Sstevel@tonic-gate 	ibcm_ud_clnt_reply_info_t	ud_clnt_info;
75887c478bd9Sstevel@tonic-gate 
75897c478bd9Sstevel@tonic-gate 	/* Check first if UD client handler is valid */
75907c478bd9Sstevel@tonic-gate 	ASSERT(ud_statep->ud_cm_handler != NULL);
75917c478bd9Sstevel@tonic-gate 
75927c478bd9Sstevel@tonic-gate 	/* Fill in ibt_cm_ud_event_t */
75937c478bd9Sstevel@tonic-gate 	ud_event.cm_type = IBT_CM_UD_EVENT_SIDR_REQ;
75947c478bd9Sstevel@tonic-gate 	ud_event.cm_session_id = ud_statep;
75957c478bd9Sstevel@tonic-gate 	ud_event.cm_event.sidr_req.sreq_service_id = ud_statep->ud_svc_id;
75967c478bd9Sstevel@tonic-gate 	ud_event.cm_event.sidr_req.sreq_hca_guid = ud_statep->ud_hcap->hca_guid;
75977c478bd9Sstevel@tonic-gate 	ud_event.cm_event.sidr_req.sreq_pkey = b2h16(sidr_reqp->sidr_req_pkey);
75987c478bd9Sstevel@tonic-gate 	ud_event.cm_event.sidr_req.sreq_hca_port = cm_mad_addr->port_num;
75997c478bd9Sstevel@tonic-gate 
76007c478bd9Sstevel@tonic-gate 	ud_event.cm_priv_data =
76017c478bd9Sstevel@tonic-gate 	    &(sidr_reqp->sidr_req_private_data[0]);
76027c478bd9Sstevel@tonic-gate 	ud_event.cm_priv_data_len = IBT_SIDR_REQ_PRIV_DATA_SZ;
76037c478bd9Sstevel@tonic-gate 
76047c478bd9Sstevel@tonic-gate 	sidr_repp =
76057c478bd9Sstevel@tonic-gate 	    (ibcm_sidr_rep_msg_t *)IBCM_OUT_MSGP(ud_statep->ud_stored_msg);
76067c478bd9Sstevel@tonic-gate 
76077c478bd9Sstevel@tonic-gate 	priv_data = &(sidr_repp->sidr_rep_private_data[0]);
76087c478bd9Sstevel@tonic-gate 
76097c478bd9Sstevel@tonic-gate 	bzero(&ud_ret_args, sizeof (ud_ret_args));
76107c478bd9Sstevel@tonic-gate 
76117c478bd9Sstevel@tonic-gate 	/* Invoke the client handler */
76127c478bd9Sstevel@tonic-gate 	cb_status = ud_statep->ud_cm_handler(ud_statep->ud_state_cm_private,
76137c478bd9Sstevel@tonic-gate 	    &ud_event, &ud_ret_args, priv_data, IBT_SIDR_REP_PRIV_DATA_SZ);
76147c478bd9Sstevel@tonic-gate 
76157c478bd9Sstevel@tonic-gate 	if (cb_status == IBT_CM_DEFER) {
76167c478bd9Sstevel@tonic-gate 
76177c478bd9Sstevel@tonic-gate 		/* unblock any blocked cm ud proceed api calls */
76187c478bd9Sstevel@tonic-gate 		mutex_enter(&ud_statep->ud_state_mutex);
76197c478bd9Sstevel@tonic-gate 		ud_statep->ud_clnt_proceed = IBCM_UNBLOCK;
76207c478bd9Sstevel@tonic-gate 		cv_broadcast(&ud_statep->ud_block_client_cv);
76217c478bd9Sstevel@tonic-gate 		mutex_exit(&ud_statep->ud_state_mutex);
76227c478bd9Sstevel@tonic-gate 
76237c478bd9Sstevel@tonic-gate 		return (IBCM_DEFER);
76247c478bd9Sstevel@tonic-gate 	}
76257c478bd9Sstevel@tonic-gate 
76267c478bd9Sstevel@tonic-gate 	/* fail any blocked ud cm proceed api calls - client bug */
76277c478bd9Sstevel@tonic-gate 	mutex_enter(&ud_statep->ud_state_mutex);
76287c478bd9Sstevel@tonic-gate 	ud_statep->ud_clnt_proceed = IBCM_FAIL;
76297c478bd9Sstevel@tonic-gate 	cv_broadcast(&ud_statep->ud_block_client_cv);
76307c478bd9Sstevel@tonic-gate 	mutex_exit(&ud_statep->ud_state_mutex);
76317c478bd9Sstevel@tonic-gate 
76327c478bd9Sstevel@tonic-gate 	/* do the query qp as soon as possible, after return from cm handler */
76337c478bd9Sstevel@tonic-gate 	if (cb_status == IBT_CM_ACCEPT) {
76347c478bd9Sstevel@tonic-gate 		retval = ibt_query_qp(ud_ret_args.ud_channel, &qp_attr);
76357c478bd9Sstevel@tonic-gate 		if (retval != IBT_SUCCESS) {
76367c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_sidr_req_ud_handler: "
76377c478bd9Sstevel@tonic-gate 			    "Failed to retrieve QPN from the channel: %d",
76387c478bd9Sstevel@tonic-gate 			    retval);
76397c478bd9Sstevel@tonic-gate 			*sidr_status = IBT_CM_SREP_NO_CHAN;
76407c478bd9Sstevel@tonic-gate 			return (IBCM_SEND_SIDR_REP);
76417c478bd9Sstevel@tonic-gate 		} else if (qp_attr.qp_info.qp_trans != IBT_UD_SRV) {
76427c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L2(cmlog, "ibcm_sidr_req_ud_handler: "
76437c478bd9Sstevel@tonic-gate 			    "Server/Passive returned non-UD %d transport type "
76447c478bd9Sstevel@tonic-gate 			    "QP", qp_attr.qp_info.qp_trans);
76457c478bd9Sstevel@tonic-gate 			*sidr_status = IBT_CM_SREP_NO_CHAN;
76467c478bd9Sstevel@tonic-gate 			return (IBCM_SEND_SIDR_REP);
76477c478bd9Sstevel@tonic-gate 		}
76487c478bd9Sstevel@tonic-gate 
76497c478bd9Sstevel@tonic-gate 		ud_clnt_info.ud_qkey = qp_attr.qp_info.qp_transport.ud.ud_qkey;
76507c478bd9Sstevel@tonic-gate 		ud_clnt_info.ud_qpn = qp_attr.qp_qpn;
76517c478bd9Sstevel@tonic-gate 	}
76527c478bd9Sstevel@tonic-gate 
76537c478bd9Sstevel@tonic-gate 	ud_clnt_info.priv_data = priv_data;
76547c478bd9Sstevel@tonic-gate 	ud_clnt_info.priv_data_len = ud_ret_args.ud_ret_len;
76557c478bd9Sstevel@tonic-gate 
76567c478bd9Sstevel@tonic-gate 	ud_clnt_info.redirect_infop = &ud_ret_args.ud_redirect;
76577c478bd9Sstevel@tonic-gate 
76587c478bd9Sstevel@tonic-gate 	ibcm_process_sidr_req_cm_hdlr(ud_statep, cb_status, &ud_clnt_info,
76597c478bd9Sstevel@tonic-gate 	    sidr_status, sidr_repp);
76607c478bd9Sstevel@tonic-gate 
76617c478bd9Sstevel@tonic-gate 	return (IBCM_SEND_SIDR_REP);
76627c478bd9Sstevel@tonic-gate }
76637c478bd9Sstevel@tonic-gate 
76647c478bd9Sstevel@tonic-gate /*ARGSUSED*/
76657c478bd9Sstevel@tonic-gate void
ibcm_process_sidr_req_cm_hdlr(ibcm_ud_state_data_t * ud_statep,ibt_cm_status_t cb_status,ibcm_ud_clnt_reply_info_t * ud_clnt_info,ibt_sidr_status_t * sidr_status,ibcm_sidr_rep_msg_t * sidr_repp)76667c478bd9Sstevel@tonic-gate ibcm_process_sidr_req_cm_hdlr(ibcm_ud_state_data_t *ud_statep,
76677c478bd9Sstevel@tonic-gate     ibt_cm_status_t cb_status, ibcm_ud_clnt_reply_info_t *ud_clnt_info,
76687c478bd9Sstevel@tonic-gate     ibt_sidr_status_t *sidr_status, ibcm_sidr_rep_msg_t *sidr_repp)
76697c478bd9Sstevel@tonic-gate {
76709c468ea9SPramod Gunjikar 	void	*sidr_rep_privp;
76719c468ea9SPramod Gunjikar 
76729c468ea9SPramod Gunjikar 	IBTF_DPRINTF_L5(cmlog, "ibcm_process_sidr_req_cm_hdlr(%p, %x, "
76739c468ea9SPramod Gunjikar 	    "%p, %p, %p)", ud_statep, cb_status, ud_clnt_info,
76749c468ea9SPramod Gunjikar 	    sidr_status, sidr_repp);
76759c468ea9SPramod Gunjikar 
76767c478bd9Sstevel@tonic-gate 	if (cb_status == IBT_CM_DEFAULT)
76777c478bd9Sstevel@tonic-gate 		cb_status = IBT_CM_REJECT;
76787c478bd9Sstevel@tonic-gate 
76797c478bd9Sstevel@tonic-gate 	if (cb_status == IBT_CM_ACCEPT)
76807c478bd9Sstevel@tonic-gate 		*sidr_status = IBT_CM_SREP_CHAN_VALID;
76817c478bd9Sstevel@tonic-gate 	else if ((cb_status == IBT_CM_REJECT) ||
76827c478bd9Sstevel@tonic-gate 	    (cb_status == IBT_CM_NO_RESOURCE))
76837c478bd9Sstevel@tonic-gate 		*sidr_status = IBT_CM_SREP_REJ;
76847c478bd9Sstevel@tonic-gate 	else if (cb_status == IBT_CM_NO_CHANNEL)
76857c478bd9Sstevel@tonic-gate 		*sidr_status = IBT_CM_SREP_NO_CHAN;
76867c478bd9Sstevel@tonic-gate 	else if (cb_status == IBT_CM_REDIRECT)
76877c478bd9Sstevel@tonic-gate 		*sidr_status = IBT_CM_SREP_REDIRECT;
76887c478bd9Sstevel@tonic-gate 	else *sidr_status = IBT_CM_SREP_REJ;
76897c478bd9Sstevel@tonic-gate 
76909c468ea9SPramod Gunjikar 	/*
76919c468ea9SPramod Gunjikar 	 * For Accept and reject copy the private data, if ud_clnt_info
76929c468ea9SPramod Gunjikar 	 * priv_data does not point to SIDR Response private data. This
76939c468ea9SPramod Gunjikar 	 * copy is needed for ibt_cm_ud_proceed().
76949c468ea9SPramod Gunjikar 	 */
76959c468ea9SPramod Gunjikar 	sidr_rep_privp = (void *)(&(sidr_repp->sidr_rep_private_data[0]));
76969c468ea9SPramod Gunjikar 	if ((cb_status == IBT_CM_ACCEPT || cb_status == IBT_CM_REJECT) &&
76979c468ea9SPramod Gunjikar 	    (ud_clnt_info->priv_data != sidr_rep_privp) &&
76989c468ea9SPramod Gunjikar 	    ud_clnt_info->priv_data_len) {
76999c468ea9SPramod Gunjikar 		bcopy(ud_clnt_info->priv_data, sidr_rep_privp,
77009c468ea9SPramod Gunjikar 		    min(ud_clnt_info->priv_data_len,
77019c468ea9SPramod Gunjikar 		    IBT_SIDR_REP_PRIV_DATA_SZ));
77029c468ea9SPramod Gunjikar 	}
77039c468ea9SPramod Gunjikar 
77047c478bd9Sstevel@tonic-gate 	if (*sidr_status != IBT_CM_SREP_CHAN_VALID) {
7705fde3102fShiremath 		IBTF_DPRINTF_L2(cmlog, "ibcm_process_sidr_req_cm_hdlr: "
77067c478bd9Sstevel@tonic-gate 		    "ud_handler return a failure: %d", cb_status);
77077c478bd9Sstevel@tonic-gate 		if (*sidr_status == IBT_CM_SREP_REDIRECT) {
77087c478bd9Sstevel@tonic-gate 		/*
77097c478bd9Sstevel@tonic-gate 		 * typecasting to ibcm_classportinfo_msg_t is ok, as addl info
77107c478bd9Sstevel@tonic-gate 		 * begins at offset 24 in sidr rep
77117c478bd9Sstevel@tonic-gate 		 */
77127c478bd9Sstevel@tonic-gate 			ibcm_init_clp_to_mad(
77137c478bd9Sstevel@tonic-gate 			    (ibcm_classportinfo_msg_t *)
77147c478bd9Sstevel@tonic-gate 			    &sidr_repp->sidr_rep_class_port_info,
77157c478bd9Sstevel@tonic-gate 			    ud_clnt_info->redirect_infop);
77167c478bd9Sstevel@tonic-gate 		}
77177c478bd9Sstevel@tonic-gate 		return;
77187c478bd9Sstevel@tonic-gate 	}
77197c478bd9Sstevel@tonic-gate 
77207c478bd9Sstevel@tonic-gate 
77217c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sidr_repp))
77227c478bd9Sstevel@tonic-gate 
77237c478bd9Sstevel@tonic-gate 	sidr_repp->sidr_rep_qkey =
77247c478bd9Sstevel@tonic-gate 	    h2b32(ud_clnt_info->ud_qkey);
77257c478bd9Sstevel@tonic-gate 	sidr_repp->sidr_rep_qpn_plus = h2b32(ud_clnt_info->ud_qpn << 8);
77267c478bd9Sstevel@tonic-gate 
77277c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sidr_repp))
77287c478bd9Sstevel@tonic-gate }
77297c478bd9Sstevel@tonic-gate 
77307c478bd9Sstevel@tonic-gate /*
77317c478bd9Sstevel@tonic-gate  * ibcm_sidr_rep_ud_handler:
77327c478bd9Sstevel@tonic-gate  *	Invoke Client's UD handler For SIDR_REP msg
77337c478bd9Sstevel@tonic-gate  *
77347c478bd9Sstevel@tonic-gate  * INPUTS:
77357c478bd9Sstevel@tonic-gate  *	ud_statep	- ud_state pointer
77367c478bd9Sstevel@tonic-gate  *	sidr_rep_msgp	- SIDR_REQ message pointer
77377c478bd9Sstevel@tonic-gate  *
77387c478bd9Sstevel@tonic-gate  */
77397c478bd9Sstevel@tonic-gate static void
ibcm_sidr_rep_ud_handler(ibcm_ud_state_data_t * ud_statep,ibcm_sidr_rep_msg_t * sidr_rep_msgp)77407c478bd9Sstevel@tonic-gate ibcm_sidr_rep_ud_handler(ibcm_ud_state_data_t *ud_statep,
77417c478bd9Sstevel@tonic-gate     ibcm_sidr_rep_msg_t *sidr_rep_msgp)
77427c478bd9Sstevel@tonic-gate {
77437c478bd9Sstevel@tonic-gate 	ibt_cm_ud_event_t	ud_event;
77447c478bd9Sstevel@tonic-gate 
77457c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L5(cmlog, "ibcm_sidr_rep_ud_handler: ud_statep 0x%p",
77467c478bd9Sstevel@tonic-gate 	    ud_statep);
77477c478bd9Sstevel@tonic-gate 
77487c478bd9Sstevel@tonic-gate 	/* Check first if UD client handler is valid */
77497c478bd9Sstevel@tonic-gate 	if (ud_statep->ud_cm_handler == NULL) {
77507c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_sidr_rep_ud_handler: "
77517c478bd9Sstevel@tonic-gate 		    "cm_handler NULL");
77527c478bd9Sstevel@tonic-gate 		return;
77537c478bd9Sstevel@tonic-gate 	}
77547c478bd9Sstevel@tonic-gate 
77557c478bd9Sstevel@tonic-gate 	/* Fill in ibt_cm_ud_event_t */
77567c478bd9Sstevel@tonic-gate 	ud_event.cm_type = IBT_CM_UD_EVENT_SIDR_REP;
77577c478bd9Sstevel@tonic-gate 	ud_event.cm_session_id = NULL;
77587c478bd9Sstevel@tonic-gate 	ud_event.cm_event.sidr_rep.srep_status =
77597c478bd9Sstevel@tonic-gate 	    sidr_rep_msgp->sidr_rep_rep_status;
77607c478bd9Sstevel@tonic-gate 	ud_event.cm_event.sidr_rep.srep_remote_qpn =
77617c478bd9Sstevel@tonic-gate 	    b2h32(sidr_rep_msgp->sidr_rep_qpn_plus) >> 8;
77627c478bd9Sstevel@tonic-gate 	ud_event.cm_event.sidr_rep.srep_remote_qkey =
77637c478bd9Sstevel@tonic-gate 	    h2b32(sidr_rep_msgp->sidr_rep_qkey);
77647c478bd9Sstevel@tonic-gate 
77657c478bd9Sstevel@tonic-gate 	if (ud_event.cm_event.sidr_rep.srep_status == IBT_CM_SREP_REDIRECT) {
77667c478bd9Sstevel@tonic-gate 		/*
77677c478bd9Sstevel@tonic-gate 		 * typecasting to ibcm_classportinfo_msg_t is ok, as addl info
77687c478bd9Sstevel@tonic-gate 		 * begins at offset 24 in sidr rep
77697c478bd9Sstevel@tonic-gate 		 */
77707c478bd9Sstevel@tonic-gate 		ibcm_init_clp_from_mad(
77717c478bd9Sstevel@tonic-gate 		    (ibcm_classportinfo_msg_t *)
77727c478bd9Sstevel@tonic-gate 		    sidr_rep_msgp->sidr_rep_class_port_info,
77737c478bd9Sstevel@tonic-gate 		    &ud_event.cm_event.sidr_rep.srep_redirect);
77747c478bd9Sstevel@tonic-gate 
77757c478bd9Sstevel@tonic-gate 		if (ud_statep->ud_return_data != NULL)
77767c478bd9Sstevel@tonic-gate 			bcopy(&ud_event.cm_event.sidr_rep.srep_redirect,
77777c478bd9Sstevel@tonic-gate 			    &ud_statep->ud_return_data->ud_redirect,
77787c478bd9Sstevel@tonic-gate 			    sizeof (ibt_redirect_info_t));
77797c478bd9Sstevel@tonic-gate 	}
77807c478bd9Sstevel@tonic-gate 
77817c478bd9Sstevel@tonic-gate 	ud_event.cm_priv_data = &(sidr_rep_msgp->sidr_rep_private_data[0]);
77827c478bd9Sstevel@tonic-gate 	ud_event.cm_priv_data_len = IBT_SIDR_REP_PRIV_DATA_SZ;
77837c478bd9Sstevel@tonic-gate 
77847c478bd9Sstevel@tonic-gate 	/* Invoke the client handler - inform only, so ignore retval */
77857c478bd9Sstevel@tonic-gate 	(void) ud_statep->ud_cm_handler(ud_statep->ud_state_cm_private,
77867c478bd9Sstevel@tonic-gate 	    &ud_event, NULL, NULL, 0);
77877c478bd9Sstevel@tonic-gate 
77887c478bd9Sstevel@tonic-gate 
77897c478bd9Sstevel@tonic-gate }
77907c478bd9Sstevel@tonic-gate 
77917c478bd9Sstevel@tonic-gate /*
77927c478bd9Sstevel@tonic-gate  * ibcm_process_lap_msg:
77937c478bd9Sstevel@tonic-gate  *	This call processes an incoming LAP message
77947c478bd9Sstevel@tonic-gate  *
77957c478bd9Sstevel@tonic-gate  * INPUTS:
77967c478bd9Sstevel@tonic-gate  *	hcap		- HCA entry pointer
77977c478bd9Sstevel@tonic-gate  *	input_madp	- incoming CM LAP MAD
77987c478bd9Sstevel@tonic-gate  *	cm_mad_addr	- Address information for the MAD
77997c478bd9Sstevel@tonic-gate  *
78007c478bd9Sstevel@tonic-gate  * RETURN VALUE: NONE
78017c478bd9Sstevel@tonic-gate  */
78027c478bd9Sstevel@tonic-gate /* ARGSUSED */
78037c478bd9Sstevel@tonic-gate void
ibcm_process_lap_msg(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)78047c478bd9Sstevel@tonic-gate ibcm_process_lap_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
78057c478bd9Sstevel@tonic-gate     ibcm_mad_addr_t *cm_mad_addr)
78067c478bd9Sstevel@tonic-gate {
78077c478bd9Sstevel@tonic-gate 	ibcm_status_t		state_lookup_status;
78087c478bd9Sstevel@tonic-gate 	ibcm_lap_msg_t		*lap_msg = (ibcm_lap_msg_t *)
7809015f8fffShiremath 	    (&input_madp[IBCM_MAD_HDR_SIZE]);
78107c478bd9Sstevel@tonic-gate 	ibcm_apr_msg_t		*apr_msg;
78117c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep = NULL;
78127c478bd9Sstevel@tonic-gate 
78137c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_lap_msg:");
78147c478bd9Sstevel@tonic-gate 
78157c478bd9Sstevel@tonic-gate 	rw_enter(&hcap->hca_state_rwlock, RW_READER);
78167c478bd9Sstevel@tonic-gate 
78177c478bd9Sstevel@tonic-gate 	state_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_LAP,
78187c478bd9Sstevel@tonic-gate 	    b2h32(lap_msg->lap_remote_comm_id), 0, 0, hcap, &statep);
78197c478bd9Sstevel@tonic-gate 
78207c478bd9Sstevel@tonic-gate 	rw_exit(&hcap->hca_state_rwlock);
78217c478bd9Sstevel@tonic-gate 
78227c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_lap_msg: lookup status %x"
78237c478bd9Sstevel@tonic-gate 	    " com id %x", state_lookup_status,
78247c478bd9Sstevel@tonic-gate 	    b2h32(lap_msg->lap_remote_comm_id));
78257c478bd9Sstevel@tonic-gate 
78267c478bd9Sstevel@tonic-gate 	if (state_lookup_status != IBCM_LOOKUP_EXISTS) {
78277c478bd9Sstevel@tonic-gate 		/* Post a REJ message ? - but spec doesn't state so */
78287c478bd9Sstevel@tonic-gate 		return;
78297c478bd9Sstevel@tonic-gate 	}
78307c478bd9Sstevel@tonic-gate 
78317c478bd9Sstevel@tonic-gate 	/* There is an existing state structure entry with active comid */
78327c478bd9Sstevel@tonic-gate 
78337c478bd9Sstevel@tonic-gate 	ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_LAP);
78347c478bd9Sstevel@tonic-gate 
78357c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
78367c478bd9Sstevel@tonic-gate 
78377c478bd9Sstevel@tonic-gate 	if ((statep->state == IBCM_STATE_ESTABLISHED) &&
78387c478bd9Sstevel@tonic-gate 	    (statep->ap_state == IBCM_AP_STATE_IDLE) &&
78397c478bd9Sstevel@tonic-gate 	    (statep->mode == IBCM_PASSIVE_MODE)) {
78407c478bd9Sstevel@tonic-gate 		if ((statep->lapr_msg) &&
78417c478bd9Sstevel@tonic-gate 		    (IBCM_OUT_HDRP(statep->lapr_msg)->TransactionID ==
78427c478bd9Sstevel@tonic-gate 		    ((ib_mad_hdr_t *)(input_madp))->TransactionID))
78437c478bd9Sstevel@tonic-gate 			ibcm_post_stored_apr_mad(statep, input_madp);
78447c478bd9Sstevel@tonic-gate 		else {
78457c478bd9Sstevel@tonic-gate 			ibcm_status_t	clnt_response;
78467c478bd9Sstevel@tonic-gate 
78477c478bd9Sstevel@tonic-gate 			statep->ap_state = IBCM_AP_STATE_LAP_RCVD;
78487c478bd9Sstevel@tonic-gate 			statep->clnt_proceed = IBCM_BLOCK;
78497c478bd9Sstevel@tonic-gate 			mutex_exit(&statep->state_mutex);
78507c478bd9Sstevel@tonic-gate 
78517c478bd9Sstevel@tonic-gate 			if (statep->lapr_msg == NULL) {
78527c478bd9Sstevel@tonic-gate 				if (ibcm_alloc_out_msg(
78537c478bd9Sstevel@tonic-gate 				    statep->stored_reply_addr.ibmf_hdl,
78547c478bd9Sstevel@tonic-gate 				    &statep->lapr_msg, MAD_METHOD_SEND) !=
78557c478bd9Sstevel@tonic-gate 				    IBT_SUCCESS) {
78567c478bd9Sstevel@tonic-gate 
78577c478bd9Sstevel@tonic-gate 					mutex_enter(&statep->state_mutex);
78587c478bd9Sstevel@tonic-gate 					statep->clnt_proceed = IBCM_FAIL;
78597c478bd9Sstevel@tonic-gate 					cv_broadcast(&statep->block_client_cv);
78607c478bd9Sstevel@tonic-gate 					IBCM_REF_CNT_DECR(statep);
78617c478bd9Sstevel@tonic-gate 					mutex_exit(&statep->state_mutex);
78627c478bd9Sstevel@tonic-gate 					return;
78637c478bd9Sstevel@tonic-gate 				}
78647c478bd9Sstevel@tonic-gate 			}
78657c478bd9Sstevel@tonic-gate 			apr_msg = (ibcm_apr_msg_t *)
78667c478bd9Sstevel@tonic-gate 			    IBCM_OUT_MSGP(statep->lapr_msg);
78677c478bd9Sstevel@tonic-gate 			IBCM_OUT_HDRP(statep->lapr_msg)->TransactionID =
78687c478bd9Sstevel@tonic-gate 			    ((ib_mad_hdr_t *)(input_madp))->TransactionID;
78697c478bd9Sstevel@tonic-gate 			clnt_response =
78707c478bd9Sstevel@tonic-gate 			    ibcm_cep_state_lap(statep, lap_msg, apr_msg);
78717c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L4(cmlog, "ibcm_process_lap_msg:"
78727c478bd9Sstevel@tonic-gate 			    " statep 0x%p  apr status %d", statep,
78737c478bd9Sstevel@tonic-gate 			    apr_msg->apr_ap_status);
78747c478bd9Sstevel@tonic-gate 
78757c478bd9Sstevel@tonic-gate 			if (clnt_response == IBCM_DEFER) {
78767c478bd9Sstevel@tonic-gate 				IBTF_DPRINTF_L4(cmlog, "ibcm_process_lap_msg: "
78777c478bd9Sstevel@tonic-gate 				    "client returned DEFER response");
78787c478bd9Sstevel@tonic-gate 				return;
78797c478bd9Sstevel@tonic-gate 			}
78807c478bd9Sstevel@tonic-gate 
78817c478bd9Sstevel@tonic-gate 			/* fail any blocked cm proceed api calls - client bug */
78827c478bd9Sstevel@tonic-gate 			mutex_enter(&statep->state_mutex);
78837c478bd9Sstevel@tonic-gate 			statep->clnt_proceed = IBCM_FAIL;
78847c478bd9Sstevel@tonic-gate 			cv_broadcast(&statep->block_client_cv);
78857c478bd9Sstevel@tonic-gate 			mutex_exit(&statep->state_mutex);
78867c478bd9Sstevel@tonic-gate 
78877c478bd9Sstevel@tonic-gate 			ibcm_post_apr_mad(statep);
78887c478bd9Sstevel@tonic-gate 			return;
78897c478bd9Sstevel@tonic-gate 		}
78907c478bd9Sstevel@tonic-gate 	}	/* drop the LAP MAD in any other state */
78917c478bd9Sstevel@tonic-gate 
78927c478bd9Sstevel@tonic-gate 	IBCM_REF_CNT_DECR(statep); /* decrement the ref count */
78937c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
78947c478bd9Sstevel@tonic-gate }
78957c478bd9Sstevel@tonic-gate 
78967c478bd9Sstevel@tonic-gate /*
78977c478bd9Sstevel@tonic-gate  * ibcm_post_stored_apr_mad:
78987c478bd9Sstevel@tonic-gate  *	Builds and posts an APR MAD from the stored APR MAD
78997c478bd9Sstevel@tonic-gate  *
79007c478bd9Sstevel@tonic-gate  * INPUTS:
79017c478bd9Sstevel@tonic-gate  *	statep		- pointer to ibcm_state_data_t
79027c478bd9Sstevel@tonic-gate  *	input_madp	- pointer to incoming lap mad
79037c478bd9Sstevel@tonic-gate  *
79047c478bd9Sstevel@tonic-gate  * RETURN VALUE:
79057c478bd9Sstevel@tonic-gate  *	NONE
79067c478bd9Sstevel@tonic-gate  *
79077c478bd9Sstevel@tonic-gate  * This function is called holding the state mutex, and returns
79087c478bd9Sstevel@tonic-gate  * holding the state mutex
79097c478bd9Sstevel@tonic-gate  */
79107c478bd9Sstevel@tonic-gate static void
ibcm_post_stored_apr_mad(ibcm_state_data_t * statep,uint8_t * input_madp)79117c478bd9Sstevel@tonic-gate ibcm_post_stored_apr_mad(ibcm_state_data_t *statep, uint8_t *input_madp)
79127c478bd9Sstevel@tonic-gate {
79137c478bd9Sstevel@tonic-gate 	ibmf_msg_t	*ibmf_apr_msg;
79147c478bd9Sstevel@tonic-gate 	uint8_t		apr_msg[IBCM_MSG_SIZE];
79157c478bd9Sstevel@tonic-gate 
79167c478bd9Sstevel@tonic-gate 	/* Need to make a copy, else an incoming new LAP may modify lapr_msg */
79177c478bd9Sstevel@tonic-gate 	bcopy(IBCM_OUT_MSGP(statep->lapr_msg), apr_msg, IBCM_MSG_SIZE);
79187c478bd9Sstevel@tonic-gate 
79197c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
79207c478bd9Sstevel@tonic-gate 
79217c478bd9Sstevel@tonic-gate 	if (ibcm_alloc_out_msg(statep->stored_reply_addr.ibmf_hdl,
79227c478bd9Sstevel@tonic-gate 	    &ibmf_apr_msg, MAD_METHOD_SEND) != IBT_SUCCESS) {
79237c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_post_stored_apr_mad: "
79247c478bd9Sstevel@tonic-gate 		    "ibcm_alloc_out_msg failed");
79257c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
79267c478bd9Sstevel@tonic-gate 		return;
79277c478bd9Sstevel@tonic-gate 	}
79287c478bd9Sstevel@tonic-gate 
79297c478bd9Sstevel@tonic-gate 	bcopy(apr_msg, IBCM_OUT_MSGP(ibmf_apr_msg), IBCM_MSG_SIZE);
79307c478bd9Sstevel@tonic-gate 
79317c478bd9Sstevel@tonic-gate 	IBCM_OUT_HDRP(ibmf_apr_msg)->AttributeID =
7932015f8fffShiremath 	    h2b16(IBCM_INCOMING_APR + IBCM_ATTR_BASE_ID);
79337c478bd9Sstevel@tonic-gate 
79347c478bd9Sstevel@tonic-gate 	IBCM_OUT_HDRP(ibmf_apr_msg)->TransactionID =
79357c478bd9Sstevel@tonic-gate 	    ((ib_mad_hdr_t *)(input_madp))->TransactionID;
79367c478bd9Sstevel@tonic-gate 
79377c478bd9Sstevel@tonic-gate 	ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_APR);
79387c478bd9Sstevel@tonic-gate 
79397c478bd9Sstevel@tonic-gate 	ibcm_post_rc_mad(statep, ibmf_apr_msg, ibcm_post_stored_apr_complete,
79407c478bd9Sstevel@tonic-gate 	    ibmf_apr_msg);
79417c478bd9Sstevel@tonic-gate 
79427c478bd9Sstevel@tonic-gate 	/* ibcm_free_out_msg done in ibcm_post_stored_apr_complete */
79437c478bd9Sstevel@tonic-gate 
79447c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
79457c478bd9Sstevel@tonic-gate }
79467c478bd9Sstevel@tonic-gate 
79477c478bd9Sstevel@tonic-gate /*
79487c478bd9Sstevel@tonic-gate  * ibcm_cep_state_lap:
79497c478bd9Sstevel@tonic-gate  *	This call processes an incoming LAP message for cep state
79507c478bd9Sstevel@tonic-gate  *	transition and invoking cm handler
79517c478bd9Sstevel@tonic-gate  *
79527c478bd9Sstevel@tonic-gate  * INPUTS:
79537c478bd9Sstevel@tonic-gate  *	statep		- pointer to ibcm_state_data_t
79547c478bd9Sstevel@tonic-gate  *	lap_msg		- lap msg received
79557c478bd9Sstevel@tonic-gate  *	apr_msg		- apr msg to be sent
79567c478bd9Sstevel@tonic-gate  *
79577c478bd9Sstevel@tonic-gate  * RETURN VALUE: NONE
79587c478bd9Sstevel@tonic-gate  */
79597c478bd9Sstevel@tonic-gate ibcm_status_t
ibcm_cep_state_lap(ibcm_state_data_t * statep,ibcm_lap_msg_t * lap_msg,ibcm_apr_msg_t * apr_msg)79607c478bd9Sstevel@tonic-gate ibcm_cep_state_lap(ibcm_state_data_t *statep, ibcm_lap_msg_t *lap_msg,
79617c478bd9Sstevel@tonic-gate     ibcm_apr_msg_t *apr_msg)
79627c478bd9Sstevel@tonic-gate {
79637c478bd9Sstevel@tonic-gate 	ibt_cm_event_t		event;
79647c478bd9Sstevel@tonic-gate 	ibt_cm_return_args_t	ret_args;
79657c478bd9Sstevel@tonic-gate 	ibt_cm_status_t		cb_status;
79667c478bd9Sstevel@tonic-gate 	ibcm_clnt_reply_info_t	clnt_info;
79677c478bd9Sstevel@tonic-gate 
79687c478bd9Sstevel@tonic-gate 
79697c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_lap: statep 0x%p", statep);
79707c478bd9Sstevel@tonic-gate 
79717c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*apr_msg))
79727c478bd9Sstevel@tonic-gate 
79737c478bd9Sstevel@tonic-gate 	/* If APM is not supported, return error */
79747c478bd9Sstevel@tonic-gate 	if (!(statep->hcap->hca_caps & IBT_HCA_AUTO_PATH_MIG)) {
79757c478bd9Sstevel@tonic-gate 		apr_msg->apr_ap_status = IBT_CM_AP_NOT_SUPPORTED;
79767c478bd9Sstevel@tonic-gate 		return (IBCM_SEND_APR);
79777c478bd9Sstevel@tonic-gate 	}
79787c478bd9Sstevel@tonic-gate 
79797c478bd9Sstevel@tonic-gate 	if (statep->local_qpn !=
79807c478bd9Sstevel@tonic-gate 	    b2h32(lap_msg->lap_remote_qpn_eecn_plus) >> 8) {
79817c478bd9Sstevel@tonic-gate 		apr_msg->apr_ap_status = IBT_CM_AP_REJECT;
79827c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_lap: local_qpn %x does "
79837c478bd9Sstevel@tonic-gate 		    "not match remote's remote_qpn %x", statep->local_qpn,
79847c478bd9Sstevel@tonic-gate 		    b2h32(lap_msg->lap_remote_qpn_eecn_plus) >> 8);
79857c478bd9Sstevel@tonic-gate 		return (IBCM_SEND_APR);
79867c478bd9Sstevel@tonic-gate 	}
79877c478bd9Sstevel@tonic-gate 
79887c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*apr_msg))
79897c478bd9Sstevel@tonic-gate 
79907c478bd9Sstevel@tonic-gate 	/* Fill up the event */
79917c478bd9Sstevel@tonic-gate 	bzero(&event, sizeof (event));
79927c478bd9Sstevel@tonic-gate 	event.cm_type = IBT_CM_EVENT_LAP_RCV;
79937c478bd9Sstevel@tonic-gate 	event.cm_channel = statep->channel;
79947c478bd9Sstevel@tonic-gate 	event.cm_session_id = statep;
79957c478bd9Sstevel@tonic-gate 	event.cm_priv_data = lap_msg->lap_private_data;
79967c478bd9Sstevel@tonic-gate 	event.cm_priv_data_len =  IBT_LAP_PRIV_DATA_SZ;
79977c478bd9Sstevel@tonic-gate 	event.cm_event.lap.lap_timeout = ibt_ib2usec(
79987c478bd9Sstevel@tonic-gate 	    ((uint8_t *)&lap_msg->lap_remote_qpn_eecn_plus)[3] >> 3);
79997c478bd9Sstevel@tonic-gate 
80007c478bd9Sstevel@tonic-gate 	ibcm_fill_adds_from_lap(&event.cm_event.lap.lap_alternate_path,
80017c478bd9Sstevel@tonic-gate 	    lap_msg, IBCM_PASSIVE_MODE);
80027c478bd9Sstevel@tonic-gate 
80037c478bd9Sstevel@tonic-gate 	cb_status = statep->cm_handler(statep->state_cm_private, &event,
80047c478bd9Sstevel@tonic-gate 	    &ret_args, apr_msg->apr_private_data, IBT_APR_PRIV_DATA_SZ);
80057c478bd9Sstevel@tonic-gate 
80067c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(cmlog, "ibcm_cep_state_lap: cb_status = %d", cb_status);
80077c478bd9Sstevel@tonic-gate 	if (cb_status == IBT_CM_DEFER) {
80087c478bd9Sstevel@tonic-gate 
80097c478bd9Sstevel@tonic-gate 		_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(statep->defer_cm_msg))
80107c478bd9Sstevel@tonic-gate 
80117c478bd9Sstevel@tonic-gate 		if (statep->defer_cm_msg == NULL)
80127c478bd9Sstevel@tonic-gate 			statep->defer_cm_msg =
80137c478bd9Sstevel@tonic-gate 			    kmem_zalloc(IBCM_MSG_SIZE, KM_SLEEP);
80147c478bd9Sstevel@tonic-gate 		bcopy(lap_msg, statep->defer_cm_msg, IBCM_MSG_SIZE);
80157c478bd9Sstevel@tonic-gate 
80167c478bd9Sstevel@tonic-gate 		_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(statep->defer_cm_msg))
80177c478bd9Sstevel@tonic-gate 
80187c478bd9Sstevel@tonic-gate 		/* unblock any blocked cm proceed api calls */
80197c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
80207c478bd9Sstevel@tonic-gate 		statep->clnt_proceed = IBCM_UNBLOCK;
80217c478bd9Sstevel@tonic-gate 		cv_broadcast(&statep->block_client_cv);
80227c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
80237c478bd9Sstevel@tonic-gate 
80247c478bd9Sstevel@tonic-gate 		return (IBCM_DEFER);
80257c478bd9Sstevel@tonic-gate 	}
80267c478bd9Sstevel@tonic-gate 
80277c478bd9Sstevel@tonic-gate 	clnt_info.reply_event = (ibt_cm_proceed_reply_t *)&ret_args.cm_ret;
80287c478bd9Sstevel@tonic-gate 	clnt_info.priv_data = NULL;
80297c478bd9Sstevel@tonic-gate 	clnt_info.priv_data_len = 0;
80307c478bd9Sstevel@tonic-gate 
80317c478bd9Sstevel@tonic-gate 	ibcm_process_cep_lap_cm_hdlr(statep, cb_status, &clnt_info, lap_msg,
80327c478bd9Sstevel@tonic-gate 	    apr_msg);
80337c478bd9Sstevel@tonic-gate 	return (IBCM_SEND_APR);
80347c478bd9Sstevel@tonic-gate }
80357c478bd9Sstevel@tonic-gate 
80367c478bd9Sstevel@tonic-gate /*
80377c478bd9Sstevel@tonic-gate  * ibcm_fill_adds_from_lap:
80387c478bd9Sstevel@tonic-gate  *	Fills the address vector (part of event structure passed to
80397c478bd9Sstevel@tonic-gate  * client) from the LAP message
80407c478bd9Sstevel@tonic-gate  *
80417c478bd9Sstevel@tonic-gate  * INPUTS:
80427c478bd9Sstevel@tonic-gate  *	adds		- Address vector to be filled-in
80437c478bd9Sstevel@tonic-gate  *	lap_msg		- LAP message used to fill the address vector
80447c478bd9Sstevel@tonic-gate  *
80457c478bd9Sstevel@tonic-gate  * RETURN VALUE: NONE
80467c478bd9Sstevel@tonic-gate  */
80477c478bd9Sstevel@tonic-gate static void
ibcm_fill_adds_from_lap(ibt_adds_vect_t * adds,ibcm_lap_msg_t * lap_msg,ibcm_mode_t mode)80487c478bd9Sstevel@tonic-gate ibcm_fill_adds_from_lap(ibt_adds_vect_t *adds, ibcm_lap_msg_t *lap_msg,
80497c478bd9Sstevel@tonic-gate     ibcm_mode_t mode)
80507c478bd9Sstevel@tonic-gate {
80517c478bd9Sstevel@tonic-gate 	adds->av_srvl = lap_msg->lap_alt_sl_plus >> 4;
80527c478bd9Sstevel@tonic-gate 	if (mode == IBCM_PASSIVE_MODE) {
80537c478bd9Sstevel@tonic-gate 		adds->av_dgid.gid_prefix =
80547c478bd9Sstevel@tonic-gate 		    b2h64(lap_msg->lap_alt_l_port_gid.gid_prefix);
80557c478bd9Sstevel@tonic-gate 		adds->av_dgid.gid_guid =
80567c478bd9Sstevel@tonic-gate 		    b2h64(lap_msg->lap_alt_l_port_gid.gid_guid);
80577c478bd9Sstevel@tonic-gate 		adds->av_sgid.gid_prefix =
80587c478bd9Sstevel@tonic-gate 		    b2h64(lap_msg->lap_alt_r_port_gid.gid_prefix);
80597c478bd9Sstevel@tonic-gate 		adds->av_sgid.gid_guid =
80607c478bd9Sstevel@tonic-gate 		    b2h64(lap_msg->lap_alt_r_port_gid.gid_guid);
80617c478bd9Sstevel@tonic-gate 		adds->av_dlid = b2h16(lap_msg->lap_alt_l_port_lid);
80627c478bd9Sstevel@tonic-gate 	} else {
80637c478bd9Sstevel@tonic-gate 		adds->av_sgid.gid_prefix =
80647c478bd9Sstevel@tonic-gate 		    b2h64(lap_msg->lap_alt_l_port_gid.gid_prefix);
80657c478bd9Sstevel@tonic-gate 		adds->av_sgid.gid_guid =
80667c478bd9Sstevel@tonic-gate 		    b2h64(lap_msg->lap_alt_l_port_gid.gid_guid);
80677c478bd9Sstevel@tonic-gate 		adds->av_dgid.gid_prefix =
80687c478bd9Sstevel@tonic-gate 		    b2h64(lap_msg->lap_alt_r_port_gid.gid_prefix);
80697c478bd9Sstevel@tonic-gate 		adds->av_dgid.gid_guid =
80707c478bd9Sstevel@tonic-gate 		    b2h64(lap_msg->lap_alt_r_port_gid.gid_guid);
80717c478bd9Sstevel@tonic-gate 		adds->av_dlid = b2h16(lap_msg->lap_alt_r_port_lid);
80727c478bd9Sstevel@tonic-gate 	}
80737c478bd9Sstevel@tonic-gate 
8074fde3102fShiremath 	IBTF_DPRINTF_L4(cmlog, "ibcm_fill_adds_from_lap: SGID=(%llX:%llX)",
80757c478bd9Sstevel@tonic-gate 	    adds->av_sgid.gid_prefix, adds->av_sgid.gid_guid);
80767c478bd9Sstevel@tonic-gate 
8077fde3102fShiremath 	IBTF_DPRINTF_L4(cmlog, "ibcm_fill_adds_from_lap: DGID=(%llX:%llX)",
80787c478bd9Sstevel@tonic-gate 	    adds->av_dgid.gid_prefix, adds->av_dgid.gid_guid);
80797c478bd9Sstevel@tonic-gate 
80807c478bd9Sstevel@tonic-gate 	adds->av_srate = lap_msg->lap_alt_srate_plus & 0x3f;
80817c478bd9Sstevel@tonic-gate 
80827c478bd9Sstevel@tonic-gate 	/* next copy off the GRH info if it exists  */
80837c478bd9Sstevel@tonic-gate 	if ((lap_msg->lap_alt_sl_plus & 0x8) == 0) {
80847c478bd9Sstevel@tonic-gate 		uint32_t flow_tclass = b2h32(lap_msg->lap_alt_flow_label_plus);
80857c478bd9Sstevel@tonic-gate 
80867c478bd9Sstevel@tonic-gate 		adds->av_send_grh = B_TRUE;
80877c478bd9Sstevel@tonic-gate 		adds->av_flow = flow_tclass >> 12;
80887c478bd9Sstevel@tonic-gate 		adds->av_tclass = flow_tclass & 0xff;
80897c478bd9Sstevel@tonic-gate 		adds->av_hop = lap_msg->lap_alt_hop_limit;
80907c478bd9Sstevel@tonic-gate 	} else {
80917c478bd9Sstevel@tonic-gate 		adds->av_send_grh = B_FALSE;
80927c478bd9Sstevel@tonic-gate 	}
80937c478bd9Sstevel@tonic-gate }
80947c478bd9Sstevel@tonic-gate 
80957c478bd9Sstevel@tonic-gate /*
80967c478bd9Sstevel@tonic-gate  * ibcm_process_cep_lap_cm_hdlr:
80977c478bd9Sstevel@tonic-gate  * Processes the cm handler response for an incoming LAP.
80987c478bd9Sstevel@tonic-gate  */
80997c478bd9Sstevel@tonic-gate 
81007c478bd9Sstevel@tonic-gate void
ibcm_process_cep_lap_cm_hdlr(ibcm_state_data_t * statep,ibt_cm_status_t cb_status,ibcm_clnt_reply_info_t * clnt_info,ibcm_lap_msg_t * lap_msg,ibcm_apr_msg_t * apr_msg)81017c478bd9Sstevel@tonic-gate ibcm_process_cep_lap_cm_hdlr(ibcm_state_data_t *statep,
81027c478bd9Sstevel@tonic-gate     ibt_cm_status_t cb_status, ibcm_clnt_reply_info_t *clnt_info,
81037c478bd9Sstevel@tonic-gate     ibcm_lap_msg_t *lap_msg, ibcm_apr_msg_t *apr_msg)
81047c478bd9Sstevel@tonic-gate {
81057c478bd9Sstevel@tonic-gate 	ibtl_cm_hca_port_t	port;
81067c478bd9Sstevel@tonic-gate 	ibt_qp_query_attr_t	qp_attrs;
81077c478bd9Sstevel@tonic-gate 	ibt_cep_modify_flags_t	cep_flags;
81087c478bd9Sstevel@tonic-gate 	ibt_status_t		status;
81097c478bd9Sstevel@tonic-gate 	ibt_adds_vect_t		*adds;
81107c478bd9Sstevel@tonic-gate 
81117c478bd9Sstevel@tonic-gate 	if (cb_status == IBT_CM_DEFAULT)
81127c478bd9Sstevel@tonic-gate 		cb_status = IBT_CM_REJECT;
81137c478bd9Sstevel@tonic-gate 
81147c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*apr_msg))
81157c478bd9Sstevel@tonic-gate 
81167c478bd9Sstevel@tonic-gate 	/* verify status */
81177c478bd9Sstevel@tonic-gate 	apr_msg->apr_addl_info_len = 0;
81187c478bd9Sstevel@tonic-gate 	if (cb_status == IBT_CM_ACCEPT) {
81197c478bd9Sstevel@tonic-gate 		apr_msg->apr_ap_status = IBT_CM_AP_LOADED;
81207c478bd9Sstevel@tonic-gate 	} else if (cb_status == IBT_CM_REJECT) {
81217c478bd9Sstevel@tonic-gate 		apr_msg->apr_ap_status = IBT_CM_AP_REJECT;
81227c478bd9Sstevel@tonic-gate 	} else if (cb_status == IBT_CM_REDIRECT) {
81237c478bd9Sstevel@tonic-gate 		apr_msg->apr_ap_status = IBT_CM_AP_REDIRECT;
81247c478bd9Sstevel@tonic-gate 		/* copy redirect info to APR */
81257c478bd9Sstevel@tonic-gate 		apr_msg->apr_addl_info_len = sizeof (ibcm_classportinfo_msg_t);
81267c478bd9Sstevel@tonic-gate 		ibcm_init_clp_to_mad(
81277c478bd9Sstevel@tonic-gate 		    (ibcm_classportinfo_msg_t *)apr_msg->apr_addl_info,
81287c478bd9Sstevel@tonic-gate 		    &clnt_info->reply_event->apr);
81297c478bd9Sstevel@tonic-gate 	} else if (cb_status == IBT_CM_NO_RESOURCE) {
81307c478bd9Sstevel@tonic-gate 		apr_msg->apr_ap_status = IBT_CM_AP_REJECT;
81317c478bd9Sstevel@tonic-gate 	} else {
81327c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_lap_cm_hdlr: statep %p"
81337c478bd9Sstevel@tonic-gate 		    " Client handler unexpected return %x", statep, cb_status);
81347c478bd9Sstevel@tonic-gate 		cb_status = IBT_CM_REJECT;
81357c478bd9Sstevel@tonic-gate 		apr_msg->apr_ap_status = IBT_CM_AP_REJECT;
81367c478bd9Sstevel@tonic-gate 	}
81377c478bd9Sstevel@tonic-gate 
81387c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_cep_lap_cm_hdlr: statep 0x%p "
81397c478bd9Sstevel@tonic-gate 	    " client handler returned %d, apr status %d", statep, cb_status,
81407c478bd9Sstevel@tonic-gate 	    apr_msg->apr_ap_status);
81417c478bd9Sstevel@tonic-gate 
81427c478bd9Sstevel@tonic-gate 	/* copy private data to outgoing apr, specified via priv_data */
81437c478bd9Sstevel@tonic-gate 	if ((clnt_info->priv_data != NULL) && (clnt_info->priv_data_len > 0))
81447c478bd9Sstevel@tonic-gate 		bcopy(clnt_info->priv_data, apr_msg->apr_private_data,
81457c478bd9Sstevel@tonic-gate 		    min(clnt_info->priv_data_len, IBT_APR_PRIV_DATA_SZ));
81467c478bd9Sstevel@tonic-gate 
81477c478bd9Sstevel@tonic-gate 	if (cb_status != IBT_CM_ACCEPT)
81487c478bd9Sstevel@tonic-gate 		return;
81497c478bd9Sstevel@tonic-gate 
81507c478bd9Sstevel@tonic-gate 	if (ibt_query_qp(statep->channel, &qp_attrs) != IBT_SUCCESS ||
81517c478bd9Sstevel@tonic-gate 	    (qp_attrs.qp_info.qp_state != IBT_STATE_RTS &&
81527c478bd9Sstevel@tonic-gate 	    qp_attrs.qp_info.qp_state != IBT_STATE_SQD)) {
81537c478bd9Sstevel@tonic-gate 		apr_msg->apr_ap_status = IBT_CM_AP_REJECT;
81547c478bd9Sstevel@tonic-gate 		return;
81557c478bd9Sstevel@tonic-gate 	}
81567c478bd9Sstevel@tonic-gate 
81577c478bd9Sstevel@tonic-gate 	/* Fill up input args for ibt_modify_qp */
81587c478bd9Sstevel@tonic-gate 	cep_flags = IBT_CEP_SET_ALT_PATH | IBT_CEP_SET_STATE;
81597c478bd9Sstevel@tonic-gate 
81607c478bd9Sstevel@tonic-gate 	/* do RTS=>RTS or SQD=>SQD.  The next line is needed for RTS=>RTS. */
81617c478bd9Sstevel@tonic-gate 	qp_attrs.qp_info.qp_current_state = qp_attrs.qp_info.qp_state;
81627c478bd9Sstevel@tonic-gate 
81637c478bd9Sstevel@tonic-gate 	adds = &IBCM_QP_RC(qp_attrs).rc_alt_path.cep_adds_vect;
81647c478bd9Sstevel@tonic-gate 	ibcm_fill_adds_from_lap(adds, lap_msg, IBCM_PASSIVE_MODE);
81657c478bd9Sstevel@tonic-gate 
81667c478bd9Sstevel@tonic-gate 	if ((status = ibtl_cm_get_hca_port(adds->av_sgid,
81677c478bd9Sstevel@tonic-gate 	    statep->local_hca_guid, &port)) != IBT_SUCCESS) {
81687c478bd9Sstevel@tonic-gate 
81697c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_lap_cm_hdlr:"
81707c478bd9Sstevel@tonic-gate 		    " ibtl_cm_get_hca_port failed status %d", status);
81717c478bd9Sstevel@tonic-gate 		apr_msg->apr_ap_status = IBT_CM_AP_REJECT;
81727c478bd9Sstevel@tonic-gate 		return;
81737c478bd9Sstevel@tonic-gate 	}
81747c478bd9Sstevel@tonic-gate 
81757c478bd9Sstevel@tonic-gate 	IBCM_QP_RC(qp_attrs).rc_alt_path.cep_hca_port_num = port.hp_port;
81767c478bd9Sstevel@tonic-gate 
8177fde3102fShiremath 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_cep_lap_cm_hdlr: statep 0x%p "
81787c478bd9Sstevel@tonic-gate 	    "gid = (%llx, %llx), port_num = %d", statep,
81797c478bd9Sstevel@tonic-gate 	    IBCM_QP_RC(qp_attrs).rc_alt_path.cep_adds_vect.av_dgid.
81807c478bd9Sstevel@tonic-gate 	    gid_prefix,
81817c478bd9Sstevel@tonic-gate 	    IBCM_QP_RC(qp_attrs).rc_alt_path.cep_adds_vect.av_dgid.gid_guid,
81827c478bd9Sstevel@tonic-gate 	    port.hp_port);
81837c478bd9Sstevel@tonic-gate 
81847c478bd9Sstevel@tonic-gate 	/* The pkey is same as the primary path */
81857c478bd9Sstevel@tonic-gate 	status = ibt_pkey2index_byguid(statep->local_hca_guid,
81867c478bd9Sstevel@tonic-gate 	    port.hp_port, statep->pkey,
81877c478bd9Sstevel@tonic-gate 	    &IBCM_QP_RC(qp_attrs).rc_alt_path.cep_pkey_ix);
81887c478bd9Sstevel@tonic-gate 
81897c478bd9Sstevel@tonic-gate 	if (status != IBT_SUCCESS) {
81907c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_lap_cm_hdlr: statep %p"
81917c478bd9Sstevel@tonic-gate 		    " ibt_pkey2index_byguid failed %d", statep, status);
81927c478bd9Sstevel@tonic-gate 		apr_msg->apr_ap_status = IBT_CM_AP_REJECT;
81937c478bd9Sstevel@tonic-gate 		return;
81947c478bd9Sstevel@tonic-gate 	}
81957c478bd9Sstevel@tonic-gate 
81967c478bd9Sstevel@tonic-gate 	IBCM_QP_RC(qp_attrs).rc_alt_path.cep_timeout =
81977c478bd9Sstevel@tonic-gate 	    lap_msg->lap_alt_local_acktime_plus >> 3;
81987c478bd9Sstevel@tonic-gate 
81997c478bd9Sstevel@tonic-gate 	qp_attrs.qp_info.qp_trans = IBT_RC_SRV;
82007c478bd9Sstevel@tonic-gate 	if (IBCM_QP_RC(qp_attrs).rc_mig_state == IBT_STATE_MIGRATED) {
82019d3d2ed0Shiremath 		IBTF_DPRINTF_L3(cmlog, "ibcm_process_cep_lap_cm_hdlr: statep %p"
82029d3d2ed0Shiremath 		    ": rearming APM", statep);
82037c478bd9Sstevel@tonic-gate 		cep_flags |= IBT_CEP_SET_MIG;
82047c478bd9Sstevel@tonic-gate 		IBCM_QP_RC(qp_attrs).rc_mig_state = IBT_STATE_REARMED;
82057c478bd9Sstevel@tonic-gate 	}
82067c478bd9Sstevel@tonic-gate 	status = ibt_modify_qp(statep->channel, cep_flags, &qp_attrs.qp_info,
82077c478bd9Sstevel@tonic-gate 	    NULL);
82087c478bd9Sstevel@tonic-gate 
82097c478bd9Sstevel@tonic-gate 	if (status != IBT_SUCCESS) {
82107c478bd9Sstevel@tonic-gate 		ibcm_insert_trace(statep, IBCM_TRACE_SET_ALT_FAIL);
82117c478bd9Sstevel@tonic-gate 	} else
82127c478bd9Sstevel@tonic-gate 		ibcm_insert_trace(statep, IBCM_TRACE_SET_ALT);
82137c478bd9Sstevel@tonic-gate 
82147c478bd9Sstevel@tonic-gate #ifdef	DEBUG
82157c478bd9Sstevel@tonic-gate 	(void) ibt_query_qp(statep->channel, &qp_attrs);
82167c478bd9Sstevel@tonic-gate 	print_modify_qp("PASSIVE LAP QUERY", statep->channel,
82177c478bd9Sstevel@tonic-gate 	    cep_flags, &qp_attrs.qp_info);
82187c478bd9Sstevel@tonic-gate #endif
82197c478bd9Sstevel@tonic-gate 
82207c478bd9Sstevel@tonic-gate 	if (status != IBT_SUCCESS) {
82217c478bd9Sstevel@tonic-gate 		apr_msg->apr_ap_status = IBT_CM_AP_REJECT;
82227c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_lap_cm_hdlr:"
82237c478bd9Sstevel@tonic-gate 		    " ibt_modify_qp() returned = %d", status);
82247c478bd9Sstevel@tonic-gate 		return;
82257c478bd9Sstevel@tonic-gate 	}
82267c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*apr_msg))
82277c478bd9Sstevel@tonic-gate }
82287c478bd9Sstevel@tonic-gate 
82297c478bd9Sstevel@tonic-gate 
82307c478bd9Sstevel@tonic-gate /*
82317c478bd9Sstevel@tonic-gate  * ibcm_post_apr_mad:
82327c478bd9Sstevel@tonic-gate  *	Posts a APR MAD and starts timer
82337c478bd9Sstevel@tonic-gate  *
82347c478bd9Sstevel@tonic-gate  * INPUTS:
82357c478bd9Sstevel@tonic-gate  *	statep		- state pointer
82367c478bd9Sstevel@tonic-gate  *
82377c478bd9Sstevel@tonic-gate  * RETURN VALUE: NONE
82387c478bd9Sstevel@tonic-gate  */
82397c478bd9Sstevel@tonic-gate void
ibcm_post_apr_mad(ibcm_state_data_t * statep)82407c478bd9Sstevel@tonic-gate ibcm_post_apr_mad(ibcm_state_data_t *statep)
82417c478bd9Sstevel@tonic-gate {
82427c478bd9Sstevel@tonic-gate 	ibcm_apr_msg_t	*apr_msgp;
82437c478bd9Sstevel@tonic-gate 
82447c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*apr_msgp))
82457c478bd9Sstevel@tonic-gate 
82467c478bd9Sstevel@tonic-gate 	apr_msgp = (ibcm_apr_msg_t *)IBCM_OUT_MSGP(statep->lapr_msg);
82477c478bd9Sstevel@tonic-gate 
82487c478bd9Sstevel@tonic-gate 	apr_msgp->apr_local_comm_id = h2b32(statep->local_comid);
82497c478bd9Sstevel@tonic-gate 	apr_msgp->apr_remote_comm_id = h2b32(statep->remote_comid);
82507c478bd9Sstevel@tonic-gate 	IBCM_OUT_HDRP(statep->lapr_msg)->AttributeID =
82517c478bd9Sstevel@tonic-gate 	    h2b16(IBCM_INCOMING_APR + IBCM_ATTR_BASE_ID);
82527c478bd9Sstevel@tonic-gate 
82537c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*apr_msgp))
82547c478bd9Sstevel@tonic-gate 
82557c478bd9Sstevel@tonic-gate 	ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_APR);
82567c478bd9Sstevel@tonic-gate 
82577c478bd9Sstevel@tonic-gate 	ibcm_post_rc_mad(statep, statep->lapr_msg, ibcm_post_apr_complete,
82587c478bd9Sstevel@tonic-gate 	    statep);
82597c478bd9Sstevel@tonic-gate }
82607c478bd9Sstevel@tonic-gate 
82617c478bd9Sstevel@tonic-gate /*
82627c478bd9Sstevel@tonic-gate  * ibcm_process_apr_msg:
82637c478bd9Sstevel@tonic-gate  *	This call processes an incoming APR message
82647c478bd9Sstevel@tonic-gate  *
82657c478bd9Sstevel@tonic-gate  * INPUTS:
82667c478bd9Sstevel@tonic-gate  *	hcap		- HCA entry pointer
82677c478bd9Sstevel@tonic-gate  *	input_madp	- incoming CM SIDR REP MAD
82687c478bd9Sstevel@tonic-gate  *	cm_mad_addr	- Address information for the MAD to be posted
82697c478bd9Sstevel@tonic-gate  *
82707c478bd9Sstevel@tonic-gate  * RETURN VALUE: NONE
82717c478bd9Sstevel@tonic-gate  */
82727c478bd9Sstevel@tonic-gate /*ARGSUSED*/
82737c478bd9Sstevel@tonic-gate void
ibcm_process_apr_msg(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)82747c478bd9Sstevel@tonic-gate ibcm_process_apr_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
82757c478bd9Sstevel@tonic-gate     ibcm_mad_addr_t *cm_mad_addr)
82767c478bd9Sstevel@tonic-gate {
82777c478bd9Sstevel@tonic-gate 	ibcm_status_t		state_lookup_status;
82787c478bd9Sstevel@tonic-gate 	ibcm_apr_msg_t		*apr_msg = (ibcm_apr_msg_t *)
8279015f8fffShiremath 	    (&input_madp[IBCM_MAD_HDR_SIZE]);
82807c478bd9Sstevel@tonic-gate 	ibcm_state_data_t	*statep = NULL;
82817c478bd9Sstevel@tonic-gate 
82827c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_apr_msg:");
82837c478bd9Sstevel@tonic-gate 
82847c478bd9Sstevel@tonic-gate 	rw_enter(&hcap->hca_state_rwlock, RW_READER);
82857c478bd9Sstevel@tonic-gate 	state_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_APR,
82867c478bd9Sstevel@tonic-gate 	    b2h32(apr_msg->apr_remote_comm_id), 0, 0, hcap, &statep);
82877c478bd9Sstevel@tonic-gate 	rw_exit(&hcap->hca_state_rwlock);
82887c478bd9Sstevel@tonic-gate 
82897c478bd9Sstevel@tonic-gate 	if (state_lookup_status != IBCM_LOOKUP_EXISTS) {
82907c478bd9Sstevel@tonic-gate 		return;
82917c478bd9Sstevel@tonic-gate 	}
82927c478bd9Sstevel@tonic-gate 
82937c478bd9Sstevel@tonic-gate 	/* if transaction id is not as expected, drop the APR mad */
82947c478bd9Sstevel@tonic-gate 	if (IBCM_OUT_HDRP(statep->lapr_msg)->TransactionID !=
82957c478bd9Sstevel@tonic-gate 	    ((ib_mad_hdr_t *)(input_madp))->TransactionID) {
82967c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
82977c478bd9Sstevel@tonic-gate 		IBCM_REF_CNT_DECR(statep);
82987c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
82997c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L3(cmlog, "ibcm_process_apr_msg: statep 0x%p"
83007c478bd9Sstevel@tonic-gate 		    ": rcv'd APR MAD with comid 0x%x",
83017c478bd9Sstevel@tonic-gate 		    statep, b2h32(apr_msg->apr_remote_comm_id));
83027c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L3(cmlog, "ibcm_process_apr_msg: "
83037c478bd9Sstevel@tonic-gate 		    "tid expected 0x%llX tid found 0x%llX",
83047c478bd9Sstevel@tonic-gate 		    b2h64(IBCM_OUT_HDRP(statep->lapr_msg)->TransactionID),
83057c478bd9Sstevel@tonic-gate 		    b2h64(((ib_mad_hdr_t *)(input_madp))->TransactionID));
83067c478bd9Sstevel@tonic-gate 		return;
83077c478bd9Sstevel@tonic-gate 	}
83087c478bd9Sstevel@tonic-gate 
83097c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_process_apr_msg: statep 0x%p "
83107c478bd9Sstevel@tonic-gate 	    "lookup status %x", statep, state_lookup_status);
83117c478bd9Sstevel@tonic-gate 
83127c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
83137c478bd9Sstevel@tonic-gate 
83147c478bd9Sstevel@tonic-gate 	if (!((statep->state == IBCM_STATE_ESTABLISHED) &&
83157c478bd9Sstevel@tonic-gate 	    ((statep->ap_state == IBCM_AP_STATE_LAP_SENT) ||
83167c478bd9Sstevel@tonic-gate 	    (statep->ap_state == IBCM_AP_STATE_MRA_LAP_RCVD)))) {
83177c478bd9Sstevel@tonic-gate 		IBCM_REF_CNT_DECR(statep); /* decrement the ref count */
83187c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
83197c478bd9Sstevel@tonic-gate 		return;
83207c478bd9Sstevel@tonic-gate 	}
83217c478bd9Sstevel@tonic-gate 
83227c478bd9Sstevel@tonic-gate 	statep->ap_state = IBCM_AP_STATE_APR_RCVD;
83237c478bd9Sstevel@tonic-gate 
83247c478bd9Sstevel@tonic-gate 	/* cancel the LAP timer */
83257c478bd9Sstevel@tonic-gate 	if (statep->timerid != 0) {
83267c478bd9Sstevel@tonic-gate 		timeout_id_t timer_val;
83277c478bd9Sstevel@tonic-gate 		timer_val = statep->timerid;
83287c478bd9Sstevel@tonic-gate 		statep->timerid = 0;
83297c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
83307c478bd9Sstevel@tonic-gate 		(void) untimeout(timer_val);
83317c478bd9Sstevel@tonic-gate 	} else {
83327c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
83337c478bd9Sstevel@tonic-gate 	}
83347c478bd9Sstevel@tonic-gate 
83357c478bd9Sstevel@tonic-gate 	ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_APR);
83367c478bd9Sstevel@tonic-gate 
83377c478bd9Sstevel@tonic-gate 	ibcm_cep_state_apr(statep,
83387c478bd9Sstevel@tonic-gate 	    (ibcm_lap_msg_t *)IBCM_OUT_MSGP(statep->lapr_msg), apr_msg);
83397c478bd9Sstevel@tonic-gate 
83407c478bd9Sstevel@tonic-gate 	mutex_enter(&statep->state_mutex);
83417c478bd9Sstevel@tonic-gate 	statep->ap_state = IBCM_AP_STATE_IDLE;
83427c478bd9Sstevel@tonic-gate 
83437c478bd9Sstevel@tonic-gate 	/* unblock any DREQ threads and close channels */
83447c478bd9Sstevel@tonic-gate 	cv_broadcast(&statep->block_mad_cv);
83457c478bd9Sstevel@tonic-gate 
83467c478bd9Sstevel@tonic-gate 	statep->ap_done = B_TRUE;
83477c478bd9Sstevel@tonic-gate 
83487c478bd9Sstevel@tonic-gate 	/* wake up blocking ibt_set_alt_path */
83497c478bd9Sstevel@tonic-gate 	cv_broadcast(&statep->block_client_cv);
83507c478bd9Sstevel@tonic-gate 
83517c478bd9Sstevel@tonic-gate 	IBCM_REF_CNT_DECR(statep); /* decrement the ref count */
83527c478bd9Sstevel@tonic-gate 	mutex_exit(&statep->state_mutex);
83537c478bd9Sstevel@tonic-gate }
83547c478bd9Sstevel@tonic-gate 
83557c478bd9Sstevel@tonic-gate static void
ibcm_set_apr_arej(int ap_status,ibcm_apr_msg_t * apr_msgp,ibt_arej_info_t * ari,boolean_t * ari_valid)83567c478bd9Sstevel@tonic-gate ibcm_set_apr_arej(int ap_status, ibcm_apr_msg_t *apr_msgp,
83577c478bd9Sstevel@tonic-gate     ibt_arej_info_t *ari, boolean_t *ari_valid)
83587c478bd9Sstevel@tonic-gate {
83595c42ea03Shiremath 	uint8_t ari_len = apr_msgp->apr_addl_info_len;
83607c478bd9Sstevel@tonic-gate 	ibcm_classportinfo_msg_t tclp;
83617c478bd9Sstevel@tonic-gate 
83627c478bd9Sstevel@tonic-gate 	*ari_valid = B_FALSE;
83637c478bd9Sstevel@tonic-gate 
8364fde3102fShiremath 	IBTF_DPRINTF_L3(cmlog, "ibcm_set_apr_arej: apr_status = %d "
8365fde3102fShiremath 	    "ari_len = %d", ap_status, ari_len);
8366fde3102fShiremath 
83677c478bd9Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ari))
83687c478bd9Sstevel@tonic-gate 
83697c478bd9Sstevel@tonic-gate 	switch (ap_status) {
83707c478bd9Sstevel@tonic-gate 	case IBT_CM_AP_REDIRECT:
83717c478bd9Sstevel@tonic-gate 		if (ari_len < sizeof (ibcm_classportinfo_msg_t))
83727c478bd9Sstevel@tonic-gate 			break;
83737c478bd9Sstevel@tonic-gate 		*ari_valid = B_TRUE;
83747c478bd9Sstevel@tonic-gate 		bcopy(apr_msgp->apr_addl_info, &tclp, sizeof (tclp));
83757c478bd9Sstevel@tonic-gate 		ibcm_init_clp_from_mad(&tclp, &ari->ari_redirect);
83767c478bd9Sstevel@tonic-gate 		break;
83777c478bd9Sstevel@tonic-gate 	case IBT_CM_AP_RLID_REJECTED:
83787c478bd9Sstevel@tonic-gate 		if (ari_len < sizeof (ib_lid_t))
83797c478bd9Sstevel@tonic-gate 			break;
83807c478bd9Sstevel@tonic-gate 		*ari_valid = B_TRUE;
83817c478bd9Sstevel@tonic-gate 		bcopy(apr_msgp->apr_addl_info, &ari->ari_lid,
83827c478bd9Sstevel@tonic-gate 		    sizeof (ib_lid_t));
83837c478bd9Sstevel@tonic-gate 		ari->ari_lid = b2h16(ari->ari_lid);
83847c478bd9Sstevel@tonic-gate 		break;
83857c478bd9Sstevel@tonic-gate 	case IBT_CM_AP_RGID_REJECTED:
83867c478bd9Sstevel@tonic-gate 		if (ari_len < sizeof (ib_gid_t))
83877c478bd9Sstevel@tonic-gate 			break;
83887c478bd9Sstevel@tonic-gate 		*ari_valid = B_TRUE;
83897c478bd9Sstevel@tonic-gate 		bcopy(apr_msgp->apr_addl_info, &ari->ari_gid,
83907c478bd9Sstevel@tonic-gate 		    sizeof (ib_gid_t));
83917c478bd9Sstevel@tonic-gate 		ari->ari_gid.gid_guid = b2h64(ari->ari_gid.gid_guid);
83927c478bd9Sstevel@tonic-gate 		ari->ari_gid.gid_prefix = b2h64(ari->ari_gid.gid_prefix);
8393fde3102fShiremath 
8394fde3102fShiremath 		IBTF_DPRINTF_L4(cmlog, "ibcm_set_apr_arej: ari_gid= %llX:%llX",
8395fde3102fShiremath 		    ari->ari_gid.gid_prefix, ari->ari_gid.gid_guid);
83967c478bd9Sstevel@tonic-gate 		break;
83977c478bd9Sstevel@tonic-gate 	case IBT_CM_AP_FLOW_REJECTED:
83987c478bd9Sstevel@tonic-gate 		if (ari_len < 3)	/* 3 bytes needed for 20 bits */
83997c478bd9Sstevel@tonic-gate 			break;
84007c478bd9Sstevel@tonic-gate 		*ari_valid = B_TRUE;
84017c478bd9Sstevel@tonic-gate 		/* take the first 20 bits */
84027c478bd9Sstevel@tonic-gate 		ari->ari_flow =
84037c478bd9Sstevel@tonic-gate 		    b2h32(*(uint32_t *)&apr_msgp->apr_addl_info) >> 12;
84047c478bd9Sstevel@tonic-gate 		break;
84057c478bd9Sstevel@tonic-gate 	case IBT_CM_AP_TCLASS_REJECTED:
84067c478bd9Sstevel@tonic-gate 		if (ari_len < 1)
84077c478bd9Sstevel@tonic-gate 			break;
84087c478bd9Sstevel@tonic-gate 		*ari_valid = B_TRUE;
84097c478bd9Sstevel@tonic-gate 		/* take the first byte */
84107c478bd9Sstevel@tonic-gate 		ari->ari_tclass = apr_msgp->apr_addl_info[0];
84117c478bd9Sstevel@tonic-gate 		break;
84127c478bd9Sstevel@tonic-gate 	case IBT_CM_AP_HOP_REJECTED:
84137c478bd9Sstevel@tonic-gate 		if (ari_len < 1)
84147c478bd9Sstevel@tonic-gate 			break;
84157c478bd9Sstevel@tonic-gate 		*ari_valid = B_TRUE;
84167c478bd9Sstevel@tonic-gate 		/* take the first byte */
84177c478bd9Sstevel@tonic-gate 		ari->ari_hop = apr_msgp->apr_addl_info[0];
84187c478bd9Sstevel@tonic-gate 		break;
84197c478bd9Sstevel@tonic-gate 	case IBT_CM_AP_RATE_REJECTED:
84207c478bd9Sstevel@tonic-gate 		if (ari_len < 1)
84217c478bd9Sstevel@tonic-gate 			break;
84227c478bd9Sstevel@tonic-gate 		*ari_valid = B_TRUE;
84237c478bd9Sstevel@tonic-gate 		/* take the first 6 bits */
84247c478bd9Sstevel@tonic-gate 		ari->ari_rate = apr_msgp->apr_addl_info[0] >> 2;
84257c478bd9Sstevel@tonic-gate 		break;
84267c478bd9Sstevel@tonic-gate 	case IBT_CM_AP_SL_REJECTED:
84277c478bd9Sstevel@tonic-gate 		if (ari_len < 1)
84287c478bd9Sstevel@tonic-gate 			break;
84297c478bd9Sstevel@tonic-gate 		*ari_valid = B_TRUE;
84307c478bd9Sstevel@tonic-gate 		/* take the first 4 bits */
84317c478bd9Sstevel@tonic-gate 		ari->ari_sl = apr_msgp->apr_addl_info[0] >> 4;
84327c478bd9Sstevel@tonic-gate 		break;
84337c478bd9Sstevel@tonic-gate 	default:
84347c478bd9Sstevel@tonic-gate 		break;
84357c478bd9Sstevel@tonic-gate 	}
84367c478bd9Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*ari))
84377c478bd9Sstevel@tonic-gate }
84387c478bd9Sstevel@tonic-gate 
84397c478bd9Sstevel@tonic-gate /*
84407c478bd9Sstevel@tonic-gate  * ibcm_cep_state_apr:
84417c478bd9Sstevel@tonic-gate  *	This call processes an incoming APR message
84427c478bd9Sstevel@tonic-gate  *
84437c478bd9Sstevel@tonic-gate  * INPUTS:
84447c478bd9Sstevel@tonic-gate  *	statep		- pointer to ibcm_state_data_t
84457c478bd9Sstevel@tonic-gate  *	lap_msg		- lap msg sent earlier
84467c478bd9Sstevel@tonic-gate  *	apr_msg		- apr msg received
84477c478bd9Sstevel@tonic-gate  *
84487c478bd9Sstevel@tonic-gate  * RETURN VALUE: NONE
84497c478bd9Sstevel@tonic-gate  */
84507c478bd9Sstevel@tonic-gate void
ibcm_cep_state_apr(ibcm_state_data_t * statep,ibcm_lap_msg_t * lap_msg,ibcm_apr_msg_t * apr_msg)84517c478bd9Sstevel@tonic-gate ibcm_cep_state_apr(ibcm_state_data_t *statep, ibcm_lap_msg_t *lap_msg,
84527c478bd9Sstevel@tonic-gate     ibcm_apr_msg_t *apr_msg)
84537c478bd9Sstevel@tonic-gate {
84547c478bd9Sstevel@tonic-gate 	ibt_cm_event_t		event;
84557c478bd9Sstevel@tonic-gate 	ibcm_status_t		status = IBCM_SUCCESS;
84567c478bd9Sstevel@tonic-gate 	uint8_t			ap_status = apr_msg->apr_ap_status;
84577c478bd9Sstevel@tonic-gate 
84587c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(cmlog, "ibcm_cep_state_apr: statep 0x%p, ap_status %d",
84597c478bd9Sstevel@tonic-gate 	    statep, ap_status);
84607c478bd9Sstevel@tonic-gate 
84617c478bd9Sstevel@tonic-gate 	if (ap_status == IBT_CM_AP_LOADED)
84627c478bd9Sstevel@tonic-gate 		status = ibcm_set_qp_from_apr(statep, lap_msg);
84637c478bd9Sstevel@tonic-gate 
84647c478bd9Sstevel@tonic-gate 	if (statep->ap_return_data != NULL) {	/* blocking call */
84657c478bd9Sstevel@tonic-gate 
84667c478bd9Sstevel@tonic-gate 		/* copy the private data */
84677c478bd9Sstevel@tonic-gate 		if ((statep->ap_return_data->ap_priv_data != NULL) &&
84687c478bd9Sstevel@tonic-gate 		    (statep->ap_return_data->ap_priv_data_len > 0))
84697c478bd9Sstevel@tonic-gate 			bcopy(apr_msg->apr_private_data,
84707c478bd9Sstevel@tonic-gate 			    statep->ap_return_data->ap_priv_data,
84717c478bd9Sstevel@tonic-gate 			    statep->ap_return_data->ap_priv_data_len);
84727c478bd9Sstevel@tonic-gate 
84737c478bd9Sstevel@tonic-gate 		/* initialize the ap status */
84747c478bd9Sstevel@tonic-gate 		if (status == IBCM_FAILURE) {
84757c478bd9Sstevel@tonic-gate 			statep->ap_return_data->ap_status = IBT_CM_AP_REJECT;
84767c478bd9Sstevel@tonic-gate 			statep->ap_return_data->ap_arej_info_valid = B_FALSE;
84777c478bd9Sstevel@tonic-gate 		} else {
84787c478bd9Sstevel@tonic-gate 			statep->ap_return_data->ap_status = ap_status;
84797c478bd9Sstevel@tonic-gate 			ibcm_set_apr_arej(ap_status, apr_msg,
84807c478bd9Sstevel@tonic-gate 			    &statep->ap_return_data->ap_arej_info,
84817c478bd9Sstevel@tonic-gate 			    &statep->ap_return_data->ap_arej_info_valid);
84827c478bd9Sstevel@tonic-gate 		}
84837c478bd9Sstevel@tonic-gate 
84847c478bd9Sstevel@tonic-gate 		/* do a cv signal for a blocking ibt_set_alt_path */
84857c478bd9Sstevel@tonic-gate 		mutex_enter(&statep->state_mutex);
84867c478bd9Sstevel@tonic-gate 		statep->ap_done = B_TRUE;
84877c478bd9Sstevel@tonic-gate 		cv_broadcast(&statep->block_client_cv);
84887c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
84897c478bd9Sstevel@tonic-gate 
84907c478bd9Sstevel@tonic-gate 	} else {	/* Non blocking call */
84917c478bd9Sstevel@tonic-gate 		/* Fill up the event */
84927c478bd9Sstevel@tonic-gate 
84937c478bd9Sstevel@tonic-gate 		bzero(&event, sizeof (event));
84947c478bd9Sstevel@tonic-gate 		event.cm_type = IBT_CM_EVENT_APR_RCV;
84957c478bd9Sstevel@tonic-gate 		event.cm_channel = statep->channel;
84967c478bd9Sstevel@tonic-gate 		event.cm_session_id = NULL;
84977c478bd9Sstevel@tonic-gate 		event.cm_priv_data = apr_msg->apr_private_data;
84987c478bd9Sstevel@tonic-gate 		event.cm_priv_data_len =  IBT_APR_PRIV_DATA_SZ;
84997c478bd9Sstevel@tonic-gate 		if (status == IBCM_FAILURE) {
85007c478bd9Sstevel@tonic-gate 			event.cm_event.apr.apr_status = IBT_CM_AP_REJECT;
85017c478bd9Sstevel@tonic-gate 			event.cm_event.apr.apr_arej_info_valid = B_FALSE;
85027c478bd9Sstevel@tonic-gate 		} else {
85037c478bd9Sstevel@tonic-gate 			event.cm_event.apr.apr_status = ap_status;
85047c478bd9Sstevel@tonic-gate 			ibcm_set_apr_arej(ap_status, apr_msg,
85057c478bd9Sstevel@tonic-gate 			    &event.cm_event.apr.apr_arej_info,
85067c478bd9Sstevel@tonic-gate 			    &event.cm_event.apr.apr_arej_info_valid);
85077c478bd9Sstevel@tonic-gate 		}
85087c478bd9Sstevel@tonic-gate 
85097c478bd9Sstevel@tonic-gate 		/* initialize the ap status */
85107c478bd9Sstevel@tonic-gate 		statep->cm_handler(statep->state_cm_private, &event,
85117c478bd9Sstevel@tonic-gate 		    NULL, apr_msg->apr_private_data, IBT_APR_PRIV_DATA_SZ);
85127c478bd9Sstevel@tonic-gate 	}
85139d3d2ed0Shiremath 	mutex_enter(&statep->state_mutex);
85149d3d2ed0Shiremath 	ibcm_open_done(statep);
85159d3d2ed0Shiremath 	mutex_exit(&statep->state_mutex);
85167c478bd9Sstevel@tonic-gate }
85177c478bd9Sstevel@tonic-gate 
85187c478bd9Sstevel@tonic-gate /*
85197c478bd9Sstevel@tonic-gate  * ibcm_set_qp_from_apr:
85207c478bd9Sstevel@tonic-gate  *	This call sets QP's alt path info based on APR message contents
85217c478bd9Sstevel@tonic-gate  *
85227c478bd9Sstevel@tonic-gate  * INPUTS:
85237c478bd9Sstevel@tonic-gate  *	statep		- pointer to ibcm_state_data_t
85247c478bd9Sstevel@tonic-gate  *	lap_msg		- lap msg sent earlier
85257c478bd9Sstevel@tonic-gate  *
85267c478bd9Sstevel@tonic-gate  * RETURN VALUE: ibcm_status_t
85277c478bd9Sstevel@tonic-gate  */
85287c478bd9Sstevel@tonic-gate static ibcm_status_t
ibcm_set_qp_from_apr(ibcm_state_data_t * statep,ibcm_lap_msg_t * lap_msg)85297c478bd9Sstevel@tonic-gate ibcm_set_qp_from_apr(ibcm_state_data_t *statep, ibcm_lap_msg_t *lap_msg)
85307c478bd9Sstevel@tonic-gate {
85317c478bd9Sstevel@tonic-gate 	ibtl_cm_hca_port_t	port;
85327c478bd9Sstevel@tonic-gate 	ibt_adds_vect_t		*adds;
85337c478bd9Sstevel@tonic-gate 
85347c478bd9Sstevel@tonic-gate 	ibt_qp_query_attr_t	qp_attrs;
85357c478bd9Sstevel@tonic-gate 	ibt_cep_modify_flags_t	cep_flags;
85367c478bd9Sstevel@tonic-gate 	ibt_status_t		status;
85377c478bd9Sstevel@tonic-gate 
85387c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(cmlog, "ibcm_set_qp_from_apr: statep 0x%p", statep);
85397c478bd9Sstevel@tonic-gate 
85407c478bd9Sstevel@tonic-gate 	status = ibt_query_qp(statep->channel, &qp_attrs);
85417c478bd9Sstevel@tonic-gate 	if (status != IBT_SUCCESS ||
85427c478bd9Sstevel@tonic-gate 	    (qp_attrs.qp_info.qp_state != IBT_STATE_RTS &&
85437c478bd9Sstevel@tonic-gate 	    qp_attrs.qp_info.qp_state != IBT_STATE_SQD)) {
85447c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_set_qp_from_apr: ibt_query_qp "
85457c478bd9Sstevel@tonic-gate 		    "failed, status = %d, qp_state = %d", statep, status,
85467c478bd9Sstevel@tonic-gate 		    qp_attrs.qp_info.qp_state);
85477c478bd9Sstevel@tonic-gate 		return (IBCM_FAILURE);
85487c478bd9Sstevel@tonic-gate 	}
85497c478bd9Sstevel@tonic-gate 
85507c478bd9Sstevel@tonic-gate 	/* Fill up input args for ibt_modify_qp */
85517c478bd9Sstevel@tonic-gate 	cep_flags = IBT_CEP_SET_ALT_PATH | IBT_CEP_SET_STATE;
85527c478bd9Sstevel@tonic-gate 
85537c478bd9Sstevel@tonic-gate 	/* do RTS=>RTS or SQD=>SQD.  The next line is needed for RTS=>RTS. */
85547c478bd9Sstevel@tonic-gate 	qp_attrs.qp_info.qp_current_state = qp_attrs.qp_info.qp_state;
85557c478bd9Sstevel@tonic-gate 
85567c478bd9Sstevel@tonic-gate 	/* Fill up input args for ibt_modify_qp */
85577c478bd9Sstevel@tonic-gate 	adds = &IBCM_QP_RC(qp_attrs).rc_alt_path.cep_adds_vect;
85587c478bd9Sstevel@tonic-gate 
85597c478bd9Sstevel@tonic-gate 	ibcm_fill_adds_from_lap(adds, lap_msg, IBCM_ACTIVE_MODE);
85607c478bd9Sstevel@tonic-gate 
85617c478bd9Sstevel@tonic-gate 	if ((status = ibtl_cm_get_hca_port(adds->av_sgid,
85627c478bd9Sstevel@tonic-gate 	    statep->local_hca_guid, &port)) != IBT_SUCCESS) {
85637c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_set_qp_from_apr: "
85647c478bd9Sstevel@tonic-gate 		    "ibtl_cm_get_hca_port failed status = %d", status);
85657c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L5(cmlog, "ibcm_set_qp_from_apr:"
85667c478bd9Sstevel@tonic-gate 		    " ibtl_cm_get_hca_port sgid guid %llX",
85677c478bd9Sstevel@tonic-gate 		    adds->av_sgid.gid_guid);
85687c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L5(cmlog, "ibcm_set_qp_from_apr:"
85697c478bd9Sstevel@tonic-gate 		    " ibtl_cm_get_hca_port sgid prefix %llX ",
85707c478bd9Sstevel@tonic-gate 		    adds->av_sgid.gid_prefix);
85717c478bd9Sstevel@tonic-gate 		return (IBCM_FAILURE);
85727c478bd9Sstevel@tonic-gate 	}
85737c478bd9Sstevel@tonic-gate 
85747c478bd9Sstevel@tonic-gate 	IBCM_QP_RC(qp_attrs).rc_alt_path.cep_hca_port_num =
85757c478bd9Sstevel@tonic-gate 	    port.hp_port;
85767c478bd9Sstevel@tonic-gate 
85777c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "ibcm_set_qp_from_apr: "
85787c478bd9Sstevel@tonic-gate 	    "gid = %llx:%llx, port_num = %d",
85797c478bd9Sstevel@tonic-gate 	    IBCM_QP_RC(qp_attrs).rc_alt_path.cep_adds_vect.av_sgid.
85807c478bd9Sstevel@tonic-gate 	    gid_prefix,
85817c478bd9Sstevel@tonic-gate 	    IBCM_QP_RC(qp_attrs).rc_alt_path.cep_adds_vect.av_sgid.gid_guid,
85827c478bd9Sstevel@tonic-gate 	    port.hp_port);
85837c478bd9Sstevel@tonic-gate 
85847c478bd9Sstevel@tonic-gate 	/* The pkey is same as the primary path */
85857c478bd9Sstevel@tonic-gate 	status = ibt_pkey2index_byguid(statep->local_hca_guid,
85867c478bd9Sstevel@tonic-gate 	    port.hp_port, statep->pkey,
85877c478bd9Sstevel@tonic-gate 	    &IBCM_QP_RC(qp_attrs).rc_alt_path.cep_pkey_ix);
85887c478bd9Sstevel@tonic-gate 
85897c478bd9Sstevel@tonic-gate 	if (status != IBT_SUCCESS) {
85907c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_set_qp_from_apr: "
85917c478bd9Sstevel@tonic-gate 		    "ibt_pkey2index_byguid failed %d", status);
85927c478bd9Sstevel@tonic-gate 		return (IBCM_FAILURE);
85937c478bd9Sstevel@tonic-gate 	}
85947c478bd9Sstevel@tonic-gate 	qp_attrs.qp_info.qp_trans = IBT_RC_SRV;
85957c478bd9Sstevel@tonic-gate 	IBCM_QP_RC(qp_attrs).rc_alt_path.cep_timeout =
85967c478bd9Sstevel@tonic-gate 	    ibt_usec2ib(statep->remote_ack_delay +
85977c478bd9Sstevel@tonic-gate 	    2 * statep->rc_alt_pkt_lt);
85987c478bd9Sstevel@tonic-gate 	if (IBCM_QP_RC(qp_attrs).rc_mig_state == IBT_STATE_MIGRATED) {
85997c478bd9Sstevel@tonic-gate 		/* Need to rearm */
86007c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L3(cmlog, "ibcm_set_qp_from_apr: statep 0x%p: "
86017c478bd9Sstevel@tonic-gate 		    "rearming APM", statep);
86027c478bd9Sstevel@tonic-gate 		cep_flags |= IBT_CEP_SET_MIG;
86037c478bd9Sstevel@tonic-gate 		IBCM_QP_RC(qp_attrs).rc_mig_state = IBT_STATE_REARMED;
86047c478bd9Sstevel@tonic-gate 	}
86057c478bd9Sstevel@tonic-gate 
86067c478bd9Sstevel@tonic-gate 	status = ibt_modify_qp(statep->channel, cep_flags, &qp_attrs.qp_info,
86077c478bd9Sstevel@tonic-gate 	    NULL);
86087c478bd9Sstevel@tonic-gate 
86097c478bd9Sstevel@tonic-gate 	if (status != IBT_SUCCESS)
86107c478bd9Sstevel@tonic-gate 		ibcm_insert_trace(statep, IBCM_TRACE_SET_ALT_FAIL);
86117c478bd9Sstevel@tonic-gate 	else
86127c478bd9Sstevel@tonic-gate 		ibcm_insert_trace(statep, IBCM_TRACE_SET_ALT);
86137c478bd9Sstevel@tonic-gate 
86147c478bd9Sstevel@tonic-gate #ifdef	DEBUG
86157c478bd9Sstevel@tonic-gate 	(void) ibt_query_qp(statep->channel, &qp_attrs);
86167c478bd9Sstevel@tonic-gate 	print_modify_qp("ACTIVE LAP QUERY", statep->channel,
86177c478bd9Sstevel@tonic-gate 	    cep_flags, &qp_attrs.qp_info);
86187c478bd9Sstevel@tonic-gate #endif
86197c478bd9Sstevel@tonic-gate 
86207c478bd9Sstevel@tonic-gate 	if (status != IBT_SUCCESS) {
86217c478bd9Sstevel@tonic-gate 		IBTF_DPRINTF_L2(cmlog, "ibcm_set_qp_from_apr:"
86227c478bd9Sstevel@tonic-gate 		    " ibt_modify_qp() failed, status = %d", status);
86237c478bd9Sstevel@tonic-gate 		return (IBCM_FAILURE);
86247c478bd9Sstevel@tonic-gate 	}
86257c478bd9Sstevel@tonic-gate 
86267c478bd9Sstevel@tonic-gate 	return (IBCM_SUCCESS);
86277c478bd9Sstevel@tonic-gate }
86287c478bd9Sstevel@tonic-gate 
86297c478bd9Sstevel@tonic-gate /*
86307c478bd9Sstevel@tonic-gate  * ibcm_sync_lapr_idle:
86317c478bd9Sstevel@tonic-gate  *
86327c478bd9Sstevel@tonic-gate  *	This call either cancels a LAP/APR operation or waits
86337c478bd9Sstevel@tonic-gate  *	until the operation is complete
86347c478bd9Sstevel@tonic-gate  *
86357c478bd9Sstevel@tonic-gate  * INPUTS:
86367c478bd9Sstevel@tonic-gate  *	statep	Pointer to ibcm_state_data_t
86377c478bd9Sstevel@tonic-gate  *
86387c478bd9Sstevel@tonic-gate  * RETURN VALUE: NONE
86397c478bd9Sstevel@tonic-gate  *
86407c478bd9Sstevel@tonic-gate  * This function is called holding state mutex
86417c478bd9Sstevel@tonic-gate  * This function returns, releasing the state mutex
86427c478bd9Sstevel@tonic-gate  */
86437c478bd9Sstevel@tonic-gate void
ibcm_sync_lapr_idle(ibcm_state_data_t * statep)86447c478bd9Sstevel@tonic-gate ibcm_sync_lapr_idle(ibcm_state_data_t *statep)
86457c478bd9Sstevel@tonic-gate {
86467c478bd9Sstevel@tonic-gate 	timeout_id_t	timer_val = statep->timerid;
86477c478bd9Sstevel@tonic-gate 	ibt_cm_event_t	event;
86487c478bd9Sstevel@tonic-gate 
86497c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L3(cmlog, "ibcm_sync_lapr_idle:"
86507c478bd9Sstevel@tonic-gate 	    "statep %p state %d ap_state %d", statep, statep->state,
86517c478bd9Sstevel@tonic-gate 	    statep->ap_state);
86527c478bd9Sstevel@tonic-gate 
86537c478bd9Sstevel@tonic-gate 	ASSERT(MUTEX_HELD(&statep->state_mutex));
86547c478bd9Sstevel@tonic-gate 	_NOTE(LOCK_RELEASED_AS_SIDE_EFFECT(&statep->state_mutex))
86557c478bd9Sstevel@tonic-gate 
86567c478bd9Sstevel@tonic-gate 	/* Busy AP states on active/passive sides */
86577c478bd9Sstevel@tonic-gate 	if ((statep->ap_state == IBCM_AP_STATE_LAP_RCVD) ||
86587c478bd9Sstevel@tonic-gate 	    (statep->ap_state == IBCM_AP_STATE_APR_RCVD) ||
86597c478bd9Sstevel@tonic-gate 	    (statep->ap_state == IBCM_AP_STATE_MRA_LAP_SENT) ||
86607c478bd9Sstevel@tonic-gate 	    (statep->ap_state == IBCM_AP_STATE_TIMED_OUT)) {
86617c478bd9Sstevel@tonic-gate 
86627c478bd9Sstevel@tonic-gate 		/* wait till ap_state becomes IBCM_AP_STATE_IDLE */
86637c478bd9Sstevel@tonic-gate 		while (statep->ap_state != IBCM_AP_STATE_IDLE)
86647c478bd9Sstevel@tonic-gate 			cv_wait(&statep->block_mad_cv, &statep->state_mutex);
86657c478bd9Sstevel@tonic-gate 
86667c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
86677c478bd9Sstevel@tonic-gate 
86687c478bd9Sstevel@tonic-gate 	} else if ((statep->ap_state == IBCM_AP_STATE_LAP_SENT) ||
86697c478bd9Sstevel@tonic-gate 	    (statep->ap_state == IBCM_AP_STATE_MRA_LAP_RCVD)) {
86707c478bd9Sstevel@tonic-gate 
86717c478bd9Sstevel@tonic-gate 		/* fail the client's ibt_set_alt_path */
86727c478bd9Sstevel@tonic-gate 
86737c478bd9Sstevel@tonic-gate 		/* blocking ibt_set_alt_path */
86747c478bd9Sstevel@tonic-gate 		if (statep->ap_return_data != NULL) {
86757c478bd9Sstevel@tonic-gate 			statep->ap_return_data->ap_status =
86767c478bd9Sstevel@tonic-gate 			    IBT_CM_AP_ABORT;
86777c478bd9Sstevel@tonic-gate 			statep->ap_state = IBCM_AP_STATE_IDLE;
86787c478bd9Sstevel@tonic-gate 			cv_broadcast(&statep->block_client_cv);
86797c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L3(cmlog, "ibcm_sync_lapr_idle:"
86807c478bd9Sstevel@tonic-gate 			    "blocked wait");
86817c478bd9Sstevel@tonic-gate 		}
86827c478bd9Sstevel@tonic-gate 
86837c478bd9Sstevel@tonic-gate 		statep->timerid = 0;
86847c478bd9Sstevel@tonic-gate 		/* Cancel the timeout */
86857c478bd9Sstevel@tonic-gate 		mutex_exit(&statep->state_mutex);
86867c478bd9Sstevel@tonic-gate 		if (timer_val != 0)
86877c478bd9Sstevel@tonic-gate 			(void) untimeout(timer_val);
86887c478bd9Sstevel@tonic-gate 
86897c478bd9Sstevel@tonic-gate 		/* Non blocking ibt_set_alt_path */
86907c478bd9Sstevel@tonic-gate 		if (statep->ap_return_data == NULL) {
86917c478bd9Sstevel@tonic-gate 
86927c478bd9Sstevel@tonic-gate 			/* Fill up the event */
86937c478bd9Sstevel@tonic-gate 
86947c478bd9Sstevel@tonic-gate 			bzero(&event, sizeof (event));
86957c478bd9Sstevel@tonic-gate 			event.cm_type = IBT_CM_EVENT_APR_RCV;
86967c478bd9Sstevel@tonic-gate 			event.cm_channel = statep->channel;
86977c478bd9Sstevel@tonic-gate 			event.cm_session_id = NULL;
86987c478bd9Sstevel@tonic-gate 			event.cm_priv_data = NULL;
86997c478bd9Sstevel@tonic-gate 			event.cm_priv_data_len =  0;
87007c478bd9Sstevel@tonic-gate 			event.cm_event.apr.apr_status = IBT_CM_AP_ABORT;
87017c478bd9Sstevel@tonic-gate 
87027c478bd9Sstevel@tonic-gate 			/* Call the cm handler */
87037c478bd9Sstevel@tonic-gate 			statep->cm_handler(statep->state_cm_private, &event,
87047c478bd9Sstevel@tonic-gate 			    NULL, NULL, 0);
87057c478bd9Sstevel@tonic-gate 			IBTF_DPRINTF_L3(cmlog, "ibcm_sync_lapr_idle:"
87067c478bd9Sstevel@tonic-gate 			    "non-blocked wait");
87077c478bd9Sstevel@tonic-gate 		}
87087c478bd9Sstevel@tonic-gate 	} else mutex_exit(&statep->state_mutex);
87097c478bd9Sstevel@tonic-gate 
87107c478bd9Sstevel@tonic-gate 	ASSERT(!MUTEX_HELD(&statep->state_mutex));
87117c478bd9Sstevel@tonic-gate }
87127c478bd9Sstevel@tonic-gate 
87137c478bd9Sstevel@tonic-gate #ifdef DEBUG
87147c478bd9Sstevel@tonic-gate 
87157c478bd9Sstevel@tonic-gate /*
87167c478bd9Sstevel@tonic-gate  * Debug function used to print all the modify qp attributes.
87177c478bd9Sstevel@tonic-gate  * Useful to manually verify the modify qp parameters are as
87187c478bd9Sstevel@tonic-gate  * expected
87197c478bd9Sstevel@tonic-gate  */
87207c478bd9Sstevel@tonic-gate static void
print_modify_qp(char * prefix,ibt_qp_hdl_t ibt_qp,ibt_cep_modify_flags_t flags,ibt_qp_info_t * qp_attr)87217c478bd9Sstevel@tonic-gate print_modify_qp(char *prefix, ibt_qp_hdl_t ibt_qp,
87227c478bd9Sstevel@tonic-gate     ibt_cep_modify_flags_t flags, ibt_qp_info_t *qp_attr)
87237c478bd9Sstevel@tonic-gate {
87247c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP %s %p", prefix, ibt_qp);
87257c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP flags 0x%x", flags);
87267c478bd9Sstevel@tonic-gate 
87277c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP "
87287c478bd9Sstevel@tonic-gate 	    "rc_rdma_ra_in %d rc_rdma_ra_out %d",
87297c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_rdma_ra_in,
87307c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_rdma_ra_out);
87317c478bd9Sstevel@tonic-gate 
87327c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP primary: "
87337c478bd9Sstevel@tonic-gate 	    "port %d path bits %d dlid %X",
87347c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_path.cep_hca_port_num,
87357c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_src_path,
87367c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_dlid);
87377c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP primary: "
87387c478bd9Sstevel@tonic-gate 	    "pkey index %d cep_timeout %d",
87397c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_path.cep_pkey_ix,
87407c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_path.cep_timeout);
87417c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP primary: "
87427c478bd9Sstevel@tonic-gate 	    "srvl %d flow label %d tclass %d",
87437c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_srvl,
87447c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_flow,
87457c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_tclass);
87467c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP primary: "
87477c478bd9Sstevel@tonic-gate 	    "hop %d srate %d sgid_ix %d send_grh %d",
87487c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_hop,
87497c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_srate,
87507c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_sgid_ix,
87517c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_send_grh);
87527c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP primary: "
87537c478bd9Sstevel@tonic-gate 	    "dgid prefix %llX dgid guid %llX",
87547c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_dgid.gid_prefix,
87557c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_dgid.gid_guid);
87567c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP primary: "
87577c478bd9Sstevel@tonic-gate 	    "sgid prefix %llX sgid guid %llX",
87587c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_sgid.gid_prefix,
87597c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_sgid.gid_guid);
87607c478bd9Sstevel@tonic-gate 
87617c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP alternate: "
87627c478bd9Sstevel@tonic-gate 	    "port %d path bits %d dlid %X",
87637c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_alt_path.cep_hca_port_num,
87647c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_src_path,
87657c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_dlid);
87667c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP alternate: "
87677c478bd9Sstevel@tonic-gate 	    "pkey index %d cep_timeout %d",
87687c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_alt_path.cep_pkey_ix,
87697c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_alt_path.cep_timeout);
87707c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP alternate: "
87717c478bd9Sstevel@tonic-gate 	    "srvl %d flow label %d tclass %d",
87727c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_srvl,
87737c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_flow,
87747c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_tclass);
87757c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP alternate: "
87767c478bd9Sstevel@tonic-gate 	    "hop %d srate %d sgid_ix %d send_grh %d",
87777c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_hop,
87787c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_srate,
87797c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_sgid_ix,
87807c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_send_grh);
87817c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP alternate: "
87827c478bd9Sstevel@tonic-gate 	    "dgid prefix %llX dgid guid %llX",
87837c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_dgid.
87847c478bd9Sstevel@tonic-gate 	    gid_prefix,
87857c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_dgid.
87867c478bd9Sstevel@tonic-gate 	    gid_guid);
87877c478bd9Sstevel@tonic-gate 	IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP alternate: "
87887c478bd9Sstevel@tonic-gate 	    "sgid prefix %llX sgid guid %llX",
87897c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_sgid.
87907c478bd9Sstevel@tonic-gate 	    gid_prefix,
87917c478bd9Sstevel@tonic-gate 	    qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_sgid.
87927c478bd9Sstevel@tonic-gate 	    gid_guid);
87937c478bd9Sstevel@tonic-gate }
87947c478bd9Sstevel@tonic-gate #endif
8795