10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
53241Shiremath * Common Development and Distribution License (the "License").
63241Shiremath * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
2212064SShantkumar.Hiremath@Sun.COM * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
230Sstevel@tonic-gate */
240Sstevel@tonic-gate
250Sstevel@tonic-gate #include <sys/ib/mgt/ibcm/ibcm_impl.h>
260Sstevel@tonic-gate #include <sys/callb.h>
270Sstevel@tonic-gate
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate * ibcm_sm.c
300Sstevel@tonic-gate * These routines implement the CM state machine (both ACTIVE and PASSIVE)
310Sstevel@tonic-gate *
320Sstevel@tonic-gate * Points to Note :
330Sstevel@tonic-gate *
340Sstevel@tonic-gate * o CM uses one ibcm_hca_info_t entry per HCA to store all the
350Sstevel@tonic-gate * connection state data belonging to that HCA in the AVL trees, etc.,
360Sstevel@tonic-gate *
370Sstevel@tonic-gate * o There is one state structure per RC, referenced from three AVL trees
380Sstevel@tonic-gate * ie. the HCA active AVL tree, and the HCA passive AVL tree and HCA
390Sstevel@tonic-gate * passive comid tree
400Sstevel@tonic-gate *
410Sstevel@tonic-gate * o SIDR state structures are stored in a linked list
420Sstevel@tonic-gate *
430Sstevel@tonic-gate * o The term statep generally refers to RC, until explicitly mentioned
440Sstevel@tonic-gate * in the notes below
450Sstevel@tonic-gate *
460Sstevel@tonic-gate * o Any thread that may access statep increments the ref_cnt. This ensures
470Sstevel@tonic-gate * that statep is not deleted when it is still being accessed and modified
480Sstevel@tonic-gate * by other threads
490Sstevel@tonic-gate *
500Sstevel@tonic-gate * o Any thread that may want to search the AVL tree(s) holds the hca state
510Sstevel@tonic-gate * table reader lock. If it shall insert/delete a new state structure, then
520Sstevel@tonic-gate * the lock held is writer lock.
530Sstevel@tonic-gate *
540Sstevel@tonic-gate * o Incrementing and Decrementing the ref_cnt can happen only after acquiring
550Sstevel@tonic-gate * statep mutex
560Sstevel@tonic-gate *
570Sstevel@tonic-gate * o Deleting a statep can happen only by acquiring the hca state writer lock
580Sstevel@tonic-gate * and statep mutex and if ref_cnt is zero.
590Sstevel@tonic-gate *
600Sstevel@tonic-gate * o Statep mutexes are used to decrease the hca state table lock holding
610Sstevel@tonic-gate * times. thus increasing more number of threads that can access hca
620Sstevel@tonic-gate * global data structures
630Sstevel@tonic-gate *
640Sstevel@tonic-gate * o Statep mutexes cannot be hold for long time. They are primarily used to
650Sstevel@tonic-gate * check the state of statep, change it and exit the lock. Other threads
660Sstevel@tonic-gate * checking this statep find statep's new state, and may exit without
670Sstevel@tonic-gate * further processing (as the statep->state has changed).
680Sstevel@tonic-gate *
690Sstevel@tonic-gate * o Statep mutex must be held while setting and unsetting the timer id
700Sstevel@tonic-gate * values and during untimeout
710Sstevel@tonic-gate *
720Sstevel@tonic-gate * Re-stating, the overall purpose of these various locks are:
730Sstevel@tonic-gate * - Minimize the time state table locks are held
740Sstevel@tonic-gate * - Writer locks are held only while inserting/deleting into trees,
750Sstevel@tonic-gate * so multiple readers can traverse data structures in parallel
760Sstevel@tonic-gate * - Minimize the time statep mutex held, so other threads entering the same
770Sstevel@tonic-gate * statep mutex are not held for long
780Sstevel@tonic-gate *
790Sstevel@tonic-gate * The CM state machine logic ensures that the statep is valid and exists
800Sstevel@tonic-gate * when timeout callback (ibcm_timeout_cb) is called. This is ensured by
810Sstevel@tonic-gate * cancelling timeouts on state changes, where appropriate
820Sstevel@tonic-gate *
830Sstevel@tonic-gate *
840Sstevel@tonic-gate * The timeout processing is handled in the context in which the
850Sstevel@tonic-gate * timeout callback is invoked.
860Sstevel@tonic-gate *
870Sstevel@tonic-gate * The CM STATE MACHINE logic flow:
880Sstevel@tonic-gate *
890Sstevel@tonic-gate * On an incoming MAD:-
900Sstevel@tonic-gate *
910Sstevel@tonic-gate * IBMF -> ibcm_process_incoming_mad
920Sstevel@tonic-gate * Verify and branch to one of the below connection state routines.
930Sstevel@tonic-gate * The callback arg from ibmf has the pointer to ibcm_hca_info_t
940Sstevel@tonic-gate *
950Sstevel@tonic-gate * 1. INCOMING REQ MAD
960Sstevel@tonic-gate *
970Sstevel@tonic-gate * Acquire hca state table WRITER lock
980Sstevel@tonic-gate * Do lookup in passive AVL tree by remote qpn and remote hca guid
990Sstevel@tonic-gate *
1000Sstevel@tonic-gate * If (new lookup)
1010Sstevel@tonic-gate *
1020Sstevel@tonic-gate * create new statep, initialize key fields
1030Sstevel@tonic-gate * obtain new local com id, insert into hca state AVL tree
1040Sstevel@tonic-gate * release hca state table WRITER lock
1050Sstevel@tonic-gate *
1060Sstevel@tonic-gate * Initialize remaining fields
1070Sstevel@tonic-gate * If invalid service id,
1080Sstevel@tonic-gate * send a REJ reply,
1090Sstevel@tonic-gate * decr ref_cnt holding state mutex
1100Sstevel@tonic-gate * If existing peer conn, check guids, and break the tie
1110Sstevel@tonic-gate * Call the cep state transition function
1120Sstevel@tonic-gate * Send an RTU/REJ reply
1130Sstevel@tonic-gate * Check and handle for any incoming REJ's during REQ RCVD state
1140Sstevel@tonic-gate *
1150Sstevel@tonic-gate * else if (existing lookup)
1160Sstevel@tonic-gate *
1170Sstevel@tonic-gate * increment refcnt holding state mutex
1180Sstevel@tonic-gate * release hca state table WRITER lock
1190Sstevel@tonic-gate *
1200Sstevel@tonic-gate * re-acquire the statep mutex
1210Sstevel@tonic-gate * if (statep->state is REP SENT/REJ SENT/ MRA SENT)
1220Sstevel@tonic-gate * resend the mad
1230Sstevel@tonic-gate * else if established
1240Sstevel@tonic-gate * handle the stale detection
1250Sstevel@tonic-gate * else
1260Sstevel@tonic-gate * drop the mad (no processing required)
1270Sstevel@tonic-gate * decr statep->ref_cnt, release state mutex
1280Sstevel@tonic-gate *
1290Sstevel@tonic-gate *
1300Sstevel@tonic-gate * 2. INCOMING REP MAD
1310Sstevel@tonic-gate *
1320Sstevel@tonic-gate * Acquire hca state READER lock
1330Sstevel@tonic-gate * Do lookup in hca state tree by local com id
1340Sstevel@tonic-gate * Release hca state table READER lock
1350Sstevel@tonic-gate *
1360Sstevel@tonic-gate * if lookup does not exist
1370Sstevel@tonic-gate * return
1380Sstevel@tonic-gate *
1390Sstevel@tonic-gate * if look up exists
1400Sstevel@tonic-gate * incr statep->ref_cnt holding state mutex
1410Sstevel@tonic-gate *
1420Sstevel@tonic-gate * acquire the statep lock
1430Sstevel@tonic-gate * if (state == ESTABLISHED or REJ SENt or MRA REP SENT)
1440Sstevel@tonic-gate * resend the MAD
1450Sstevel@tonic-gate * release state mutex, cancel req sent timer
1460Sstevel@tonic-gate * decrement ref_cnt holding the statep lock
1470Sstevel@tonic-gate * return
1480Sstevel@tonic-gate *
1490Sstevel@tonic-gate * if (state == REQ_SENT or REP_WAIT)
1500Sstevel@tonic-gate * first, change state to REP_RCVD
1510Sstevel@tonic-gate * release statep lock
1520Sstevel@tonic-gate * cancel timers
1530Sstevel@tonic-gate * lookup in the passive tree by remote qpn and remote hca guid
1540Sstevel@tonic-gate * if entry already exists
1550Sstevel@tonic-gate * handle the stale detection
1560Sstevel@tonic-gate * else
1570Sstevel@tonic-gate * add to the passive tree
1580Sstevel@tonic-gate *
1590Sstevel@tonic-gate * Initialize fields of statep
1600Sstevel@tonic-gate * Call the qp state transition function
1610Sstevel@tonic-gate * Post RTU/REJ reply
1620Sstevel@tonic-gate * Acquire the state mutex
1630Sstevel@tonic-gate * decrement the ref cnt
1640Sstevel@tonic-gate * release the statep lock
1650Sstevel@tonic-gate *
1660Sstevel@tonic-gate * 3. INCOMING MRA
1670Sstevel@tonic-gate *
1680Sstevel@tonic-gate * Acquire hca state table READER lock
1690Sstevel@tonic-gate * Do lookup in active hca state tree by local com id
1700Sstevel@tonic-gate * Release hca state table READER lock
1710Sstevel@tonic-gate *
1720Sstevel@tonic-gate * If lookup does not exist
1730Sstevel@tonic-gate * return
1740Sstevel@tonic-gate *
1750Sstevel@tonic-gate * if look up exists
1760Sstevel@tonic-gate * incr statep->ref_cnt holding state mutex
1770Sstevel@tonic-gate *
1780Sstevel@tonic-gate * acquire state mutex
1790Sstevel@tonic-gate * if (state is REQ_SENT or REP_SENT)
1800Sstevel@tonic-gate * change state to REP WAIT or MRA REP RCVD
1810Sstevel@tonic-gate * release state mutex
1820Sstevel@tonic-gate * cancel the current timer
1830Sstevel@tonic-gate *
1840Sstevel@tonic-gate * reacquire state mutex
1850Sstevel@tonic-gate * if (state is REP_WAIT or MRA_REP_RCVD)
1860Sstevel@tonic-gate * set new timer, using service timeout for the first timeout
1870Sstevel@tonic-gate * decr ref cnt, release state mutex
1880Sstevel@tonic-gate *
1890Sstevel@tonic-gate * 4. INCOMING RTU
1900Sstevel@tonic-gate *
1910Sstevel@tonic-gate * Acquire hca state table READER lock
1920Sstevel@tonic-gate * Do lookup in active hca state tree by local com id
1930Sstevel@tonic-gate * Release hca state table READER lock
1940Sstevel@tonic-gate *
1950Sstevel@tonic-gate * If lookup does not exist
1960Sstevel@tonic-gate * return
1970Sstevel@tonic-gate *
1980Sstevel@tonic-gate * if look up exists
1990Sstevel@tonic-gate * incr statep->ref_cnt holding state mutex
2000Sstevel@tonic-gate *
2010Sstevel@tonic-gate * acquire statep mutex
2020Sstevel@tonic-gate * if (state == REP_SENT or MRA REP RCVD))
2030Sstevel@tonic-gate * change state to ESTABLISHED
2040Sstevel@tonic-gate * release statep mutex
2050Sstevel@tonic-gate * cancel timer
2060Sstevel@tonic-gate *
2070Sstevel@tonic-gate * Change QP state
2080Sstevel@tonic-gate *
2090Sstevel@tonic-gate * acquire the statep mutex
2100Sstevel@tonic-gate * decrement the ref count
2110Sstevel@tonic-gate * release statep mutex
2120Sstevel@tonic-gate *
2130Sstevel@tonic-gate * 5. INCOMING REJ
2140Sstevel@tonic-gate *
2150Sstevel@tonic-gate * Acquire hca state table READER lock
2160Sstevel@tonic-gate * Do lookup in active hca state tree by local com id
2170Sstevel@tonic-gate * Release hca state table READER lock
2180Sstevel@tonic-gate *
2190Sstevel@tonic-gate * If lookup does not exist
2200Sstevel@tonic-gate * return
2210Sstevel@tonic-gate *
2220Sstevel@tonic-gate * if look up exists
2230Sstevel@tonic-gate * incr statep->ref_cnt holding state mutex
2240Sstevel@tonic-gate *
2250Sstevel@tonic-gate * if (state == REQ RCVD or REP RCVD MRA_SENT or MRA_REP_SNET)
2260Sstevel@tonic-gate * set statep->delete = true
2270Sstevel@tonic-gate * decrement the ref_cnt
2280Sstevel@tonic-gate * release statep mutex;
2290Sstevel@tonic-gate *
2300Sstevel@tonic-gate * else if (state == REQ_SENT or REP SENT or MRA REP Rcvd)
2310Sstevel@tonic-gate * state = IBCM_STATE_DELETE
2320Sstevel@tonic-gate * Cancel running timers
2330Sstevel@tonic-gate * decrement the ref_cnt
2340Sstevel@tonic-gate * release state mutex
2350Sstevel@tonic-gate * Call the client QP handler
2360Sstevel@tonic-gate * delete the state data
2370Sstevel@tonic-gate *
2380Sstevel@tonic-gate * 6. INCOMING DREQ
2390Sstevel@tonic-gate *
2400Sstevel@tonic-gate * Acquire hca state table READER lock
2410Sstevel@tonic-gate * Do lookup in active hca state tree by local com id
2420Sstevel@tonic-gate * Release hca state table READER lock
2430Sstevel@tonic-gate *
2440Sstevel@tonic-gate * If lookup does not exist
2450Sstevel@tonic-gate * return
2460Sstevel@tonic-gate *
2470Sstevel@tonic-gate * if look up exists
2480Sstevel@tonic-gate * incr statep->ref_cnt holding state mutex
2490Sstevel@tonic-gate *
2500Sstevel@tonic-gate * acquire state mutex
2510Sstevel@tonic-gate * if (state is ESTABLISHED/DREQ SENT/TIMEWAIT)
2520Sstevel@tonic-gate * if state is ESTABLISHED/DREQ SENT,
2530Sstevel@tonic-gate * change state to DREQ RECVD
2540Sstevel@tonic-gate * start timers
2550Sstevel@tonic-gate *
2560Sstevel@tonic-gate * send DREP reply
2570Sstevel@tonic-gate * decr ref_cnt
2580Sstevel@tonic-gate * release state mutex
2590Sstevel@tonic-gate *
2600Sstevel@tonic-gate * 7. Incoming DREP
2610Sstevel@tonic-gate *
2620Sstevel@tonic-gate * Acquire hca state table READER lock
2630Sstevel@tonic-gate * Do lookup in active hca state tree by local com id
2640Sstevel@tonic-gate * Release hca state table READER lock
2650Sstevel@tonic-gate *
2660Sstevel@tonic-gate * If lookup does not exist
2670Sstevel@tonic-gate * return
2680Sstevel@tonic-gate *
2690Sstevel@tonic-gate * if look up exists
2700Sstevel@tonic-gate * incr statep->ref_cnt holding state mutex
2710Sstevel@tonic-gate *
2720Sstevel@tonic-gate * acquire state mutex
2730Sstevel@tonic-gate * if state is DREQ_SENT
2740Sstevel@tonic-gate * change state to DREP_RCVD
2750Sstevel@tonic-gate * cancel timer
2760Sstevel@tonic-gate * change state to TIMEWAIT
2770Sstevel@tonic-gate * set timewait timer
2780Sstevel@tonic-gate * decr ref_cnt
2790Sstevel@tonic-gate * release state mutex
2800Sstevel@tonic-gate *
2810Sstevel@tonic-gate * 8. Timeout handler
2820Sstevel@tonic-gate *
2830Sstevel@tonic-gate * (for states REQ SENT/REP SENT/REJ SENT/DREQ SENT/DREP SENT/TIMEWAIT)
2840Sstevel@tonic-gate *
2850Sstevel@tonic-gate * acquire the statep mutex
2860Sstevel@tonic-gate *
2870Sstevel@tonic-gate * if (set state != stored_state)
2880Sstevel@tonic-gate * The thread that changed the state is responsible for any cleanup
2890Sstevel@tonic-gate * decrement ref cnt
2900Sstevel@tonic-gate * release statep mutex
2910Sstevel@tonic-gate * return
2920Sstevel@tonic-gate * else if (statep's state == REJ SENT)
2930Sstevel@tonic-gate * change state to DELETE
2940Sstevel@tonic-gate * decrement ref cnt
2950Sstevel@tonic-gate * release statep mutex
2960Sstevel@tonic-gate * delete statep
2970Sstevel@tonic-gate * return
2980Sstevel@tonic-gate * else if (state == TIME WAIT)
2990Sstevel@tonic-gate * do the time wait state processing
3000Sstevel@tonic-gate * decrement ref cnt
3010Sstevel@tonic-gate * change state to DELETE
3020Sstevel@tonic-gate * release statep mutex
3030Sstevel@tonic-gate * delete statep, and also QP
3040Sstevel@tonic-gate * else if (remaining retry cnt > 0)
3050Sstevel@tonic-gate * resend the mad
3060Sstevel@tonic-gate * decrement ref cnt
3070Sstevel@tonic-gate * release statep mutex
3080Sstevel@tonic-gate * else if (state == rep sent or req sent or mra rep rcvd or rep wait)
3090Sstevel@tonic-gate * (retry counter expired)
3100Sstevel@tonic-gate * change state to REJ SENT (No one shall delete in REJ SENT)
3110Sstevel@tonic-gate * decrement the ref_cnt
3120Sstevel@tonic-gate * release the statep mutex
3130Sstevel@tonic-gate * Post REJ MAD
3140Sstevel@tonic-gate * cv_signal anyone blocking
3150Sstevel@tonic-gate * Invoke client handler
3160Sstevel@tonic-gate * else if state == DREQ_SENT
3170Sstevel@tonic-gate * change state to TIME WAIT
3180Sstevel@tonic-gate * decrement the ref cnt
3190Sstevel@tonic-gate * set a timer for time wait time
3200Sstevel@tonic-gate * release the statep mutex
3210Sstevel@tonic-gate *
3220Sstevel@tonic-gate *
3230Sstevel@tonic-gate * SIDR processing
3240Sstevel@tonic-gate *
3250Sstevel@tonic-gate * 9. INCOMING SIDR_REQ MAD
3260Sstevel@tonic-gate *
3270Sstevel@tonic-gate * Figure out LID/GID
3280Sstevel@tonic-gate * Do lookup in SIDR LIST based on LID, GID, grh_exists and req_id
3290Sstevel@tonic-gate * increment ud_statep->ud_ref_cnt
3300Sstevel@tonic-gate *
3310Sstevel@tonic-gate * If (new lookup)
3320Sstevel@tonic-gate *
3330Sstevel@tonic-gate * validate service id, and the create new statep,
3340Sstevel@tonic-gate * initialize key fields
3350Sstevel@tonic-gate * do a lookup based on service id
3360Sstevel@tonic-gate * if service_id_lookup returns exists
3370Sstevel@tonic-gate * set sidr_status to QPN_VALID
3380Sstevel@tonic-gate * else
3390Sstevel@tonic-gate * set sidr_status to SID_INVALID
3400Sstevel@tonic-gate * post SIDR_REP mad
3410Sstevel@tonic-gate * decr ud_statep->ud_ref_cnt, release ud_state_mutex
3420Sstevel@tonic-gate *
3430Sstevel@tonic-gate * else if (existing lookup)
3440Sstevel@tonic-gate *
3450Sstevel@tonic-gate * if (ud_statep->ud_state is SIDR_REP_SENT)
3460Sstevel@tonic-gate * resend the mad
3470Sstevel@tonic-gate *
3480Sstevel@tonic-gate * decr ud_statep->ud_ref_cnt, release ud_state_mutex
3490Sstevel@tonic-gate *
3500Sstevel@tonic-gate *
3510Sstevel@tonic-gate * 10. INCOMING SIDR_REP MAD
3520Sstevel@tonic-gate *
3530Sstevel@tonic-gate * Figure out LID/GID
3540Sstevel@tonic-gate * Do lookup in SIDR LIST based on LID, GID, grh_exists and req_id
3550Sstevel@tonic-gate * increment ud_statep->ud_ref_cnt
3560Sstevel@tonic-gate *
3570Sstevel@tonic-gate * if look up doesn't exists
3580Sstevel@tonic-gate * return
3590Sstevel@tonic-gate *
3600Sstevel@tonic-gate * if (state == SIDR_REQ_SENT)
3610Sstevel@tonic-gate * first, change state to SIDR_REP_RCVD
3620Sstevel@tonic-gate * release statep lock
3630Sstevel@tonic-gate * cancel timers
3640Sstevel@tonic-gate * cv_signal anyone blocking
3650Sstevel@tonic-gate * release the statep lock
3660Sstevel@tonic-gate * extract return args
3670Sstevel@tonic-gate * destroy the statep
3680Sstevel@tonic-gate *
3690Sstevel@tonic-gate * 11. Timeout handler
3700Sstevel@tonic-gate *
3710Sstevel@tonic-gate * (for states SIDR_REQ_SENT/SIDR_REP_SENT)
3720Sstevel@tonic-gate *
3730Sstevel@tonic-gate * acquire the statep mutex
3740Sstevel@tonic-gate *
3750Sstevel@tonic-gate * if (statep's state == SIDR_REP_SENT SENT)
3760Sstevel@tonic-gate * change state to DELETE
3770Sstevel@tonic-gate * decrement ref cnt
3780Sstevel@tonic-gate * release statep mutex
3790Sstevel@tonic-gate * delete statep
3800Sstevel@tonic-gate * return
3810Sstevel@tonic-gate * else if (remaining retry cnt > 0 and state is SIDR_REQ_SENT)
3820Sstevel@tonic-gate * resend the mad
3830Sstevel@tonic-gate * decrement ref cnt
3840Sstevel@tonic-gate * release statep mutex
3850Sstevel@tonic-gate * else if (state == SIDR_REQ_SENT)
3860Sstevel@tonic-gate * (retry counter expired)
3870Sstevel@tonic-gate * change state to DELETE
3880Sstevel@tonic-gate * decrement the ref_cnt
3890Sstevel@tonic-gate * the statep mutex
3900Sstevel@tonic-gate * cv_signal anyone blocking
3910Sstevel@tonic-gate * Invoke client handler
3920Sstevel@tonic-gate * delete statep
3930Sstevel@tonic-gate */
3940Sstevel@tonic-gate
3950Sstevel@tonic-gate /* Function prototypes */
3960Sstevel@tonic-gate static void ibcm_set_primary_adds_vect(ibcm_state_data_t *,
3970Sstevel@tonic-gate ibt_adds_vect_t *, ibcm_req_msg_t *);
3980Sstevel@tonic-gate static void ibcm_set_alt_adds_vect(ibcm_state_data_t *,
3990Sstevel@tonic-gate ibt_adds_vect_t *, ibcm_req_msg_t *);
4000Sstevel@tonic-gate static ibt_status_t ibcm_set_primary_cep_path(ibcm_state_data_t *,
4010Sstevel@tonic-gate ibt_cep_path_t *, ibcm_req_msg_t *);
4020Sstevel@tonic-gate static ibt_status_t ibcm_set_alt_cep_path(ibcm_state_data_t *,
4030Sstevel@tonic-gate ibt_cep_path_t *, ibcm_req_msg_t *);
4040Sstevel@tonic-gate static ibt_status_t ibcm_invoke_qp_modify(ibcm_state_data_t *,
4050Sstevel@tonic-gate ibcm_req_msg_t *, ibcm_rep_msg_t *);
4060Sstevel@tonic-gate static ibt_status_t ibcm_invoke_rtu_qp_modify(ibcm_state_data_t *,
4070Sstevel@tonic-gate ib_time_t, ibcm_rep_msg_t *);
4080Sstevel@tonic-gate static ibcm_status_t ibcm_sidr_req_ud_handler(ibcm_ud_state_data_t *,
4090Sstevel@tonic-gate ibcm_sidr_req_msg_t *, ibcm_mad_addr_t *,
4100Sstevel@tonic-gate ibt_sidr_status_t *);
4110Sstevel@tonic-gate static void ibcm_sidr_rep_ud_handler(ibcm_ud_state_data_t *,
4120Sstevel@tonic-gate ibcm_sidr_rep_msg_t *);
4130Sstevel@tonic-gate static void ibcm_handler_conn_fail(ibcm_state_data_t *,
4140Sstevel@tonic-gate uint8_t cf_code, uint8_t cf_msg,
4150Sstevel@tonic-gate ibt_cm_reason_t rej_reason, uint8_t *,
4160Sstevel@tonic-gate ibt_priv_data_len_t);
4170Sstevel@tonic-gate static void ibcm_build_n_post_rej_mad(uint8_t *input_madp,
4180Sstevel@tonic-gate ib_com_id_t, ibcm_mad_addr_t *, int, uint16_t);
4190Sstevel@tonic-gate static void ibcm_post_drep_mad(ibcm_state_data_t *);
4200Sstevel@tonic-gate
4210Sstevel@tonic-gate static ibcm_status_t ibcm_verify_req_gids_and_svcid(
4220Sstevel@tonic-gate ibcm_state_data_t *statep,
4230Sstevel@tonic-gate ibcm_req_msg_t *cm_req_msgp);
4240Sstevel@tonic-gate
4250Sstevel@tonic-gate static void ibcm_timeout_client_cb(ibcm_state_data_t *statep);
4260Sstevel@tonic-gate static void ibcm_ud_timeout_client_cb(
4270Sstevel@tonic-gate ibcm_ud_state_data_t *ud_statep);
4280Sstevel@tonic-gate
4290Sstevel@tonic-gate static void ibcm_process_dreq_timeout(ibcm_state_data_t *statep);
4300Sstevel@tonic-gate
4310Sstevel@tonic-gate static void ibcm_fill_adds_from_lap(ibt_adds_vect_t *adds,
4320Sstevel@tonic-gate ibcm_lap_msg_t *lap_msg, ibcm_mode_t mode);
4330Sstevel@tonic-gate
4340Sstevel@tonic-gate static void ibcm_post_stored_apr_mad(ibcm_state_data_t *statep,
4350Sstevel@tonic-gate uint8_t *input_madp);
4360Sstevel@tonic-gate
4370Sstevel@tonic-gate static ibcm_status_t ibcm_set_qp_from_apr(ibcm_state_data_t *statep,
4380Sstevel@tonic-gate ibcm_lap_msg_t *lap_msg);
4390Sstevel@tonic-gate
4400Sstevel@tonic-gate static boolean_t ibcm_compare_prim_alt_paths(ibt_adds_vect_t *prim,
4410Sstevel@tonic-gate ibt_adds_vect_t *alt);
4420Sstevel@tonic-gate
4430Sstevel@tonic-gate static void ibcm_process_get_classport_info(ibcm_hca_info_t *hcap,
4440Sstevel@tonic-gate uint8_t *input_madp, ibcm_mad_addr_t *cm_mad_addr);
4450Sstevel@tonic-gate
4460Sstevel@tonic-gate static void ibcm_decode_classport_info(ibcm_hca_info_t *hcap,
4470Sstevel@tonic-gate uint8_t *input_madp, ibcm_mad_addr_t *cm_mad_addr);
4480Sstevel@tonic-gate
4490Sstevel@tonic-gate static void ibcm_post_rej_ver_mismatch(uint8_t *input_madp,
4500Sstevel@tonic-gate ibcm_mad_addr_t *cm_mad_addr);
4510Sstevel@tonic-gate
4520Sstevel@tonic-gate static void ibcm_init_clp_to_mad(ibcm_classportinfo_msg_t *clp,
4530Sstevel@tonic-gate ibt_redirect_info_t *rinfo);
4540Sstevel@tonic-gate
4550Sstevel@tonic-gate static void ibcm_init_clp_from_mad(ibcm_classportinfo_msg_t *clp,
4560Sstevel@tonic-gate ibt_redirect_info_t *rinfo);
4570Sstevel@tonic-gate
4580Sstevel@tonic-gate static void ibcm_copy_addl_rej(ibcm_state_data_t *statep,
4590Sstevel@tonic-gate ibcm_rej_msg_t *rej_msgp,
4600Sstevel@tonic-gate ibt_cm_conn_failed_t *failed);
4610Sstevel@tonic-gate
4620Sstevel@tonic-gate static void ibcm_return_open_data(ibcm_state_data_t *statep,
4630Sstevel@tonic-gate ibcm_rep_msg_t *rep_msgp,
4640Sstevel@tonic-gate ibt_cm_reason_t reject_reason);
4650Sstevel@tonic-gate
4660Sstevel@tonic-gate /* limit the number of taskq threads to handle received MADs. */
4670Sstevel@tonic-gate int ibcm_recv_tasks = 0;
4680Sstevel@tonic-gate int ibcm_max_recv_tasks = 24;
4690Sstevel@tonic-gate int ibcm_recv_timeouts = 0;
4700Sstevel@tonic-gate
4713241Shiremath /*
4723241Shiremath * Tunable MAX MRA Service Timeout value in MicroSECONDS.
4733241Shiremath * 0 - Tunable parameter not used.
4743241Shiremath *
4753241Shiremath * Ex: 60000000 - Max MRA Service Delay is 60 Seconds.
4763241Shiremath */
4773241Shiremath clock_t ibcm_mra_service_timeout_max = 0;
4783241Shiremath
4790Sstevel@tonic-gate #ifdef DEBUG
4800Sstevel@tonic-gate
4810Sstevel@tonic-gate static void print_modify_qp(char *prefix,
4820Sstevel@tonic-gate ibt_qp_hdl_t ibt_qp,
4830Sstevel@tonic-gate ibt_cep_modify_flags_t flags,
4840Sstevel@tonic-gate ibt_qp_info_t *qp_attr);
4850Sstevel@tonic-gate #endif
4860Sstevel@tonic-gate
4870Sstevel@tonic-gate /* Warlock annotations */
4880Sstevel@tonic-gate
_NOTE(READ_ONLY_DATA (ibt_arej_info_u))4890Sstevel@tonic-gate _NOTE(READ_ONLY_DATA(ibt_arej_info_u))
4900Sstevel@tonic-gate
4910Sstevel@tonic-gate /*
4920Sstevel@tonic-gate * ibcm_process_incoming_mad:
4930Sstevel@tonic-gate * The CM callback that is invoked by IBMF, when a valid CM MAD arrives
4940Sstevel@tonic-gate * on any of the registered ibmf handles by CM.
4950Sstevel@tonic-gate *
4960Sstevel@tonic-gate * It is assumed that the incoming MAD (except for incoming REQ) belongs
4970Sstevel@tonic-gate * to a connection on the HCA, on which the MAD is received.
4980Sstevel@tonic-gate * The IBMF callback arg specifies ibcm_hca_info_t
4990Sstevel@tonic-gate *
5000Sstevel@tonic-gate * NOTE: IBMF always invokes ibcm_recv_cb() in a taskq. CM does some memory
5010Sstevel@tonic-gate * allocations and invoke ibcm_sm_funcs_tbl[i]() in the same taskq.
5020Sstevel@tonic-gate *
5030Sstevel@tonic-gate * INPUTS:
5040Sstevel@tonic-gate * ibmf_handle - IBMF Handle
5050Sstevel@tonic-gate * args - from IBMF. Is a ptr to ibcm_hca_info_t
5060Sstevel@tonic-gate * status - Callback status. Is mostly IBMF_SUCCESS
5070Sstevel@tonic-gate * madbuf - IBMF allocated MAD buffer (CM should free it)
5080Sstevel@tonic-gate * madaddr - IBMF MAD's address
5090Sstevel@tonic-gate * grhvalid - If GRH is valid or not
5100Sstevel@tonic-gate *
5110Sstevel@tonic-gate * RETURN VALUES: NONE
5120Sstevel@tonic-gate */
5130Sstevel@tonic-gate void
5140Sstevel@tonic-gate ibcm_process_incoming_mad(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
5150Sstevel@tonic-gate void *args)
5160Sstevel@tonic-gate {
5170Sstevel@tonic-gate uint8_t method; /* Method type in MAD hdr */
5180Sstevel@tonic-gate ib_mad_hdr_t *in_mad_hdr; /* Incoming MAD's header */
5190Sstevel@tonic-gate ibcm_hca_info_t *hcap; /* pointer to HCA entry */
5200Sstevel@tonic-gate ibcm_port_info_t *portp;
5210Sstevel@tonic-gate ibcm_mad_addr_t *cm_mad_addr; /* MAD address information */
5220Sstevel@tonic-gate ibcm_event_type_t attr_id; /* Attribute ID in MAD hdr */
5230Sstevel@tonic-gate ibcm_mad_addr_t loc_mad_addr; /* MAD address information */
5240Sstevel@tonic-gate ibcm_qp_list_t *cm_qp_entry;
5250Sstevel@tonic-gate int ibmf_status;
5260Sstevel@tonic-gate
5270Sstevel@tonic-gate
5280Sstevel@tonic-gate /* Noticed that IBMF always calls with IBMF_SUCCESS, but still check */
5290Sstevel@tonic-gate if (msgp->im_msg_status != IBMF_SUCCESS) {
5300Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
5310Sstevel@tonic-gate "bad status %x", msgp->im_msg_status);
5320Sstevel@tonic-gate /* IBMF allocates Input MAD, so free it here */
5330Sstevel@tonic-gate if ((ibmf_status = ibmf_free_msg(ibmf_handle, &msgp)) !=
5340Sstevel@tonic-gate IBMF_SUCCESS)
5350Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
5360Sstevel@tonic-gate "ibmf_free_msg failed %d", ibmf_status);
5370Sstevel@tonic-gate return;
5380Sstevel@tonic-gate }
5390Sstevel@tonic-gate
5400Sstevel@tonic-gate /* Get the HCA entry pointer */
5410Sstevel@tonic-gate cm_qp_entry = (ibcm_qp_list_t *)args;
5420Sstevel@tonic-gate
543557Shiremath IBTF_DPRINTF_L5(cmlog, "ibcm_process_incoming_mad: ibmf_hdl %p "
5440Sstevel@tonic-gate "msg %p args %p", ibmf_handle, msgp, args);
5450Sstevel@tonic-gate
5460Sstevel@tonic-gate #ifdef DEBUG
5470Sstevel@tonic-gate if (ibcm_test_mode > 1)
5480Sstevel@tonic-gate ibcm_query_qp(ibmf_handle, cm_qp_entry->qp_cm);
5490Sstevel@tonic-gate #endif
5500Sstevel@tonic-gate
5510Sstevel@tonic-gate portp = cm_qp_entry->qp_port;
5520Sstevel@tonic-gate hcap = portp->port_hcap;
5530Sstevel@tonic-gate
5540Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_incoming_mad: CM MAD on "
5550Sstevel@tonic-gate "port %d", portp->port_num);
5560Sstevel@tonic-gate
5570Sstevel@tonic-gate /* Increment hca ref cnt, if HCA is in attached state, else fail */
5580Sstevel@tonic-gate if (ibcm_inc_hca_acc_cnt(hcap) != IBCM_SUCCESS) {
5590Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
5600Sstevel@tonic-gate "hca not in attach state");
5610Sstevel@tonic-gate /* IBMF allocates Input MAD, and ibcm free's it */
5620Sstevel@tonic-gate if ((ibmf_status = ibmf_free_msg(ibmf_handle, &msgp)) !=
5630Sstevel@tonic-gate IBMF_SUCCESS)
5640Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
5650Sstevel@tonic-gate "ibmf_free_msg failed %d", ibmf_status);
5660Sstevel@tonic-gate return;
5670Sstevel@tonic-gate }
5680Sstevel@tonic-gate
5690Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*cm_mad_addr))
5700Sstevel@tonic-gate
5710Sstevel@tonic-gate /* allocate memory for internal MAD address buffer */
5720Sstevel@tonic-gate cm_mad_addr = &loc_mad_addr;
5730Sstevel@tonic-gate bzero(cm_mad_addr, sizeof (ibcm_mad_addr_t));
5740Sstevel@tonic-gate
5750Sstevel@tonic-gate cm_mad_addr->port_num = portp->port_num;
5760Sstevel@tonic-gate
5770Sstevel@tonic-gate /* initialize cm_mad_addr field(s) */
5780Sstevel@tonic-gate in_mad_hdr = msgp->im_msgbufs_recv.im_bufs_mad_hdr;
5790Sstevel@tonic-gate
5800Sstevel@tonic-gate if (in_mad_hdr->MgmtClass != MAD_MGMT_CLASS_COMM_MGT) {
5810Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
5820Sstevel@tonic-gate "bad mgmt class %x", in_mad_hdr->MgmtClass);
5830Sstevel@tonic-gate if ((ibmf_status = ibmf_free_msg(ibmf_handle, &msgp)) !=
5840Sstevel@tonic-gate IBMF_SUCCESS)
5850Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
5860Sstevel@tonic-gate "ibmf_free_msg failed %d", ibmf_status);
5870Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
5880Sstevel@tonic-gate return;
5890Sstevel@tonic-gate }
5900Sstevel@tonic-gate
5910Sstevel@tonic-gate cm_mad_addr->rcvd_addr = msgp->im_local_addr;
5920Sstevel@tonic-gate if (msgp->im_msg_flags & IBMF_MSG_FLAGS_GLOBAL_ADDRESS) {
5930Sstevel@tonic-gate cm_mad_addr->grh_hdr = msgp->im_global_addr;
5940Sstevel@tonic-gate cm_mad_addr->grh_exists = B_TRUE;
5950Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_process_incoming_mad: "
5960Sstevel@tonic-gate "CM recv GID GUID %llX sender GID GUID %llX",
5970Sstevel@tonic-gate msgp->im_global_addr.ig_recver_gid.gid_guid,
5980Sstevel@tonic-gate msgp->im_global_addr.ig_sender_gid.gid_guid);
5990Sstevel@tonic-gate }
6000Sstevel@tonic-gate
6010Sstevel@tonic-gate /* Save IBMF handle and ibmf qp related information */
6020Sstevel@tonic-gate cm_mad_addr->ibmf_hdl = ibmf_handle;
6030Sstevel@tonic-gate cm_mad_addr->cm_qp_entry = cm_qp_entry;
6040Sstevel@tonic-gate
6050Sstevel@tonic-gate /* IBMF does not initialize ia_p_key for non-QP1's */
6060Sstevel@tonic-gate if (cm_qp_entry->qp_cm != IBMF_QP_HANDLE_DEFAULT)
6070Sstevel@tonic-gate cm_mad_addr->rcvd_addr.ia_p_key = cm_qp_entry->qp_pkey;
6080Sstevel@tonic-gate
6090Sstevel@tonic-gate if (cm_mad_addr->rcvd_addr.ia_p_key & 0x8000)
6100Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_process_incoming_mad: PKEY %x",
6110Sstevel@tonic-gate cm_mad_addr->rcvd_addr.ia_p_key);
6120Sstevel@tonic-gate else
6130Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: CM MAD "
6140Sstevel@tonic-gate "arrived from limited PKEY %x",
6150Sstevel@tonic-gate cm_mad_addr->rcvd_addr.ia_p_key);
6160Sstevel@tonic-gate
6170Sstevel@tonic-gate /* Retrieve the method and Attr-Id from generic mad header */
6180Sstevel@tonic-gate method = in_mad_hdr->R_Method;
6190Sstevel@tonic-gate attr_id = b2h16(in_mad_hdr->AttributeID);
6200Sstevel@tonic-gate
6210Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_incoming_mad: "
6220Sstevel@tonic-gate "Method %x Attribute %x", method, attr_id);
6230Sstevel@tonic-gate
6240Sstevel@tonic-gate if (in_mad_hdr->ClassVersion != IBCM_MAD_CLASS_VERSION) {
6250Sstevel@tonic-gate
6260Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
6270Sstevel@tonic-gate "unsupported ibcm class version %x",
6280Sstevel@tonic-gate in_mad_hdr->ClassVersion);
6290Sstevel@tonic-gate
6300Sstevel@tonic-gate if (attr_id == (IBCM_INCOMING_REQ + IBCM_ATTR_BASE_ID))
6310Sstevel@tonic-gate ibcm_post_rej_ver_mismatch(
6320Sstevel@tonic-gate (uint8_t *)IBCM_IN_HDRP(msgp), cm_mad_addr);
6330Sstevel@tonic-gate
6340Sstevel@tonic-gate if ((ibmf_status = ibmf_free_msg(ibmf_handle, &msgp)) !=
6350Sstevel@tonic-gate IBMF_SUCCESS)
6360Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
6370Sstevel@tonic-gate "ibmf_free_msg failed %d", ibmf_status);
6380Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
6390Sstevel@tonic-gate return;
6400Sstevel@tonic-gate }
6410Sstevel@tonic-gate
6420Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_incoming_mad: "
6430Sstevel@tonic-gate "Transaction Id 0x%llX", b2h64(in_mad_hdr->TransactionID));
6440Sstevel@tonic-gate
6450Sstevel@tonic-gate #ifdef DEBUG
6460Sstevel@tonic-gate ibcm_decode_tranid(b2h64(in_mad_hdr->TransactionID), NULL);
6470Sstevel@tonic-gate #endif
6480Sstevel@tonic-gate
6490Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*cm_mad_addr))
6500Sstevel@tonic-gate
6510Sstevel@tonic-gate /*
6520Sstevel@tonic-gate * The following are valid combination of Method type
6530Sstevel@tonic-gate * and attribute id in the received MAD :-
6540Sstevel@tonic-gate * o ClassPortInfo with Get method
6550Sstevel@tonic-gate * o CM messages with Send method
6560Sstevel@tonic-gate */
6570Sstevel@tonic-gate if ((attr_id == MAD_ATTR_ID_CLASSPORTINFO) &&
6580Sstevel@tonic-gate ((method == MAD_METHOD_GET) ||
6590Sstevel@tonic-gate (method == MAD_METHOD_GET_RESPONSE))) {
6600Sstevel@tonic-gate if (method == MAD_METHOD_GET)
6610Sstevel@tonic-gate ibcm_process_get_classport_info(hcap,
6620Sstevel@tonic-gate (uint8_t *)IBCM_IN_HDRP(msgp), cm_mad_addr);
6630Sstevel@tonic-gate else if (method == MAD_METHOD_GET_RESPONSE)
6640Sstevel@tonic-gate ibcm_decode_classport_info(hcap,
6650Sstevel@tonic-gate (uint8_t *)IBCM_IN_HDRP(msgp), cm_mad_addr);
6660Sstevel@tonic-gate } else if ((attr_id >= IBCM_ATTR_BASE_ID) &&
6670Sstevel@tonic-gate (attr_id < (IBCM_ATTR_BASE_ID + IBCM_MAX_EVENTS)) &&
6680Sstevel@tonic-gate (method == MAD_METHOD_SEND)) {
6690Sstevel@tonic-gate
6700Sstevel@tonic-gate attr_id -= IBCM_ATTR_BASE_ID; /* figure out CM message id */
6710Sstevel@tonic-gate
6720Sstevel@tonic-gate ASSERT(msgp->im_msgbufs_recv.im_bufs_mad_hdr != NULL);
6730Sstevel@tonic-gate
6740Sstevel@tonic-gate /* Call the CM process connection state function */
6750Sstevel@tonic-gate ibcm_sm_funcs_tbl[attr_id](hcap,
6760Sstevel@tonic-gate (uint8_t *)IBCM_IN_HDRP(msgp), cm_mad_addr);
6770Sstevel@tonic-gate } else {
6780Sstevel@tonic-gate /*
6790Sstevel@tonic-gate * Any other combination of method and attribute are invalid,
6800Sstevel@tonic-gate * hence drop the MAD
6810Sstevel@tonic-gate */
6820Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
6830Sstevel@tonic-gate "unknown Method %x or Attribute %x", method, attr_id);
6840Sstevel@tonic-gate }
6850Sstevel@tonic-gate
6860Sstevel@tonic-gate /* decrement the hcap access reference count */
6870Sstevel@tonic-gate ibcm_dec_hca_acc_cnt(hcap);
6880Sstevel@tonic-gate
6890Sstevel@tonic-gate /* ASSERT(NO_LOCKS_HELD); */
6900Sstevel@tonic-gate
6910Sstevel@tonic-gate /* free up ibmf msgp */
6920Sstevel@tonic-gate if ((ibmf_status = ibmf_free_msg(ibmf_handle, &msgp)) != IBMF_SUCCESS)
6930Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
6940Sstevel@tonic-gate "ibmf_free_msg failed %d", ibmf_status);
6950Sstevel@tonic-gate }
6960Sstevel@tonic-gate
6970Sstevel@tonic-gate /*
6980Sstevel@tonic-gate * Structure to carry the arguments from ibcm_recv_cb() to
6990Sstevel@tonic-gate * ibcm_recv_incoming_mad() via taskq_dispatch
7000Sstevel@tonic-gate */
7010Sstevel@tonic-gate typedef struct ibcm_taskq_args_s {
7020Sstevel@tonic-gate ibmf_handle_t tq_ibmf_handle;
7030Sstevel@tonic-gate ibmf_msg_t *tq_ibmf_msgp;
7040Sstevel@tonic-gate void *tq_args;
7050Sstevel@tonic-gate } ibcm_taskq_args_t;
7060Sstevel@tonic-gate
707557Shiremath #define IBCM_RECV_MAX 128
7080Sstevel@tonic-gate ibcm_taskq_args_t ibcm_recv_array[IBCM_RECV_MAX + 1];
7090Sstevel@tonic-gate int ibcm_get, ibcm_put;
7100Sstevel@tonic-gate int ibcm_recv_total;
7110Sstevel@tonic-gate int ibcm_recv_queued;
7120Sstevel@tonic-gate
_NOTE(READ_ONLY_DATA (ibcm_taskq_args_t))7130Sstevel@tonic-gate _NOTE(READ_ONLY_DATA(ibcm_taskq_args_t))
7140Sstevel@tonic-gate
7150Sstevel@tonic-gate static int
7160Sstevel@tonic-gate ibcm_recv_dequeue(ibmf_handle_t *ibmf_handlep, ibmf_msg_t **msgpp, void **argsp)
7170Sstevel@tonic-gate {
7180Sstevel@tonic-gate ibcm_taskq_args_t *tq;
7190Sstevel@tonic-gate
7200Sstevel@tonic-gate if (ibcm_put == ibcm_get)
7210Sstevel@tonic-gate return (0);
7220Sstevel@tonic-gate
7230Sstevel@tonic-gate if (++ibcm_get >= IBCM_RECV_MAX)
7240Sstevel@tonic-gate ibcm_get = 0;
7250Sstevel@tonic-gate tq = ibcm_recv_array + ibcm_get;
7260Sstevel@tonic-gate *ibmf_handlep = tq->tq_ibmf_handle;
7270Sstevel@tonic-gate *msgpp = tq->tq_ibmf_msgp;
7280Sstevel@tonic-gate *argsp = tq->tq_args;
7290Sstevel@tonic-gate return (1);
7300Sstevel@tonic-gate }
7310Sstevel@tonic-gate
7320Sstevel@tonic-gate static int
ibcm_recv_enqueue(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)7330Sstevel@tonic-gate ibcm_recv_enqueue(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, void *args)
7340Sstevel@tonic-gate {
7350Sstevel@tonic-gate int next;
7360Sstevel@tonic-gate ibcm_taskq_args_t *tq;
7370Sstevel@tonic-gate
7380Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ibcm_recv_mutex));
7390Sstevel@tonic-gate next = ibcm_put + 1;
7400Sstevel@tonic-gate if (next >= IBCM_RECV_MAX)
7410Sstevel@tonic-gate next = 0;
7420Sstevel@tonic-gate if (next != ibcm_get) {
7430Sstevel@tonic-gate ibcm_recv_queued++;
7440Sstevel@tonic-gate ibcm_put = next;
7450Sstevel@tonic-gate tq = ibcm_recv_array + next;
7460Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*tq))
7470Sstevel@tonic-gate tq->tq_ibmf_handle = ibmf_handle;
7480Sstevel@tonic-gate tq->tq_ibmf_msgp = msgp;
7490Sstevel@tonic-gate tq->tq_args = args;
7500Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*tq))
7510Sstevel@tonic-gate return (1);
7520Sstevel@tonic-gate } else {
7530Sstevel@tonic-gate return (0);
7540Sstevel@tonic-gate }
7550Sstevel@tonic-gate }
7560Sstevel@tonic-gate
7570Sstevel@tonic-gate void
ibcm_drop_msg(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp)7580Sstevel@tonic-gate ibcm_drop_msg(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp)
7590Sstevel@tonic-gate {
7600Sstevel@tonic-gate int ibmf_status;
7610Sstevel@tonic-gate
7620Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_drop_msg: discarding MAD");
7630Sstevel@tonic-gate
7640Sstevel@tonic-gate if ((ibmf_status = ibmf_free_msg(ibmf_handle, &msgp)) != IBMF_SUCCESS)
7650Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_drop_msg: "
7660Sstevel@tonic-gate "ibmf_free_msg failed %d", ibmf_status);
7670Sstevel@tonic-gate }
7680Sstevel@tonic-gate
7690Sstevel@tonic-gate /*
7700Sstevel@tonic-gate * Processing done in taskq thread.
7710Sstevel@tonic-gate *
7720Sstevel@tonic-gate * Calls ibcm_process_incoming_mad with all function arguments extracted
7730Sstevel@tonic-gate * from args. Afterwards, check for queued requests.
7740Sstevel@tonic-gate */
7750Sstevel@tonic-gate static void
ibcm_recv_task(void * args)7760Sstevel@tonic-gate ibcm_recv_task(void *args)
7770Sstevel@tonic-gate {
7780Sstevel@tonic-gate ibcm_taskq_args_t *taskq_args;
7790Sstevel@tonic-gate ibmf_handle_t ibmf_handle;
7800Sstevel@tonic-gate ibmf_msg_t *msgp;
7810Sstevel@tonic-gate
7820Sstevel@tonic-gate taskq_args = (ibcm_taskq_args_t *)args;
7830Sstevel@tonic-gate
7840Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_recv_task: Processing incoming MAD"
7850Sstevel@tonic-gate " via taskq");
7860Sstevel@tonic-gate
7870Sstevel@tonic-gate ibcm_process_incoming_mad(taskq_args->tq_ibmf_handle,
7880Sstevel@tonic-gate taskq_args->tq_ibmf_msgp, taskq_args->tq_args);
7890Sstevel@tonic-gate
7900Sstevel@tonic-gate kmem_free(taskq_args, sizeof (ibcm_taskq_args_t));
7910Sstevel@tonic-gate
7920Sstevel@tonic-gate /* process queued entries before giving up this thread */
7930Sstevel@tonic-gate mutex_enter(&ibcm_recv_mutex);
7940Sstevel@tonic-gate while (ibcm_recv_dequeue(&ibmf_handle, &msgp, &args)) {
7950Sstevel@tonic-gate mutex_exit(&ibcm_recv_mutex);
7960Sstevel@tonic-gate ibcm_process_incoming_mad(ibmf_handle, msgp, args);
7970Sstevel@tonic-gate mutex_enter(&ibcm_recv_mutex);
7980Sstevel@tonic-gate }
7990Sstevel@tonic-gate --ibcm_recv_tasks;
8000Sstevel@tonic-gate mutex_exit(&ibcm_recv_mutex);
8010Sstevel@tonic-gate }
8020Sstevel@tonic-gate
8030Sstevel@tonic-gate static void
ibcm_recv_timeout_cb(void * args)8040Sstevel@tonic-gate ibcm_recv_timeout_cb(void *args)
8050Sstevel@tonic-gate {
8060Sstevel@tonic-gate ibcm_taskq_args_t *tq = (ibcm_taskq_args_t *)args;
8070Sstevel@tonic-gate int rv = 1;
8080Sstevel@tonic-gate
8090Sstevel@tonic-gate mutex_enter(&ibcm_recv_mutex);
8100Sstevel@tonic-gate ibcm_recv_timeouts--;
8110Sstevel@tonic-gate if (ibcm_recv_tasks == 0) {
8120Sstevel@tonic-gate ibcm_recv_tasks++;
8130Sstevel@tonic-gate mutex_exit(&ibcm_recv_mutex);
8140Sstevel@tonic-gate if (taskq_dispatch(ibcm_taskq, ibcm_recv_task, tq,
8150Sstevel@tonic-gate TQ_NOQUEUE | TQ_NOSLEEP) == 0) {
8160Sstevel@tonic-gate mutex_enter(&ibcm_recv_mutex);
8170Sstevel@tonic-gate if (--ibcm_recv_tasks == 0) {
8180Sstevel@tonic-gate (void) timeout(ibcm_recv_timeout_cb, tq, 1);
8190Sstevel@tonic-gate ibcm_recv_timeouts++;
8200Sstevel@tonic-gate } else {
8210Sstevel@tonic-gate rv = ibcm_recv_enqueue(tq->tq_ibmf_handle,
8220Sstevel@tonic-gate tq->tq_ibmf_msgp, tq->tq_args);
8230Sstevel@tonic-gate kmem_free(tq, sizeof (*tq));
8240Sstevel@tonic-gate }
8250Sstevel@tonic-gate mutex_exit(&ibcm_recv_mutex);
8260Sstevel@tonic-gate }
8270Sstevel@tonic-gate } else {
8280Sstevel@tonic-gate /*
8290Sstevel@tonic-gate * one or more taskq threads are running now
8300Sstevel@tonic-gate * so just try to enqueue this one.
8310Sstevel@tonic-gate */
8320Sstevel@tonic-gate rv = ibcm_recv_enqueue(tq->tq_ibmf_handle,
8330Sstevel@tonic-gate tq->tq_ibmf_msgp, tq->tq_args);
8340Sstevel@tonic-gate kmem_free(tq, sizeof (*tq));
8350Sstevel@tonic-gate mutex_exit(&ibcm_recv_mutex);
8360Sstevel@tonic-gate }
8370Sstevel@tonic-gate if (rv == 0)
8380Sstevel@tonic-gate ibcm_drop_msg(tq->tq_ibmf_handle, tq->tq_ibmf_msgp);
8390Sstevel@tonic-gate }
8400Sstevel@tonic-gate
8410Sstevel@tonic-gate /*
8420Sstevel@tonic-gate * Dispatch to taskq if we're not using many, else just queue it
8430Sstevel@tonic-gate * and have the taskq thread pick it up. Return 0 if we're dropping it.
8440Sstevel@tonic-gate */
8450Sstevel@tonic-gate static int
ibcm_recv_add_one(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)8460Sstevel@tonic-gate ibcm_recv_add_one(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, void *args)
8470Sstevel@tonic-gate {
8480Sstevel@tonic-gate int rv;
8490Sstevel@tonic-gate ibcm_taskq_args_t *tq;
8500Sstevel@tonic-gate
8510Sstevel@tonic-gate mutex_enter(&ibcm_recv_mutex);
8520Sstevel@tonic-gate ibcm_recv_total++;
8530Sstevel@tonic-gate if (ibcm_recv_tasks >= ibcm_max_recv_tasks) { /* just queue this one */
8540Sstevel@tonic-gate rv = ibcm_recv_enqueue(ibmf_handle, msgp, args);
8550Sstevel@tonic-gate mutex_exit(&ibcm_recv_mutex);
8560Sstevel@tonic-gate return (rv);
8570Sstevel@tonic-gate } else {
8580Sstevel@tonic-gate ibcm_recv_tasks++; /* dispatch this one to a taskq thread */
8590Sstevel@tonic-gate mutex_exit(&ibcm_recv_mutex);
8600Sstevel@tonic-gate tq = kmem_alloc(sizeof (*tq), KM_NOSLEEP);
8610Sstevel@tonic-gate if (tq == NULL) {
8620Sstevel@tonic-gate mutex_enter(&ibcm_recv_mutex);
8630Sstevel@tonic-gate if (--ibcm_recv_tasks > 0)
8640Sstevel@tonic-gate rv = ibcm_recv_enqueue(ibmf_handle, msgp, args);
8650Sstevel@tonic-gate else /* don't enqueue if no threads are running */
8660Sstevel@tonic-gate rv = 0;
8670Sstevel@tonic-gate mutex_exit(&ibcm_recv_mutex);
8680Sstevel@tonic-gate return (rv);
8690Sstevel@tonic-gate }
8700Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*tq))
8710Sstevel@tonic-gate tq->tq_ibmf_handle = ibmf_handle;
8720Sstevel@tonic-gate tq->tq_ibmf_msgp = msgp;
8730Sstevel@tonic-gate tq->tq_args = args;
8740Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*tq))
8750Sstevel@tonic-gate if (taskq_dispatch(ibcm_taskq, ibcm_recv_task, tq,
8760Sstevel@tonic-gate TQ_NOQUEUE | TQ_NOSLEEP) == 0) { /* dispatch failed */
8770Sstevel@tonic-gate mutex_enter(&ibcm_recv_mutex);
8780Sstevel@tonic-gate if (--ibcm_recv_tasks == 0) {
8790Sstevel@tonic-gate /* try the dispatch again, after a tick */
8800Sstevel@tonic-gate (void) timeout(ibcm_recv_timeout_cb, tq, 1);
8810Sstevel@tonic-gate ibcm_recv_timeouts++;
8820Sstevel@tonic-gate rv = 1; /* indicate success */
8830Sstevel@tonic-gate } else {
8840Sstevel@tonic-gate rv = ibcm_recv_enqueue(ibmf_handle, msgp, args);
8850Sstevel@tonic-gate kmem_free(tq, sizeof (*tq));
8860Sstevel@tonic-gate }
8870Sstevel@tonic-gate mutex_exit(&ibcm_recv_mutex);
8880Sstevel@tonic-gate return (rv);
8890Sstevel@tonic-gate } else {
8900Sstevel@tonic-gate return (1);
8910Sstevel@tonic-gate }
8920Sstevel@tonic-gate }
8930Sstevel@tonic-gate }
8940Sstevel@tonic-gate
8950Sstevel@tonic-gate /*
8960Sstevel@tonic-gate * ibcm_recv_cb:
8970Sstevel@tonic-gate * The CM callback that is invoked by IBMF, when a valid CM MAD arrives
8980Sstevel@tonic-gate * on any of the registered ibmf handles by CM.
8990Sstevel@tonic-gate *
9000Sstevel@tonic-gate * INPUTS:
9010Sstevel@tonic-gate * ibmf_handle - IBMF Handle
9020Sstevel@tonic-gate * msgp - IBMF msg containing the MAD (allocated by IBMF)
9030Sstevel@tonic-gate * args - Ptr to ibcm_hca_info_t
9040Sstevel@tonic-gate *
9050Sstevel@tonic-gate * RETURN VALUES: NONE
9060Sstevel@tonic-gate */
9070Sstevel@tonic-gate void
ibcm_recv_cb(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)9080Sstevel@tonic-gate ibcm_recv_cb(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, void *args)
9090Sstevel@tonic-gate {
9100Sstevel@tonic-gate if (ibcm_recv_add_one(ibmf_handle, msgp, args) == 0)
9110Sstevel@tonic-gate ibcm_drop_msg(ibmf_handle, msgp);
9120Sstevel@tonic-gate }
9130Sstevel@tonic-gate
9140Sstevel@tonic-gate /*
9150Sstevel@tonic-gate * ibcm_process_req_msg:
9160Sstevel@tonic-gate * PASSIVE SIDE CM
9170Sstevel@tonic-gate * Called from ibcm_process_incoming_mad on reception of a REQ message
9180Sstevel@tonic-gate *
9190Sstevel@tonic-gate * Description:
9200Sstevel@tonic-gate * If it a new REQ (not duplicate)
9210Sstevel@tonic-gate * creates a new state structure in passive connection mode
9220Sstevel@tonic-gate * populate state structure fields
9230Sstevel@tonic-gate * inserts state structure in hca active and passive trees
9240Sstevel@tonic-gate * validates service id
9250Sstevel@tonic-gate * validates primary and alternate lid/gid in REQ,
9260Sstevel@tonic-gate * calls QP state transition function
9270Sstevel@tonic-gate * generates REP/REJ response
9280Sstevel@tonic-gate * stores the response MAD in state structure for future re-sends
9290Sstevel@tonic-gate * initializes timers as required
9300Sstevel@tonic-gate * If a duplicate REQ, action depends upon current state in the state
9310Sstevel@tonic-gate * structure
9320Sstevel@tonic-gate *
9330Sstevel@tonic-gate * INPUTS:
9340Sstevel@tonic-gate * hcap - HCA entry ptr
9350Sstevel@tonic-gate * input_madp - CM MAD that is input to this function
9360Sstevel@tonic-gate * cm_mad_addr - Address information for the MAD
9370Sstevel@tonic-gate *
9380Sstevel@tonic-gate * RETURN VALUE:
9390Sstevel@tonic-gate * NONE
9400Sstevel@tonic-gate */
9410Sstevel@tonic-gate void
ibcm_process_req_msg(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)9420Sstevel@tonic-gate ibcm_process_req_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
9430Sstevel@tonic-gate ibcm_mad_addr_t *cm_mad_addr)
9440Sstevel@tonic-gate {
9450Sstevel@tonic-gate ibt_priv_data_len_t arej_info_len = 0;
9460Sstevel@tonic-gate ib_qpn_t remote_qpn;
9470Sstevel@tonic-gate ib_guid_t remote_hca_guid;
9480Sstevel@tonic-gate ib_com_id_t remote_comid;
9490Sstevel@tonic-gate ib_com_id_t local_comid;
9500Sstevel@tonic-gate ibcm_status_t state_lookup_status;
9510Sstevel@tonic-gate ibcm_status_t comid_lookup_status;
9520Sstevel@tonic-gate ibcm_status_t response;
9534703Shiremath ibcm_req_msg_t *req_msgp =
9544703Shiremath (ibcm_req_msg_t *)&input_madp[IBCM_MAD_HDR_SIZE];
9550Sstevel@tonic-gate ibt_cm_reason_t reject_reason = IBT_CM_SUCCESS;
9560Sstevel@tonic-gate ibcm_state_data_t *statep;
9570Sstevel@tonic-gate ibcm_state_data_t *stale_statep = NULL;
9580Sstevel@tonic-gate ibcm_status_t svc_gid_check;
9590Sstevel@tonic-gate uint32_t psn24_timeout5_retry3;
9600Sstevel@tonic-gate ibt_tran_srv_t trans;
9610Sstevel@tonic-gate
9620Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_process_req_msg(%p, %p, %p)",
9630Sstevel@tonic-gate hcap, input_madp, cm_mad_addr);
9640Sstevel@tonic-gate
9650Sstevel@tonic-gate /*
9660Sstevel@tonic-gate * Lookup for an existing state structure or create a new state struct
9670Sstevel@tonic-gate * If there is no entry, the lookup function also allocates a new
9680Sstevel@tonic-gate * state structure and inserts in the table, initializes remote qpn
9690Sstevel@tonic-gate * and hca guid from REQ
9700Sstevel@tonic-gate */
9710Sstevel@tonic-gate remote_hca_guid = b2h64(req_msgp->req_local_ca_guid);
9720Sstevel@tonic-gate remote_qpn = b2h32(req_msgp->req_local_qpn_plus) >> 8;
9730Sstevel@tonic-gate remote_comid = b2h32(req_msgp->req_local_comm_id);
9740Sstevel@tonic-gate
9750Sstevel@tonic-gate IBCM_DUMP_RAW_MSG((uchar_t *)input_madp);
9760Sstevel@tonic-gate
9770Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: remote_comid = %x"
9780Sstevel@tonic-gate " remote_qpn = %x", remote_comid, remote_qpn);
9790Sstevel@tonic-gate
9800Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: remote_hcaguid = %llX",
9810Sstevel@tonic-gate remote_hca_guid);
9820Sstevel@tonic-gate
9830Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
9840Sstevel@tonic-gate
9850Sstevel@tonic-gate new_req:
9860Sstevel@tonic-gate /* allocate the local_comid before proceeding */
9870Sstevel@tonic-gate if (ibcm_alloc_comid(hcap, &local_comid) != IBCM_SUCCESS) {
9880Sstevel@tonic-gate ibcm_build_n_post_rej_mad(input_madp,
9890Sstevel@tonic-gate b2h32(req_msgp->req_local_comm_id), cm_mad_addr,
9900Sstevel@tonic-gate IBT_CM_FAILURE_REQ, IBT_CM_NO_RESC);
9910Sstevel@tonic-gate return;
9920Sstevel@tonic-gate }
9930Sstevel@tonic-gate
9940Sstevel@tonic-gate /* allocate ibcm_state_data_t before grabbing the WRITER lock */
9950Sstevel@tonic-gate statep = kmem_zalloc(sizeof (*statep), KM_SLEEP);
9960Sstevel@tonic-gate
9970Sstevel@tonic-gate rw_enter(&hcap->hca_state_rwlock, RW_WRITER);
9980Sstevel@tonic-gate
9990Sstevel@tonic-gate /* NOTE that only a writer lock is held here */
10000Sstevel@tonic-gate
10010Sstevel@tonic-gate state_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_REQ,
10020Sstevel@tonic-gate local_comid, remote_qpn, remote_hca_guid, hcap, &statep);
10030Sstevel@tonic-gate
10040Sstevel@tonic-gate if (state_lookup_status == IBCM_LOOKUP_NEW) {
10050Sstevel@tonic-gate /* seeing the REQ request for the first time */
10060Sstevel@tonic-gate
10070Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
10080Sstevel@tonic-gate /* Release the state table lock */
10090Sstevel@tonic-gate rw_exit(&hcap->hca_state_rwlock);
10100Sstevel@tonic-gate
10110Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: New statep 0x%p"
10120Sstevel@tonic-gate " created", statep);
10130Sstevel@tonic-gate
10140Sstevel@tonic-gate psn24_timeout5_retry3 = b2h32(req_msgp->req_starting_psn_plus);
10150Sstevel@tonic-gate
10160Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
10170Sstevel@tonic-gate
10180Sstevel@tonic-gate /* if ibmf msg allocation fails, delete the statep */
10190Sstevel@tonic-gate if (ibcm_alloc_out_msg(cm_mad_addr->ibmf_hdl,
10200Sstevel@tonic-gate &statep->stored_msg, MAD_METHOD_SEND) != IBT_SUCCESS) {
10210Sstevel@tonic-gate
10220Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
10230Sstevel@tonic-gate statep->state = IBCM_STATE_DELETE;
10240Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
10250Sstevel@tonic-gate /* HCA res cnt decremented via ibcm_delete_state_data */
10260Sstevel@tonic-gate ibcm_inc_hca_res_cnt(hcap);
10270Sstevel@tonic-gate ibcm_delete_state_data(statep);
10280Sstevel@tonic-gate return;
10290Sstevel@tonic-gate }
10300Sstevel@tonic-gate
10313241Shiremath /* Allocate dreq_msg buf to be used during teardown. */
10323241Shiremath if (ibcm_alloc_out_msg(cm_mad_addr->ibmf_hdl,
10333241Shiremath &statep->dreq_msg, MAD_METHOD_SEND) != IBT_SUCCESS) {
10343241Shiremath
10353241Shiremath IBCM_REF_CNT_DECR(statep);
10363241Shiremath statep->state = IBCM_STATE_DELETE;
10373241Shiremath mutex_exit(&statep->state_mutex);
10383241Shiremath IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_msg: "
10393241Shiremath "statep 0x%p: Failed to allocate dreq_msg", statep);
10403241Shiremath
10413241Shiremath /* HCA res cnt decremented via ibcm_delete_state_data */
10423241Shiremath ibcm_inc_hca_res_cnt(hcap);
10433241Shiremath ibcm_delete_state_data(statep);
10443241Shiremath return;
10453241Shiremath }
10463241Shiremath
10470Sstevel@tonic-gate /* initialize some "statep" fields */
10480Sstevel@tonic-gate statep->mode = IBCM_PASSIVE_MODE;
10490Sstevel@tonic-gate statep->hcap = hcap;
10500Sstevel@tonic-gate statep->remote_comid = remote_comid;
10510Sstevel@tonic-gate statep->svcid = b2h64(req_msgp->req_svc_id);
105211369SPramod.Gunjikar@Sun.COM statep->local_qp_rnr_cnt =
105311369SPramod.Gunjikar@Sun.COM req_msgp->req_mtu_plus & 0x7;
10540Sstevel@tonic-gate
10550Sstevel@tonic-gate /*
10560Sstevel@tonic-gate * get the remote_ack_delay, etc.
10570Sstevel@tonic-gate */
10580Sstevel@tonic-gate statep->remote_ack_delay =
10590Sstevel@tonic-gate ibt_ib2usec(req_msgp->req_primary_localtime_plus >> 3);
10600Sstevel@tonic-gate statep->cep_retry_cnt = psn24_timeout5_retry3 & 0x7;
10610Sstevel@tonic-gate
10620Sstevel@tonic-gate /*
10630Sstevel@tonic-gate * get the req_max_cm_retries
10640Sstevel@tonic-gate */
10650Sstevel@tonic-gate statep->max_cm_retries = req_msgp->req_max_cm_retries_plus >> 4;
10660Sstevel@tonic-gate statep->remaining_retry_cnt = statep->max_cm_retries;
10670Sstevel@tonic-gate
10680Sstevel@tonic-gate /* Approximate pkt life time for now */
10690Sstevel@tonic-gate statep->pkt_life_time = statep->remote_ack_delay/2;
10700Sstevel@tonic-gate
10710Sstevel@tonic-gate /* Passive side timer is set to LocalCMRespTime in REQ */
10720Sstevel@tonic-gate statep->timer_value =
10730Sstevel@tonic-gate ibt_ib2usec(psn24_timeout5_retry3 >> 3 & 0x1f);
10740Sstevel@tonic-gate
10750Sstevel@tonic-gate statep->starting_psn = psn24_timeout5_retry3 >> 8;
10760Sstevel@tonic-gate
10770Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: statep 0x%p "
10780Sstevel@tonic-gate "active cep timeout(usec) = %u",
10790Sstevel@tonic-gate statep, statep->remote_ack_delay);
10800Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: "
10810Sstevel@tonic-gate "passive timer(usec) = %u", statep->timer_value);
10820Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: "
10830Sstevel@tonic-gate "approx pkt lt(usec)= %u ", statep->pkt_life_time);
10840Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: "
10850Sstevel@tonic-gate "max cm retries %u", statep->max_cm_retries);
10860Sstevel@tonic-gate
10870Sstevel@tonic-gate /* The reply ie., REP/REJ transaction id copied from REQ */
10880Sstevel@tonic-gate IBCM_OUT_HDRP(statep->stored_msg)->TransactionID =
10890Sstevel@tonic-gate ((ib_mad_hdr_t *)(input_madp))->TransactionID;
10900Sstevel@tonic-gate
10910Sstevel@tonic-gate /*
10920Sstevel@tonic-gate * Initialize the stale clock. Any other REQ
10930Sstevel@tonic-gate * messages on this statep are considered as duplicate
10940Sstevel@tonic-gate * if they arrive within stale clock
10950Sstevel@tonic-gate * ibcm_adj_btime is used to offset for retry REQ's
10960Sstevel@tonic-gate * arriving just after expected retry clock
10970Sstevel@tonic-gate */
10980Sstevel@tonic-gate statep->stale_clock = gethrtime() +
1099557Shiremath (hrtime_t)(ibcm_adj_btime * 1000000000) +
1100557Shiremath (hrtime_t)statep->remote_ack_delay *
1101557Shiremath (statep->max_cm_retries * (1000 / 2));
11020Sstevel@tonic-gate
11030Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
11040Sstevel@tonic-gate
11050Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_REQ);
11060Sstevel@tonic-gate
11070Sstevel@tonic-gate /* Increment the hca's resource count */
11080Sstevel@tonic-gate ibcm_inc_hca_res_cnt(hcap);
11090Sstevel@tonic-gate
11100Sstevel@tonic-gate ibcm_build_reply_mad_addr(cm_mad_addr,
11110Sstevel@tonic-gate &statep->stored_reply_addr);
11120Sstevel@tonic-gate
11130Sstevel@tonic-gate if (statep->stored_reply_addr.cm_qp_entry == NULL) {
11140Sstevel@tonic-gate
11150Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_msg: "
11160Sstevel@tonic-gate "statep 0x%p cm_qp_entry alloc failed", statep);
11170Sstevel@tonic-gate
11180Sstevel@tonic-gate /*
11190Sstevel@tonic-gate * Not much choice. CM MADs cannot go on QP1, not even
11200Sstevel@tonic-gate * REJ. Hence delete state data and go away silently.
11210Sstevel@tonic-gate * The remote will timeout after repeated attempts
11220Sstevel@tonic-gate */
11230Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
11240Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
11250Sstevel@tonic-gate statep->state = IBCM_STATE_DELETE;
11260Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
11270Sstevel@tonic-gate
11280Sstevel@tonic-gate ibcm_delete_state_data(statep);
11290Sstevel@tonic-gate return;
11300Sstevel@tonic-gate }
11310Sstevel@tonic-gate
11320Sstevel@tonic-gate stale_statep = statep;
11330Sstevel@tonic-gate rw_enter(&hcap->hca_state_rwlock, RW_WRITER);
11340Sstevel@tonic-gate comid_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_REQ_STALE,
11350Sstevel@tonic-gate remote_comid, 0, remote_hca_guid, hcap, &stale_statep);
11360Sstevel@tonic-gate rw_exit(&hcap->hca_state_rwlock);
11370Sstevel@tonic-gate
11380Sstevel@tonic-gate if (comid_lookup_status == IBCM_LOOKUP_EXISTS) {
11390Sstevel@tonic-gate
11400Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_msg: "
11410Sstevel@tonic-gate "dup comid %x stale_statep 0x%p statep 0x%p",
11420Sstevel@tonic-gate remote_comid, stale_statep, statep);
11430Sstevel@tonic-gate
11440Sstevel@tonic-gate ibcm_insert_trace(stale_statep,
11450Sstevel@tonic-gate IBCM_TRACE_STALE_DETECT);
11460Sstevel@tonic-gate
11470Sstevel@tonic-gate /* Send a REJ with duplicate com id */
11480Sstevel@tonic-gate ibcm_post_rej_mad(statep, IBT_CM_DUP_COM_ID,
11490Sstevel@tonic-gate IBT_CM_FAILURE_REQ, NULL, 0);
11500Sstevel@tonic-gate
11510Sstevel@tonic-gate /*
11520Sstevel@tonic-gate * Don't free the ibmf msg, if stale_statep is not in
11530Sstevel@tonic-gate * ESTABLISHED state, because probability is very less.
11540Sstevel@tonic-gate * ibmf msg shall be deleted along with statep
11550Sstevel@tonic-gate */
11560Sstevel@tonic-gate
11570Sstevel@tonic-gate /*
11580Sstevel@tonic-gate * if stale_statep is in established state, process
11590Sstevel@tonic-gate * stale connection handling on stale_statep
11600Sstevel@tonic-gate */
11610Sstevel@tonic-gate mutex_enter(&stale_statep->state_mutex);
11620Sstevel@tonic-gate if (stale_statep->state == IBCM_STATE_ESTABLISHED) {
11630Sstevel@tonic-gate
11640Sstevel@tonic-gate stale_statep->state =
11650Sstevel@tonic-gate IBCM_STATE_TRANSIENT_DREQ_SENT;
11660Sstevel@tonic-gate stale_statep->stale = B_TRUE;
11670Sstevel@tonic-gate
11680Sstevel@tonic-gate /* Cancel pending ibt_set_alt_path */
11690Sstevel@tonic-gate ibcm_sync_lapr_idle(stale_statep);
11700Sstevel@tonic-gate /* The above call releases the state mutex */
11710Sstevel@tonic-gate
11720Sstevel@tonic-gate if (stale_statep->dreq_msg == NULL)
11730Sstevel@tonic-gate (void) ibcm_alloc_out_msg(stale_statep->
11740Sstevel@tonic-gate stored_reply_addr.ibmf_hdl,
11750Sstevel@tonic-gate &stale_statep->dreq_msg,
11760Sstevel@tonic-gate MAD_METHOD_SEND);
11770Sstevel@tonic-gate
11780Sstevel@tonic-gate /*
11790Sstevel@tonic-gate * Spec says, post DREQ MAD on the stale
11800Sstevel@tonic-gate * channel. This moves channel into timewait
11810Sstevel@tonic-gate */
11820Sstevel@tonic-gate if (stale_statep->dreq_msg != NULL) {
11830Sstevel@tonic-gate ibcm_post_dreq_mad(stale_statep);
11840Sstevel@tonic-gate mutex_enter(&stale_statep->state_mutex);
11850Sstevel@tonic-gate } else {
11860Sstevel@tonic-gate mutex_enter(&stale_statep->state_mutex);
11870Sstevel@tonic-gate /* Set it back to original state. */
11880Sstevel@tonic-gate stale_statep->state =
11890Sstevel@tonic-gate IBCM_STATE_ESTABLISHED;
11900Sstevel@tonic-gate cv_broadcast(
11910Sstevel@tonic-gate &stale_statep->block_mad_cv);
11920Sstevel@tonic-gate }
11930Sstevel@tonic-gate }
11940Sstevel@tonic-gate
11950Sstevel@tonic-gate IBCM_REF_CNT_DECR(stale_statep);
11960Sstevel@tonic-gate mutex_exit(&stale_statep->state_mutex);
11970Sstevel@tonic-gate
11980Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
11990Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
12000Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
12010Sstevel@tonic-gate return;
12020Sstevel@tonic-gate }
12030Sstevel@tonic-gate
12040Sstevel@tonic-gate /* If unknown service type, just post a REJ */
12050Sstevel@tonic-gate trans = ((uint8_t *)&req_msgp->req_remote_eecn_plus)[3] >> 1 &
12060Sstevel@tonic-gate 0x3;
12070Sstevel@tonic-gate if ((trans != IBT_RC_SRV) && (trans != IBT_UC_SRV) &&
12080Sstevel@tonic-gate (trans != IBT_RD_SRV)) {
12090Sstevel@tonic-gate
12100Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_msg: "
12110Sstevel@tonic-gate "statep 0x%p invalid transport type %x", statep,
12120Sstevel@tonic-gate trans);
12130Sstevel@tonic-gate
12140Sstevel@tonic-gate /* Send a REJ with invalid transport type */
12150Sstevel@tonic-gate ibcm_post_rej_mad(statep, IBT_CM_INVALID_SRV_TYPE,
12160Sstevel@tonic-gate IBT_CM_FAILURE_REQ, NULL, 0);
12170Sstevel@tonic-gate
12180Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
12190Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
12200Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
12210Sstevel@tonic-gate return;
12220Sstevel@tonic-gate }
12230Sstevel@tonic-gate
12240Sstevel@tonic-gate /* Validate the gids, lids and service id */
12250Sstevel@tonic-gate svc_gid_check = ibcm_verify_req_gids_and_svcid(statep,
12260Sstevel@tonic-gate req_msgp);
12270Sstevel@tonic-gate
12280Sstevel@tonic-gate if (svc_gid_check == IBCM_FAILURE) {
12290Sstevel@tonic-gate
12300Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_process_req_msg: Either "
12310Sstevel@tonic-gate "gid or sid invalid for statep 0x%p", statep);
12320Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
12330Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
12340Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
12350Sstevel@tonic-gate
12360Sstevel@tonic-gate /* REJ posted from ibcm_verify_req_gids_and_svcid */
12370Sstevel@tonic-gate return;
12380Sstevel@tonic-gate }
12390Sstevel@tonic-gate
12400Sstevel@tonic-gate /* Call the QP state transition processing function */
12410Sstevel@tonic-gate response = ibcm_cep_state_req(statep, req_msgp,
12420Sstevel@tonic-gate &reject_reason, &arej_info_len);
12430Sstevel@tonic-gate
12440Sstevel@tonic-gate /* If defer, return holding the statep ref cnt */
12450Sstevel@tonic-gate if (response == IBCM_DEFER) {
12460Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: "
12470Sstevel@tonic-gate "statep %0xp client returned DEFER response",
12480Sstevel@tonic-gate statep);
12490Sstevel@tonic-gate return;
12500Sstevel@tonic-gate }
12510Sstevel@tonic-gate
12520Sstevel@tonic-gate /* statep ref cnt decremented in the func below */
12530Sstevel@tonic-gate ibcm_handle_cep_req_response(statep, response,
12540Sstevel@tonic-gate reject_reason, arej_info_len);
12550Sstevel@tonic-gate
12560Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*statep))
12570Sstevel@tonic-gate
12580Sstevel@tonic-gate return;
12590Sstevel@tonic-gate
12600Sstevel@tonic-gate } else {
12610Sstevel@tonic-gate rw_exit(&hcap->hca_state_rwlock);
12620Sstevel@tonic-gate ibcm_free_comid(hcap, local_comid);
12630Sstevel@tonic-gate }
12640Sstevel@tonic-gate
12650Sstevel@tonic-gate if (state_lookup_status == IBCM_LOOKUP_EXISTS) {
12660Sstevel@tonic-gate hrtime_t cur_time;
12670Sstevel@tonic-gate
12680Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
12690Sstevel@tonic-gate
12700Sstevel@tonic-gate /*
12710Sstevel@tonic-gate * There is an existing state structure entry
12720Sstevel@tonic-gate * with the same active comid
12730Sstevel@tonic-gate * Resending REP MAD is necessary only for REP/REJ/MRA Sent
12740Sstevel@tonic-gate * states
12750Sstevel@tonic-gate * Any other state implies the active has already received
12760Sstevel@tonic-gate * the REP/REJ response, and this REQ is an old MAD popping
12770Sstevel@tonic-gate * out of the fabric, hence no resend is required
12780Sstevel@tonic-gate */
12790Sstevel@tonic-gate cur_time = gethrtime();
12800Sstevel@tonic-gate
12810Sstevel@tonic-gate if ((remote_comid == statep->remote_comid) &&
12820Sstevel@tonic-gate (IBCM_OUT_HDRP(statep->stored_msg)->TransactionID ==
12830Sstevel@tonic-gate ((ib_mad_hdr_t *)(input_madp))->TransactionID) &&
12840Sstevel@tonic-gate (cur_time <= statep->stale_clock)) {
12850Sstevel@tonic-gate
12860Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_REQ);
12870Sstevel@tonic-gate
12880Sstevel@tonic-gate if (statep->state == IBCM_STATE_REP_SENT)
12890Sstevel@tonic-gate ibcm_resend_rep_mad(statep);
12900Sstevel@tonic-gate else if (statep->state == IBCM_STATE_REJ_SENT)
12910Sstevel@tonic-gate ibcm_resend_rej_mad(statep);
12920Sstevel@tonic-gate else if (statep->state == IBCM_STATE_MRA_SENT)
12930Sstevel@tonic-gate ibcm_resend_mra_mad(statep);
12940Sstevel@tonic-gate
12950Sstevel@tonic-gate /* decrementing ref cnt and returning from below */
12960Sstevel@tonic-gate
12970Sstevel@tonic-gate } else if ((statep->state == IBCM_STATE_REJ_SENT) &&
12980Sstevel@tonic-gate remote_comid != statep->remote_comid) {
12990Sstevel@tonic-gate timeout_id_t timer_val;
13000Sstevel@tonic-gate
13010Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_msg: "
13020Sstevel@tonic-gate "statep 0x%p being retired, REMOTE_QPN %x",
13030Sstevel@tonic-gate statep, remote_qpn);
13040Sstevel@tonic-gate /*
13050Sstevel@tonic-gate * OK, this is reuse of the QPN on the active side
13060Sstevel@tonic-gate * that was not connected last time. This REQ is
13070Sstevel@tonic-gate * considered NEW. We delete the statep here,
13080Sstevel@tonic-gate * then start over from the top.
13090Sstevel@tonic-gate */
13100Sstevel@tonic-gate statep->state = IBCM_STATE_DELETE;
13110Sstevel@tonic-gate timer_val = statep->timerid;
13120Sstevel@tonic-gate statep->timerid = 0;
13130Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
13140Sstevel@tonic-gate if (timer_val)
13150Sstevel@tonic-gate (void) untimeout(timer_val);
13160Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
13170Sstevel@tonic-gate ibcm_delete_state_data(statep);
13180Sstevel@tonic-gate goto new_req;
13190Sstevel@tonic-gate
13200Sstevel@tonic-gate /*
13210Sstevel@tonic-gate * The statep is stale in the following cases :-
13220Sstevel@tonic-gate * 1) if incoming REQ's comid's doesn't match with what is
13230Sstevel@tonic-gate * stored in statep
13240Sstevel@tonic-gate * 2) incoming REQ's local comid matches with statep's
13250Sstevel@tonic-gate * remote comid, but the REQ is for a new connection.
13260Sstevel@tonic-gate * This is verified that by comparing the current time
13270Sstevel@tonic-gate * with stale clock in statep
13280Sstevel@tonic-gate */
13290Sstevel@tonic-gate } else {
13300Sstevel@tonic-gate /* This is a stale connection on passive side */
13310Sstevel@tonic-gate
13320Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_STALE_DETECT);
13330Sstevel@tonic-gate
13340Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_msg: "
13350Sstevel@tonic-gate "stale detected statep %p state %x",
13360Sstevel@tonic-gate statep, statep->state);
13370Sstevel@tonic-gate
13380Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: "
13390Sstevel@tonic-gate "cur_time 0x%llX stale_clock 0x%llX", cur_time,
13400Sstevel@tonic-gate statep->stale_clock);
13410Sstevel@tonic-gate
13420Sstevel@tonic-gate if (statep->state == IBCM_STATE_ESTABLISHED) {
13430Sstevel@tonic-gate
13440Sstevel@tonic-gate statep->state = IBCM_STATE_TRANSIENT_DREQ_SENT;
13450Sstevel@tonic-gate statep->stale = B_TRUE;
13460Sstevel@tonic-gate
13470Sstevel@tonic-gate /* Cancel pending ibt_set_alt_path */
13480Sstevel@tonic-gate ibcm_sync_lapr_idle(statep);
13490Sstevel@tonic-gate /* The above call releases the state mutex */
13500Sstevel@tonic-gate
13510Sstevel@tonic-gate if (statep->dreq_msg == NULL)
13520Sstevel@tonic-gate (void) ibcm_alloc_out_msg(
13530Sstevel@tonic-gate statep->stored_reply_addr.ibmf_hdl,
13540Sstevel@tonic-gate &statep->dreq_msg, MAD_METHOD_SEND);
13550Sstevel@tonic-gate
13560Sstevel@tonic-gate /*
13570Sstevel@tonic-gate * Spec says, post DREQ MAD on the stale
13580Sstevel@tonic-gate * channel. This moves channel into timewait
13590Sstevel@tonic-gate */
13600Sstevel@tonic-gate if (statep->dreq_msg != NULL)
13610Sstevel@tonic-gate ibcm_post_dreq_mad(statep);
13620Sstevel@tonic-gate else {
13630Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
13640Sstevel@tonic-gate statep->state = IBCM_STATE_ESTABLISHED;
13650Sstevel@tonic-gate cv_broadcast(&statep->block_mad_cv);
13660Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
13670Sstevel@tonic-gate }
13680Sstevel@tonic-gate } else {
13690Sstevel@tonic-gate /*
13700Sstevel@tonic-gate * If not in established state, the CM
13710Sstevel@tonic-gate * protocol would timeout and delete the
13720Sstevel@tonic-gate * statep that is stale, eventually
13730Sstevel@tonic-gate */
13740Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
13750Sstevel@tonic-gate }
13760Sstevel@tonic-gate
13770Sstevel@tonic-gate /* Post a REJ MAD to the incoming REQ's sender */
13780Sstevel@tonic-gate ibcm_build_n_post_rej_mad(input_madp,
13790Sstevel@tonic-gate b2h32(req_msgp->req_local_comm_id),
13800Sstevel@tonic-gate cm_mad_addr, IBT_CM_FAILURE_REQ, IBT_CM_CONN_STALE);
13810Sstevel@tonic-gate
13820Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
13830Sstevel@tonic-gate }
13840Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep); /* decrement the ref count */
13850Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
13860Sstevel@tonic-gate }
13870Sstevel@tonic-gate }
13880Sstevel@tonic-gate
13890Sstevel@tonic-gate /*
13900Sstevel@tonic-gate * ibcm_handle_cep_req_response:
13910Sstevel@tonic-gate * Processes the response from ibcm_cep_state_req. Called holding a
13920Sstevel@tonic-gate * statep ref cnt. The statep ref cnt is decremented before returning.
13930Sstevel@tonic-gate */
13940Sstevel@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)13950Sstevel@tonic-gate ibcm_handle_cep_req_response(ibcm_state_data_t *statep, ibcm_status_t response,
13960Sstevel@tonic-gate ibt_cm_reason_t reject_reason, uint8_t arej_info_len)
13970Sstevel@tonic-gate {
13980Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
13990Sstevel@tonic-gate
14000Sstevel@tonic-gate if (response == IBCM_SEND_REP)
14010Sstevel@tonic-gate ibcm_post_rep_mad(statep);
14020Sstevel@tonic-gate else {
14030Sstevel@tonic-gate ASSERT(response == IBCM_SEND_REJ);
14040Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_handle_cep_req_response: statep %p"
1405401Shiremath " posting REJ reject_reason = %d", statep, reject_reason);
14060Sstevel@tonic-gate
14070Sstevel@tonic-gate ibcm_post_rej_mad(statep,
14080Sstevel@tonic-gate reject_reason, IBT_CM_FAILURE_REQ,
14090Sstevel@tonic-gate NULL, arej_info_len);
14100Sstevel@tonic-gate }
14110Sstevel@tonic-gate
14120Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*statep))
14130Sstevel@tonic-gate
14140Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
14150Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
14160Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
14170Sstevel@tonic-gate }
14180Sstevel@tonic-gate
14190Sstevel@tonic-gate
14200Sstevel@tonic-gate /*
14210Sstevel@tonic-gate * ibcm_process_rep_msg:
14220Sstevel@tonic-gate * ACTIVE SIDE CM
14230Sstevel@tonic-gate * Called from ibcm_process_incoming_mad on reception of a REP message
14240Sstevel@tonic-gate *
14250Sstevel@tonic-gate * INPUTS:
14260Sstevel@tonic-gate * hcap - HCA entry pointer
14270Sstevel@tonic-gate * input_madp - CM MAD that is input to this function
14280Sstevel@tonic-gate * cm_mad_addr - Address information for the MAD
14290Sstevel@tonic-gate *
14300Sstevel@tonic-gate * RETURN VALUE: NONE
14310Sstevel@tonic-gate */
14320Sstevel@tonic-gate void
ibcm_process_rep_msg(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)14330Sstevel@tonic-gate ibcm_process_rep_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
14340Sstevel@tonic-gate ibcm_mad_addr_t *cm_mad_addr)
14350Sstevel@tonic-gate {
14360Sstevel@tonic-gate ibt_priv_data_len_t arej_info_len = 0;
14370Sstevel@tonic-gate ib_com_id_t local_comid;
14380Sstevel@tonic-gate timeout_id_t timer_val;
14390Sstevel@tonic-gate ibcm_status_t lookup_status; /* state lookup status */
14400Sstevel@tonic-gate ibcm_status_t stale_lookup_status;
14410Sstevel@tonic-gate ibcm_status_t stale_comid_lookup_status;
14420Sstevel@tonic-gate ibcm_status_t response;
14430Sstevel@tonic-gate ibcm_rep_msg_t *rep_msgp; /* Response REP mesg */
14440Sstevel@tonic-gate ibt_cm_reason_t reject_reason;
14450Sstevel@tonic-gate ibcm_state_data_t *statep = NULL;
14460Sstevel@tonic-gate ibcm_state_data_t *stale_qpn = NULL;
14470Sstevel@tonic-gate ibcm_state_data_t *stale_comid = NULL;
14480Sstevel@tonic-gate ib_guid_t remote_ca_guid;
14490Sstevel@tonic-gate
14500Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_process_rep_msg:");
14510Sstevel@tonic-gate
14520Sstevel@tonic-gate /* Lookup for an existing state structure */
14530Sstevel@tonic-gate rep_msgp = (ibcm_rep_msg_t *)(&input_madp[IBCM_MAD_HDR_SIZE]);
14540Sstevel@tonic-gate
145511369SPramod.Gunjikar@Sun.COM IBCM_DUMP_RAW_MSG((uchar_t *)input_madp);
145611369SPramod.Gunjikar@Sun.COM
14570Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_process_rep_msg: active comid: %x",
14580Sstevel@tonic-gate rep_msgp->rep_remote_comm_id);
14590Sstevel@tonic-gate
14600Sstevel@tonic-gate local_comid = b2h32(rep_msgp->rep_remote_comm_id);
14610Sstevel@tonic-gate
14620Sstevel@tonic-gate /* lookup message holding a reader lock */
14630Sstevel@tonic-gate rw_enter(&hcap->hca_state_rwlock, RW_READER);
14640Sstevel@tonic-gate lookup_status = ibcm_lookup_msg(IBCM_INCOMING_REP, local_comid, 0, 0,
14650Sstevel@tonic-gate hcap, &statep);
14660Sstevel@tonic-gate rw_exit(&hcap->hca_state_rwlock);
14670Sstevel@tonic-gate
14680Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_rep_msg: lkup status %x, "
14690Sstevel@tonic-gate "statep 0x%p active comid %x", lookup_status, statep, local_comid);
14700Sstevel@tonic-gate
14710Sstevel@tonic-gate if (lookup_status == IBCM_LOOKUP_FAIL) {
14720Sstevel@tonic-gate ibcm_build_n_post_rej_mad(input_madp,
14730Sstevel@tonic-gate b2h32(rep_msgp->rep_local_comm_id), cm_mad_addr,
14740Sstevel@tonic-gate IBT_CM_FAILURE_REP, IBT_CM_INVALID_CID);
14750Sstevel@tonic-gate
14760Sstevel@tonic-gate return;
14770Sstevel@tonic-gate }
14780Sstevel@tonic-gate
14790Sstevel@tonic-gate /* if transaction id is not as expected, drop the REP mad */
14800Sstevel@tonic-gate if (IBCM_OUT_HDRP(statep->stored_msg)->TransactionID !=
14810Sstevel@tonic-gate ((ib_mad_hdr_t *)(input_madp))->TransactionID) {
14820Sstevel@tonic-gate
14830Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_process_rep_msg: statep 0x%p, "
14840Sstevel@tonic-gate "An REP MAD with tid expected 0x%llX tid found 0x%llX ",
14850Sstevel@tonic-gate statep,
14860Sstevel@tonic-gate b2h64(IBCM_OUT_HDRP(statep->stored_msg)->TransactionID),
14870Sstevel@tonic-gate b2h64(((ib_mad_hdr_t *)(input_madp))->TransactionID));
14880Sstevel@tonic-gate
14890Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
14900Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
14910Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
14920Sstevel@tonic-gate return;
14930Sstevel@tonic-gate }
14940Sstevel@tonic-gate
14950Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_REP);
14960Sstevel@tonic-gate
14970Sstevel@tonic-gate /* grab mutex first */
14980Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
14990Sstevel@tonic-gate
15000Sstevel@tonic-gate /*
15010Sstevel@tonic-gate * There is a state structure entry with active comid
15020Sstevel@tonic-gate * First, handle the re-send cases
15030Sstevel@tonic-gate * The resend routines below release the state mutex
15040Sstevel@tonic-gate */
1505557Shiremath if (statep->state == IBCM_STATE_ESTABLISHED ||
1506557Shiremath statep->state == IBCM_STATE_DREQ_SENT)
15070Sstevel@tonic-gate ibcm_resend_rtu_mad(statep);
15080Sstevel@tonic-gate else if (statep->state == IBCM_STATE_REJ_SENT)
15090Sstevel@tonic-gate ibcm_resend_rej_mad(statep);
15100Sstevel@tonic-gate else if (statep->state == IBCM_STATE_MRA_REP_SENT)
15110Sstevel@tonic-gate ibcm_resend_mra_mad(statep);
15120Sstevel@tonic-gate else if ((statep->state == IBCM_STATE_REQ_SENT) ||
15130Sstevel@tonic-gate (statep->state == IBCM_STATE_REP_WAIT)) {
15140Sstevel@tonic-gate
15150Sstevel@tonic-gate /* change state */
15160Sstevel@tonic-gate statep->state = IBCM_STATE_REP_RCVD;
15170Sstevel@tonic-gate statep->clnt_proceed = IBCM_BLOCK;
151811369SPramod.Gunjikar@Sun.COM statep->local_qp_rnr_cnt =
151911369SPramod.Gunjikar@Sun.COM rep_msgp->rep_rnr_retry_cnt_plus >> 5;
15200Sstevel@tonic-gate
15210Sstevel@tonic-gate /* cancel the REQ timer */
15220Sstevel@tonic-gate if (statep->timerid != 0) {
15230Sstevel@tonic-gate timer_val = statep->timerid;
15240Sstevel@tonic-gate statep->timerid = 0;
15250Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
15260Sstevel@tonic-gate (void) untimeout(timer_val);
15270Sstevel@tonic-gate } else {
15280Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
15290Sstevel@tonic-gate }
15300Sstevel@tonic-gate
15310Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
15320Sstevel@tonic-gate
15330Sstevel@tonic-gate /* Initialize the remote destination QPN for further MADs */
15340Sstevel@tonic-gate statep->stored_reply_addr.rcvd_addr.ia_remote_qno =
15350Sstevel@tonic-gate cm_mad_addr->rcvd_addr.ia_remote_qno;
15360Sstevel@tonic-gate statep->remote_qpn = b2h32(rep_msgp->rep_local_qpn_plus) >> 8;
15370Sstevel@tonic-gate statep->remote_comid = b2h32(rep_msgp->rep_local_comm_id);
15380Sstevel@tonic-gate bcopy(rep_msgp->rep_local_ca_guid, &remote_ca_guid,
15390Sstevel@tonic-gate sizeof (ib_guid_t));
15400Sstevel@tonic-gate statep->remote_hca_guid = b2h64(remote_ca_guid);
15410Sstevel@tonic-gate
15420Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_rep_msg: statep 0x%p "
15430Sstevel@tonic-gate "passive cid = %x passive qpn = %x", statep,
15440Sstevel@tonic-gate statep->remote_comid, statep->remote_qpn);
15450Sstevel@tonic-gate
15460Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_rep_msg: statep 0x%p "
15470Sstevel@tonic-gate "passive hcaguid = %llX", statep, statep->remote_hca_guid);
15480Sstevel@tonic-gate
15490Sstevel@tonic-gate stale_qpn = statep;
15500Sstevel@tonic-gate stale_comid = statep;
15510Sstevel@tonic-gate
15520Sstevel@tonic-gate /* Handle stale connection detection on active side */
15530Sstevel@tonic-gate rw_enter(&hcap->hca_state_rwlock, RW_WRITER);
15540Sstevel@tonic-gate
15550Sstevel@tonic-gate stale_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_REP_STALE,
15560Sstevel@tonic-gate 0, statep->remote_qpn, statep->remote_hca_guid, hcap,
15570Sstevel@tonic-gate &stale_qpn);
15580Sstevel@tonic-gate
15590Sstevel@tonic-gate stale_comid_lookup_status = ibcm_lookup_msg(
15600Sstevel@tonic-gate IBCM_INCOMING_REQ_STALE, statep->remote_comid, 0,
15610Sstevel@tonic-gate statep->remote_hca_guid, hcap, &stale_comid);
15620Sstevel@tonic-gate
15630Sstevel@tonic-gate rw_exit(&hcap->hca_state_rwlock);
15640Sstevel@tonic-gate
15650Sstevel@tonic-gate /*
15660Sstevel@tonic-gate * Check for other side reusing QPN that was attempted
15670Sstevel@tonic-gate * to be used, but somehow we sent a REJ.
15680Sstevel@tonic-gate */
15690Sstevel@tonic-gate mutex_enter(&stale_qpn->state_mutex);
15700Sstevel@tonic-gate if ((stale_lookup_status == IBCM_LOOKUP_EXISTS) &&
15710Sstevel@tonic-gate (stale_comid_lookup_status != IBCM_LOOKUP_EXISTS) &&
15720Sstevel@tonic-gate (stale_qpn->state == IBCM_STATE_REJ_SENT)) {
15730Sstevel@tonic-gate
15740Sstevel@tonic-gate timeout_id_t timer_val;
15750Sstevel@tonic-gate
15760Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_process_rep_msg: "
15770Sstevel@tonic-gate "statep 0x%p being retired, REMOTE_QPN %x",
15780Sstevel@tonic-gate stale_qpn, statep->remote_qpn);
15790Sstevel@tonic-gate /*
15800Sstevel@tonic-gate * OK, this is reuse of the QPN on the active side
15810Sstevel@tonic-gate * that was not connected last time. This REQ is
15820Sstevel@tonic-gate * considered NEW. We delete the statep here,
15830Sstevel@tonic-gate * then start over from the top.
15840Sstevel@tonic-gate */
15850Sstevel@tonic-gate stale_qpn->state = IBCM_STATE_DELETE;
15860Sstevel@tonic-gate timer_val = stale_qpn->timerid;
15870Sstevel@tonic-gate stale_qpn->timerid = 0;
15880Sstevel@tonic-gate mutex_exit(&stale_qpn->state_mutex);
15890Sstevel@tonic-gate if (timer_val)
15900Sstevel@tonic-gate (void) untimeout(timer_val);
15910Sstevel@tonic-gate IBCM_REF_CNT_DECR(stale_qpn);
15920Sstevel@tonic-gate ibcm_delete_state_data(stale_qpn);
15930Sstevel@tonic-gate stale_qpn = statep;
15940Sstevel@tonic-gate rw_enter(&hcap->hca_state_rwlock, RW_WRITER);
15950Sstevel@tonic-gate stale_lookup_status = ibcm_lookup_msg(
15960Sstevel@tonic-gate IBCM_INCOMING_REP_STALE, 0, statep->remote_qpn,
15970Sstevel@tonic-gate statep->remote_hca_guid, hcap, &stale_qpn);
15980Sstevel@tonic-gate rw_exit(&hcap->hca_state_rwlock);
15990Sstevel@tonic-gate /* OK to continue now */
16000Sstevel@tonic-gate } else
16010Sstevel@tonic-gate mutex_exit(&stale_qpn->state_mutex);
16020Sstevel@tonic-gate
16030Sstevel@tonic-gate /*
16040Sstevel@tonic-gate * lookup exists implies that there is already an entry with
16050Sstevel@tonic-gate * the remote qpn/comid and remote hca guid
16060Sstevel@tonic-gate */
16070Sstevel@tonic-gate if ((stale_lookup_status == IBCM_LOOKUP_EXISTS) ||
16080Sstevel@tonic-gate (stale_comid_lookup_status == IBCM_LOOKUP_EXISTS)) {
16090Sstevel@tonic-gate
16100Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_rep_msg: "
16110Sstevel@tonic-gate "statep 0x%p stale detected "
16120Sstevel@tonic-gate "qpn_lkup %d comid_lkup %d", statep,
16130Sstevel@tonic-gate stale_lookup_status, stale_comid_lookup_status);
16140Sstevel@tonic-gate
16150Sstevel@tonic-gate /* Disassociate statep and QP */
16160Sstevel@tonic-gate IBCM_SET_CHAN_PRIVATE(statep->channel, NULL);
16170Sstevel@tonic-gate
16180Sstevel@tonic-gate if (stale_lookup_status == IBCM_LOOKUP_EXISTS)
16190Sstevel@tonic-gate reject_reason = IBT_CM_CONN_STALE;
16200Sstevel@tonic-gate else
16210Sstevel@tonic-gate reject_reason = IBT_CM_DUP_COM_ID;
16220Sstevel@tonic-gate
16230Sstevel@tonic-gate ibcm_handler_conn_fail(statep,
16240Sstevel@tonic-gate IBT_CM_FAILURE_REJ_SENT, IBT_CM_FAILURE_REP,
16250Sstevel@tonic-gate reject_reason,
16260Sstevel@tonic-gate IBCM_REJ_PRIV(statep->stored_msg),
16270Sstevel@tonic-gate IBT_REJ_PRIV_DATA_SZ);
16280Sstevel@tonic-gate
16290Sstevel@tonic-gate /* Send a REJ with stale reason for statep */
16300Sstevel@tonic-gate ibcm_post_rej_mad(statep, reject_reason,
16310Sstevel@tonic-gate IBT_CM_FAILURE_REP, NULL, 0);
16320Sstevel@tonic-gate
16330Sstevel@tonic-gate /* Now let's handle the logic for stale connections */
16340Sstevel@tonic-gate /* If in established state, stale_statep is stale */
16350Sstevel@tonic-gate if (stale_lookup_status == IBCM_LOOKUP_EXISTS) {
16360Sstevel@tonic-gate
16370Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_rep_msg: "
16380Sstevel@tonic-gate "state_qpn 0x%p stale QPN detected "
16390Sstevel@tonic-gate "state %X", stale_qpn, stale_qpn->state);
16400Sstevel@tonic-gate
16410Sstevel@tonic-gate ibcm_insert_trace(stale_qpn,
16420Sstevel@tonic-gate IBCM_TRACE_STALE_DETECT);
16430Sstevel@tonic-gate
16440Sstevel@tonic-gate mutex_enter(&stale_qpn->state_mutex);
16450Sstevel@tonic-gate if (stale_qpn->state ==
16460Sstevel@tonic-gate IBCM_STATE_ESTABLISHED) {
16470Sstevel@tonic-gate /* change state to DREQ sent */
16480Sstevel@tonic-gate stale_qpn->state =
16490Sstevel@tonic-gate IBCM_STATE_TRANSIENT_DREQ_SENT;
16500Sstevel@tonic-gate stale_qpn->stale = B_TRUE;
16510Sstevel@tonic-gate
16520Sstevel@tonic-gate /* wait for/cancel pending LAP/APR */
16530Sstevel@tonic-gate ibcm_sync_lapr_idle(stale_qpn);
16540Sstevel@tonic-gate /* above call releases state mutex */
16550Sstevel@tonic-gate
16560Sstevel@tonic-gate if (stale_qpn->dreq_msg == NULL)
16570Sstevel@tonic-gate (void) ibcm_alloc_out_msg(
16580Sstevel@tonic-gate stale_qpn->
16590Sstevel@tonic-gate stored_reply_addr.ibmf_hdl,
16600Sstevel@tonic-gate &stale_qpn->dreq_msg,
16610Sstevel@tonic-gate MAD_METHOD_SEND);
16620Sstevel@tonic-gate
16630Sstevel@tonic-gate if (stale_qpn->dreq_msg != NULL) {
16640Sstevel@tonic-gate ibcm_post_dreq_mad(stale_qpn);
16650Sstevel@tonic-gate mutex_enter(
16660Sstevel@tonic-gate &stale_qpn->state_mutex);
16670Sstevel@tonic-gate } else {
16680Sstevel@tonic-gate mutex_enter(
16690Sstevel@tonic-gate &stale_qpn->state_mutex);
16700Sstevel@tonic-gate stale_qpn->state =
16710Sstevel@tonic-gate IBCM_STATE_ESTABLISHED;
16720Sstevel@tonic-gate cv_broadcast(
16730Sstevel@tonic-gate &stale_qpn->block_mad_cv);
16740Sstevel@tonic-gate }
16750Sstevel@tonic-gate }
16760Sstevel@tonic-gate IBCM_REF_CNT_DECR(stale_qpn);
16770Sstevel@tonic-gate mutex_exit(&stale_qpn->state_mutex);
16780Sstevel@tonic-gate }
16790Sstevel@tonic-gate
16800Sstevel@tonic-gate if (stale_comid_lookup_status == IBCM_LOOKUP_EXISTS) {
16810Sstevel@tonic-gate
16820Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_rep_msg: "
16830Sstevel@tonic-gate "state_comid 0x%p stale COMID detected "
16840Sstevel@tonic-gate "state %X", stale_comid,
16850Sstevel@tonic-gate stale_comid->state);
16860Sstevel@tonic-gate
16870Sstevel@tonic-gate mutex_enter(&stale_comid->state_mutex);
16880Sstevel@tonic-gate if (!((stale_lookup_status ==
16890Sstevel@tonic-gate IBCM_LOOKUP_EXISTS) &&
16900Sstevel@tonic-gate (stale_qpn == stale_comid)) &&
16910Sstevel@tonic-gate (stale_comid->state ==
16920Sstevel@tonic-gate IBCM_STATE_ESTABLISHED)) {
16930Sstevel@tonic-gate
16940Sstevel@tonic-gate ibcm_insert_trace(stale_comid,
16950Sstevel@tonic-gate IBCM_TRACE_STALE_DETECT);
16960Sstevel@tonic-gate
16970Sstevel@tonic-gate /* change state to DREQ sent */
16980Sstevel@tonic-gate stale_comid->state =
16990Sstevel@tonic-gate IBCM_STATE_TRANSIENT_DREQ_SENT;
17000Sstevel@tonic-gate stale_comid->stale = B_TRUE;
17010Sstevel@tonic-gate
17020Sstevel@tonic-gate /* wait for/cancel pending LAP/APR */
17030Sstevel@tonic-gate ibcm_sync_lapr_idle(stale_comid);
17040Sstevel@tonic-gate
17050Sstevel@tonic-gate /* above call releases state mutex */
17060Sstevel@tonic-gate
17070Sstevel@tonic-gate if (stale_comid->dreq_msg == NULL)
17080Sstevel@tonic-gate (void) ibcm_alloc_out_msg(
17090Sstevel@tonic-gate stale_comid->
17100Sstevel@tonic-gate stored_reply_addr.ibmf_hdl,
17110Sstevel@tonic-gate &stale_comid->dreq_msg,
17120Sstevel@tonic-gate MAD_METHOD_SEND);
17130Sstevel@tonic-gate
17140Sstevel@tonic-gate if (stale_comid->dreq_msg != NULL) {
17150Sstevel@tonic-gate ibcm_post_dreq_mad(stale_comid);
17160Sstevel@tonic-gate mutex_enter(
17170Sstevel@tonic-gate &stale_comid->state_mutex);
17180Sstevel@tonic-gate } else {
17190Sstevel@tonic-gate mutex_enter(
17200Sstevel@tonic-gate &stale_comid->state_mutex);
17210Sstevel@tonic-gate stale_comid->state =
17220Sstevel@tonic-gate IBCM_STATE_ESTABLISHED;
17230Sstevel@tonic-gate cv_broadcast(
17240Sstevel@tonic-gate &stale_comid->block_mad_cv);
17250Sstevel@tonic-gate }
17260Sstevel@tonic-gate }
17270Sstevel@tonic-gate IBCM_REF_CNT_DECR(stale_comid);
17280Sstevel@tonic-gate mutex_exit(&stale_comid->state_mutex);
17290Sstevel@tonic-gate }
17300Sstevel@tonic-gate ibcm_return_open_data(statep, rep_msgp, reject_reason);
17310Sstevel@tonic-gate return;
17320Sstevel@tonic-gate }
17330Sstevel@tonic-gate
17340Sstevel@tonic-gate /*
17350Sstevel@tonic-gate * No need to handle out of memory conditions as we called
17360Sstevel@tonic-gate * ibcm_lookup_msg() with IBT_CHAN_BLOCKING flags.
17370Sstevel@tonic-gate */
17380Sstevel@tonic-gate ASSERT(stale_lookup_status == IBCM_LOOKUP_NEW);
17390Sstevel@tonic-gate
17400Sstevel@tonic-gate /* Initialize the remote ack delay */
17410Sstevel@tonic-gate statep->remote_ack_delay =
17420Sstevel@tonic-gate ibt_ib2usec(rep_msgp->rep_target_delay_plus >> 3);
17430Sstevel@tonic-gate
17440Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_rep_msg: statep 0x%p"
17450Sstevel@tonic-gate " passive hca_ack_delay= %x ", statep,
17460Sstevel@tonic-gate statep->remote_ack_delay);
17470Sstevel@tonic-gate
17480Sstevel@tonic-gate response = ibcm_cep_state_rep(statep, rep_msgp,
17490Sstevel@tonic-gate &reject_reason, &arej_info_len);
17500Sstevel@tonic-gate
17510Sstevel@tonic-gate if (response == IBCM_DEFER) {
17520Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_rep_msg: "
17530Sstevel@tonic-gate "statep 0x%p client returned DEFER response",
17540Sstevel@tonic-gate statep);
17550Sstevel@tonic-gate return;
17560Sstevel@tonic-gate }
17570Sstevel@tonic-gate ibcm_handle_cep_rep_response(statep, response,
17580Sstevel@tonic-gate reject_reason, arej_info_len, rep_msgp);
17590Sstevel@tonic-gate
17600Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*statep))
17610Sstevel@tonic-gate
17620Sstevel@tonic-gate return;
17630Sstevel@tonic-gate
17640Sstevel@tonic-gate } else if (statep->state == IBCM_STATE_DELETE) {
17650Sstevel@tonic-gate
17660Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
17670Sstevel@tonic-gate ibcm_build_n_post_rej_mad(input_madp,
17680Sstevel@tonic-gate b2h32(rep_msgp->rep_local_comm_id), cm_mad_addr,
17690Sstevel@tonic-gate IBT_CM_FAILURE_REP, IBT_CM_INVALID_CID);
17700Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
17710Sstevel@tonic-gate } else {
17720Sstevel@tonic-gate
17730Sstevel@tonic-gate #ifdef DEBUG
17740Sstevel@tonic-gate if (ibcm_test_mode > 0)
17750Sstevel@tonic-gate if (statep->state == IBCM_STATE_REP_RCVD)
17760Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_rep_msg: "
17770Sstevel@tonic-gate "REP re-send from passive for statep 0x%p"
17780Sstevel@tonic-gate " in state %d", statep, statep->state);
17790Sstevel@tonic-gate else
17800Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_rep_msg: "
17810Sstevel@tonic-gate "Unexpected REP for statep 0x%p in "
17820Sstevel@tonic-gate "state %d", statep, statep->state);
17830Sstevel@tonic-gate #endif
17840Sstevel@tonic-gate }
17850Sstevel@tonic-gate /* decrement ref count and return for LOOKUP_EXISTS */
17860Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
17870Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
17880Sstevel@tonic-gate
17890Sstevel@tonic-gate }
17900Sstevel@tonic-gate
17910Sstevel@tonic-gate /*
17920Sstevel@tonic-gate * ibcm_handle_cep_req_response:
17930Sstevel@tonic-gate * Processes the response from ibcm_cep_state_rep. Called holding a
17940Sstevel@tonic-gate * statep ref cnt. The statep ref cnt is decremented before returning.
17950Sstevel@tonic-gate */
17960Sstevel@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)17970Sstevel@tonic-gate ibcm_handle_cep_rep_response(ibcm_state_data_t *statep, ibcm_status_t response,
17980Sstevel@tonic-gate ibt_cm_reason_t reject_reason, uint8_t arej_info_len,
17990Sstevel@tonic-gate ibcm_rep_msg_t *rep_msgp)
18000Sstevel@tonic-gate {
18010Sstevel@tonic-gate /* wait until the send completion callback is invoked for REQ post */
18020Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
18030Sstevel@tonic-gate while (statep->send_mad_flags & IBCM_REQ_POST_BUSY)
18040Sstevel@tonic-gate cv_wait(&statep->block_mad_cv, &statep->state_mutex);
18050Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
18060Sstevel@tonic-gate
18070Sstevel@tonic-gate if (response == IBCM_SEND_RTU) {
18080Sstevel@tonic-gate /* if connection aborted, return */
18090Sstevel@tonic-gate if (ibcm_post_rtu_mad(statep) != IBCM_SUCCESS) {
18100Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
18110Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
18120Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
18130Sstevel@tonic-gate return;
18140Sstevel@tonic-gate }
18150Sstevel@tonic-gate
18160Sstevel@tonic-gate /*
18170Sstevel@tonic-gate * Call client handler with cm event IBT_CM_EVENT_CONN_EST to
18180Sstevel@tonic-gate * indicate RTU posted
18190Sstevel@tonic-gate */
18200Sstevel@tonic-gate ibcm_cep_send_rtu(statep);
18210Sstevel@tonic-gate } else {
1822557Shiremath IBTF_DPRINTF_L4(cmlog, "ibcm_handle_cep_rep_response: statep %p"
1823401Shiremath " posting REJ reject_reason = %d", statep, reject_reason);
18240Sstevel@tonic-gate
18250Sstevel@tonic-gate ASSERT(response == IBCM_SEND_REJ);
18260Sstevel@tonic-gate ibcm_post_rej_mad(statep, reject_reason, IBT_CM_FAILURE_REP,
18270Sstevel@tonic-gate NULL, arej_info_len);
18280Sstevel@tonic-gate }
18290Sstevel@tonic-gate
18300Sstevel@tonic-gate ibcm_return_open_data(statep, rep_msgp, reject_reason);
18310Sstevel@tonic-gate }
18320Sstevel@tonic-gate
18330Sstevel@tonic-gate /*
18340Sstevel@tonic-gate * ibcm_return_open_data:
18350Sstevel@tonic-gate * Initializes the ibt_open_rc_channel return data. The statep ref cnt is
18360Sstevel@tonic-gate * decremented before returning.
18370Sstevel@tonic-gate */
18380Sstevel@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)18390Sstevel@tonic-gate ibcm_return_open_data(ibcm_state_data_t *statep, ibcm_rep_msg_t *rep_msgp,
18400Sstevel@tonic-gate ibt_cm_reason_t reject_reason)
18410Sstevel@tonic-gate {
18420Sstevel@tonic-gate /* signal waiting CV - blocking in ibt_open_channel() */
18430Sstevel@tonic-gate if (statep->open_return_data != NULL) {
18440Sstevel@tonic-gate if (statep->open_return_data->rc_priv_data_len > 0)
18450Sstevel@tonic-gate bcopy(rep_msgp->rep_private_data,
18460Sstevel@tonic-gate statep->open_return_data->rc_priv_data,
18470Sstevel@tonic-gate statep->open_return_data->rc_priv_data_len);
18480Sstevel@tonic-gate statep->open_return_data->rc_rdma_ra_in =
18496709Shiremath rep_msgp->rep_initiator_depth;
18500Sstevel@tonic-gate statep->open_return_data->rc_rdma_ra_out =
18516709Shiremath rep_msgp->rep_resp_resources;
18520Sstevel@tonic-gate statep->open_return_data->rc_failover_status =
18534703Shiremath rep_msgp->rep_target_delay_plus >> 1 & 3;
18540Sstevel@tonic-gate statep->open_return_data->rc_status = reject_reason;
18550Sstevel@tonic-gate
18560Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
18570Sstevel@tonic-gate statep->open_done = B_TRUE;
18580Sstevel@tonic-gate cv_broadcast(&statep->block_client_cv);
18590Sstevel@tonic-gate } else mutex_enter(&statep->state_mutex);
18600Sstevel@tonic-gate
18610Sstevel@tonic-gate /* decrement ref count and return for LOOKUP_EXISTS */
18620Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
18630Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
18640Sstevel@tonic-gate }
18650Sstevel@tonic-gate
18660Sstevel@tonic-gate
18670Sstevel@tonic-gate /*
18680Sstevel@tonic-gate * ibcm_process_mra_msg:
18690Sstevel@tonic-gate * Called from ibcm_process_incoming_mad on reception of a MRA message
18700Sstevel@tonic-gate *
18710Sstevel@tonic-gate * Cancels existing timer, and sets a new timer based on timeout
18720Sstevel@tonic-gate * value from MRA message. The remaining retry count of statep is
18730Sstevel@tonic-gate * not changed, and timer value for the remaining retry timers is
18740Sstevel@tonic-gate * also not changed
18750Sstevel@tonic-gate *
18760Sstevel@tonic-gate * INPUTS:
18770Sstevel@tonic-gate * hcap - HCA entry pointer
18780Sstevel@tonic-gate * input_madp - CM MAD that is input to this function
18790Sstevel@tonic-gate * cm_mad_addr - Address information for the MAD
18800Sstevel@tonic-gate *
18810Sstevel@tonic-gate * RETURN VALUE: NONE
18820Sstevel@tonic-gate */
18830Sstevel@tonic-gate void
ibcm_process_mra_msg(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)18840Sstevel@tonic-gate ibcm_process_mra_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
18850Sstevel@tonic-gate ibcm_mad_addr_t *cm_mad_addr)
18860Sstevel@tonic-gate {
18870Sstevel@tonic-gate ibcm_status_t state_lookup_status;
18884703Shiremath ibcm_mra_msg_t *mra_msgp =
18894703Shiremath (ibcm_mra_msg_t *)(&input_madp[IBCM_MAD_HDR_SIZE]);
18900Sstevel@tonic-gate ibcm_state_data_t *statep = NULL;
18910Sstevel@tonic-gate uint8_t mra_msg;
18920Sstevel@tonic-gate
18930Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_mra_msg:");
18940Sstevel@tonic-gate
18950Sstevel@tonic-gate /* Lookup for an existing state structure (as a READER) */
18960Sstevel@tonic-gate rw_enter(&hcap->hca_state_rwlock, RW_READER);
18970Sstevel@tonic-gate state_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_MRA,
18980Sstevel@tonic-gate b2h32(mra_msgp->mra_remote_comm_id), 0, 0, hcap, &statep);
18990Sstevel@tonic-gate rw_exit(&hcap->hca_state_rwlock);
19000Sstevel@tonic-gate
19010Sstevel@tonic-gate /* if state doesn't exist just return */
19020Sstevel@tonic-gate if (state_lookup_status != IBCM_LOOKUP_EXISTS) {
19030Sstevel@tonic-gate ibcm_build_n_post_rej_mad(input_madp,
19040Sstevel@tonic-gate b2h32(mra_msgp->mra_local_comm_id), cm_mad_addr,
19050Sstevel@tonic-gate IBT_CM_FAILURE_UNKNOWN, IBT_CM_INVALID_CID);
19060Sstevel@tonic-gate return;
19070Sstevel@tonic-gate }
19080Sstevel@tonic-gate
19090Sstevel@tonic-gate if (IBCM_OUT_HDRP(statep->stored_msg)->TransactionID !=
19100Sstevel@tonic-gate ((ib_mad_hdr_t *)(input_madp))->TransactionID) {
19110Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
19120Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
19130Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
1914557Shiremath IBTF_DPRINTF_L3(cmlog, "ibcm_process_mra_msg: statep 0x%p "
19150Sstevel@tonic-gate "MRA MAD with tid expected 0x%llX tid found 0x%llX "
19160Sstevel@tonic-gate "com id 0x%x arrived", statep,
19170Sstevel@tonic-gate b2h64(IBCM_OUT_HDRP(statep->stored_msg)->TransactionID),
19180Sstevel@tonic-gate b2h64(((ib_mad_hdr_t *)(input_madp))->TransactionID),
19190Sstevel@tonic-gate b2h32(mra_msgp->mra_local_comm_id));
19200Sstevel@tonic-gate return;
19210Sstevel@tonic-gate }
19220Sstevel@tonic-gate
19230Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_MRA);
19240Sstevel@tonic-gate
19250Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
19260Sstevel@tonic-gate
19270Sstevel@tonic-gate /*
19280Sstevel@tonic-gate * Only allow for REQ/REP "mra_msg_typ" ONLY
19290Sstevel@tonic-gate * (to validate MRA message received)?
19300Sstevel@tonic-gate */
19310Sstevel@tonic-gate mra_msg = mra_msgp->mra_message_type_plus >> 6;
19320Sstevel@tonic-gate if ((mra_msg != IBT_CM_MRA_TYPE_REQ) &&
19330Sstevel@tonic-gate (mra_msg != IBT_CM_MRA_TYPE_REP) &&
19340Sstevel@tonic-gate (mra_msg != IBT_CM_MRA_TYPE_LAP)) {
19350Sstevel@tonic-gate
19360Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_mra_msg: statep 0x%p "
19370Sstevel@tonic-gate "Unexpected MRA MSG Type %x", statep, mra_msg);
19380Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
19390Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
19400Sstevel@tonic-gate return;
19410Sstevel@tonic-gate }
19420Sstevel@tonic-gate
19430Sstevel@tonic-gate if ((statep->state == IBCM_STATE_REQ_SENT) ||
19440Sstevel@tonic-gate (statep->state == IBCM_STATE_REP_SENT) ||
19450Sstevel@tonic-gate ((statep->state == IBCM_STATE_ESTABLISHED) &&
19460Sstevel@tonic-gate (statep->ap_state == IBCM_AP_STATE_LAP_SENT))) {
19470Sstevel@tonic-gate timeout_id_t timer_val = statep->timerid;
19483241Shiremath clock_t service_timeout;
19490Sstevel@tonic-gate
19500Sstevel@tonic-gate if (statep->state == IBCM_STATE_REQ_SENT) {
19510Sstevel@tonic-gate mra_msg = IBT_CM_MRA_TYPE_REQ;
19520Sstevel@tonic-gate statep->state = IBCM_STATE_REP_WAIT;
19530Sstevel@tonic-gate } else if (statep->state == IBCM_STATE_REP_SENT) {
19540Sstevel@tonic-gate mra_msg = IBT_CM_MRA_TYPE_REP;
19550Sstevel@tonic-gate statep->state = IBCM_STATE_MRA_REP_RCVD;
19560Sstevel@tonic-gate } else { /* statep->state == IBCM_STATE_LAP_SENT */
19570Sstevel@tonic-gate mra_msg = IBT_CM_MRA_TYPE_LAP;
19580Sstevel@tonic-gate statep->ap_state = IBCM_AP_STATE_MRA_LAP_RCVD;
19590Sstevel@tonic-gate }
19600Sstevel@tonic-gate
19610Sstevel@tonic-gate /* cancel the timer */
19620Sstevel@tonic-gate statep->timerid = 0;
19630Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
19640Sstevel@tonic-gate
19650Sstevel@tonic-gate (void) untimeout(timer_val);
19660Sstevel@tonic-gate
19673241Shiremath service_timeout =
19683241Shiremath ibt_ib2usec(mra_msgp->mra_service_timeout_plus >> 3);
19693241Shiremath
19703241Shiremath /*
19713241Shiremath * If tunable MAX MRA Service Timeout parameter is set, then
19723241Shiremath * verify whether the requested timer value exceeds the MAX
19733241Shiremath * value and reset the timer value to the MAX value.
19743241Shiremath */
19753241Shiremath if (ibcm_mra_service_timeout_max &&
19763241Shiremath ibcm_mra_service_timeout_max < service_timeout) {
19773241Shiremath IBTF_DPRINTF_L2(cmlog, "ibcm_process_mra_msg: "
19783241Shiremath "Unexpected MRA Service Timeout value (%ld), Max "
19793241Shiremath "allowed is (%ld)", service_timeout,
19803241Shiremath ibcm_mra_service_timeout_max);
19813241Shiremath service_timeout = ibcm_mra_service_timeout_max;
19823241Shiremath }
19833241Shiremath
19840Sstevel@tonic-gate /*
19850Sstevel@tonic-gate * Invoke client handler to pass the MRA private data
19860Sstevel@tonic-gate */
19870Sstevel@tonic-gate if (statep->cm_handler != NULL) {
19880Sstevel@tonic-gate ibt_cm_event_t event;
19890Sstevel@tonic-gate
19900Sstevel@tonic-gate bzero(&event, sizeof (event));
19910Sstevel@tonic-gate
19920Sstevel@tonic-gate event.cm_type = IBT_CM_EVENT_MRA_RCV;
19930Sstevel@tonic-gate event.cm_channel = statep->channel;
19940Sstevel@tonic-gate event.cm_session_id = NULL;
19950Sstevel@tonic-gate event.cm_priv_data = mra_msgp->mra_private_data;
19960Sstevel@tonic-gate event.cm_priv_data_len = IBT_MRA_PRIV_DATA_SZ;
19970Sstevel@tonic-gate
19980Sstevel@tonic-gate event.cm_event.mra.mra_msg_type = mra_msg;
19990Sstevel@tonic-gate
20003241Shiremath event.cm_event.mra.mra_service_time = service_timeout;
20010Sstevel@tonic-gate
20020Sstevel@tonic-gate /* Client cannot return private data */
20030Sstevel@tonic-gate (void) statep->cm_handler(statep->state_cm_private,
20040Sstevel@tonic-gate &event, NULL, NULL, 0);
20050Sstevel@tonic-gate }
20060Sstevel@tonic-gate
20070Sstevel@tonic-gate /*
20080Sstevel@tonic-gate * Must re-check state, as an RTU could have come
20090Sstevel@tonic-gate * after the above mutex_exit and mutex_enter below
20100Sstevel@tonic-gate */
20110Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
20120Sstevel@tonic-gate if ((statep->state == IBCM_STATE_REP_WAIT) ||
20130Sstevel@tonic-gate (statep->state == IBCM_STATE_MRA_REP_RCVD) ||
20140Sstevel@tonic-gate (statep->ap_state == IBCM_AP_STATE_MRA_LAP_RCVD)) {
20150Sstevel@tonic-gate
20160Sstevel@tonic-gate statep->remaining_retry_cnt = statep->max_cm_retries;
20170Sstevel@tonic-gate
20180Sstevel@tonic-gate /*
20190Sstevel@tonic-gate * The timeout interval is changed only for the first
20200Sstevel@tonic-gate * retry. The later retries use the timeout from
20210Sstevel@tonic-gate * statep->timer_value
20220Sstevel@tonic-gate */
20230Sstevel@tonic-gate statep->timer_stored_state = statep->state;
2024401Shiremath statep->timer_value = statep->pkt_life_time +
20253241Shiremath service_timeout;
2026401Shiremath statep->timerid = IBCM_TIMEOUT(statep,
2027401Shiremath statep->timer_value);
20280Sstevel@tonic-gate }
20290Sstevel@tonic-gate
20300Sstevel@tonic-gate } else if (statep->state == IBCM_STATE_DELETE) {
20310Sstevel@tonic-gate
20320Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
20330Sstevel@tonic-gate ibcm_build_n_post_rej_mad(input_madp,
20340Sstevel@tonic-gate b2h32(mra_msgp->mra_local_comm_id), cm_mad_addr,
20350Sstevel@tonic-gate IBT_CM_FAILURE_UNKNOWN, IBT_CM_INVALID_CID);
20360Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
20370Sstevel@tonic-gate } else {
20380Sstevel@tonic-gate
20390Sstevel@tonic-gate #ifdef DEBUG
20400Sstevel@tonic-gate if (ibcm_test_mode > 0)
20410Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_mra_msg: "
20420Sstevel@tonic-gate "Unexpected mra for statep 0x%p in state %d",
20430Sstevel@tonic-gate statep, statep->state);
20440Sstevel@tonic-gate #endif
20450Sstevel@tonic-gate }
20460Sstevel@tonic-gate
20470Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
20480Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
20490Sstevel@tonic-gate }
20500Sstevel@tonic-gate
20510Sstevel@tonic-gate
20520Sstevel@tonic-gate /*
20530Sstevel@tonic-gate * ibcm_process_rtu_msg:
20540Sstevel@tonic-gate * Called from ibcm_process_incoming_mad on reception of a RTU message
20550Sstevel@tonic-gate *
20560Sstevel@tonic-gate * Changes connection state to established if in REP SENT state
20570Sstevel@tonic-gate *
20580Sstevel@tonic-gate * INPUTS:
20590Sstevel@tonic-gate * hcap - HCA entry pointer
20600Sstevel@tonic-gate * input_madp - CM MAD that is input to this function
20610Sstevel@tonic-gate * cm_mad_addr - Address information for the MAD
20620Sstevel@tonic-gate *
20630Sstevel@tonic-gate * RETURN VALUE: NONE
20640Sstevel@tonic-gate */
20650Sstevel@tonic-gate void
ibcm_process_rtu_msg(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)20660Sstevel@tonic-gate ibcm_process_rtu_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
20670Sstevel@tonic-gate ibcm_mad_addr_t *cm_mad_addr)
20680Sstevel@tonic-gate {
20690Sstevel@tonic-gate timeout_id_t timer_val;
20700Sstevel@tonic-gate ibcm_status_t status;
20714703Shiremath ibcm_rtu_msg_t *rtu_msg =
20724703Shiremath (ibcm_rtu_msg_t *)(&input_madp[IBCM_MAD_HDR_SIZE]);
20730Sstevel@tonic-gate ibcm_state_data_t *statep = NULL;
20740Sstevel@tonic-gate
20750Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_rtu_msg:");
20760Sstevel@tonic-gate
20770Sstevel@tonic-gate /* Lookup for an existing state structure - using a reader lock */
20780Sstevel@tonic-gate rw_enter(&hcap->hca_state_rwlock, RW_READER);
20790Sstevel@tonic-gate status = ibcm_lookup_msg(IBCM_INCOMING_RTU,
20800Sstevel@tonic-gate b2h32(rtu_msg->rtu_remote_comm_id), 0, 0, hcap, &statep);
20810Sstevel@tonic-gate rw_exit(&hcap->hca_state_rwlock);
20820Sstevel@tonic-gate
20830Sstevel@tonic-gate /* if state doesn't exist just return */
20840Sstevel@tonic-gate if (status != IBCM_LOOKUP_EXISTS) {
20850Sstevel@tonic-gate ibcm_build_n_post_rej_mad(input_madp,
20860Sstevel@tonic-gate b2h32(rtu_msg->rtu_local_comm_id), cm_mad_addr,
20870Sstevel@tonic-gate IBT_CM_FAILURE_UNKNOWN, IBT_CM_INVALID_CID);
20880Sstevel@tonic-gate return;
20890Sstevel@tonic-gate }
20900Sstevel@tonic-gate
20910Sstevel@tonic-gate if (IBCM_OUT_HDRP(statep->stored_msg)->TransactionID !=
20920Sstevel@tonic-gate ((ib_mad_hdr_t *)(input_madp))->TransactionID) {
20930Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
20940Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
20950Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
2096557Shiremath IBTF_DPRINTF_L3(cmlog, "ibcm_process_rtu_msg: statep 0x%p "
20970Sstevel@tonic-gate "An RTU MAD with tid expected 0x%llX tid found 0x%llX "
20980Sstevel@tonic-gate "com id 0x%x arrived", statep,
20990Sstevel@tonic-gate b2h64(IBCM_OUT_HDRP(statep->stored_msg)->TransactionID),
21000Sstevel@tonic-gate b2h64(((ib_mad_hdr_t *)(input_madp))->TransactionID),
21010Sstevel@tonic-gate b2h32(rtu_msg->rtu_remote_comm_id));
21020Sstevel@tonic-gate return;
21030Sstevel@tonic-gate }
21040Sstevel@tonic-gate
21050Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_RTU);
21060Sstevel@tonic-gate
21070Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
21080Sstevel@tonic-gate
21090Sstevel@tonic-gate if ((statep->state == IBCM_STATE_REP_SENT) ||
21100Sstevel@tonic-gate (statep->state == IBCM_STATE_MRA_REP_RCVD)) {
21110Sstevel@tonic-gate
21120Sstevel@tonic-gate /* transient until ibt_modify_qp succeeds to RTS */
21130Sstevel@tonic-gate statep->state = IBCM_STATE_TRANSIENT_ESTABLISHED;
21140Sstevel@tonic-gate
21150Sstevel@tonic-gate timer_val = statep->timerid;
21160Sstevel@tonic-gate statep->timerid = 0;
21170Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
21180Sstevel@tonic-gate
21190Sstevel@tonic-gate (void) untimeout(timer_val);
21200Sstevel@tonic-gate
21210Sstevel@tonic-gate ibcm_cep_state_rtu(statep, rtu_msg);
21220Sstevel@tonic-gate
21230Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
21240Sstevel@tonic-gate
21250Sstevel@tonic-gate } else if (statep->state == IBCM_STATE_REJ_SENT) {
21260Sstevel@tonic-gate ibcm_resend_rej_mad(statep);
21270Sstevel@tonic-gate } else if (statep->state == IBCM_STATE_DELETE) {
21280Sstevel@tonic-gate
21290Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
21300Sstevel@tonic-gate ibcm_build_n_post_rej_mad(input_madp,
21310Sstevel@tonic-gate b2h32(rtu_msg->rtu_local_comm_id), cm_mad_addr,
21320Sstevel@tonic-gate IBT_CM_FAILURE_UNKNOWN, IBT_CM_INVALID_CID);
21330Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
21340Sstevel@tonic-gate } else {
21350Sstevel@tonic-gate
21360Sstevel@tonic-gate #ifdef DEBUG
21370Sstevel@tonic-gate if ((ibcm_test_mode > 0) &&
21380Sstevel@tonic-gate (statep->state != IBCM_STATE_ESTABLISHED))
21390Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_rtu_msg: "
21400Sstevel@tonic-gate "Unexpected rtu for statep 0x%p in state %d",
21410Sstevel@tonic-gate statep, statep->state);
21420Sstevel@tonic-gate #endif
21430Sstevel@tonic-gate }
21440Sstevel@tonic-gate
21450Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
21460Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
21470Sstevel@tonic-gate }
21480Sstevel@tonic-gate
21490Sstevel@tonic-gate
21500Sstevel@tonic-gate /*
21510Sstevel@tonic-gate * ibcm_process_rej_msg:
21520Sstevel@tonic-gate * Called from ibcm_process_incoming_mad on reception of a REJ message.
21530Sstevel@tonic-gate *
21540Sstevel@tonic-gate * INPUTS:
21550Sstevel@tonic-gate * hcap - HCA entry pointer
21560Sstevel@tonic-gate * input_madp - CM MAD that is input to this function
21570Sstevel@tonic-gate * cm_mad_addr - Address information for the MAD
21580Sstevel@tonic-gate *
21590Sstevel@tonic-gate * RETURN VALUE: NONE
21600Sstevel@tonic-gate */
21610Sstevel@tonic-gate /* ARGSUSED */
21620Sstevel@tonic-gate void
ibcm_process_rej_msg(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)21630Sstevel@tonic-gate ibcm_process_rej_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
21640Sstevel@tonic-gate ibcm_mad_addr_t *cm_mad_addr)
21650Sstevel@tonic-gate {
21660Sstevel@tonic-gate ibcm_status_t state_lookup_status;
21674703Shiremath ibcm_rej_msg_t *rej_msg =
21684703Shiremath (ibcm_rej_msg_t *)(&input_madp[IBCM_MAD_HDR_SIZE]);
21690Sstevel@tonic-gate ibcm_state_data_t *statep = NULL;
21700Sstevel@tonic-gate ib_guid_t remote_hca_guid;
21710Sstevel@tonic-gate ibcm_conn_state_t rej_state;
21720Sstevel@tonic-gate
21730Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_rej_msg:");
21740Sstevel@tonic-gate
21750Sstevel@tonic-gate /* Lookup for an existing state structure */
21760Sstevel@tonic-gate rw_enter(&hcap->hca_state_rwlock, RW_READER); /* grab READER lock */
21770Sstevel@tonic-gate
21780Sstevel@tonic-gate if ((b2h32(rej_msg->rej_remote_comm_id) == 0) &&
21790Sstevel@tonic-gate ((rej_msg->rej_reject_info_len_plus >> 1) >= sizeof (ib_guid_t)) &&
21800Sstevel@tonic-gate (b2h16(rej_msg->rej_rejection_reason) == IBT_CM_TIMEOUT)) {
21810Sstevel@tonic-gate bcopy(rej_msg->rej_addl_rej_info, &remote_hca_guid,
21820Sstevel@tonic-gate sizeof (ib_guid_t));
21830Sstevel@tonic-gate remote_hca_guid = b2h64(remote_hca_guid);
21840Sstevel@tonic-gate
21850Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_rej_msg: "
21860Sstevel@tonic-gate "hca guid in REJ's ARI = %llX", remote_hca_guid);
21870Sstevel@tonic-gate
21880Sstevel@tonic-gate state_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_REJ_RCOMID,
21890Sstevel@tonic-gate b2h32(rej_msg->rej_local_comm_id), 0, remote_hca_guid,
21900Sstevel@tonic-gate hcap, &statep);
21910Sstevel@tonic-gate } else
21920Sstevel@tonic-gate state_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_REJ,
21930Sstevel@tonic-gate b2h32(rej_msg->rej_remote_comm_id), 0, 0, hcap, &statep);
21940Sstevel@tonic-gate
21950Sstevel@tonic-gate rw_exit(&hcap->hca_state_rwlock);
21960Sstevel@tonic-gate
21970Sstevel@tonic-gate
21980Sstevel@tonic-gate /* if state doesn't exist just return */
21990Sstevel@tonic-gate if (state_lookup_status != IBCM_LOOKUP_EXISTS) {
22000Sstevel@tonic-gate
22010Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_rej_msg: no statep with "
22020Sstevel@tonic-gate "local com id %x remote com id %x reason %d",
22030Sstevel@tonic-gate b2h32(rej_msg->rej_remote_comm_id),
22040Sstevel@tonic-gate b2h32(rej_msg->rej_local_comm_id),
22050Sstevel@tonic-gate b2h16(rej_msg->rej_rejection_reason));
22060Sstevel@tonic-gate
22070Sstevel@tonic-gate /* Do NOT respond with invalid comid REJ */
22080Sstevel@tonic-gate return;
22090Sstevel@tonic-gate }
22100Sstevel@tonic-gate
22114908Shiremath IBTF_DPRINTF_L2(cmlog, "ibcm_process_rej_msg: statep 0x%p INCOMING_REJ",
22121093Shiremath statep);
22130Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_REJ);
22140Sstevel@tonic-gate if (ibcm_enable_trace & 2)
22150Sstevel@tonic-gate ibcm_dump_conn_trace(statep);
22160Sstevel@tonic-gate
22170Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
22180Sstevel@tonic-gate
22190Sstevel@tonic-gate rej_state = statep->state;
22200Sstevel@tonic-gate
22210Sstevel@tonic-gate if ((statep->state == IBCM_STATE_REP_SENT) ||
22220Sstevel@tonic-gate (statep->state == IBCM_STATE_REQ_SENT) ||
22230Sstevel@tonic-gate (statep->state == IBCM_STATE_REP_WAIT) ||
22240Sstevel@tonic-gate (statep->state == IBCM_STATE_MRA_REP_RCVD)) {
22250Sstevel@tonic-gate timeout_id_t timer_val = statep->timerid;
22260Sstevel@tonic-gate
22270Sstevel@tonic-gate statep->state = IBCM_STATE_DELETE;
22280Sstevel@tonic-gate
22290Sstevel@tonic-gate /* cancel the REQ/REP timer */
22300Sstevel@tonic-gate if (timer_val != 0) {
22310Sstevel@tonic-gate statep->timerid = 0;
22320Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
22330Sstevel@tonic-gate
22340Sstevel@tonic-gate (void) untimeout(timer_val);
22350Sstevel@tonic-gate } else {
22360Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
22370Sstevel@tonic-gate }
22380Sstevel@tonic-gate
22390Sstevel@tonic-gate /*
22400Sstevel@tonic-gate * Call the QP state transition processing function
22410Sstevel@tonic-gate * NOTE: Input MAD is the REJ received, there is no output MAD
22420Sstevel@tonic-gate */
22430Sstevel@tonic-gate ibcm_cep_state_rej(statep, rej_msg, rej_state);
22440Sstevel@tonic-gate
22450Sstevel@tonic-gate /* signal waiting CV - blocking in ibt_open_channel() */
22460Sstevel@tonic-gate if (statep->open_return_data != NULL) {
22470Sstevel@tonic-gate statep->open_return_data->rc_status =
22480Sstevel@tonic-gate b2h16(rej_msg->rej_rejection_reason);
22490Sstevel@tonic-gate
22500Sstevel@tonic-gate if (statep->open_return_data->rc_priv_data_len > 0)
22510Sstevel@tonic-gate bcopy(rej_msg->rej_private_data,
22520Sstevel@tonic-gate statep->open_return_data->rc_priv_data,
22530Sstevel@tonic-gate min(
22540Sstevel@tonic-gate statep->open_return_data->rc_priv_data_len,
22550Sstevel@tonic-gate IBT_REJ_PRIV_DATA_SZ));
22560Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
22570Sstevel@tonic-gate statep->open_done = B_TRUE;
22580Sstevel@tonic-gate cv_broadcast(&statep->block_client_cv);
22590Sstevel@tonic-gate } else {
22600Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
22610Sstevel@tonic-gate }
22620Sstevel@tonic-gate
22630Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
22640Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
22650Sstevel@tonic-gate
22660Sstevel@tonic-gate /* Now delete the statep */
22670Sstevel@tonic-gate ibcm_delete_state_data(statep);
22680Sstevel@tonic-gate
22690Sstevel@tonic-gate } else if ((statep->state == IBCM_STATE_ESTABLISHED) &&
22700Sstevel@tonic-gate (statep->mode == IBCM_ACTIVE_MODE)) {
22710Sstevel@tonic-gate
2272557Shiremath IBTF_DPRINTF_L4(cmlog, "ibcm_process_rej_msg: statep 0x%p "
22730Sstevel@tonic-gate "REJ in established state", statep);
22740Sstevel@tonic-gate
22750Sstevel@tonic-gate statep->state = IBCM_STATE_TIMEWAIT;
22760Sstevel@tonic-gate
22770Sstevel@tonic-gate /* wait for/cancel pending LAP/APR, release state mutex */
22780Sstevel@tonic-gate ibcm_sync_lapr_idle(statep);
22790Sstevel@tonic-gate
22800Sstevel@tonic-gate /* wait until client is informed CONN EST event */
22810Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
22820Sstevel@tonic-gate while (statep->cep_in_rts == IBCM_BLOCK)
22830Sstevel@tonic-gate cv_wait(&statep->block_mad_cv, &statep->state_mutex);
22840Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
22850Sstevel@tonic-gate
22860Sstevel@tonic-gate /*
22870Sstevel@tonic-gate * Call the QP state transition processing function
22880Sstevel@tonic-gate * NOTE: Input MAD is the REJ received, there is no output MAD
22890Sstevel@tonic-gate */
22900Sstevel@tonic-gate ibcm_cep_state_rej_est(statep);
22910Sstevel@tonic-gate
22920Sstevel@tonic-gate /*
22930Sstevel@tonic-gate * Start the timewait state timer, as connection is in
22940Sstevel@tonic-gate * established state
22950Sstevel@tonic-gate */
22960Sstevel@tonic-gate
22970Sstevel@tonic-gate /*
22980Sstevel@tonic-gate * For passive side CM set it to remote_ack_delay
22990Sstevel@tonic-gate * For active side CM add the pkt_life_time * 2
23000Sstevel@tonic-gate */
23010Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
23020Sstevel@tonic-gate statep->timer_value = statep->remote_ack_delay;
23030Sstevel@tonic-gate /* statep->mode == IBCM_ACTIVE_MODE) */
23040Sstevel@tonic-gate statep->timer_value += (2 * statep->pkt_life_time);
23050Sstevel@tonic-gate
23060Sstevel@tonic-gate statep->remaining_retry_cnt = 0;
23070Sstevel@tonic-gate statep->timer_stored_state = statep->state;
23080Sstevel@tonic-gate
23090Sstevel@tonic-gate statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
23100Sstevel@tonic-gate
23110Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
23120Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
23130Sstevel@tonic-gate
23140Sstevel@tonic-gate } else if (((statep->state == IBCM_STATE_REQ_RCVD) ||
23150Sstevel@tonic-gate (statep->state == IBCM_STATE_REP_RCVD) ||
23160Sstevel@tonic-gate (statep->state == IBCM_STATE_MRA_SENT) ||
23170Sstevel@tonic-gate (statep->state == IBCM_STATE_MRA_REP_SENT)) &&
23180Sstevel@tonic-gate (b2h16(rej_msg->rej_rejection_reason) == IBT_CM_TIMEOUT)) {
23190Sstevel@tonic-gate
23200Sstevel@tonic-gate if (statep->abort_flag == IBCM_ABORT_INIT)
23210Sstevel@tonic-gate statep->abort_flag = IBCM_ABORT_REJ;
23220Sstevel@tonic-gate
23230Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
23240Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
23250Sstevel@tonic-gate } else {
23260Sstevel@tonic-gate
23270Sstevel@tonic-gate #ifdef DEBUG
23280Sstevel@tonic-gate if ((ibcm_test_mode > 0) &&
23290Sstevel@tonic-gate (statep->state != IBCM_STATE_DELETE))
23300Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_rej_msg: "
23310Sstevel@tonic-gate "Unexpected rej for statep 0x%p in state %d",
23320Sstevel@tonic-gate statep, statep->state);
23330Sstevel@tonic-gate #endif
23340Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
23350Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
23360Sstevel@tonic-gate }
23370Sstevel@tonic-gate }
23380Sstevel@tonic-gate
23390Sstevel@tonic-gate
23400Sstevel@tonic-gate /*
23410Sstevel@tonic-gate * ibcm_process_dreq_msg:
23420Sstevel@tonic-gate * Processes incoming DREQ message on active/passive side
23430Sstevel@tonic-gate *
23440Sstevel@tonic-gate * INPUTS:
23450Sstevel@tonic-gate * hcap - HCA entry pointer
23460Sstevel@tonic-gate * input_madp - CM MAD that is input to this function
23470Sstevel@tonic-gate * cm_mad_addr - Address information for the MAD
23480Sstevel@tonic-gate *
23490Sstevel@tonic-gate * RETURN VALUE: NONE
23500Sstevel@tonic-gate */
23510Sstevel@tonic-gate /*ARGSUSED*/
23520Sstevel@tonic-gate void
ibcm_process_dreq_msg(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)23530Sstevel@tonic-gate ibcm_process_dreq_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
23540Sstevel@tonic-gate ibcm_mad_addr_t *cm_mad_addr)
23550Sstevel@tonic-gate {
23560Sstevel@tonic-gate void *priv_data = NULL;
23570Sstevel@tonic-gate ibcm_status_t state_lookup_status;
23580Sstevel@tonic-gate ib_qpn_t local_qpn;
23594703Shiremath ibcm_dreq_msg_t *dreq_msgp =
23604703Shiremath (ibcm_dreq_msg_t *)(&input_madp[IBCM_MAD_HDR_SIZE]);
23610Sstevel@tonic-gate ibcm_state_data_t *statep = NULL;
23620Sstevel@tonic-gate uint8_t close_event_type;
23630Sstevel@tonic-gate ibt_cm_status_t cb_status;
23640Sstevel@tonic-gate
23650Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_dreq_msg:");
23660Sstevel@tonic-gate
23670Sstevel@tonic-gate /* Lookup for an existing state structure */
23680Sstevel@tonic-gate rw_enter(&hcap->hca_state_rwlock, RW_READER);
23690Sstevel@tonic-gate
23700Sstevel@tonic-gate state_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_DREQ,
23710Sstevel@tonic-gate b2h32(dreq_msgp->dreq_remote_comm_id), 0, 0, hcap, &statep);
23720Sstevel@tonic-gate rw_exit(&hcap->hca_state_rwlock);
23730Sstevel@tonic-gate
23740Sstevel@tonic-gate local_qpn = b2h32(dreq_msgp->dreq_remote_qpn_eecn_plus) >> 8;
23750Sstevel@tonic-gate
23760Sstevel@tonic-gate if (state_lookup_status != IBCM_LOOKUP_EXISTS) {
2377557Shiremath IBTF_DPRINTF_L3(cmlog, "ibcm_process_dreq_msg: no statep with"
23780Sstevel@tonic-gate "com id %x", b2h32(dreq_msgp->dreq_remote_comm_id));
23790Sstevel@tonic-gate /* implies a bogus message */
23800Sstevel@tonic-gate return;
23810Sstevel@tonic-gate }
23820Sstevel@tonic-gate
23830Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_dreq_msg: statep 0x%p "
23840Sstevel@tonic-gate "lookup status %x dreq qpn = %x", statep, state_lookup_status,
23850Sstevel@tonic-gate local_qpn);
23860Sstevel@tonic-gate
23870Sstevel@tonic-gate /*
23880Sstevel@tonic-gate * Local QPN check is necessary. There could be a DREQ from
23890Sstevel@tonic-gate * a remote stale connection processing with the same com id, but
23900Sstevel@tonic-gate * not intended for this statep
23910Sstevel@tonic-gate */
2392557Shiremath mutex_enter(&statep->state_mutex);
23930Sstevel@tonic-gate if ((statep->local_qpn != local_qpn) ||
23940Sstevel@tonic-gate (statep->remote_comid != b2h32(dreq_msgp->dreq_local_comm_id))) {
23950Sstevel@tonic-gate
23960Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_process_dreq_msg:"
23970Sstevel@tonic-gate "statep->local_qpn = %x qpn in dreq = %x"
23980Sstevel@tonic-gate "statep->remote_comid = %x local comid in dreq = %x",
23990Sstevel@tonic-gate statep->local_qpn, local_qpn, statep->remote_comid,
24000Sstevel@tonic-gate b2h32(dreq_msgp->dreq_local_comm_id));
24010Sstevel@tonic-gate
2402557Shiremath IBCM_REF_CNT_DECR(statep);
2403557Shiremath mutex_exit(&statep->state_mutex);
2404557Shiremath return;
2405557Shiremath }
2406557Shiremath /*
2407557Shiremath * If another thread is processing a copy of this same DREQ,
2408557Shiremath * bail out here.
2409557Shiremath */
24101093Shiremath if (statep->state == IBCM_STATE_TRANSIENT_DREQ_SENT ||
24111093Shiremath statep->drep_in_progress) {
24120Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
24130Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
24140Sstevel@tonic-gate return;
24150Sstevel@tonic-gate }
2416557Shiremath switch (statep->state) {
2417557Shiremath case IBCM_STATE_ESTABLISHED:
2418557Shiremath case IBCM_STATE_DREQ_SENT:
2419557Shiremath case IBCM_STATE_TIMEWAIT:
2420557Shiremath break;
2421557Shiremath default:
2422557Shiremath /* All other states ignore DREQ */
2423557Shiremath IBCM_REF_CNT_DECR(statep);
2424557Shiremath mutex_exit(&statep->state_mutex);
2425557Shiremath return;
2426557Shiremath }
2427557Shiremath statep->drep_in_progress = 1;
24280Sstevel@tonic-gate
24290Sstevel@tonic-gate /*
24300Sstevel@tonic-gate * If drep msg wasn't really required, it shall be deleted finally
24310Sstevel@tonic-gate * when statep goes away
24320Sstevel@tonic-gate */
24330Sstevel@tonic-gate if (statep->drep_msg == NULL) {
2434557Shiremath mutex_exit(&statep->state_mutex);
24350Sstevel@tonic-gate if (ibcm_alloc_out_msg(statep->stored_reply_addr.ibmf_hdl,
24360Sstevel@tonic-gate &statep->drep_msg, MAD_METHOD_SEND) != IBT_SUCCESS) {
24370Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_dreq_msg: "
24380Sstevel@tonic-gate "statep 0x%p ibcm_alloc_out_msg failed", statep);
24390Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
2440557Shiremath statep->drep_in_progress = 0;
24410Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
24420Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
24430Sstevel@tonic-gate return;
24440Sstevel@tonic-gate }
2445557Shiremath mutex_enter(&statep->state_mutex);
2446557Shiremath }
2447557Shiremath
24481093Shiremath if (statep->state == IBCM_STATE_TRANSIENT_DREQ_SENT) {
24491093Shiremath IBCM_REF_CNT_DECR(statep);
24501093Shiremath statep->drep_in_progress = 0;
24511093Shiremath mutex_exit(&statep->state_mutex);
24521093Shiremath return;
24531093Shiremath }
24541093Shiremath
24550Sstevel@tonic-gate /*
24560Sstevel@tonic-gate * Need to generate drep, as time wait can be reached either by an
24570Sstevel@tonic-gate * outgoing dreq or an incoming dreq
24580Sstevel@tonic-gate */
24590Sstevel@tonic-gate if ((statep->state == IBCM_STATE_ESTABLISHED) ||
24600Sstevel@tonic-gate (statep->state == IBCM_STATE_DREQ_SENT)) {
24610Sstevel@tonic-gate timeout_id_t timer_val = statep->timerid;
24620Sstevel@tonic-gate
24630Sstevel@tonic-gate if (statep->state == IBCM_STATE_DREQ_SENT) {
24640Sstevel@tonic-gate statep->state = IBCM_STATE_DREQ_RCVD;
24650Sstevel@tonic-gate statep->timerid = 0;
24661093Shiremath ibcm_close_done(statep, 0);
24670Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
24680Sstevel@tonic-gate
24690Sstevel@tonic-gate close_event_type = IBT_CM_CLOSED_DUP;
24700Sstevel@tonic-gate if (timer_val != 0) {
24710Sstevel@tonic-gate /* Cancel the timer set for DREP reception */
24720Sstevel@tonic-gate (void) untimeout(timer_val);
24730Sstevel@tonic-gate }
24740Sstevel@tonic-gate } else { /* In ESTABLISHED State */
247511369SPramod.Gunjikar@Sun.COM boolean_t is_ofuv = statep->is_this_ofuv_chan;
247611369SPramod.Gunjikar@Sun.COM
24770Sstevel@tonic-gate statep->state = IBCM_STATE_DREQ_RCVD;
24780Sstevel@tonic-gate statep->clnt_proceed = IBCM_BLOCK;
24790Sstevel@tonic-gate
24800Sstevel@tonic-gate /* Cancel or wait for LAP/APR to complete */
24810Sstevel@tonic-gate ibcm_sync_lapr_idle(statep);
24820Sstevel@tonic-gate /* The above function releases the state mutex */
24830Sstevel@tonic-gate
24840Sstevel@tonic-gate /* wait until client knows CONN EST event */
24850Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
24860Sstevel@tonic-gate while (statep->cep_in_rts == IBCM_BLOCK)
24870Sstevel@tonic-gate cv_wait(&statep->block_mad_cv,
24880Sstevel@tonic-gate &statep->state_mutex);
24890Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
24900Sstevel@tonic-gate
24910Sstevel@tonic-gate close_event_type = IBT_CM_CLOSED_DREQ_RCVD;
24920Sstevel@tonic-gate /* Move CEP to error state */
249311369SPramod.Gunjikar@Sun.COM if (is_ofuv == B_FALSE) /* Skip for OFUV channel */
249411369SPramod.Gunjikar@Sun.COM (void) ibcm_cep_to_error_state(statep);
24950Sstevel@tonic-gate }
2496557Shiremath mutex_enter(&statep->state_mutex);
2497557Shiremath statep->drep_in_progress = 0;
24980Sstevel@tonic-gate
24990Sstevel@tonic-gate IBCM_OUT_HDRP(statep->drep_msg)->TransactionID =
25000Sstevel@tonic-gate ((ib_mad_hdr_t *)(input_madp))->TransactionID;
25010Sstevel@tonic-gate
25020Sstevel@tonic-gate priv_data = &(((ibcm_drep_msg_t *)
25030Sstevel@tonic-gate IBCM_OUT_MSGP(statep->drep_msg))->drep_private_data[0]);
25040Sstevel@tonic-gate
25050Sstevel@tonic-gate if (statep->close_ret_status)
25060Sstevel@tonic-gate *statep->close_ret_status = close_event_type;
25070Sstevel@tonic-gate
25080Sstevel@tonic-gate if (statep->close_nocb_state != IBCM_FAIL) {
25090Sstevel@tonic-gate ibtl_cm_chan_is_closing(statep->channel);
25100Sstevel@tonic-gate statep->close_nocb_state = IBCM_BLOCK;
25110Sstevel@tonic-gate }
25120Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
25130Sstevel@tonic-gate
25140Sstevel@tonic-gate /*
25150Sstevel@tonic-gate * if close_nocb_state is IBCM_FAIL, then cm_handler is NULL
25160Sstevel@tonic-gate * if close_nocb_state is IBCM_BLOCK, client cannot go away
25170Sstevel@tonic-gate */
25180Sstevel@tonic-gate if (statep->cm_handler != NULL) {
25190Sstevel@tonic-gate ibt_cm_event_t event;
25200Sstevel@tonic-gate ibt_cm_return_args_t ret_args;
25210Sstevel@tonic-gate
25220Sstevel@tonic-gate bzero(&event, sizeof (event));
25230Sstevel@tonic-gate bzero(&ret_args, sizeof (ret_args));
25240Sstevel@tonic-gate
25250Sstevel@tonic-gate event.cm_type = IBT_CM_EVENT_CONN_CLOSED;
25260Sstevel@tonic-gate event.cm_channel = statep->channel;
25270Sstevel@tonic-gate event.cm_session_id = statep;
25280Sstevel@tonic-gate event.cm_priv_data = dreq_msgp->dreq_private_data;
25290Sstevel@tonic-gate event.cm_priv_data_len = IBT_DREQ_PRIV_DATA_SZ;
25300Sstevel@tonic-gate event.cm_event.closed = close_event_type;
25310Sstevel@tonic-gate
25320Sstevel@tonic-gate ibcm_insert_trace(statep,
25330Sstevel@tonic-gate IBCM_TRACE_CALLED_CONN_CLOSE_EVENT);
25340Sstevel@tonic-gate
25350Sstevel@tonic-gate cb_status = statep->cm_handler(statep->state_cm_private,
25360Sstevel@tonic-gate &event, &ret_args, priv_data,
25370Sstevel@tonic-gate IBT_DREP_PRIV_DATA_SZ);
25380Sstevel@tonic-gate
25390Sstevel@tonic-gate ibcm_insert_trace(statep,
25400Sstevel@tonic-gate IBCM_TRACE_RET_CONN_CLOSE_EVENT);
25410Sstevel@tonic-gate
25420Sstevel@tonic-gate if (cb_status == IBT_CM_DEFER) {
25430Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
25440Sstevel@tonic-gate statep->clnt_proceed =
25450Sstevel@tonic-gate IBCM_UNBLOCK;
25460Sstevel@tonic-gate cv_broadcast(&statep->block_client_cv);
25470Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
25480Sstevel@tonic-gate
25490Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_dreq_msg:"
25500Sstevel@tonic-gate " statep 0x%p client returned DEFER "
25510Sstevel@tonic-gate "response", statep);
25520Sstevel@tonic-gate return;
25530Sstevel@tonic-gate }
25540Sstevel@tonic-gate }
25550Sstevel@tonic-gate
25560Sstevel@tonic-gate /* fail/resume any blocked cm api call */
25570Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
25580Sstevel@tonic-gate
25590Sstevel@tonic-gate /* Signal for cm proceed api */
25600Sstevel@tonic-gate statep->clnt_proceed = IBCM_FAIL;
25610Sstevel@tonic-gate
25620Sstevel@tonic-gate /* Signal for close with no callbacks */
25630Sstevel@tonic-gate statep->close_nocb_state = IBCM_FAIL;
25640Sstevel@tonic-gate
25650Sstevel@tonic-gate /* Signal any waiting close channel thread */
25660Sstevel@tonic-gate statep->close_done = B_TRUE;
25670Sstevel@tonic-gate
25680Sstevel@tonic-gate cv_broadcast(&statep->block_client_cv);
25690Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
25700Sstevel@tonic-gate
25710Sstevel@tonic-gate ibcm_handle_cep_dreq_response(statep, NULL, 0);
25720Sstevel@tonic-gate
25730Sstevel@tonic-gate } else if (statep->state == IBCM_STATE_TIMEWAIT) {
2574557Shiremath statep->drep_in_progress = 0;
25750Sstevel@tonic-gate if (statep->send_mad_flags & IBCM_DREP_POST_BUSY) {
25760Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
25770Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
25780Sstevel@tonic-gate return;
25790Sstevel@tonic-gate }
25800Sstevel@tonic-gate statep->send_mad_flags |= IBCM_DREP_POST_BUSY;
25810Sstevel@tonic-gate
25820Sstevel@tonic-gate /* Release statep mutex before posting the MAD */
25830Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
25840Sstevel@tonic-gate
25850Sstevel@tonic-gate IBCM_OUT_HDRP(statep->drep_msg)->TransactionID =
25860Sstevel@tonic-gate ((ib_mad_hdr_t *)(input_madp))->TransactionID;
25870Sstevel@tonic-gate
25880Sstevel@tonic-gate ibcm_post_drep_mad(statep);
25890Sstevel@tonic-gate /* ref cnt decremented in ibcm_post_drep_complete */
25900Sstevel@tonic-gate } else {
25910Sstevel@tonic-gate #ifdef DEBUG
25920Sstevel@tonic-gate if ((ibcm_test_mode > 0) &&
25930Sstevel@tonic-gate (statep->state != IBCM_STATE_DELETE))
25940Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_dreq_msg: "
25950Sstevel@tonic-gate "Unexpected dreq for statep 0x%p in state %d",
25960Sstevel@tonic-gate statep, statep->state);
25970Sstevel@tonic-gate #endif
25980Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
2599557Shiremath statep->drep_in_progress = 0;
26000Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
26010Sstevel@tonic-gate }
26020Sstevel@tonic-gate }
26030Sstevel@tonic-gate
26040Sstevel@tonic-gate /*
26050Sstevel@tonic-gate * ibcm_handle_cep_dreq_response:
26060Sstevel@tonic-gate * Processes the response from client handler for an incoming DREQ.
26070Sstevel@tonic-gate * The statep ref cnt is decremented before returning.
26080Sstevel@tonic-gate */
26090Sstevel@tonic-gate void
ibcm_handle_cep_dreq_response(ibcm_state_data_t * statep,void * priv_data,ibt_priv_data_len_t priv_data_len)26100Sstevel@tonic-gate ibcm_handle_cep_dreq_response(ibcm_state_data_t *statep, void *priv_data,
26110Sstevel@tonic-gate ibt_priv_data_len_t priv_data_len)
26120Sstevel@tonic-gate {
26130Sstevel@tonic-gate if ((priv_data != NULL) && (priv_data_len > 0))
26140Sstevel@tonic-gate bcopy(priv_data,
26150Sstevel@tonic-gate &(((ibcm_drep_msg_t *)
26160Sstevel@tonic-gate IBCM_OUT_MSGP(statep->drep_msg))->drep_private_data[0]),
26170Sstevel@tonic-gate min(priv_data_len, IBT_DREP_PRIV_DATA_SZ));
26180Sstevel@tonic-gate
26190Sstevel@tonic-gate ibcm_post_drep_mad(statep);
26200Sstevel@tonic-gate }
26210Sstevel@tonic-gate
26220Sstevel@tonic-gate
26230Sstevel@tonic-gate /*
26240Sstevel@tonic-gate * ibcm_post_dreq_mad:
26250Sstevel@tonic-gate * Posts a DREQ MAD
26260Sstevel@tonic-gate * Post DREQ now for TIMEWAIT state and DREQ_RCVD
26270Sstevel@tonic-gate *
26280Sstevel@tonic-gate * INPUTS:
26290Sstevel@tonic-gate * statep - state pointer
26300Sstevel@tonic-gate *
26310Sstevel@tonic-gate * RETURN VALUE:
26320Sstevel@tonic-gate * NONE
26330Sstevel@tonic-gate */
26340Sstevel@tonic-gate void
ibcm_post_dreq_mad(void * vstatep)26350Sstevel@tonic-gate ibcm_post_dreq_mad(void *vstatep)
26360Sstevel@tonic-gate {
26370Sstevel@tonic-gate ibcm_state_data_t *statep = vstatep;
26380Sstevel@tonic-gate ibcm_dreq_msg_t *dreq_msgp;
26390Sstevel@tonic-gate
26400Sstevel@tonic-gate ASSERT(statep->dreq_msg != NULL);
26410Sstevel@tonic-gate
26420Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*dreq_msgp))
26430Sstevel@tonic-gate
26440Sstevel@tonic-gate /* Fill in the DREQ message */
26450Sstevel@tonic-gate dreq_msgp = (ibcm_dreq_msg_t *)IBCM_OUT_MSGP(statep->dreq_msg);
26460Sstevel@tonic-gate dreq_msgp->dreq_local_comm_id = h2b32(statep->local_comid);
26470Sstevel@tonic-gate dreq_msgp->dreq_remote_comm_id = h2b32(statep->remote_comid);
26480Sstevel@tonic-gate dreq_msgp->dreq_remote_qpn_eecn_plus = h2b32(statep->remote_qpn << 8);
26490Sstevel@tonic-gate
26500Sstevel@tonic-gate IBCM_OUT_HDRP(statep->dreq_msg)->AttributeID =
26510Sstevel@tonic-gate h2b16(IBCM_INCOMING_DREQ + IBCM_ATTR_BASE_ID);
26520Sstevel@tonic-gate
26530Sstevel@tonic-gate /* wait until client knows CONN EST event */
26540Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
26550Sstevel@tonic-gate while (statep->cep_in_rts == IBCM_BLOCK)
26560Sstevel@tonic-gate cv_wait(&statep->block_mad_cv, &statep->state_mutex);
26570Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
26580Sstevel@tonic-gate
26590Sstevel@tonic-gate /* Transition QP/EEC state to ERROR state */
26600Sstevel@tonic-gate (void) ibcm_cep_to_error_state(statep);
26610Sstevel@tonic-gate
26620Sstevel@tonic-gate IBCM_OUT_HDRP(statep->dreq_msg)->TransactionID =
26630Sstevel@tonic-gate h2b64(ibcm_generate_tranid(IBCM_INCOMING_DREQ, statep->local_comid,
26640Sstevel@tonic-gate 0));
26650Sstevel@tonic-gate
26660Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*dreq_msgp))
26670Sstevel@tonic-gate
26680Sstevel@tonic-gate /* post the first DREQ via timeout callback */
26690Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
26700Sstevel@tonic-gate
26710Sstevel@tonic-gate statep->state = IBCM_STATE_DREQ_SENT;
26720Sstevel@tonic-gate cv_broadcast(&statep->block_mad_cv);
26730Sstevel@tonic-gate
26740Sstevel@tonic-gate statep->timer_stored_state = statep->state;
26750Sstevel@tonic-gate /* client cannot specify more than 16 retries */
2676557Shiremath statep->timer_value = statep->remote_ack_delay;
2677557Shiremath if (statep->mode == IBCM_ACTIVE_MODE) {
2678557Shiremath statep->timer_value += (2 * statep->pkt_life_time);
2679557Shiremath }
26800Sstevel@tonic-gate statep->remaining_retry_cnt = statep->max_cm_retries + 1;
26810Sstevel@tonic-gate statep->timerid = IBCM_TIMEOUT(statep, 0);
26820Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
26830Sstevel@tonic-gate }
26840Sstevel@tonic-gate
26850Sstevel@tonic-gate /*
26860Sstevel@tonic-gate * ibcm_post_drep_mad:
26870Sstevel@tonic-gate * Posts a DREP MAD
26880Sstevel@tonic-gate * Post DREP now for TIMEWAIT state and DREQ_RCVD
26890Sstevel@tonic-gate *
26900Sstevel@tonic-gate * INPUTS:
26910Sstevel@tonic-gate * statep - state pointer
26920Sstevel@tonic-gate *
26930Sstevel@tonic-gate * RETURN VALUE:
26940Sstevel@tonic-gate * NONE
26950Sstevel@tonic-gate */
26960Sstevel@tonic-gate static void
ibcm_post_drep_mad(ibcm_state_data_t * statep)26970Sstevel@tonic-gate ibcm_post_drep_mad(ibcm_state_data_t *statep)
26980Sstevel@tonic-gate {
26990Sstevel@tonic-gate ibcm_drep_msg_t *drep_msgp;
27000Sstevel@tonic-gate
27010Sstevel@tonic-gate drep_msgp = (ibcm_drep_msg_t *)IBCM_OUT_MSGP(statep->drep_msg);
27020Sstevel@tonic-gate
27030Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*drep_msgp))
27040Sstevel@tonic-gate
2705557Shiremath IBTF_DPRINTF_L4(cmlog, "ibcm_post_drep_mad:");
27060Sstevel@tonic-gate
27070Sstevel@tonic-gate /* Fill up DREP fields */
27080Sstevel@tonic-gate drep_msgp->drep_local_comm_id = h2b32(statep->local_comid);
27090Sstevel@tonic-gate drep_msgp->drep_remote_comm_id = h2b32(statep->remote_comid);
27100Sstevel@tonic-gate IBCM_OUT_HDRP(statep->drep_msg)->AttributeID =
27110Sstevel@tonic-gate h2b16(IBCM_INCOMING_DREP + IBCM_ATTR_BASE_ID);
27120Sstevel@tonic-gate
27130Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*drep_msgp))
27140Sstevel@tonic-gate
27150Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_DREP);
27160Sstevel@tonic-gate
27170Sstevel@tonic-gate /* Post the DREP MAD now. */
27180Sstevel@tonic-gate ibcm_post_rc_mad(statep, statep->drep_msg, ibcm_post_drep_complete,
27190Sstevel@tonic-gate statep);
27200Sstevel@tonic-gate }
27210Sstevel@tonic-gate
27220Sstevel@tonic-gate /*
27230Sstevel@tonic-gate * ibcm_process_drep_msg:
27240Sstevel@tonic-gate * Processes incoming DREP message on active/passive side
27250Sstevel@tonic-gate *
27260Sstevel@tonic-gate * INPUTS:
27270Sstevel@tonic-gate * hcap - HCA entry pointer
27280Sstevel@tonic-gate * input_madp - CM MAD that is input to this function
27290Sstevel@tonic-gate * cm_mad_addr - Address information for the MAD
27300Sstevel@tonic-gate *
27310Sstevel@tonic-gate * RETURN VALUE: NONE
27320Sstevel@tonic-gate */
27330Sstevel@tonic-gate /* ARGSUSED */
27340Sstevel@tonic-gate void
ibcm_process_drep_msg(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)27350Sstevel@tonic-gate ibcm_process_drep_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
27360Sstevel@tonic-gate ibcm_mad_addr_t *cm_mad_addr)
27370Sstevel@tonic-gate {
27380Sstevel@tonic-gate ibcm_status_t state_lookup_status;
27394703Shiremath ibcm_drep_msg_t *drep_msgp =
27404703Shiremath (ibcm_drep_msg_t *)(&input_madp[IBCM_MAD_HDR_SIZE]);
27410Sstevel@tonic-gate ibcm_state_data_t *statep = NULL;
27420Sstevel@tonic-gate
27430Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_drep_msg:");
27440Sstevel@tonic-gate
27450Sstevel@tonic-gate /* Lookup for an existing state structure */
27460Sstevel@tonic-gate rw_enter(&hcap->hca_state_rwlock, RW_READER);
27470Sstevel@tonic-gate
27480Sstevel@tonic-gate state_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_DREP,
27490Sstevel@tonic-gate b2h32(drep_msgp->drep_remote_comm_id), 0, 0, hcap, &statep);
27500Sstevel@tonic-gate rw_exit(&hcap->hca_state_rwlock);
27510Sstevel@tonic-gate
27520Sstevel@tonic-gate if (state_lookup_status != IBCM_LOOKUP_EXISTS) {
27530Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_process_drep_msg: no statep with"
27540Sstevel@tonic-gate "com id %x", b2h32(drep_msgp->drep_remote_comm_id));
27550Sstevel@tonic-gate return;
27560Sstevel@tonic-gate }
27570Sstevel@tonic-gate
27580Sstevel@tonic-gate /* if transaction id is not as expected, drop the DREP mad */
27590Sstevel@tonic-gate if (IBCM_OUT_HDRP(statep->dreq_msg)->TransactionID !=
27600Sstevel@tonic-gate ((ib_mad_hdr_t *)(input_madp))->TransactionID) {
27610Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
27620Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
27630Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
2764557Shiremath IBTF_DPRINTF_L3(cmlog, "ibcm_process_drep_msg: statep 0x%p "
2765557Shiremath "DREP with tid expected 0x%llX tid found 0x%llX", statep,
27660Sstevel@tonic-gate b2h64(IBCM_OUT_HDRP(statep->dreq_msg)->TransactionID),
27670Sstevel@tonic-gate b2h64(((ib_mad_hdr_t *)(input_madp))->TransactionID));
27680Sstevel@tonic-gate return;
27690Sstevel@tonic-gate }
27700Sstevel@tonic-gate
27710Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_DREP);
27720Sstevel@tonic-gate
27730Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
27740Sstevel@tonic-gate
27750Sstevel@tonic-gate if (statep->state == IBCM_STATE_DREQ_SENT) {
27760Sstevel@tonic-gate timeout_id_t timer_val = statep->timerid;
27770Sstevel@tonic-gate
27780Sstevel@tonic-gate statep->state = IBCM_STATE_DREP_RCVD;
27790Sstevel@tonic-gate
27800Sstevel@tonic-gate statep->timerid = 0;
27810Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
27820Sstevel@tonic-gate (void) untimeout(timer_val);
27830Sstevel@tonic-gate
27840Sstevel@tonic-gate if (statep->stale == B_TRUE)
27850Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_drep_msg: "
27860Sstevel@tonic-gate "statep 0x%p Unexpected DREP received for a stale "
27870Sstevel@tonic-gate "DREQ sent", statep);
27880Sstevel@tonic-gate
27890Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
27900Sstevel@tonic-gate /* allow free qp, if close channel with NOCALLBACKS didn't */
27910Sstevel@tonic-gate if (statep->close_nocb_state != IBCM_FAIL) {
27920Sstevel@tonic-gate ibtl_cm_chan_is_closing(statep->channel);
27930Sstevel@tonic-gate statep->close_nocb_state = IBCM_BLOCK;
27940Sstevel@tonic-gate }
27950Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
27960Sstevel@tonic-gate
27970Sstevel@tonic-gate /* if close_nocb_state is IBCM_FAIL, then cm_handler is NULL */
27980Sstevel@tonic-gate if (statep->cm_handler != NULL) {
27990Sstevel@tonic-gate ibt_cm_event_t event;
28000Sstevel@tonic-gate ibt_cm_return_args_t ret_args;
28010Sstevel@tonic-gate
28020Sstevel@tonic-gate bzero(&event, sizeof (event));
28030Sstevel@tonic-gate bzero(&ret_args, sizeof (ret_args));
28040Sstevel@tonic-gate
28050Sstevel@tonic-gate event.cm_type = IBT_CM_EVENT_CONN_CLOSED;
28060Sstevel@tonic-gate event.cm_channel = statep->channel;
28070Sstevel@tonic-gate event.cm_session_id = NULL;
28080Sstevel@tonic-gate
28090Sstevel@tonic-gate if (statep->stale == B_TRUE) {
28100Sstevel@tonic-gate event.cm_event.closed = IBT_CM_CLOSED_STALE;
28110Sstevel@tonic-gate event.cm_priv_data = NULL;
28120Sstevel@tonic-gate event.cm_priv_data_len = 0;
28130Sstevel@tonic-gate } else {
28140Sstevel@tonic-gate event.cm_event.closed = IBT_CM_CLOSED_DREP_RCVD;
28150Sstevel@tonic-gate event.cm_priv_data =
28160Sstevel@tonic-gate drep_msgp->drep_private_data;
28170Sstevel@tonic-gate event.cm_priv_data_len = IBT_DREP_PRIV_DATA_SZ;
28180Sstevel@tonic-gate }
28190Sstevel@tonic-gate
28200Sstevel@tonic-gate ibcm_insert_trace(statep,
28210Sstevel@tonic-gate IBCM_TRACE_CALLED_CONN_CLOSE_EVENT);
28220Sstevel@tonic-gate
28230Sstevel@tonic-gate (void) statep->cm_handler(statep->state_cm_private,
28240Sstevel@tonic-gate &event, &ret_args, NULL, 0);
28250Sstevel@tonic-gate
28260Sstevel@tonic-gate ibcm_insert_trace(statep,
28270Sstevel@tonic-gate IBCM_TRACE_RET_CONN_CLOSE_EVENT);
28280Sstevel@tonic-gate }
28290Sstevel@tonic-gate
28300Sstevel@tonic-gate /* copy the private to close channel, if specified */
28313241Shiremath if ((statep->close_ret_priv_data != NULL) &&
28323241Shiremath (statep->close_ret_priv_data_len != NULL) &&
28333241Shiremath (*statep->close_ret_priv_data_len > 0)) {
28340Sstevel@tonic-gate bcopy(drep_msgp->drep_private_data,
28353241Shiremath statep->close_ret_priv_data,
28363241Shiremath min(*statep->close_ret_priv_data_len,
28374703Shiremath IBT_DREP_PRIV_DATA_SZ));
28380Sstevel@tonic-gate }
28390Sstevel@tonic-gate
28400Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
28410Sstevel@tonic-gate if (statep->close_ret_status)
28420Sstevel@tonic-gate *statep->close_ret_status = IBT_CM_CLOSED_DREP_RCVD;
28430Sstevel@tonic-gate /* signal waiting CV - blocking in ibt_close_channel() */
28440Sstevel@tonic-gate statep->close_done = B_TRUE;
28450Sstevel@tonic-gate
28460Sstevel@tonic-gate /* signal any blocked close channels with no callbacks */
28470Sstevel@tonic-gate statep->close_nocb_state = IBCM_FAIL;
28480Sstevel@tonic-gate
28490Sstevel@tonic-gate cv_broadcast(&statep->block_client_cv);
28500Sstevel@tonic-gate
28510Sstevel@tonic-gate /* Set the timer wait state timer */
28520Sstevel@tonic-gate statep->state = statep->timer_stored_state =
28530Sstevel@tonic-gate IBCM_STATE_TIMEWAIT;
28541093Shiremath ibcm_close_done(statep, 0);
28550Sstevel@tonic-gate
28560Sstevel@tonic-gate statep->remaining_retry_cnt = 0;
28570Sstevel@tonic-gate /*
28580Sstevel@tonic-gate * For passive side CM set it to remote_ack_delay
28590Sstevel@tonic-gate * For active side CM add the pkt_life_time * 2
28600Sstevel@tonic-gate */
28610Sstevel@tonic-gate statep->timer_value = statep->remote_ack_delay;
28620Sstevel@tonic-gate if (statep->mode == IBCM_ACTIVE_MODE) {
28630Sstevel@tonic-gate statep->timer_value += (2 * statep->pkt_life_time);
28640Sstevel@tonic-gate }
28650Sstevel@tonic-gate
28660Sstevel@tonic-gate /* start TIMEWAIT processing */
28670Sstevel@tonic-gate statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
28680Sstevel@tonic-gate }
28690Sstevel@tonic-gate
28700Sstevel@tonic-gate /* There is no processing required for other states */
28710Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
28720Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
28730Sstevel@tonic-gate }
28740Sstevel@tonic-gate
28750Sstevel@tonic-gate /*
28760Sstevel@tonic-gate * Following are the routines used to resend various CM MADs as a response to
28770Sstevel@tonic-gate * incoming MADs
28780Sstevel@tonic-gate */
28790Sstevel@tonic-gate void
ibcm_resend_rtu_mad(ibcm_state_data_t * statep)28800Sstevel@tonic-gate ibcm_resend_rtu_mad(ibcm_state_data_t *statep)
28810Sstevel@tonic-gate {
28820Sstevel@tonic-gate ASSERT(MUTEX_HELD(&statep->state_mutex));
28830Sstevel@tonic-gate
28840Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_resend_rtu_mad statep %p ", statep);
28850Sstevel@tonic-gate
28860Sstevel@tonic-gate /* don't care, if timer is running or not. Timer may be from LAP */
28870Sstevel@tonic-gate
28880Sstevel@tonic-gate if (!(statep->send_mad_flags & IBCM_RTU_POST_BUSY)) {
28890Sstevel@tonic-gate statep->send_mad_flags |= IBCM_RTU_POST_BUSY;
28900Sstevel@tonic-gate IBCM_REF_CNT_INCR(statep); /* for non-blocking RTU post */
28910Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
28920Sstevel@tonic-gate
28930Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_RTU);
28940Sstevel@tonic-gate
28950Sstevel@tonic-gate ibcm_post_rc_mad(statep, statep->stored_msg,
28960Sstevel@tonic-gate ibcm_post_rtu_complete, statep);
28970Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
28980Sstevel@tonic-gate }
28990Sstevel@tonic-gate /* ref cnt is decremented in ibcm_post_rtu_complete */
29000Sstevel@tonic-gate }
29010Sstevel@tonic-gate
29020Sstevel@tonic-gate void
ibcm_resend_rej_mad(ibcm_state_data_t * statep)29030Sstevel@tonic-gate ibcm_resend_rej_mad(ibcm_state_data_t *statep)
29040Sstevel@tonic-gate {
29050Sstevel@tonic-gate timeout_id_t timer_val = statep->timerid;
29060Sstevel@tonic-gate
29070Sstevel@tonic-gate ASSERT(MUTEX_HELD(&statep->state_mutex));
29080Sstevel@tonic-gate
29090Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_resend_rej_mad statep %p ", statep);
29100Sstevel@tonic-gate
29110Sstevel@tonic-gate /* It's a too fast of a REQ or REP */
29120Sstevel@tonic-gate if (timer_val == 0)
29130Sstevel@tonic-gate return;
29140Sstevel@tonic-gate
29150Sstevel@tonic-gate statep->timerid = 0;
29160Sstevel@tonic-gate if (!(statep->send_mad_flags & IBCM_REJ_POST_BUSY)) {
29170Sstevel@tonic-gate statep->send_mad_flags |= IBCM_REJ_POST_BUSY;
29180Sstevel@tonic-gate IBCM_REF_CNT_INCR(statep); /* for nonblocking REJ post */
29190Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
29200Sstevel@tonic-gate (void) untimeout(timer_val);
29210Sstevel@tonic-gate
29220Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_REJ);
29230Sstevel@tonic-gate if (ibcm_enable_trace & 2)
29240Sstevel@tonic-gate ibcm_dump_conn_trace(statep);
29254908Shiremath else
29264908Shiremath IBTF_DPRINTF_L2(cmlog, "ibcm_resend_rej_mad statep %p "
29274908Shiremath "OUTGOING_REJ", statep);
29280Sstevel@tonic-gate
29290Sstevel@tonic-gate ibcm_post_rc_mad(statep, statep->stored_msg,
29300Sstevel@tonic-gate ibcm_post_rej_complete, statep);
29310Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
29320Sstevel@tonic-gate }
29330Sstevel@tonic-gate /* return, holding the state mutex */
29340Sstevel@tonic-gate }
29350Sstevel@tonic-gate
29360Sstevel@tonic-gate void
ibcm_resend_rep_mad(ibcm_state_data_t * statep)29370Sstevel@tonic-gate ibcm_resend_rep_mad(ibcm_state_data_t *statep)
29380Sstevel@tonic-gate {
29390Sstevel@tonic-gate timeout_id_t timer_val = statep->timerid;
29400Sstevel@tonic-gate
29410Sstevel@tonic-gate ASSERT(MUTEX_HELD(&statep->state_mutex));
29420Sstevel@tonic-gate
29430Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_resend_rep_mad statep %p ", statep);
29440Sstevel@tonic-gate
29450Sstevel@tonic-gate /* REP timer that is set by ibcm_post_rep_mad */
29460Sstevel@tonic-gate if (timer_val != 0) {
29470Sstevel@tonic-gate /* Re-start REP timeout */
29480Sstevel@tonic-gate statep->remaining_retry_cnt = statep->max_cm_retries;
29490Sstevel@tonic-gate if (!(statep->send_mad_flags & IBCM_REP_POST_BUSY)) {
29500Sstevel@tonic-gate statep->send_mad_flags |= IBCM_REP_POST_BUSY;
29510Sstevel@tonic-gate /* for nonblocking REP post */
29520Sstevel@tonic-gate IBCM_REF_CNT_INCR(statep);
29530Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
29540Sstevel@tonic-gate
29551093Shiremath ibcm_insert_trace(statep, IBCM_TRACE_OUT_REP_RETRY);
29560Sstevel@tonic-gate
29570Sstevel@tonic-gate ibcm_post_rc_mad(statep, statep->stored_msg,
29580Sstevel@tonic-gate ibcm_resend_post_rep_complete, statep);
29590Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
29600Sstevel@tonic-gate }
29610Sstevel@tonic-gate }
29620Sstevel@tonic-gate
29630Sstevel@tonic-gate /*
29640Sstevel@tonic-gate * else, timer is not yet set by ibcm_post_rep_mad. This is too fast
29650Sstevel@tonic-gate * of a REQ being re-transmitted.
29660Sstevel@tonic-gate */
29670Sstevel@tonic-gate }
29680Sstevel@tonic-gate
29690Sstevel@tonic-gate void
ibcm_resend_mra_mad(ibcm_state_data_t * statep)29700Sstevel@tonic-gate ibcm_resend_mra_mad(ibcm_state_data_t *statep)
29710Sstevel@tonic-gate {
29720Sstevel@tonic-gate ASSERT(MUTEX_HELD(&statep->state_mutex));
29730Sstevel@tonic-gate
29740Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_resend_mra_mad statep %p ", statep);
29750Sstevel@tonic-gate
29760Sstevel@tonic-gate if (statep->send_mad_flags & IBCM_MRA_POST_BUSY)
29770Sstevel@tonic-gate return;
29780Sstevel@tonic-gate
29790Sstevel@tonic-gate statep->send_mad_flags |= IBCM_MRA_POST_BUSY;
29800Sstevel@tonic-gate
29811093Shiremath statep->mra_time = gethrtime();
29820Sstevel@tonic-gate IBCM_REF_CNT_INCR(statep); /* for non-blocking MRA post */
29830Sstevel@tonic-gate /* Exit the statep mutex, before sending the MAD */
29840Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
29850Sstevel@tonic-gate
29860Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_MRA);
29870Sstevel@tonic-gate
29880Sstevel@tonic-gate /* Always resend the response MAD to the original reply destination */
29890Sstevel@tonic-gate ibcm_post_rc_mad(statep, statep->mra_msg, ibcm_post_mra_complete,
29900Sstevel@tonic-gate statep);
29910Sstevel@tonic-gate
29920Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
29930Sstevel@tonic-gate
29940Sstevel@tonic-gate /* return, holding the state mutex */
29950Sstevel@tonic-gate }
29960Sstevel@tonic-gate
29970Sstevel@tonic-gate
29980Sstevel@tonic-gate /*
29990Sstevel@tonic-gate * ibcm_post_rej_mad:
30000Sstevel@tonic-gate * Posts a REJ MAD and starts timer
30010Sstevel@tonic-gate *
30020Sstevel@tonic-gate * INPUTS:
30030Sstevel@tonic-gate * statep - state pointer
30040Sstevel@tonic-gate * which_msg - which message is being MRAed
30050Sstevel@tonic-gate * reject_reason - Rejection reason See Section 12.6.7.2 rev1.0a IB Spec
30060Sstevel@tonic-gate * addl_rej_info - Additional rej Information
30070Sstevel@tonic-gate * arej_info_len - Additional rej Info length
30080Sstevel@tonic-gate *
30090Sstevel@tonic-gate * RETURN VALUE:
30100Sstevel@tonic-gate * NONE
30110Sstevel@tonic-gate * Notes
30120Sstevel@tonic-gate * There is no need to hold the statep->mutex and call ibcm_post_rej_mad
30130Sstevel@tonic-gate * REJ can be posted either in IBCM_STATE_REQ_RCVD or IBCM_STATE_REP_RCVD
30140Sstevel@tonic-gate * In these states, there is no timer active, and an incoming REJ shall
30150Sstevel@tonic-gate * not modify the state or cancel timers
30160Sstevel@tonic-gate * An incoming REJ doesn't affect statep in state = IBCM_STATE_REJ_SENT/BUSY
30170Sstevel@tonic-gate */
30180Sstevel@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)30190Sstevel@tonic-gate ibcm_post_rej_mad(ibcm_state_data_t *statep, ibt_cm_reason_t reject_reason,
30200Sstevel@tonic-gate int which_msg, void *addl_rej_info, ibt_priv_data_len_t arej_info_len)
30210Sstevel@tonic-gate {
30224703Shiremath ibcm_rej_msg_t *rej_msg =
30234703Shiremath (ibcm_rej_msg_t *)IBCM_OUT_MSGP(statep->stored_msg);
30240Sstevel@tonic-gate
30250Sstevel@tonic-gate /* Message printed if connection gets REJed */
30260Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_post_rej_mad: "
3027401Shiremath "statep = %p, reject_reason = %d", statep, reject_reason);
30280Sstevel@tonic-gate
30290Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rej_msg))
30300Sstevel@tonic-gate
30310Sstevel@tonic-gate /* Initialize rej_msg fields */
30320Sstevel@tonic-gate rej_msg->rej_local_comm_id = h2b32(statep->local_comid);
30330Sstevel@tonic-gate rej_msg->rej_remote_comm_id = h2b32(statep->remote_comid);
30340Sstevel@tonic-gate rej_msg->rej_msg_type_plus = (which_msg & 0x3) << 6;
30350Sstevel@tonic-gate rej_msg->rej_reject_info_len_plus = arej_info_len << 1;
30360Sstevel@tonic-gate rej_msg->rej_rejection_reason = h2b16((uint16_t)reject_reason);
30370Sstevel@tonic-gate
30380Sstevel@tonic-gate if ((arej_info_len != 0) && (addl_rej_info != NULL))
30390Sstevel@tonic-gate bcopy(addl_rej_info, rej_msg->rej_addl_rej_info, arej_info_len);
30400Sstevel@tonic-gate
30410Sstevel@tonic-gate IBCM_OUT_HDRP(statep->stored_msg)->AttributeID =
30420Sstevel@tonic-gate h2b16(IBCM_INCOMING_REJ + IBCM_ATTR_BASE_ID);
30430Sstevel@tonic-gate
30440Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rej_msg))
30450Sstevel@tonic-gate
30460Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
30470Sstevel@tonic-gate
30480Sstevel@tonic-gate /* signal any waiting close channels with blocking or no callbacks */
30490Sstevel@tonic-gate statep->close_done = B_TRUE;
30500Sstevel@tonic-gate statep->close_nocb_state = IBCM_FAIL;
30510Sstevel@tonic-gate
30520Sstevel@tonic-gate cv_signal(&statep->block_client_cv);
30530Sstevel@tonic-gate
30540Sstevel@tonic-gate statep->timer_stored_state = statep->state = IBCM_STATE_REJ_SENT;
30550Sstevel@tonic-gate statep->send_mad_flags |= IBCM_REJ_POST_BUSY;
30560Sstevel@tonic-gate
30570Sstevel@tonic-gate IBCM_REF_CNT_INCR(statep); /* for non-blocking post */
30580Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
30590Sstevel@tonic-gate
30600Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_REJ);
30610Sstevel@tonic-gate if (ibcm_enable_trace & 2)
30620Sstevel@tonic-gate ibcm_dump_conn_trace(statep);
30634908Shiremath else
30644908Shiremath IBTF_DPRINTF_L2(cmlog, "ibcm_post_rej_mad statep %p "
30654908Shiremath "OUTGOING_REJ", statep);
30660Sstevel@tonic-gate
30670Sstevel@tonic-gate ibcm_post_rc_mad(statep, statep->stored_msg, ibcm_post_rej_complete,
30680Sstevel@tonic-gate statep);
30690Sstevel@tonic-gate }
30700Sstevel@tonic-gate
30710Sstevel@tonic-gate
30720Sstevel@tonic-gate /*
30730Sstevel@tonic-gate * ibcm_build_n_post_rej_mad:
30740Sstevel@tonic-gate * Builds and posts a REJ MAD for "reject_reason"
30750Sstevel@tonic-gate * Doesn't set a timer, and doesn't need statep
30760Sstevel@tonic-gate *
30770Sstevel@tonic-gate * INPUTS:
30780Sstevel@tonic-gate * input_madp - Incoming MAD
30790Sstevel@tonic-gate * remote_comid - Local comid in the message being rejected
30800Sstevel@tonic-gate * cm_mad_addr - Address information for the MAD to be posted
30810Sstevel@tonic-gate * which_msg - REJ message type ie., REJ for REQ/REP
30820Sstevel@tonic-gate *
30830Sstevel@tonic-gate * RETURN VALUE:
30840Sstevel@tonic-gate * NONE
30850Sstevel@tonic-gate */
30860Sstevel@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)30870Sstevel@tonic-gate ibcm_build_n_post_rej_mad(uint8_t *input_madp, ib_com_id_t remote_comid,
30880Sstevel@tonic-gate ibcm_mad_addr_t *cm_mad_addr, int which_msg, uint16_t reject_reason)
30890Sstevel@tonic-gate {
30900Sstevel@tonic-gate ibcm_rej_msg_t *rej_msg;
30910Sstevel@tonic-gate ibmf_msg_t *cm_rej_msg;
30920Sstevel@tonic-gate ibcm_mad_addr_t rej_reply_addr;
30930Sstevel@tonic-gate
30940Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_build_n_post_rej_mad: "
3095401Shiremath "remote_comid: %x reject_reason %d", remote_comid, reject_reason);
30960Sstevel@tonic-gate
30970Sstevel@tonic-gate if (ibcm_alloc_out_msg(cm_mad_addr->ibmf_hdl, &cm_rej_msg,
30980Sstevel@tonic-gate MAD_METHOD_SEND) != IBT_SUCCESS) {
30990Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_build_n_post_rej_mad: "
31000Sstevel@tonic-gate "ibcm_alloc_out_msg failed");
31010Sstevel@tonic-gate return;
31020Sstevel@tonic-gate }
31030Sstevel@tonic-gate
31040Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rej_msg))
31050Sstevel@tonic-gate
31060Sstevel@tonic-gate IBCM_OUT_HDRP(cm_rej_msg)->TransactionID =
31070Sstevel@tonic-gate ((ib_mad_hdr_t *)(input_madp))->TransactionID;
31080Sstevel@tonic-gate
31090Sstevel@tonic-gate /* Initialize rej_msg fields */
31100Sstevel@tonic-gate rej_msg = (ibcm_rej_msg_t *)IBCM_OUT_MSGP(cm_rej_msg);
31110Sstevel@tonic-gate rej_msg->rej_local_comm_id = 0;
31120Sstevel@tonic-gate rej_msg->rej_remote_comm_id = h2b32(remote_comid);
3113557Shiremath rej_msg->rej_msg_type_plus = (which_msg & 0x3) << 6;
31140Sstevel@tonic-gate rej_msg->rej_reject_info_len_plus = 0;
31150Sstevel@tonic-gate rej_msg->rej_rejection_reason = h2b16(reject_reason);
31160Sstevel@tonic-gate
31170Sstevel@tonic-gate IBCM_OUT_HDRP(cm_rej_msg)->AttributeID =
31180Sstevel@tonic-gate h2b16(IBCM_INCOMING_REJ + IBCM_ATTR_BASE_ID);
31190Sstevel@tonic-gate
31200Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rej_msg))
31210Sstevel@tonic-gate
31220Sstevel@tonic-gate ibcm_build_reply_mad_addr(cm_mad_addr, &rej_reply_addr);
31230Sstevel@tonic-gate
31240Sstevel@tonic-gate if (rej_reply_addr.cm_qp_entry != NULL) {
31250Sstevel@tonic-gate (void) ibcm_post_mad(cm_rej_msg, &rej_reply_addr, NULL, NULL);
31260Sstevel@tonic-gate ibcm_release_qp(rej_reply_addr.cm_qp_entry);
31270Sstevel@tonic-gate }
31280Sstevel@tonic-gate
31290Sstevel@tonic-gate (void) ibcm_free_out_msg(cm_mad_addr->ibmf_hdl, &cm_rej_msg);
31300Sstevel@tonic-gate }
31310Sstevel@tonic-gate
31320Sstevel@tonic-gate /* posts a REJ for an incoming REQ with unsupported class version */
31330Sstevel@tonic-gate
31340Sstevel@tonic-gate static void
ibcm_post_rej_ver_mismatch(uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)31350Sstevel@tonic-gate ibcm_post_rej_ver_mismatch(uint8_t *input_madp, ibcm_mad_addr_t *cm_mad_addr)
31360Sstevel@tonic-gate {
31374703Shiremath ibcm_req_msg_t *req_msgp =
31384703Shiremath (ibcm_req_msg_t *)&input_madp[IBCM_MAD_HDR_SIZE];
31390Sstevel@tonic-gate ibcm_rej_msg_t *rej_msg;
31400Sstevel@tonic-gate ibmf_msg_t *cm_rej_msg;
31410Sstevel@tonic-gate ibcm_mad_addr_t rej_reply_addr;
31420Sstevel@tonic-gate
31430Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_post_rej_ver_mismatch: remote comid %x",
31440Sstevel@tonic-gate b2h32(req_msgp->req_local_comm_id));
31450Sstevel@tonic-gate
31460Sstevel@tonic-gate if (ibcm_alloc_out_msg(cm_mad_addr->ibmf_hdl, &cm_rej_msg,
31470Sstevel@tonic-gate MAD_METHOD_SEND) != IBT_SUCCESS) {
31480Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_post_rej_ver_mismatch: "
31490Sstevel@tonic-gate "ibcm_alloc_out_msg failed");
31500Sstevel@tonic-gate return;
31510Sstevel@tonic-gate }
31520Sstevel@tonic-gate
31530Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rej_msg))
31540Sstevel@tonic-gate
31550Sstevel@tonic-gate IBCM_OUT_HDRP(cm_rej_msg)->TransactionID =
31560Sstevel@tonic-gate ((ib_mad_hdr_t *)(input_madp))->TransactionID;
31570Sstevel@tonic-gate
31580Sstevel@tonic-gate /* Initialize rej_msg fields */
31590Sstevel@tonic-gate rej_msg = (ibcm_rej_msg_t *)IBCM_OUT_MSGP(cm_rej_msg);
31600Sstevel@tonic-gate rej_msg->rej_local_comm_id = 0;
31610Sstevel@tonic-gate rej_msg->rej_remote_comm_id = req_msgp->req_local_comm_id;
31620Sstevel@tonic-gate rej_msg->rej_msg_type_plus = IBT_CM_FAILURE_REQ << 6;
31630Sstevel@tonic-gate rej_msg->rej_rejection_reason = h2b16(IBT_CM_CLASS_NO_SUPPORT);
31640Sstevel@tonic-gate rej_msg->rej_reject_info_len_plus = 1 << 1;
31650Sstevel@tonic-gate rej_msg->rej_addl_rej_info[0] = IBCM_MAD_CLASS_VERSION;
31660Sstevel@tonic-gate
31670Sstevel@tonic-gate IBCM_OUT_HDRP(cm_rej_msg)->AttributeID =
31684703Shiremath h2b16(IBCM_INCOMING_REJ + IBCM_ATTR_BASE_ID);
31690Sstevel@tonic-gate IBCM_OUT_HDRP(cm_rej_msg)->Status = h2b16(MAD_STATUS_BAD_VERSION);
31700Sstevel@tonic-gate
31710Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rej_msg))
31720Sstevel@tonic-gate
31730Sstevel@tonic-gate ibcm_build_reply_mad_addr(cm_mad_addr, &rej_reply_addr);
31740Sstevel@tonic-gate if (rej_reply_addr.cm_qp_entry != NULL) {
31750Sstevel@tonic-gate (void) ibcm_post_mad(cm_rej_msg, &rej_reply_addr, NULL, NULL);
31760Sstevel@tonic-gate ibcm_release_qp(rej_reply_addr.cm_qp_entry);
31770Sstevel@tonic-gate }
31780Sstevel@tonic-gate (void) ibcm_free_out_msg(cm_mad_addr->ibmf_hdl, &cm_rej_msg);
31790Sstevel@tonic-gate }
31800Sstevel@tonic-gate
31810Sstevel@tonic-gate
31820Sstevel@tonic-gate /*
31830Sstevel@tonic-gate * ibcm_post_rep_mad:
31840Sstevel@tonic-gate * Posts a REP MAD and starts timer
31850Sstevel@tonic-gate *
31860Sstevel@tonic-gate * INPUTS:
31870Sstevel@tonic-gate * statep - state pointer
31880Sstevel@tonic-gate *
31890Sstevel@tonic-gate * RETURN VALUE:
31900Sstevel@tonic-gate * NONE
31910Sstevel@tonic-gate */
31920Sstevel@tonic-gate void
ibcm_post_rep_mad(ibcm_state_data_t * statep)31930Sstevel@tonic-gate ibcm_post_rep_mad(ibcm_state_data_t *statep)
31940Sstevel@tonic-gate {
31954703Shiremath ibcm_rep_msg_t *rep_msgp =
31964703Shiremath (ibcm_rep_msg_t *)IBCM_OUT_MSGP(statep->stored_msg);
31970Sstevel@tonic-gate ibmf_msg_t *mra_msg = NULL;
31980Sstevel@tonic-gate boolean_t ret = B_FALSE;
31990Sstevel@tonic-gate
32000Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_post_rep_mad: statep 0x%p", statep);
32010Sstevel@tonic-gate
32020Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rep_msgp))
32030Sstevel@tonic-gate
32040Sstevel@tonic-gate /*
32050Sstevel@tonic-gate * All other REP fields, other that the 2 below, are filled in
32060Sstevel@tonic-gate * the ibcm_cep_state_req() function.
32070Sstevel@tonic-gate */
32080Sstevel@tonic-gate rep_msgp->rep_local_comm_id = h2b32(statep->local_comid);
32090Sstevel@tonic-gate rep_msgp->rep_remote_comm_id = h2b32(statep->remote_comid);
32100Sstevel@tonic-gate IBCM_OUT_HDRP(statep->stored_msg)->AttributeID =
32110Sstevel@tonic-gate h2b16(IBCM_INCOMING_REP + IBCM_ATTR_BASE_ID);
32120Sstevel@tonic-gate
32130Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rep_msgp))
32140Sstevel@tonic-gate
32150Sstevel@tonic-gate /*
32160Sstevel@tonic-gate * Changing state and attempt to delete the mra msg must be done
32170Sstevel@tonic-gate * together holding the state_mutex
32180Sstevel@tonic-gate */
32190Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
32200Sstevel@tonic-gate
32210Sstevel@tonic-gate /* Now, attempt to delete the mra_msg, if there is one allocated */
32220Sstevel@tonic-gate if (statep->mra_msg != NULL) {
32230Sstevel@tonic-gate if (!(statep->send_mad_flags & IBCM_MRA_POST_BUSY)) {
32240Sstevel@tonic-gate mra_msg = statep->mra_msg;
32250Sstevel@tonic-gate statep->mra_msg = NULL;
32260Sstevel@tonic-gate } else statep->delete_mra_msg = B_TRUE;
32270Sstevel@tonic-gate }
32280Sstevel@tonic-gate
32290Sstevel@tonic-gate if (statep->abort_flag == IBCM_ABORT_CLIENT) {
32300Sstevel@tonic-gate statep->state = IBCM_STATE_ABORTED;
32310Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
32320Sstevel@tonic-gate ibcm_process_abort(statep);
32330Sstevel@tonic-gate
32340Sstevel@tonic-gate /* Now post a REJ MAD, rej reason consumer abort */
32350Sstevel@tonic-gate ibcm_post_rej_mad(statep, IBT_CM_CONSUMER, IBT_CM_FAILURE_REQ,
32360Sstevel@tonic-gate NULL, 0);
32370Sstevel@tonic-gate ret = B_TRUE;
32380Sstevel@tonic-gate } else if (statep->abort_flag & IBCM_ABORT_REJ) {
32390Sstevel@tonic-gate
32400Sstevel@tonic-gate statep->state = IBCM_STATE_DELETE;
32410Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
32420Sstevel@tonic-gate
32430Sstevel@tonic-gate ibcm_process_abort(statep);
32440Sstevel@tonic-gate ibcm_delete_state_data(statep);
32450Sstevel@tonic-gate ret = B_TRUE;
32460Sstevel@tonic-gate } else {
32470Sstevel@tonic-gate
32480Sstevel@tonic-gate statep->state = statep->timer_stored_state =
32490Sstevel@tonic-gate IBCM_STATE_REP_SENT;
32500Sstevel@tonic-gate statep->remaining_retry_cnt = statep->max_cm_retries;
32510Sstevel@tonic-gate statep->send_mad_flags |= IBCM_REP_POST_BUSY;
32520Sstevel@tonic-gate IBCM_REF_CNT_INCR(statep); /* for nonblocking REP Post */
32530Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
32540Sstevel@tonic-gate }
32550Sstevel@tonic-gate
32560Sstevel@tonic-gate if (mra_msg != NULL)
32570Sstevel@tonic-gate (void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl,
32580Sstevel@tonic-gate &mra_msg);
32590Sstevel@tonic-gate if (ret == B_TRUE)
32600Sstevel@tonic-gate return;
32610Sstevel@tonic-gate
32620Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_REP);
32630Sstevel@tonic-gate
32640Sstevel@tonic-gate ibcm_post_rc_mad(statep, statep->stored_msg, ibcm_post_rep_complete,
32650Sstevel@tonic-gate statep);
32660Sstevel@tonic-gate }
32670Sstevel@tonic-gate
32680Sstevel@tonic-gate
32690Sstevel@tonic-gate /*
32700Sstevel@tonic-gate * ibcm_post_rtu_mad:
32710Sstevel@tonic-gate * From active side post RTU MAD
32720Sstevel@tonic-gate *
32730Sstevel@tonic-gate * INPUTS:
32740Sstevel@tonic-gate * statep - state pointer
32750Sstevel@tonic-gate *
32760Sstevel@tonic-gate * RETURN VALUE: NONE
32770Sstevel@tonic-gate *
32780Sstevel@tonic-gate * NOTE: No timer set after posting RTU
32790Sstevel@tonic-gate */
32800Sstevel@tonic-gate ibcm_status_t
ibcm_post_rtu_mad(ibcm_state_data_t * statep)32810Sstevel@tonic-gate ibcm_post_rtu_mad(ibcm_state_data_t *statep)
32820Sstevel@tonic-gate {
32830Sstevel@tonic-gate ibcm_rtu_msg_t *rtu_msg;
32840Sstevel@tonic-gate ibmf_msg_t *mra_msg = NULL;
32850Sstevel@tonic-gate boolean_t ret = B_FALSE;
32860Sstevel@tonic-gate
32870Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_post_rtu_mad: statep 0x%p", statep);
32880Sstevel@tonic-gate
32890Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rtu_msg))
32900Sstevel@tonic-gate
32910Sstevel@tonic-gate rtu_msg = (ibcm_rtu_msg_t *)IBCM_OUT_MSGP(statep->stored_msg);
32920Sstevel@tonic-gate
32930Sstevel@tonic-gate rtu_msg->rtu_local_comm_id = h2b32(statep->local_comid);
32940Sstevel@tonic-gate rtu_msg->rtu_remote_comm_id = h2b32(statep->remote_comid);
32950Sstevel@tonic-gate IBCM_OUT_HDRP(statep->stored_msg)->AttributeID =
32960Sstevel@tonic-gate h2b16(IBCM_INCOMING_RTU + IBCM_ATTR_BASE_ID);
32970Sstevel@tonic-gate
32980Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rtu_msg))
32990Sstevel@tonic-gate
33000Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
33010Sstevel@tonic-gate
33020Sstevel@tonic-gate /* Now, attempt to delete the mra_msg, if there is one allocated */
33030Sstevel@tonic-gate if (statep->mra_msg != NULL) {
33040Sstevel@tonic-gate if (!(statep->send_mad_flags & IBCM_MRA_POST_BUSY)) {
33050Sstevel@tonic-gate mra_msg = statep->mra_msg;
33060Sstevel@tonic-gate statep->mra_msg = NULL;
33070Sstevel@tonic-gate } else statep->delete_mra_msg = B_TRUE;
33080Sstevel@tonic-gate }
33090Sstevel@tonic-gate
33100Sstevel@tonic-gate if (statep->abort_flag == IBCM_ABORT_CLIENT) {
33110Sstevel@tonic-gate statep->state = IBCM_STATE_ABORTED;
33120Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
33130Sstevel@tonic-gate
33140Sstevel@tonic-gate ibcm_process_abort(statep);
33150Sstevel@tonic-gate
33160Sstevel@tonic-gate /* Now post a REJ MAD */
33170Sstevel@tonic-gate ibcm_post_rej_mad(statep, IBT_CM_CONSUMER, IBT_CM_FAILURE_REP,
33180Sstevel@tonic-gate NULL, 0);
33190Sstevel@tonic-gate ret = B_TRUE;
33200Sstevel@tonic-gate } else if (statep->abort_flag & IBCM_ABORT_REJ) {
33210Sstevel@tonic-gate statep->state = IBCM_STATE_DELETE;
33220Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
33230Sstevel@tonic-gate
33240Sstevel@tonic-gate ibcm_process_abort(statep);
33250Sstevel@tonic-gate ibcm_delete_state_data(statep);
33260Sstevel@tonic-gate ret = B_TRUE;
33270Sstevel@tonic-gate } else {
33280Sstevel@tonic-gate statep->state = IBCM_STATE_ESTABLISHED;
33290Sstevel@tonic-gate ibtl_cm_chan_is_open(statep->channel);
33300Sstevel@tonic-gate statep->send_mad_flags |= IBCM_RTU_POST_BUSY;
33310Sstevel@tonic-gate IBCM_REF_CNT_INCR(statep); /* for nonblocking RTU post */
33320Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
33330Sstevel@tonic-gate }
33340Sstevel@tonic-gate
33350Sstevel@tonic-gate if (mra_msg != NULL)
33360Sstevel@tonic-gate (void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl,
33370Sstevel@tonic-gate &mra_msg);
33380Sstevel@tonic-gate
33390Sstevel@tonic-gate if (ret == B_TRUE) /* Abort case, no RTU posted */
33400Sstevel@tonic-gate return (IBCM_FAILURE);
33410Sstevel@tonic-gate
33420Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_RTU);
33430Sstevel@tonic-gate
33440Sstevel@tonic-gate ibcm_post_rc_mad(statep, statep->stored_msg, ibcm_post_rtu_complete,
33450Sstevel@tonic-gate statep);
33460Sstevel@tonic-gate return (IBCM_SUCCESS);
33470Sstevel@tonic-gate }
33480Sstevel@tonic-gate
33490Sstevel@tonic-gate
33500Sstevel@tonic-gate /*
33510Sstevel@tonic-gate * ibcm_process_abort:
33520Sstevel@tonic-gate * Processes abort, if client requested abort connection attempt
33530Sstevel@tonic-gate *
33540Sstevel@tonic-gate * INPUTS:
33550Sstevel@tonic-gate * statep - pointer to ibcm_state_data_t is passed
33560Sstevel@tonic-gate *
33570Sstevel@tonic-gate * RETURN VALUES: None
33580Sstevel@tonic-gate */
33590Sstevel@tonic-gate void
ibcm_process_abort(ibcm_state_data_t * statep)33600Sstevel@tonic-gate ibcm_process_abort(ibcm_state_data_t *statep)
33610Sstevel@tonic-gate {
33620Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_process_abort: statep 0x%p", statep);
33630Sstevel@tonic-gate
33640Sstevel@tonic-gate /* move CEP to error state, before calling client handler */
33650Sstevel@tonic-gate (void) ibcm_cep_to_error_state(statep);
33660Sstevel@tonic-gate
33670Sstevel@tonic-gate /* Now disassociate the link between statep and qp */
33680Sstevel@tonic-gate IBCM_SET_CHAN_PRIVATE(statep->channel, NULL);
33690Sstevel@tonic-gate
33700Sstevel@tonic-gate /* invoke cm handler, for non-blocking open/close rc channel calls */
33710Sstevel@tonic-gate if (statep->cm_handler) { /* cannot be NULL, but still .. */
33720Sstevel@tonic-gate ibt_cm_event_t event;
33730Sstevel@tonic-gate ibt_cm_return_args_t ret_args;
33740Sstevel@tonic-gate
33750Sstevel@tonic-gate bzero(&event, sizeof (event));
33760Sstevel@tonic-gate bzero(&ret_args, sizeof (ret_args));
33770Sstevel@tonic-gate
33780Sstevel@tonic-gate if (statep->abort_flag & IBCM_ABORT_REJ)
33790Sstevel@tonic-gate ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_RCV,
33800Sstevel@tonic-gate IBT_CM_FAILURE_UNKNOWN, IBT_CM_TIMEOUT, NULL, 0);
33810Sstevel@tonic-gate else {
3382557Shiremath ibcm_path_cache_purge();
3383557Shiremath
33840Sstevel@tonic-gate event.cm_type = IBT_CM_EVENT_CONN_CLOSED;
33850Sstevel@tonic-gate event.cm_channel = statep->channel;
33860Sstevel@tonic-gate event.cm_event.closed = IBT_CM_CLOSED_ABORT;
33870Sstevel@tonic-gate
33880Sstevel@tonic-gate ibcm_insert_trace(statep,
33890Sstevel@tonic-gate IBCM_TRACE_CALLED_CONN_CLOSE_EVENT);
33900Sstevel@tonic-gate
3391*12292SPramod.Gunjikar@Sun.COM if (statep->channel)
3392*12292SPramod.Gunjikar@Sun.COM ibtl_cm_chan_open_is_aborted(statep->channel);
339312064SShantkumar.Hiremath@Sun.COM
33940Sstevel@tonic-gate (void) statep->cm_handler(statep->state_cm_private,
33950Sstevel@tonic-gate &event, &ret_args, NULL, 0);
33960Sstevel@tonic-gate
33970Sstevel@tonic-gate ibcm_insert_trace(statep,
33980Sstevel@tonic-gate IBCM_TRACE_RET_CONN_CLOSE_EVENT);
33990Sstevel@tonic-gate
34001093Shiremath mutex_enter(&statep->state_mutex);
34011093Shiremath ibcm_open_done(statep);
34021093Shiremath mutex_exit(&statep->state_mutex);
34030Sstevel@tonic-gate }
34040Sstevel@tonic-gate }
34050Sstevel@tonic-gate
34060Sstevel@tonic-gate /*
34070Sstevel@tonic-gate * Unblock an ibt_open_rc_channel called in a blocking mode, though
34080Sstevel@tonic-gate * it is an unlikely scenario
34090Sstevel@tonic-gate */
34100Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
34110Sstevel@tonic-gate
34121093Shiremath statep->cm_retries++; /* cause connection trace to be printed */
34130Sstevel@tonic-gate statep->open_done = B_TRUE;
34140Sstevel@tonic-gate statep->close_done = B_TRUE;
34150Sstevel@tonic-gate statep->close_nocb_state = IBCM_FAIL; /* sanity sake */
34160Sstevel@tonic-gate
34170Sstevel@tonic-gate if (statep->open_return_data != NULL) {
34180Sstevel@tonic-gate /* REJ came first, and then client aborted connection */
34190Sstevel@tonic-gate if (statep->abort_flag & IBCM_ABORT_REJ)
34200Sstevel@tonic-gate statep->open_return_data->rc_status = IBT_CM_TIMEOUT;
34210Sstevel@tonic-gate else statep->open_return_data->rc_status = IBT_CM_ABORT;
34220Sstevel@tonic-gate }
34230Sstevel@tonic-gate
34240Sstevel@tonic-gate cv_broadcast(&statep->block_client_cv);
34250Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
34261093Shiremath if (ibcm_enable_trace != 0)
34271093Shiremath ibcm_dump_conn_trace(statep);
34280Sstevel@tonic-gate }
34290Sstevel@tonic-gate
34300Sstevel@tonic-gate /*
34310Sstevel@tonic-gate * ibcm_timeout_cb:
34320Sstevel@tonic-gate * Called when the timer expires
34330Sstevel@tonic-gate *
34340Sstevel@tonic-gate * INPUTS:
34350Sstevel@tonic-gate * arg - ibcm_state_data_t is passed
34360Sstevel@tonic-gate *
34370Sstevel@tonic-gate * RETURN VALUES: NONE
34380Sstevel@tonic-gate */
34390Sstevel@tonic-gate void
ibcm_timeout_cb(void * arg)34400Sstevel@tonic-gate ibcm_timeout_cb(void *arg)
34410Sstevel@tonic-gate {
34420Sstevel@tonic-gate ibcm_state_data_t *statep = (ibcm_state_data_t *)arg;
34430Sstevel@tonic-gate
34440Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
34450Sstevel@tonic-gate
34460Sstevel@tonic-gate /*
34470Sstevel@tonic-gate * The blocking operations are handled in a separate thread.
34480Sstevel@tonic-gate * All other non-blocking operations, including ibmf non-blocking
34490Sstevel@tonic-gate * posts are done from timeout context
34500Sstevel@tonic-gate */
34510Sstevel@tonic-gate
34520Sstevel@tonic-gate if ((statep->timer_stored_state != statep->state) ||
34530Sstevel@tonic-gate ((statep->timer_stored_state == IBCM_STATE_ESTABLISHED) &&
34540Sstevel@tonic-gate (statep->ap_state != statep->timer_stored_ap_state))) {
34550Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
34560Sstevel@tonic-gate return;
34570Sstevel@tonic-gate }
34580Sstevel@tonic-gate
34590Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_timeout_cb: statep 0x%p state %x "
34600Sstevel@tonic-gate "ap_state %x", statep, statep->state, statep->ap_state);
34610Sstevel@tonic-gate
34620Sstevel@tonic-gate /* Processing depends upon current state */
34630Sstevel@tonic-gate
34640Sstevel@tonic-gate if (statep->state == IBCM_STATE_REJ_SENT) {
34650Sstevel@tonic-gate statep->state = IBCM_STATE_DELETE;
34660Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
34670Sstevel@tonic-gate
34680Sstevel@tonic-gate /* Deallocate the CM state structure */
34690Sstevel@tonic-gate ibcm_delete_state_data(statep);
34700Sstevel@tonic-gate return;
34710Sstevel@tonic-gate
34720Sstevel@tonic-gate } else if (statep->state == IBCM_STATE_TIMEWAIT) {
34730Sstevel@tonic-gate statep->state = IBCM_STATE_DELETE;
34740Sstevel@tonic-gate
34750Sstevel@tonic-gate /* TIME_WAIT timer expired, so cleanup */
34760Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
34770Sstevel@tonic-gate
34780Sstevel@tonic-gate if (statep->channel)
34790Sstevel@tonic-gate ibtl_cm_chan_is_closed(statep->channel);
34800Sstevel@tonic-gate
34810Sstevel@tonic-gate if (statep->recycle_arg) {
34820Sstevel@tonic-gate struct ibcm_taskq_recycle_arg_s *recycle_arg;
34830Sstevel@tonic-gate
34840Sstevel@tonic-gate recycle_arg = statep->recycle_arg;
34850Sstevel@tonic-gate
34860Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(
34870Sstevel@tonic-gate statep->recycle_arg))
34880Sstevel@tonic-gate statep->recycle_arg = NULL;
34890Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(statep->recycle_arg))
34900Sstevel@tonic-gate
34910Sstevel@tonic-gate /* if possible, do not slow down calling recycle func */
34920Sstevel@tonic-gate if (taskq_dispatch(ibcm_taskq, ibcm_process_rc_recycle,
34930Sstevel@tonic-gate recycle_arg, TQ_NOQUEUE | TQ_NOSLEEP) == 0) {
34940Sstevel@tonic-gate
34950Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(
34960Sstevel@tonic-gate statep->recycle_arg))
34970Sstevel@tonic-gate statep->recycle_arg = recycle_arg;
34980Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(
34990Sstevel@tonic-gate statep->recycle_arg))
35000Sstevel@tonic-gate ibcm_add_tlist(statep);
35010Sstevel@tonic-gate return;
35020Sstevel@tonic-gate }
35030Sstevel@tonic-gate }
35040Sstevel@tonic-gate
35050Sstevel@tonic-gate ibcm_delete_state_data(statep);
35060Sstevel@tonic-gate return;
35070Sstevel@tonic-gate } else if (statep->remaining_retry_cnt > 0) {
35080Sstevel@tonic-gate ibcm_conn_state_t stored_state;
35090Sstevel@tonic-gate ibcm_ap_state_t stored_ap_state;
35100Sstevel@tonic-gate
35110Sstevel@tonic-gate statep->remaining_retry_cnt--;
3512557Shiremath IBTF_DPRINTF_L3(cmlog, "ibcm_timeout_cb: statep 0x%p "
35130Sstevel@tonic-gate "attr-id= 0x%x, retries remaining = 0x%x", statep,
35140Sstevel@tonic-gate b2h16(IBCM_OUT_HDRP(statep->stored_msg)->AttributeID),
35150Sstevel@tonic-gate statep->remaining_retry_cnt);
35160Sstevel@tonic-gate
35170Sstevel@tonic-gate /*
35180Sstevel@tonic-gate * REP could be resent, either because of timeout or an
35190Sstevel@tonic-gate * incoming REQ. Any other MAD below can be resent, because
35200Sstevel@tonic-gate * of timeout only, hence send_mad_flag manipulation not
35210Sstevel@tonic-gate * required for those cases.
35220Sstevel@tonic-gate * If REP is already being retransmitted, then just set the
35230Sstevel@tonic-gate * timer and return. Else post REP in non-blocking mode
35240Sstevel@tonic-gate */
35250Sstevel@tonic-gate if (statep->timer_stored_state == IBCM_STATE_REP_SENT) {
35260Sstevel@tonic-gate if (statep->send_mad_flags & IBCM_REP_POST_BUSY) {
35270Sstevel@tonic-gate statep->timerid = IBCM_TIMEOUT(statep,
35280Sstevel@tonic-gate statep->timer_value);
35290Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
35300Sstevel@tonic-gate ibcm_insert_trace(statep,
35310Sstevel@tonic-gate IBCM_TRACE_TIMEOUT_REP);
35320Sstevel@tonic-gate return;
35330Sstevel@tonic-gate }
35340Sstevel@tonic-gate
35350Sstevel@tonic-gate /*
35360Sstevel@tonic-gate * Set REP busy flag, so any incoming REQ's will not
35370Sstevel@tonic-gate * initiate new REP transmissions
35380Sstevel@tonic-gate */
35390Sstevel@tonic-gate statep->send_mad_flags |= IBCM_REP_POST_BUSY;
35400Sstevel@tonic-gate
35410Sstevel@tonic-gate /* Since REQ/RTU/REJ on active side use same MAD, synchronize */
35420Sstevel@tonic-gate } else if (statep->timer_stored_state == IBCM_STATE_REQ_SENT) {
35430Sstevel@tonic-gate ASSERT((statep->send_mad_flags & IBCM_REQ_POST_BUSY)
35440Sstevel@tonic-gate == 0);
35450Sstevel@tonic-gate statep->send_mad_flags |= IBCM_REQ_POST_BUSY;
35460Sstevel@tonic-gate }
35470Sstevel@tonic-gate
35480Sstevel@tonic-gate IBCM_REF_CNT_INCR(statep); /* for non-blocking post */
35490Sstevel@tonic-gate stored_state = statep->timer_stored_state;
35500Sstevel@tonic-gate stored_ap_state = statep->timer_stored_ap_state;
35510Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
35520Sstevel@tonic-gate
35530Sstevel@tonic-gate /* Post REQ MAD in non-blocking mode */
35540Sstevel@tonic-gate if (stored_state == IBCM_STATE_REQ_SENT) {
35551093Shiremath ibcm_insert_trace(statep, IBCM_TRACE_OUT_REQ_RETRY);
35560Sstevel@tonic-gate ibcm_post_rc_mad(statep, statep->stored_msg,
35570Sstevel@tonic-gate ibcm_post_req_complete, statep);
35580Sstevel@tonic-gate /* Post REQ MAD in non-blocking mode */
35590Sstevel@tonic-gate } else if (stored_state == IBCM_STATE_REP_WAIT) {
35601093Shiremath ibcm_insert_trace(statep, IBCM_TRACE_OUT_REQ_RETRY);
35610Sstevel@tonic-gate ibcm_post_rc_mad(statep, statep->stored_msg,
35620Sstevel@tonic-gate ibcm_post_rep_wait_complete, statep);
35630Sstevel@tonic-gate /* Post REP MAD in non-blocking mode */
35640Sstevel@tonic-gate } else if (stored_state == IBCM_STATE_REP_SENT) {
35651093Shiremath ibcm_insert_trace(statep, IBCM_TRACE_OUT_REP_RETRY);
35660Sstevel@tonic-gate ibcm_post_rc_mad(statep, statep->stored_msg,
35670Sstevel@tonic-gate ibcm_post_rep_complete, statep);
35680Sstevel@tonic-gate /* Post REP MAD in non-blocking mode */
35690Sstevel@tonic-gate } else if (stored_state == IBCM_STATE_MRA_REP_RCVD) {
35701093Shiremath ibcm_insert_trace(statep, IBCM_TRACE_OUT_REP_RETRY);
35711093Shiremath mutex_enter(&statep->state_mutex);
35721093Shiremath statep->mra_time = gethrtime();
35731093Shiremath mutex_exit(&statep->state_mutex);
35740Sstevel@tonic-gate ibcm_post_rc_mad(statep, statep->stored_msg,
35750Sstevel@tonic-gate ibcm_post_mra_rep_complete, statep);
35760Sstevel@tonic-gate /* Post DREQ MAD in non-blocking mode */
35770Sstevel@tonic-gate } else if (stored_state == IBCM_STATE_DREQ_SENT) {
35781093Shiremath mutex_enter(&statep->state_mutex);
35791093Shiremath if (statep->remaining_retry_cnt ==
35801093Shiremath statep->max_cm_retries)
35811093Shiremath ibcm_insert_trace(statep,
35821093Shiremath IBCM_TRACE_OUTGOING_DREQ);
35831093Shiremath else {
35841093Shiremath ibcm_insert_trace(statep,
35851093Shiremath IBCM_TRACE_OUT_DREQ_RETRY);
35861093Shiremath statep->cm_retries++;
35871093Shiremath ibcm_close_done(statep, 0);
35881093Shiremath }
35891093Shiremath mutex_exit(&statep->state_mutex);
35900Sstevel@tonic-gate ibcm_post_rc_mad(statep, statep->dreq_msg,
35910Sstevel@tonic-gate ibcm_post_dreq_complete, statep);
35920Sstevel@tonic-gate /* post LAP MAD in non-blocking mode */
35930Sstevel@tonic-gate } else if (stored_ap_state == IBCM_AP_STATE_LAP_SENT) {
35941093Shiremath ibcm_insert_trace(statep, IBCM_TRACE_OUT_LAP_RETRY);
35950Sstevel@tonic-gate ibcm_post_rc_mad(statep, statep->lapr_msg,
35960Sstevel@tonic-gate ibcm_post_lap_complete, statep);
35970Sstevel@tonic-gate /* post LAP MAD in non-blocking mode */
35980Sstevel@tonic-gate } else if (stored_ap_state == IBCM_AP_STATE_MRA_LAP_RCVD) {
35991093Shiremath ibcm_insert_trace(statep, IBCM_TRACE_OUT_LAP_RETRY);
36001093Shiremath mutex_enter(&statep->state_mutex);
36011093Shiremath statep->mra_time = gethrtime();
36021093Shiremath mutex_exit(&statep->state_mutex);
36030Sstevel@tonic-gate ibcm_post_rc_mad(statep, statep->lapr_msg,
36040Sstevel@tonic-gate ibcm_post_mra_lap_complete, statep);
36050Sstevel@tonic-gate }
36060Sstevel@tonic-gate return;
36070Sstevel@tonic-gate
36080Sstevel@tonic-gate } else if ((statep->state == IBCM_STATE_REQ_SENT) ||
36090Sstevel@tonic-gate (statep->state == IBCM_STATE_REP_SENT) ||
36100Sstevel@tonic-gate (statep->state == IBCM_STATE_MRA_REP_RCVD) ||
36110Sstevel@tonic-gate (statep->state == IBCM_STATE_REP_WAIT)) {
36120Sstevel@tonic-gate
36130Sstevel@tonic-gate /*
36140Sstevel@tonic-gate * MAX retries reached, send a REJ to the remote,
36150Sstevel@tonic-gate * and close the connection
36160Sstevel@tonic-gate */
36170Sstevel@tonic-gate statep->timedout_state = statep->state;
36180Sstevel@tonic-gate statep->state = IBCM_STATE_TIMED_OUT;
36190Sstevel@tonic-gate
36200Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_timeout_cb: "
36210Sstevel@tonic-gate "max retries done for statep 0x%p", statep);
36221093Shiremath statep->cm_retries++; /* cause conn trace to print */
36230Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
36240Sstevel@tonic-gate
36250Sstevel@tonic-gate if ((statep->timedout_state == IBCM_STATE_REP_SENT) ||
36260Sstevel@tonic-gate (statep->timedout_state == IBCM_STATE_MRA_REP_RCVD))
36270Sstevel@tonic-gate (void) ibcm_cep_to_error_state(statep);
36280Sstevel@tonic-gate
36290Sstevel@tonic-gate /* Disassociate statep from QP */
36300Sstevel@tonic-gate IBCM_SET_CHAN_PRIVATE(statep->channel, NULL);
36310Sstevel@tonic-gate
36320Sstevel@tonic-gate /*
36330Sstevel@tonic-gate * statep is in REJ SENT state, the only way to get deleted is
36340Sstevel@tonic-gate * the timeout callback that is set after posting REJ
36350Sstevel@tonic-gate * The thread processing is required where cm handler is
36360Sstevel@tonic-gate * specified
36370Sstevel@tonic-gate */
36380Sstevel@tonic-gate
36390Sstevel@tonic-gate if (statep->cm_handler != NULL) {
36400Sstevel@tonic-gate /* Attach the statep to timeout list */
36410Sstevel@tonic-gate ibcm_add_tlist(statep);
36420Sstevel@tonic-gate } else {
36430Sstevel@tonic-gate ib_guid_t local_hca_guid;
36440Sstevel@tonic-gate
36450Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
36460Sstevel@tonic-gate
36470Sstevel@tonic-gate /*
36480Sstevel@tonic-gate * statep->open_return_data is set for blocking
36490Sstevel@tonic-gate * No handler specified, hence signal blocked
36500Sstevel@tonic-gate * ibt_open_rc_channel from here
36510Sstevel@tonic-gate */
36520Sstevel@tonic-gate if (statep->open_return_data != NULL) {
36530Sstevel@tonic-gate statep->open_return_data->rc_status =
36540Sstevel@tonic-gate IBT_CM_TIMEOUT;
36550Sstevel@tonic-gate statep->open_done = B_TRUE;
36560Sstevel@tonic-gate cv_broadcast(&statep->block_client_cv);
36570Sstevel@tonic-gate }
36580Sstevel@tonic-gate
36590Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
36600Sstevel@tonic-gate
36610Sstevel@tonic-gate local_hca_guid = h2b64(statep->local_hca_guid);
36620Sstevel@tonic-gate ibcm_post_rej_mad(statep, IBT_CM_TIMEOUT,
36630Sstevel@tonic-gate (statep->timedout_state == IBCM_STATE_REP_SENT ||
36640Sstevel@tonic-gate statep->timedout_state == IBCM_STATE_MRA_REP_RCVD) ?
36650Sstevel@tonic-gate IBT_CM_FAILURE_REP: IBT_CM_FAILURE_REQ,
36660Sstevel@tonic-gate &local_hca_guid, sizeof (ib_guid_t));
36670Sstevel@tonic-gate }
36680Sstevel@tonic-gate
36690Sstevel@tonic-gate } else if ((statep->ap_state == IBCM_AP_STATE_LAP_SENT) ||
36700Sstevel@tonic-gate (statep->ap_state == IBCM_AP_STATE_MRA_LAP_RCVD)) {
36710Sstevel@tonic-gate
3672557Shiremath IBTF_DPRINTF_L4(cmlog, "ibcm_timeout_cb: statep 0x%p "
36730Sstevel@tonic-gate "LAP timed out", statep);
36740Sstevel@tonic-gate statep->timedout_state = statep->state;
36750Sstevel@tonic-gate /*
36760Sstevel@tonic-gate * This state setting ensures that the processing of DREQ is
36770Sstevel@tonic-gate * sequentialized, once this ap_state is set. If statep is
36780Sstevel@tonic-gate * attached to timeout list, it cannot be re-attached as long
36790Sstevel@tonic-gate * as in this state
36800Sstevel@tonic-gate */
36810Sstevel@tonic-gate statep->ap_state = IBCM_AP_STATE_TIMED_OUT;
36821093Shiremath ibcm_open_done(statep);
36830Sstevel@tonic-gate
36840Sstevel@tonic-gate if (statep->cm_handler != NULL) {
36850Sstevel@tonic-gate /* Attach statep to timeout list - thread handling */
36860Sstevel@tonic-gate ibcm_add_tlist(statep);
36870Sstevel@tonic-gate } else if (statep->ap_return_data != NULL) {
36880Sstevel@tonic-gate /*
36890Sstevel@tonic-gate * statep->ap_return_data is initialized for blocking in
36900Sstevel@tonic-gate * ibt_set_alt_path(), signal the waiting CV
36910Sstevel@tonic-gate */
36920Sstevel@tonic-gate statep->ap_return_data->ap_status = IBT_CM_AP_TIMEOUT;
36930Sstevel@tonic-gate statep->ap_done = B_TRUE;
36940Sstevel@tonic-gate cv_broadcast(&statep->block_client_cv);
36950Sstevel@tonic-gate
36960Sstevel@tonic-gate statep->ap_state = IBCM_AP_STATE_IDLE;
36970Sstevel@tonic-gate /* Wake up threads waiting for LAP/APR to complete */
36980Sstevel@tonic-gate cv_broadcast(&statep->block_mad_cv);
36990Sstevel@tonic-gate }
37000Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
37010Sstevel@tonic-gate
37020Sstevel@tonic-gate } else if (statep->state == IBCM_STATE_DREQ_SENT) {
37030Sstevel@tonic-gate
37040Sstevel@tonic-gate statep->timedout_state = statep->state;
37050Sstevel@tonic-gate statep->state = IBCM_STATE_TIMED_OUT;
37060Sstevel@tonic-gate
37070Sstevel@tonic-gate /*
37080Sstevel@tonic-gate * The logic below is necessary, for a race situation between
37090Sstevel@tonic-gate * ibt_close_rc_channel with no callbacks option and CM's
37100Sstevel@tonic-gate * internal stale connection handling on the same connection
37110Sstevel@tonic-gate */
37120Sstevel@tonic-gate if (statep->close_nocb_state != IBCM_FAIL) {
37130Sstevel@tonic-gate ASSERT(statep->close_nocb_state == IBCM_UNBLOCK);
37140Sstevel@tonic-gate ibtl_cm_chan_is_closing(statep->channel);
37150Sstevel@tonic-gate statep->close_nocb_state = IBCM_BLOCK;
37160Sstevel@tonic-gate }
37170Sstevel@tonic-gate
37180Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
37190Sstevel@tonic-gate
37200Sstevel@tonic-gate /*
37210Sstevel@tonic-gate * If cm handler is specified, then invoke handler for
37220Sstevel@tonic-gate * the DREQ timeout
37230Sstevel@tonic-gate */
37240Sstevel@tonic-gate if (statep->cm_handler != NULL) {
37250Sstevel@tonic-gate ibcm_add_tlist(statep);
37260Sstevel@tonic-gate return;
37270Sstevel@tonic-gate }
37280Sstevel@tonic-gate
37290Sstevel@tonic-gate ibcm_process_dreq_timeout(statep);
37300Sstevel@tonic-gate } else {
37310Sstevel@tonic-gate
37320Sstevel@tonic-gate #ifdef DEBUG
37330Sstevel@tonic-gate if (ibcm_test_mode > 0)
37340Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_timeout_cb: "
37350Sstevel@tonic-gate "Unexpected unhandled timeout for statep 0x%p "
37360Sstevel@tonic-gate "state %d", statep, statep->state);
37370Sstevel@tonic-gate #endif
37380Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
37390Sstevel@tonic-gate }
37400Sstevel@tonic-gate }
37410Sstevel@tonic-gate
37420Sstevel@tonic-gate /*
37430Sstevel@tonic-gate * Following are set of ibmf send callback routines that are used when posting
37440Sstevel@tonic-gate * various CM MADs in non-blocking post mode
37450Sstevel@tonic-gate */
37460Sstevel@tonic-gate
37470Sstevel@tonic-gate /*ARGSUSED*/
37480Sstevel@tonic-gate void
ibcm_post_req_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)37490Sstevel@tonic-gate ibcm_post_req_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, void *args)
37500Sstevel@tonic-gate {
37510Sstevel@tonic-gate ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
37520Sstevel@tonic-gate
37530Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_post_req_complete statep %p ", statep);
37540Sstevel@tonic-gate
37551093Shiremath mutex_enter(&statep->state_mutex);
37561093Shiremath ibcm_flow_dec(statep->post_time, "REQ");
37570Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_REQ_POST_COMPLETE);
37580Sstevel@tonic-gate
37590Sstevel@tonic-gate statep->send_mad_flags &= ~IBCM_REQ_POST_BUSY;
37600Sstevel@tonic-gate
37610Sstevel@tonic-gate /* signal any waiting threads for REQ MAD to become available */
37620Sstevel@tonic-gate cv_signal(&statep->block_mad_cv);
37630Sstevel@tonic-gate
37640Sstevel@tonic-gate if (statep->state == IBCM_STATE_REQ_SENT)
37650Sstevel@tonic-gate statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
37660Sstevel@tonic-gate
37670Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
37680Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
37690Sstevel@tonic-gate }
37700Sstevel@tonic-gate
37710Sstevel@tonic-gate /*ARGSUSED*/
37720Sstevel@tonic-gate void
ibcm_post_rep_wait_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)37730Sstevel@tonic-gate ibcm_post_rep_wait_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
37740Sstevel@tonic-gate void *args)
37750Sstevel@tonic-gate {
37760Sstevel@tonic-gate ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
37770Sstevel@tonic-gate
37780Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_post_rep_wait_complete statep %p", statep);
37790Sstevel@tonic-gate
37801093Shiremath mutex_enter(&statep->state_mutex);
37811093Shiremath ibcm_flow_dec(statep->post_time, "REQ_RETRY");
37820Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_REQ_POST_COMPLETE);
37830Sstevel@tonic-gate if (statep->state == IBCM_STATE_REP_WAIT)
37840Sstevel@tonic-gate statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
37850Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
37860Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
37870Sstevel@tonic-gate }
37880Sstevel@tonic-gate
37890Sstevel@tonic-gate /*ARGSUSED*/
37900Sstevel@tonic-gate void
ibcm_post_rep_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)37910Sstevel@tonic-gate ibcm_post_rep_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, void *args)
37920Sstevel@tonic-gate {
37930Sstevel@tonic-gate ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
37940Sstevel@tonic-gate
37950Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_post_rep_complete statep %p", statep);
37960Sstevel@tonic-gate
37971093Shiremath mutex_enter(&statep->state_mutex);
37981093Shiremath ibcm_flow_dec(statep->post_time, "REP");
37990Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_REP_POST_COMPLETE);
38000Sstevel@tonic-gate statep->send_mad_flags &= ~IBCM_REP_POST_BUSY;
38010Sstevel@tonic-gate if (statep->state == IBCM_STATE_REP_SENT)
38020Sstevel@tonic-gate statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
38030Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
38040Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
38050Sstevel@tonic-gate }
38060Sstevel@tonic-gate
38070Sstevel@tonic-gate /*ARGSUSED*/
38080Sstevel@tonic-gate void
ibcm_resend_post_rep_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)38090Sstevel@tonic-gate ibcm_resend_post_rep_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
38100Sstevel@tonic-gate void *args)
38110Sstevel@tonic-gate {
38120Sstevel@tonic-gate ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
38130Sstevel@tonic-gate
3814557Shiremath IBTF_DPRINTF_L4(cmlog, "ibcm_resend_post_rep_complete(%p)", statep);
38150Sstevel@tonic-gate
38161093Shiremath mutex_enter(&statep->state_mutex);
38171093Shiremath ibcm_flow_dec(statep->post_time, "REP_RETRY");
38180Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_REP_POST_COMPLETE);
38190Sstevel@tonic-gate statep->send_mad_flags &= ~IBCM_REP_POST_BUSY;
38200Sstevel@tonic-gate
38210Sstevel@tonic-gate /* No new timeout is set for resending a REP MAD for an incoming REQ */
38220Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
38230Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
38240Sstevel@tonic-gate }
38250Sstevel@tonic-gate
38260Sstevel@tonic-gate /*ARGSUSED*/
38270Sstevel@tonic-gate void
ibcm_post_mra_rep_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)38280Sstevel@tonic-gate ibcm_post_mra_rep_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
38290Sstevel@tonic-gate void *args)
38300Sstevel@tonic-gate {
38310Sstevel@tonic-gate ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
38320Sstevel@tonic-gate
38330Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_post_mra_rep_complete statep %p", statep);
38340Sstevel@tonic-gate
38351093Shiremath mutex_enter(&statep->state_mutex);
38361093Shiremath ibcm_flow_dec(statep->mra_time, "MRA_REP");
38370Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_REP_POST_COMPLETE);
38380Sstevel@tonic-gate if (statep->state == IBCM_STATE_MRA_REP_RCVD)
38390Sstevel@tonic-gate statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
38400Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
38410Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
38420Sstevel@tonic-gate }
38430Sstevel@tonic-gate
38440Sstevel@tonic-gate
38450Sstevel@tonic-gate /*ARGSUSED*/
38460Sstevel@tonic-gate void
ibcm_post_mra_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)38470Sstevel@tonic-gate ibcm_post_mra_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
38480Sstevel@tonic-gate void *args)
38490Sstevel@tonic-gate {
38500Sstevel@tonic-gate ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
38510Sstevel@tonic-gate
38520Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_post_mra_complete statep %p", statep);
38530Sstevel@tonic-gate
38541093Shiremath mutex_enter(&statep->state_mutex);
38551093Shiremath ibcm_flow_dec(statep->mra_time, "MRA");
38560Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_MRA_POST_COMPLETE);
38570Sstevel@tonic-gate
38580Sstevel@tonic-gate if (statep->delete_mra_msg == B_TRUE) {
38590Sstevel@tonic-gate ibmf_msg_t *mra_msg;
38600Sstevel@tonic-gate
38610Sstevel@tonic-gate mra_msg = statep->mra_msg;
38620Sstevel@tonic-gate statep->mra_msg = NULL;
38630Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
38640Sstevel@tonic-gate (void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl,
38650Sstevel@tonic-gate &mra_msg);
38660Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
38670Sstevel@tonic-gate }
38680Sstevel@tonic-gate statep->send_mad_flags &= ~IBCM_MRA_POST_BUSY;
38690Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
38700Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
38710Sstevel@tonic-gate }
38720Sstevel@tonic-gate
38730Sstevel@tonic-gate /*ARGSUSED*/
38740Sstevel@tonic-gate void
ibcm_post_dreq_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)38750Sstevel@tonic-gate ibcm_post_dreq_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, void *args)
38760Sstevel@tonic-gate {
38770Sstevel@tonic-gate ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
38780Sstevel@tonic-gate
38790Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_post_dreq_complete statep %p", statep);
38800Sstevel@tonic-gate
38811093Shiremath mutex_enter(&statep->state_mutex);
38821093Shiremath ibcm_flow_dec(statep->post_time, "DREQ");
38830Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_DREQ_POST_COMPLETE);
38840Sstevel@tonic-gate if (statep->state == IBCM_STATE_DREQ_SENT)
38850Sstevel@tonic-gate statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
38861093Shiremath ibcm_close_done(statep, 1);
38870Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
38880Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
38890Sstevel@tonic-gate }
38900Sstevel@tonic-gate
38910Sstevel@tonic-gate /*ARGSUSED*/
38920Sstevel@tonic-gate void
ibcm_post_lap_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)38930Sstevel@tonic-gate ibcm_post_lap_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, void *args)
38940Sstevel@tonic-gate {
38950Sstevel@tonic-gate ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
38960Sstevel@tonic-gate
38970Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_post_lap_complete statep %p", statep);
38980Sstevel@tonic-gate
38991093Shiremath mutex_enter(&statep->state_mutex);
39001093Shiremath ibcm_flow_dec(statep->post_time, "LAP");
39010Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_LAP_POST_COMPLETE);
39020Sstevel@tonic-gate if (statep->ap_state == IBCM_AP_STATE_LAP_SENT)
39030Sstevel@tonic-gate statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
39040Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
39050Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
39060Sstevel@tonic-gate }
39070Sstevel@tonic-gate
39080Sstevel@tonic-gate /*ARGSUSED*/
39090Sstevel@tonic-gate void
ibcm_post_mra_lap_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)39100Sstevel@tonic-gate ibcm_post_mra_lap_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
39110Sstevel@tonic-gate void *args)
39120Sstevel@tonic-gate {
39130Sstevel@tonic-gate ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
39140Sstevel@tonic-gate
39150Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_post_mra_lap_complete statep %p", statep);
39160Sstevel@tonic-gate
39171093Shiremath mutex_enter(&statep->state_mutex);
39181093Shiremath ibcm_flow_dec(statep->mra_time, "MRA_LAP");
39190Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_LAP_POST_COMPLETE);
39200Sstevel@tonic-gate if (statep->ap_state == IBCM_AP_STATE_MRA_LAP_RCVD)
39210Sstevel@tonic-gate statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
39220Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
39230Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
39240Sstevel@tonic-gate }
39250Sstevel@tonic-gate
39260Sstevel@tonic-gate /*ARGSUSED*/
39270Sstevel@tonic-gate void
ibcm_post_rej_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)39280Sstevel@tonic-gate ibcm_post_rej_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
39290Sstevel@tonic-gate void *args)
39300Sstevel@tonic-gate {
39310Sstevel@tonic-gate ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
39320Sstevel@tonic-gate
39330Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_post_rej_complete statep %p", statep);
39340Sstevel@tonic-gate
39351093Shiremath mutex_enter(&statep->state_mutex);
39361093Shiremath ibcm_flow_dec(statep->post_time, "REJ");
39370Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_REJ_POST_COMPLETE);
39380Sstevel@tonic-gate statep->send_mad_flags &= ~IBCM_REJ_POST_BUSY;
39390Sstevel@tonic-gate if (statep->state == IBCM_STATE_REJ_SENT) {
39400Sstevel@tonic-gate statep->remaining_retry_cnt = 0;
39410Sstevel@tonic-gate
39420Sstevel@tonic-gate /* wait until all possible retransmits of REQ/REP happened */
39430Sstevel@tonic-gate statep->timerid = IBCM_TIMEOUT(statep,
39440Sstevel@tonic-gate statep->timer_value * statep->max_cm_retries);
39450Sstevel@tonic-gate }
39460Sstevel@tonic-gate
39470Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
39480Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
39490Sstevel@tonic-gate }
39500Sstevel@tonic-gate
39510Sstevel@tonic-gate /*ARGSUSED*/
39520Sstevel@tonic-gate void
ibcm_post_rtu_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)39530Sstevel@tonic-gate ibcm_post_rtu_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
39540Sstevel@tonic-gate void *args)
39550Sstevel@tonic-gate {
39560Sstevel@tonic-gate ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
39570Sstevel@tonic-gate
39580Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_post_rtu_complete statep %p", statep);
39590Sstevel@tonic-gate
39601093Shiremath mutex_enter(&statep->state_mutex);
39611093Shiremath ibcm_flow_dec(statep->post_time, "RTU");
39620Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_RTU_POST_COMPLETE);
39630Sstevel@tonic-gate statep->send_mad_flags &= ~IBCM_RTU_POST_BUSY;
39640Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
39651093Shiremath ibcm_open_done(statep);
39660Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
39670Sstevel@tonic-gate }
39680Sstevel@tonic-gate
39690Sstevel@tonic-gate /*ARGSUSED*/
39700Sstevel@tonic-gate void
ibcm_post_apr_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)39710Sstevel@tonic-gate ibcm_post_apr_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
39720Sstevel@tonic-gate void *args)
39730Sstevel@tonic-gate {
39740Sstevel@tonic-gate ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
39750Sstevel@tonic-gate
39760Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_post_apr_complete statep %p", statep);
39770Sstevel@tonic-gate
39781093Shiremath mutex_enter(&statep->state_mutex);
39791093Shiremath ibcm_flow_dec(statep->post_time, "APR");
39800Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_APR_POST_COMPLETE);
39810Sstevel@tonic-gate /* As long as one APR mad in transit, no retransmits are allowed */
39820Sstevel@tonic-gate statep->ap_state = IBCM_AP_STATE_IDLE;
39830Sstevel@tonic-gate
39840Sstevel@tonic-gate /* unblock any DREQ threads and close channels */
39850Sstevel@tonic-gate cv_broadcast(&statep->block_mad_cv);
39860Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep); /* decrement the ref count */
39870Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
39880Sstevel@tonic-gate
39890Sstevel@tonic-gate }
39900Sstevel@tonic-gate
39910Sstevel@tonic-gate /*ARGSUSED*/
39920Sstevel@tonic-gate void
ibcm_post_stored_apr_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)39930Sstevel@tonic-gate ibcm_post_stored_apr_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
39940Sstevel@tonic-gate void *args)
39950Sstevel@tonic-gate {
39960Sstevel@tonic-gate ibmf_msg_t *ibmf_apr_msg = (ibmf_msg_t *)args;
39970Sstevel@tonic-gate
39980Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_post_stored_apr_complete args %p", args);
39990Sstevel@tonic-gate
40001093Shiremath ibcm_flow_dec(0, "APR_RESEND");
40010Sstevel@tonic-gate (void) ibcm_free_out_msg(ibmf_handle, &ibmf_apr_msg);
40020Sstevel@tonic-gate }
40030Sstevel@tonic-gate
40040Sstevel@tonic-gate /*ARGSUSED*/
40050Sstevel@tonic-gate void
ibcm_post_drep_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)40060Sstevel@tonic-gate ibcm_post_drep_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
40070Sstevel@tonic-gate void *args)
40080Sstevel@tonic-gate {
40090Sstevel@tonic-gate ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
40100Sstevel@tonic-gate
40110Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_post_drep_complete statep %p", statep);
40120Sstevel@tonic-gate
40131093Shiremath mutex_enter(&statep->state_mutex);
40141093Shiremath ibcm_flow_dec(statep->post_time, "DREP");
40150Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_DREP_POST_COMPLETE);
40160Sstevel@tonic-gate statep->send_mad_flags &= ~IBCM_REJ_POST_BUSY;
40170Sstevel@tonic-gate
40180Sstevel@tonic-gate if (statep->state == IBCM_STATE_DREQ_RCVD) {
40190Sstevel@tonic-gate
40201093Shiremath ibcm_close_done(statep, 1);
40210Sstevel@tonic-gate statep->state = IBCM_STATE_TIMEWAIT;
40220Sstevel@tonic-gate
40230Sstevel@tonic-gate /*
40240Sstevel@tonic-gate * For passive side CM set it to remote_ack_delay
40250Sstevel@tonic-gate * For active side CM add the pkt_life_time * 2
40260Sstevel@tonic-gate */
40270Sstevel@tonic-gate statep->timer_value = statep->remote_ack_delay;
40280Sstevel@tonic-gate if (statep->mode == IBCM_ACTIVE_MODE)
40290Sstevel@tonic-gate statep->timer_value += (2 * statep->pkt_life_time);
40300Sstevel@tonic-gate statep->remaining_retry_cnt = 0;
40310Sstevel@tonic-gate statep->timer_stored_state = statep->state;
40320Sstevel@tonic-gate statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
40330Sstevel@tonic-gate }
40340Sstevel@tonic-gate
40350Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
40360Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
40370Sstevel@tonic-gate }
40380Sstevel@tonic-gate
40390Sstevel@tonic-gate /*ARGSUSED*/
40400Sstevel@tonic-gate void
ibcm_post_sidr_rep_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)40410Sstevel@tonic-gate ibcm_post_sidr_rep_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
40420Sstevel@tonic-gate void *args)
40430Sstevel@tonic-gate {
40440Sstevel@tonic-gate ibcm_ud_state_data_t *ud_statep = (ibcm_ud_state_data_t *)args;
40450Sstevel@tonic-gate
40460Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_post_sidr_rep_complete ud_statep %p",
40470Sstevel@tonic-gate ud_statep);
40480Sstevel@tonic-gate
40491093Shiremath ibcm_flow_dec(0, "SIDR_REP");
40500Sstevel@tonic-gate mutex_enter(&ud_statep->ud_state_mutex);
40510Sstevel@tonic-gate ud_statep->ud_send_mad_flags &= ~IBCM_SREP_POST_BUSY;
40520Sstevel@tonic-gate ud_statep->ud_remaining_retry_cnt = 0;
40530Sstevel@tonic-gate if (ud_statep->ud_state == IBCM_STATE_SIDR_REP_SENT)
40540Sstevel@tonic-gate ud_statep->ud_timerid = IBCM_UD_TIMEOUT(ud_statep,
40550Sstevel@tonic-gate ud_statep->ud_timer_value);
40560Sstevel@tonic-gate IBCM_UD_REF_CNT_DECR(ud_statep);
40570Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
40580Sstevel@tonic-gate
40590Sstevel@tonic-gate }
40600Sstevel@tonic-gate
40610Sstevel@tonic-gate /*ARGSUSED*/
40620Sstevel@tonic-gate void
ibcm_post_sidr_req_complete(ibmf_handle_t ibmf_handle,ibmf_msg_t * msgp,void * args)40630Sstevel@tonic-gate ibcm_post_sidr_req_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
40640Sstevel@tonic-gate void *args)
40650Sstevel@tonic-gate {
40660Sstevel@tonic-gate ibcm_ud_state_data_t *ud_statep = (ibcm_ud_state_data_t *)args;
40670Sstevel@tonic-gate
40680Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_post_sidr_req_complete ud_statep %p",
40690Sstevel@tonic-gate ud_statep);
40700Sstevel@tonic-gate
40711093Shiremath ibcm_flow_dec(0, "SIDR_REQ");
40720Sstevel@tonic-gate mutex_enter(&ud_statep->ud_state_mutex);
40730Sstevel@tonic-gate if (ud_statep->ud_state == IBCM_STATE_SIDR_REQ_SENT)
40740Sstevel@tonic-gate ud_statep->ud_timerid = IBCM_UD_TIMEOUT(ud_statep,
40750Sstevel@tonic-gate ud_statep->ud_timer_value);
40760Sstevel@tonic-gate IBCM_UD_REF_CNT_DECR(ud_statep);
40770Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
40780Sstevel@tonic-gate
40790Sstevel@tonic-gate }
40800Sstevel@tonic-gate
40810Sstevel@tonic-gate /*
40820Sstevel@tonic-gate * ibcm_process_dreq_timeout:
40830Sstevel@tonic-gate * Called when the timer expires on DREP
40840Sstevel@tonic-gate *
40850Sstevel@tonic-gate * INPUTS:
40860Sstevel@tonic-gate * arg - ibcm_state_data_t is passed
40870Sstevel@tonic-gate *
40880Sstevel@tonic-gate * RETURN VALUES: NONE
40890Sstevel@tonic-gate */
40900Sstevel@tonic-gate void
ibcm_process_dreq_timeout(ibcm_state_data_t * statep)40910Sstevel@tonic-gate ibcm_process_dreq_timeout(ibcm_state_data_t *statep)
40920Sstevel@tonic-gate {
40930Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
40940Sstevel@tonic-gate
40950Sstevel@tonic-gate /* Max retries reached, move to the time wait state */
40960Sstevel@tonic-gate statep->state = statep->timer_stored_state =
40970Sstevel@tonic-gate IBCM_STATE_TIMEWAIT;
40981093Shiremath ibcm_close_done(statep, 0);
40990Sstevel@tonic-gate
41000Sstevel@tonic-gate /* Set the TIME_WAIT state timer value */
41010Sstevel@tonic-gate statep->timer_value = statep->remote_ack_delay;
41020Sstevel@tonic-gate if (statep->mode == IBCM_ACTIVE_MODE) {
41030Sstevel@tonic-gate statep->timer_value += (2 * statep->pkt_life_time);
41040Sstevel@tonic-gate }
41050Sstevel@tonic-gate
41060Sstevel@tonic-gate statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
41070Sstevel@tonic-gate
41080Sstevel@tonic-gate if (statep->close_ret_status)
41090Sstevel@tonic-gate if (statep->stale == B_TRUE)
41100Sstevel@tonic-gate *statep->close_ret_status = IBT_CM_CLOSED_STALE;
41110Sstevel@tonic-gate else *statep->close_ret_status = IBT_CM_CLOSED_DREQ_TIMEOUT;
41120Sstevel@tonic-gate
41130Sstevel@tonic-gate /* signal waiting CVs - blocking in ibt_close_channel() */
41140Sstevel@tonic-gate statep->close_done = B_TRUE;
41153241Shiremath if (statep->close_ret_priv_data_len != NULL)
41163241Shiremath *statep->close_ret_priv_data_len = 0;
41170Sstevel@tonic-gate
41180Sstevel@tonic-gate /* unblock any close channel with no callbacks option */
41190Sstevel@tonic-gate statep->close_nocb_state = IBCM_FAIL;
41200Sstevel@tonic-gate
41210Sstevel@tonic-gate cv_broadcast(&statep->block_client_cv);
41220Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
41230Sstevel@tonic-gate }
41240Sstevel@tonic-gate
41250Sstevel@tonic-gate /*
41260Sstevel@tonic-gate * ibcm_add_tlist:
41270Sstevel@tonic-gate * Adds the given RC statep to timeout list
41280Sstevel@tonic-gate *
41290Sstevel@tonic-gate * INPUTS:
41300Sstevel@tonic-gate * arg - ibcm_state_data_t is passed
41310Sstevel@tonic-gate *
41320Sstevel@tonic-gate * RETURN VALUES: NONE
41330Sstevel@tonic-gate */
41340Sstevel@tonic-gate void
ibcm_add_tlist(ibcm_state_data_t * statep)41350Sstevel@tonic-gate ibcm_add_tlist(ibcm_state_data_t *statep)
41360Sstevel@tonic-gate {
41370Sstevel@tonic-gate mutex_enter(&ibcm_timeout_list_lock);
41380Sstevel@tonic-gate
41390Sstevel@tonic-gate statep->timeout_next = NULL;
41400Sstevel@tonic-gate if (ibcm_timeout_list_hdr == NULL) {
41410Sstevel@tonic-gate ibcm_timeout_list_hdr = statep;
41420Sstevel@tonic-gate } else {
41430Sstevel@tonic-gate ibcm_timeout_list_tail->timeout_next = statep;
41440Sstevel@tonic-gate }
41450Sstevel@tonic-gate
41460Sstevel@tonic-gate ibcm_timeout_list_tail = statep;
41470Sstevel@tonic-gate
41480Sstevel@tonic-gate cv_signal(&ibcm_timeout_list_cv);
41490Sstevel@tonic-gate
41500Sstevel@tonic-gate mutex_exit(&ibcm_timeout_list_lock);
41510Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_add_tlist: "
41520Sstevel@tonic-gate "attached state = %p to timeout list", statep);
41530Sstevel@tonic-gate }
41540Sstevel@tonic-gate
41551093Shiremath void
ibcm_run_tlist_thread(void)41561093Shiremath ibcm_run_tlist_thread(void)
41571093Shiremath {
41581093Shiremath mutex_enter(&ibcm_timeout_list_lock);
41591093Shiremath cv_signal(&ibcm_timeout_list_cv);
41601093Shiremath mutex_exit(&ibcm_timeout_list_lock);
41611093Shiremath }
41620Sstevel@tonic-gate
41630Sstevel@tonic-gate /*
41640Sstevel@tonic-gate * ibcm_add_ud_tlist:
41650Sstevel@tonic-gate * Adds the given UD statep to timeout list
41660Sstevel@tonic-gate *
41670Sstevel@tonic-gate * INPUTS:
41680Sstevel@tonic-gate * arg - ibcm_ud_state_data_t is passed
41690Sstevel@tonic-gate *
41700Sstevel@tonic-gate * RETURN VALUES: NONE
41710Sstevel@tonic-gate */
41720Sstevel@tonic-gate void
ibcm_add_ud_tlist(ibcm_ud_state_data_t * ud_statep)41730Sstevel@tonic-gate ibcm_add_ud_tlist(ibcm_ud_state_data_t *ud_statep)
41740Sstevel@tonic-gate {
41750Sstevel@tonic-gate mutex_enter(&ibcm_timeout_list_lock);
41760Sstevel@tonic-gate
41770Sstevel@tonic-gate ud_statep->ud_timeout_next = NULL;
41780Sstevel@tonic-gate if (ibcm_ud_timeout_list_hdr == NULL) {
41790Sstevel@tonic-gate ibcm_ud_timeout_list_hdr = ud_statep;
41800Sstevel@tonic-gate } else {
41810Sstevel@tonic-gate ibcm_ud_timeout_list_tail->ud_timeout_next = ud_statep;
41820Sstevel@tonic-gate }
41830Sstevel@tonic-gate
41840Sstevel@tonic-gate ibcm_ud_timeout_list_tail = ud_statep;
41850Sstevel@tonic-gate
41860Sstevel@tonic-gate cv_signal(&ibcm_timeout_list_cv);
41870Sstevel@tonic-gate
41880Sstevel@tonic-gate mutex_exit(&ibcm_timeout_list_lock);
41890Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_add_ud_tlist: "
41900Sstevel@tonic-gate "attached state = %p to ud timeout list", ud_statep);
41910Sstevel@tonic-gate }
41920Sstevel@tonic-gate
41930Sstevel@tonic-gate /*
41940Sstevel@tonic-gate * ibcm_process_tlist:
41950Sstevel@tonic-gate * Thread that processes all the RC and UD statep's from
41960Sstevel@tonic-gate * the appropriate lists
41970Sstevel@tonic-gate *
41980Sstevel@tonic-gate * INPUTS:
41990Sstevel@tonic-gate * NONE
42000Sstevel@tonic-gate *
42010Sstevel@tonic-gate * RETURN VALUES: NONE
42020Sstevel@tonic-gate */
42030Sstevel@tonic-gate void
ibcm_process_tlist()42040Sstevel@tonic-gate ibcm_process_tlist()
42050Sstevel@tonic-gate {
42060Sstevel@tonic-gate ibcm_state_data_t *statep;
42070Sstevel@tonic-gate ibcm_ud_state_data_t *ud_statep;
42080Sstevel@tonic-gate callb_cpr_t cprinfo;
42090Sstevel@tonic-gate
42100Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_process_tlist: thread started");
42110Sstevel@tonic-gate
42120Sstevel@tonic-gate mutex_enter(&ibcm_timeout_list_lock);
42130Sstevel@tonic-gate
42140Sstevel@tonic-gate CALLB_CPR_INIT(&cprinfo, &ibcm_timeout_list_lock, callb_generic_cpr,
42150Sstevel@tonic-gate "ibcm_process_tlist");
42160Sstevel@tonic-gate
42170Sstevel@tonic-gate for (;;) {
42180Sstevel@tonic-gate if (ibcm_timeout_list_flags & IBCM_TIMEOUT_THREAD_EXIT) {
42190Sstevel@tonic-gate /* The thread needs to exit */
42200Sstevel@tonic-gate cv_signal(&ibcm_timeout_thread_done_cv);
42210Sstevel@tonic-gate break;
42220Sstevel@tonic-gate }
42231093Shiremath mutex_exit(&ibcm_timeout_list_lock);
42241093Shiremath ibcm_check_for_opens();
42253241Shiremath ibcm_check_for_async_close();
42261093Shiremath mutex_enter(&ibcm_timeout_list_lock);
42270Sstevel@tonic-gate
42280Sstevel@tonic-gate /* First, handle pending RC statep's, followed by UD's */
42290Sstevel@tonic-gate if (ibcm_timeout_list_hdr != NULL) {
42300Sstevel@tonic-gate statep = ibcm_timeout_list_hdr;
42310Sstevel@tonic-gate ibcm_timeout_list_hdr = statep->timeout_next;
42320Sstevel@tonic-gate
42330Sstevel@tonic-gate if (ibcm_timeout_list_hdr == NULL)
42344703Shiremath ibcm_timeout_list_tail = NULL;
42350Sstevel@tonic-gate
42360Sstevel@tonic-gate statep->timeout_next = NULL;
42370Sstevel@tonic-gate
42380Sstevel@tonic-gate mutex_exit(&ibcm_timeout_list_lock);
42390Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_process_tlist: "
42400Sstevel@tonic-gate "scheduling state = %p", statep);
42410Sstevel@tonic-gate ibcm_timeout_client_cb(statep);
42420Sstevel@tonic-gate mutex_enter(&ibcm_timeout_list_lock);
42430Sstevel@tonic-gate } else if (ibcm_ud_timeout_list_hdr != NULL) {
42440Sstevel@tonic-gate ud_statep = ibcm_ud_timeout_list_hdr;
42450Sstevel@tonic-gate ibcm_ud_timeout_list_hdr = ud_statep->ud_timeout_next;
42460Sstevel@tonic-gate
42470Sstevel@tonic-gate if (ibcm_ud_timeout_list_hdr == NULL)
42484703Shiremath ibcm_ud_timeout_list_tail = NULL;
42490Sstevel@tonic-gate
42500Sstevel@tonic-gate ud_statep->ud_timeout_next = NULL;
42510Sstevel@tonic-gate
42520Sstevel@tonic-gate mutex_exit(&ibcm_timeout_list_lock);
42530Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_process_tlist: "
42540Sstevel@tonic-gate "ud scheduling state = %p", ud_statep);
42550Sstevel@tonic-gate ibcm_ud_timeout_client_cb(ud_statep);
42560Sstevel@tonic-gate mutex_enter(&ibcm_timeout_list_lock);
42570Sstevel@tonic-gate } else {
42580Sstevel@tonic-gate CALLB_CPR_SAFE_BEGIN(&cprinfo);
42590Sstevel@tonic-gate cv_wait(&ibcm_timeout_list_cv, &ibcm_timeout_list_lock);
42600Sstevel@tonic-gate CALLB_CPR_SAFE_END(&cprinfo, &ibcm_timeout_list_lock);
42610Sstevel@tonic-gate }
42620Sstevel@tonic-gate }
42630Sstevel@tonic-gate
42640Sstevel@tonic-gate #ifndef __lock_lint
42650Sstevel@tonic-gate CALLB_CPR_EXIT(&cprinfo); /* mutex_exit */
42660Sstevel@tonic-gate #endif
42670Sstevel@tonic-gate }
42680Sstevel@tonic-gate
42690Sstevel@tonic-gate
42700Sstevel@tonic-gate /*
42710Sstevel@tonic-gate * ibcm_timeout_client_cb:
42720Sstevel@tonic-gate * Called from timeout thread processing
42730Sstevel@tonic-gate * Primary purpose is to call client handler
42740Sstevel@tonic-gate *
42750Sstevel@tonic-gate * INPUTS:
42760Sstevel@tonic-gate * arg - ibcm_state_data_t is passed
42770Sstevel@tonic-gate *
42780Sstevel@tonic-gate * RETURN VALUES: NONE
42790Sstevel@tonic-gate */
42800Sstevel@tonic-gate void
ibcm_timeout_client_cb(ibcm_state_data_t * statep)42810Sstevel@tonic-gate ibcm_timeout_client_cb(ibcm_state_data_t *statep)
42820Sstevel@tonic-gate {
42830Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
42840Sstevel@tonic-gate
42850Sstevel@tonic-gate if ((statep->state == IBCM_STATE_DELETE) &&
42860Sstevel@tonic-gate (statep->recycle_arg != NULL)) {
42870Sstevel@tonic-gate struct ibcm_taskq_recycle_arg_s *recycle_arg;
42880Sstevel@tonic-gate
42890Sstevel@tonic-gate recycle_arg = statep->recycle_arg;
42900Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(statep->recycle_arg))
42910Sstevel@tonic-gate statep->recycle_arg = NULL;
42920Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(statep->recycle_arg))
42930Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
42940Sstevel@tonic-gate (void) ibcm_process_rc_recycle(recycle_arg);
42950Sstevel@tonic-gate ibcm_delete_state_data(statep);
42960Sstevel@tonic-gate return;
42970Sstevel@tonic-gate }
42980Sstevel@tonic-gate
42990Sstevel@tonic-gate if ((statep->state == IBCM_STATE_DELETE) &&
43000Sstevel@tonic-gate (statep->delete_state_data == B_TRUE)) {
43010Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
43020Sstevel@tonic-gate ibcm_dealloc_state_data(statep);
43030Sstevel@tonic-gate return;
43040Sstevel@tonic-gate }
43050Sstevel@tonic-gate
43060Sstevel@tonic-gate /* Else, it must be in TIMEOUT state, do the necessary processing */
43070Sstevel@tonic-gate if (statep->state == IBCM_STATE_TIMED_OUT) {
43080Sstevel@tonic-gate void *data;
43090Sstevel@tonic-gate uint8_t cf_msg;
43100Sstevel@tonic-gate ib_guid_t local_hca_guid;
43110Sstevel@tonic-gate
43120Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
43130Sstevel@tonic-gate
43140Sstevel@tonic-gate if (statep->timedout_state == IBCM_STATE_DREQ_SENT) {
43150Sstevel@tonic-gate ibt_cm_event_t event;
43160Sstevel@tonic-gate ibt_cm_return_args_t ret_args;
43170Sstevel@tonic-gate
43180Sstevel@tonic-gate bzero(&event, sizeof (event));
43190Sstevel@tonic-gate bzero(&ret_args, sizeof (ret_args));
43200Sstevel@tonic-gate
43210Sstevel@tonic-gate event.cm_type = IBT_CM_EVENT_CONN_CLOSED;
43220Sstevel@tonic-gate event.cm_channel = statep->channel;
43230Sstevel@tonic-gate event.cm_session_id = NULL;
43240Sstevel@tonic-gate event.cm_priv_data = NULL;
43250Sstevel@tonic-gate event.cm_priv_data_len = 0;
43260Sstevel@tonic-gate
43270Sstevel@tonic-gate if (statep->stale == B_TRUE)
43280Sstevel@tonic-gate event.cm_event.closed = IBT_CM_CLOSED_STALE;
43290Sstevel@tonic-gate else event.cm_event.closed = IBT_CM_CLOSED_DREQ_TIMEOUT;
43300Sstevel@tonic-gate
43310Sstevel@tonic-gate /*
43320Sstevel@tonic-gate * cm handler cannot be non-NULL, as that check is
43330Sstevel@tonic-gate * already made in ibcm_timeout_cb
43340Sstevel@tonic-gate */
43350Sstevel@tonic-gate ibcm_insert_trace(statep,
43360Sstevel@tonic-gate IBCM_TRACE_CALLED_CONN_CLOSE_EVENT);
43370Sstevel@tonic-gate
43380Sstevel@tonic-gate (void) statep->cm_handler(statep->state_cm_private,
43390Sstevel@tonic-gate &event, &ret_args, NULL, 0);
43400Sstevel@tonic-gate
43410Sstevel@tonic-gate ibcm_insert_trace(statep,
43420Sstevel@tonic-gate IBCM_TRACE_RET_CONN_CLOSE_EVENT);
43430Sstevel@tonic-gate
43440Sstevel@tonic-gate ibcm_process_dreq_timeout(statep);
43450Sstevel@tonic-gate return;
43460Sstevel@tonic-gate }
43470Sstevel@tonic-gate
43480Sstevel@tonic-gate data = ((ibcm_rej_msg_t *)
43490Sstevel@tonic-gate IBCM_OUT_MSGP(statep->stored_msg))->rej_private_data;
43500Sstevel@tonic-gate
43510Sstevel@tonic-gate if ((statep->timedout_state == IBCM_STATE_REQ_SENT) ||
43520Sstevel@tonic-gate (statep->timedout_state == IBCM_STATE_REP_WAIT)) {
43530Sstevel@tonic-gate cf_msg = IBT_CM_FAILURE_REQ;
43540Sstevel@tonic-gate } else {
43550Sstevel@tonic-gate ASSERT(
43560Sstevel@tonic-gate (statep->timedout_state == IBCM_STATE_REP_SENT) ||
43570Sstevel@tonic-gate (statep->timedout_state ==
43580Sstevel@tonic-gate IBCM_STATE_MRA_REP_RCVD));
43590Sstevel@tonic-gate cf_msg = IBT_CM_FAILURE_REP;
43600Sstevel@tonic-gate }
43610Sstevel@tonic-gate
43620Sstevel@tonic-gate /*
43630Sstevel@tonic-gate * Invoke the CM handler w/ event IBT_CM_EVENT_TIMEOUT
43640Sstevel@tonic-gate * This callback happens for only active non blocking or
43650Sstevel@tonic-gate * passive client
43660Sstevel@tonic-gate */
43670Sstevel@tonic-gate ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_TIMEOUT,
43680Sstevel@tonic-gate cf_msg, IBT_CM_TIMEOUT, data, IBT_REJ_PRIV_DATA_SZ);
43690Sstevel@tonic-gate
43700Sstevel@tonic-gate /* signal the blocked ibt_open_rc_channel */
43710Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
43720Sstevel@tonic-gate
43730Sstevel@tonic-gate /*
43740Sstevel@tonic-gate * statep->open_return_data is set for blocking
43750Sstevel@tonic-gate * signal the blocked ibt_open_rc_channel
43760Sstevel@tonic-gate */
43770Sstevel@tonic-gate if (statep->open_return_data != NULL) {
43780Sstevel@tonic-gate statep->open_return_data->rc_status = IBT_CM_TIMEOUT;
43790Sstevel@tonic-gate statep->open_done = B_TRUE;
43800Sstevel@tonic-gate cv_broadcast(&statep->block_client_cv);
43810Sstevel@tonic-gate }
43820Sstevel@tonic-gate
43830Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
43840Sstevel@tonic-gate
43850Sstevel@tonic-gate local_hca_guid = h2b64(statep->local_hca_guid);
43860Sstevel@tonic-gate ibcm_post_rej_mad(statep, IBT_CM_TIMEOUT,
43870Sstevel@tonic-gate IBT_CM_FAILURE_UNKNOWN, &local_hca_guid,
43880Sstevel@tonic-gate sizeof (ib_guid_t));
43890Sstevel@tonic-gate } else if (statep->ap_state == IBCM_AP_STATE_TIMED_OUT) {
43900Sstevel@tonic-gate
43910Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
43920Sstevel@tonic-gate
43930Sstevel@tonic-gate ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_TIMEOUT,
43940Sstevel@tonic-gate IBT_CM_FAILURE_LAP, IBT_CM_TIMEOUT, NULL, 0);
43950Sstevel@tonic-gate
43960Sstevel@tonic-gate /* Now wake up threads waiting for LAP/APR to complete */
43970Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
43980Sstevel@tonic-gate /*
43990Sstevel@tonic-gate * statep->ap_return_data is initialized for blocking in
44000Sstevel@tonic-gate * ibt_set_alt_path(), signal the waiting CV
44010Sstevel@tonic-gate */
44020Sstevel@tonic-gate if (statep->ap_return_data != NULL) {
44030Sstevel@tonic-gate statep->ap_return_data->ap_status = IBT_CM_AP_TIMEOUT;
44040Sstevel@tonic-gate statep->ap_done = B_TRUE;
44050Sstevel@tonic-gate cv_broadcast(&statep->block_client_cv);
44060Sstevel@tonic-gate }
44070Sstevel@tonic-gate statep->ap_state = IBCM_AP_STATE_IDLE;
44080Sstevel@tonic-gate cv_broadcast(&statep->block_mad_cv);
44090Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
44100Sstevel@tonic-gate } else {
44110Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_timeout_client_cb "
44120Sstevel@tonic-gate "Unexpected else path statep %p state %d ap_state %d",
44130Sstevel@tonic-gate statep, statep->state, statep->ap_state);
44140Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
44150Sstevel@tonic-gate
44160Sstevel@tonic-gate }
44170Sstevel@tonic-gate }
44180Sstevel@tonic-gate
44190Sstevel@tonic-gate /*
44200Sstevel@tonic-gate * ibcm_ud_timeout_client_cb:
44210Sstevel@tonic-gate * Called from UD timeout thread processing
44220Sstevel@tonic-gate * Primary purpose is to call client handler
44230Sstevel@tonic-gate *
44240Sstevel@tonic-gate * INPUTS:
44250Sstevel@tonic-gate * arg - ibcm_ud_state_data_t is passed
44260Sstevel@tonic-gate *
44270Sstevel@tonic-gate * RETURN VALUES: NONE
44280Sstevel@tonic-gate */
44290Sstevel@tonic-gate void
ibcm_ud_timeout_client_cb(ibcm_ud_state_data_t * ud_statep)44300Sstevel@tonic-gate ibcm_ud_timeout_client_cb(ibcm_ud_state_data_t *ud_statep)
44310Sstevel@tonic-gate {
44320Sstevel@tonic-gate ibt_cm_ud_event_t ud_event;
44330Sstevel@tonic-gate
44340Sstevel@tonic-gate mutex_enter(&ud_statep->ud_state_mutex);
44350Sstevel@tonic-gate
44360Sstevel@tonic-gate if ((ud_statep->ud_state == IBCM_STATE_DELETE) &&
44370Sstevel@tonic-gate (ud_statep->ud_delete_state_data == B_TRUE)) {
44380Sstevel@tonic-gate
44390Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
44400Sstevel@tonic-gate ibcm_dealloc_ud_state_data(ud_statep);
44410Sstevel@tonic-gate return;
44420Sstevel@tonic-gate } else
44430Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
44440Sstevel@tonic-gate
44450Sstevel@tonic-gate /* Fill in ibt_cm_ud_event_t */
44460Sstevel@tonic-gate ud_event.cm_type = IBT_CM_UD_EVENT_SIDR_REP;
44470Sstevel@tonic-gate ud_event.cm_session_id = NULL;
44480Sstevel@tonic-gate ud_event.cm_event.sidr_rep.srep_status = IBT_CM_SREP_TIMEOUT;
44490Sstevel@tonic-gate
44500Sstevel@tonic-gate (void) ud_statep->ud_cm_handler(ud_statep->ud_state_cm_private,
44510Sstevel@tonic-gate &ud_event, NULL, NULL, 0);
44520Sstevel@tonic-gate
44530Sstevel@tonic-gate /* Delete UD state data now, finally done with it */
44540Sstevel@tonic-gate ibcm_delete_ud_state_data(ud_statep);
44550Sstevel@tonic-gate }
44560Sstevel@tonic-gate
44570Sstevel@tonic-gate
44580Sstevel@tonic-gate /*
44590Sstevel@tonic-gate * ibcm_process_sidr_req_msg:
44600Sstevel@tonic-gate * This call processes an incoming SIDR REQ
44610Sstevel@tonic-gate *
44620Sstevel@tonic-gate * INPUTS:
44630Sstevel@tonic-gate * hcap - HCA entry pointer
44640Sstevel@tonic-gate * input_madp - Incoming CM SIDR REQ MAD
44650Sstevel@tonic-gate * cm_mad_addr - Address information for the MAD to be posted
44660Sstevel@tonic-gate *
44670Sstevel@tonic-gate * RETURN VALUE:
44680Sstevel@tonic-gate * NONE
44690Sstevel@tonic-gate */
44700Sstevel@tonic-gate void
ibcm_process_sidr_req_msg(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)44710Sstevel@tonic-gate ibcm_process_sidr_req_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
44720Sstevel@tonic-gate ibcm_mad_addr_t *cm_mad_addr)
44730Sstevel@tonic-gate {
44740Sstevel@tonic-gate ib_gid_t gid;
44750Sstevel@tonic-gate ib_lid_t lid;
44760Sstevel@tonic-gate uint32_t req_id;
44770Sstevel@tonic-gate ibcm_status_t state_lookup_status;
44780Sstevel@tonic-gate ibcm_status_t cm_status;
44790Sstevel@tonic-gate ibt_sidr_status_t sidr_status;
44800Sstevel@tonic-gate ibcm_svc_info_t *svc_infop;
44810Sstevel@tonic-gate ibcm_svc_bind_t *svc_bindp;
44820Sstevel@tonic-gate ibcm_svc_bind_t *tmp_bindp;
44830Sstevel@tonic-gate ibcm_sidr_req_msg_t *sidr_reqp = (ibcm_sidr_req_msg_t *)
44844703Shiremath (&input_madp[IBCM_MAD_HDR_SIZE]);
44850Sstevel@tonic-gate ibcm_ud_state_data_t *ud_statep = NULL;
44860Sstevel@tonic-gate ibcm_sidr_srch_t srch_sidr;
44870Sstevel@tonic-gate ib_pkey_t pkey;
44880Sstevel@tonic-gate uint8_t port_num;
44890Sstevel@tonic-gate ib_guid_t hca_guid;
44900Sstevel@tonic-gate
44910Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_sidr_req_msg:");
44920Sstevel@tonic-gate
44930Sstevel@tonic-gate hca_guid = hcap->hca_guid;
44940Sstevel@tonic-gate port_num = cm_mad_addr->port_num;
44950Sstevel@tonic-gate
44960Sstevel@tonic-gate /* Figure out LID, GID, RequestId for svc_id lookup */
44970Sstevel@tonic-gate lid = cm_mad_addr->rcvd_addr.ia_remote_lid;
44980Sstevel@tonic-gate req_id = b2h32(sidr_reqp->sidr_req_request_id);
44990Sstevel@tonic-gate pkey = b2h16(sidr_reqp->sidr_req_pkey);
45000Sstevel@tonic-gate if (cm_mad_addr->grh_exists == B_TRUE)
45010Sstevel@tonic-gate gid = cm_mad_addr->grh_hdr.ig_sender_gid;
45020Sstevel@tonic-gate else
45030Sstevel@tonic-gate gid.gid_prefix = gid.gid_guid = 0;
45040Sstevel@tonic-gate
45050Sstevel@tonic-gate /*
45060Sstevel@tonic-gate * Lookup for an existing state structure
45070Sstevel@tonic-gate * - if lookup fails it creates a new ud_state struct
45080Sstevel@tonic-gate * No need to hold a lock across the call to ibcm_find_sidr_entry() as
45090Sstevel@tonic-gate * the list lock is held in that function to find the matching entry.
45100Sstevel@tonic-gate */
45110Sstevel@tonic-gate
45120Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(srch_sidr))
45130Sstevel@tonic-gate
45140Sstevel@tonic-gate srch_sidr.srch_lid = lid;
45150Sstevel@tonic-gate srch_sidr.srch_gid = gid;
45160Sstevel@tonic-gate srch_sidr.srch_grh_exists = cm_mad_addr->grh_exists;
45170Sstevel@tonic-gate srch_sidr.srch_req_id = req_id;
45180Sstevel@tonic-gate srch_sidr.srch_mode = IBCM_PASSIVE_MODE;
45190Sstevel@tonic-gate
45200Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(srch_sidr))
45210Sstevel@tonic-gate
45220Sstevel@tonic-gate rw_enter(&hcap->hca_sidr_list_lock, RW_WRITER);
45230Sstevel@tonic-gate state_lookup_status = ibcm_find_sidr_entry(&srch_sidr, hcap, &ud_statep,
45240Sstevel@tonic-gate IBCM_FLAG_LOOKUP_AND_ADD);
45250Sstevel@tonic-gate rw_exit(&hcap->hca_sidr_list_lock);
45260Sstevel@tonic-gate
45270Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_sidr_req_msg: ud_statep 0x%p "
45280Sstevel@tonic-gate "lookup status %x", ud_statep, state_lookup_status);
45290Sstevel@tonic-gate
45300Sstevel@tonic-gate if (state_lookup_status == IBCM_LOOKUP_NEW) {
45310Sstevel@tonic-gate
45320Sstevel@tonic-gate /* Increment hca's resource count */
45330Sstevel@tonic-gate ibcm_inc_hca_res_cnt(hcap);
45340Sstevel@tonic-gate
45350Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ud_statep))
45360Sstevel@tonic-gate
45370Sstevel@tonic-gate /*
45380Sstevel@tonic-gate * Allocate CM MAD for a response
45390Sstevel@tonic-gate * This MAD is deallocated on state structure delete
45400Sstevel@tonic-gate * and re-used for all outgoing MADs for this connection.
45410Sstevel@tonic-gate * If MAD allocation fails, delete the ud statep
45420Sstevel@tonic-gate */
45430Sstevel@tonic-gate if (ibcm_alloc_out_msg(cm_mad_addr->ibmf_hdl,
45440Sstevel@tonic-gate &ud_statep->ud_stored_msg, MAD_METHOD_SEND) !=
45450Sstevel@tonic-gate IBT_SUCCESS) {
45460Sstevel@tonic-gate mutex_enter(&ud_statep->ud_state_mutex);
45470Sstevel@tonic-gate IBCM_UD_REF_CNT_DECR(ud_statep);
45480Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
45490Sstevel@tonic-gate ibcm_delete_ud_state_data(ud_statep);
45500Sstevel@tonic-gate return;
45510Sstevel@tonic-gate }
45520Sstevel@tonic-gate
45530Sstevel@tonic-gate /* Lookup for service */
45540Sstevel@tonic-gate ud_statep->ud_svc_id = b2h64(sidr_reqp->sidr_req_service_id);
45550Sstevel@tonic-gate ud_statep->ud_state = IBCM_STATE_SIDR_REQ_RCVD;
45560Sstevel@tonic-gate ud_statep->ud_clnt_proceed = IBCM_BLOCK;
45570Sstevel@tonic-gate
45580Sstevel@tonic-gate mutex_enter(&ibcm_svc_info_lock);
45590Sstevel@tonic-gate
45600Sstevel@tonic-gate svc_infop = ibcm_find_svc_entry(ud_statep->ud_svc_id);
45610Sstevel@tonic-gate
45620Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_sidr_req_msg: "
45630Sstevel@tonic-gate " ud_statep 0x%p svc_info %p", ud_statep, svc_infop);
45640Sstevel@tonic-gate
45650Sstevel@tonic-gate /*
45660Sstevel@tonic-gate * No need to hold the ud state mutex, as no other thread
45670Sstevel@tonic-gate * modifies ud statep in IBCM_STATE_SIDR_REQ_RCVD state
45680Sstevel@tonic-gate */
45690Sstevel@tonic-gate
45700Sstevel@tonic-gate if (svc_infop != NULL) {
45710Sstevel@tonic-gate /* find the "bind" entry that enables this port */
45720Sstevel@tonic-gate
45730Sstevel@tonic-gate svc_bindp = NULL;
45740Sstevel@tonic-gate tmp_bindp = svc_infop->svc_bind_list;
45750Sstevel@tonic-gate while (tmp_bindp) {
45760Sstevel@tonic-gate if (tmp_bindp->sbind_hcaguid == hca_guid &&
45770Sstevel@tonic-gate tmp_bindp->sbind_port == port_num) {
45780Sstevel@tonic-gate if (gid.gid_guid ==
45790Sstevel@tonic-gate tmp_bindp->sbind_gid.gid_guid &&
45800Sstevel@tonic-gate gid.gid_prefix ==
45810Sstevel@tonic-gate tmp_bindp->sbind_gid.gid_prefix) {
45820Sstevel@tonic-gate /* a really good match */
45830Sstevel@tonic-gate svc_bindp = tmp_bindp;
45840Sstevel@tonic-gate if (pkey ==
45850Sstevel@tonic-gate tmp_bindp->sbind_pkey)
45860Sstevel@tonic-gate /* absolute best */
45870Sstevel@tonic-gate break;
45880Sstevel@tonic-gate } else if (svc_bindp == NULL) {
45890Sstevel@tonic-gate /* port match => a good match */
45900Sstevel@tonic-gate svc_bindp = tmp_bindp;
45910Sstevel@tonic-gate }
45920Sstevel@tonic-gate }
45930Sstevel@tonic-gate tmp_bindp = tmp_bindp->sbind_link;
45940Sstevel@tonic-gate }
45950Sstevel@tonic-gate if (svc_bindp == NULL) {
45960Sstevel@tonic-gate svc_infop = NULL;
45970Sstevel@tonic-gate }
45980Sstevel@tonic-gate }
45990Sstevel@tonic-gate
46000Sstevel@tonic-gate IBCM_OUT_HDRP(ud_statep->ud_stored_msg)->TransactionID =
46010Sstevel@tonic-gate ((ib_mad_hdr_t *)(input_madp))->TransactionID;
46020Sstevel@tonic-gate
46030Sstevel@tonic-gate ibcm_build_reply_mad_addr(cm_mad_addr,
46040Sstevel@tonic-gate &ud_statep->ud_stored_reply_addr);
46050Sstevel@tonic-gate
46060Sstevel@tonic-gate if (ud_statep->ud_stored_reply_addr.cm_qp_entry == NULL) {
46070Sstevel@tonic-gate
46080Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
46090Sstevel@tonic-gate
46100Sstevel@tonic-gate /* Not much choice. CM MADs cannot go on QP1 */
46110Sstevel@tonic-gate mutex_enter(&ud_statep->ud_state_mutex);
46120Sstevel@tonic-gate IBCM_UD_REF_CNT_DECR(ud_statep);
46130Sstevel@tonic-gate ud_statep->ud_state = IBCM_STATE_DELETE;
46140Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
46150Sstevel@tonic-gate
46160Sstevel@tonic-gate ibcm_delete_ud_state_data(ud_statep);
46170Sstevel@tonic-gate return;
46180Sstevel@tonic-gate }
46190Sstevel@tonic-gate
46200Sstevel@tonic-gate if (svc_infop == NULL || svc_infop->svc_ud_handler == NULL) {
46210Sstevel@tonic-gate /*
46220Sstevel@tonic-gate * Don't have a record of Service ID in CM's
46230Sstevel@tonic-gate * internal list registered at this gid/lid.
46240Sstevel@tonic-gate * So, send out Service ID not supported SIDR REP msg
46250Sstevel@tonic-gate */
46260Sstevel@tonic-gate sidr_status = IBT_CM_SREP_SID_INVALID;
46270Sstevel@tonic-gate } else {
46280Sstevel@tonic-gate ud_statep->ud_cm_handler = svc_infop->svc_ud_handler;
46290Sstevel@tonic-gate ud_statep->ud_state_cm_private =
46300Sstevel@tonic-gate svc_bindp->sbind_cm_private;
46310Sstevel@tonic-gate IBCM_SVC_INCR(svc_infop);
46320Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
46330Sstevel@tonic-gate
46340Sstevel@tonic-gate /* Call Client's UD handler */
46350Sstevel@tonic-gate cm_status = ibcm_sidr_req_ud_handler(ud_statep,
46360Sstevel@tonic-gate sidr_reqp, cm_mad_addr, &sidr_status);
46370Sstevel@tonic-gate
46380Sstevel@tonic-gate mutex_enter(&ibcm_svc_info_lock);
46390Sstevel@tonic-gate IBCM_SVC_DECR(svc_infop);
46400Sstevel@tonic-gate }
46410Sstevel@tonic-gate
46420Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
46430Sstevel@tonic-gate
46440Sstevel@tonic-gate if (cm_status == IBCM_DEFER) {
46450Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_sidr_req_msg: "
46460Sstevel@tonic-gate "ud_statep 0x%p client returned DEFER response",
46470Sstevel@tonic-gate ud_statep);
46480Sstevel@tonic-gate return;
46490Sstevel@tonic-gate }
46500Sstevel@tonic-gate
46510Sstevel@tonic-gate ibcm_post_sidr_rep_mad(ud_statep, sidr_status);
46520Sstevel@tonic-gate
46530Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*ud_statep))
46540Sstevel@tonic-gate
46550Sstevel@tonic-gate mutex_enter(&ud_statep->ud_state_mutex);
46560Sstevel@tonic-gate IBCM_UD_REF_CNT_DECR(ud_statep);
46570Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
46580Sstevel@tonic-gate } else {
46590Sstevel@tonic-gate ASSERT(state_lookup_status == IBCM_LOOKUP_EXISTS);
46600Sstevel@tonic-gate
46610Sstevel@tonic-gate mutex_enter(&ud_statep->ud_state_mutex);
46620Sstevel@tonic-gate
46630Sstevel@tonic-gate if (ud_statep->ud_state == IBCM_STATE_SIDR_REP_SENT)
46640Sstevel@tonic-gate ibcm_resend_srep_mad(ud_statep);
46650Sstevel@tonic-gate
46660Sstevel@tonic-gate IBCM_UD_REF_CNT_DECR(ud_statep);
46670Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
46680Sstevel@tonic-gate }
46690Sstevel@tonic-gate }
46700Sstevel@tonic-gate
46710Sstevel@tonic-gate
46720Sstevel@tonic-gate /*
46730Sstevel@tonic-gate * ibcm_process_sidr_rep_msg:
46740Sstevel@tonic-gate * This call processes an incoming SIDR REP
46750Sstevel@tonic-gate *
46760Sstevel@tonic-gate * INPUTS:
46770Sstevel@tonic-gate * hcap - HCA entry pointer
46780Sstevel@tonic-gate * input_madp - incoming CM SIDR REP MAD
46790Sstevel@tonic-gate * cm_mad_addr - Address information for the MAD to be posted
46800Sstevel@tonic-gate *
46810Sstevel@tonic-gate * RETURN VALUE:
46820Sstevel@tonic-gate * NONE
46830Sstevel@tonic-gate */
46840Sstevel@tonic-gate void
ibcm_process_sidr_rep_msg(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)46850Sstevel@tonic-gate ibcm_process_sidr_rep_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
46860Sstevel@tonic-gate ibcm_mad_addr_t *cm_mad_addr)
46870Sstevel@tonic-gate {
46880Sstevel@tonic-gate ib_lid_t lid;
46890Sstevel@tonic-gate ib_gid_t gid;
46900Sstevel@tonic-gate ibcm_status_t status;
46910Sstevel@tonic-gate ib_svc_id_t tmp_svc_id;
46920Sstevel@tonic-gate ibcm_sidr_rep_msg_t *sidr_repp = (ibcm_sidr_rep_msg_t *)
46934703Shiremath (&input_madp[IBCM_MAD_HDR_SIZE]);
46940Sstevel@tonic-gate ibcm_ud_state_data_t *ud_statep = NULL;
46950Sstevel@tonic-gate ibcm_sidr_srch_t srch_sidr;
46960Sstevel@tonic-gate
46970Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_sidr_rep_msg:");
46980Sstevel@tonic-gate
46990Sstevel@tonic-gate lid = cm_mad_addr->rcvd_addr.ia_local_lid;
47000Sstevel@tonic-gate if (cm_mad_addr->grh_exists == B_TRUE)
47010Sstevel@tonic-gate gid = cm_mad_addr->grh_hdr.ig_recver_gid;
47020Sstevel@tonic-gate else
47030Sstevel@tonic-gate gid.gid_prefix = gid.gid_guid = 0;
47040Sstevel@tonic-gate
47050Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_process_sidr_rep_msg: QPN rcvd = %x",
47060Sstevel@tonic-gate h2b32(sidr_repp->sidr_rep_qpn_plus) >> 8);
47070Sstevel@tonic-gate
47080Sstevel@tonic-gate /*
47090Sstevel@tonic-gate * Lookup for an existing state structure.
47100Sstevel@tonic-gate * No need to hold a lock as ibcm_find_sidr_entry() holds the
47110Sstevel@tonic-gate * list lock to find the matching entry.
47120Sstevel@tonic-gate */
47130Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_sidr_rep: lid=%x, (%llX, %llX), "
47140Sstevel@tonic-gate "grh = %x, id = %x", lid, gid.gid_prefix, gid.gid_guid,
47150Sstevel@tonic-gate cm_mad_addr->grh_exists, sidr_repp->sidr_rep_request_id);
47160Sstevel@tonic-gate
47170Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(srch_sidr))
47180Sstevel@tonic-gate
47190Sstevel@tonic-gate srch_sidr.srch_lid = lid;
47200Sstevel@tonic-gate srch_sidr.srch_gid = gid;
47210Sstevel@tonic-gate srch_sidr.srch_grh_exists = cm_mad_addr->grh_exists;
47220Sstevel@tonic-gate srch_sidr.srch_req_id = b2h32(sidr_repp->sidr_rep_request_id);
47230Sstevel@tonic-gate srch_sidr.srch_mode = IBCM_ACTIVE_MODE;
47240Sstevel@tonic-gate
47250Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(srch_sidr))
47260Sstevel@tonic-gate
47270Sstevel@tonic-gate rw_enter(&hcap->hca_sidr_list_lock, RW_READER);
47280Sstevel@tonic-gate status = ibcm_find_sidr_entry(&srch_sidr, hcap, &ud_statep,
47290Sstevel@tonic-gate IBCM_FLAG_LOOKUP);
47300Sstevel@tonic-gate rw_exit(&hcap->hca_sidr_list_lock);
47310Sstevel@tonic-gate
4732557Shiremath IBTF_DPRINTF_L4(cmlog, "ibcm_process_sidr_rep_msg: ud_statep 0x%p "
47330Sstevel@tonic-gate "find sidr entry status = %x", ud_statep, status);
47340Sstevel@tonic-gate
47350Sstevel@tonic-gate if (status != IBCM_LOOKUP_EXISTS) {
47360Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_sidr_rep_msg: "
47370Sstevel@tonic-gate "No matching ud_statep for SIDR REP");
47380Sstevel@tonic-gate return;
47390Sstevel@tonic-gate }
47400Sstevel@tonic-gate
47410Sstevel@tonic-gate if (IBCM_OUT_HDRP(ud_statep->ud_stored_msg)->TransactionID !=
47420Sstevel@tonic-gate ((ib_mad_hdr_t *)(input_madp))->TransactionID) {
47430Sstevel@tonic-gate mutex_enter(&ud_statep->ud_state_mutex);
47440Sstevel@tonic-gate IBCM_UD_REF_CNT_DECR(ud_statep);
47450Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
47460Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_sidr_rep_msg: "
47470Sstevel@tonic-gate "ud_statep 0x%p. A SIDR REP MAD with tid expected 0x%llX "
47480Sstevel@tonic-gate "tid found 0x%llX req_id %x arrived", ud_statep,
47490Sstevel@tonic-gate b2h64(
47500Sstevel@tonic-gate IBCM_OUT_HDRP(ud_statep->ud_stored_msg)->TransactionID),
47510Sstevel@tonic-gate b2h64(((ib_mad_hdr_t *)(input_madp))->TransactionID),
47520Sstevel@tonic-gate b2h32(sidr_repp->sidr_rep_request_id));
47530Sstevel@tonic-gate return;
47540Sstevel@tonic-gate }
47550Sstevel@tonic-gate
47560Sstevel@tonic-gate mutex_enter(&ud_statep->ud_state_mutex);
47570Sstevel@tonic-gate
47580Sstevel@tonic-gate /*
47590Sstevel@tonic-gate * We need to check service ID received against the one sent?
47600Sstevel@tonic-gate * If they don't match just return.
47610Sstevel@tonic-gate */
47620Sstevel@tonic-gate bcopy(sidr_repp->sidr_rep_service_id, &tmp_svc_id, sizeof (tmp_svc_id));
47630Sstevel@tonic-gate bcopy(&tmp_svc_id, sidr_repp->sidr_rep_service_id, sizeof (tmp_svc_id));
47640Sstevel@tonic-gate if (ud_statep->ud_svc_id != b2h64(tmp_svc_id)) {
47650Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_sidr_rep_msg: "
47661093Shiremath "ud_statep -0x%p svcids do not match %llx %llx",
47670Sstevel@tonic-gate ud_statep, ud_statep->ud_svc_id, b2h64(tmp_svc_id));
47680Sstevel@tonic-gate
47690Sstevel@tonic-gate IBCM_UD_REF_CNT_DECR(ud_statep);
47700Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
47710Sstevel@tonic-gate return;
47720Sstevel@tonic-gate }
47730Sstevel@tonic-gate
47740Sstevel@tonic-gate if (ud_statep->ud_state == IBCM_STATE_SIDR_REQ_SENT) {
47750Sstevel@tonic-gate timeout_id_t timer_val = ud_statep->ud_timerid;
47760Sstevel@tonic-gate
47770Sstevel@tonic-gate ud_statep->ud_state = IBCM_STATE_SIDR_REP_RCVD;
47780Sstevel@tonic-gate ud_statep->ud_timerid = 0;
47790Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
47800Sstevel@tonic-gate
47810Sstevel@tonic-gate /* Cancel timer set after sending SIDR REQ */
47820Sstevel@tonic-gate (void) untimeout(timer_val);
47830Sstevel@tonic-gate
47840Sstevel@tonic-gate /*
47850Sstevel@tonic-gate * Call Client's UD handler
47860Sstevel@tonic-gate */
47870Sstevel@tonic-gate ibcm_sidr_rep_ud_handler(ud_statep, sidr_repp);
47880Sstevel@tonic-gate
47890Sstevel@tonic-gate mutex_enter(&ud_statep->ud_state_mutex);
47900Sstevel@tonic-gate
47910Sstevel@tonic-gate ud_statep->ud_state = IBCM_STATE_DELETE;
47920Sstevel@tonic-gate
47930Sstevel@tonic-gate /*
47940Sstevel@tonic-gate * ud_statep->ud_return_data is initialized for blocking in
47950Sstevel@tonic-gate * ibt_ud_get_dqpn(). Initialize its fields and
47960Sstevel@tonic-gate * signal the blocking call in ibt_ud_get_dqpn().
47970Sstevel@tonic-gate */
47980Sstevel@tonic-gate if (ud_statep->ud_return_data != NULL) {
47990Sstevel@tonic-gate /* get rep_qpn and rep_status */
48000Sstevel@tonic-gate ibt_priv_data_len_t len;
48010Sstevel@tonic-gate
48020Sstevel@tonic-gate /* Copy the SIDR private data */
48030Sstevel@tonic-gate len = min(ud_statep->ud_return_data->ud_priv_data_len,
48040Sstevel@tonic-gate IBT_SIDR_REP_PRIV_DATA_SZ);
48050Sstevel@tonic-gate
48060Sstevel@tonic-gate if ((ud_statep->ud_return_data->ud_priv_data != NULL) &&
48070Sstevel@tonic-gate (len > 0)) {
48080Sstevel@tonic-gate bcopy(sidr_repp->sidr_rep_private_data,
48090Sstevel@tonic-gate ud_statep->ud_return_data->ud_priv_data,
48100Sstevel@tonic-gate len);
48110Sstevel@tonic-gate }
48120Sstevel@tonic-gate
48130Sstevel@tonic-gate /* get status first */
48140Sstevel@tonic-gate ud_statep->ud_return_data->ud_status =
48150Sstevel@tonic-gate sidr_repp->sidr_rep_rep_status;
48160Sstevel@tonic-gate
48170Sstevel@tonic-gate if (ud_statep->ud_return_data->ud_status ==
48180Sstevel@tonic-gate IBT_CM_SREP_QPN_VALID) {
48190Sstevel@tonic-gate ud_statep->ud_return_data->ud_dqpn =
48200Sstevel@tonic-gate h2b32(sidr_repp->sidr_rep_qpn_plus) >> 8;
48210Sstevel@tonic-gate ud_statep->ud_return_data->ud_qkey =
48220Sstevel@tonic-gate b2h32(sidr_repp->sidr_rep_qkey);
48230Sstevel@tonic-gate }
48240Sstevel@tonic-gate
48250Sstevel@tonic-gate ud_statep->ud_blocking_done = B_TRUE;
48260Sstevel@tonic-gate cv_broadcast(&ud_statep->ud_block_client_cv);
48270Sstevel@tonic-gate }
48280Sstevel@tonic-gate
48290Sstevel@tonic-gate IBCM_UD_REF_CNT_DECR(ud_statep);
48300Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
48310Sstevel@tonic-gate
48320Sstevel@tonic-gate /* Delete UD state data now, finally done with it */
48330Sstevel@tonic-gate ibcm_delete_ud_state_data(ud_statep);
48340Sstevel@tonic-gate } else {
48350Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_process_sidr_rep_msg: "
48360Sstevel@tonic-gate "ud state is = 0x%x", ud_statep->ud_state);
48370Sstevel@tonic-gate IBCM_UD_REF_CNT_DECR(ud_statep);
48380Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
48390Sstevel@tonic-gate }
48400Sstevel@tonic-gate }
48410Sstevel@tonic-gate
48420Sstevel@tonic-gate
48430Sstevel@tonic-gate /*
48440Sstevel@tonic-gate * ibcm_post_sidr_rep_mad:
48450Sstevel@tonic-gate * This call posts a SIDR REP MAD
48460Sstevel@tonic-gate *
48470Sstevel@tonic-gate * INPUTS:
48480Sstevel@tonic-gate * ud_statep - pointer to ibcm_ud_state_data_t
48490Sstevel@tonic-gate * status - Status information
48500Sstevel@tonic-gate *
48510Sstevel@tonic-gate * RETURN VALUE: NONE
48520Sstevel@tonic-gate */
48530Sstevel@tonic-gate void
ibcm_post_sidr_rep_mad(ibcm_ud_state_data_t * ud_statep,ibt_sidr_status_t status)48540Sstevel@tonic-gate ibcm_post_sidr_rep_mad(ibcm_ud_state_data_t *ud_statep,
48550Sstevel@tonic-gate ibt_sidr_status_t status)
48560Sstevel@tonic-gate {
48570Sstevel@tonic-gate ib_svc_id_t tmp_svc_id;
48580Sstevel@tonic-gate ibcm_sidr_rep_msg_t *sidr_repp =
48590Sstevel@tonic-gate (ibcm_sidr_rep_msg_t *)IBCM_OUT_MSGP(ud_statep->ud_stored_msg);
48600Sstevel@tonic-gate clock_t timer_value;
48610Sstevel@tonic-gate
48620Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_post_sidr_rep_mad:");
48630Sstevel@tonic-gate
48640Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sidr_repp))
48650Sstevel@tonic-gate
48660Sstevel@tonic-gate IBCM_OUT_HDRP(ud_statep->ud_stored_msg)->AttributeID =
48670Sstevel@tonic-gate h2b16(IBCM_INCOMING_SIDR_REP + IBCM_ATTR_BASE_ID);
48680Sstevel@tonic-gate
48690Sstevel@tonic-gate /*
48700Sstevel@tonic-gate * Initialize SIDR REP message. (Other fields were
48710Sstevel@tonic-gate * already filled up in ibcm_sidr_req_ud_handler()
48720Sstevel@tonic-gate */
48730Sstevel@tonic-gate sidr_repp->sidr_rep_request_id = h2b32(ud_statep->ud_req_id);
48740Sstevel@tonic-gate tmp_svc_id = h2b64(ud_statep->ud_svc_id);
48750Sstevel@tonic-gate bcopy(&tmp_svc_id, sidr_repp->sidr_rep_service_id, sizeof (tmp_svc_id));
48760Sstevel@tonic-gate
48770Sstevel@tonic-gate sidr_repp->sidr_rep_rep_status = (uint8_t)status;
48780Sstevel@tonic-gate
48790Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*sidr_repp))
48800Sstevel@tonic-gate
48810Sstevel@tonic-gate /* post the SIDR REP MAD */
48820Sstevel@tonic-gate ibcm_post_ud_mad(ud_statep, ud_statep->ud_stored_msg, NULL, NULL);
48830Sstevel@tonic-gate
48840Sstevel@tonic-gate timer_value = ibt_ib2usec(ibcm_max_sidr_rep_store_time);
48850Sstevel@tonic-gate /*
48860Sstevel@tonic-gate * Hold the statep lock, as a SIDR REQ may come in after setting state
48870Sstevel@tonic-gate * but before timeout. This can result in a dangling timeout ie.,
48880Sstevel@tonic-gate * the incoming SIDR REQ would be unable to cancel this timeout
48890Sstevel@tonic-gate */
48900Sstevel@tonic-gate mutex_enter(&ud_statep->ud_state_mutex);
48910Sstevel@tonic-gate
48920Sstevel@tonic-gate ud_statep->ud_remaining_retry_cnt = 1;
48930Sstevel@tonic-gate ud_statep->ud_timer_value = timer_value;
48940Sstevel@tonic-gate
48950Sstevel@tonic-gate ud_statep->ud_timer_stored_state = ud_statep->ud_state =
48960Sstevel@tonic-gate IBCM_STATE_SIDR_REP_SENT;
48970Sstevel@tonic-gate ud_statep->ud_timerid = IBCM_UD_TIMEOUT(ud_statep,
48980Sstevel@tonic-gate ud_statep->ud_timer_value);
48990Sstevel@tonic-gate
49000Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
49010Sstevel@tonic-gate }
49020Sstevel@tonic-gate
49030Sstevel@tonic-gate
49040Sstevel@tonic-gate /*
49050Sstevel@tonic-gate * ibcm_sidr_timeout_cb:
49060Sstevel@tonic-gate * Called when the timer expires on SIDR request
49070Sstevel@tonic-gate *
49080Sstevel@tonic-gate * INPUTS:
49090Sstevel@tonic-gate * arg - ibcm_ud_state_data_t with all the info
49100Sstevel@tonic-gate *
49110Sstevel@tonic-gate * RETURN VALUE: NONE
49120Sstevel@tonic-gate */
49130Sstevel@tonic-gate void
ibcm_sidr_timeout_cb(void * arg)49140Sstevel@tonic-gate ibcm_sidr_timeout_cb(void *arg)
49150Sstevel@tonic-gate {
49160Sstevel@tonic-gate ibcm_ud_state_data_t *ud_statep = (ibcm_ud_state_data_t *)arg;
49170Sstevel@tonic-gate
49180Sstevel@tonic-gate mutex_enter(&ud_statep->ud_state_mutex);
49199913SShantkumar.Hiremath@Sun.COM ud_statep->ud_timerid = 0;
49200Sstevel@tonic-gate
49210Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_sidr_timeout_cb: ud_statep 0x%p "
49220Sstevel@tonic-gate "state = 0x%x", ud_statep, ud_statep->ud_state);
49230Sstevel@tonic-gate
49240Sstevel@tonic-gate /* Processing depends upon current state */
49250Sstevel@tonic-gate if (ud_statep->ud_state == IBCM_STATE_SIDR_REP_SENT) {
49260Sstevel@tonic-gate ud_statep->ud_state = IBCM_STATE_DELETE;
49270Sstevel@tonic-gate
49280Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
49290Sstevel@tonic-gate
49300Sstevel@tonic-gate /* Deallocate the CM state structure */
49310Sstevel@tonic-gate ibcm_delete_ud_state_data(ud_statep);
49320Sstevel@tonic-gate
49330Sstevel@tonic-gate } else if ((ud_statep->ud_remaining_retry_cnt > 0) &&
49340Sstevel@tonic-gate (ud_statep->ud_state == IBCM_STATE_SIDR_REQ_SENT)) {
49350Sstevel@tonic-gate
49360Sstevel@tonic-gate ud_statep->ud_remaining_retry_cnt--;
49370Sstevel@tonic-gate IBCM_UD_REF_CNT_INCR(ud_statep); /* for non-blocking post */
49380Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_sidr_timeout_cb: "
49390Sstevel@tonic-gate "ud_statep = %p, retries remaining = 0x%x",
49400Sstevel@tonic-gate ud_statep, ud_statep->ud_remaining_retry_cnt);
49410Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
49420Sstevel@tonic-gate
49430Sstevel@tonic-gate /* Post mad in non blocking mode */
49440Sstevel@tonic-gate ibcm_post_ud_mad(ud_statep, ud_statep->ud_stored_msg,
49450Sstevel@tonic-gate ibcm_post_sidr_req_complete, ud_statep);
49460Sstevel@tonic-gate
49470Sstevel@tonic-gate } else if (ud_statep->ud_state == IBCM_STATE_SIDR_REQ_SENT) {
49480Sstevel@tonic-gate
49490Sstevel@tonic-gate /* This is on SIDR REQ Sender side processing */
49500Sstevel@tonic-gate
49510Sstevel@tonic-gate /* set state to IBCM_STATE_DELETE */
49520Sstevel@tonic-gate ud_statep->ud_state = IBCM_STATE_DELETE;
49530Sstevel@tonic-gate
49540Sstevel@tonic-gate /*
49550Sstevel@tonic-gate * retry counter expired, clean up
49560Sstevel@tonic-gate *
49570Sstevel@tonic-gate * Invoke the client/server handler with a "status" of
49580Sstevel@tonic-gate * IBT_CM_SREP_TIMEOUT.
49590Sstevel@tonic-gate */
49600Sstevel@tonic-gate
49610Sstevel@tonic-gate if (ud_statep->ud_return_data != NULL) {
49620Sstevel@tonic-gate ud_statep->ud_return_data->ud_status =
49634703Shiremath IBT_CM_SREP_TIMEOUT;
49640Sstevel@tonic-gate ud_statep->ud_blocking_done = B_TRUE;
49650Sstevel@tonic-gate cv_broadcast(&ud_statep->ud_block_client_cv);
49660Sstevel@tonic-gate }
49670Sstevel@tonic-gate
49680Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
49690Sstevel@tonic-gate
49700Sstevel@tonic-gate /* Invoke the client handler in a separate thread */
49710Sstevel@tonic-gate if (ud_statep->ud_cm_handler != NULL) {
49720Sstevel@tonic-gate /* UD state data is delete in timeout thread */
49730Sstevel@tonic-gate ibcm_add_ud_tlist(ud_statep);
49740Sstevel@tonic-gate return;
49750Sstevel@tonic-gate }
49760Sstevel@tonic-gate
49770Sstevel@tonic-gate /* Delete UD state data now, finally done with it */
49780Sstevel@tonic-gate ibcm_delete_ud_state_data(ud_statep);
49790Sstevel@tonic-gate } else {
49800Sstevel@tonic-gate
49810Sstevel@tonic-gate #ifdef DEBUG
49820Sstevel@tonic-gate if (ibcm_test_mode > 0)
49830Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_sidr_timeout_cb: "
49840Sstevel@tonic-gate "Nop timeout for ud_statep 0x%p in ud_state %d",
49850Sstevel@tonic-gate ud_statep, ud_statep->ud_state);
49860Sstevel@tonic-gate #endif
49870Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
49880Sstevel@tonic-gate }
49890Sstevel@tonic-gate }
49900Sstevel@tonic-gate
49910Sstevel@tonic-gate
49920Sstevel@tonic-gate /*
49930Sstevel@tonic-gate * ibcm_resend_srep_mad:
49940Sstevel@tonic-gate * Called on a duplicate incoming SIDR REQ on server side
49950Sstevel@tonic-gate * Posts the stored MAD from ud state structure using ud_stored_reply_addr
49960Sstevel@tonic-gate * Cancels any running timer, and then re-starts the timer
49970Sstevel@tonic-gate * This routine must be called with state structure table lock held
49980Sstevel@tonic-gate *
49990Sstevel@tonic-gate * INPUTS:
50000Sstevel@tonic-gate * ud_statep - ibcm_ud_state_data_t
50010Sstevel@tonic-gate *
50020Sstevel@tonic-gate * RETURN VALUE: NONE
50030Sstevel@tonic-gate */
50040Sstevel@tonic-gate void
ibcm_resend_srep_mad(ibcm_ud_state_data_t * ud_statep)50050Sstevel@tonic-gate ibcm_resend_srep_mad(ibcm_ud_state_data_t *ud_statep)
50060Sstevel@tonic-gate {
50070Sstevel@tonic-gate timeout_id_t timer_val;
50080Sstevel@tonic-gate
50090Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ud_statep->ud_state_mutex));
50100Sstevel@tonic-gate
50110Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_resend_srep_mad: ud_statep 0x%p",
50120Sstevel@tonic-gate ud_statep);
50130Sstevel@tonic-gate
50140Sstevel@tonic-gate if (ud_statep->ud_send_mad_flags & IBCM_SREP_POST_BUSY)
50150Sstevel@tonic-gate return;
50160Sstevel@tonic-gate
50170Sstevel@tonic-gate ud_statep->ud_send_mad_flags |= IBCM_SREP_POST_BUSY;
50180Sstevel@tonic-gate
50190Sstevel@tonic-gate /* for nonblocking SIDR REP Post */
50200Sstevel@tonic-gate IBCM_UD_REF_CNT_INCR(ud_statep);
50210Sstevel@tonic-gate
50220Sstevel@tonic-gate /* Cancel currently running timer */
50230Sstevel@tonic-gate timer_val = ud_statep->ud_timerid;
50240Sstevel@tonic-gate
50250Sstevel@tonic-gate if (ud_statep->ud_timerid != 0) {
50260Sstevel@tonic-gate ud_statep->ud_timerid = 0;
50270Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
50280Sstevel@tonic-gate (void) untimeout(timer_val);
50290Sstevel@tonic-gate } else {
50300Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
50310Sstevel@tonic-gate }
50320Sstevel@tonic-gate
50330Sstevel@tonic-gate /* Always resend the response MAD to the original reply destination */
50340Sstevel@tonic-gate ibcm_post_ud_mad(ud_statep, ud_statep->ud_stored_msg,
50350Sstevel@tonic-gate ibcm_post_sidr_rep_complete, ud_statep);
50360Sstevel@tonic-gate
50370Sstevel@tonic-gate mutex_enter(&ud_statep->ud_state_mutex);
50380Sstevel@tonic-gate }
50390Sstevel@tonic-gate
50400Sstevel@tonic-gate
50410Sstevel@tonic-gate /*
50420Sstevel@tonic-gate * ibcm_build_reply_mad_addr:
50430Sstevel@tonic-gate * Forms the reply MAD address based on "incoming mad addr" that is
50440Sstevel@tonic-gate * supplied as an arg.
50450Sstevel@tonic-gate *
50460Sstevel@tonic-gate * Swaps the source and destination gids in ib_grh_t
50470Sstevel@tonic-gate *
50480Sstevel@tonic-gate * INPUTS:
50490Sstevel@tonic-gate * inp_mad_addr: Address information in the incoming MAD
50500Sstevel@tonic-gate * out_mad_addr: Derived address for the reply MAD
50510Sstevel@tonic-gate * The reply MAD address is derived based
50520Sstevel@tonic-gate * address information of incoming CM MAD
50530Sstevel@tonic-gate * RETURN VALUE: NONE
50540Sstevel@tonic-gate */
50550Sstevel@tonic-gate void
ibcm_build_reply_mad_addr(ibcm_mad_addr_t * inp_mad_addr,ibcm_mad_addr_t * out_mad_addr)50560Sstevel@tonic-gate ibcm_build_reply_mad_addr(ibcm_mad_addr_t *inp_mad_addr,
50570Sstevel@tonic-gate ibcm_mad_addr_t *out_mad_addr)
50580Sstevel@tonic-gate {
50590Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_build_reply_mad_addr:");
50600Sstevel@tonic-gate
50610Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*out_mad_addr))
50620Sstevel@tonic-gate
50630Sstevel@tonic-gate bcopy(inp_mad_addr, out_mad_addr, sizeof (ibcm_mad_addr_t));
50640Sstevel@tonic-gate
50650Sstevel@tonic-gate /* Swap the GIDs in the GRH */
50660Sstevel@tonic-gate if (inp_mad_addr->grh_exists == B_TRUE) {
50670Sstevel@tonic-gate ib_gid_t sgid = inp_mad_addr->grh_hdr.ig_sender_gid;
50680Sstevel@tonic-gate
50690Sstevel@tonic-gate /* swap the SGID and DGID */
50700Sstevel@tonic-gate out_mad_addr->grh_hdr.ig_sender_gid =
50710Sstevel@tonic-gate inp_mad_addr->grh_hdr.ig_recver_gid;
50720Sstevel@tonic-gate out_mad_addr->grh_hdr.ig_recver_gid = sgid;
50730Sstevel@tonic-gate }
50740Sstevel@tonic-gate
50750Sstevel@tonic-gate /*
50760Sstevel@tonic-gate * CM posts response MAD on a new/existing internal QP on the same port
50770Sstevel@tonic-gate * and pkey
50780Sstevel@tonic-gate */
50790Sstevel@tonic-gate out_mad_addr->cm_qp_entry =
50800Sstevel@tonic-gate ibcm_find_qp(inp_mad_addr->cm_qp_entry->qp_port->port_hcap,
50810Sstevel@tonic-gate inp_mad_addr->port_num, inp_mad_addr->rcvd_addr.ia_p_key);
50820Sstevel@tonic-gate
50830Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*out_mad_addr))
50840Sstevel@tonic-gate }
50850Sstevel@tonic-gate
50860Sstevel@tonic-gate
50870Sstevel@tonic-gate /*
50880Sstevel@tonic-gate * ibcm_post_rc_mad
50890Sstevel@tonic-gate * Posts a CM MAD associated with a RC statep
50900Sstevel@tonic-gate *
50910Sstevel@tonic-gate * INPUTS:
50920Sstevel@tonic-gate * statep : RC statep associated with the post
50930Sstevel@tonic-gate * msgp : CM MAD to be posted
50940Sstevel@tonic-gate * post_cb : non-NULL callback address implies non-blocking post
50950Sstevel@tonic-gate * args : Args to ibmf send callback
50960Sstevel@tonic-gate *
50970Sstevel@tonic-gate * RETURN VALUE: based on ibmf_send_mad
50980Sstevel@tonic-gate */
50990Sstevel@tonic-gate void
ibcm_post_rc_mad(ibcm_state_data_t * statep,ibmf_msg_t * msgp,ibmf_msg_cb_t post_cb,void * args)51000Sstevel@tonic-gate ibcm_post_rc_mad(ibcm_state_data_t *statep, ibmf_msg_t *msgp,
51010Sstevel@tonic-gate ibmf_msg_cb_t post_cb, void *args)
51020Sstevel@tonic-gate {
51030Sstevel@tonic-gate ibt_status_t status;
51040Sstevel@tonic-gate
51051093Shiremath mutex_enter(&statep->state_mutex);
51061093Shiremath statep->post_time = gethrtime();
51071093Shiremath mutex_exit(&statep->state_mutex);
51080Sstevel@tonic-gate status = ibcm_post_mad(msgp, &statep->stored_reply_addr, post_cb,
51090Sstevel@tonic-gate args);
51100Sstevel@tonic-gate if ((status != IBT_SUCCESS) && (post_cb != NULL))
51110Sstevel@tonic-gate /* Call ibmf callback directly */
51120Sstevel@tonic-gate (*post_cb)(NULL, msgp, args);
51130Sstevel@tonic-gate }
51140Sstevel@tonic-gate
51150Sstevel@tonic-gate
51160Sstevel@tonic-gate /*
51170Sstevel@tonic-gate * ibcm_post_ud_mad
51180Sstevel@tonic-gate * Posts a CM MAD associated with a UD statep
51190Sstevel@tonic-gate *
51200Sstevel@tonic-gate * INPUTS:
51210Sstevel@tonic-gate * ud_statep : UD statep associated with the post
51220Sstevel@tonic-gate * msgp : CM MAD to be posted
51230Sstevel@tonic-gate * post_cb : non-NULL callback address implies non-blocking post
51240Sstevel@tonic-gate * args : Args to ibmf send callback
51250Sstevel@tonic-gate *
51260Sstevel@tonic-gate * RETURN VALUE: based on ibmf_send_mad
51270Sstevel@tonic-gate */
51280Sstevel@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)51290Sstevel@tonic-gate ibcm_post_ud_mad(ibcm_ud_state_data_t *ud_statep, ibmf_msg_t *msgp,
51300Sstevel@tonic-gate ibmf_msg_cb_t ud_post_cb, void *args)
51310Sstevel@tonic-gate {
51320Sstevel@tonic-gate ibt_status_t status;
51330Sstevel@tonic-gate status = ibcm_post_mad(msgp, &ud_statep->ud_stored_reply_addr,
51340Sstevel@tonic-gate ud_post_cb, args);
51350Sstevel@tonic-gate if ((status != IBT_SUCCESS) && (ud_post_cb != NULL))
51360Sstevel@tonic-gate /* Call ibmf callback directly */
51370Sstevel@tonic-gate (*ud_post_cb)(NULL, msgp, args);
51380Sstevel@tonic-gate }
51390Sstevel@tonic-gate
51400Sstevel@tonic-gate /*
51410Sstevel@tonic-gate * ibcm_post_mad:
51420Sstevel@tonic-gate * Posts CM MAD using IBMF in blocking mode
51430Sstevel@tonic-gate *
51440Sstevel@tonic-gate * INPUTS:
51450Sstevel@tonic-gate * msgp : CM MAD to be posted
51460Sstevel@tonic-gate * cm_mad_addr : Address information for the MAD to be posted
51470Sstevel@tonic-gate * post_cb : non-NULL callback address implies non-blocking post
51480Sstevel@tonic-gate * args : Args to ibmf send callback
51490Sstevel@tonic-gate *
51500Sstevel@tonic-gate * RETURN VALUE: based on ibmf_send_mad
51510Sstevel@tonic-gate */
51520Sstevel@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)51530Sstevel@tonic-gate ibcm_post_mad(ibmf_msg_t *msgp, ibcm_mad_addr_t *cm_mad_addr,
51540Sstevel@tonic-gate ibmf_msg_cb_t post_cb, void *args)
51550Sstevel@tonic-gate {
51560Sstevel@tonic-gate int post_status;
51570Sstevel@tonic-gate
51580Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_post_mad: "
51590Sstevel@tonic-gate "ibmf_msg_t = %p, cm_madd_adr = %p", msgp, cm_mad_addr);
51600Sstevel@tonic-gate
51610Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_post_mad: dlid = %x, d_qno= %x",
51620Sstevel@tonic-gate cm_mad_addr->rcvd_addr.ia_remote_lid,
51630Sstevel@tonic-gate cm_mad_addr->rcvd_addr.ia_remote_qno);
51640Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_post_mad: p_key = %x, q_key = %x, "
51650Sstevel@tonic-gate "sl = %x, grh_exists = %x",
51660Sstevel@tonic-gate cm_mad_addr->rcvd_addr.ia_p_key, cm_mad_addr->rcvd_addr.ia_q_key,
51670Sstevel@tonic-gate cm_mad_addr->rcvd_addr.ia_service_level, cm_mad_addr->grh_exists);
51680Sstevel@tonic-gate
51690Sstevel@tonic-gate /* Copy local addressing info */
51700Sstevel@tonic-gate msgp->im_local_addr = cm_mad_addr->rcvd_addr;
51710Sstevel@tonic-gate
51720Sstevel@tonic-gate /* Copy global/GRH addressing info */
51730Sstevel@tonic-gate if (cm_mad_addr->grh_exists == B_TRUE)
51740Sstevel@tonic-gate msgp->im_global_addr = cm_mad_addr->grh_hdr;
51750Sstevel@tonic-gate
51761093Shiremath if (post_cb)
51771093Shiremath ibcm_flow_inc();
51780Sstevel@tonic-gate post_status = ibmf_msg_transport(
51790Sstevel@tonic-gate cm_mad_addr->ibmf_hdl, cm_mad_addr->cm_qp_entry->qp_cm, msgp,
51800Sstevel@tonic-gate NULL, post_cb, args, 0);
51810Sstevel@tonic-gate if (post_status != IBMF_SUCCESS) {
51821093Shiremath IBTF_DPRINTF_L2(cmlog, "ibcm_post_mad: ibmf_msg_transport "
51831093Shiremath "failed: status %d, cb = %p", post_status, post_cb);
51840Sstevel@tonic-gate /* Analyze the reason for failure */
51850Sstevel@tonic-gate return (ibcm_ibmf_analyze_error(post_status));
51860Sstevel@tonic-gate }
51870Sstevel@tonic-gate
51880Sstevel@tonic-gate return (IBT_SUCCESS);
51890Sstevel@tonic-gate }
51900Sstevel@tonic-gate
51910Sstevel@tonic-gate
51920Sstevel@tonic-gate /*
51930Sstevel@tonic-gate * ibcm_process_get_classport_info:
51940Sstevel@tonic-gate * Get classportinfo
51950Sstevel@tonic-gate *
51960Sstevel@tonic-gate * INPUTS:
51970Sstevel@tonic-gate * hcap - HCA entry pointer
51980Sstevel@tonic-gate * input_madp - Input MAD pointer
51990Sstevel@tonic-gate * cm_mad_addr - Address information for the MAD to be posted
52000Sstevel@tonic-gate *
52010Sstevel@tonic-gate * RETURN VALUE: NONE
52020Sstevel@tonic-gate */
52030Sstevel@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)52040Sstevel@tonic-gate ibcm_process_get_classport_info(ibcm_hca_info_t *hcap, uint8_t *input_madp,
52050Sstevel@tonic-gate ibcm_mad_addr_t *cm_mad_addr)
52060Sstevel@tonic-gate {
52070Sstevel@tonic-gate ibmf_msg_t *msgp;
52080Sstevel@tonic-gate
52090Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_process_get_classport_info: (%p, %p, %p)",
52100Sstevel@tonic-gate hcap, input_madp, cm_mad_addr);
52110Sstevel@tonic-gate
52120Sstevel@tonic-gate if (ibcm_alloc_out_msg(cm_mad_addr->ibmf_hdl, &msgp,
52130Sstevel@tonic-gate MAD_METHOD_GET_RESPONSE) != IBT_SUCCESS) {
52140Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_get_classport_info: "
52150Sstevel@tonic-gate "ibcm_alloc_out_msg failed");
52160Sstevel@tonic-gate return;
52170Sstevel@tonic-gate }
52180Sstevel@tonic-gate
52190Sstevel@tonic-gate /* copy the transaction id from input get mad */
52200Sstevel@tonic-gate IBCM_OUT_HDRP(msgp)->TransactionID =
52210Sstevel@tonic-gate ((ib_mad_hdr_t *)(input_madp))->TransactionID;
52220Sstevel@tonic-gate IBCM_OUT_HDRP(msgp)->AttributeID = h2b16(MAD_ATTR_ID_CLASSPORTINFO);
52230Sstevel@tonic-gate
52240Sstevel@tonic-gate bcopy(&ibcm_clpinfo, IBCM_OUT_MSGP(msgp), sizeof (ibcm_clpinfo));
52250Sstevel@tonic-gate
52260Sstevel@tonic-gate (void) ibcm_post_mad(msgp, cm_mad_addr, NULL, NULL);
52270Sstevel@tonic-gate (void) ibcm_free_out_msg(cm_mad_addr->ibmf_hdl, &msgp);
52280Sstevel@tonic-gate
52290Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_get_classport_info: done");
52300Sstevel@tonic-gate }
52310Sstevel@tonic-gate
52320Sstevel@tonic-gate /*
52330Sstevel@tonic-gate * ibcm_decode_classport_info:
52340Sstevel@tonic-gate * Decode classportinfo
52350Sstevel@tonic-gate *
52360Sstevel@tonic-gate * INPUTS:
52370Sstevel@tonic-gate * hcap - HCA entry pointer
52380Sstevel@tonic-gate * cm_mad_addr - Address information for the MAD to be posted
52390Sstevel@tonic-gate * input_madp - Input MAD pointer
52400Sstevel@tonic-gate *
52410Sstevel@tonic-gate * RETURN VALUE: NONE
52420Sstevel@tonic-gate */
52430Sstevel@tonic-gate static void
ibcm_decode_classport_info(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)52440Sstevel@tonic-gate ibcm_decode_classport_info(ibcm_hca_info_t *hcap, uint8_t *input_madp,
52450Sstevel@tonic-gate ibcm_mad_addr_t *cm_mad_addr)
52460Sstevel@tonic-gate {
52470Sstevel@tonic-gate ibcm_classportinfo_msg_t *portinfop = (ibcm_classportinfo_msg_t *)
52484703Shiremath (&input_madp[IBCM_MAD_HDR_SIZE]);
52490Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_decode_classport_info: (%p, %p, %p)",
52500Sstevel@tonic-gate hcap, input_madp, cm_mad_addr);
52510Sstevel@tonic-gate
52520Sstevel@tonic-gate /* Print various fields of received classportinfo in debuf buf */
52530Sstevel@tonic-gate
52540Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_decode_classport_info: "
52550Sstevel@tonic-gate "Base version %d Class version %d", portinfop->BaseVersion,
52560Sstevel@tonic-gate portinfop->ClassVersion);
52570Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_decode_classport_info: "
52580Sstevel@tonic-gate "Cap Mask %d Resp Time %d", portinfop->CapabilityMask,
52590Sstevel@tonic-gate portinfop->RespTimeValue_plus);
52600Sstevel@tonic-gate }
52610Sstevel@tonic-gate
52620Sstevel@tonic-gate
52630Sstevel@tonic-gate /*
52640Sstevel@tonic-gate * ibcm_handler_conn_fail:
52650Sstevel@tonic-gate * Helper function used to call client handler for Conn fail event
52660Sstevel@tonic-gate *
52670Sstevel@tonic-gate * INPUTS:
52680Sstevel@tonic-gate * statep: The connection state pointer
52690Sstevel@tonic-gate * rej_type: Message being rejected
52700Sstevel@tonic-gate * rej_reason: Reason why CM is sending the REJ message
52710Sstevel@tonic-gate * client_data: Private data returned by the client for REJ
52720Sstevel@tonic-gate * client_data_len: Length of above client's private data.
52730Sstevel@tonic-gate *
52740Sstevel@tonic-gate * RETURN VALUE: Client Handler's return status
52750Sstevel@tonic-gate */
52760Sstevel@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)52770Sstevel@tonic-gate ibcm_handler_conn_fail(ibcm_state_data_t *statep, uint8_t cf_code,
52780Sstevel@tonic-gate uint8_t cf_msg, ibt_cm_reason_t cf_reason, uint8_t *client_data,
52790Sstevel@tonic-gate ibt_priv_data_len_t client_data_len)
52800Sstevel@tonic-gate {
52810Sstevel@tonic-gate ibt_cm_event_t event;
52820Sstevel@tonic-gate
5283557Shiremath ibcm_path_cache_purge();
5284557Shiremath
5285*12292SPramod.Gunjikar@Sun.COM if (statep->channel)
5286*12292SPramod.Gunjikar@Sun.COM ibtl_cm_chan_open_is_aborted(statep->channel);
528712064SShantkumar.Hiremath@Sun.COM
52880Sstevel@tonic-gate /* Invoke CM handler w/ event passed as arg */
52890Sstevel@tonic-gate if (statep->cm_handler != NULL) {
52900Sstevel@tonic-gate bzero(&event, sizeof (ibt_cm_event_t));
52910Sstevel@tonic-gate
52920Sstevel@tonic-gate event.cm_type = IBT_CM_EVENT_FAILURE;
52930Sstevel@tonic-gate event.cm_channel = statep->channel;
52940Sstevel@tonic-gate event.cm_session_id = NULL;
52950Sstevel@tonic-gate event.cm_priv_data = NULL;
52960Sstevel@tonic-gate event.cm_priv_data_len = 0;
52970Sstevel@tonic-gate
52980Sstevel@tonic-gate event.cm_event.failed.cf_code = cf_code;
52990Sstevel@tonic-gate event.cm_event.failed.cf_msg = cf_msg;
53000Sstevel@tonic-gate event.cm_event.failed.cf_reason = cf_reason;
53010Sstevel@tonic-gate
53020Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_CALLED_CONN_FAIL_EVENT);
53030Sstevel@tonic-gate
53040Sstevel@tonic-gate (void) statep->cm_handler(statep->state_cm_private, &event,
53050Sstevel@tonic-gate NULL, client_data, client_data_len);
53060Sstevel@tonic-gate
53070Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_RET_CONN_FAIL_EVENT);
53080Sstevel@tonic-gate }
53090Sstevel@tonic-gate if (ibcm_enable_trace != 0)
53100Sstevel@tonic-gate ibcm_dump_conn_trace(statep);
53111093Shiremath mutex_enter(&statep->state_mutex);
53121093Shiremath ibcm_open_done(statep);
53131093Shiremath mutex_exit(&statep->state_mutex);
53140Sstevel@tonic-gate }
53150Sstevel@tonic-gate
53160Sstevel@tonic-gate /*
53170Sstevel@tonic-gate * QP State transition functions here
53180Sstevel@tonic-gate *
53190Sstevel@tonic-gate * The brief description of these functions :
53200Sstevel@tonic-gate * Validate QP related attributes in the messages
53210Sstevel@tonic-gate * Call client/server callback handlers
53220Sstevel@tonic-gate * Change QP state
53230Sstevel@tonic-gate * Set QP attributes (modify QP)
53240Sstevel@tonic-gate * Fill up the response MADs
53250Sstevel@tonic-gate */
53260Sstevel@tonic-gate
53270Sstevel@tonic-gate /*
53280Sstevel@tonic-gate * ibcm_set_primary_adds_vect:
53290Sstevel@tonic-gate * Helper function used to fill up ibt_adds_vect_t PRIMARY PATH
53300Sstevel@tonic-gate * (called from ibcm_cep_state_*() functions)
53310Sstevel@tonic-gate *
53320Sstevel@tonic-gate * INPUTS:
53330Sstevel@tonic-gate * statep : The connection state pointer
53340Sstevel@tonic-gate * adds_vectp : The ibt_adds_vect_t ptr that is being filled up
53350Sstevel@tonic-gate * msgp : CM REQ message that is the source of information
53360Sstevel@tonic-gate *
53370Sstevel@tonic-gate * RETURN VALUE: NONE
53380Sstevel@tonic-gate */
53390Sstevel@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)53400Sstevel@tonic-gate ibcm_set_primary_adds_vect(ibcm_state_data_t *statep,
53410Sstevel@tonic-gate ibt_adds_vect_t *adds_vectp, ibcm_req_msg_t *msgp)
53420Sstevel@tonic-gate {
53430Sstevel@tonic-gate uint32_t flow_label20_res6_rate6;
53440Sstevel@tonic-gate
53450Sstevel@tonic-gate flow_label20_res6_rate6 = b2h32(msgp->req_primary_flow_label_plus);
53460Sstevel@tonic-gate
53470Sstevel@tonic-gate /* first setup the srvl, srate, dlid and dgid */
53480Sstevel@tonic-gate adds_vectp->av_srvl = msgp->req_primary_sl_plus >> 4;
53490Sstevel@tonic-gate adds_vectp->av_src_path = statep->prim_src_path_bits;
53500Sstevel@tonic-gate
53510Sstevel@tonic-gate if (statep->mode == IBCM_PASSIVE_MODE) {
53520Sstevel@tonic-gate adds_vectp->av_dlid = b2h16(msgp->req_primary_l_port_lid);
53530Sstevel@tonic-gate adds_vectp->av_dgid.gid_prefix =
53544703Shiremath b2h64(msgp->req_primary_l_port_gid.gid_prefix);
53550Sstevel@tonic-gate adds_vectp->av_dgid.gid_guid =
53564703Shiremath b2h64(msgp->req_primary_l_port_gid.gid_guid);
53570Sstevel@tonic-gate adds_vectp->av_sgid.gid_prefix =
53584703Shiremath b2h64(msgp->req_primary_r_port_gid.gid_prefix);
53590Sstevel@tonic-gate adds_vectp->av_sgid.gid_guid =
53604703Shiremath b2h64(msgp->req_primary_r_port_gid.gid_guid);
53610Sstevel@tonic-gate adds_vectp->av_srate = flow_label20_res6_rate6 & 0x3f;
53620Sstevel@tonic-gate } else {
53630Sstevel@tonic-gate adds_vectp->av_dlid = b2h16(msgp->req_primary_r_port_lid);
53640Sstevel@tonic-gate adds_vectp->av_dgid.gid_prefix =
53654703Shiremath b2h64(msgp->req_primary_r_port_gid.gid_prefix);
53660Sstevel@tonic-gate adds_vectp->av_dgid.gid_guid =
53674703Shiremath b2h64(msgp->req_primary_r_port_gid.gid_guid);
53680Sstevel@tonic-gate adds_vectp->av_sgid.gid_prefix =
53694703Shiremath b2h64(msgp->req_primary_l_port_gid.gid_prefix);
53700Sstevel@tonic-gate adds_vectp->av_sgid.gid_guid =
53714703Shiremath b2h64(msgp->req_primary_l_port_gid.gid_guid);
53720Sstevel@tonic-gate adds_vectp->av_srate = statep->local_srate;
53730Sstevel@tonic-gate }
53740Sstevel@tonic-gate
53750Sstevel@tonic-gate /* next copy off the GRH info if it exists */
53760Sstevel@tonic-gate if ((msgp->req_primary_sl_plus & 0x8) == 0) {
53770Sstevel@tonic-gate adds_vectp->av_send_grh = B_TRUE;
53780Sstevel@tonic-gate adds_vectp->av_flow = flow_label20_res6_rate6 >> 12;
53790Sstevel@tonic-gate adds_vectp->av_tclass = msgp->req_primary_traffic_class;
53800Sstevel@tonic-gate adds_vectp->av_hop = msgp->req_primary_hop_limit;
53810Sstevel@tonic-gate } else {
53820Sstevel@tonic-gate adds_vectp->av_send_grh = B_FALSE;
53830Sstevel@tonic-gate }
53840Sstevel@tonic-gate }
53850Sstevel@tonic-gate
53860Sstevel@tonic-gate
53870Sstevel@tonic-gate /*
53880Sstevel@tonic-gate * ibcm_set_alt_adds_vect:
53890Sstevel@tonic-gate * Helper function used to fill up ibt_adds_vect_t ALTERNATE PATH
53900Sstevel@tonic-gate * (called from ibcm_cep_state_*() functions)
53910Sstevel@tonic-gate *
53920Sstevel@tonic-gate * INPUTS:
53930Sstevel@tonic-gate * statep : The connection state pointer
53940Sstevel@tonic-gate * adds_vectp : The ibt_adds_vect_t ptr that is being filled up
53950Sstevel@tonic-gate * msgp : CM REQ message that is the source of information
53960Sstevel@tonic-gate *
53970Sstevel@tonic-gate * RETURN VALUE: NONE
53980Sstevel@tonic-gate */
53990Sstevel@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)54000Sstevel@tonic-gate ibcm_set_alt_adds_vect(ibcm_state_data_t *statep,
54010Sstevel@tonic-gate ibt_adds_vect_t *adds_vectp, ibcm_req_msg_t *msgp)
54020Sstevel@tonic-gate {
54030Sstevel@tonic-gate ib_gid_t dgid;
54040Sstevel@tonic-gate ib_gid_t sgid;
54050Sstevel@tonic-gate uint32_t flow_label20_res6_rate6;
54060Sstevel@tonic-gate
54070Sstevel@tonic-gate flow_label20_res6_rate6 = b2h32(msgp->req_alt_flow_label_plus);
54080Sstevel@tonic-gate
54090Sstevel@tonic-gate /* first setup the srvl, srate, dlid and dgid */
54100Sstevel@tonic-gate adds_vectp->av_srvl = msgp->req_alt_sl_plus >> 4;
54110Sstevel@tonic-gate adds_vectp->av_src_path = statep->alt_src_path_bits;
54120Sstevel@tonic-gate
54130Sstevel@tonic-gate if (statep->mode == IBCM_PASSIVE_MODE) {
54140Sstevel@tonic-gate adds_vectp->av_dlid = b2h16(msgp->req_alt_l_port_lid);
54150Sstevel@tonic-gate bcopy(&msgp->req_alt_l_port_gid[0], &dgid, sizeof (ib_gid_t));
54160Sstevel@tonic-gate bcopy(&msgp->req_alt_r_port_gid[0], &sgid, sizeof (ib_gid_t));
54170Sstevel@tonic-gate adds_vectp->av_srate = flow_label20_res6_rate6 & 0x3f;
54180Sstevel@tonic-gate } else {
54190Sstevel@tonic-gate adds_vectp->av_dlid = b2h16(msgp->req_alt_r_port_lid);
54200Sstevel@tonic-gate bcopy(&msgp->req_alt_r_port_gid[0], &dgid, sizeof (ib_gid_t));
54210Sstevel@tonic-gate bcopy(&msgp->req_alt_l_port_gid[0], &sgid, sizeof (ib_gid_t));
54220Sstevel@tonic-gate adds_vectp->av_srate = statep->local_alt_srate;
54230Sstevel@tonic-gate }
54240Sstevel@tonic-gate adds_vectp->av_dgid.gid_prefix = b2h64(dgid.gid_prefix);
54250Sstevel@tonic-gate adds_vectp->av_dgid.gid_guid = b2h64(dgid.gid_guid);
54260Sstevel@tonic-gate adds_vectp->av_sgid.gid_prefix = b2h64(sgid.gid_prefix);
54270Sstevel@tonic-gate adds_vectp->av_sgid.gid_guid = b2h64(sgid.gid_guid);
54280Sstevel@tonic-gate
54290Sstevel@tonic-gate /* next copy off the GRH info if it exists */
54300Sstevel@tonic-gate if ((msgp->req_alt_sl_plus & 0x8) == 0) {
54310Sstevel@tonic-gate adds_vectp->av_send_grh = B_TRUE;
54320Sstevel@tonic-gate adds_vectp->av_flow = flow_label20_res6_rate6 >> 12;
54330Sstevel@tonic-gate adds_vectp->av_tclass = msgp->req_alt_traffic_class;
54340Sstevel@tonic-gate adds_vectp->av_hop = msgp->req_alt_hop_limit;
54350Sstevel@tonic-gate } else {
54360Sstevel@tonic-gate adds_vectp->av_send_grh = B_FALSE; /* no GRH */
54370Sstevel@tonic-gate }
54380Sstevel@tonic-gate }
54390Sstevel@tonic-gate
54400Sstevel@tonic-gate
54410Sstevel@tonic-gate /*
54420Sstevel@tonic-gate * ibcm_set_primary_cep_path:
54430Sstevel@tonic-gate * Helper function used to fill up ibt_cep_path_t PRIMARY PATH
54440Sstevel@tonic-gate * (called from ibcm_cep_state_*() functions)
54450Sstevel@tonic-gate *
54460Sstevel@tonic-gate * INPUTS:
54470Sstevel@tonic-gate * statep : The connection state pointer
54480Sstevel@tonic-gate * adds_vectp : The ibt_cep_path_t ptr that is being filled up
54490Sstevel@tonic-gate * msgp : CM REQ message that is the source of information
54500Sstevel@tonic-gate *
54510Sstevel@tonic-gate * RETURN VALUE: NONE
54520Sstevel@tonic-gate */
54530Sstevel@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)54540Sstevel@tonic-gate ibcm_set_primary_cep_path(ibcm_state_data_t *statep, ibt_cep_path_t *pathp,
54550Sstevel@tonic-gate ibcm_req_msg_t *msgp)
54560Sstevel@tonic-gate {
54570Sstevel@tonic-gate ibt_status_t status;
54580Sstevel@tonic-gate
54590Sstevel@tonic-gate /* validate the PKEY in REQ for prim port */
54600Sstevel@tonic-gate status = ibt_pkey2index_byguid(statep->local_hca_guid,
54610Sstevel@tonic-gate statep->prim_port, b2h16(msgp->req_part_key), &pathp->cep_pkey_ix);
54620Sstevel@tonic-gate
54630Sstevel@tonic-gate if (status != IBT_SUCCESS) {
54640Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_set_primary_cep_path: "
54650Sstevel@tonic-gate "statep 0x%p pkey %x prim_port %d ", statep,
54660Sstevel@tonic-gate b2h16(msgp->req_part_key), statep->prim_port);
54670Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_set_primary_cep_path: "
54680Sstevel@tonic-gate "statep 0x%p Invalid PKEY on prim_port, status %d ",
54690Sstevel@tonic-gate statep, status);
54700Sstevel@tonic-gate return (status);
54710Sstevel@tonic-gate }
54720Sstevel@tonic-gate statep->pkey = b2h16(msgp->req_part_key);
54730Sstevel@tonic-gate ibcm_set_primary_adds_vect(statep, &pathp->cep_adds_vect, msgp);
54740Sstevel@tonic-gate return (IBT_SUCCESS);
54750Sstevel@tonic-gate }
54760Sstevel@tonic-gate
54770Sstevel@tonic-gate
54780Sstevel@tonic-gate /*
54790Sstevel@tonic-gate * ibcm_set_alt_cep_path:
54800Sstevel@tonic-gate * Helper function used to fill up ibt_cep_path_t ALTERNATE PATH
54810Sstevel@tonic-gate * (called from ibcm_cep_state_*() functions)
54820Sstevel@tonic-gate *
54830Sstevel@tonic-gate * INPUTS:
54840Sstevel@tonic-gate * statep : The connection state pointer
54850Sstevel@tonic-gate * adds_vectp : The ibt_cep_path_t ptr that is being filled up
54860Sstevel@tonic-gate * msgp : CM REQ message that is the source of information
54870Sstevel@tonic-gate *
54880Sstevel@tonic-gate * RETURN VALUE: NONE
54890Sstevel@tonic-gate */
54900Sstevel@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)54910Sstevel@tonic-gate ibcm_set_alt_cep_path(ibcm_state_data_t *statep, ibt_cep_path_t *pathp,
54920Sstevel@tonic-gate ibcm_req_msg_t *msgp)
54930Sstevel@tonic-gate {
54940Sstevel@tonic-gate ibt_status_t status;
54950Sstevel@tonic-gate
54960Sstevel@tonic-gate if (b2h16(msgp->req_alt_l_port_lid) == 0) {
54970Sstevel@tonic-gate /* no alternate path specified */
54980Sstevel@tonic-gate return (IBT_SUCCESS);
54990Sstevel@tonic-gate }
55000Sstevel@tonic-gate
55010Sstevel@tonic-gate /* validate the PKEY in REQ for alt port */
55020Sstevel@tonic-gate status = ibt_pkey2index_byguid(statep->local_hca_guid,
55030Sstevel@tonic-gate statep->alt_port, b2h16(msgp->req_part_key), &pathp->cep_pkey_ix);
55040Sstevel@tonic-gate
55050Sstevel@tonic-gate if (status != IBT_SUCCESS) {
55060Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_set_alt_cep_path: "
55070Sstevel@tonic-gate "statep 0x%p pkey %x alt_port %d ", statep,
55080Sstevel@tonic-gate b2h16(msgp->req_part_key), statep->alt_port);
55090Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_set_alt_cep_path: "
55100Sstevel@tonic-gate "statep 0x%p Invalid PKEY on alt_port, status %d ",
55110Sstevel@tonic-gate statep, status);
55120Sstevel@tonic-gate return (status);
55130Sstevel@tonic-gate }
55140Sstevel@tonic-gate pathp->cep_hca_port_num = statep->alt_port;
55150Sstevel@tonic-gate ibcm_set_alt_adds_vect(statep, &pathp->cep_adds_vect, msgp);
55160Sstevel@tonic-gate return (IBT_SUCCESS);
55170Sstevel@tonic-gate
55180Sstevel@tonic-gate }
55190Sstevel@tonic-gate
55200Sstevel@tonic-gate /*
55210Sstevel@tonic-gate * ibcm_compare_prim_alt_paths:
55220Sstevel@tonic-gate * Helper function used to find if primary and alternate paths are
55230Sstevel@tonic-gate * identical
55240Sstevel@tonic-gate * (called from ibcm_cep_state_req)
55250Sstevel@tonic-gate *
55260Sstevel@tonic-gate * INPUTS:
55270Sstevel@tonic-gate * req: Pointer to ibt_cm_req_rcv_t, filled before invoking
55280Sstevel@tonic-gate * the function
55290Sstevel@tonic-gate *
55300Sstevel@tonic-gate * RETURN VALUE: NONE
55310Sstevel@tonic-gate */
55320Sstevel@tonic-gate
55330Sstevel@tonic-gate static boolean_t
ibcm_compare_prim_alt_paths(ibt_adds_vect_t * prim,ibt_adds_vect_t * alt)55340Sstevel@tonic-gate ibcm_compare_prim_alt_paths(ibt_adds_vect_t *prim, ibt_adds_vect_t *alt)
55350Sstevel@tonic-gate {
55360Sstevel@tonic-gate
55370Sstevel@tonic-gate if ((alt->av_dlid == prim->av_dlid) &&
55380Sstevel@tonic-gate (alt->av_dgid.gid_prefix == prim->av_dgid.gid_prefix) &&
55390Sstevel@tonic-gate (alt->av_dgid.gid_guid == prim->av_dgid.gid_guid) &&
55400Sstevel@tonic-gate (alt->av_sgid.gid_prefix == prim->av_sgid.gid_prefix) &&
55410Sstevel@tonic-gate (alt->av_sgid.gid_guid == prim->av_sgid.gid_guid) &&
55420Sstevel@tonic-gate (alt->av_src_path == prim->av_src_path)) {
55430Sstevel@tonic-gate
55440Sstevel@tonic-gate return (B_TRUE);
55450Sstevel@tonic-gate }
55460Sstevel@tonic-gate return (B_FALSE);
55470Sstevel@tonic-gate }
55480Sstevel@tonic-gate
55490Sstevel@tonic-gate
55500Sstevel@tonic-gate /*
55510Sstevel@tonic-gate * ibcm_invoke_qp_modify:
55520Sstevel@tonic-gate * Helper function used to call ibt_modify_qp()
55530Sstevel@tonic-gate * called from ibcm_cep_state_req()/ibcm_cep_state_rep()
55540Sstevel@tonic-gate * It sets up qp_info/eec_info
55550Sstevel@tonic-gate *
55560Sstevel@tonic-gate * Sets state to RTR as well.
55570Sstevel@tonic-gate *
55580Sstevel@tonic-gate *
55590Sstevel@tonic-gate * INPUTS:
55600Sstevel@tonic-gate * statep: The connection state pointer
55610Sstevel@tonic-gate * req_msgp: The CM REQ message
55620Sstevel@tonic-gate *
55630Sstevel@tonic-gate * RETURN VALUE:
55640Sstevel@tonic-gate * IBT_SUCCESS - call succeeded
55650Sstevel@tonic-gate */
55660Sstevel@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)55670Sstevel@tonic-gate ibcm_invoke_qp_modify(ibcm_state_data_t *statep, ibcm_req_msg_t *req_msgp,
55680Sstevel@tonic-gate ibcm_rep_msg_t *rep_msgp)
55690Sstevel@tonic-gate {
55700Sstevel@tonic-gate ibt_status_t status;
55710Sstevel@tonic-gate ibt_qp_info_t qp_info;
55720Sstevel@tonic-gate ibt_cep_modify_flags_t cep_flags;
55730Sstevel@tonic-gate ibt_tran_srv_t trans;
55740Sstevel@tonic-gate
55750Sstevel@tonic-gate cep_flags = IBT_CEP_SET_INIT_RTR | IBT_CEP_SET_PKEY_IX;
55760Sstevel@tonic-gate trans = ((uint8_t *)&req_msgp->req_remote_eecn_plus)[3] >> 1 & 0x3;
55770Sstevel@tonic-gate
55780Sstevel@tonic-gate ASSERT(statep->channel != NULL);
55790Sstevel@tonic-gate
55800Sstevel@tonic-gate /*
55810Sstevel@tonic-gate * If alternate path is present in REQ message then
55820Sstevel@tonic-gate * OR in IBT_CEP_SET_ALT_PATH, if APM supported on hca
55830Sstevel@tonic-gate */
55840Sstevel@tonic-gate if (b2h16(req_msgp->req_alt_l_port_lid) != 0) {
55850Sstevel@tonic-gate
55860Sstevel@tonic-gate if (statep->hcap->hca_caps & IBT_HCA_AUTO_PATH_MIG)
55870Sstevel@tonic-gate cep_flags |= IBT_CEP_SET_ALT_PATH;
55880Sstevel@tonic-gate /* default value of rep_failover is ACCEPT */
55890Sstevel@tonic-gate else {
55900Sstevel@tonic-gate rep_msgp->rep_target_delay_plus |=
55910Sstevel@tonic-gate IBT_CM_FAILOVER_REJ_NOTSUPP << 1;
55920Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_invoke_qp_modify"
55930Sstevel@tonic-gate " Alt Path specified in REQ, but not supported");
55940Sstevel@tonic-gate }
55950Sstevel@tonic-gate }
55960Sstevel@tonic-gate
55970Sstevel@tonic-gate /* If transport type is RD OR in IBC_CEP_SET_QKEY */
55980Sstevel@tonic-gate if (trans == IBT_RD_SRV) {
55990Sstevel@tonic-gate cep_flags |= IBT_CEP_SET_QKEY;
56000Sstevel@tonic-gate }
56010Sstevel@tonic-gate
56020Sstevel@tonic-gate /* Start filling up ibt_qp_info_t. */
56030Sstevel@tonic-gate bzero(&qp_info, sizeof (qp_info));
56040Sstevel@tonic-gate qp_info.qp_trans = trans;
56050Sstevel@tonic-gate qp_info.qp_state = IBT_STATE_RTR;
56060Sstevel@tonic-gate qp_info.qp_flags = IBT_CEP_NO_FLAGS;
56070Sstevel@tonic-gate
56080Sstevel@tonic-gate switch (trans) {
56090Sstevel@tonic-gate case IBT_RC_SRV:
56100Sstevel@tonic-gate
56110Sstevel@tonic-gate if (statep->mode == IBCM_ACTIVE_MODE) {
56120Sstevel@tonic-gate /* Setting PSN on RQ */
56130Sstevel@tonic-gate
56140Sstevel@tonic-gate IBCM_QPINFO_RC(qp_info).rc_rq_psn =
56150Sstevel@tonic-gate b2h32(req_msgp->req_starting_psn_plus) >> 8;
56160Sstevel@tonic-gate
56170Sstevel@tonic-gate IBCM_QPINFO_RC(qp_info).rc_dst_qpn =
56180Sstevel@tonic-gate b2h32(rep_msgp->rep_local_qpn_plus) >> 8;
56190Sstevel@tonic-gate
56200Sstevel@tonic-gate /* RDMA resources taken from negotiated REP values */
56210Sstevel@tonic-gate IBCM_QPINFO_RC(qp_info).rc_rdma_ra_in =
56220Sstevel@tonic-gate rep_msgp->rep_initiator_depth;
56230Sstevel@tonic-gate
56240Sstevel@tonic-gate } else { /* Passive side CM */
56250Sstevel@tonic-gate /* Setting PSN on SQ and RQ */
562611369SPramod.Gunjikar@Sun.COM IBCM_QPINFO_RC(qp_info).rc_sq_psn =
562711369SPramod.Gunjikar@Sun.COM IBCM_QPINFO_RC(qp_info).rc_rq_psn =
56280Sstevel@tonic-gate b2h32(rep_msgp->rep_starting_psn_plus) >> 8;
56290Sstevel@tonic-gate
56300Sstevel@tonic-gate IBCM_QPINFO_RC(qp_info).rc_dst_qpn =
56310Sstevel@tonic-gate b2h32(req_msgp->req_local_qpn_plus) >> 8;
56320Sstevel@tonic-gate
56330Sstevel@tonic-gate /* RDMA resources taken from negotiated REP values */
56340Sstevel@tonic-gate IBCM_QPINFO_RC(qp_info).rc_rdma_ra_in =
56350Sstevel@tonic-gate rep_msgp->rep_resp_resources;
56360Sstevel@tonic-gate }
56370Sstevel@tonic-gate
56380Sstevel@tonic-gate /* XXX, Oh!, ibtl doesn't have interface for setting this */
56390Sstevel@tonic-gate IBCM_QPINFO_RC(qp_info).rc_min_rnr_nak =
56400Sstevel@tonic-gate ibcm_default_rnr_nak_time;
56410Sstevel@tonic-gate IBCM_QPINFO_RC(qp_info).rc_path_mtu =
56420Sstevel@tonic-gate req_msgp->req_mtu_plus >> 4;
56430Sstevel@tonic-gate IBCM_QPINFO_RC(qp_info).rc_retry_cnt =
56440Sstevel@tonic-gate ((uint8_t *)&req_msgp->req_starting_psn_plus)[3] & 0x7;
56450Sstevel@tonic-gate IBCM_QPINFO_RC(qp_info).rc_rnr_retry_cnt =
56460Sstevel@tonic-gate req_msgp->req_mtu_plus & 0x7;
56470Sstevel@tonic-gate
56480Sstevel@tonic-gate if ((status = ibcm_set_primary_cep_path(statep,
56490Sstevel@tonic-gate &IBCM_QPINFO_RC(qp_info).rc_path, req_msgp)) !=
56500Sstevel@tonic-gate IBT_SUCCESS)
56510Sstevel@tonic-gate return (status);
56520Sstevel@tonic-gate
56530Sstevel@tonic-gate if ((status = ibcm_set_alt_cep_path(statep,
56540Sstevel@tonic-gate &IBCM_QPINFO_RC(qp_info).rc_alt_path, req_msgp)) !=
56550Sstevel@tonic-gate IBT_SUCCESS)
56560Sstevel@tonic-gate return (status);
56570Sstevel@tonic-gate
56580Sstevel@tonic-gate break;
56590Sstevel@tonic-gate case IBT_RD_SRV:
56600Sstevel@tonic-gate if (statep->mode == IBCM_ACTIVE_MODE) { /* look at REP msg */
56610Sstevel@tonic-gate IBCM_QPINFO(qp_info).rd.rd_qkey =
56624703Shiremath b2h32(rep_msgp->rep_local_qkey);
56630Sstevel@tonic-gate } else {
56640Sstevel@tonic-gate IBCM_QPINFO(qp_info).rd.rd_qkey =
56654703Shiremath b2h32(req_msgp->req_local_qkey);
56660Sstevel@tonic-gate }
56670Sstevel@tonic-gate
56680Sstevel@tonic-gate break;
56690Sstevel@tonic-gate
56700Sstevel@tonic-gate case IBT_UC_SRV:
56710Sstevel@tonic-gate if (statep->mode == IBCM_ACTIVE_MODE) { /* look at REP msg */
567211369SPramod.Gunjikar@Sun.COM IBCM_QPINFO_UC(qp_info).uc_sq_psn =
56730Sstevel@tonic-gate b2h32(req_msgp->req_starting_psn_plus) >> 8;
56740Sstevel@tonic-gate IBCM_QPINFO_UC(qp_info).uc_dst_qpn =
56750Sstevel@tonic-gate b2h32(rep_msgp->rep_local_qpn_plus) >> 8;
56760Sstevel@tonic-gate } else {
56770Sstevel@tonic-gate IBCM_QPINFO_UC(qp_info).uc_rq_psn =
567811369SPramod.Gunjikar@Sun.COM IBCM_QPINFO_UC(qp_info).uc_sq_psn =
56790Sstevel@tonic-gate b2h32(rep_msgp->rep_starting_psn_plus) >> 8;
56800Sstevel@tonic-gate IBCM_QPINFO_UC(qp_info).uc_dst_qpn =
56810Sstevel@tonic-gate b2h32(req_msgp->req_local_qpn_plus) >> 8;
56820Sstevel@tonic-gate }
56830Sstevel@tonic-gate IBCM_QPINFO_UC(qp_info).uc_path_mtu =
56840Sstevel@tonic-gate req_msgp->req_mtu_plus >> 4;
56850Sstevel@tonic-gate
56860Sstevel@tonic-gate if ((status = ibcm_set_primary_cep_path(statep,
56870Sstevel@tonic-gate &IBCM_QPINFO_UC(qp_info).uc_path, req_msgp)) !=
56880Sstevel@tonic-gate IBT_SUCCESS)
56890Sstevel@tonic-gate return (status);
56900Sstevel@tonic-gate
56910Sstevel@tonic-gate if ((status = ibcm_set_alt_cep_path(statep,
56920Sstevel@tonic-gate &IBCM_QPINFO_UC(qp_info).uc_alt_path, req_msgp)) !=
56930Sstevel@tonic-gate IBT_SUCCESS)
56940Sstevel@tonic-gate return (status);
56950Sstevel@tonic-gate
56960Sstevel@tonic-gate break;
56970Sstevel@tonic-gate default:
56980Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_invoke_qp_modify: "
56990Sstevel@tonic-gate "unknown svc_type = %x", trans);
57000Sstevel@tonic-gate break;
57010Sstevel@tonic-gate }
57020Sstevel@tonic-gate
57030Sstevel@tonic-gate /* Call modify_qp */
57040Sstevel@tonic-gate status = ibt_modify_qp(statep->channel, cep_flags, &qp_info, NULL);
57050Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_invoke_qp_modify: statep 0x%p"
57060Sstevel@tonic-gate " ibt_modify_qp() Init to RTR returned = %d", statep, status);
57070Sstevel@tonic-gate
57080Sstevel@tonic-gate if (status == IBT_SUCCESS)
57090Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_INIT_RTR);
57100Sstevel@tonic-gate else
57110Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_INIT_RTR_FAIL);
57120Sstevel@tonic-gate
57130Sstevel@tonic-gate #ifdef DEBUG
57140Sstevel@tonic-gate
57150Sstevel@tonic-gate print_modify_qp("Init to RTR", statep->channel, cep_flags, &qp_info);
57160Sstevel@tonic-gate
57170Sstevel@tonic-gate if (statep->channel != NULL) {
57180Sstevel@tonic-gate ibt_qp_query_attr_t qp_attrs;
57190Sstevel@tonic-gate
57200Sstevel@tonic-gate (void) ibt_query_qp(statep->channel, &qp_attrs);
57210Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_invoke_qp_modify: "
57220Sstevel@tonic-gate "qp_info.qp_state = %x", qp_attrs.qp_info.qp_state);
57230Sstevel@tonic-gate }
57240Sstevel@tonic-gate #endif
57250Sstevel@tonic-gate
57260Sstevel@tonic-gate return (status);
57270Sstevel@tonic-gate }
57280Sstevel@tonic-gate
57290Sstevel@tonic-gate
57300Sstevel@tonic-gate /*
57310Sstevel@tonic-gate * ibcm_verify_req_gids_and_svcid
57320Sstevel@tonic-gate * Validation of LIDs, GIDs and SVC ID
57330Sstevel@tonic-gate *
57340Sstevel@tonic-gate * INPUTS:
57350Sstevel@tonic-gate * statep - state pointer
57360Sstevel@tonic-gate * cm_req_msgp - REQ message pointer
57370Sstevel@tonic-gate *
57380Sstevel@tonic-gate * RETURN VALUE: IBCM_SUCCESS/IBCM_FAILURE
57390Sstevel@tonic-gate *
57400Sstevel@tonic-gate */
57410Sstevel@tonic-gate ibcm_status_t
ibcm_verify_req_gids_and_svcid(ibcm_state_data_t * statep,ibcm_req_msg_t * cm_req_msgp)57420Sstevel@tonic-gate ibcm_verify_req_gids_and_svcid(ibcm_state_data_t *statep,
57430Sstevel@tonic-gate ibcm_req_msg_t *cm_req_msgp)
57440Sstevel@tonic-gate {
57450Sstevel@tonic-gate ib_gid_t gid;
57460Sstevel@tonic-gate ib_gid_t agid;
57470Sstevel@tonic-gate ib_lid_t lid;
57480Sstevel@tonic-gate ibt_status_t status;
57490Sstevel@tonic-gate ibtl_cm_hca_port_t port;
57500Sstevel@tonic-gate ibt_cm_reason_t reject_reason = IBT_CM_SUCCESS;
57510Sstevel@tonic-gate ibcm_svc_info_t *svc_infop;
57520Sstevel@tonic-gate ibcm_svc_bind_t *svc_bindp;
57530Sstevel@tonic-gate ibcm_svc_bind_t *tmp_bindp;
57540Sstevel@tonic-gate ib_pkey_t pkey;
57550Sstevel@tonic-gate uint8_t port_num;
57560Sstevel@tonic-gate ib_guid_t hca_guid;
57574703Shiremath ibcm_ip_pvtdata_t *ip_data;
57580Sstevel@tonic-gate
57590Sstevel@tonic-gate /* Verify LID and GID of primary port */
57600Sstevel@tonic-gate
57610Sstevel@tonic-gate gid.gid_prefix = b2h64(cm_req_msgp->req_primary_r_port_gid.gid_prefix);
57620Sstevel@tonic-gate gid.gid_guid = b2h64(cm_req_msgp->req_primary_r_port_gid.gid_guid);
57630Sstevel@tonic-gate
57640Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: statep 0x%p"
57650Sstevel@tonic-gate " PRIM _r_gid (%llx, %llx)", statep, gid.gid_prefix,
57660Sstevel@tonic-gate gid.gid_guid);
57670Sstevel@tonic-gate
57680Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: statep 0x%p "
57690Sstevel@tonic-gate "PRIM passive lid %x", statep,
57700Sstevel@tonic-gate b2h16(cm_req_msgp->req_primary_r_port_lid));
57710Sstevel@tonic-gate
57720Sstevel@tonic-gate /* Verify GID validity, if specified */
57730Sstevel@tonic-gate if ((status = ibtl_cm_get_hca_port(gid, 0, &port)) == IBT_SUCCESS) {
57740Sstevel@tonic-gate
57750Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: statep 0x%p "
57760Sstevel@tonic-gate "prim_port_num %d", statep, port.hp_port);
57770Sstevel@tonic-gate
57780Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: statep 0x%p "
57790Sstevel@tonic-gate "passive hca_guid 0x%llX", statep, port.hp_hca_guid);
57800Sstevel@tonic-gate
57810Sstevel@tonic-gate port_num = port.hp_port;
57820Sstevel@tonic-gate hca_guid = port.hp_hca_guid;
57830Sstevel@tonic-gate }
57840Sstevel@tonic-gate
57850Sstevel@tonic-gate if (status != IBT_SUCCESS) {
57860Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_verify_req_gids: statep 0x%p "
57870Sstevel@tonic-gate "ibtl_cm_get_hca_port() primary port failed = %d", statep,
57880Sstevel@tonic-gate status);
57890Sstevel@tonic-gate reject_reason = IBT_CM_PRIM_GID;
57900Sstevel@tonic-gate /* we will search for an acceptable GID to this port */
57910Sstevel@tonic-gate port_num = statep->stored_reply_addr.port_num;
57920Sstevel@tonic-gate hca_guid = statep->hcap->hca_guid;
57930Sstevel@tonic-gate
57940Sstevel@tonic-gate } else if (port.hp_base_lid !=
57954703Shiremath (b2h16(cm_req_msgp->req_primary_r_port_lid) &
57964703Shiremath (~((1 << port.hp_lmc) - 1)))) {
57970Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_verify_req_gids: statep 0x%p "
57980Sstevel@tonic-gate "primary port lid invalid (%x, %x, %x)", statep,
57990Sstevel@tonic-gate port.hp_base_lid,
58000Sstevel@tonic-gate b2h16(cm_req_msgp->req_primary_r_port_lid), port.hp_lmc);
58010Sstevel@tonic-gate reject_reason = IBT_CM_PRIM_LID;
58020Sstevel@tonic-gate } else {
58030Sstevel@tonic-gate
58040Sstevel@tonic-gate statep->local_hca_guid = port.hp_hca_guid;
58050Sstevel@tonic-gate statep->prim_port = port.hp_port;
58060Sstevel@tonic-gate statep->prim_src_path_bits =
58070Sstevel@tonic-gate b2h16(cm_req_msgp->req_primary_r_port_lid) -
58080Sstevel@tonic-gate port.hp_base_lid;
58090Sstevel@tonic-gate
58100Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: "
58110Sstevel@tonic-gate "statep 0x%p prim_port_path_bits %d ",
58120Sstevel@tonic-gate statep, statep->prim_src_path_bits);
58130Sstevel@tonic-gate
58140Sstevel@tonic-gate /* Verify LID and GID of alternate port. Post REJ if invalid */
58150Sstevel@tonic-gate
58160Sstevel@tonic-gate /* Need a bcopy, as alt port gid is unaligned in req message */
58170Sstevel@tonic-gate bcopy(&cm_req_msgp->req_alt_r_port_gid[0], &agid,
58180Sstevel@tonic-gate sizeof (ib_gid_t));
58190Sstevel@tonic-gate agid.gid_prefix = b2h64(agid.gid_prefix);
58200Sstevel@tonic-gate agid.gid_guid = b2h64(agid.gid_guid);
58210Sstevel@tonic-gate
58220Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: statep 0x%p"
58230Sstevel@tonic-gate " Alt port_gid is (%llX:%llX)", statep, agid.gid_prefix,
58240Sstevel@tonic-gate agid.gid_guid);
58250Sstevel@tonic-gate
58260Sstevel@tonic-gate if ((agid.gid_prefix != 0) || (agid.gid_guid != 0)) {
58270Sstevel@tonic-gate
58280Sstevel@tonic-gate /* Verify GID validity, if specified */
58290Sstevel@tonic-gate if ((status = ibtl_cm_get_hca_port(agid,
58300Sstevel@tonic-gate statep->local_hca_guid, &port)) != IBT_SUCCESS) {
58310Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog,
58320Sstevel@tonic-gate "ibcm_verify_req_gids: ibtl_cm_get_hca_port"
58330Sstevel@tonic-gate " statep 0x%p alternate port failed = %d",
58340Sstevel@tonic-gate statep, status);
58350Sstevel@tonic-gate reject_reason = IBT_CM_ALT_GID;
58360Sstevel@tonic-gate
58370Sstevel@tonic-gate } else if (port.hp_base_lid !=
58380Sstevel@tonic-gate (b2h16(cm_req_msgp->req_alt_r_port_lid) &
58390Sstevel@tonic-gate (~((1 << port.hp_lmc) - 1)))) {
58400Sstevel@tonic-gate
58410Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog,
58420Sstevel@tonic-gate "ibcm_verify_req_gids: statep 0x%p "
58430Sstevel@tonic-gate "alternate port lid invalid (%x, %x, %x)",
58440Sstevel@tonic-gate statep, port.hp_base_lid,
58450Sstevel@tonic-gate cm_req_msgp->req_alt_r_port_lid,
58460Sstevel@tonic-gate port.hp_lmc);
58470Sstevel@tonic-gate reject_reason = IBT_CM_ALT_LID;
58480Sstevel@tonic-gate } else { /* Alt LID and GID are valid */
58490Sstevel@tonic-gate statep->alt_port = port.hp_port;
58500Sstevel@tonic-gate statep->alt_src_path_bits =
58510Sstevel@tonic-gate b2h16(cm_req_msgp->req_alt_r_port_lid) -
58520Sstevel@tonic-gate port.hp_base_lid;
58530Sstevel@tonic-gate
58540Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: "
58550Sstevel@tonic-gate "statep 0x%p alt_port_num %d "
58560Sstevel@tonic-gate "alt_rc_hca_guid 0x%llX", statep,
58570Sstevel@tonic-gate port.hp_port, port.hp_hca_guid);
58580Sstevel@tonic-gate
58590Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: "
58600Sstevel@tonic-gate "statep 0x%p alt_port_path_bits %d ",
58610Sstevel@tonic-gate statep, statep->alt_src_path_bits);
58620Sstevel@tonic-gate }
58630Sstevel@tonic-gate }
58640Sstevel@tonic-gate }
58650Sstevel@tonic-gate
58660Sstevel@tonic-gate mutex_enter(&ibcm_svc_info_lock);
58670Sstevel@tonic-gate svc_infop = ibcm_find_svc_entry(statep->svcid);
58680Sstevel@tonic-gate
58690Sstevel@tonic-gate /*
58700Sstevel@tonic-gate * Note: When we return SUCCESS, the reader lock won't get dropped
58710Sstevel@tonic-gate * until after the cm_handler is called from ibcm_cep_state_req().
58720Sstevel@tonic-gate */
58730Sstevel@tonic-gate
58740Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: "
58750Sstevel@tonic-gate "ibcm_find_svc_entry found svc_infop %p", svc_infop);
58760Sstevel@tonic-gate
58770Sstevel@tonic-gate /*
58780Sstevel@tonic-gate * Send REJ with reject reason "invalid service id" for the
58790Sstevel@tonic-gate * the following cases :-
58800Sstevel@tonic-gate * Service id is valid, but not available at gid/lid of REQ
58810Sstevel@tonic-gate * Service id is invalid
58820Sstevel@tonic-gate */
58830Sstevel@tonic-gate
58840Sstevel@tonic-gate if (svc_infop == NULL || svc_infop->svc_bind_list == NULL) {
58850Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
58860Sstevel@tonic-gate
58870Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_verify_req_gids_and_svcid: "
58880Sstevel@tonic-gate "statep 0x%p svc_id %llX svc_infop NULL", statep,
58890Sstevel@tonic-gate statep->svcid);
58900Sstevel@tonic-gate
58910Sstevel@tonic-gate /* Send a REJ with invalid SID reason */
58920Sstevel@tonic-gate ibcm_post_rej_mad(statep,
58930Sstevel@tonic-gate IBT_CM_INVALID_SID, IBT_CM_FAILURE_REQ, NULL, 0);
58940Sstevel@tonic-gate return (IBCM_FAILURE);
58950Sstevel@tonic-gate }
58960Sstevel@tonic-gate
58970Sstevel@tonic-gate if (svc_infop->svc_rc_handler == NULL) {
58980Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
58990Sstevel@tonic-gate
59000Sstevel@tonic-gate /* Send a REJ with invalid SID reason */
59010Sstevel@tonic-gate ibcm_post_rej_mad(statep,
59020Sstevel@tonic-gate IBT_CM_INVALID_SRV_TYPE, IBT_CM_FAILURE_REQ, NULL, 0);
59030Sstevel@tonic-gate return (IBCM_FAILURE);
59040Sstevel@tonic-gate }
59050Sstevel@tonic-gate
59064703Shiremath /*
59074703Shiremath * Check if ServiceID is in RDMA IP CM SID range, if yes, we parse
59084703Shiremath * the REQ's Private Data and verify for it's goodness.
59094703Shiremath */
59104703Shiremath if (((statep->svcid & IB_SID_IPADDR_PREFIX_MASK) == 0) &&
59114703Shiremath (statep->svcid & IB_SID_IPADDR_PREFIX)) {
59124703Shiremath ibt_ari_ip_t ari_ip;
59134703Shiremath boolean_t rdma_rej_mad = B_FALSE;
59144703Shiremath
59154703Shiremath if (cm_req_msgp->req_private_data == NULL) {
59164703Shiremath mutex_exit(&ibcm_svc_info_lock);
59174703Shiremath
59184703Shiremath IBTF_DPRINTF_L2(cmlog, "ibcm_verify_req_gids_and_svcid:"
59194703Shiremath " RDMA CM IP REQ Priv Data is NULL");
59204703Shiremath
59214703Shiremath /* Send a REJ with CONSUMER REJ */
59224703Shiremath ibcm_post_rej_mad(statep, IBT_CM_CONSUMER,
59234703Shiremath IBT_CM_FAILURE_REQ, NULL, 0);
59244703Shiremath return (IBCM_FAILURE);
59254703Shiremath }
59264703Shiremath ip_data = (ibcm_ip_pvtdata_t *)cm_req_msgp->req_private_data;
59274703Shiremath
59284703Shiremath bzero(&ari_ip, sizeof (ibt_ari_ip_t));
59294703Shiremath
59304703Shiremath /* RDMA IP CM Layer Rejects this */
59314703Shiremath if (ip_data->ip_MajV != IBT_CM_IP_MAJ_VER) {
59324703Shiremath IBTF_DPRINTF_L2(cmlog, "ibcm_verify_req_gids_and_svcid:"
59334703Shiremath "IP MajorVer mis-match %d", ip_data->ip_MajV);
59344703Shiremath ari_ip.ip_reason = IBT_ARI_IP_MAJOR_VERSION;
59354703Shiremath ari_ip.ip_suggested_version = IBT_CM_IP_MAJ_VER;
59364703Shiremath ari_ip.ip_suggested = B_TRUE;
59374703Shiremath rdma_rej_mad = B_TRUE;
59384703Shiremath } else if (ip_data->ip_MinV != IBT_CM_IP_MIN_VER) {
59394703Shiremath IBTF_DPRINTF_L2(cmlog, "ibcm_verify_req_gids_and_svcid:"
59404703Shiremath "IP MinorVer mis-match %d", ip_data->ip_MinV);
59414703Shiremath ari_ip.ip_reason = IBT_ARI_IP_MINOR_VERSION;
59424703Shiremath ari_ip.ip_suggested_version = IBT_CM_IP_MIN_VER;
59434703Shiremath ari_ip.ip_suggested = B_TRUE;
59444703Shiremath rdma_rej_mad = B_TRUE;
59454703Shiremath } else if ((ip_data->ip_ipv != IBT_CM_IP_IPV_V4) &&
59464703Shiremath (ip_data->ip_ipv != IBT_CM_IP_IPV_V6)) {
59474703Shiremath IBTF_DPRINTF_L2(cmlog, "ibcm_verify_req_gids_and_svcid:"
59484703Shiremath " Invalid IPV specified %d", ip_data->ip_ipv);
59494703Shiremath ari_ip.ip_reason = IBT_ARI_IP_IPV;
59504703Shiremath ari_ip.ip_suggested_version = IBT_CM_IP_IPV_V4;
59514703Shiremath ari_ip.ip_suggested = B_TRUE;
59524703Shiremath rdma_rej_mad = B_TRUE;
59534703Shiremath } else {
59544703Shiremath /*
59554703Shiremath * Validate whether ip_addr specified are non-NULL.
59564703Shiremath *
59574703Shiremath * NOTE:
59584703Shiremath * RDMA ULP which is servicing this SID, should validate
59594703Shiremath * the correctness of srcip/dstip and accordingly post
59604703Shiremath * REJ related to ibt_ari_ip_reason_t of
59614703Shiremath * IBT_ARI_IP_SRC_ADDR, IBT_ARI_IP_DST_ADDR and
59624703Shiremath * IBT_ARI_IP_UNKNOWN_ADDR.
59634703Shiremath */
59644703Shiremath if (ip_data->ip_ipv == IBT_CM_IP_IPV_V4) {
59654703Shiremath if (ip_data->ip_srcv4 == 0) {
59664703Shiremath IBTF_DPRINTF_L2(cmlog,
59674703Shiremath "ibcm_verify_req_gids_and_svcid: "
59684703Shiremath "Invalid NULL V4 SrcIp specified");
59694703Shiremath rdma_rej_mad = B_TRUE;
59704703Shiremath ari_ip.ip_reason = IBT_ARI_IP_SRC_ADDR;
59714703Shiremath ari_ip.ip_suggested = B_TRUE;
59724703Shiremath ari_ip.ip_suggested_version =
59734703Shiremath IBT_CM_IP_IPV_V4;
59744703Shiremath } else if (ip_data->ip_dstv4 == 0) {
59754703Shiremath IBTF_DPRINTF_L2(cmlog,
59764703Shiremath "ibcm_verify_req_gids_and_svcid: "
59774703Shiremath "Invalid NULL V4 DstIp specified");
59784703Shiremath rdma_rej_mad = B_TRUE;
59794703Shiremath ari_ip.ip_reason = IBT_ARI_IP_DST_ADDR;
59804703Shiremath ari_ip.ip_suggested = B_TRUE;
59814703Shiremath ari_ip.ip_suggested_version =
59824703Shiremath IBT_CM_IP_IPV_V4;
59834703Shiremath }
59844703Shiremath } else if (ip_data->ip_ipv == IBT_CM_IP_IPV_V6) {
59854703Shiremath if (IN6_IS_ADDR_UNSPECIFIED(
59864703Shiremath &ip_data->ip_srcv6)) {
59874703Shiremath IBTF_DPRINTF_L2(cmlog,
59884703Shiremath "ibcm_verify_req_gids_and_svcid: "
59894703Shiremath "Invalid NULL V6 SrcIp specified");
59904703Shiremath rdma_rej_mad = B_TRUE;
59914703Shiremath ari_ip.ip_reason = IBT_ARI_IP_SRC_ADDR;
59924703Shiremath ari_ip.ip_suggested = B_TRUE;
59934703Shiremath ari_ip.ip_suggested_version =
59944703Shiremath IBT_CM_IP_IPV_V6;
59954703Shiremath } else if (IN6_IS_ADDR_UNSPECIFIED(
59964703Shiremath &ip_data->ip_dstv6)) {
59974703Shiremath IBTF_DPRINTF_L2(cmlog,
59984703Shiremath "ibcm_verify_req_gids_and_svcid: "
59994703Shiremath "Invalid NULL V6 DstIp specified");
60004703Shiremath rdma_rej_mad = B_TRUE;
60014703Shiremath ari_ip.ip_reason = IBT_ARI_IP_DST_ADDR;
60024703Shiremath ari_ip.ip_suggested = B_TRUE;
60034703Shiremath ari_ip.ip_suggested_version =
60044703Shiremath IBT_CM_IP_IPV_V6;
60054703Shiremath }
60064703Shiremath }
60074703Shiremath /* TBD: IBT_ARI_IP_UNKNOWN_ADDR */
60084703Shiremath }
60094703Shiremath if (rdma_rej_mad == B_TRUE) {
60104703Shiremath ibt_ari_con_t cons_rej;
60114703Shiremath
60124703Shiremath mutex_exit(&ibcm_svc_info_lock);
60134703Shiremath
60144703Shiremath cons_rej.rej_ari_len = 1 + sizeof (ibt_ari_ip_t);
60154703Shiremath cons_rej.rej_ari[0] = 0; /* Rejected by CM Layer */
60164703Shiremath bcopy(&ari_ip, &cons_rej.rej_ari[1],
60174703Shiremath sizeof (ibt_ari_ip_t));
60184703Shiremath /* Send a REJ with CONSUMER REJ */
60194703Shiremath ibcm_post_rej_mad(statep, IBT_CM_CONSUMER,
60204703Shiremath IBT_CM_FAILURE_REQ, &cons_rej,
60214703Shiremath sizeof (ibt_ari_con_t));
60224703Shiremath return (IBCM_FAILURE);
60234703Shiremath }
60244703Shiremath }
60254703Shiremath
60260Sstevel@tonic-gate /* find the best "bind" entry that enables this port */
60270Sstevel@tonic-gate
60280Sstevel@tonic-gate pkey = b2h16(cm_req_msgp->req_part_key);
60290Sstevel@tonic-gate svc_bindp = NULL;
60300Sstevel@tonic-gate tmp_bindp = svc_infop->svc_bind_list;
60310Sstevel@tonic-gate while (tmp_bindp) {
60320Sstevel@tonic-gate if (tmp_bindp->sbind_hcaguid == hca_guid &&
60330Sstevel@tonic-gate tmp_bindp->sbind_port == port_num) {
60340Sstevel@tonic-gate if (gid.gid_guid ==
60350Sstevel@tonic-gate tmp_bindp->sbind_gid.gid_guid &&
60360Sstevel@tonic-gate gid.gid_prefix ==
60370Sstevel@tonic-gate tmp_bindp->sbind_gid.gid_prefix) {
60380Sstevel@tonic-gate /* gid match => really good match */
60390Sstevel@tonic-gate svc_bindp = tmp_bindp;
60400Sstevel@tonic-gate if (pkey == tmp_bindp->sbind_pkey)
60410Sstevel@tonic-gate /* absolute best match */
60420Sstevel@tonic-gate break;
60430Sstevel@tonic-gate } else if (svc_bindp == NULL) {
60440Sstevel@tonic-gate /* port match => a good match */
60450Sstevel@tonic-gate svc_bindp = tmp_bindp;
60460Sstevel@tonic-gate }
60470Sstevel@tonic-gate }
60480Sstevel@tonic-gate tmp_bindp = tmp_bindp->sbind_link;
60490Sstevel@tonic-gate }
60500Sstevel@tonic-gate if (svc_bindp == NULL) { /* port not enabled for this SID */
60510Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
60520Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog,
60530Sstevel@tonic-gate "ibcm_verify_req_gids_and_svcid: statep 0x%p "
60540Sstevel@tonic-gate "no binding found", statep);
60550Sstevel@tonic-gate ibcm_post_rej_mad(statep,
60560Sstevel@tonic-gate IBT_CM_INVALID_SID, IBT_CM_FAILURE_REQ, NULL, 0);
60570Sstevel@tonic-gate return (IBCM_FAILURE);
60580Sstevel@tonic-gate }
60590Sstevel@tonic-gate /* copy the GID in case we need it in REJ below */
60600Sstevel@tonic-gate gid.gid_prefix = b2h64(svc_bindp->sbind_gid.gid_prefix);
60610Sstevel@tonic-gate gid.gid_guid = b2h64(svc_bindp->sbind_gid.gid_guid);
60620Sstevel@tonic-gate
60630Sstevel@tonic-gate statep->state_cm_private = svc_bindp->sbind_cm_private;
60640Sstevel@tonic-gate statep->state_svc_infop = svc_infop;
60650Sstevel@tonic-gate statep->cm_handler = svc_infop->svc_rc_handler;
60660Sstevel@tonic-gate if (reject_reason == IBT_CM_SUCCESS)
60670Sstevel@tonic-gate IBCM_SVC_INCR(svc_infop);
60680Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
60690Sstevel@tonic-gate
60700Sstevel@tonic-gate /*
60710Sstevel@tonic-gate * If the service id is valid, but gid in REQ is invalid,
60720Sstevel@tonic-gate * then send a REJ with invalid gid
60730Sstevel@tonic-gate * For Invalid primary gid, the ARI field is filled with
60740Sstevel@tonic-gate * with gid from svcinfo
60750Sstevel@tonic-gate * For invalid prim/alt gid reject, CM uses one of the gids
60760Sstevel@tonic-gate * registered in ARI.
60770Sstevel@tonic-gate * For invalid prim/alt lid reject, CM uses the base lid in ARI
60780Sstevel@tonic-gate */
60790Sstevel@tonic-gate if (reject_reason != IBT_CM_SUCCESS) {
60800Sstevel@tonic-gate
60810Sstevel@tonic-gate switch (reject_reason) {
60820Sstevel@tonic-gate
60830Sstevel@tonic-gate case IBT_CM_PRIM_GID :
60840Sstevel@tonic-gate case IBT_CM_ALT_GID :
60850Sstevel@tonic-gate ibcm_post_rej_mad(statep,
60860Sstevel@tonic-gate reject_reason, IBT_CM_FAILURE_REQ,
60870Sstevel@tonic-gate &gid, sizeof (ib_gid_t));
60880Sstevel@tonic-gate break;
60890Sstevel@tonic-gate
60900Sstevel@tonic-gate case IBT_CM_PRIM_LID :
60910Sstevel@tonic-gate case IBT_CM_ALT_LID :
60920Sstevel@tonic-gate
60930Sstevel@tonic-gate lid = h2b16(port.hp_base_lid);
60940Sstevel@tonic-gate ibcm_post_rej_mad(statep,
60950Sstevel@tonic-gate reject_reason, IBT_CM_FAILURE_REQ,
60960Sstevel@tonic-gate &lid, sizeof (ib_lid_t));
60970Sstevel@tonic-gate break;
60980Sstevel@tonic-gate }
60990Sstevel@tonic-gate
61000Sstevel@tonic-gate return (IBCM_FAILURE);
61010Sstevel@tonic-gate }
61020Sstevel@tonic-gate
61030Sstevel@tonic-gate /* Service, primary/alt gid and lid are all valid */
61040Sstevel@tonic-gate
61050Sstevel@tonic-gate return (IBCM_SUCCESS);
61060Sstevel@tonic-gate }
61070Sstevel@tonic-gate
61080Sstevel@tonic-gate /*
61090Sstevel@tonic-gate * ibcm_cep_state_req:
61100Sstevel@tonic-gate * QP state transition function called for an incoming REQ on passive side
61110Sstevel@tonic-gate * LIDs and GIDs should be maintained and validated by the client handler
61120Sstevel@tonic-gate *
61130Sstevel@tonic-gate * INPUTS:
61140Sstevel@tonic-gate * statep - state pointer
61150Sstevel@tonic-gate * cm_req_msgp - REQ message pointer
61160Sstevel@tonic-gate * reject_reason - Rejection reason See Section 12.6.7.2 rev1.0a IB Spec
61170Sstevel@tonic-gate * arej_info_len - Additional Rejection reason info length
61180Sstevel@tonic-gate *
61190Sstevel@tonic-gate * RETURN VALUE: IBCM_SEND_REP/IBCM_SEND_REJ
61200Sstevel@tonic-gate */
61210Sstevel@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)61220Sstevel@tonic-gate ibcm_cep_state_req(ibcm_state_data_t *statep, ibcm_req_msg_t *cm_req_msgp,
61230Sstevel@tonic-gate ibt_cm_reason_t *reject_reason, uint8_t *arej_len)
61240Sstevel@tonic-gate {
61250Sstevel@tonic-gate void *priv_data = NULL;
61260Sstevel@tonic-gate ibt_cm_event_t event;
61270Sstevel@tonic-gate ibt_cm_status_t cb_status;
61280Sstevel@tonic-gate ibcm_status_t status;
61290Sstevel@tonic-gate ibt_cm_return_args_t ret_args;
61300Sstevel@tonic-gate ibcm_clnt_reply_info_t clnt_info;
61310Sstevel@tonic-gate
61320Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_req: statep 0x%p", statep);
61339913SShantkumar.Hiremath@Sun.COM IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_req: SID 0x%lX",
61349913SShantkumar.Hiremath@Sun.COM b2h64(cm_req_msgp->req_svc_id));
61350Sstevel@tonic-gate /* client handler should be valid */
61360Sstevel@tonic-gate ASSERT(statep->cm_handler != NULL);
61370Sstevel@tonic-gate
61380Sstevel@tonic-gate bzero(&event, sizeof (event));
61390Sstevel@tonic-gate
61400Sstevel@tonic-gate /* Fill in ibt_cm_event_t */
61410Sstevel@tonic-gate event.cm_type = IBT_CM_EVENT_REQ_RCV;
61420Sstevel@tonic-gate event.cm_session_id = statep;
61430Sstevel@tonic-gate IBCM_EVT_REQ(event).req_service_id = b2h64(cm_req_msgp->req_svc_id);
61440Sstevel@tonic-gate IBCM_EVT_REQ(event).req_transport =
61450Sstevel@tonic-gate ((uint8_t *)&cm_req_msgp->req_remote_eecn_plus)[3] >> 1 & 0x3;
61460Sstevel@tonic-gate IBCM_EVT_REQ(event).req_timeout = ibt_ib2usec(
61470Sstevel@tonic-gate (((uint8_t *)&cm_req_msgp->req_remote_eecn_plus)[3] >> 3) & 0x1F);
61480Sstevel@tonic-gate IBCM_EVT_REQ(event).req_retry_cnt =
61490Sstevel@tonic-gate ((uint8_t *)&cm_req_msgp->req_starting_psn_plus)[3] & 0x7;
61500Sstevel@tonic-gate IBCM_EVT_REQ(event).req_rnr_retry_cnt = cm_req_msgp->req_mtu_plus & 0x7;
61510Sstevel@tonic-gate IBCM_EVT_REQ(event).req_pkey = b2h16(cm_req_msgp->req_part_key);
61520Sstevel@tonic-gate IBCM_EVT_REQ(event).req_rdma_ra_in =
61530Sstevel@tonic-gate ((uint8_t *)&cm_req_msgp->req_local_qpn_plus)[3];
61540Sstevel@tonic-gate IBCM_EVT_REQ(event).req_rdma_ra_out =
61550Sstevel@tonic-gate ((uint8_t *)&cm_req_msgp->req_local_eec_no_plus)[3];
61560Sstevel@tonic-gate
61576709Shiremath /* Check for HCA limits for RDMA Resources */
61586709Shiremath if (IBCM_EVT_REQ(event).req_rdma_ra_in >
61596709Shiremath statep->hcap->hca_max_rdma_in_qp) {
61606709Shiremath IBTF_DPRINTF_L2(cmlog, "ibcm_cep_state_req: statep 0x%p, REQ "
61616709Shiremath "req_rdma_ra_in %d is greater than HCA Limit %d, resetting"
61626709Shiremath "it to HCA limit", statep,
61636709Shiremath IBCM_EVT_REQ(event).req_rdma_ra_in,
61646709Shiremath statep->hcap->hca_max_rdma_in_qp);
61656709Shiremath IBCM_EVT_REQ(event).req_rdma_ra_in =
61666709Shiremath statep->hcap->hca_max_rdma_in_qp;
61676709Shiremath }
61686709Shiremath
61696709Shiremath if (IBCM_EVT_REQ(event).req_rdma_ra_out >
61706709Shiremath statep->hcap->hca_max_rdma_out_qp) {
61716709Shiremath IBTF_DPRINTF_L2(cmlog, "ibcm_cep_state_req: statep 0x%p, REQ "
61726709Shiremath "req_rdma_ra_out %d is greater than HCA Limit %d, resetting"
61736709Shiremath "it to HCA limit", statep,
61746709Shiremath IBCM_EVT_REQ(event).req_rdma_ra_out,
61756709Shiremath statep->hcap->hca_max_rdma_out_qp);
61766709Shiremath IBCM_EVT_REQ(event).req_rdma_ra_out =
61776709Shiremath statep->hcap->hca_max_rdma_out_qp;
61786709Shiremath }
61796709Shiremath
61800Sstevel@tonic-gate /* Account for CM and other software delays */
61810Sstevel@tonic-gate if (IBCM_EVT_REQ(event).req_timeout > ibcm_sw_delay) {
61820Sstevel@tonic-gate IBCM_EVT_REQ(event).req_timeout -= ibcm_sw_delay;
61830Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_cep_state_req: statep 0x%p"
61840Sstevel@tonic-gate "Avail resp time %d (usec)", statep,
61850Sstevel@tonic-gate IBCM_EVT_REQ(event).req_timeout);
61860Sstevel@tonic-gate } else {
61870Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_cep_state_req: statep 0x%p "
61880Sstevel@tonic-gate "REQ rem_resp_time < local sw delay 0x%x", statep,
61890Sstevel@tonic-gate IBCM_EVT_REQ(event).req_timeout);
61900Sstevel@tonic-gate
61910Sstevel@tonic-gate IBCM_EVT_REQ(event).req_timeout = 0;
61920Sstevel@tonic-gate }
61930Sstevel@tonic-gate
61940Sstevel@tonic-gate IBCM_EVT_REQ(event).req_prim_hca_port = statep->prim_port;
61950Sstevel@tonic-gate IBCM_EVT_REQ(event).req_alt_hca_port = statep->alt_port;
61960Sstevel@tonic-gate IBCM_EVT_REQ(event).req_hca_guid = statep->local_hca_guid;
61970Sstevel@tonic-gate IBCM_EVT_REQ(event).req_remote_qpn = statep->remote_qpn;
61980Sstevel@tonic-gate
61990Sstevel@tonic-gate if (((uint8_t *)&cm_req_msgp->req_remote_eecn_plus)[3] &
62000Sstevel@tonic-gate IBT_CM_FLOW_CONTROL)
62010Sstevel@tonic-gate IBCM_EVT_REQ(event).req_flags |= IBT_CM_FLOW_CONTROL;
62020Sstevel@tonic-gate
62030Sstevel@tonic-gate if ((cm_req_msgp->req_max_cm_retries_plus >> 3) & 0x1)
62040Sstevel@tonic-gate IBCM_EVT_REQ(event).req_flags |= IBT_CM_SRQ_EXISTS;
62050Sstevel@tonic-gate
62060Sstevel@tonic-gate /* Initialize req.req_prim_addr */
62070Sstevel@tonic-gate ibcm_set_primary_adds_vect(statep, &IBCM_EVT_REQ(event).req_prim_addr,
62080Sstevel@tonic-gate cm_req_msgp);
62090Sstevel@tonic-gate
62100Sstevel@tonic-gate /* Initialize req.req_alternate_path if they exist */
62110Sstevel@tonic-gate if (b2h16(cm_req_msgp->req_alt_l_port_lid) != 0) {
62120Sstevel@tonic-gate ibcm_set_alt_adds_vect(statep,
62130Sstevel@tonic-gate &IBCM_EVT_REQ(event).req_alt_addr, cm_req_msgp);
62140Sstevel@tonic-gate
62150Sstevel@tonic-gate /* Verify, alt path is not same as primary */
62160Sstevel@tonic-gate if (ibcm_compare_prim_alt_paths(
62170Sstevel@tonic-gate &event.cm_event.req.req_prim_addr,
62180Sstevel@tonic-gate &event.cm_event.req.req_alt_addr) == B_TRUE) {
62190Sstevel@tonic-gate /* XXX New REJ code needed */
62200Sstevel@tonic-gate *reject_reason = IBT_CM_NO_RESC;
62210Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_cep_state_req: statep 0x%p"
62220Sstevel@tonic-gate " Alt and prim paths are same", statep);
62230Sstevel@tonic-gate mutex_enter(&ibcm_svc_info_lock);
62240Sstevel@tonic-gate IBCM_SVC_DECR(statep->state_svc_infop);
62250Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
62260Sstevel@tonic-gate return (IBCM_SEND_REJ);
62270Sstevel@tonic-gate }
62280Sstevel@tonic-gate }
62290Sstevel@tonic-gate
62300Sstevel@tonic-gate #ifdef NO_EEC_SUPPORT_YET
62310Sstevel@tonic-gate IBCM_EVT_REQ(event).req_rdc_exists = cm_req_msgp->req_mtu_plus >> 3 & 1;
62320Sstevel@tonic-gate IBCM_EVT_REQ(event).req_remote_eecn =
62330Sstevel@tonic-gate b2h32(cm_req_msgp->req_remote_eecn_plus) >> 8;
62340Sstevel@tonic-gate IBCM_EVT_REQ(event).req_local_eecn =
62350Sstevel@tonic-gate b2h32(cm_req_msgp->req_local_eec_no_plus) >> 8;
62360Sstevel@tonic-gate IBCM_EVT_REQ(event).req_remote_qkey =
62370Sstevel@tonic-gate b2h32(cm_req_msgp->req_local_qkey);
62380Sstevel@tonic-gate #endif
62390Sstevel@tonic-gate
62400Sstevel@tonic-gate /* cm_req_msgp->req_private_data to event.cm_event.cm_priv_data */
62410Sstevel@tonic-gate event.cm_priv_data = cm_req_msgp->req_private_data;
62420Sstevel@tonic-gate
62430Sstevel@tonic-gate event.cm_priv_data_len = IBT_REQ_PRIV_DATA_SZ;
62440Sstevel@tonic-gate
62450Sstevel@tonic-gate /*
62460Sstevel@tonic-gate * Allocate priv_data of size IBT_MAX_PRIV_DATA_SZ
62470Sstevel@tonic-gate */
62480Sstevel@tonic-gate priv_data = kmem_zalloc(IBT_MAX_PRIV_DATA_SZ, KM_SLEEP);
62490Sstevel@tonic-gate
62500Sstevel@tonic-gate bzero(&ret_args, sizeof (ret_args));
62510Sstevel@tonic-gate
62520Sstevel@tonic-gate /* Fill in the default values from REQ, that client can modify */
62530Sstevel@tonic-gate ret_args.cm_ret.rep.cm_rdma_ra_in = IBCM_EVT_REQ(event).req_rdma_ra_out;
62540Sstevel@tonic-gate ret_args.cm_ret.rep.cm_rdma_ra_out = IBCM_EVT_REQ(event).req_rdma_ra_in;
62550Sstevel@tonic-gate ret_args.cm_ret.rep.cm_rnr_retry_cnt = cm_req_msgp->req_mtu_plus & 0x7;
62560Sstevel@tonic-gate
62570Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_CALLED_REQ_RCVD_EVENT);
62580Sstevel@tonic-gate
62590Sstevel@tonic-gate /* Invoke the client handler */
62609913SShantkumar.Hiremath@Sun.COM statep->req_msgp = cm_req_msgp;
62610Sstevel@tonic-gate cb_status = statep->cm_handler(statep->state_cm_private, &event,
62620Sstevel@tonic-gate &ret_args, priv_data, IBT_REP_PRIV_DATA_SZ);
62639913SShantkumar.Hiremath@Sun.COM statep->req_msgp = NULL;
62640Sstevel@tonic-gate
62650Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_RET_REQ_RCVD_EVENT);
62660Sstevel@tonic-gate
62670Sstevel@tonic-gate mutex_enter(&ibcm_svc_info_lock);
62680Sstevel@tonic-gate IBCM_SVC_DECR(statep->state_svc_infop);
62690Sstevel@tonic-gate mutex_exit(&ibcm_svc_info_lock);
62700Sstevel@tonic-gate
62710Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_req: Client handler returned %d"
62720Sstevel@tonic-gate " statep 0x%p", cb_status, statep);
62730Sstevel@tonic-gate
62740Sstevel@tonic-gate if (cb_status == IBT_CM_DEFER) {
62750Sstevel@tonic-gate
62760Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(statep->defer_cm_msg))
62770Sstevel@tonic-gate
62780Sstevel@tonic-gate if (statep->defer_cm_msg == NULL)
62790Sstevel@tonic-gate statep->defer_cm_msg =
62800Sstevel@tonic-gate kmem_zalloc(IBCM_MSG_SIZE, KM_SLEEP);
62810Sstevel@tonic-gate bcopy(cm_req_msgp, statep->defer_cm_msg, IBCM_MSG_SIZE);
62820Sstevel@tonic-gate
62830Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(statep->defer_cm_msg))
62840Sstevel@tonic-gate
62850Sstevel@tonic-gate /*
62860Sstevel@tonic-gate * unblock any blocked cm proceed api calls. Do not access
62870Sstevel@tonic-gate * statep after cv_signal
62880Sstevel@tonic-gate */
62890Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
62900Sstevel@tonic-gate statep->clnt_proceed = IBCM_UNBLOCK;
62910Sstevel@tonic-gate cv_broadcast(&statep->block_client_cv);
62920Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
62930Sstevel@tonic-gate
62940Sstevel@tonic-gate kmem_free(priv_data, IBT_MAX_PRIV_DATA_SZ);
62950Sstevel@tonic-gate return (IBCM_DEFER);
62960Sstevel@tonic-gate }
62970Sstevel@tonic-gate
62980Sstevel@tonic-gate /* fail any blocked cm proceed api call - client bug */
62990Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
63000Sstevel@tonic-gate statep->clnt_proceed = IBCM_FAIL;
63010Sstevel@tonic-gate cv_broadcast(&statep->block_client_cv);
63020Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
63030Sstevel@tonic-gate
63040Sstevel@tonic-gate clnt_info.reply_event = (ibt_cm_proceed_reply_t *)&ret_args.cm_ret;
63050Sstevel@tonic-gate clnt_info.priv_data = priv_data;
63060Sstevel@tonic-gate clnt_info.priv_data_len = ret_args.cm_ret_len;
63070Sstevel@tonic-gate
63080Sstevel@tonic-gate status =
63094703Shiremath ibcm_process_cep_req_cm_hdlr(statep, cb_status,
63104703Shiremath &clnt_info, reject_reason, arej_len, cm_req_msgp);
63110Sstevel@tonic-gate kmem_free(priv_data, IBT_MAX_PRIV_DATA_SZ);
63120Sstevel@tonic-gate return (status);
63130Sstevel@tonic-gate }
63140Sstevel@tonic-gate
63150Sstevel@tonic-gate /*
63160Sstevel@tonic-gate * ibcm_process_cep_req_cm_hdlr:
63170Sstevel@tonic-gate * Processes the response from client handler for an incoming REQ.
63180Sstevel@tonic-gate */
63190Sstevel@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)63200Sstevel@tonic-gate ibcm_process_cep_req_cm_hdlr(ibcm_state_data_t *statep,
63210Sstevel@tonic-gate ibt_cm_status_t cb_status, ibcm_clnt_reply_info_t *clnt_info,
63220Sstevel@tonic-gate ibt_cm_reason_t *reject_reason, uint8_t *arej_len,
63230Sstevel@tonic-gate ibcm_req_msg_t *cm_req_msg)
63240Sstevel@tonic-gate {
63250Sstevel@tonic-gate ibt_status_t status;
63260Sstevel@tonic-gate ibt_qp_query_attr_t qp_attrs;
63270Sstevel@tonic-gate ibcm_state_data_t *old_statep;
63280Sstevel@tonic-gate ibt_channel_hdl_t channel;
63290Sstevel@tonic-gate ib_guid_t local_ca_guid;
63300Sstevel@tonic-gate ibcm_rej_msg_t *rej_msgp;
63310Sstevel@tonic-gate #ifdef NO_EEC_SUPPORT_YET
63320Sstevel@tonic-gate ibt_eec_query_attr_t eec_attrs;
63330Sstevel@tonic-gate #endif
63340Sstevel@tonic-gate
63350Sstevel@tonic-gate if (cb_status == IBT_CM_DEFAULT)
63360Sstevel@tonic-gate cb_status = IBT_CM_REJECT;
63370Sstevel@tonic-gate
63380Sstevel@tonic-gate /* verify status */
63390Sstevel@tonic-gate if (cb_status == IBT_CM_ACCEPT) {
63400Sstevel@tonic-gate *reject_reason = IBT_CM_SUCCESS;
63410Sstevel@tonic-gate } else if (cb_status == IBT_CM_REJECT) {
63420Sstevel@tonic-gate *reject_reason = IBT_CM_CONSUMER;
63430Sstevel@tonic-gate } else if (cb_status == IBT_CM_REDIRECT_PORT) {
63440Sstevel@tonic-gate *reject_reason = IBT_CM_PORT_REDIRECT;
63450Sstevel@tonic-gate } else if (cb_status == IBT_CM_REDIRECT) {
63460Sstevel@tonic-gate *reject_reason = IBT_CM_REDIRECT_CM;
63470Sstevel@tonic-gate } else if (cb_status == IBT_CM_NO_CHANNEL) {
63480Sstevel@tonic-gate *reject_reason = IBT_CM_NO_CHAN;
63490Sstevel@tonic-gate } else if (cb_status == IBT_CM_NO_RESOURCE) {
63500Sstevel@tonic-gate *reject_reason = IBT_CM_NO_RESC;
63510Sstevel@tonic-gate } else {
63520Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_req_cm_hdlr: statep %p"
63530Sstevel@tonic-gate " Client handler unexpected return %x", statep, cb_status);
63540Sstevel@tonic-gate *reject_reason = IBT_CM_CONSUMER;
63550Sstevel@tonic-gate }
63560Sstevel@tonic-gate
63570Sstevel@tonic-gate /* client handler gave CM ok */
63580Sstevel@tonic-gate if (cb_status == IBT_CM_ACCEPT) {
63590Sstevel@tonic-gate ibcm_rep_msg_t *rep_msgp = (ibcm_rep_msg_t *)
63604703Shiremath IBCM_OUT_MSGP(statep->stored_msg);
63610Sstevel@tonic-gate
63620Sstevel@tonic-gate
63630Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
63640Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rep_msgp))
63650Sstevel@tonic-gate
63660Sstevel@tonic-gate /*
63670Sstevel@tonic-gate * Check first if ret_args make sense. If not, bailout
63680Sstevel@tonic-gate * here rather than going along and panicing later.
63690Sstevel@tonic-gate */
63700Sstevel@tonic-gate channel = clnt_info->reply_event->rep.cm_channel;
63710Sstevel@tonic-gate if (IBCM_INVALID_CHANNEL(channel)) {
63720Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_req_cm_hdlr: "
63730Sstevel@tonic-gate "statep 0x%p server's QP handle is NULL", statep);
63740Sstevel@tonic-gate *reject_reason = IBT_CM_NO_CHAN;
63750Sstevel@tonic-gate }
63760Sstevel@tonic-gate
63770Sstevel@tonic-gate IBCM_GET_CHAN_PRIVATE(channel, old_statep);
63780Sstevel@tonic-gate
63790Sstevel@tonic-gate if ((*reject_reason == IBT_CM_SUCCESS) &&
63800Sstevel@tonic-gate (old_statep != NULL)) {
63810Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_req_cm_hdlr: "
63820Sstevel@tonic-gate "statep 0x%p Channel being re-used on passive side",
63830Sstevel@tonic-gate statep);
63840Sstevel@tonic-gate *reject_reason = IBT_CM_NO_CHAN;
63850Sstevel@tonic-gate }
63860Sstevel@tonic-gate if (old_statep != NULL)
63870Sstevel@tonic-gate IBCM_RELEASE_CHAN_PRIVATE(channel);
63880Sstevel@tonic-gate
63890Sstevel@tonic-gate if (*reject_reason != IBT_CM_SUCCESS) {
63900Sstevel@tonic-gate ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
63910Sstevel@tonic-gate IBT_CM_FAILURE_REQ, *reject_reason, NULL, 0);
63920Sstevel@tonic-gate return (IBCM_SEND_REJ);
63930Sstevel@tonic-gate }
63940Sstevel@tonic-gate
63950Sstevel@tonic-gate statep->channel = channel;
63960Sstevel@tonic-gate status = ibt_query_qp(channel, &qp_attrs);
63970Sstevel@tonic-gate
63980Sstevel@tonic-gate if (status != IBT_SUCCESS) {
63990Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_process_cep_req_cm_hdlr: "
64000Sstevel@tonic-gate "statep %p ibt_query_qp failed %d", statep, status);
64010Sstevel@tonic-gate *reject_reason = IBT_CM_NO_RESC;
64020Sstevel@tonic-gate ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
64030Sstevel@tonic-gate IBT_CM_FAILURE_REQ, IBT_CM_CI_FAILURE, NULL, 0);
64040Sstevel@tonic-gate return (IBCM_SEND_REJ);
64050Sstevel@tonic-gate }
64060Sstevel@tonic-gate
64070Sstevel@tonic-gate if (qp_attrs.qp_info.qp_trans != IBT_RC_SRV) {
64080Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_req_cm_hdlr: "
64090Sstevel@tonic-gate "statep %p qp is not RC channel on server", statep);
64100Sstevel@tonic-gate *reject_reason = IBT_CM_INVALID_SRV_TYPE;
64110Sstevel@tonic-gate ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
64120Sstevel@tonic-gate IBT_CM_FAILURE_REQ, IBT_CM_CHAN_INVALID_STATE,
64130Sstevel@tonic-gate NULL, 0);
64140Sstevel@tonic-gate return (IBCM_SEND_REJ);
64150Sstevel@tonic-gate }
64160Sstevel@tonic-gate
64179913SShantkumar.Hiremath@Sun.COM if (qp_attrs.qp_info.qp_state != IBT_STATE_INIT &&
641811369SPramod.Gunjikar@Sun.COM statep->is_this_ofuv_chan == B_FALSE) {
64190Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_process_cep_req_cm_hdlr: "
64200Sstevel@tonic-gate "qp state != INIT on server");
64210Sstevel@tonic-gate *reject_reason = IBT_CM_CHAN_INVALID_STATE;
64220Sstevel@tonic-gate ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
64230Sstevel@tonic-gate IBT_CM_FAILURE_REQ, IBT_CM_CHAN_INVALID_STATE,
64240Sstevel@tonic-gate NULL, 0);
64250Sstevel@tonic-gate return (IBCM_SEND_REJ);
642611369SPramod.Gunjikar@Sun.COM } else if (statep->is_this_ofuv_chan &&
642711369SPramod.Gunjikar@Sun.COM qp_attrs.qp_info.qp_state != IBT_STATE_RTR &&
642811369SPramod.Gunjikar@Sun.COM qp_attrs.qp_info.qp_state != IBT_STATE_INIT) {
64299913SShantkumar.Hiremath@Sun.COM IBTF_DPRINTF_L3(cmlog, "ibcm_process_cep_req_cm_hdlr: "
643011369SPramod.Gunjikar@Sun.COM "qp state != INIT or RTR on server");
64319913SShantkumar.Hiremath@Sun.COM *reject_reason = IBT_CM_CHAN_INVALID_STATE;
64329913SShantkumar.Hiremath@Sun.COM ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
64339913SShantkumar.Hiremath@Sun.COM IBT_CM_FAILURE_REQ, IBT_CM_CHAN_INVALID_STATE,
64349913SShantkumar.Hiremath@Sun.COM NULL, 0);
64359913SShantkumar.Hiremath@Sun.COM return (IBCM_SEND_REJ);
64360Sstevel@tonic-gate }
64370Sstevel@tonic-gate
643811369SPramod.Gunjikar@Sun.COM if (statep->is_this_ofuv_chan &&
643911369SPramod.Gunjikar@Sun.COM qp_attrs.qp_info.qp_state == IBT_STATE_RTR &&
64409913SShantkumar.Hiremath@Sun.COM qp_attrs.qp_info.qp_transport.rc.rc_path.cep_hca_port_num !=
64419913SShantkumar.Hiremath@Sun.COM statep->prim_port) {
64429913SShantkumar.Hiremath@Sun.COM IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_req_cm_hdlr: "
64439913SShantkumar.Hiremath@Sun.COM "QP port invalid");
64449913SShantkumar.Hiremath@Sun.COM *reject_reason = IBT_CM_CHAN_INVALID_STATE;
64459913SShantkumar.Hiremath@Sun.COM ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
64469913SShantkumar.Hiremath@Sun.COM IBT_CM_FAILURE_REQ, IBT_CM_CHAN_INVALID_STATE,
64479913SShantkumar.Hiremath@Sun.COM NULL, 0);
64489913SShantkumar.Hiremath@Sun.COM return (IBCM_SEND_REJ);
644911369SPramod.Gunjikar@Sun.COM } else if (statep->is_this_ofuv_chan &&
645011369SPramod.Gunjikar@Sun.COM qp_attrs.qp_info.qp_state == IBT_STATE_RTR) {
64519913SShantkumar.Hiremath@Sun.COM goto skip_init_trans;
645211369SPramod.Gunjikar@Sun.COM }
64539913SShantkumar.Hiremath@Sun.COM
64540Sstevel@tonic-gate /* Init to Init, if required */
64550Sstevel@tonic-gate if (qp_attrs.qp_info.qp_transport.rc.rc_path.cep_hca_port_num !=
64560Sstevel@tonic-gate statep->prim_port) {
64570Sstevel@tonic-gate
64580Sstevel@tonic-gate ibt_qp_info_t qp_info;
64590Sstevel@tonic-gate ibt_cep_modify_flags_t cep_flags;
64600Sstevel@tonic-gate
64610Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_process_cep_req_cm_hdlr: "
64620Sstevel@tonic-gate "chan 0x%p chan port %d", channel,
64630Sstevel@tonic-gate qp_attrs.qp_info.qp_transport.rc.rc_path.\
64640Sstevel@tonic-gate cep_hca_port_num);
64650Sstevel@tonic-gate
64660Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_process_cep_req_cm_hdlr: "
64670Sstevel@tonic-gate "chan 0x%p d path port %d", channel,
64680Sstevel@tonic-gate statep->prim_port);
64690Sstevel@tonic-gate
64700Sstevel@tonic-gate bzero(&qp_info, sizeof (qp_info));
64710Sstevel@tonic-gate qp_info.qp_trans = IBT_RC_SRV;
64720Sstevel@tonic-gate qp_info.qp_state = IBT_STATE_INIT;
64730Sstevel@tonic-gate qp_info.qp_transport.rc.rc_path.cep_hca_port_num =
64740Sstevel@tonic-gate statep->prim_port;
64750Sstevel@tonic-gate
64760Sstevel@tonic-gate cep_flags = IBT_CEP_SET_STATE | IBT_CEP_SET_PORT;
64770Sstevel@tonic-gate
64780Sstevel@tonic-gate status = ibt_modify_qp(statep->channel, cep_flags,
64790Sstevel@tonic-gate &qp_info, NULL);
64800Sstevel@tonic-gate
64810Sstevel@tonic-gate if (status != IBT_SUCCESS) {
64820Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog,
64830Sstevel@tonic-gate "ibcm_process_cep_req_cm_hdlr: "
64840Sstevel@tonic-gate "chan 0x%p ibt_modify_qp() = %d", channel,
64850Sstevel@tonic-gate status);
64860Sstevel@tonic-gate *reject_reason = IBT_CM_NO_RESC;
64870Sstevel@tonic-gate
64880Sstevel@tonic-gate ibcm_insert_trace(statep,
64890Sstevel@tonic-gate IBCM_TRACE_INIT_INIT_FAIL);
64900Sstevel@tonic-gate
64910Sstevel@tonic-gate ibcm_handler_conn_fail(statep,
64920Sstevel@tonic-gate IBT_CM_FAILURE_REJ_SENT, IBT_CM_FAILURE_REQ,
64930Sstevel@tonic-gate IBT_CM_CI_FAILURE, NULL, 0);
64940Sstevel@tonic-gate return (IBCM_SEND_REJ);
64950Sstevel@tonic-gate } else {
64960Sstevel@tonic-gate ibcm_insert_trace(statep,
64970Sstevel@tonic-gate IBCM_TRACE_INIT_INIT);
64980Sstevel@tonic-gate
64990Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog,
65000Sstevel@tonic-gate "ibcm_process_cep_req_cm_hdlr: "
65010Sstevel@tonic-gate "chan 0x%p ibt_modify_qp() = %d", channel,
65020Sstevel@tonic-gate status);
65030Sstevel@tonic-gate }
65040Sstevel@tonic-gate }
65059913SShantkumar.Hiremath@Sun.COM skip_init_trans:
65069913SShantkumar.Hiremath@Sun.COM /* Do sanity tests even if we are skipping RTR */
65070Sstevel@tonic-gate
65080Sstevel@tonic-gate /* fill in the REP msg based on ret_args from client */
65096709Shiremath if (clnt_info->reply_event->rep.cm_rdma_ra_out >
65107919SBill.Taylor@Sun.COM ((uint8_t *)&cm_req_msg->req_local_qpn_plus)[3]) {
65116709Shiremath IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_cm_hdlr "
65126709Shiremath "statep 0x%p ERROR: InitiatorDepth(%d) is Greater "
65136709Shiremath "than ResponderResource(%d)", statep,
65146709Shiremath clnt_info->reply_event->rep.cm_rdma_ra_out,
65157919SBill.Taylor@Sun.COM ((uint8_t *)&cm_req_msg->req_local_qpn_plus)[3]);
65166709Shiremath *reject_reason = IBT_CM_NOT_SUPPORTED;
65176709Shiremath ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
65186709Shiremath IBT_CM_FAILURE_REQ, IBT_CM_NOT_SUPPORTED, NULL, 0);
65196709Shiremath return (IBCM_SEND_REJ);
65206709Shiremath }
65216709Shiremath
65226709Shiremath /* Check for HCA limits for RDMA Resources */
65236709Shiremath if (clnt_info->reply_event->rep.cm_rdma_ra_in >
65246709Shiremath statep->hcap->hca_max_rdma_in_qp) {
65256709Shiremath IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_cm_hdlr: "
65266709Shiremath "statep %p, ERROR: client specified rdma_ra_in %d "
65276709Shiremath "is greater than HCA Limit %d, rejecting MAD",
65286709Shiremath statep, clnt_info->reply_event->rep.cm_rdma_ra_in,
65296709Shiremath statep->hcap->hca_max_rdma_in_qp);
65306709Shiremath *reject_reason = IBT_CM_NOT_SUPPORTED;
65316709Shiremath ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
65326709Shiremath IBT_CM_FAILURE_REQ, IBT_CM_NOT_SUPPORTED, NULL, 0);
65336709Shiremath return (IBCM_SEND_REJ);
65346709Shiremath }
65356709Shiremath
65366709Shiremath if (clnt_info->reply_event->rep.cm_rdma_ra_out >
65376709Shiremath statep->hcap->hca_max_rdma_out_qp) {
65386709Shiremath IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_cm_hdlr: "
65396709Shiremath "statep %p, ERROR: client specified rdma_ra_out %d "
65406709Shiremath "is greater than HCA Limit %d, rejecting MAD",
65416709Shiremath statep, clnt_info->reply_event->rep.cm_rdma_ra_out,
65426709Shiremath statep->hcap->hca_max_rdma_out_qp);
65436709Shiremath *reject_reason = IBT_CM_NOT_SUPPORTED;
65446709Shiremath ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
65456709Shiremath IBT_CM_FAILURE_REQ, IBT_CM_NOT_SUPPORTED, NULL, 0);
65466709Shiremath return (IBCM_SEND_REJ);
65476709Shiremath }
65486709Shiremath
65490Sstevel@tonic-gate rep_msgp->rep_resp_resources =
65500Sstevel@tonic-gate clnt_info->reply_event->rep.cm_rdma_ra_in;
65510Sstevel@tonic-gate rep_msgp->rep_initiator_depth =
65520Sstevel@tonic-gate clnt_info->reply_event->rep.cm_rdma_ra_out;
65530Sstevel@tonic-gate
65540Sstevel@tonic-gate /* IBT_CM_FLOW_CONTROL is always set by default. */
65550Sstevel@tonic-gate rep_msgp->rep_target_delay_plus |= IBT_CM_FLOW_CONTROL;
65560Sstevel@tonic-gate
65570Sstevel@tonic-gate rep_msgp->rep_rnr_retry_cnt_plus =
65580Sstevel@tonic-gate (clnt_info->reply_event->rep.cm_rnr_retry_cnt & 0x7) << 5;
65590Sstevel@tonic-gate
65600Sstevel@tonic-gate /*
65610Sstevel@tonic-gate * Check out whether SRQ is associated with this channel.
65620Sstevel@tonic-gate * If yes, then set the appropriate bit.
65630Sstevel@tonic-gate */
65640Sstevel@tonic-gate if (qp_attrs.qp_srq != NULL) {
65650Sstevel@tonic-gate rep_msgp->rep_rnr_retry_cnt_plus |= (1 << 4);
65660Sstevel@tonic-gate }
65670Sstevel@tonic-gate
65680Sstevel@tonic-gate local_ca_guid = h2b64(statep->local_hca_guid);
65690Sstevel@tonic-gate bcopy(&local_ca_guid, rep_msgp->rep_local_ca_guid,
65700Sstevel@tonic-gate sizeof (ib_guid_t));
65710Sstevel@tonic-gate
657211369SPramod.Gunjikar@Sun.COM if (statep->is_this_ofuv_chan &&
657311369SPramod.Gunjikar@Sun.COM qp_attrs.qp_info.qp_state == IBT_STATE_RTR)
65749913SShantkumar.Hiremath@Sun.COM goto skip_rtr_trans;
65759913SShantkumar.Hiremath@Sun.COM
65760Sstevel@tonic-gate /* Transition QP from Init to RTR state */
65770Sstevel@tonic-gate if (ibcm_invoke_qp_modify(statep, cm_req_msg, rep_msgp) !=
65780Sstevel@tonic-gate IBT_SUCCESS) {
65790Sstevel@tonic-gate
65800Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_cm_hdlr "
65810Sstevel@tonic-gate "statep 0x%p ibcm_invoke_qp_modify failed because "
65820Sstevel@tonic-gate "of invalid data", statep);
65830Sstevel@tonic-gate *reject_reason = IBT_CM_NO_RESC;
65840Sstevel@tonic-gate ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
65850Sstevel@tonic-gate IBT_CM_FAILURE_REQ, IBT_CM_CI_FAILURE, NULL, 0);
65860Sstevel@tonic-gate return (IBCM_SEND_REJ);
65870Sstevel@tonic-gate }
65889913SShantkumar.Hiremath@Sun.COM skip_rtr_trans:
65890Sstevel@tonic-gate
65900Sstevel@tonic-gate /*
65910Sstevel@tonic-gate * Link statep and channel, once CM determines it is
65920Sstevel@tonic-gate * post REP definitely.
65930Sstevel@tonic-gate */
65940Sstevel@tonic-gate IBCM_SET_CHAN_PRIVATE(statep->channel, statep);
65950Sstevel@tonic-gate
65960Sstevel@tonic-gate /*
65970Sstevel@tonic-gate * Fill up the REP fields from ret_args
65980Sstevel@tonic-gate * failover status, from ret_args
65990Sstevel@tonic-gate *
66000Sstevel@tonic-gate * Fill up local QPN and EECN from ret_args->channel
66010Sstevel@tonic-gate */
66020Sstevel@tonic-gate
66030Sstevel@tonic-gate /* fill in REP msg bytes Qkey, Starting PSN, 12-15, and 16-19 */
66040Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_cep_req_cm_hdlr: "
66050Sstevel@tonic-gate "qp_info.qp_state = %x", qp_attrs.qp_info.qp_state);
66060Sstevel@tonic-gate
66070Sstevel@tonic-gate rep_msgp->rep_local_qpn_plus = h2b32(qp_attrs.qp_qpn << 8);
66080Sstevel@tonic-gate
66090Sstevel@tonic-gate statep->local_qpn = qp_attrs.qp_qpn;
66100Sstevel@tonic-gate
66110Sstevel@tonic-gate switch (qp_attrs.qp_info.qp_trans) {
66120Sstevel@tonic-gate case IBT_RD_SRV:
66130Sstevel@tonic-gate rep_msgp->rep_local_qkey = h2b32(
66140Sstevel@tonic-gate qp_attrs.qp_info.qp_transport.rd.rd_qkey);
66150Sstevel@tonic-gate break;
66160Sstevel@tonic-gate case IBT_RC_SRV:
66170Sstevel@tonic-gate rep_msgp->rep_starting_psn_plus =
661811369SPramod.Gunjikar@Sun.COM h2b32(IBCM_QP_RC(qp_attrs).rc_rq_psn << 8);
66190Sstevel@tonic-gate break;
66200Sstevel@tonic-gate case IBT_UC_SRV:
66210Sstevel@tonic-gate rep_msgp->rep_starting_psn_plus =
66220Sstevel@tonic-gate h2b32(IBCM_QP_UC(qp_attrs).uc_sq_psn << 8);
66230Sstevel@tonic-gate break;
66240Sstevel@tonic-gate }
66250Sstevel@tonic-gate
66260Sstevel@tonic-gate #ifdef NO_EEC_SUPPORT_YET
66270Sstevel@tonic-gate if (ret_args.cm_channel.ch_eec != NULL) {
66280Sstevel@tonic-gate status = ibt_query_eec(ret_args.cm_channel.ch_eec,
66290Sstevel@tonic-gate &eec_attrs);
66300Sstevel@tonic-gate if (status == IBT_SUCCESS) {
66310Sstevel@tonic-gate rep_msgp->rep_local_eecn_plus =
66320Sstevel@tonic-gate h2b32(((uint32_t)eec_attrs.eec_eecn << 8));
66330Sstevel@tonic-gate }
66340Sstevel@tonic-gate }
66350Sstevel@tonic-gate #endif
66360Sstevel@tonic-gate
66370Sstevel@tonic-gate /* figure out Target ACK delay */
66380Sstevel@tonic-gate rep_msgp->rep_target_delay_plus |= (status == IBT_SUCCESS) ?
66390Sstevel@tonic-gate statep->hcap->hca_ack_delay << 3 : 0;
66400Sstevel@tonic-gate
66410Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_cep_req_cm_hdlr:statep %p "
66420Sstevel@tonic-gate "REP priv len %x", statep, clnt_info->priv_data_len);
66430Sstevel@tonic-gate /* Copy PrivateData from priv_data */
66440Sstevel@tonic-gate if (clnt_info->priv_data_len != 0) {
66450Sstevel@tonic-gate bcopy(clnt_info->priv_data, rep_msgp->rep_private_data,
66460Sstevel@tonic-gate min(IBT_REP_PRIV_DATA_SZ,
66470Sstevel@tonic-gate clnt_info->priv_data_len));
66480Sstevel@tonic-gate }
66490Sstevel@tonic-gate
66500Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*statep))
66510Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rep_msgp))
66520Sstevel@tonic-gate
66530Sstevel@tonic-gate return (IBCM_SEND_REP);
66540Sstevel@tonic-gate }
66550Sstevel@tonic-gate
66560Sstevel@tonic-gate /* REJ message */
66570Sstevel@tonic-gate rej_msgp = (ibcm_rej_msg_t *)IBCM_OUT_MSGP(statep->stored_msg);
66580Sstevel@tonic-gate
66590Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_cep_req_cm_hdlr: statep %p REJ "
66600Sstevel@tonic-gate "priv len %x", statep, clnt_info->priv_data_len);
66610Sstevel@tonic-gate
66620Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rej_msgp))
66630Sstevel@tonic-gate
66640Sstevel@tonic-gate /* if priv_data_len != 0 use priv_data to copy back to rej_priv_data */
66650Sstevel@tonic-gate if (clnt_info->priv_data_len != 0) {
66660Sstevel@tonic-gate bcopy(clnt_info->priv_data, rej_msgp->rej_private_data,
66670Sstevel@tonic-gate min(IBT_REJ_PRIV_DATA_SZ, clnt_info->priv_data_len));
66680Sstevel@tonic-gate }
66690Sstevel@tonic-gate
66700Sstevel@tonic-gate if (cb_status == IBT_CM_REDIRECT_PORT) {
66710Sstevel@tonic-gate ib_gid_t tgid;
66720Sstevel@tonic-gate
66730Sstevel@tonic-gate tgid.gid_guid =
66740Sstevel@tonic-gate h2b64(clnt_info->reply_event->rej.ari_gid.gid_guid);
66750Sstevel@tonic-gate tgid.gid_prefix =
66760Sstevel@tonic-gate h2b64(clnt_info->reply_event->rej.ari_gid.gid_prefix);
66770Sstevel@tonic-gate
66780Sstevel@tonic-gate *arej_len = sizeof (ib_gid_t);
66790Sstevel@tonic-gate bcopy(&tgid, &rej_msgp->rej_addl_rej_info, sizeof (ib_gid_t));
66800Sstevel@tonic-gate
6681401Shiremath IBTF_DPRINTF_L3(cmlog, "ibcm_process_cep_req_cm_hdlr: ari_gid= "
6682401Shiremath "%llX:%llX", tgid.gid_prefix, tgid.gid_guid);
6683401Shiremath
66840Sstevel@tonic-gate } else if (cb_status == IBT_CM_REDIRECT) {
66850Sstevel@tonic-gate ibcm_classportinfo_msg_t tclp;
66860Sstevel@tonic-gate
66870Sstevel@tonic-gate ibcm_init_clp_to_mad(&tclp,
66880Sstevel@tonic-gate &clnt_info->reply_event->rej.ari_redirect);
66890Sstevel@tonic-gate bcopy(&tclp, rej_msgp->rej_addl_rej_info, sizeof (tclp));
66900Sstevel@tonic-gate
66910Sstevel@tonic-gate *arej_len = sizeof (ibcm_classportinfo_msg_t);
66920Sstevel@tonic-gate
66930Sstevel@tonic-gate } else if (cb_status == IBT_CM_REJECT) {
66940Sstevel@tonic-gate
66950Sstevel@tonic-gate /* Fill up the REJ fields, from ret_args */
66960Sstevel@tonic-gate *arej_len = min(
66970Sstevel@tonic-gate clnt_info->reply_event->rej.ari_consumer.rej_ari_len,
66980Sstevel@tonic-gate IBT_CM_ADDL_REJ_LEN);
66990Sstevel@tonic-gate bcopy(clnt_info->reply_event->rej.ari_consumer.rej_ari,
67000Sstevel@tonic-gate &rej_msgp->rej_addl_rej_info, *arej_len);
67014703Shiremath
67024703Shiremath /*
67034703Shiremath * RDMA IP REQ was passed up to the ULP, the ULP decided to do
67044703Shiremath * a "normal" consumer REJ, by the returning IBT_CM_REJECT in
67054703Shiremath * the cm handler.
67064703Shiremath * CM has to do some extra stuff too, it has to
67074703Shiremath * a) return REJ code 28 (consumer) and b) put 0x1 in the first
67084703Shiremath * byte of the ARI data, to indicate that this is a RDMA aware
67094703Shiremath * ULP that is doing a consumer reject. The ULP should have
67104703Shiremath * put its consumer specific data into ibt_arej_info_t(9s) at
67114703Shiremath * byte 1 of the rej_ari[] array.
67124703Shiremath */
67134703Shiremath if (((statep->svcid & IB_SID_IPADDR_PREFIX_MASK) == 0) &&
67144703Shiremath (statep->svcid & IB_SID_IPADDR_PREFIX)) {
67154703Shiremath rej_msgp->rej_addl_rej_info[0] = 1;
67164703Shiremath }
67170Sstevel@tonic-gate }
67180Sstevel@tonic-gate
67190Sstevel@tonic-gate rej_msgp->rej_msg_type_plus = IBT_CM_FAILURE_REQ << 6;
67200Sstevel@tonic-gate
67210Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rej_msgp))
67220Sstevel@tonic-gate
67230Sstevel@tonic-gate return (IBCM_SEND_REJ);
67240Sstevel@tonic-gate }
67250Sstevel@tonic-gate
67260Sstevel@tonic-gate /*
67270Sstevel@tonic-gate * ibcm_cep_state_rep:
67280Sstevel@tonic-gate * QP state transition function called for an incoming REP on active side
67290Sstevel@tonic-gate *
67300Sstevel@tonic-gate * INPUTS:
67310Sstevel@tonic-gate * statep - state pointer
67320Sstevel@tonic-gate * cm_rep_msg - REP message pointer
67330Sstevel@tonic-gate * reject_reason - Rejection reason See Section 12.6.7.2 rev1.0a IB Spec
67340Sstevel@tonic-gate *
67350Sstevel@tonic-gate * RETURN VALUE:
67360Sstevel@tonic-gate */
67370Sstevel@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)67380Sstevel@tonic-gate ibcm_cep_state_rep(ibcm_state_data_t *statep, ibcm_rep_msg_t *cm_rep_msgp,
67390Sstevel@tonic-gate ibt_cm_reason_t *reject_reason, uint8_t *arej_len)
67400Sstevel@tonic-gate {
67410Sstevel@tonic-gate void *priv_data = NULL;
67420Sstevel@tonic-gate ibcm_status_t rval = IBCM_SEND_RTU;
67430Sstevel@tonic-gate ibt_cm_event_t event;
67440Sstevel@tonic-gate ibt_cm_status_t cb_status = IBT_CM_ACCEPT;
67450Sstevel@tonic-gate ibt_cm_return_args_t ret_args;
67460Sstevel@tonic-gate ibcm_clnt_reply_info_t clnt_info;
67476709Shiremath uint8_t req_init_depth;
67480Sstevel@tonic-gate
67490Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_cep_state_rep: statep 0x%p", statep);
67500Sstevel@tonic-gate
67510Sstevel@tonic-gate /* Check first if client handler is valid */
67520Sstevel@tonic-gate if (statep->cm_handler != NULL) {
67530Sstevel@tonic-gate /* initialize fields in ibt_cm_event_t */
67540Sstevel@tonic-gate bzero(&event, sizeof (event));
67550Sstevel@tonic-gate event.cm_type = IBT_CM_EVENT_REP_RCV;
67560Sstevel@tonic-gate event.cm_channel = statep->channel;
67570Sstevel@tonic-gate event.cm_session_id = statep;
67580Sstevel@tonic-gate
67590Sstevel@tonic-gate IBCM_EVT_REP(event).rep_rdma_ra_in =
67606709Shiremath cm_rep_msgp->rep_initiator_depth;
67616709Shiremath req_init_depth =
67626709Shiremath ((uint8_t *)&(((ibcm_req_msg_t *)IBCM_OUT_MSGP(
67636709Shiremath statep->stored_msg))->req_local_eec_no_plus))[3];
67640Sstevel@tonic-gate IBCM_EVT_REP(event).rep_rdma_ra_out =
67656709Shiremath min(cm_rep_msgp->rep_resp_resources, req_init_depth);
67666709Shiremath
67676709Shiremath IBTF_DPRINTF_L3(cmlog, "ibcm_cep_state_rep: statep 0x%p, "
67686709Shiremath "InitDepth %d, RespResr %d", statep,
67696709Shiremath cm_rep_msgp->rep_initiator_depth,
67706709Shiremath IBCM_EVT_REP(event).rep_rdma_ra_out);
67716709Shiremath
67720Sstevel@tonic-gate IBCM_EVT_REP(event).rep_service_time = ibt_ib2usec(
67730Sstevel@tonic-gate ((uint8_t *)&(((ibcm_req_msg_t *)IBCM_OUT_MSGP(
67740Sstevel@tonic-gate statep->stored_msg))->req_starting_psn_plus))[3] >> 3);
67750Sstevel@tonic-gate
67760Sstevel@tonic-gate IBCM_EVT_REP(event).rep_service_time -=
67770Sstevel@tonic-gate 2 * statep->pkt_life_time - ibcm_sw_delay;
67780Sstevel@tonic-gate
67790Sstevel@tonic-gate IBCM_EVT_REP(event).rep_failover_status =
67804703Shiremath cm_rep_msgp->rep_target_delay_plus >> 1 & 3;
67810Sstevel@tonic-gate
67820Sstevel@tonic-gate if (cm_rep_msgp->rep_target_delay_plus & 0x1)
67830Sstevel@tonic-gate IBCM_EVT_REP(event).rep_flags |= IBT_CM_FLOW_CONTROL;
67840Sstevel@tonic-gate
67850Sstevel@tonic-gate if ((cm_rep_msgp->rep_rnr_retry_cnt_plus >> 4) & 0x1)
67860Sstevel@tonic-gate IBCM_EVT_REP(event).rep_flags |= IBT_CM_SRQ_EXISTS;
67870Sstevel@tonic-gate
6788557Shiremath IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_rep: statep 0x%p "
67890Sstevel@tonic-gate "rep_service_time %d", statep,
67900Sstevel@tonic-gate IBCM_EVT_REP(event).rep_service_time);
67910Sstevel@tonic-gate
67920Sstevel@tonic-gate event.cm_priv_data = &(cm_rep_msgp->rep_private_data[0]);
67930Sstevel@tonic-gate event.cm_priv_data_len = IBT_REP_PRIV_DATA_SZ;
67940Sstevel@tonic-gate
67950Sstevel@tonic-gate /*
67960Sstevel@tonic-gate * Allocate priv_data of size IBT_MAX_PRIV_DATA_SZ
67970Sstevel@tonic-gate */
67980Sstevel@tonic-gate priv_data = kmem_zalloc(IBT_MAX_PRIV_DATA_SZ, KM_SLEEP);
67990Sstevel@tonic-gate bzero(&ret_args, sizeof (ret_args));
68000Sstevel@tonic-gate
68010Sstevel@tonic-gate
68020Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_CALLED_REP_RCVD_EVENT);
68030Sstevel@tonic-gate
68040Sstevel@tonic-gate /* invoke the CM handler */
68050Sstevel@tonic-gate cb_status = statep->cm_handler(statep->state_cm_private, &event,
68060Sstevel@tonic-gate &ret_args, priv_data, IBT_RTU_PRIV_DATA_SZ);
68070Sstevel@tonic-gate
68080Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_RET_REP_RCVD_EVENT);
68090Sstevel@tonic-gate
6810557Shiremath IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_rep: statep 0x%p "
68110Sstevel@tonic-gate "Client handler returned %x", statep, cb_status);
68120Sstevel@tonic-gate
68130Sstevel@tonic-gate if (cb_status == IBT_CM_DEFER) {
68140Sstevel@tonic-gate if (statep->defer_cm_msg == NULL)
68150Sstevel@tonic-gate statep->defer_cm_msg =
68160Sstevel@tonic-gate kmem_zalloc(IBCM_MSG_SIZE, KM_SLEEP);
68170Sstevel@tonic-gate bcopy(cm_rep_msgp, statep->defer_cm_msg, IBCM_MSG_SIZE);
68180Sstevel@tonic-gate
68190Sstevel@tonic-gate /* unblock any blocked cm proceed api calls */
68200Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
68210Sstevel@tonic-gate statep->clnt_proceed = IBCM_UNBLOCK;
68220Sstevel@tonic-gate cv_broadcast(&statep->block_client_cv);
68230Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
68240Sstevel@tonic-gate
68250Sstevel@tonic-gate kmem_free(priv_data, IBT_MAX_PRIV_DATA_SZ);
68260Sstevel@tonic-gate return (IBCM_DEFER);
68270Sstevel@tonic-gate }
68280Sstevel@tonic-gate }
68290Sstevel@tonic-gate
68300Sstevel@tonic-gate /* fail any blocked cm proceed api calls - client bug */
68310Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
68320Sstevel@tonic-gate statep->clnt_proceed = IBCM_FAIL;
68330Sstevel@tonic-gate cv_broadcast(&statep->block_client_cv);
68340Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
68350Sstevel@tonic-gate
68360Sstevel@tonic-gate clnt_info.reply_event = (ibt_cm_proceed_reply_t *)&ret_args.cm_ret;
68370Sstevel@tonic-gate clnt_info.priv_data = priv_data;
68380Sstevel@tonic-gate clnt_info.priv_data_len = ret_args.cm_ret_len;
68390Sstevel@tonic-gate
68400Sstevel@tonic-gate rval =
68410Sstevel@tonic-gate ibcm_process_cep_rep_cm_hdlr(statep, cb_status, &clnt_info,
68420Sstevel@tonic-gate reject_reason, arej_len, cm_rep_msgp);
68430Sstevel@tonic-gate
68440Sstevel@tonic-gate if (priv_data != NULL)
68450Sstevel@tonic-gate kmem_free(priv_data, IBT_MAX_PRIV_DATA_SZ);
68460Sstevel@tonic-gate return (rval);
68470Sstevel@tonic-gate }
68480Sstevel@tonic-gate
68490Sstevel@tonic-gate
68500Sstevel@tonic-gate /*
68510Sstevel@tonic-gate * ibcm_process_cep_rep_cm_hdlr:
68520Sstevel@tonic-gate * Processes the response from client handler for an incoming REP.
68530Sstevel@tonic-gate */
68540Sstevel@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)68550Sstevel@tonic-gate ibcm_process_cep_rep_cm_hdlr(ibcm_state_data_t *statep,
68560Sstevel@tonic-gate ibt_cm_status_t cb_status, ibcm_clnt_reply_info_t *clnt_info,
68570Sstevel@tonic-gate ibt_cm_reason_t *reject_reason, uint8_t *arej_len,
68580Sstevel@tonic-gate ibcm_rep_msg_t *cm_rep_msgp)
68590Sstevel@tonic-gate {
68600Sstevel@tonic-gate ibcm_status_t rval = IBCM_SEND_RTU;
68610Sstevel@tonic-gate ibcm_rej_msg_t *rej_msgp;
68620Sstevel@tonic-gate
68630Sstevel@tonic-gate if (cb_status == IBT_CM_DEFAULT)
68640Sstevel@tonic-gate cb_status = IBT_CM_ACCEPT;
68650Sstevel@tonic-gate
68660Sstevel@tonic-gate if (cb_status == IBT_CM_REJECT) {
68670Sstevel@tonic-gate *reject_reason = IBT_CM_CONSUMER;
68680Sstevel@tonic-gate } else if (cb_status == IBT_CM_REDIRECT_PORT) {
68690Sstevel@tonic-gate *reject_reason = IBT_CM_PORT_REDIRECT;
68700Sstevel@tonic-gate } else if (cb_status == IBT_CM_REDIRECT) {
68710Sstevel@tonic-gate *reject_reason = IBT_CM_REDIRECT_CM;
68720Sstevel@tonic-gate } else if (cb_status == IBT_CM_NO_RESOURCE) {
68730Sstevel@tonic-gate *reject_reason = IBT_CM_NO_RESC;
68740Sstevel@tonic-gate } else if (cb_status != IBT_CM_ACCEPT) {
6875557Shiremath IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_rep_cm_hdlr: statep "
6876557Shiremath "0x%p, Client handler returned unexpected value %d",
68770Sstevel@tonic-gate statep, cb_status);
68780Sstevel@tonic-gate *reject_reason = IBT_CM_CONSUMER;
68790Sstevel@tonic-gate } else
68800Sstevel@tonic-gate *reject_reason = IBT_CM_SUCCESS;
68810Sstevel@tonic-gate
68820Sstevel@tonic-gate
68830Sstevel@tonic-gate /* We come here if status is ACCEPT or CM handler is NULL */
68840Sstevel@tonic-gate if (cb_status == IBT_CM_ACCEPT) {
68850Sstevel@tonic-gate ib_time_t time;
68860Sstevel@tonic-gate
68870Sstevel@tonic-gate time = ibt_usec2ib(statep->pkt_life_time * 2 +
68880Sstevel@tonic-gate ibt_ib2usec(cm_rep_msgp->rep_target_delay_plus >> 3));
68890Sstevel@tonic-gate
6890557Shiremath IBTF_DPRINTF_L5(cmlog, "ibcm_process_cep_rep_cm_hdlr: statep %p"
68910Sstevel@tonic-gate " active cep_timeout(usec) 0x%x ", statep, time);
68920Sstevel@tonic-gate
6893557Shiremath IBTF_DPRINTF_L4(cmlog, "ibcm_process_cep_rep_cm_hdlr: statep %p"
68940Sstevel@tonic-gate " passive hca_ack_delay(ib_time) = 0x%x, ", statep,
68950Sstevel@tonic-gate cm_rep_msgp->rep_target_delay_plus >> 3);
68960Sstevel@tonic-gate
6897557Shiremath IBTF_DPRINTF_L5(cmlog, "ibcm_process_cep_rep_cm_hdlr: statep %p"
68980Sstevel@tonic-gate " rnr_retry_cnt = 0x%x", statep,
68990Sstevel@tonic-gate cm_rep_msgp->rep_rnr_retry_cnt_plus >> 5);
69000Sstevel@tonic-gate
69010Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
69020Sstevel@tonic-gate statep->starting_psn =
69030Sstevel@tonic-gate b2h32(cm_rep_msgp->rep_starting_psn_plus) >> 8;
69040Sstevel@tonic-gate
69050Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
69060Sstevel@tonic-gate
69070Sstevel@tonic-gate /* Call IBTL CM's qp modify function from Init to RTR */
69080Sstevel@tonic-gate if (ibcm_invoke_qp_modify(statep,
69090Sstevel@tonic-gate (ibcm_req_msg_t *)IBCM_OUT_MSGP(statep->stored_msg),
69100Sstevel@tonic-gate cm_rep_msgp) != IBT_SUCCESS) {
69110Sstevel@tonic-gate
6912557Shiremath IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_rep_cm_hdlr: "
6913557Shiremath "statep %p, ibcm_invoke_qp_modify to RTR failed",
6914557Shiremath statep);
69150Sstevel@tonic-gate *reject_reason = IBT_CM_NO_RESC;
69160Sstevel@tonic-gate /*
69170Sstevel@tonic-gate * Call modify qp function from RTR to RTS
69180Sstevel@tonic-gate * RDMA initiator depth on active is same as negotiated
69190Sstevel@tonic-gate * passive REP's responder resources
69200Sstevel@tonic-gate */
69210Sstevel@tonic-gate } else if (ibcm_invoke_rtu_qp_modify(statep, time, cm_rep_msgp)
69220Sstevel@tonic-gate != IBT_SUCCESS) {
69230Sstevel@tonic-gate
6924557Shiremath IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_rep_cm_hdlr: "
6925557Shiremath "statep %p ibcm_invoke_rtu_qp_modify to RTS failed",
6926557Shiremath statep);
69270Sstevel@tonic-gate (void) ibcm_cep_to_error_state(statep);
69280Sstevel@tonic-gate *reject_reason = IBT_CM_NO_RESC;
69290Sstevel@tonic-gate }
69300Sstevel@tonic-gate
69310Sstevel@tonic-gate if (*reject_reason == IBT_CM_NO_RESC) {
69320Sstevel@tonic-gate
69330Sstevel@tonic-gate /* Disassociate statep and QP */
69340Sstevel@tonic-gate IBCM_SET_CHAN_PRIVATE(statep->channel, NULL);
69350Sstevel@tonic-gate
69360Sstevel@tonic-gate ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
69370Sstevel@tonic-gate IBT_CM_FAILURE_REP, IBT_CM_CI_FAILURE, NULL, 0);
69380Sstevel@tonic-gate return (IBCM_SEND_REJ); /* send REJ */
69390Sstevel@tonic-gate }
69400Sstevel@tonic-gate
69410Sstevel@tonic-gate if (clnt_info->priv_data_len != 0) {
69420Sstevel@tonic-gate ibcm_rtu_msg_t *rtu_msgp;
69430Sstevel@tonic-gate rtu_msgp = (ibcm_rtu_msg_t *)
69444703Shiremath IBCM_OUT_MSGP(statep->stored_msg);
69450Sstevel@tonic-gate bcopy(clnt_info->priv_data, rtu_msgp->rtu_private_data,
69460Sstevel@tonic-gate min(IBT_RTU_PRIV_DATA_SZ,
69470Sstevel@tonic-gate clnt_info->priv_data_len));
69480Sstevel@tonic-gate }
69490Sstevel@tonic-gate
69500Sstevel@tonic-gate *reject_reason = IBT_CM_SUCCESS;
69510Sstevel@tonic-gate return (rval);
69520Sstevel@tonic-gate }
69530Sstevel@tonic-gate
69540Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rej_msgp))
69550Sstevel@tonic-gate
69560Sstevel@tonic-gate /* Fill up the REJ fields, from ret_args */
69570Sstevel@tonic-gate rej_msgp = (ibcm_rej_msg_t *)IBCM_OUT_MSGP(statep->stored_msg);
69580Sstevel@tonic-gate rej_msgp->rej_msg_type_plus = IBT_CM_FAILURE_REP << 6;
69590Sstevel@tonic-gate
69600Sstevel@tonic-gate /* if priv_len != 0 use priv_data to copy back to rej_priv_data */
69610Sstevel@tonic-gate if (clnt_info->priv_data_len != 0)
69620Sstevel@tonic-gate bcopy(clnt_info->priv_data, rej_msgp->rej_private_data,
69630Sstevel@tonic-gate min(IBT_REJ_PRIV_DATA_SZ, clnt_info->priv_data_len));
69640Sstevel@tonic-gate
69650Sstevel@tonic-gate if (clnt_info->reply_event != NULL)
69660Sstevel@tonic-gate *arej_len =
69670Sstevel@tonic-gate min(clnt_info->reply_event->rej.ari_consumer.rej_ari_len,
69680Sstevel@tonic-gate IBT_CM_ADDL_REJ_LEN);
69690Sstevel@tonic-gate
69700Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(clnt_info->reply_event->rej))
69710Sstevel@tonic-gate
69720Sstevel@tonic-gate if (*arej_len != 0) /* asserts that clnt_info->reply_event != 0 */
69730Sstevel@tonic-gate bcopy(clnt_info->reply_event->rej.ari_consumer.rej_ari,
69740Sstevel@tonic-gate &rej_msgp->rej_addl_rej_info, *arej_len);
69750Sstevel@tonic-gate
69760Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(clnt_info->reply_event->rej))
69770Sstevel@tonic-gate
69780Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rej_msgp))
69790Sstevel@tonic-gate
69800Sstevel@tonic-gate rval = IBCM_SEND_REJ;
69810Sstevel@tonic-gate
69820Sstevel@tonic-gate /* Disassociate statep and QP */
69830Sstevel@tonic-gate IBCM_SET_CHAN_PRIVATE(statep->channel, NULL);
69840Sstevel@tonic-gate
69850Sstevel@tonic-gate /* callback client, to enable client to do resource cleanup */
69860Sstevel@tonic-gate ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
69870Sstevel@tonic-gate IBT_CM_FAILURE_REP, *reject_reason, NULL, 0);
69880Sstevel@tonic-gate
69890Sstevel@tonic-gate return (rval);
69900Sstevel@tonic-gate }
69910Sstevel@tonic-gate
69920Sstevel@tonic-gate /*
69930Sstevel@tonic-gate * ibcm_invoke_rtu_qp_modify:
69940Sstevel@tonic-gate * Helper function to modify QP for RTU only called from
69950Sstevel@tonic-gate * ibcm_cep_state_rtu() and ibcm_cep_send_rtu()
69960Sstevel@tonic-gate *
69970Sstevel@tonic-gate * INPUTS:
69980Sstevel@tonic-gate * statep - connection state pointer
69990Sstevel@tonic-gate *
70000Sstevel@tonic-gate * RETURN VALUE:
70010Sstevel@tonic-gate */
70020Sstevel@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)70030Sstevel@tonic-gate ibcm_invoke_rtu_qp_modify(ibcm_state_data_t *statep, ib_time_t timeout,
70040Sstevel@tonic-gate ibcm_rep_msg_t *rep_msg)
70050Sstevel@tonic-gate {
70060Sstevel@tonic-gate ibt_status_t status;
70070Sstevel@tonic-gate ibt_qp_info_t qp_info;
70080Sstevel@tonic-gate ibt_cep_modify_flags_t cep_flags = IBT_CEP_SET_RTR_RTS;
70090Sstevel@tonic-gate
70100Sstevel@tonic-gate /* Start filling up ibt_qp_info_t. */
70110Sstevel@tonic-gate bzero(&qp_info, sizeof (qp_info));
70120Sstevel@tonic-gate qp_info.qp_trans = ibtl_cm_get_chan_type(statep->channel);
70130Sstevel@tonic-gate qp_info.qp_current_state = IBT_STATE_RTR;
70140Sstevel@tonic-gate
70150Sstevel@tonic-gate switch (qp_info.qp_trans) {
70160Sstevel@tonic-gate case IBT_RC_SRV:
70170Sstevel@tonic-gate IBCM_QPINFO_RC_PATH(qp_info).cep_timeout = timeout;
70180Sstevel@tonic-gate IBCM_QPINFO_RC(qp_info).rc_retry_cnt = statep->cep_retry_cnt;
70190Sstevel@tonic-gate IBCM_QPINFO_RC(qp_info).rc_rnr_retry_cnt =
702011369SPramod.Gunjikar@Sun.COM statep->local_qp_rnr_cnt;
70210Sstevel@tonic-gate IBCM_QPINFO_RC(qp_info).rc_sq_psn = statep->starting_psn;
70220Sstevel@tonic-gate
70230Sstevel@tonic-gate if (statep->mode == IBCM_ACTIVE_MODE) {
70240Sstevel@tonic-gate IBCM_QPINFO_RC(qp_info).rc_rdma_ra_out =
70250Sstevel@tonic-gate rep_msg->rep_resp_resources;
70260Sstevel@tonic-gate } else {
70270Sstevel@tonic-gate IBCM_QPINFO_RC(qp_info).rc_rdma_ra_out =
70280Sstevel@tonic-gate rep_msg->rep_initiator_depth;
70290Sstevel@tonic-gate }
70300Sstevel@tonic-gate if (statep->alt_port &&
70310Sstevel@tonic-gate (((rep_msg->rep_target_delay_plus >> 1) & 0x3) ==
70320Sstevel@tonic-gate IBT_CM_FAILOVER_ACCEPT)) {
70330Sstevel@tonic-gate /* failover was accepted */
70340Sstevel@tonic-gate cep_flags |= IBT_CEP_SET_MIG;
70350Sstevel@tonic-gate IBCM_QPINFO_RC(qp_info).rc_mig_state =
70360Sstevel@tonic-gate IBT_STATE_REARMED;
70370Sstevel@tonic-gate }
70380Sstevel@tonic-gate
70390Sstevel@tonic-gate break;
70400Sstevel@tonic-gate /* XXX RD? */
70410Sstevel@tonic-gate case IBT_UC_SRV:
70420Sstevel@tonic-gate IBCM_QPINFO_UC_PATH(qp_info).cep_timeout = timeout;
70430Sstevel@tonic-gate break;
70440Sstevel@tonic-gate default:
70450Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_invoke_rtu_qp_modify: "
70460Sstevel@tonic-gate "unknow svc_type = %x", qp_info.qp_trans);
70470Sstevel@tonic-gate break;
70480Sstevel@tonic-gate }
70490Sstevel@tonic-gate
70500Sstevel@tonic-gate /* Call modify_qp */
70510Sstevel@tonic-gate status = ibt_modify_qp(statep->channel, cep_flags, &qp_info, NULL);
70520Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_invoke_rtu_qp_modify: statep 0x%p "
70530Sstevel@tonic-gate "modify qp status = %d", statep, status);
70540Sstevel@tonic-gate
70550Sstevel@tonic-gate if (status == IBT_SUCCESS)
70560Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_RTR_RTS);
70570Sstevel@tonic-gate else
70580Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_RTR_RTS_FAIL);
70590Sstevel@tonic-gate
70600Sstevel@tonic-gate #ifdef DEBUG
70610Sstevel@tonic-gate print_modify_qp("RTR to RTS", statep->channel, cep_flags, &qp_info);
70620Sstevel@tonic-gate
70630Sstevel@tonic-gate if (statep->channel != NULL) {
70640Sstevel@tonic-gate ibt_qp_query_attr_t qp_attrs;
70650Sstevel@tonic-gate
70660Sstevel@tonic-gate (void) ibt_query_qp(statep->channel, &qp_attrs);
70670Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_invoke_rtu_qp_modify: "
70680Sstevel@tonic-gate "qp_info.qp_state = %x", qp_attrs.qp_info.qp_state);
70690Sstevel@tonic-gate }
70700Sstevel@tonic-gate #endif
70710Sstevel@tonic-gate return (status);
70720Sstevel@tonic-gate }
70730Sstevel@tonic-gate
70740Sstevel@tonic-gate
70750Sstevel@tonic-gate /*
70760Sstevel@tonic-gate * ibcm_cep_state_rtu:
70770Sstevel@tonic-gate * QP state transition function called for an incoming RTU
70780Sstevel@tonic-gate * on passive side.
70790Sstevel@tonic-gate *
70800Sstevel@tonic-gate * INPUTS:
70810Sstevel@tonic-gate * statep - connection state pointer
70820Sstevel@tonic-gate * cm_rtu_msg - RTU message pointer
70830Sstevel@tonic-gate *
70840Sstevel@tonic-gate */
70850Sstevel@tonic-gate void
ibcm_cep_state_rtu(ibcm_state_data_t * statep,ibcm_rtu_msg_t * cm_rtu_msgp)70860Sstevel@tonic-gate ibcm_cep_state_rtu(ibcm_state_data_t *statep, ibcm_rtu_msg_t *cm_rtu_msgp)
70870Sstevel@tonic-gate {
70880Sstevel@tonic-gate ibt_status_t status;
70890Sstevel@tonic-gate ibt_cm_event_t event;
70900Sstevel@tonic-gate ibcm_rep_msg_t *rep_msgp = (ibcm_rep_msg_t *)
70914703Shiremath IBCM_OUT_MSGP(statep->stored_msg);
70920Sstevel@tonic-gate
70930Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_rtu: statep 0x%p", statep);
70940Sstevel@tonic-gate
70950Sstevel@tonic-gate ASSERT(statep->channel != NULL);
70960Sstevel@tonic-gate
70970Sstevel@tonic-gate /* RDMA initiator depth taken from negotiated REP values */
70980Sstevel@tonic-gate status = ibcm_invoke_rtu_qp_modify(statep,
70990Sstevel@tonic-gate ibt_usec2ib(statep->remote_ack_delay), rep_msgp);
71000Sstevel@tonic-gate
71010Sstevel@tonic-gate if (status != IBT_SUCCESS) {
71020Sstevel@tonic-gate
71030Sstevel@tonic-gate (void) ibcm_cep_to_error_state(statep);
71040Sstevel@tonic-gate /*
71050Sstevel@tonic-gate * Disassociate statep and QP, as there is a
71060Sstevel@tonic-gate * QP associated with this statep.
71070Sstevel@tonic-gate */
71080Sstevel@tonic-gate IBCM_SET_CHAN_PRIVATE(statep->channel, NULL);
71090Sstevel@tonic-gate
71100Sstevel@tonic-gate ibcm_post_rej_mad(statep, IBT_CM_NO_RESC,
71110Sstevel@tonic-gate IBT_CM_FAILURE_UNKNOWN, NULL, 0);
71120Sstevel@tonic-gate /*
71130Sstevel@tonic-gate * Invoke CM handler, so client/server can do
71140Sstevel@tonic-gate * resource cleanup. No private data can be returned here
71150Sstevel@tonic-gate */
71160Sstevel@tonic-gate ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
71170Sstevel@tonic-gate IBT_CM_FAILURE_UNKNOWN, IBT_CM_NO_RESC, NULL, 0);
71180Sstevel@tonic-gate
71190Sstevel@tonic-gate /* unblock any pending DREQ threads */
71200Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
71210Sstevel@tonic-gate statep->cep_in_rts = IBCM_FAIL;
71220Sstevel@tonic-gate cv_broadcast(&statep->block_mad_cv);
71230Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
71240Sstevel@tonic-gate return;
71250Sstevel@tonic-gate }
71260Sstevel@tonic-gate
71270Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
71280Sstevel@tonic-gate statep->state = IBCM_STATE_ESTABLISHED;
71290Sstevel@tonic-gate ibtl_cm_chan_is_open(statep->channel);
71300Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
71310Sstevel@tonic-gate
71320Sstevel@tonic-gate /* invoke the CM handler */
71330Sstevel@tonic-gate ASSERT(statep->cm_handler != NULL);
71340Sstevel@tonic-gate
71350Sstevel@tonic-gate bzero(&event, sizeof (event));
71360Sstevel@tonic-gate event.cm_channel = statep->channel;
71370Sstevel@tonic-gate event.cm_session_id = NULL;
71380Sstevel@tonic-gate
71390Sstevel@tonic-gate event.cm_type = IBT_CM_EVENT_CONN_EST;
71400Sstevel@tonic-gate if (cm_rtu_msgp != NULL) {
71410Sstevel@tonic-gate event.cm_priv_data = &(cm_rtu_msgp->rtu_private_data[0]);
71420Sstevel@tonic-gate event.cm_priv_data_len = IBT_RTU_PRIV_DATA_SZ;
71430Sstevel@tonic-gate }
71440Sstevel@tonic-gate
71450Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_CALLED_CONN_EST_EVENT);
71460Sstevel@tonic-gate
71470Sstevel@tonic-gate (void) statep->cm_handler(statep->state_cm_private, &event, NULL,
71480Sstevel@tonic-gate NULL, 0);
71490Sstevel@tonic-gate
71500Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_RET_CONN_EST_EVENT);
71510Sstevel@tonic-gate if (ibcm_enable_trace & 4)
71520Sstevel@tonic-gate ibcm_dump_conn_trace(statep);
71534908Shiremath else
71544908Shiremath IBTF_DPRINTF_L2(cmlog, "ibcm_cep_state_rtu CONN_EST Channel %p",
71554908Shiremath statep->channel);
71560Sstevel@tonic-gate
71570Sstevel@tonic-gate /* unblock any pending DREQ threads */
71580Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
71590Sstevel@tonic-gate statep->cep_in_rts = IBCM_UNBLOCK;
71600Sstevel@tonic-gate cv_broadcast(&statep->block_mad_cv);
71610Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
71620Sstevel@tonic-gate }
71630Sstevel@tonic-gate
71640Sstevel@tonic-gate
71650Sstevel@tonic-gate /*
71660Sstevel@tonic-gate * ibcm_cep_send_rtu:
71670Sstevel@tonic-gate * QP state transition function called for an outgoing RTU
71680Sstevel@tonic-gate * on active side.
71690Sstevel@tonic-gate *
71700Sstevel@tonic-gate * INPUTS:
71710Sstevel@tonic-gate * statep - connection state pointer
71720Sstevel@tonic-gate *
71730Sstevel@tonic-gate * RETURN VALUE:
71740Sstevel@tonic-gate */
71750Sstevel@tonic-gate void
ibcm_cep_send_rtu(ibcm_state_data_t * statep)71760Sstevel@tonic-gate ibcm_cep_send_rtu(ibcm_state_data_t *statep)
71770Sstevel@tonic-gate {
71780Sstevel@tonic-gate /* invoke the CM handler */
71790Sstevel@tonic-gate if (statep->cm_handler) {
71800Sstevel@tonic-gate ibt_cm_event_t event;
71810Sstevel@tonic-gate
71820Sstevel@tonic-gate bzero(&event, sizeof (event));
71830Sstevel@tonic-gate event.cm_type = IBT_CM_EVENT_CONN_EST;
71840Sstevel@tonic-gate event.cm_channel = statep->channel;
71850Sstevel@tonic-gate event.cm_session_id = NULL;
71860Sstevel@tonic-gate event.cm_priv_data = NULL;
71870Sstevel@tonic-gate event.cm_priv_data_len = 0;
71880Sstevel@tonic-gate
71890Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_CALLED_CONN_EST_EVENT);
71900Sstevel@tonic-gate
71910Sstevel@tonic-gate (void) statep->cm_handler(statep->state_cm_private, &event,
71920Sstevel@tonic-gate NULL, NULL, 0);
71930Sstevel@tonic-gate
71940Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_RET_CONN_EST_EVENT);
71950Sstevel@tonic-gate
71960Sstevel@tonic-gate } else {
71970Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_cep_send_rtu: cm_handler NULL");
71980Sstevel@tonic-gate }
71990Sstevel@tonic-gate if (ibcm_enable_trace & 4)
72000Sstevel@tonic-gate ibcm_dump_conn_trace(statep);
72014908Shiremath else
72024908Shiremath IBTF_DPRINTF_L2(cmlog, "ibcm_cep_send_rtu CONN_EST Channel %p",
72034908Shiremath statep->channel);
72040Sstevel@tonic-gate
72050Sstevel@tonic-gate /* unblock any pending DREQ threads */
72060Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
72070Sstevel@tonic-gate statep->cep_in_rts = IBCM_UNBLOCK;
72080Sstevel@tonic-gate cv_broadcast(&statep->block_mad_cv);
72090Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
72100Sstevel@tonic-gate }
72110Sstevel@tonic-gate
72120Sstevel@tonic-gate
72130Sstevel@tonic-gate /*
72140Sstevel@tonic-gate * ibcm_cep_to_error_state:
72150Sstevel@tonic-gate * CEP state transition function. Changes state to IBT_STATE_ERROR
72160Sstevel@tonic-gate *
72170Sstevel@tonic-gate * INPUTS:
72180Sstevel@tonic-gate * statep - connection state pointer
72190Sstevel@tonic-gate *
72200Sstevel@tonic-gate * RETURN VALUE:
72210Sstevel@tonic-gate * IBT_SUCCESS - if able to change state otherwise failure
72220Sstevel@tonic-gate */
72230Sstevel@tonic-gate ibt_status_t
ibcm_cep_to_error_state(ibcm_state_data_t * statep)72240Sstevel@tonic-gate ibcm_cep_to_error_state(ibcm_state_data_t *statep)
72250Sstevel@tonic-gate {
72260Sstevel@tonic-gate ibt_status_t status = IBT_SUCCESS;
72270Sstevel@tonic-gate
72280Sstevel@tonic-gate if (statep->channel != NULL) {
72290Sstevel@tonic-gate ibt_qp_info_t qp_info;
72300Sstevel@tonic-gate
72310Sstevel@tonic-gate bzero(&qp_info, sizeof (qp_info));
72320Sstevel@tonic-gate /* For now, set it to RC type */
72330Sstevel@tonic-gate qp_info.qp_trans = IBT_RC_SRV;
72340Sstevel@tonic-gate qp_info.qp_state = IBT_STATE_ERROR;
72350Sstevel@tonic-gate
72360Sstevel@tonic-gate /* Call modify_qp to move to ERROR state */
72370Sstevel@tonic-gate status = ibt_modify_qp(statep->channel, IBT_CEP_SET_STATE,
72380Sstevel@tonic-gate &qp_info, NULL);
72390Sstevel@tonic-gate
72400Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_cep_to_error_state: "
72410Sstevel@tonic-gate "statep %p ibt_modify_qp() = %d", statep, status);
72420Sstevel@tonic-gate
72430Sstevel@tonic-gate if (status == IBT_SUCCESS)
72440Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_ERROR);
72450Sstevel@tonic-gate else
72460Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_ERROR_FAIL);
72470Sstevel@tonic-gate
72480Sstevel@tonic-gate }
72490Sstevel@tonic-gate
72500Sstevel@tonic-gate #ifdef NO_EEC_SUPPORT_YET
72510Sstevel@tonic-gate if (statep->channel.ch_eec != NULL) {
72520Sstevel@tonic-gate ibt_eec_info_t eec_info;
72530Sstevel@tonic-gate
72540Sstevel@tonic-gate bzero(&eec_info, sizeof (ibt_eec_info_t));
72550Sstevel@tonic-gate eec_info.eec_state = what;
72560Sstevel@tonic-gate
72570Sstevel@tonic-gate /* Call modify_eec */
72580Sstevel@tonic-gate status = ibtl_cm_modify_eec(statep->channel.ch_eec, &eec_info,
72590Sstevel@tonic-gate IBT_CEP_SET_NOTHING);
72600Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_cep_to_error_state: "
72610Sstevel@tonic-gate "ibtl_cm_modify_eec() returned = %x", status);
72620Sstevel@tonic-gate }
72630Sstevel@tonic-gate #endif
72640Sstevel@tonic-gate
72650Sstevel@tonic-gate return (status);
72660Sstevel@tonic-gate }
72670Sstevel@tonic-gate
72680Sstevel@tonic-gate
72690Sstevel@tonic-gate /*
72700Sstevel@tonic-gate * ibcm_cep_state_rej:
72710Sstevel@tonic-gate * QP state transition function called for an incoming REJ
72720Sstevel@tonic-gate * on active/passive side
72730Sstevel@tonic-gate *
72740Sstevel@tonic-gate * INPUTS:
72750Sstevel@tonic-gate * statep - connection state pointer
72760Sstevel@tonic-gate * rej_msgp - REJ message pointer
72770Sstevel@tonic-gate * rej_state - State where REJ processing began
72780Sstevel@tonic-gate *
72790Sstevel@tonic-gate * RETURN VALUE:
72800Sstevel@tonic-gate */
72810Sstevel@tonic-gate void
ibcm_cep_state_rej(ibcm_state_data_t * statep,ibcm_rej_msg_t * rej_msgp,ibcm_conn_state_t rej_state)72820Sstevel@tonic-gate ibcm_cep_state_rej(ibcm_state_data_t *statep, ibcm_rej_msg_t *rej_msgp,
72830Sstevel@tonic-gate ibcm_conn_state_t rej_state)
72840Sstevel@tonic-gate {
72850Sstevel@tonic-gate ibt_cm_event_t event;
72860Sstevel@tonic-gate ibt_status_t status;
72870Sstevel@tonic-gate
72880Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_rej: statep 0x%p", statep);
72890Sstevel@tonic-gate
7290557Shiremath ibcm_path_cache_purge();
7291557Shiremath
72920Sstevel@tonic-gate if ((rej_state == IBCM_STATE_REP_SENT) ||
72930Sstevel@tonic-gate (rej_state == IBCM_STATE_MRA_REP_RCVD)) {
72940Sstevel@tonic-gate status = ibcm_cep_to_error_state(statep);
7295557Shiremath IBTF_DPRINTF_L5(cmlog, "ibcm_cep_state_rej: statep 0x%p "
72960Sstevel@tonic-gate "ibcm_cep_to_error_state returned %d", statep,
72970Sstevel@tonic-gate status);
72980Sstevel@tonic-gate }
72990Sstevel@tonic-gate
7300*12292SPramod.Gunjikar@Sun.COM if (statep->channel)
7301*12292SPramod.Gunjikar@Sun.COM ibtl_cm_chan_open_is_aborted(statep->channel);
730212064SShantkumar.Hiremath@Sun.COM
73030Sstevel@tonic-gate /* Disassociate state structure and CM */
73040Sstevel@tonic-gate IBCM_SET_CHAN_PRIVATE(statep->channel, NULL);
73050Sstevel@tonic-gate
73060Sstevel@tonic-gate /* invoke the CM handler */
73070Sstevel@tonic-gate bzero(&event, sizeof (event));
73080Sstevel@tonic-gate if (statep->cm_handler) {
73090Sstevel@tonic-gate event.cm_type = IBT_CM_EVENT_FAILURE;
73100Sstevel@tonic-gate event.cm_channel = statep->channel;
73110Sstevel@tonic-gate event.cm_session_id = NULL;
73120Sstevel@tonic-gate
73130Sstevel@tonic-gate /*
73140Sstevel@tonic-gate * copy rej_msgp->rej_private_data to
73150Sstevel@tonic-gate * event.cm_event.cm_priv_data
73160Sstevel@tonic-gate */
73170Sstevel@tonic-gate event.cm_priv_data = &(rej_msgp->rej_private_data[0]);
73180Sstevel@tonic-gate event.cm_priv_data_len = IBT_REJ_PRIV_DATA_SZ;
73190Sstevel@tonic-gate
73200Sstevel@tonic-gate event.cm_event.failed.cf_code = IBT_CM_FAILURE_REJ_RCV;
73210Sstevel@tonic-gate event.cm_event.failed.cf_msg = rej_msgp->rej_msg_type_plus >> 6;
73220Sstevel@tonic-gate event.cm_event.failed.cf_reason =
73234703Shiremath b2h16(rej_msgp->rej_rejection_reason);
73240Sstevel@tonic-gate
7325401Shiremath IBTF_DPRINTF_L3(cmlog, "ibcm_cep_state_rej: rej_reason = %d",
73260Sstevel@tonic-gate event.cm_event.failed.cf_reason);
73270Sstevel@tonic-gate
73280Sstevel@tonic-gate ibcm_copy_addl_rej(statep, rej_msgp, &event.cm_event.failed);
73290Sstevel@tonic-gate
73300Sstevel@tonic-gate (void) statep->cm_handler(statep->state_cm_private, &event,
73310Sstevel@tonic-gate NULL, NULL, 0);
73320Sstevel@tonic-gate }
73330Sstevel@tonic-gate
73340Sstevel@tonic-gate if (statep->open_return_data != NULL)
73350Sstevel@tonic-gate bcopy(&event.cm_event.failed.cf_additional,
73360Sstevel@tonic-gate &statep->open_return_data->rc_arej_info,
73370Sstevel@tonic-gate sizeof (ibt_arej_info_t));
73380Sstevel@tonic-gate if (ibcm_enable_trace != 0)
73390Sstevel@tonic-gate ibcm_dump_conn_trace(statep);
73401093Shiremath mutex_enter(&statep->state_mutex);
73411093Shiremath ibcm_open_done(statep);
73421093Shiremath mutex_exit(&statep->state_mutex);
73430Sstevel@tonic-gate }
73440Sstevel@tonic-gate
73450Sstevel@tonic-gate /* Used to initialize client args with addl rej information from REJ MAD */
73460Sstevel@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)73470Sstevel@tonic-gate ibcm_copy_addl_rej(ibcm_state_data_t *statep, ibcm_rej_msg_t *rej_msgp,
73480Sstevel@tonic-gate ibt_cm_conn_failed_t *failed)
73490Sstevel@tonic-gate {
73500Sstevel@tonic-gate uint16_t rej_reason = b2h16(rej_msgp->rej_rejection_reason);
73516709Shiremath uint8_t ari_len = rej_msgp->rej_reject_info_len_plus >> 1;
73520Sstevel@tonic-gate ibcm_classportinfo_msg_t tclp;
73530Sstevel@tonic-gate ibt_arej_info_t *cf_addl = &failed->cf_additional;
73540Sstevel@tonic-gate
73550Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*cf_addl))
73560Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(failed->cf_arej_info_valid))
73570Sstevel@tonic-gate
73580Sstevel@tonic-gate failed->cf_arej_info_valid = B_FALSE;
73590Sstevel@tonic-gate
7360401Shiremath IBTF_DPRINTF_L3(cmlog, "ibcm_copy_addl_rej: rej_reason = %d "
7361401Shiremath "ari_len = %d", rej_reason, ari_len);
7362401Shiremath
73630Sstevel@tonic-gate if ((statep->mode == IBCM_PASSIVE_MODE) &&
73640Sstevel@tonic-gate (rej_reason != IBT_CM_CONSUMER))
73650Sstevel@tonic-gate return;
73660Sstevel@tonic-gate
73670Sstevel@tonic-gate switch (rej_reason) {
73680Sstevel@tonic-gate case IBT_CM_PRIM_GID:
73690Sstevel@tonic-gate case IBT_CM_ALT_GID:
73700Sstevel@tonic-gate case IBT_CM_PORT_REDIRECT:
73710Sstevel@tonic-gate if (ari_len < sizeof (ib_gid_t))
73720Sstevel@tonic-gate break;
73730Sstevel@tonic-gate failed->cf_arej_info_valid = B_TRUE;
73740Sstevel@tonic-gate bcopy(rej_msgp->rej_addl_rej_info, &cf_addl->ari_gid,
73750Sstevel@tonic-gate sizeof (ib_gid_t));
73760Sstevel@tonic-gate cf_addl->ari_gid.gid_guid = b2h64(cf_addl->ari_gid.gid_guid);
73770Sstevel@tonic-gate cf_addl->ari_gid.gid_prefix =
73780Sstevel@tonic-gate b2h64(cf_addl->ari_gid.gid_prefix);
7379401Shiremath
7380401Shiremath IBTF_DPRINTF_L4(cmlog, "ibcm_copy_addl_rej: ari_gid= %llX:%llX",
7381401Shiremath cf_addl->ari_gid.gid_prefix, cf_addl->ari_gid.gid_guid);
7382401Shiremath
73830Sstevel@tonic-gate break;
73840Sstevel@tonic-gate case IBT_CM_PRIM_LID:
73850Sstevel@tonic-gate case IBT_CM_ALT_LID:
73860Sstevel@tonic-gate if (ari_len < sizeof (ib_lid_t))
73870Sstevel@tonic-gate break;
73880Sstevel@tonic-gate failed->cf_arej_info_valid = B_TRUE;
73890Sstevel@tonic-gate bcopy(rej_msgp->rej_addl_rej_info, &cf_addl->ari_lid,
73900Sstevel@tonic-gate sizeof (ib_lid_t));
73910Sstevel@tonic-gate cf_addl->ari_lid = b2h16(cf_addl->ari_lid);
7392401Shiremath IBTF_DPRINTF_L4(cmlog, "ibcm_copy_addl_rej: ari_lid= 0x%lX",
7393401Shiremath cf_addl->ari_lid);
7394401Shiremath
73950Sstevel@tonic-gate break;
73960Sstevel@tonic-gate case IBT_CM_INVALID_PRIM_SL:
73970Sstevel@tonic-gate case IBT_CM_INVALID_ALT_SL:
73980Sstevel@tonic-gate if (ari_len < 1)
73990Sstevel@tonic-gate break;
74000Sstevel@tonic-gate failed->cf_arej_info_valid = B_TRUE;
74010Sstevel@tonic-gate /* take the first 4 bits */
74020Sstevel@tonic-gate cf_addl->ari_sl = rej_msgp->rej_addl_rej_info[0] >> 4;
74030Sstevel@tonic-gate break;
74040Sstevel@tonic-gate case IBT_CM_INVALID_PRIM_TC:
74050Sstevel@tonic-gate case IBT_CM_INVALID_ALT_TC:
74060Sstevel@tonic-gate if (ari_len < 1)
74070Sstevel@tonic-gate break;
74080Sstevel@tonic-gate failed->cf_arej_info_valid = B_TRUE;
74090Sstevel@tonic-gate /* take the first byte */
74100Sstevel@tonic-gate cf_addl->ari_tclass = rej_msgp->rej_addl_rej_info[0];
74110Sstevel@tonic-gate break;
74120Sstevel@tonic-gate case IBT_CM_INVALID_PRIM_HOP:
74130Sstevel@tonic-gate case IBT_CM_INVALID_ALT_HOP:
74140Sstevel@tonic-gate if (ari_len < 1)
74150Sstevel@tonic-gate break;
74160Sstevel@tonic-gate failed->cf_arej_info_valid = B_TRUE;
74170Sstevel@tonic-gate /* take the first byte */
74180Sstevel@tonic-gate cf_addl->ari_hop = rej_msgp->rej_addl_rej_info[0];
74190Sstevel@tonic-gate break;
74200Sstevel@tonic-gate case IBT_CM_INVALID_PRIM_RATE:
74210Sstevel@tonic-gate case IBT_CM_INVALID_ALT_RATE:
74220Sstevel@tonic-gate if (ari_len < 1)
74230Sstevel@tonic-gate break;
74240Sstevel@tonic-gate failed->cf_arej_info_valid = B_TRUE;
74250Sstevel@tonic-gate /* take the first 6 bits */
74260Sstevel@tonic-gate cf_addl->ari_rate = rej_msgp->rej_addl_rej_info[0] >> 2;
74270Sstevel@tonic-gate break;
74280Sstevel@tonic-gate case IBT_CM_REDIRECT_CM:
74290Sstevel@tonic-gate if (ari_len < sizeof (ibcm_classportinfo_msg_t))
74300Sstevel@tonic-gate break;
74310Sstevel@tonic-gate failed->cf_arej_info_valid = B_TRUE;
74320Sstevel@tonic-gate bcopy(rej_msgp->rej_addl_rej_info, &tclp, sizeof (tclp));
74330Sstevel@tonic-gate ibcm_init_clp_from_mad(&tclp, &cf_addl->ari_redirect);
74340Sstevel@tonic-gate break;
74350Sstevel@tonic-gate case IBT_CM_INVALID_MTU:
74360Sstevel@tonic-gate if (ari_len < 1)
74370Sstevel@tonic-gate break;
74380Sstevel@tonic-gate failed->cf_arej_info_valid = B_TRUE;
74390Sstevel@tonic-gate /* take the first 4 bits */
74400Sstevel@tonic-gate cf_addl->ari_mtu = rej_msgp->rej_addl_rej_info[0] >> 4;
74410Sstevel@tonic-gate break;
74420Sstevel@tonic-gate case IBT_CM_CONSUMER:
74430Sstevel@tonic-gate if (ari_len == 0)
74440Sstevel@tonic-gate break;
74450Sstevel@tonic-gate failed->cf_arej_info_valid = B_TRUE;
74460Sstevel@tonic-gate if (ari_len > IBT_CM_ADDL_REJ_LEN)
74470Sstevel@tonic-gate ari_len = IBT_CM_ADDL_REJ_LEN;
74480Sstevel@tonic-gate bcopy(&rej_msgp->rej_addl_rej_info,
74490Sstevel@tonic-gate cf_addl->ari_consumer.rej_ari, ari_len);
74500Sstevel@tonic-gate cf_addl->ari_consumer.rej_ari_len = ari_len;
74510Sstevel@tonic-gate break;
74520Sstevel@tonic-gate case IBT_CM_INVALID_PRIM_FLOW:
74530Sstevel@tonic-gate case IBT_CM_INVALID_ALT_FLOW:
74540Sstevel@tonic-gate if (ari_len < 3) /* 3 bytes needed for 20 bits */
74550Sstevel@tonic-gate break;
74560Sstevel@tonic-gate failed->cf_arej_info_valid = B_TRUE;
74570Sstevel@tonic-gate /* take the first 20 bits */
74580Sstevel@tonic-gate cf_addl->ari_flow =
74590Sstevel@tonic-gate b2h32(*(uint32_t *)&rej_msgp->rej_addl_rej_info) >> 12;
74600Sstevel@tonic-gate break;
74610Sstevel@tonic-gate default:
74620Sstevel@tonic-gate break;
74630Sstevel@tonic-gate }
74640Sstevel@tonic-gate
74650Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(failed->cf_arej_info_valid))
74660Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*cf_addl))
74670Sstevel@tonic-gate }
74680Sstevel@tonic-gate
74690Sstevel@tonic-gate
74700Sstevel@tonic-gate /* Used to copy classportinfo to MAD from client initialized args */
74710Sstevel@tonic-gate static void
ibcm_init_clp_to_mad(ibcm_classportinfo_msg_t * clp,ibt_redirect_info_t * rinfo)74720Sstevel@tonic-gate ibcm_init_clp_to_mad(ibcm_classportinfo_msg_t *clp, ibt_redirect_info_t *rinfo)
74730Sstevel@tonic-gate {
74740Sstevel@tonic-gate
74750Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*clp))
74760Sstevel@tonic-gate
74770Sstevel@tonic-gate bcopy(&ibcm_clpinfo, clp, sizeof (ibcm_clpinfo));
74780Sstevel@tonic-gate
74790Sstevel@tonic-gate clp->RedirectGID_hi = h2b64(rinfo->rdi_gid.gid_prefix);
74800Sstevel@tonic-gate clp->RedirectGID_lo = h2b64(rinfo->rdi_gid.gid_guid);
74810Sstevel@tonic-gate clp->RedirectTC_plus =
74820Sstevel@tonic-gate h2b32((rinfo->rdi_tclass << 24) | (rinfo->rdi_sl << 20) |
74830Sstevel@tonic-gate (rinfo->rdi_flow & 0xfffff));
74840Sstevel@tonic-gate clp->RedirectLID = h2b16(rinfo->rdi_dlid);
74850Sstevel@tonic-gate clp->RedirectQP_plus = h2b32(rinfo->rdi_qpn & 0xffffff);
74860Sstevel@tonic-gate clp->RedirectQ_Key = h2b32(rinfo->rdi_qkey);
74870Sstevel@tonic-gate clp->RedirectP_Key = h2b16(rinfo->rdi_pkey);
74880Sstevel@tonic-gate
7489401Shiremath IBTF_DPRINTF_L4(cmlog, "ibcm_init_clp_to_mad: RedirectGID= %llX:%llX,"
7490401Shiremath " RedirectLID= 0x%lX", clp->RedirectGID_hi, clp->RedirectGID_lo,
7491401Shiremath clp->RedirectLID);
7492401Shiremath
74930Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*clp))
74940Sstevel@tonic-gate }
74950Sstevel@tonic-gate
74960Sstevel@tonic-gate
74970Sstevel@tonic-gate /* Used to initialize classportinfo to be returned to clients, from MAD */
74980Sstevel@tonic-gate static void
ibcm_init_clp_from_mad(ibcm_classportinfo_msg_t * clp,ibt_redirect_info_t * rinfo)74990Sstevel@tonic-gate ibcm_init_clp_from_mad(ibcm_classportinfo_msg_t *clp,
75000Sstevel@tonic-gate ibt_redirect_info_t *rinfo)
75010Sstevel@tonic-gate {
75020Sstevel@tonic-gate uint32_t temp32;
75030Sstevel@tonic-gate
75040Sstevel@tonic-gate rinfo->rdi_gid.gid_prefix = b2h64(clp->RedirectGID_hi);
75050Sstevel@tonic-gate rinfo->rdi_gid.gid_guid = b2h64(clp->RedirectGID_lo);
75060Sstevel@tonic-gate temp32 = b2h32(clp->RedirectTC_plus);
75070Sstevel@tonic-gate rinfo->rdi_tclass = temp32 >> 24;
75080Sstevel@tonic-gate rinfo->rdi_sl = (temp32 >> 20) & 0xf;
75090Sstevel@tonic-gate rinfo->rdi_flow = temp32 & 0xffff;
75100Sstevel@tonic-gate rinfo->rdi_dlid = b2h16(clp->RedirectLID);
75110Sstevel@tonic-gate rinfo->rdi_qpn = b2h32(clp->RedirectQP_plus & 0xffffff);
75120Sstevel@tonic-gate rinfo->rdi_qkey = b2h32(clp->RedirectQ_Key);
75130Sstevel@tonic-gate rinfo->rdi_pkey = b2h16(clp->RedirectP_Key);
7514401Shiremath
7515401Shiremath IBTF_DPRINTF_L4(cmlog, "ibcm_init_clp_from_mad: RedirectGID= %llX:%llX,"
7516401Shiremath " RedirectLID= 0x%lX", rinfo->rdi_gid.gid_prefix,
7517401Shiremath rinfo->rdi_gid.gid_guid, rinfo->rdi_dlid);
75180Sstevel@tonic-gate }
75190Sstevel@tonic-gate
75200Sstevel@tonic-gate
75210Sstevel@tonic-gate /*
75220Sstevel@tonic-gate * ibcm_cep_state_rej_est:
75230Sstevel@tonic-gate * QP state transition function called for an incoming REJ
75240Sstevel@tonic-gate * on active side in established state
75250Sstevel@tonic-gate *
75260Sstevel@tonic-gate * INPUTS:
75270Sstevel@tonic-gate * statep - connection state pointer
75280Sstevel@tonic-gate *
75290Sstevel@tonic-gate * RETURN VALUE:
75300Sstevel@tonic-gate */
75310Sstevel@tonic-gate void
ibcm_cep_state_rej_est(ibcm_state_data_t * statep)75320Sstevel@tonic-gate ibcm_cep_state_rej_est(ibcm_state_data_t *statep)
75330Sstevel@tonic-gate {
75340Sstevel@tonic-gate ibt_cm_event_t event;
75350Sstevel@tonic-gate ibt_status_t status;
75360Sstevel@tonic-gate
75370Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_cep_state_rej_est:");
75380Sstevel@tonic-gate
75390Sstevel@tonic-gate status = ibcm_cep_to_error_state(statep);
75400Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_rej_est: statep 0x%p "
75410Sstevel@tonic-gate "ibcm_cep_to_error_state returned %d", statep, status);
75420Sstevel@tonic-gate
75430Sstevel@tonic-gate /* Disassociate state structure and CM */
75440Sstevel@tonic-gate IBCM_SET_CHAN_PRIVATE(statep->channel, NULL);
75450Sstevel@tonic-gate
75460Sstevel@tonic-gate ibtl_cm_chan_is_closing(statep->channel);
75470Sstevel@tonic-gate
75480Sstevel@tonic-gate /* invoke the CM handler */
75490Sstevel@tonic-gate if (statep->cm_handler) {
75500Sstevel@tonic-gate bzero(&event, sizeof (event));
75510Sstevel@tonic-gate event.cm_type = IBT_CM_EVENT_CONN_CLOSED;
75520Sstevel@tonic-gate event.cm_channel = statep->channel;
75530Sstevel@tonic-gate event.cm_session_id = NULL;
75540Sstevel@tonic-gate
75550Sstevel@tonic-gate event.cm_priv_data = NULL;
75560Sstevel@tonic-gate event.cm_priv_data_len = 0;
75570Sstevel@tonic-gate
75580Sstevel@tonic-gate event.cm_event.closed = IBT_CM_CLOSED_REJ_RCVD;
75590Sstevel@tonic-gate
75600Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_rej_est: "
7561557Shiremath "rej_reason = %d", event.cm_event.failed.cf_reason);
75620Sstevel@tonic-gate
75630Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_CALLED_CONN_CLOSE_EVENT);
75640Sstevel@tonic-gate
75650Sstevel@tonic-gate (void) statep->cm_handler(statep->state_cm_private, &event,
75660Sstevel@tonic-gate NULL, NULL, 0);
75670Sstevel@tonic-gate
75680Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_RET_CONN_CLOSE_EVENT);
75690Sstevel@tonic-gate
75700Sstevel@tonic-gate }
75710Sstevel@tonic-gate }
75720Sstevel@tonic-gate
75730Sstevel@tonic-gate
75740Sstevel@tonic-gate /*
75750Sstevel@tonic-gate * ibcm_sidr_req_ud_handler:
75760Sstevel@tonic-gate * Invoke Client's UD handler For SIDR_REQ msg
75770Sstevel@tonic-gate *
75780Sstevel@tonic-gate * INPUTS:
75790Sstevel@tonic-gate * ud_statep - ud_state pointer
75800Sstevel@tonic-gate * sidr_reqp - SIDR_REQ message pointer
75810Sstevel@tonic-gate *
75820Sstevel@tonic-gate * RETURN VALUE: IBCM_SEND_REP/IBCM_SEND_REJ
75830Sstevel@tonic-gate */
75840Sstevel@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)75850Sstevel@tonic-gate ibcm_sidr_req_ud_handler(ibcm_ud_state_data_t *ud_statep,
75860Sstevel@tonic-gate ibcm_sidr_req_msg_t *sidr_reqp, ibcm_mad_addr_t *cm_mad_addr,
75870Sstevel@tonic-gate ibt_sidr_status_t *sidr_status)
75880Sstevel@tonic-gate {
75890Sstevel@tonic-gate void *priv_data = NULL;
75900Sstevel@tonic-gate ibt_cm_ud_event_t ud_event;
75910Sstevel@tonic-gate ibcm_sidr_rep_msg_t *sidr_repp;
75920Sstevel@tonic-gate ibt_cm_ud_return_args_t ud_ret_args;
75930Sstevel@tonic-gate ibt_cm_status_t cb_status;
75940Sstevel@tonic-gate ibt_qp_query_attr_t qp_attr;
75950Sstevel@tonic-gate ibt_status_t retval;
75960Sstevel@tonic-gate ibcm_ud_clnt_reply_info_t ud_clnt_info;
75970Sstevel@tonic-gate
75980Sstevel@tonic-gate /* Check first if UD client handler is valid */
75990Sstevel@tonic-gate ASSERT(ud_statep->ud_cm_handler != NULL);
76000Sstevel@tonic-gate
76010Sstevel@tonic-gate /* Fill in ibt_cm_ud_event_t */
76020Sstevel@tonic-gate ud_event.cm_type = IBT_CM_UD_EVENT_SIDR_REQ;
76030Sstevel@tonic-gate ud_event.cm_session_id = ud_statep;
76040Sstevel@tonic-gate ud_event.cm_event.sidr_req.sreq_service_id = ud_statep->ud_svc_id;
76050Sstevel@tonic-gate ud_event.cm_event.sidr_req.sreq_hca_guid = ud_statep->ud_hcap->hca_guid;
76060Sstevel@tonic-gate ud_event.cm_event.sidr_req.sreq_pkey = b2h16(sidr_reqp->sidr_req_pkey);
76070Sstevel@tonic-gate ud_event.cm_event.sidr_req.sreq_hca_port = cm_mad_addr->port_num;
76080Sstevel@tonic-gate
76090Sstevel@tonic-gate ud_event.cm_priv_data =
76100Sstevel@tonic-gate &(sidr_reqp->sidr_req_private_data[0]);
76110Sstevel@tonic-gate ud_event.cm_priv_data_len = IBT_SIDR_REQ_PRIV_DATA_SZ;
76120Sstevel@tonic-gate
76130Sstevel@tonic-gate sidr_repp =
76140Sstevel@tonic-gate (ibcm_sidr_rep_msg_t *)IBCM_OUT_MSGP(ud_statep->ud_stored_msg);
76150Sstevel@tonic-gate
76160Sstevel@tonic-gate priv_data = &(sidr_repp->sidr_rep_private_data[0]);
76170Sstevel@tonic-gate
76180Sstevel@tonic-gate bzero(&ud_ret_args, sizeof (ud_ret_args));
76190Sstevel@tonic-gate
76200Sstevel@tonic-gate /* Invoke the client handler */
76210Sstevel@tonic-gate cb_status = ud_statep->ud_cm_handler(ud_statep->ud_state_cm_private,
76220Sstevel@tonic-gate &ud_event, &ud_ret_args, priv_data, IBT_SIDR_REP_PRIV_DATA_SZ);
76230Sstevel@tonic-gate
76240Sstevel@tonic-gate if (cb_status == IBT_CM_DEFER) {
76250Sstevel@tonic-gate
76260Sstevel@tonic-gate /* unblock any blocked cm ud proceed api calls */
76270Sstevel@tonic-gate mutex_enter(&ud_statep->ud_state_mutex);
76280Sstevel@tonic-gate ud_statep->ud_clnt_proceed = IBCM_UNBLOCK;
76290Sstevel@tonic-gate cv_broadcast(&ud_statep->ud_block_client_cv);
76300Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
76310Sstevel@tonic-gate
76320Sstevel@tonic-gate return (IBCM_DEFER);
76330Sstevel@tonic-gate }
76340Sstevel@tonic-gate
76350Sstevel@tonic-gate /* fail any blocked ud cm proceed api calls - client bug */
76360Sstevel@tonic-gate mutex_enter(&ud_statep->ud_state_mutex);
76370Sstevel@tonic-gate ud_statep->ud_clnt_proceed = IBCM_FAIL;
76380Sstevel@tonic-gate cv_broadcast(&ud_statep->ud_block_client_cv);
76390Sstevel@tonic-gate mutex_exit(&ud_statep->ud_state_mutex);
76400Sstevel@tonic-gate
76410Sstevel@tonic-gate /* do the query qp as soon as possible, after return from cm handler */
76420Sstevel@tonic-gate if (cb_status == IBT_CM_ACCEPT) {
76430Sstevel@tonic-gate retval = ibt_query_qp(ud_ret_args.ud_channel, &qp_attr);
76440Sstevel@tonic-gate if (retval != IBT_SUCCESS) {
76450Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_sidr_req_ud_handler: "
76460Sstevel@tonic-gate "Failed to retrieve QPN from the channel: %d",
76470Sstevel@tonic-gate retval);
76480Sstevel@tonic-gate *sidr_status = IBT_CM_SREP_NO_CHAN;
76490Sstevel@tonic-gate return (IBCM_SEND_SIDR_REP);
76500Sstevel@tonic-gate } else if (qp_attr.qp_info.qp_trans != IBT_UD_SRV) {
76510Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_sidr_req_ud_handler: "
76520Sstevel@tonic-gate "Server/Passive returned non-UD %d transport type "
76530Sstevel@tonic-gate "QP", qp_attr.qp_info.qp_trans);
76540Sstevel@tonic-gate *sidr_status = IBT_CM_SREP_NO_CHAN;
76550Sstevel@tonic-gate return (IBCM_SEND_SIDR_REP);
76560Sstevel@tonic-gate }
76570Sstevel@tonic-gate
76580Sstevel@tonic-gate ud_clnt_info.ud_qkey = qp_attr.qp_info.qp_transport.ud.ud_qkey;
76590Sstevel@tonic-gate ud_clnt_info.ud_qpn = qp_attr.qp_qpn;
76600Sstevel@tonic-gate }
76610Sstevel@tonic-gate
76620Sstevel@tonic-gate ud_clnt_info.priv_data = priv_data;
76630Sstevel@tonic-gate ud_clnt_info.priv_data_len = ud_ret_args.ud_ret_len;
76640Sstevel@tonic-gate
76650Sstevel@tonic-gate ud_clnt_info.redirect_infop = &ud_ret_args.ud_redirect;
76660Sstevel@tonic-gate
76670Sstevel@tonic-gate ibcm_process_sidr_req_cm_hdlr(ud_statep, cb_status, &ud_clnt_info,
76680Sstevel@tonic-gate sidr_status, sidr_repp);
76690Sstevel@tonic-gate
76700Sstevel@tonic-gate return (IBCM_SEND_SIDR_REP);
76710Sstevel@tonic-gate }
76720Sstevel@tonic-gate
76730Sstevel@tonic-gate /*ARGSUSED*/
76740Sstevel@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)76750Sstevel@tonic-gate ibcm_process_sidr_req_cm_hdlr(ibcm_ud_state_data_t *ud_statep,
76760Sstevel@tonic-gate ibt_cm_status_t cb_status, ibcm_ud_clnt_reply_info_t *ud_clnt_info,
76770Sstevel@tonic-gate ibt_sidr_status_t *sidr_status, ibcm_sidr_rep_msg_t *sidr_repp)
76780Sstevel@tonic-gate {
767911369SPramod.Gunjikar@Sun.COM void *sidr_rep_privp;
768011369SPramod.Gunjikar@Sun.COM
768111369SPramod.Gunjikar@Sun.COM IBTF_DPRINTF_L5(cmlog, "ibcm_process_sidr_req_cm_hdlr(%p, %x, "
768211369SPramod.Gunjikar@Sun.COM "%p, %p, %p)", ud_statep, cb_status, ud_clnt_info,
768311369SPramod.Gunjikar@Sun.COM sidr_status, sidr_repp);
768411369SPramod.Gunjikar@Sun.COM
76850Sstevel@tonic-gate if (cb_status == IBT_CM_DEFAULT)
76860Sstevel@tonic-gate cb_status = IBT_CM_REJECT;
76870Sstevel@tonic-gate
76880Sstevel@tonic-gate if (cb_status == IBT_CM_ACCEPT)
76890Sstevel@tonic-gate *sidr_status = IBT_CM_SREP_CHAN_VALID;
76900Sstevel@tonic-gate else if ((cb_status == IBT_CM_REJECT) ||
76910Sstevel@tonic-gate (cb_status == IBT_CM_NO_RESOURCE))
76920Sstevel@tonic-gate *sidr_status = IBT_CM_SREP_REJ;
76930Sstevel@tonic-gate else if (cb_status == IBT_CM_NO_CHANNEL)
76940Sstevel@tonic-gate *sidr_status = IBT_CM_SREP_NO_CHAN;
76950Sstevel@tonic-gate else if (cb_status == IBT_CM_REDIRECT)
76960Sstevel@tonic-gate *sidr_status = IBT_CM_SREP_REDIRECT;
76970Sstevel@tonic-gate else *sidr_status = IBT_CM_SREP_REJ;
76980Sstevel@tonic-gate
769911369SPramod.Gunjikar@Sun.COM /*
770011369SPramod.Gunjikar@Sun.COM * For Accept and reject copy the private data, if ud_clnt_info
770111369SPramod.Gunjikar@Sun.COM * priv_data does not point to SIDR Response private data. This
770211369SPramod.Gunjikar@Sun.COM * copy is needed for ibt_cm_ud_proceed().
770311369SPramod.Gunjikar@Sun.COM */
770411369SPramod.Gunjikar@Sun.COM sidr_rep_privp = (void *)(&(sidr_repp->sidr_rep_private_data[0]));
770511369SPramod.Gunjikar@Sun.COM if ((cb_status == IBT_CM_ACCEPT || cb_status == IBT_CM_REJECT) &&
770611369SPramod.Gunjikar@Sun.COM (ud_clnt_info->priv_data != sidr_rep_privp) &&
770711369SPramod.Gunjikar@Sun.COM ud_clnt_info->priv_data_len) {
770811369SPramod.Gunjikar@Sun.COM bcopy(ud_clnt_info->priv_data, sidr_rep_privp,
770911369SPramod.Gunjikar@Sun.COM min(ud_clnt_info->priv_data_len,
771011369SPramod.Gunjikar@Sun.COM IBT_SIDR_REP_PRIV_DATA_SZ));
771111369SPramod.Gunjikar@Sun.COM }
771211369SPramod.Gunjikar@Sun.COM
77130Sstevel@tonic-gate if (*sidr_status != IBT_CM_SREP_CHAN_VALID) {
7714557Shiremath IBTF_DPRINTF_L2(cmlog, "ibcm_process_sidr_req_cm_hdlr: "
77150Sstevel@tonic-gate "ud_handler return a failure: %d", cb_status);
77160Sstevel@tonic-gate if (*sidr_status == IBT_CM_SREP_REDIRECT) {
77170Sstevel@tonic-gate /*
77180Sstevel@tonic-gate * typecasting to ibcm_classportinfo_msg_t is ok, as addl info
77190Sstevel@tonic-gate * begins at offset 24 in sidr rep
77200Sstevel@tonic-gate */
77210Sstevel@tonic-gate ibcm_init_clp_to_mad(
77220Sstevel@tonic-gate (ibcm_classportinfo_msg_t *)
77230Sstevel@tonic-gate &sidr_repp->sidr_rep_class_port_info,
77240Sstevel@tonic-gate ud_clnt_info->redirect_infop);
77250Sstevel@tonic-gate }
77260Sstevel@tonic-gate return;
77270Sstevel@tonic-gate }
77280Sstevel@tonic-gate
77290Sstevel@tonic-gate
77300Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sidr_repp))
77310Sstevel@tonic-gate
77320Sstevel@tonic-gate sidr_repp->sidr_rep_qkey =
77330Sstevel@tonic-gate h2b32(ud_clnt_info->ud_qkey);
77340Sstevel@tonic-gate sidr_repp->sidr_rep_qpn_plus = h2b32(ud_clnt_info->ud_qpn << 8);
77350Sstevel@tonic-gate
77360Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sidr_repp))
77370Sstevel@tonic-gate }
77380Sstevel@tonic-gate
77390Sstevel@tonic-gate /*
77400Sstevel@tonic-gate * ibcm_sidr_rep_ud_handler:
77410Sstevel@tonic-gate * Invoke Client's UD handler For SIDR_REP msg
77420Sstevel@tonic-gate *
77430Sstevel@tonic-gate * INPUTS:
77440Sstevel@tonic-gate * ud_statep - ud_state pointer
77450Sstevel@tonic-gate * sidr_rep_msgp - SIDR_REQ message pointer
77460Sstevel@tonic-gate *
77470Sstevel@tonic-gate */
77480Sstevel@tonic-gate static void
ibcm_sidr_rep_ud_handler(ibcm_ud_state_data_t * ud_statep,ibcm_sidr_rep_msg_t * sidr_rep_msgp)77490Sstevel@tonic-gate ibcm_sidr_rep_ud_handler(ibcm_ud_state_data_t *ud_statep,
77500Sstevel@tonic-gate ibcm_sidr_rep_msg_t *sidr_rep_msgp)
77510Sstevel@tonic-gate {
77520Sstevel@tonic-gate ibt_cm_ud_event_t ud_event;
77530Sstevel@tonic-gate
77540Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_sidr_rep_ud_handler: ud_statep 0x%p",
77550Sstevel@tonic-gate ud_statep);
77560Sstevel@tonic-gate
77570Sstevel@tonic-gate /* Check first if UD client handler is valid */
77580Sstevel@tonic-gate if (ud_statep->ud_cm_handler == NULL) {
77590Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_sidr_rep_ud_handler: "
77600Sstevel@tonic-gate "cm_handler NULL");
77610Sstevel@tonic-gate return;
77620Sstevel@tonic-gate }
77630Sstevel@tonic-gate
77640Sstevel@tonic-gate /* Fill in ibt_cm_ud_event_t */
77650Sstevel@tonic-gate ud_event.cm_type = IBT_CM_UD_EVENT_SIDR_REP;
77660Sstevel@tonic-gate ud_event.cm_session_id = NULL;
77670Sstevel@tonic-gate ud_event.cm_event.sidr_rep.srep_status =
77680Sstevel@tonic-gate sidr_rep_msgp->sidr_rep_rep_status;
77690Sstevel@tonic-gate ud_event.cm_event.sidr_rep.srep_remote_qpn =
77700Sstevel@tonic-gate b2h32(sidr_rep_msgp->sidr_rep_qpn_plus) >> 8;
77710Sstevel@tonic-gate ud_event.cm_event.sidr_rep.srep_remote_qkey =
77720Sstevel@tonic-gate h2b32(sidr_rep_msgp->sidr_rep_qkey);
77730Sstevel@tonic-gate
77740Sstevel@tonic-gate if (ud_event.cm_event.sidr_rep.srep_status == IBT_CM_SREP_REDIRECT) {
77750Sstevel@tonic-gate /*
77760Sstevel@tonic-gate * typecasting to ibcm_classportinfo_msg_t is ok, as addl info
77770Sstevel@tonic-gate * begins at offset 24 in sidr rep
77780Sstevel@tonic-gate */
77790Sstevel@tonic-gate ibcm_init_clp_from_mad(
77800Sstevel@tonic-gate (ibcm_classportinfo_msg_t *)
77810Sstevel@tonic-gate sidr_rep_msgp->sidr_rep_class_port_info,
77820Sstevel@tonic-gate &ud_event.cm_event.sidr_rep.srep_redirect);
77830Sstevel@tonic-gate
77840Sstevel@tonic-gate if (ud_statep->ud_return_data != NULL)
77850Sstevel@tonic-gate bcopy(&ud_event.cm_event.sidr_rep.srep_redirect,
77860Sstevel@tonic-gate &ud_statep->ud_return_data->ud_redirect,
77870Sstevel@tonic-gate sizeof (ibt_redirect_info_t));
77880Sstevel@tonic-gate }
77890Sstevel@tonic-gate
77900Sstevel@tonic-gate ud_event.cm_priv_data = &(sidr_rep_msgp->sidr_rep_private_data[0]);
77910Sstevel@tonic-gate ud_event.cm_priv_data_len = IBT_SIDR_REP_PRIV_DATA_SZ;
77920Sstevel@tonic-gate
77930Sstevel@tonic-gate /* Invoke the client handler - inform only, so ignore retval */
77940Sstevel@tonic-gate (void) ud_statep->ud_cm_handler(ud_statep->ud_state_cm_private,
77950Sstevel@tonic-gate &ud_event, NULL, NULL, 0);
77960Sstevel@tonic-gate
77970Sstevel@tonic-gate
77980Sstevel@tonic-gate }
77990Sstevel@tonic-gate
78000Sstevel@tonic-gate /*
78010Sstevel@tonic-gate * ibcm_process_lap_msg:
78020Sstevel@tonic-gate * This call processes an incoming LAP message
78030Sstevel@tonic-gate *
78040Sstevel@tonic-gate * INPUTS:
78050Sstevel@tonic-gate * hcap - HCA entry pointer
78060Sstevel@tonic-gate * input_madp - incoming CM LAP MAD
78070Sstevel@tonic-gate * cm_mad_addr - Address information for the MAD
78080Sstevel@tonic-gate *
78090Sstevel@tonic-gate * RETURN VALUE: NONE
78100Sstevel@tonic-gate */
78110Sstevel@tonic-gate /* ARGSUSED */
78120Sstevel@tonic-gate void
ibcm_process_lap_msg(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)78130Sstevel@tonic-gate ibcm_process_lap_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
78140Sstevel@tonic-gate ibcm_mad_addr_t *cm_mad_addr)
78150Sstevel@tonic-gate {
78160Sstevel@tonic-gate ibcm_status_t state_lookup_status;
78170Sstevel@tonic-gate ibcm_lap_msg_t *lap_msg = (ibcm_lap_msg_t *)
78184703Shiremath (&input_madp[IBCM_MAD_HDR_SIZE]);
78190Sstevel@tonic-gate ibcm_apr_msg_t *apr_msg;
78200Sstevel@tonic-gate ibcm_state_data_t *statep = NULL;
78210Sstevel@tonic-gate
78220Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_lap_msg:");
78230Sstevel@tonic-gate
78240Sstevel@tonic-gate rw_enter(&hcap->hca_state_rwlock, RW_READER);
78250Sstevel@tonic-gate
78260Sstevel@tonic-gate state_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_LAP,
78270Sstevel@tonic-gate b2h32(lap_msg->lap_remote_comm_id), 0, 0, hcap, &statep);
78280Sstevel@tonic-gate
78290Sstevel@tonic-gate rw_exit(&hcap->hca_state_rwlock);
78300Sstevel@tonic-gate
78310Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_lap_msg: lookup status %x"
78320Sstevel@tonic-gate " com id %x", state_lookup_status,
78330Sstevel@tonic-gate b2h32(lap_msg->lap_remote_comm_id));
78340Sstevel@tonic-gate
78350Sstevel@tonic-gate if (state_lookup_status != IBCM_LOOKUP_EXISTS) {
78360Sstevel@tonic-gate /* Post a REJ message ? - but spec doesn't state so */
78370Sstevel@tonic-gate return;
78380Sstevel@tonic-gate }
78390Sstevel@tonic-gate
78400Sstevel@tonic-gate /* There is an existing state structure entry with active comid */
78410Sstevel@tonic-gate
78420Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_LAP);
78430Sstevel@tonic-gate
78440Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
78450Sstevel@tonic-gate
78460Sstevel@tonic-gate if ((statep->state == IBCM_STATE_ESTABLISHED) &&
78470Sstevel@tonic-gate (statep->ap_state == IBCM_AP_STATE_IDLE) &&
78480Sstevel@tonic-gate (statep->mode == IBCM_PASSIVE_MODE)) {
78490Sstevel@tonic-gate if ((statep->lapr_msg) &&
78500Sstevel@tonic-gate (IBCM_OUT_HDRP(statep->lapr_msg)->TransactionID ==
78510Sstevel@tonic-gate ((ib_mad_hdr_t *)(input_madp))->TransactionID))
78520Sstevel@tonic-gate ibcm_post_stored_apr_mad(statep, input_madp);
78530Sstevel@tonic-gate else {
78540Sstevel@tonic-gate ibcm_status_t clnt_response;
78550Sstevel@tonic-gate
78560Sstevel@tonic-gate statep->ap_state = IBCM_AP_STATE_LAP_RCVD;
78570Sstevel@tonic-gate statep->clnt_proceed = IBCM_BLOCK;
78580Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
78590Sstevel@tonic-gate
78600Sstevel@tonic-gate if (statep->lapr_msg == NULL) {
78610Sstevel@tonic-gate if (ibcm_alloc_out_msg(
78620Sstevel@tonic-gate statep->stored_reply_addr.ibmf_hdl,
78630Sstevel@tonic-gate &statep->lapr_msg, MAD_METHOD_SEND) !=
78640Sstevel@tonic-gate IBT_SUCCESS) {
78650Sstevel@tonic-gate
78660Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
78670Sstevel@tonic-gate statep->clnt_proceed = IBCM_FAIL;
78680Sstevel@tonic-gate cv_broadcast(&statep->block_client_cv);
78690Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
78700Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
78710Sstevel@tonic-gate return;
78720Sstevel@tonic-gate }
78730Sstevel@tonic-gate }
78740Sstevel@tonic-gate apr_msg = (ibcm_apr_msg_t *)
78750Sstevel@tonic-gate IBCM_OUT_MSGP(statep->lapr_msg);
78760Sstevel@tonic-gate IBCM_OUT_HDRP(statep->lapr_msg)->TransactionID =
78770Sstevel@tonic-gate ((ib_mad_hdr_t *)(input_madp))->TransactionID;
78780Sstevel@tonic-gate clnt_response =
78790Sstevel@tonic-gate ibcm_cep_state_lap(statep, lap_msg, apr_msg);
78800Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_lap_msg:"
78810Sstevel@tonic-gate " statep 0x%p apr status %d", statep,
78820Sstevel@tonic-gate apr_msg->apr_ap_status);
78830Sstevel@tonic-gate
78840Sstevel@tonic-gate if (clnt_response == IBCM_DEFER) {
78850Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_lap_msg: "
78860Sstevel@tonic-gate "client returned DEFER response");
78870Sstevel@tonic-gate return;
78880Sstevel@tonic-gate }
78890Sstevel@tonic-gate
78900Sstevel@tonic-gate /* fail any blocked cm proceed api calls - client bug */
78910Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
78920Sstevel@tonic-gate statep->clnt_proceed = IBCM_FAIL;
78930Sstevel@tonic-gate cv_broadcast(&statep->block_client_cv);
78940Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
78950Sstevel@tonic-gate
78960Sstevel@tonic-gate ibcm_post_apr_mad(statep);
78970Sstevel@tonic-gate return;
78980Sstevel@tonic-gate }
78990Sstevel@tonic-gate } /* drop the LAP MAD in any other state */
79000Sstevel@tonic-gate
79010Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep); /* decrement the ref count */
79020Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
79030Sstevel@tonic-gate }
79040Sstevel@tonic-gate
79050Sstevel@tonic-gate /*
79060Sstevel@tonic-gate * ibcm_post_stored_apr_mad:
79070Sstevel@tonic-gate * Builds and posts an APR MAD from the stored APR MAD
79080Sstevel@tonic-gate *
79090Sstevel@tonic-gate * INPUTS:
79100Sstevel@tonic-gate * statep - pointer to ibcm_state_data_t
79110Sstevel@tonic-gate * input_madp - pointer to incoming lap mad
79120Sstevel@tonic-gate *
79130Sstevel@tonic-gate * RETURN VALUE:
79140Sstevel@tonic-gate * NONE
79150Sstevel@tonic-gate *
79160Sstevel@tonic-gate * This function is called holding the state mutex, and returns
79170Sstevel@tonic-gate * holding the state mutex
79180Sstevel@tonic-gate */
79190Sstevel@tonic-gate static void
ibcm_post_stored_apr_mad(ibcm_state_data_t * statep,uint8_t * input_madp)79200Sstevel@tonic-gate ibcm_post_stored_apr_mad(ibcm_state_data_t *statep, uint8_t *input_madp)
79210Sstevel@tonic-gate {
79220Sstevel@tonic-gate ibmf_msg_t *ibmf_apr_msg;
79230Sstevel@tonic-gate uint8_t apr_msg[IBCM_MSG_SIZE];
79240Sstevel@tonic-gate
79250Sstevel@tonic-gate /* Need to make a copy, else an incoming new LAP may modify lapr_msg */
79260Sstevel@tonic-gate bcopy(IBCM_OUT_MSGP(statep->lapr_msg), apr_msg, IBCM_MSG_SIZE);
79270Sstevel@tonic-gate
79280Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
79290Sstevel@tonic-gate
79300Sstevel@tonic-gate if (ibcm_alloc_out_msg(statep->stored_reply_addr.ibmf_hdl,
79310Sstevel@tonic-gate &ibmf_apr_msg, MAD_METHOD_SEND) != IBT_SUCCESS) {
79320Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_post_stored_apr_mad: "
79330Sstevel@tonic-gate "ibcm_alloc_out_msg failed");
79340Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
79350Sstevel@tonic-gate return;
79360Sstevel@tonic-gate }
79370Sstevel@tonic-gate
79380Sstevel@tonic-gate bcopy(apr_msg, IBCM_OUT_MSGP(ibmf_apr_msg), IBCM_MSG_SIZE);
79390Sstevel@tonic-gate
79400Sstevel@tonic-gate IBCM_OUT_HDRP(ibmf_apr_msg)->AttributeID =
79414703Shiremath h2b16(IBCM_INCOMING_APR + IBCM_ATTR_BASE_ID);
79420Sstevel@tonic-gate
79430Sstevel@tonic-gate IBCM_OUT_HDRP(ibmf_apr_msg)->TransactionID =
79440Sstevel@tonic-gate ((ib_mad_hdr_t *)(input_madp))->TransactionID;
79450Sstevel@tonic-gate
79460Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_APR);
79470Sstevel@tonic-gate
79480Sstevel@tonic-gate ibcm_post_rc_mad(statep, ibmf_apr_msg, ibcm_post_stored_apr_complete,
79490Sstevel@tonic-gate ibmf_apr_msg);
79500Sstevel@tonic-gate
79510Sstevel@tonic-gate /* ibcm_free_out_msg done in ibcm_post_stored_apr_complete */
79520Sstevel@tonic-gate
79530Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
79540Sstevel@tonic-gate }
79550Sstevel@tonic-gate
79560Sstevel@tonic-gate /*
79570Sstevel@tonic-gate * ibcm_cep_state_lap:
79580Sstevel@tonic-gate * This call processes an incoming LAP message for cep state
79590Sstevel@tonic-gate * transition and invoking cm handler
79600Sstevel@tonic-gate *
79610Sstevel@tonic-gate * INPUTS:
79620Sstevel@tonic-gate * statep - pointer to ibcm_state_data_t
79630Sstevel@tonic-gate * lap_msg - lap msg received
79640Sstevel@tonic-gate * apr_msg - apr msg to be sent
79650Sstevel@tonic-gate *
79660Sstevel@tonic-gate * RETURN VALUE: NONE
79670Sstevel@tonic-gate */
79680Sstevel@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)79690Sstevel@tonic-gate ibcm_cep_state_lap(ibcm_state_data_t *statep, ibcm_lap_msg_t *lap_msg,
79700Sstevel@tonic-gate ibcm_apr_msg_t *apr_msg)
79710Sstevel@tonic-gate {
79720Sstevel@tonic-gate ibt_cm_event_t event;
79730Sstevel@tonic-gate ibt_cm_return_args_t ret_args;
79740Sstevel@tonic-gate ibt_cm_status_t cb_status;
79750Sstevel@tonic-gate ibcm_clnt_reply_info_t clnt_info;
79760Sstevel@tonic-gate
79770Sstevel@tonic-gate
79780Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_lap: statep 0x%p", statep);
79790Sstevel@tonic-gate
79800Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*apr_msg))
79810Sstevel@tonic-gate
79820Sstevel@tonic-gate /* If APM is not supported, return error */
79830Sstevel@tonic-gate if (!(statep->hcap->hca_caps & IBT_HCA_AUTO_PATH_MIG)) {
79840Sstevel@tonic-gate apr_msg->apr_ap_status = IBT_CM_AP_NOT_SUPPORTED;
79850Sstevel@tonic-gate return (IBCM_SEND_APR);
79860Sstevel@tonic-gate }
79870Sstevel@tonic-gate
79880Sstevel@tonic-gate if (statep->local_qpn !=
79890Sstevel@tonic-gate b2h32(lap_msg->lap_remote_qpn_eecn_plus) >> 8) {
79900Sstevel@tonic-gate apr_msg->apr_ap_status = IBT_CM_AP_REJECT;
79910Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_lap: local_qpn %x does "
79920Sstevel@tonic-gate "not match remote's remote_qpn %x", statep->local_qpn,
79930Sstevel@tonic-gate b2h32(lap_msg->lap_remote_qpn_eecn_plus) >> 8);
79940Sstevel@tonic-gate return (IBCM_SEND_APR);
79950Sstevel@tonic-gate }
79960Sstevel@tonic-gate
79970Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*apr_msg))
79980Sstevel@tonic-gate
79990Sstevel@tonic-gate /* Fill up the event */
80000Sstevel@tonic-gate bzero(&event, sizeof (event));
80010Sstevel@tonic-gate event.cm_type = IBT_CM_EVENT_LAP_RCV;
80020Sstevel@tonic-gate event.cm_channel = statep->channel;
80030Sstevel@tonic-gate event.cm_session_id = statep;
80040Sstevel@tonic-gate event.cm_priv_data = lap_msg->lap_private_data;
80050Sstevel@tonic-gate event.cm_priv_data_len = IBT_LAP_PRIV_DATA_SZ;
80060Sstevel@tonic-gate event.cm_event.lap.lap_timeout = ibt_ib2usec(
80070Sstevel@tonic-gate ((uint8_t *)&lap_msg->lap_remote_qpn_eecn_plus)[3] >> 3);
80080Sstevel@tonic-gate
80090Sstevel@tonic-gate ibcm_fill_adds_from_lap(&event.cm_event.lap.lap_alternate_path,
80100Sstevel@tonic-gate lap_msg, IBCM_PASSIVE_MODE);
80110Sstevel@tonic-gate
80120Sstevel@tonic-gate cb_status = statep->cm_handler(statep->state_cm_private, &event,
80130Sstevel@tonic-gate &ret_args, apr_msg->apr_private_data, IBT_APR_PRIV_DATA_SZ);
80140Sstevel@tonic-gate
80150Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_cep_state_lap: cb_status = %d", cb_status);
80160Sstevel@tonic-gate if (cb_status == IBT_CM_DEFER) {
80170Sstevel@tonic-gate
80180Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(statep->defer_cm_msg))
80190Sstevel@tonic-gate
80200Sstevel@tonic-gate if (statep->defer_cm_msg == NULL)
80210Sstevel@tonic-gate statep->defer_cm_msg =
80220Sstevel@tonic-gate kmem_zalloc(IBCM_MSG_SIZE, KM_SLEEP);
80230Sstevel@tonic-gate bcopy(lap_msg, statep->defer_cm_msg, IBCM_MSG_SIZE);
80240Sstevel@tonic-gate
80250Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(statep->defer_cm_msg))
80260Sstevel@tonic-gate
80270Sstevel@tonic-gate /* unblock any blocked cm proceed api calls */
80280Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
80290Sstevel@tonic-gate statep->clnt_proceed = IBCM_UNBLOCK;
80300Sstevel@tonic-gate cv_broadcast(&statep->block_client_cv);
80310Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
80320Sstevel@tonic-gate
80330Sstevel@tonic-gate return (IBCM_DEFER);
80340Sstevel@tonic-gate }
80350Sstevel@tonic-gate
80360Sstevel@tonic-gate clnt_info.reply_event = (ibt_cm_proceed_reply_t *)&ret_args.cm_ret;
80370Sstevel@tonic-gate clnt_info.priv_data = NULL;
80380Sstevel@tonic-gate clnt_info.priv_data_len = 0;
80390Sstevel@tonic-gate
80400Sstevel@tonic-gate ibcm_process_cep_lap_cm_hdlr(statep, cb_status, &clnt_info, lap_msg,
80410Sstevel@tonic-gate apr_msg);
80420Sstevel@tonic-gate return (IBCM_SEND_APR);
80430Sstevel@tonic-gate }
80440Sstevel@tonic-gate
80450Sstevel@tonic-gate /*
80460Sstevel@tonic-gate * ibcm_fill_adds_from_lap:
80470Sstevel@tonic-gate * Fills the address vector (part of event structure passed to
80480Sstevel@tonic-gate * client) from the LAP message
80490Sstevel@tonic-gate *
80500Sstevel@tonic-gate * INPUTS:
80510Sstevel@tonic-gate * adds - Address vector to be filled-in
80520Sstevel@tonic-gate * lap_msg - LAP message used to fill the address vector
80530Sstevel@tonic-gate *
80540Sstevel@tonic-gate * RETURN VALUE: NONE
80550Sstevel@tonic-gate */
80560Sstevel@tonic-gate static void
ibcm_fill_adds_from_lap(ibt_adds_vect_t * adds,ibcm_lap_msg_t * lap_msg,ibcm_mode_t mode)80570Sstevel@tonic-gate ibcm_fill_adds_from_lap(ibt_adds_vect_t *adds, ibcm_lap_msg_t *lap_msg,
80580Sstevel@tonic-gate ibcm_mode_t mode)
80590Sstevel@tonic-gate {
80600Sstevel@tonic-gate adds->av_srvl = lap_msg->lap_alt_sl_plus >> 4;
80610Sstevel@tonic-gate if (mode == IBCM_PASSIVE_MODE) {
80620Sstevel@tonic-gate adds->av_dgid.gid_prefix =
80630Sstevel@tonic-gate b2h64(lap_msg->lap_alt_l_port_gid.gid_prefix);
80640Sstevel@tonic-gate adds->av_dgid.gid_guid =
80650Sstevel@tonic-gate b2h64(lap_msg->lap_alt_l_port_gid.gid_guid);
80660Sstevel@tonic-gate adds->av_sgid.gid_prefix =
80670Sstevel@tonic-gate b2h64(lap_msg->lap_alt_r_port_gid.gid_prefix);
80680Sstevel@tonic-gate adds->av_sgid.gid_guid =
80690Sstevel@tonic-gate b2h64(lap_msg->lap_alt_r_port_gid.gid_guid);
80700Sstevel@tonic-gate adds->av_dlid = b2h16(lap_msg->lap_alt_l_port_lid);
80710Sstevel@tonic-gate } else {
80720Sstevel@tonic-gate adds->av_sgid.gid_prefix =
80730Sstevel@tonic-gate b2h64(lap_msg->lap_alt_l_port_gid.gid_prefix);
80740Sstevel@tonic-gate adds->av_sgid.gid_guid =
80750Sstevel@tonic-gate b2h64(lap_msg->lap_alt_l_port_gid.gid_guid);
80760Sstevel@tonic-gate adds->av_dgid.gid_prefix =
80770Sstevel@tonic-gate b2h64(lap_msg->lap_alt_r_port_gid.gid_prefix);
80780Sstevel@tonic-gate adds->av_dgid.gid_guid =
80790Sstevel@tonic-gate b2h64(lap_msg->lap_alt_r_port_gid.gid_guid);
80800Sstevel@tonic-gate adds->av_dlid = b2h16(lap_msg->lap_alt_r_port_lid);
80810Sstevel@tonic-gate }
80820Sstevel@tonic-gate
8083557Shiremath IBTF_DPRINTF_L4(cmlog, "ibcm_fill_adds_from_lap: SGID=(%llX:%llX)",
80840Sstevel@tonic-gate adds->av_sgid.gid_prefix, adds->av_sgid.gid_guid);
80850Sstevel@tonic-gate
8086557Shiremath IBTF_DPRINTF_L4(cmlog, "ibcm_fill_adds_from_lap: DGID=(%llX:%llX)",
80870Sstevel@tonic-gate adds->av_dgid.gid_prefix, adds->av_dgid.gid_guid);
80880Sstevel@tonic-gate
80890Sstevel@tonic-gate adds->av_srate = lap_msg->lap_alt_srate_plus & 0x3f;
80900Sstevel@tonic-gate
80910Sstevel@tonic-gate /* next copy off the GRH info if it exists */
80920Sstevel@tonic-gate if ((lap_msg->lap_alt_sl_plus & 0x8) == 0) {
80930Sstevel@tonic-gate uint32_t flow_tclass = b2h32(lap_msg->lap_alt_flow_label_plus);
80940Sstevel@tonic-gate
80950Sstevel@tonic-gate adds->av_send_grh = B_TRUE;
80960Sstevel@tonic-gate adds->av_flow = flow_tclass >> 12;
80970Sstevel@tonic-gate adds->av_tclass = flow_tclass & 0xff;
80980Sstevel@tonic-gate adds->av_hop = lap_msg->lap_alt_hop_limit;
80990Sstevel@tonic-gate } else {
81000Sstevel@tonic-gate adds->av_send_grh = B_FALSE;
81010Sstevel@tonic-gate }
81020Sstevel@tonic-gate }
81030Sstevel@tonic-gate
81040Sstevel@tonic-gate /*
81050Sstevel@tonic-gate * ibcm_process_cep_lap_cm_hdlr:
81060Sstevel@tonic-gate * Processes the cm handler response for an incoming LAP.
81070Sstevel@tonic-gate */
81080Sstevel@tonic-gate
81090Sstevel@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)81100Sstevel@tonic-gate ibcm_process_cep_lap_cm_hdlr(ibcm_state_data_t *statep,
81110Sstevel@tonic-gate ibt_cm_status_t cb_status, ibcm_clnt_reply_info_t *clnt_info,
81120Sstevel@tonic-gate ibcm_lap_msg_t *lap_msg, ibcm_apr_msg_t *apr_msg)
81130Sstevel@tonic-gate {
81140Sstevel@tonic-gate ibtl_cm_hca_port_t port;
81150Sstevel@tonic-gate ibt_qp_query_attr_t qp_attrs;
81160Sstevel@tonic-gate ibt_cep_modify_flags_t cep_flags;
81170Sstevel@tonic-gate ibt_status_t status;
81180Sstevel@tonic-gate ibt_adds_vect_t *adds;
81190Sstevel@tonic-gate
81200Sstevel@tonic-gate if (cb_status == IBT_CM_DEFAULT)
81210Sstevel@tonic-gate cb_status = IBT_CM_REJECT;
81220Sstevel@tonic-gate
81230Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*apr_msg))
81240Sstevel@tonic-gate
81250Sstevel@tonic-gate /* verify status */
81260Sstevel@tonic-gate apr_msg->apr_addl_info_len = 0;
81270Sstevel@tonic-gate if (cb_status == IBT_CM_ACCEPT) {
81280Sstevel@tonic-gate apr_msg->apr_ap_status = IBT_CM_AP_LOADED;
81290Sstevel@tonic-gate } else if (cb_status == IBT_CM_REJECT) {
81300Sstevel@tonic-gate apr_msg->apr_ap_status = IBT_CM_AP_REJECT;
81310Sstevel@tonic-gate } else if (cb_status == IBT_CM_REDIRECT) {
81320Sstevel@tonic-gate apr_msg->apr_ap_status = IBT_CM_AP_REDIRECT;
81330Sstevel@tonic-gate /* copy redirect info to APR */
81340Sstevel@tonic-gate apr_msg->apr_addl_info_len = sizeof (ibcm_classportinfo_msg_t);
81350Sstevel@tonic-gate ibcm_init_clp_to_mad(
81360Sstevel@tonic-gate (ibcm_classportinfo_msg_t *)apr_msg->apr_addl_info,
81370Sstevel@tonic-gate &clnt_info->reply_event->apr);
81380Sstevel@tonic-gate } else if (cb_status == IBT_CM_NO_RESOURCE) {
81390Sstevel@tonic-gate apr_msg->apr_ap_status = IBT_CM_AP_REJECT;
81400Sstevel@tonic-gate } else {
81410Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_lap_cm_hdlr: statep %p"
81420Sstevel@tonic-gate " Client handler unexpected return %x", statep, cb_status);
81430Sstevel@tonic-gate cb_status = IBT_CM_REJECT;
81440Sstevel@tonic-gate apr_msg->apr_ap_status = IBT_CM_AP_REJECT;
81450Sstevel@tonic-gate }
81460Sstevel@tonic-gate
81470Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_cep_lap_cm_hdlr: statep 0x%p "
81480Sstevel@tonic-gate " client handler returned %d, apr status %d", statep, cb_status,
81490Sstevel@tonic-gate apr_msg->apr_ap_status);
81500Sstevel@tonic-gate
81510Sstevel@tonic-gate /* copy private data to outgoing apr, specified via priv_data */
81520Sstevel@tonic-gate if ((clnt_info->priv_data != NULL) && (clnt_info->priv_data_len > 0))
81530Sstevel@tonic-gate bcopy(clnt_info->priv_data, apr_msg->apr_private_data,
81540Sstevel@tonic-gate min(clnt_info->priv_data_len, IBT_APR_PRIV_DATA_SZ));
81550Sstevel@tonic-gate
81560Sstevel@tonic-gate if (cb_status != IBT_CM_ACCEPT)
81570Sstevel@tonic-gate return;
81580Sstevel@tonic-gate
81590Sstevel@tonic-gate if (ibt_query_qp(statep->channel, &qp_attrs) != IBT_SUCCESS ||
81600Sstevel@tonic-gate (qp_attrs.qp_info.qp_state != IBT_STATE_RTS &&
81610Sstevel@tonic-gate qp_attrs.qp_info.qp_state != IBT_STATE_SQD)) {
81620Sstevel@tonic-gate apr_msg->apr_ap_status = IBT_CM_AP_REJECT;
81630Sstevel@tonic-gate return;
81640Sstevel@tonic-gate }
81650Sstevel@tonic-gate
81660Sstevel@tonic-gate /* Fill up input args for ibt_modify_qp */
81670Sstevel@tonic-gate cep_flags = IBT_CEP_SET_ALT_PATH | IBT_CEP_SET_STATE;
81680Sstevel@tonic-gate
81690Sstevel@tonic-gate /* do RTS=>RTS or SQD=>SQD. The next line is needed for RTS=>RTS. */
81700Sstevel@tonic-gate qp_attrs.qp_info.qp_current_state = qp_attrs.qp_info.qp_state;
81710Sstevel@tonic-gate
81720Sstevel@tonic-gate adds = &IBCM_QP_RC(qp_attrs).rc_alt_path.cep_adds_vect;
81730Sstevel@tonic-gate ibcm_fill_adds_from_lap(adds, lap_msg, IBCM_PASSIVE_MODE);
81740Sstevel@tonic-gate
81750Sstevel@tonic-gate if ((status = ibtl_cm_get_hca_port(adds->av_sgid,
81760Sstevel@tonic-gate statep->local_hca_guid, &port)) != IBT_SUCCESS) {
81770Sstevel@tonic-gate
81780Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_lap_cm_hdlr:"
81790Sstevel@tonic-gate " ibtl_cm_get_hca_port failed status %d", status);
81800Sstevel@tonic-gate apr_msg->apr_ap_status = IBT_CM_AP_REJECT;
81810Sstevel@tonic-gate return;
81820Sstevel@tonic-gate }
81830Sstevel@tonic-gate
81840Sstevel@tonic-gate IBCM_QP_RC(qp_attrs).rc_alt_path.cep_hca_port_num = port.hp_port;
81850Sstevel@tonic-gate
8186557Shiremath IBTF_DPRINTF_L4(cmlog, "ibcm_process_cep_lap_cm_hdlr: statep 0x%p "
81870Sstevel@tonic-gate "gid = (%llx, %llx), port_num = %d", statep,
81880Sstevel@tonic-gate IBCM_QP_RC(qp_attrs).rc_alt_path.cep_adds_vect.av_dgid.
81890Sstevel@tonic-gate gid_prefix,
81900Sstevel@tonic-gate IBCM_QP_RC(qp_attrs).rc_alt_path.cep_adds_vect.av_dgid.gid_guid,
81910Sstevel@tonic-gate port.hp_port);
81920Sstevel@tonic-gate
81930Sstevel@tonic-gate /* The pkey is same as the primary path */
81940Sstevel@tonic-gate status = ibt_pkey2index_byguid(statep->local_hca_guid,
81950Sstevel@tonic-gate port.hp_port, statep->pkey,
81960Sstevel@tonic-gate &IBCM_QP_RC(qp_attrs).rc_alt_path.cep_pkey_ix);
81970Sstevel@tonic-gate
81980Sstevel@tonic-gate if (status != IBT_SUCCESS) {
81990Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_lap_cm_hdlr: statep %p"
82000Sstevel@tonic-gate " ibt_pkey2index_byguid failed %d", statep, status);
82010Sstevel@tonic-gate apr_msg->apr_ap_status = IBT_CM_AP_REJECT;
82020Sstevel@tonic-gate return;
82030Sstevel@tonic-gate }
82040Sstevel@tonic-gate
82050Sstevel@tonic-gate IBCM_QP_RC(qp_attrs).rc_alt_path.cep_timeout =
82060Sstevel@tonic-gate lap_msg->lap_alt_local_acktime_plus >> 3;
82070Sstevel@tonic-gate
82080Sstevel@tonic-gate qp_attrs.qp_info.qp_trans = IBT_RC_SRV;
82090Sstevel@tonic-gate if (IBCM_QP_RC(qp_attrs).rc_mig_state == IBT_STATE_MIGRATED) {
82101093Shiremath IBTF_DPRINTF_L3(cmlog, "ibcm_process_cep_lap_cm_hdlr: statep %p"
82111093Shiremath ": rearming APM", statep);
82120Sstevel@tonic-gate cep_flags |= IBT_CEP_SET_MIG;
82130Sstevel@tonic-gate IBCM_QP_RC(qp_attrs).rc_mig_state = IBT_STATE_REARMED;
82140Sstevel@tonic-gate }
82150Sstevel@tonic-gate status = ibt_modify_qp(statep->channel, cep_flags, &qp_attrs.qp_info,
82160Sstevel@tonic-gate NULL);
82170Sstevel@tonic-gate
82180Sstevel@tonic-gate if (status != IBT_SUCCESS) {
82190Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_SET_ALT_FAIL);
82200Sstevel@tonic-gate } else
82210Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_SET_ALT);
82220Sstevel@tonic-gate
82230Sstevel@tonic-gate #ifdef DEBUG
82240Sstevel@tonic-gate (void) ibt_query_qp(statep->channel, &qp_attrs);
82250Sstevel@tonic-gate print_modify_qp("PASSIVE LAP QUERY", statep->channel,
82260Sstevel@tonic-gate cep_flags, &qp_attrs.qp_info);
82270Sstevel@tonic-gate #endif
82280Sstevel@tonic-gate
82290Sstevel@tonic-gate if (status != IBT_SUCCESS) {
82300Sstevel@tonic-gate apr_msg->apr_ap_status = IBT_CM_AP_REJECT;
82310Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_lap_cm_hdlr:"
82320Sstevel@tonic-gate " ibt_modify_qp() returned = %d", status);
82330Sstevel@tonic-gate return;
82340Sstevel@tonic-gate }
82350Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*apr_msg))
82360Sstevel@tonic-gate }
82370Sstevel@tonic-gate
82380Sstevel@tonic-gate
82390Sstevel@tonic-gate /*
82400Sstevel@tonic-gate * ibcm_post_apr_mad:
82410Sstevel@tonic-gate * Posts a APR MAD and starts timer
82420Sstevel@tonic-gate *
82430Sstevel@tonic-gate * INPUTS:
82440Sstevel@tonic-gate * statep - state pointer
82450Sstevel@tonic-gate *
82460Sstevel@tonic-gate * RETURN VALUE: NONE
82470Sstevel@tonic-gate */
82480Sstevel@tonic-gate void
ibcm_post_apr_mad(ibcm_state_data_t * statep)82490Sstevel@tonic-gate ibcm_post_apr_mad(ibcm_state_data_t *statep)
82500Sstevel@tonic-gate {
82510Sstevel@tonic-gate ibcm_apr_msg_t *apr_msgp;
82520Sstevel@tonic-gate
82530Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*apr_msgp))
82540Sstevel@tonic-gate
82550Sstevel@tonic-gate apr_msgp = (ibcm_apr_msg_t *)IBCM_OUT_MSGP(statep->lapr_msg);
82560Sstevel@tonic-gate
82570Sstevel@tonic-gate apr_msgp->apr_local_comm_id = h2b32(statep->local_comid);
82580Sstevel@tonic-gate apr_msgp->apr_remote_comm_id = h2b32(statep->remote_comid);
82590Sstevel@tonic-gate IBCM_OUT_HDRP(statep->lapr_msg)->AttributeID =
82600Sstevel@tonic-gate h2b16(IBCM_INCOMING_APR + IBCM_ATTR_BASE_ID);
82610Sstevel@tonic-gate
82620Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*apr_msgp))
82630Sstevel@tonic-gate
82640Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_APR);
82650Sstevel@tonic-gate
82660Sstevel@tonic-gate ibcm_post_rc_mad(statep, statep->lapr_msg, ibcm_post_apr_complete,
82670Sstevel@tonic-gate statep);
82680Sstevel@tonic-gate }
82690Sstevel@tonic-gate
82700Sstevel@tonic-gate /*
82710Sstevel@tonic-gate * ibcm_process_apr_msg:
82720Sstevel@tonic-gate * This call processes an incoming APR message
82730Sstevel@tonic-gate *
82740Sstevel@tonic-gate * INPUTS:
82750Sstevel@tonic-gate * hcap - HCA entry pointer
82760Sstevel@tonic-gate * input_madp - incoming CM SIDR REP MAD
82770Sstevel@tonic-gate * cm_mad_addr - Address information for the MAD to be posted
82780Sstevel@tonic-gate *
82790Sstevel@tonic-gate * RETURN VALUE: NONE
82800Sstevel@tonic-gate */
82810Sstevel@tonic-gate /*ARGSUSED*/
82820Sstevel@tonic-gate void
ibcm_process_apr_msg(ibcm_hca_info_t * hcap,uint8_t * input_madp,ibcm_mad_addr_t * cm_mad_addr)82830Sstevel@tonic-gate ibcm_process_apr_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
82840Sstevel@tonic-gate ibcm_mad_addr_t *cm_mad_addr)
82850Sstevel@tonic-gate {
82860Sstevel@tonic-gate ibcm_status_t state_lookup_status;
82870Sstevel@tonic-gate ibcm_apr_msg_t *apr_msg = (ibcm_apr_msg_t *)
82884703Shiremath (&input_madp[IBCM_MAD_HDR_SIZE]);
82890Sstevel@tonic-gate ibcm_state_data_t *statep = NULL;
82900Sstevel@tonic-gate
82910Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_apr_msg:");
82920Sstevel@tonic-gate
82930Sstevel@tonic-gate rw_enter(&hcap->hca_state_rwlock, RW_READER);
82940Sstevel@tonic-gate state_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_APR,
82950Sstevel@tonic-gate b2h32(apr_msg->apr_remote_comm_id), 0, 0, hcap, &statep);
82960Sstevel@tonic-gate rw_exit(&hcap->hca_state_rwlock);
82970Sstevel@tonic-gate
82980Sstevel@tonic-gate if (state_lookup_status != IBCM_LOOKUP_EXISTS) {
82990Sstevel@tonic-gate return;
83000Sstevel@tonic-gate }
83010Sstevel@tonic-gate
83020Sstevel@tonic-gate /* if transaction id is not as expected, drop the APR mad */
83030Sstevel@tonic-gate if (IBCM_OUT_HDRP(statep->lapr_msg)->TransactionID !=
83040Sstevel@tonic-gate ((ib_mad_hdr_t *)(input_madp))->TransactionID) {
83050Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
83060Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep);
83070Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
83080Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_process_apr_msg: statep 0x%p"
83090Sstevel@tonic-gate ": rcv'd APR MAD with comid 0x%x",
83100Sstevel@tonic-gate statep, b2h32(apr_msg->apr_remote_comm_id));
83110Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_process_apr_msg: "
83120Sstevel@tonic-gate "tid expected 0x%llX tid found 0x%llX",
83130Sstevel@tonic-gate b2h64(IBCM_OUT_HDRP(statep->lapr_msg)->TransactionID),
83140Sstevel@tonic-gate b2h64(((ib_mad_hdr_t *)(input_madp))->TransactionID));
83150Sstevel@tonic-gate return;
83160Sstevel@tonic-gate }
83170Sstevel@tonic-gate
83180Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_process_apr_msg: statep 0x%p "
83190Sstevel@tonic-gate "lookup status %x", statep, state_lookup_status);
83200Sstevel@tonic-gate
83210Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
83220Sstevel@tonic-gate
83230Sstevel@tonic-gate if (!((statep->state == IBCM_STATE_ESTABLISHED) &&
83240Sstevel@tonic-gate ((statep->ap_state == IBCM_AP_STATE_LAP_SENT) ||
83250Sstevel@tonic-gate (statep->ap_state == IBCM_AP_STATE_MRA_LAP_RCVD)))) {
83260Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep); /* decrement the ref count */
83270Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
83280Sstevel@tonic-gate return;
83290Sstevel@tonic-gate }
83300Sstevel@tonic-gate
83310Sstevel@tonic-gate statep->ap_state = IBCM_AP_STATE_APR_RCVD;
83320Sstevel@tonic-gate
83330Sstevel@tonic-gate /* cancel the LAP timer */
83340Sstevel@tonic-gate if (statep->timerid != 0) {
83350Sstevel@tonic-gate timeout_id_t timer_val;
83360Sstevel@tonic-gate timer_val = statep->timerid;
83370Sstevel@tonic-gate statep->timerid = 0;
83380Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
83390Sstevel@tonic-gate (void) untimeout(timer_val);
83400Sstevel@tonic-gate } else {
83410Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
83420Sstevel@tonic-gate }
83430Sstevel@tonic-gate
83440Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_APR);
83450Sstevel@tonic-gate
83460Sstevel@tonic-gate ibcm_cep_state_apr(statep,
83470Sstevel@tonic-gate (ibcm_lap_msg_t *)IBCM_OUT_MSGP(statep->lapr_msg), apr_msg);
83480Sstevel@tonic-gate
83490Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
83500Sstevel@tonic-gate statep->ap_state = IBCM_AP_STATE_IDLE;
83510Sstevel@tonic-gate
83520Sstevel@tonic-gate /* unblock any DREQ threads and close channels */
83530Sstevel@tonic-gate cv_broadcast(&statep->block_mad_cv);
83540Sstevel@tonic-gate
83550Sstevel@tonic-gate statep->ap_done = B_TRUE;
83560Sstevel@tonic-gate
83570Sstevel@tonic-gate /* wake up blocking ibt_set_alt_path */
83580Sstevel@tonic-gate cv_broadcast(&statep->block_client_cv);
83590Sstevel@tonic-gate
83600Sstevel@tonic-gate IBCM_REF_CNT_DECR(statep); /* decrement the ref count */
83610Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
83620Sstevel@tonic-gate }
83630Sstevel@tonic-gate
83640Sstevel@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)83650Sstevel@tonic-gate ibcm_set_apr_arej(int ap_status, ibcm_apr_msg_t *apr_msgp,
83660Sstevel@tonic-gate ibt_arej_info_t *ari, boolean_t *ari_valid)
83670Sstevel@tonic-gate {
83686709Shiremath uint8_t ari_len = apr_msgp->apr_addl_info_len;
83690Sstevel@tonic-gate ibcm_classportinfo_msg_t tclp;
83700Sstevel@tonic-gate
83710Sstevel@tonic-gate *ari_valid = B_FALSE;
83720Sstevel@tonic-gate
8373557Shiremath IBTF_DPRINTF_L3(cmlog, "ibcm_set_apr_arej: apr_status = %d "
8374557Shiremath "ari_len = %d", ap_status, ari_len);
8375557Shiremath
83760Sstevel@tonic-gate _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ari))
83770Sstevel@tonic-gate
83780Sstevel@tonic-gate switch (ap_status) {
83790Sstevel@tonic-gate case IBT_CM_AP_REDIRECT:
83800Sstevel@tonic-gate if (ari_len < sizeof (ibcm_classportinfo_msg_t))
83810Sstevel@tonic-gate break;
83820Sstevel@tonic-gate *ari_valid = B_TRUE;
83830Sstevel@tonic-gate bcopy(apr_msgp->apr_addl_info, &tclp, sizeof (tclp));
83840Sstevel@tonic-gate ibcm_init_clp_from_mad(&tclp, &ari->ari_redirect);
83850Sstevel@tonic-gate break;
83860Sstevel@tonic-gate case IBT_CM_AP_RLID_REJECTED:
83870Sstevel@tonic-gate if (ari_len < sizeof (ib_lid_t))
83880Sstevel@tonic-gate break;
83890Sstevel@tonic-gate *ari_valid = B_TRUE;
83900Sstevel@tonic-gate bcopy(apr_msgp->apr_addl_info, &ari->ari_lid,
83910Sstevel@tonic-gate sizeof (ib_lid_t));
83920Sstevel@tonic-gate ari->ari_lid = b2h16(ari->ari_lid);
83930Sstevel@tonic-gate break;
83940Sstevel@tonic-gate case IBT_CM_AP_RGID_REJECTED:
83950Sstevel@tonic-gate if (ari_len < sizeof (ib_gid_t))
83960Sstevel@tonic-gate break;
83970Sstevel@tonic-gate *ari_valid = B_TRUE;
83980Sstevel@tonic-gate bcopy(apr_msgp->apr_addl_info, &ari->ari_gid,
83990Sstevel@tonic-gate sizeof (ib_gid_t));
84000Sstevel@tonic-gate ari->ari_gid.gid_guid = b2h64(ari->ari_gid.gid_guid);
84010Sstevel@tonic-gate ari->ari_gid.gid_prefix = b2h64(ari->ari_gid.gid_prefix);
8402557Shiremath
8403557Shiremath IBTF_DPRINTF_L4(cmlog, "ibcm_set_apr_arej: ari_gid= %llX:%llX",
8404557Shiremath ari->ari_gid.gid_prefix, ari->ari_gid.gid_guid);
84050Sstevel@tonic-gate break;
84060Sstevel@tonic-gate case IBT_CM_AP_FLOW_REJECTED:
84070Sstevel@tonic-gate if (ari_len < 3) /* 3 bytes needed for 20 bits */
84080Sstevel@tonic-gate break;
84090Sstevel@tonic-gate *ari_valid = B_TRUE;
84100Sstevel@tonic-gate /* take the first 20 bits */
84110Sstevel@tonic-gate ari->ari_flow =
84120Sstevel@tonic-gate b2h32(*(uint32_t *)&apr_msgp->apr_addl_info) >> 12;
84130Sstevel@tonic-gate break;
84140Sstevel@tonic-gate case IBT_CM_AP_TCLASS_REJECTED:
84150Sstevel@tonic-gate if (ari_len < 1)
84160Sstevel@tonic-gate break;
84170Sstevel@tonic-gate *ari_valid = B_TRUE;
84180Sstevel@tonic-gate /* take the first byte */
84190Sstevel@tonic-gate ari->ari_tclass = apr_msgp->apr_addl_info[0];
84200Sstevel@tonic-gate break;
84210Sstevel@tonic-gate case IBT_CM_AP_HOP_REJECTED:
84220Sstevel@tonic-gate if (ari_len < 1)
84230Sstevel@tonic-gate break;
84240Sstevel@tonic-gate *ari_valid = B_TRUE;
84250Sstevel@tonic-gate /* take the first byte */
84260Sstevel@tonic-gate ari->ari_hop = apr_msgp->apr_addl_info[0];
84270Sstevel@tonic-gate break;
84280Sstevel@tonic-gate case IBT_CM_AP_RATE_REJECTED:
84290Sstevel@tonic-gate if (ari_len < 1)
84300Sstevel@tonic-gate break;
84310Sstevel@tonic-gate *ari_valid = B_TRUE;
84320Sstevel@tonic-gate /* take the first 6 bits */
84330Sstevel@tonic-gate ari->ari_rate = apr_msgp->apr_addl_info[0] >> 2;
84340Sstevel@tonic-gate break;
84350Sstevel@tonic-gate case IBT_CM_AP_SL_REJECTED:
84360Sstevel@tonic-gate if (ari_len < 1)
84370Sstevel@tonic-gate break;
84380Sstevel@tonic-gate *ari_valid = B_TRUE;
84390Sstevel@tonic-gate /* take the first 4 bits */
84400Sstevel@tonic-gate ari->ari_sl = apr_msgp->apr_addl_info[0] >> 4;
84410Sstevel@tonic-gate break;
84420Sstevel@tonic-gate default:
84430Sstevel@tonic-gate break;
84440Sstevel@tonic-gate }
84450Sstevel@tonic-gate _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*ari))
84460Sstevel@tonic-gate }
84470Sstevel@tonic-gate
84480Sstevel@tonic-gate /*
84490Sstevel@tonic-gate * ibcm_cep_state_apr:
84500Sstevel@tonic-gate * This call processes an incoming APR message
84510Sstevel@tonic-gate *
84520Sstevel@tonic-gate * INPUTS:
84530Sstevel@tonic-gate * statep - pointer to ibcm_state_data_t
84540Sstevel@tonic-gate * lap_msg - lap msg sent earlier
84550Sstevel@tonic-gate * apr_msg - apr msg received
84560Sstevel@tonic-gate *
84570Sstevel@tonic-gate * RETURN VALUE: NONE
84580Sstevel@tonic-gate */
84590Sstevel@tonic-gate void
ibcm_cep_state_apr(ibcm_state_data_t * statep,ibcm_lap_msg_t * lap_msg,ibcm_apr_msg_t * apr_msg)84600Sstevel@tonic-gate ibcm_cep_state_apr(ibcm_state_data_t *statep, ibcm_lap_msg_t *lap_msg,
84610Sstevel@tonic-gate ibcm_apr_msg_t *apr_msg)
84620Sstevel@tonic-gate {
84630Sstevel@tonic-gate ibt_cm_event_t event;
84640Sstevel@tonic-gate ibcm_status_t status = IBCM_SUCCESS;
84650Sstevel@tonic-gate uint8_t ap_status = apr_msg->apr_ap_status;
84660Sstevel@tonic-gate
84670Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_cep_state_apr: statep 0x%p, ap_status %d",
84680Sstevel@tonic-gate statep, ap_status);
84690Sstevel@tonic-gate
84700Sstevel@tonic-gate if (ap_status == IBT_CM_AP_LOADED)
84710Sstevel@tonic-gate status = ibcm_set_qp_from_apr(statep, lap_msg);
84720Sstevel@tonic-gate
84730Sstevel@tonic-gate if (statep->ap_return_data != NULL) { /* blocking call */
84740Sstevel@tonic-gate
84750Sstevel@tonic-gate /* copy the private data */
84760Sstevel@tonic-gate if ((statep->ap_return_data->ap_priv_data != NULL) &&
84770Sstevel@tonic-gate (statep->ap_return_data->ap_priv_data_len > 0))
84780Sstevel@tonic-gate bcopy(apr_msg->apr_private_data,
84790Sstevel@tonic-gate statep->ap_return_data->ap_priv_data,
84800Sstevel@tonic-gate statep->ap_return_data->ap_priv_data_len);
84810Sstevel@tonic-gate
84820Sstevel@tonic-gate /* initialize the ap status */
84830Sstevel@tonic-gate if (status == IBCM_FAILURE) {
84840Sstevel@tonic-gate statep->ap_return_data->ap_status = IBT_CM_AP_REJECT;
84850Sstevel@tonic-gate statep->ap_return_data->ap_arej_info_valid = B_FALSE;
84860Sstevel@tonic-gate } else {
84870Sstevel@tonic-gate statep->ap_return_data->ap_status = ap_status;
84880Sstevel@tonic-gate ibcm_set_apr_arej(ap_status, apr_msg,
84890Sstevel@tonic-gate &statep->ap_return_data->ap_arej_info,
84900Sstevel@tonic-gate &statep->ap_return_data->ap_arej_info_valid);
84910Sstevel@tonic-gate }
84920Sstevel@tonic-gate
84930Sstevel@tonic-gate /* do a cv signal for a blocking ibt_set_alt_path */
84940Sstevel@tonic-gate mutex_enter(&statep->state_mutex);
84950Sstevel@tonic-gate statep->ap_done = B_TRUE;
84960Sstevel@tonic-gate cv_broadcast(&statep->block_client_cv);
84970Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
84980Sstevel@tonic-gate
84990Sstevel@tonic-gate } else { /* Non blocking call */
85000Sstevel@tonic-gate /* Fill up the event */
85010Sstevel@tonic-gate
85020Sstevel@tonic-gate bzero(&event, sizeof (event));
85030Sstevel@tonic-gate event.cm_type = IBT_CM_EVENT_APR_RCV;
85040Sstevel@tonic-gate event.cm_channel = statep->channel;
85050Sstevel@tonic-gate event.cm_session_id = NULL;
85060Sstevel@tonic-gate event.cm_priv_data = apr_msg->apr_private_data;
85070Sstevel@tonic-gate event.cm_priv_data_len = IBT_APR_PRIV_DATA_SZ;
85080Sstevel@tonic-gate if (status == IBCM_FAILURE) {
85090Sstevel@tonic-gate event.cm_event.apr.apr_status = IBT_CM_AP_REJECT;
85100Sstevel@tonic-gate event.cm_event.apr.apr_arej_info_valid = B_FALSE;
85110Sstevel@tonic-gate } else {
85120Sstevel@tonic-gate event.cm_event.apr.apr_status = ap_status;
85130Sstevel@tonic-gate ibcm_set_apr_arej(ap_status, apr_msg,
85140Sstevel@tonic-gate &event.cm_event.apr.apr_arej_info,
85150Sstevel@tonic-gate &event.cm_event.apr.apr_arej_info_valid);
85160Sstevel@tonic-gate }
85170Sstevel@tonic-gate
85180Sstevel@tonic-gate /* initialize the ap status */
85190Sstevel@tonic-gate statep->cm_handler(statep->state_cm_private, &event,
85200Sstevel@tonic-gate NULL, apr_msg->apr_private_data, IBT_APR_PRIV_DATA_SZ);
85210Sstevel@tonic-gate }
85221093Shiremath mutex_enter(&statep->state_mutex);
85231093Shiremath ibcm_open_done(statep);
85241093Shiremath mutex_exit(&statep->state_mutex);
85250Sstevel@tonic-gate }
85260Sstevel@tonic-gate
85270Sstevel@tonic-gate /*
85280Sstevel@tonic-gate * ibcm_set_qp_from_apr:
85290Sstevel@tonic-gate * This call sets QP's alt path info based on APR message contents
85300Sstevel@tonic-gate *
85310Sstevel@tonic-gate * INPUTS:
85320Sstevel@tonic-gate * statep - pointer to ibcm_state_data_t
85330Sstevel@tonic-gate * lap_msg - lap msg sent earlier
85340Sstevel@tonic-gate *
85350Sstevel@tonic-gate * RETURN VALUE: ibcm_status_t
85360Sstevel@tonic-gate */
85370Sstevel@tonic-gate static ibcm_status_t
ibcm_set_qp_from_apr(ibcm_state_data_t * statep,ibcm_lap_msg_t * lap_msg)85380Sstevel@tonic-gate ibcm_set_qp_from_apr(ibcm_state_data_t *statep, ibcm_lap_msg_t *lap_msg)
85390Sstevel@tonic-gate {
85400Sstevel@tonic-gate ibtl_cm_hca_port_t port;
85410Sstevel@tonic-gate ibt_adds_vect_t *adds;
85420Sstevel@tonic-gate
85430Sstevel@tonic-gate ibt_qp_query_attr_t qp_attrs;
85440Sstevel@tonic-gate ibt_cep_modify_flags_t cep_flags;
85450Sstevel@tonic-gate ibt_status_t status;
85460Sstevel@tonic-gate
85470Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_set_qp_from_apr: statep 0x%p", statep);
85480Sstevel@tonic-gate
85490Sstevel@tonic-gate status = ibt_query_qp(statep->channel, &qp_attrs);
85500Sstevel@tonic-gate if (status != IBT_SUCCESS ||
85510Sstevel@tonic-gate (qp_attrs.qp_info.qp_state != IBT_STATE_RTS &&
85520Sstevel@tonic-gate qp_attrs.qp_info.qp_state != IBT_STATE_SQD)) {
85530Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_set_qp_from_apr: ibt_query_qp "
85540Sstevel@tonic-gate "failed, status = %d, qp_state = %d", statep, status,
85550Sstevel@tonic-gate qp_attrs.qp_info.qp_state);
85560Sstevel@tonic-gate return (IBCM_FAILURE);
85570Sstevel@tonic-gate }
85580Sstevel@tonic-gate
85590Sstevel@tonic-gate /* Fill up input args for ibt_modify_qp */
85600Sstevel@tonic-gate cep_flags = IBT_CEP_SET_ALT_PATH | IBT_CEP_SET_STATE;
85610Sstevel@tonic-gate
85620Sstevel@tonic-gate /* do RTS=>RTS or SQD=>SQD. The next line is needed for RTS=>RTS. */
85630Sstevel@tonic-gate qp_attrs.qp_info.qp_current_state = qp_attrs.qp_info.qp_state;
85640Sstevel@tonic-gate
85650Sstevel@tonic-gate /* Fill up input args for ibt_modify_qp */
85660Sstevel@tonic-gate adds = &IBCM_QP_RC(qp_attrs).rc_alt_path.cep_adds_vect;
85670Sstevel@tonic-gate
85680Sstevel@tonic-gate ibcm_fill_adds_from_lap(adds, lap_msg, IBCM_ACTIVE_MODE);
85690Sstevel@tonic-gate
85700Sstevel@tonic-gate if ((status = ibtl_cm_get_hca_port(adds->av_sgid,
85710Sstevel@tonic-gate statep->local_hca_guid, &port)) != IBT_SUCCESS) {
85720Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_set_qp_from_apr: "
85730Sstevel@tonic-gate "ibtl_cm_get_hca_port failed status = %d", status);
85740Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_set_qp_from_apr:"
85750Sstevel@tonic-gate " ibtl_cm_get_hca_port sgid guid %llX",
85760Sstevel@tonic-gate adds->av_sgid.gid_guid);
85770Sstevel@tonic-gate IBTF_DPRINTF_L5(cmlog, "ibcm_set_qp_from_apr:"
85780Sstevel@tonic-gate " ibtl_cm_get_hca_port sgid prefix %llX ",
85790Sstevel@tonic-gate adds->av_sgid.gid_prefix);
85800Sstevel@tonic-gate return (IBCM_FAILURE);
85810Sstevel@tonic-gate }
85820Sstevel@tonic-gate
85830Sstevel@tonic-gate IBCM_QP_RC(qp_attrs).rc_alt_path.cep_hca_port_num =
85840Sstevel@tonic-gate port.hp_port;
85850Sstevel@tonic-gate
85860Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "ibcm_set_qp_from_apr: "
85870Sstevel@tonic-gate "gid = %llx:%llx, port_num = %d",
85880Sstevel@tonic-gate IBCM_QP_RC(qp_attrs).rc_alt_path.cep_adds_vect.av_sgid.
85890Sstevel@tonic-gate gid_prefix,
85900Sstevel@tonic-gate IBCM_QP_RC(qp_attrs).rc_alt_path.cep_adds_vect.av_sgid.gid_guid,
85910Sstevel@tonic-gate port.hp_port);
85920Sstevel@tonic-gate
85930Sstevel@tonic-gate /* The pkey is same as the primary path */
85940Sstevel@tonic-gate status = ibt_pkey2index_byguid(statep->local_hca_guid,
85950Sstevel@tonic-gate port.hp_port, statep->pkey,
85960Sstevel@tonic-gate &IBCM_QP_RC(qp_attrs).rc_alt_path.cep_pkey_ix);
85970Sstevel@tonic-gate
85980Sstevel@tonic-gate if (status != IBT_SUCCESS) {
85990Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_set_qp_from_apr: "
86000Sstevel@tonic-gate "ibt_pkey2index_byguid failed %d", status);
86010Sstevel@tonic-gate return (IBCM_FAILURE);
86020Sstevel@tonic-gate }
86030Sstevel@tonic-gate qp_attrs.qp_info.qp_trans = IBT_RC_SRV;
86040Sstevel@tonic-gate IBCM_QP_RC(qp_attrs).rc_alt_path.cep_timeout =
86050Sstevel@tonic-gate ibt_usec2ib(statep->remote_ack_delay +
86060Sstevel@tonic-gate 2 * statep->rc_alt_pkt_lt);
86070Sstevel@tonic-gate if (IBCM_QP_RC(qp_attrs).rc_mig_state == IBT_STATE_MIGRATED) {
86080Sstevel@tonic-gate /* Need to rearm */
86090Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_set_qp_from_apr: statep 0x%p: "
86100Sstevel@tonic-gate "rearming APM", statep);
86110Sstevel@tonic-gate cep_flags |= IBT_CEP_SET_MIG;
86120Sstevel@tonic-gate IBCM_QP_RC(qp_attrs).rc_mig_state = IBT_STATE_REARMED;
86130Sstevel@tonic-gate }
86140Sstevel@tonic-gate
86150Sstevel@tonic-gate status = ibt_modify_qp(statep->channel, cep_flags, &qp_attrs.qp_info,
86160Sstevel@tonic-gate NULL);
86170Sstevel@tonic-gate
86180Sstevel@tonic-gate if (status != IBT_SUCCESS)
86190Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_SET_ALT_FAIL);
86200Sstevel@tonic-gate else
86210Sstevel@tonic-gate ibcm_insert_trace(statep, IBCM_TRACE_SET_ALT);
86220Sstevel@tonic-gate
86230Sstevel@tonic-gate #ifdef DEBUG
86240Sstevel@tonic-gate (void) ibt_query_qp(statep->channel, &qp_attrs);
86250Sstevel@tonic-gate print_modify_qp("ACTIVE LAP QUERY", statep->channel,
86260Sstevel@tonic-gate cep_flags, &qp_attrs.qp_info);
86270Sstevel@tonic-gate #endif
86280Sstevel@tonic-gate
86290Sstevel@tonic-gate if (status != IBT_SUCCESS) {
86300Sstevel@tonic-gate IBTF_DPRINTF_L2(cmlog, "ibcm_set_qp_from_apr:"
86310Sstevel@tonic-gate " ibt_modify_qp() failed, status = %d", status);
86320Sstevel@tonic-gate return (IBCM_FAILURE);
86330Sstevel@tonic-gate }
86340Sstevel@tonic-gate
86350Sstevel@tonic-gate return (IBCM_SUCCESS);
86360Sstevel@tonic-gate }
86370Sstevel@tonic-gate
86380Sstevel@tonic-gate /*
86390Sstevel@tonic-gate * ibcm_sync_lapr_idle:
86400Sstevel@tonic-gate *
86410Sstevel@tonic-gate * This call either cancels a LAP/APR operation or waits
86420Sstevel@tonic-gate * until the operation is complete
86430Sstevel@tonic-gate *
86440Sstevel@tonic-gate * INPUTS:
86450Sstevel@tonic-gate * statep Pointer to ibcm_state_data_t
86460Sstevel@tonic-gate *
86470Sstevel@tonic-gate * RETURN VALUE: NONE
86480Sstevel@tonic-gate *
86490Sstevel@tonic-gate * This function is called holding state mutex
86500Sstevel@tonic-gate * This function returns, releasing the state mutex
86510Sstevel@tonic-gate */
86520Sstevel@tonic-gate void
ibcm_sync_lapr_idle(ibcm_state_data_t * statep)86530Sstevel@tonic-gate ibcm_sync_lapr_idle(ibcm_state_data_t *statep)
86540Sstevel@tonic-gate {
86550Sstevel@tonic-gate timeout_id_t timer_val = statep->timerid;
86560Sstevel@tonic-gate ibt_cm_event_t event;
86570Sstevel@tonic-gate
86580Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_sync_lapr_idle:"
86590Sstevel@tonic-gate "statep %p state %d ap_state %d", statep, statep->state,
86600Sstevel@tonic-gate statep->ap_state);
86610Sstevel@tonic-gate
86620Sstevel@tonic-gate ASSERT(MUTEX_HELD(&statep->state_mutex));
86630Sstevel@tonic-gate _NOTE(LOCK_RELEASED_AS_SIDE_EFFECT(&statep->state_mutex))
86640Sstevel@tonic-gate
86650Sstevel@tonic-gate /* Busy AP states on active/passive sides */
86660Sstevel@tonic-gate if ((statep->ap_state == IBCM_AP_STATE_LAP_RCVD) ||
86670Sstevel@tonic-gate (statep->ap_state == IBCM_AP_STATE_APR_RCVD) ||
86680Sstevel@tonic-gate (statep->ap_state == IBCM_AP_STATE_MRA_LAP_SENT) ||
86690Sstevel@tonic-gate (statep->ap_state == IBCM_AP_STATE_TIMED_OUT)) {
86700Sstevel@tonic-gate
86710Sstevel@tonic-gate /* wait till ap_state becomes IBCM_AP_STATE_IDLE */
86720Sstevel@tonic-gate while (statep->ap_state != IBCM_AP_STATE_IDLE)
86730Sstevel@tonic-gate cv_wait(&statep->block_mad_cv, &statep->state_mutex);
86740Sstevel@tonic-gate
86750Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
86760Sstevel@tonic-gate
86770Sstevel@tonic-gate } else if ((statep->ap_state == IBCM_AP_STATE_LAP_SENT) ||
86780Sstevel@tonic-gate (statep->ap_state == IBCM_AP_STATE_MRA_LAP_RCVD)) {
86790Sstevel@tonic-gate
86800Sstevel@tonic-gate /* fail the client's ibt_set_alt_path */
86810Sstevel@tonic-gate
86820Sstevel@tonic-gate /* blocking ibt_set_alt_path */
86830Sstevel@tonic-gate if (statep->ap_return_data != NULL) {
86840Sstevel@tonic-gate statep->ap_return_data->ap_status =
86850Sstevel@tonic-gate IBT_CM_AP_ABORT;
86860Sstevel@tonic-gate statep->ap_state = IBCM_AP_STATE_IDLE;
86870Sstevel@tonic-gate cv_broadcast(&statep->block_client_cv);
86880Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_sync_lapr_idle:"
86890Sstevel@tonic-gate "blocked wait");
86900Sstevel@tonic-gate }
86910Sstevel@tonic-gate
86920Sstevel@tonic-gate statep->timerid = 0;
86930Sstevel@tonic-gate /* Cancel the timeout */
86940Sstevel@tonic-gate mutex_exit(&statep->state_mutex);
86950Sstevel@tonic-gate if (timer_val != 0)
86960Sstevel@tonic-gate (void) untimeout(timer_val);
86970Sstevel@tonic-gate
86980Sstevel@tonic-gate /* Non blocking ibt_set_alt_path */
86990Sstevel@tonic-gate if (statep->ap_return_data == NULL) {
87000Sstevel@tonic-gate
87010Sstevel@tonic-gate /* Fill up the event */
87020Sstevel@tonic-gate
87030Sstevel@tonic-gate bzero(&event, sizeof (event));
87040Sstevel@tonic-gate event.cm_type = IBT_CM_EVENT_APR_RCV;
87050Sstevel@tonic-gate event.cm_channel = statep->channel;
87060Sstevel@tonic-gate event.cm_session_id = NULL;
87070Sstevel@tonic-gate event.cm_priv_data = NULL;
87080Sstevel@tonic-gate event.cm_priv_data_len = 0;
87090Sstevel@tonic-gate event.cm_event.apr.apr_status = IBT_CM_AP_ABORT;
87100Sstevel@tonic-gate
87110Sstevel@tonic-gate /* Call the cm handler */
87120Sstevel@tonic-gate statep->cm_handler(statep->state_cm_private, &event,
87130Sstevel@tonic-gate NULL, NULL, 0);
87140Sstevel@tonic-gate IBTF_DPRINTF_L3(cmlog, "ibcm_sync_lapr_idle:"
87150Sstevel@tonic-gate "non-blocked wait");
87160Sstevel@tonic-gate }
87170Sstevel@tonic-gate } else mutex_exit(&statep->state_mutex);
87180Sstevel@tonic-gate
87190Sstevel@tonic-gate ASSERT(!MUTEX_HELD(&statep->state_mutex));
87200Sstevel@tonic-gate }
87210Sstevel@tonic-gate
87220Sstevel@tonic-gate #ifdef DEBUG
87230Sstevel@tonic-gate
87240Sstevel@tonic-gate /*
87250Sstevel@tonic-gate * Debug function used to print all the modify qp attributes.
87260Sstevel@tonic-gate * Useful to manually verify the modify qp parameters are as
87270Sstevel@tonic-gate * expected
87280Sstevel@tonic-gate */
87290Sstevel@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)87300Sstevel@tonic-gate print_modify_qp(char *prefix, ibt_qp_hdl_t ibt_qp,
87310Sstevel@tonic-gate ibt_cep_modify_flags_t flags, ibt_qp_info_t *qp_attr)
87320Sstevel@tonic-gate {
87330Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP %s %p", prefix, ibt_qp);
87340Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP flags 0x%x", flags);
87350Sstevel@tonic-gate
87360Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP "
87370Sstevel@tonic-gate "rc_rdma_ra_in %d rc_rdma_ra_out %d",
87380Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_rdma_ra_in,
87390Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_rdma_ra_out);
87400Sstevel@tonic-gate
87410Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP primary: "
87420Sstevel@tonic-gate "port %d path bits %d dlid %X",
87430Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_path.cep_hca_port_num,
87440Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_src_path,
87450Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_dlid);
87460Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP primary: "
87470Sstevel@tonic-gate "pkey index %d cep_timeout %d",
87480Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_path.cep_pkey_ix,
87490Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_path.cep_timeout);
87500Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP primary: "
87510Sstevel@tonic-gate "srvl %d flow label %d tclass %d",
87520Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_srvl,
87530Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_flow,
87540Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_tclass);
87550Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP primary: "
87560Sstevel@tonic-gate "hop %d srate %d sgid_ix %d send_grh %d",
87570Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_hop,
87580Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_srate,
87590Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_sgid_ix,
87600Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_send_grh);
87610Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP primary: "
87620Sstevel@tonic-gate "dgid prefix %llX dgid guid %llX",
87630Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_dgid.gid_prefix,
87640Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_dgid.gid_guid);
87650Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP primary: "
87660Sstevel@tonic-gate "sgid prefix %llX sgid guid %llX",
87670Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_sgid.gid_prefix,
87680Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_sgid.gid_guid);
87690Sstevel@tonic-gate
87700Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP alternate: "
87710Sstevel@tonic-gate "port %d path bits %d dlid %X",
87720Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_alt_path.cep_hca_port_num,
87730Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_src_path,
87740Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_dlid);
87750Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP alternate: "
87760Sstevel@tonic-gate "pkey index %d cep_timeout %d",
87770Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_alt_path.cep_pkey_ix,
87780Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_alt_path.cep_timeout);
87790Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP alternate: "
87800Sstevel@tonic-gate "srvl %d flow label %d tclass %d",
87810Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_srvl,
87820Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_flow,
87830Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_tclass);
87840Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP alternate: "
87850Sstevel@tonic-gate "hop %d srate %d sgid_ix %d send_grh %d",
87860Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_hop,
87870Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_srate,
87880Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_sgid_ix,
87890Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_send_grh);
87900Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP alternate: "
87910Sstevel@tonic-gate "dgid prefix %llX dgid guid %llX",
87920Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_dgid.
87930Sstevel@tonic-gate gid_prefix,
87940Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_dgid.
87950Sstevel@tonic-gate gid_guid);
87960Sstevel@tonic-gate IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP alternate: "
87970Sstevel@tonic-gate "sgid prefix %llX sgid guid %llX",
87980Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_sgid.
87990Sstevel@tonic-gate gid_prefix,
88000Sstevel@tonic-gate qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_sgid.
88010Sstevel@tonic-gate gid_guid);
88020Sstevel@tonic-gate }
88030Sstevel@tonic-gate #endif
8804