1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _SYS_IB_MGT_IBCM_IBCM_IMPL_H 27 #define _SYS_IB_MGT_IBCM_IBCM_IMPL_H 28 29 #pragma ident "%Z%%M% %I% %E% SMI" 30 31 /* 32 * ibcm_impl.h 33 * 34 * This file contains all of the internal data structures and 35 * definitions for IBCM. 36 * 37 * The general state transition processing of CM is achieved by the 38 * following callgraph: 39 * 40 * CM INIT : Register for hca attach and detach callbacks, and other asyncs 41 * 42 * On new HCA attach: Register with IBMF on all ports of upcoming HCA 43 * Specify CM callback and callback "per HCA arg" 44 * Register with SA, allocate AVL trees etc. 45 * 46 * IBMF Callback 47 * Validate combination of method and attribute Id in the generic MAD hdr 48 * -> Call CM Connection state transition function based on attribute ID 49 * Create/lookup/delete CM state structure and save it into avl tree 50 * Handle duplicate messages and MRA to adjust timers etc. 51 * Handle stale connections 52 * Allocate reply MADs 53 * -> Call CM QP/EEC state transition function based on CM message 54 * Change QP/EEC state (to enable recvQ posting by client) 55 * Call Client/Server handler callback function 56 * Modify QP/EEC attributes 57 * Optionally fill up some fields of response MAD 58 * Post reply MADs 59 * Store reply MADs and reply MAD address, if necessary 60 * Initialize timeouts for the message 61 * Change CM state 62 * Deallocate reply MADs 63 * 64 * NOTES: 65 * o There are *NO* explicit CM allocation and deallocation routines for 66 * CM MADs and state data structures 67 * o CM timeouts are scheduled using timeout(9f), and cancelled using 68 * untimeout(9f) 69 * o svc_id allocation scheme 70 * A new counter for svcid is maintained in ibcm_hca_info_t 71 * which is used to allocate svcid. The svcids are incremented 72 * sequentially and allocated (with wrap around on overflow) with 73 * these considerations: 74 * The WellKnown service id's and locally allocated svcid's 75 * could be maintained in separate lists, thus allowing the 76 * lists to be kept apart and sorted easily. 77 * The insertions are done at the end of the list 78 * o reqid allocation scheme 79 * The list is a sorted one (as reqid's are allocated sequentially). 80 * If there is a code required for wrap around, it would search for 81 * a reqid from the head of the list. 82 * The insertions are always done at the end of the lists 83 * o XXX svc_id allocation scheme and req_id allocation scheme will 84 * be revisited. 85 */ 86 87 #include <sys/sysmacros.h> 88 #include <sys/systm.h> 89 #include <sys/kmem.h> 90 #include <sys/modctl.h> 91 #include <sys/avl.h> 92 #include <sys/taskq.h> 93 #include <sys/vmem.h> 94 #include <sys/note.h> 95 #include <sys/t_lock.h> 96 97 #include <sys/ib/ibtl/ibvti.h> 98 #include <sys/ib/ibtl/impl/ibtl_cm.h> 99 #include <sys/ib/ibtl/impl/ibtl_util.h> 100 #include <sys/ib/mgt/ibmf/ibmf.h> 101 #include <sys/ib/mgt/ibcm/ibcm_trace.h> 102 #include <inet/ip.h> 103 104 #ifdef __cplusplus 105 extern "C" { 106 #endif 107 108 _NOTE(SCHEME_PROTECTS_DATA("Private", sa_service_record_s)) 109 _NOTE(SCHEME_PROTECTS_DATA("Exclusive access to ibmf msg buf based on state", 110 ib_mad_hdr_t)) 111 _NOTE(SCHEME_PROTECTS_DATA("Exclusive access to ibmf msg buf based on state", 112 _ibmf_msg)) 113 114 /* 115 * Defines for all CM state machine states, as defined in 116 * section 12.9.7. IBCM_REJ_SENT is a state not defined in 117 * the spec and is added for implementation purposes. 118 */ 119 typedef enum ibcm_conn_state_e { 120 /* Initial states */ 121 IBCM_STATE_IDLE = 0, 122 IBCM_STATE_LISTEN, 123 124 /* States during connection establishment */ 125 IBCM_STATE_REQ_SENT, 126 IBCM_STATE_REQ_RCVD, 127 IBCM_STATE_REP_SENT, 128 IBCM_STATE_REP_RCVD, 129 IBCM_STATE_REP_WAIT, 130 IBCM_STATE_MRA_SENT, 131 IBCM_STATE_MRA_REP_SENT, 132 IBCM_STATE_MRA_REP_RCVD, 133 134 /* States during connection establishment failures */ 135 IBCM_STATE_TIMED_OUT, 136 IBCM_STATE_ABORTED, 137 IBCM_STATE_REJ_SENT, 138 139 /* Established state */ 140 IBCM_STATE_TRANSIENT_ESTABLISHED, 141 IBCM_STATE_ESTABLISHED, 142 143 /* States during connection teardown */ 144 IBCM_STATE_TRANSIENT_DREQ_SENT, 145 IBCM_STATE_DREQ_SENT, 146 IBCM_STATE_DREQ_RCVD, 147 IBCM_STATE_DREP_RCVD, 148 IBCM_STATE_TIMEWAIT, 149 150 /* states for UD side of things */ 151 IBCM_STATE_SIDR_REQ_SENT, 152 IBCM_STATE_SIDR_REQ_RCVD, 153 IBCM_STATE_SIDR_REP_SENT, 154 IBCM_STATE_SIDR_REP_RCVD, 155 156 /* states common to RC and UD, during state resource deletion */ 157 IBCM_STATE_DELETE 158 } ibcm_conn_state_t; 159 160 /* Defines the AP states for LAP/APR */ 161 typedef enum ibcm_ap_state_e { 162 IBCM_AP_STATE_IDLE = 0x0, 163 IBCM_AP_STATE_LAP_SENT, 164 IBCM_AP_STATE_LAP_RCVD, 165 IBCM_AP_STATE_APR_RCVD, 166 IBCM_AP_STATE_MRA_LAP_RCVD, 167 IBCM_AP_STATE_MRA_LAP_SENT, 168 IBCM_AP_STATE_TIMED_OUT 169 } ibcm_ap_state_t; 170 171 /* 172 * Defines for the CM event types/MAD attribute IDs 173 */ 174 typedef enum ibcm_event_type_e { 175 IBCM_INCOMING_REQ = 0x0, 176 IBCM_INCOMING_MRA = 0x1, 177 IBCM_INCOMING_REJ = 0x2, 178 IBCM_INCOMING_REP = 0x3, 179 IBCM_INCOMING_RTU = 0x4, 180 IBCM_INCOMING_DREQ = 0x5, 181 IBCM_INCOMING_DREP = 0x6, 182 IBCM_INCOMING_SIDR_REQ = 0x7, 183 IBCM_INCOMING_SIDR_REP = 0x8, 184 IBCM_INCOMING_LAP = 0x9, 185 IBCM_INCOMING_APR = 0xA, 186 IBCM_OUTGOING_REQ = 0xB, /* REQ Sent on active CM side */ 187 IBCM_INCOMING_REQ_STALE = 0xC, /* lookup by remote HCA and */ 188 /* remote comid */ 189 IBCM_INCOMING_REP_STALE = 0xD, /* lookup by passive HCA and QPN */ 190 IBCM_INCOMING_REJ_RCOMID = 0xE /* lookup by remote com id */ 191 } ibcm_event_type_t; 192 193 /* 194 * IBMF calls back into CM on only the first 11 events defined in 195 * ibcm_event_type_t. CM has pre-defined functions for these 11 events 196 * 197 */ 198 #define IBCM_MAX_EVENTS 11 199 200 /* 201 * CM message attribute IDs begin at this "base ID". The first 11 event types 202 * in ibcm_event_type_t are CM protocol messages that are posted to IBMF by 203 * adding the "base_id" to the respective event type value. By subtracting 204 * the "base_id" in IBMF callback in CM MAD, the message type is gotten back 205 */ 206 #define IBCM_ATTR_BASE_ID 0x10 207 208 #define IBCM_MAX_RETRY_CNT 15 209 #define IBCM_ATTRID_FIELD_SIZE 4 210 #define IBCM_TRANID_PRIV_FIELD_SIZE 28 211 212 #define IBCM_RNR_RETRY_CNT_MASK 0x7 /* 3 bits */ 213 #define IBCM_MAX_RNR_RETRY_CNT 7 214 215 #define IBCM_INITIAL_COMID 1 216 #define IBCM_INITIAL_REQID 1 217 #define IBCM_INITIAL_SID 1 218 219 /* 220 * Maximum number of com ids / req ids that can be active at any given time 221 * MUST ENSURE THAT (INITIAL ID + MAX IDS -1), for any of the IDs does not 222 * exceed the max 32 bit 223 */ 224 225 /* An hca can have max of 2^24 -2 RC connections */ 226 #define IBCM_MAX_COMIDS (0x01000000 - 2) 227 #define IBCM_MAX_REQIDS 0xFFFFFFFF 228 #define IBCM_MAX_LOCAL_SIDS 0xFFFFFFFF 229 #define IBCM_MAX_IP_SIDS 0xFFFF 230 231 typedef uint32_t ib_com_id_t; /* CM Communication ID */ 232 233 /* 234 * Defines the CM Mode of operation for a connection 235 */ 236 typedef enum ibcm_mode_e { 237 IBCM_ACTIVE_MODE = 1, /* Active side CM */ 238 IBCM_PASSIVE_MODE = 2 /* Passive side CM */ 239 } ibcm_mode_t; 240 241 242 /* different IBCM return values */ 243 typedef enum ibcm_status_e { 244 IBCM_SUCCESS = 0, /* good status */ 245 IBCM_LOOKUP_EXISTS, /* statep lookup found existing entry */ 246 IBCM_LOOKUP_NEW, /* lookup created new statep entry */ 247 IBCM_LOOKUP_FAIL, /* lookup found no statep entry */ 248 IBCM_SEND_REJ, /* CM QP state change sent REJ msg */ 249 IBCM_SEND_REP, /* CM QP state change sent REP msg */ 250 IBCM_SEND_RTU, /* CM QP state change sent RTU msg */ 251 IBCM_SEND_APR, /* CM to send APR MAD as response */ 252 IBCM_SEND_SIDR_REP, /* client's UD handler returned this */ 253 IBCM_DEFER, /* client's handler returned this */ 254 IBCM_FAILURE /* generic IBCM failure */ 255 } ibcm_status_t; 256 257 /* 258 * Struct definition for addressing information that CM maintains for 259 * each of the incoming MADs 260 */ 261 typedef struct ibcm_mad_addr { 262 ibmf_global_addr_info_t grh_hdr; /* GRH related fields of MAD */ 263 ibmf_addr_info_t rcvd_addr; /* Outgoing/Incoming MAD addr */ 264 ibmf_handle_t ibmf_hdl; /* IBMF handle */ 265 boolean_t grh_exists; /* TRUE if grh exists */ 266 uint8_t port_num; 267 struct ibcm_qp_list_s *cm_qp_entry; /* IBMF hdl on which MAD rcvd */ 268 /* or on which MAD shall be */ 269 /* sent out */ 270 } ibcm_mad_addr_t; 271 272 _NOTE(READ_ONLY_DATA(ibcm_mad_addr)) 273 274 #define IBCM_MAD_SIZE 0x100 /* size of MAD */ 275 #define IBCM_MAD_HDR_SIZE sizeof (ib_mad_hdr_t) /* size of MAD HDR */ 276 #define IBCM_MSG_SIZE IBCM_MAD_SIZE-IBCM_MAD_HDR_SIZE 277 278 typedef enum ibcm_abort_flag_e { 279 IBCM_ABORT_INIT = 0, /* no abort flag is set */ 280 IBCM_ABORT_CLIENT = 1, /* client requested connection abort */ 281 IBCM_ABORT_REJ = 2 /* REJ received with timeout reason */ 282 } ibcm_abort_flag_t; 283 284 typedef enum ibcm_isync_e { 285 IBCM_BLOCK = 0, /* Block cm operation */ 286 IBCM_UNBLOCK = 1, /* Unblock cm operation */ 287 IBCM_FAIL = 2 /* fail cm operation */ 288 } ibcm_isync_t; 289 290 /* 291 * Define a connection state structure, used by the IBTF CM 292 * to maintain state about connected QPs. 293 * 294 * mode : CM connection mode active/passive 295 * state : CM connection state 296 * ap_state : CM AP Internal state to manage LAP/APR state machine 297 * state_mutex : lock for this structure 298 * channel : Channel associated with this RC state structure 299 * ref_cnt : Number of active threads that may reference this 300 * state structure 301 * svcid : Service ID 302 * cm_handler : Client handler callback address 303 * stored_reply_addr : Address for replying using the stored mad 304 * hcap : A pointer to the HCA's entry 305 * stored_msg : Stores the response REP/REJ/RTU MAD 306 * mra_msg : Stores the response MRA MAD 307 * dreq_msg : Stores the DREQ MAD 308 * drep_msg : Stores the DREP MAD 309 * lapr_msg : Stores the LAP/APR MAD 310 * detect duplicate LAP messages 311 * local_comid : Local communication id 312 * local_hca_guid : Local HCA GUID 313 * local_qpn : Local QPN 314 * 315 * remote_comid : Remote communication id 316 * remote_hca_guid : Remote HCA GUID 317 * remote_qpn : Remote QPN 318 * 319 * timerid : Timer id for the timeout either for re-sending the 320 * stored mad or deleting the stored mad 321 * Ex: A REJ/RTU response for an incoming REP 322 * A REP response to an incoming REQ 323 * An outgoing REQ on active connection side 324 * timer_value : Time for any of the above timers in HZ 325 * pkt_life_time : pkt life time from source to destination 326 * remote_ack_delay : Remote hca's ack delay in clock_t 327 * rc_alt_pkt_lt : Life time for new ALT path specified in LAP 328 * stale_clock : clock used to detect stale vs duplicate REQs 329 * timer_stored_state : state of connection for timeout() validation 330 * timer_stored_ap_state: CM ap_state for timeout validation 331 * remaining_retry_count: Remaining count for retries ie., posting stored MADs 332 * max_cm_retries : Max retry count for sending a REQ/REP/DREQ 333 * delete_mra_msg : Set to TRUE for deletion, if MRA re-send in progress 334 * resend_mad : B_TRUE, if REQ/REP/RTU/REJ MAD re-send is in progress 335 * resend_mra_mad : B_TRUE, if a MRA mad re-sens is in progress 336 * cep_retry_cnt : Retry count for CEP. 337 * stale : B_TRUE, if connection has become stale 338 * blocking_done : B_TRUE, if cv_signal been issued to block_client_cv 339 * clnt_hdl : Clnt_hdl passed in ibt_open_channel 340 * return_data : RC return args, valid for blocking 341 * ibt_open_channel 342 * drep_priv_data; : The pointer to client specified outgoing private 343 * data, from close channel API call 344 * drep_priv_data_len : The length of DREP private data that client would 345 * like to be returned from close channel API call 346 * delete_state_data : B_TRUE, if CM decides to delete state data, but 347 * there is some thread that could access state data 348 * 349 * avl_active_link : For inserting this state-data into active AVL tree 350 * avl_passive_link : For inserting this state-data into passive AVL tree 351 * Note : All timer values that are of type "clock_t" below are in usecs 352 */ 353 typedef struct ibcm_state_data_s { 354 /* for AVL tree */ 355 avl_node_t avl_active_link; 356 avl_node_t avl_passive_link; 357 avl_node_t avl_passive_comid_link; 358 359 /* remote stuff */ 360 ib_guid_t remote_hca_guid; 361 ib_com_id_t remote_comid; 362 ib_qpn_t remote_qpn; 363 364 /* local stuff */ 365 ib_com_id_t local_comid; 366 ib_qpn_t local_qpn; 367 ib_guid_t local_hca_guid; 368 369 ibcm_mode_t mode; 370 ibcm_conn_state_t state; 371 ibcm_ap_state_t ap_state; 372 kmutex_t state_mutex; 373 ibt_channel_hdl_t channel; /* save a copy */ 374 375 /* ref_cnt so others cannot delete a statep that may be referenced */ 376 int ref_cnt; 377 378 ib_svc_id_t svcid; 379 ibt_cm_handler_t cm_handler; 380 381 ibcm_mad_addr_t stored_reply_addr; 382 383 struct ibcm_hca_info_s *hcap; 384 385 ibmf_msg_t *stored_msg; 386 ibmf_msg_t *mra_msg; 387 ibmf_msg_t *dreq_msg; 388 ibmf_msg_t *drep_msg; 389 ibmf_msg_t *lapr_msg; 390 391 void *defer_cm_msg; 392 393 /* timeout related stuff */ 394 timeout_id_t timerid; 395 clock_t timer_value; 396 clock_t pkt_life_time; 397 clock_t remote_ack_delay; 398 clock_t rc_alt_pkt_lt; 399 400 hrtime_t stale_clock; 401 hrtime_t post_time; 402 hrtime_t mra_time; 403 404 ibcm_conn_state_t timer_stored_state; 405 ibcm_ap_state_t timer_stored_ap_state; 406 uint8_t remaining_retry_cnt; 407 uint8_t max_cm_retries; 408 uint8_t cm_retries; 409 410 uint8_t drep_in_progress; 411 412 /* some cep stuff, stored here temporarily during connection est */ 413 uint8_t cep_retry_cnt:3; 414 ibt_srate_t local_srate; 415 ibt_srate_t local_alt_srate; 416 ib_pkey_t pkey; 417 uint8_t prim_port; 418 uint8_t alt_port; 419 uint32_t starting_psn; 420 ib_path_bits_t prim_src_path_bits; 421 ib_path_bits_t alt_src_path_bits; 422 423 boolean_t delete_mra_msg; 424 boolean_t stale; 425 boolean_t delete_state_data; 426 427 boolean_t open_done; 428 boolean_t close_done; 429 boolean_t ap_done; 430 431 uint8_t send_mad_flags; 432 uint8_t close_flow; 433 uint8_t open_flow; 434 ibcm_abort_flag_t abort_flag; 435 436 struct ibcm_state_data_s *timeout_next; 437 438 ibcm_conn_state_t timedout_state; 439 440 ibcm_isync_t cep_in_rts; 441 ibcm_isync_t clnt_proceed; 442 ibcm_isync_t close_nocb_state; 443 444 /* Clients' information */ 445 void *state_cm_private; 446 447 /* pointer to service info */ 448 struct ibcm_svc_info_s *state_svc_infop; 449 450 kcondvar_t block_client_cv; 451 kcondvar_t block_mad_cv; 452 453 /* Data for recycle function */ 454 struct ibcm_taskq_recycle_arg_s *recycle_arg; 455 456 /* Return data pointers in various cm api calls */ 457 ibt_rc_returns_t *open_return_data; 458 ibt_ap_returns_t *ap_return_data; 459 uint8_t *close_ret_priv_data; 460 ibt_priv_data_len_t *close_ret_priv_data_len; 461 uint8_t *close_ret_status; 462 463 /* for queuing of open_rc_channel requests */ 464 struct ibcm_state_data_s *open_link; 465 /* for queuing of non-blocking close_rc_channel requests */ 466 struct ibcm_state_data_s *close_link; 467 468 struct ibcm_conn_trace_s *conn_trace; 469 470 } ibcm_state_data_t; 471 472 _NOTE(MUTEX_PROTECTS_DATA(ibcm_state_data_s::state_mutex, 473 ibcm_state_data_s::{state ref_cnt timer_stored_state timer_value 474 timer_stored_ap_state remaining_retry_cnt clnt_proceed cep_in_rts 475 close_nocb_state block_client_cv block_mad_cv timedout_state cm_handler 476 abort_flag mra_msg})) 477 478 _NOTE(READ_ONLY_DATA(ibcm_state_data_s::{mode channel svcid hcap 479 local_comid local_hca_guid local_qpn remote_comid remote_hca_guid 480 remote_qpn pkt_life_time remote_ack_delay rc_alt_pkt_lt stored_reply_addr 481 max_cm_retries cep_retry_cnt local_srate local_alt_srate pkey 482 prim_port alt_port starting_psn state_svc_infop avl_active_link 483 avl_passive_link avl_passive_comid_link defer_cm_msg recycle_arg 484 conn_trace})) 485 486 _NOTE(SCHEME_PROTECTS_DATA("Serailized access by block_client_cv", 487 ibcm_state_data_s::{open_return_data ap_return_data close_ret_priv_data 488 close_ret_priv_data_len close_ret_status})) 489 490 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibcm_state_data_s::{timedout_state 491 cm_handler mra_msg abort_flag})) 492 493 /* 494 * Definitions for send mad flags. Respective bits in send_mad_flags or 495 * ud_send_mad_flags are set to 1, during MAD transmission, and reset in 496 * ibmf send completion callback or on completion of a blocking ibmf mad post. 497 */ 498 #define IBCM_REP_POST_BUSY 1 /* REP post in progress */ 499 #define IBCM_REJ_POST_BUSY 2 /* REJ post in progress */ 500 #define IBCM_RTU_POST_BUSY 4 /* RTU post in progress */ 501 #define IBCM_MRA_POST_BUSY 8 /* MRA post in progress */ 502 #define IBCM_DREP_POST_BUSY 16 /* DREQ post in progress */ 503 #define IBCM_SREP_POST_BUSY 32 /* SIDR REP post in progress */ 504 505 /* MADs that are retransmitted only because of a timeout */ 506 #define IBCM_REQ_POST_BUSY 64 /* REQ post in progress */ 507 508 509 /* Incr/Decr ref_cnt by 1 */ 510 #define IBCM_REF_CNT_INCR(s) (s->ref_cnt++) 511 #define IBCM_REF_CNT_DECR(s) \ 512 if ((--(s->ref_cnt) == 0) && (s->delete_state_data == B_TRUE)) { \ 513 ibcm_add_tlist(s);\ 514 } \ 515 ASSERT(s->ref_cnt >= 0); 516 517 /* 518 * This macro checks if ch_qp/ch_eec handles are both not set for a channel 519 */ 520 #define IBCM_INVALID_CHANNEL(chan) (chan == NULL) 521 522 /* 523 * The next macros are used to get/set the statep from the QP 524 * handles, using the CM private data. These call into IBTL. 525 * The WAIT and RELEASE macros deal with related issues that 526 * require use of the same lock within IBTL. 527 */ 528 #define IBCM_GET_CHAN_PRIVATE(ch, s) \ 529 if ((ch) != NULL) { \ 530 s = ibtl_cm_get_chan_private(ch); \ 531 } else \ 532 s = NULL; 533 534 #define IBCM_SET_CHAN_PRIVATE(ch, s) \ 535 if ((ch) != NULL) { \ 536 ibtl_cm_set_chan_private(ch, (void *)(s)); \ 537 } 538 539 #define IBCM_RELEASE_CHAN_PRIVATE(ch) \ 540 if ((ch) != NULL) { \ 541 ibtl_cm_release_chan_private(ch); \ 542 } 543 544 #define IBCM_WAIT_CHAN_PRIVATE(ch) \ 545 ibtl_cm_wait_chan_private(ch); 546 547 /* In future, if we intend to change it to realtime_timeout, it's easy */ 548 #define IBCM_TIMEOUT(arg1, arg2) timeout(ibcm_timeout_cb, arg1,\ 549 drv_usectohz(arg2)) 550 #define IBCM_UD_TIMEOUT(arg1, arg2) timeout(ibcm_sidr_timeout_cb, arg1,\ 551 drv_usectohz(arg2)) 552 553 extern void ibcm_open_enqueue(ibcm_state_data_t *statep); 554 extern void ibcm_open_done(ibcm_state_data_t *statep); 555 extern void ibcm_close_enqueue(ibcm_state_data_t *statep); 556 extern void ibcm_close_done(ibcm_state_data_t *statep, int send_done); 557 extern void ibcm_close_enter(void); 558 extern void ibcm_close_exit(void); 559 extern void ibcm_lapr_enter(void); 560 extern void ibcm_lapr_exit(void); 561 extern void ibcm_check_for_opens(void); 562 extern void ibcm_check_for_async_close(void); 563 extern void ibcm_close_start(ibcm_state_data_t *statep); 564 extern void ibcm_run_tlist_thread(void); 565 566 /* 567 * Structures & defines for SIDR 568 */ 569 570 /* 571 * Define a connection state structure, used for SIDR REQ and REP 572 * (ibcm_ud_state_data_t - struct for SIDR connection) 573 * 574 * ud_state: CM connection state (See ibcm_conn_state_t) 575 * ud_req_id: Request ID 576 * ud_svcid: Service ID 577 * ud_state_mutex: CM connection state 578 * 579 * ud_max_cm_retries: Max retry count for sending a SIDR REQ 580 * ud_ref_cnt: State ref count for not deleting accidentally 581 * ud_remaining_retry_count: Remaining count for retries ie., posting 582 * stored MADs 583 * ud_cm_handler: Server's handler callback address 584 * 585 * ud_nextp: CM link for IBTF list 586 * ud_hcap: A pointer to the HCA's entry 587 * 588 * ud_timerid: Timer id for the timeout either for re-sending the 589 * stored mad or deleting the stored mad 590 * Ex: A SIDR REP response for an incoming SIDR REQ 591 * An outgoing SIDR REQ on active connection side 592 * ud_timer_value: Time for any of the above timers in HZ 593 * ud_pkt_life_time: pkt life time from source to destination 594 * ud_stored_reply_addr: Address for replying using the stored mad 595 * 596 * ud_sidr_req_lid: SIDR REQ sender's port LID 597 * ud_sidr_req_gid: SIDR REQ sender's port GID 598 * ud_grh_exists: TRUE if GRH exists in the incoming SIDR REQ 599 * 600 * ud_passive_qpn: QPN allocated by server for a SIDR REQ 601 * ud_passive_qpn_qkey: QPN's QKEY allocated by server 602 * 603 * ud_block_client_cv: CV condition variable on which ibt_ud_get_dqpn() waits, 604 * if called in blocking mode. 605 * ud_return_data: UD return args, valid for blocking ibt_ud_get_dqpn 606 * ud_timer_stored_state: State stored for timeout handling 607 * ud_blocking_done : Tells if cv_wait is needed or not. To handle the 608 * case where a cv_signal is received prior to its 609 * cv_wait(). 610 * Note : All timer values that are of type "clock_t" below are in usec 611 */ 612 typedef struct ibcm_ud_state_data_s { 613 kmutex_t ud_state_mutex; 614 ibcm_conn_state_t ud_state; 615 ibcm_mode_t ud_mode; 616 617 int ud_ref_cnt; 618 619 uint32_t ud_req_id; 620 ib_svc_id_t ud_svc_id; 621 622 uint8_t ud_max_cm_retries; 623 uint8_t ud_remaining_retry_cnt; 624 ibt_cm_ud_handler_t ud_cm_handler; 625 626 struct ibcm_ud_state_data_s *ud_nextp; 627 struct ibcm_hca_info_s *ud_hcap; 628 629 /* timeout related stuff */ 630 timeout_id_t ud_timerid; 631 clock_t ud_timer_value; 632 clock_t ud_pkt_life_time; 633 ibcm_mad_addr_t ud_stored_reply_addr; 634 ibmf_msg_t *ud_stored_msg; 635 636 637 /* SIDR REQ side related */ 638 ib_lid_t ud_sidr_req_lid; 639 ib_gid_t ud_sidr_req_gid; 640 boolean_t ud_grh_exists; 641 642 /* Stored values on server/SIDR REP side for re-transmits */ 643 ib_qpn_t ud_passive_qpn; 644 ib_qkey_t ud_passive_qp_qkey; 645 646 /* Clients' information */ 647 void *ud_state_cm_private; 648 649 struct ibcm_ud_state_data_s *ud_timeout_next; 650 boolean_t ud_delete_state_data; 651 boolean_t ud_blocking_done; 652 653 uint8_t ud_send_mad_flags; 654 655 ibcm_isync_t ud_clnt_proceed; 656 657 /* The following fields are not used by server side connection */ 658 kcondvar_t ud_block_client_cv; 659 ibt_ud_returns_t *ud_return_data; 660 ibcm_conn_state_t ud_timer_stored_state; 661 } ibcm_ud_state_data_t; 662 663 _NOTE(MUTEX_PROTECTS_DATA(ibcm_ud_state_data_s::ud_state_mutex, 664 ibcm_ud_state_data_s::{ud_state ud_ref_cnt ud_timerid 665 ud_delete_state_data ud_blocking_done ud_send_mad_flags ud_clnt_proceed 666 ud_timer_stored_state ud_send_mad_flags ud_clnt_proceed 667 ud_block_client_cv ud_timer_value ud_remaining_retry_cnt})) 668 669 _NOTE(READ_ONLY_DATA(ibcm_ud_state_data_s::{ud_mode ud_req_id ud_svc_id 670 ud_max_cm_retries ud_pkt_life_time ud_stored_reply_addr ud_stored_msg 671 ud_sidr_req_lid ud_sidr_req_gid ud_grh_exists ud_passive_qpn 672 ud_passive_qp_qkey ud_state_cm_private ud_stored_reply_addr ud_stored_msg})) 673 674 _NOTE(SCHEME_PROTECTS_DATA("Serailized access by ud_block_client_cv", 675 ibcm_ud_state_data_s::{ud_return_data})) 676 677 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibcm_ud_state_data_s::{ud_cm_handler})) 678 679 /* 680 * Structure used to specify the SIDR search parameters 681 */ 682 typedef struct ibcm_sidr_srch_s { 683 ib_lid_t srch_lid; 684 ib_gid_t srch_gid; 685 boolean_t srch_grh_exists; 686 uint32_t srch_req_id; 687 ibcm_mode_t srch_mode; 688 } ibcm_sidr_srch_t; 689 690 _NOTE(READ_ONLY_DATA(ibcm_sidr_srch_s)) 691 692 /* 693 * Incr/Decr ud_ref_cnt by 1 694 */ 695 #define IBCM_UD_REF_CNT_INCR(s) ((s)->ud_ref_cnt++) 696 #define IBCM_UD_REF_CNT_DECR(s) \ 697 if ((--(s->ud_ref_cnt) == 0) && (s->ud_delete_state_data == B_TRUE)) { \ 698 ibcm_add_ud_tlist(s);\ 699 } \ 700 ASSERT(s->ud_ref_cnt >= 0); 701 702 /* 703 * Structure to store the Service Registration and Service Bind entries. 704 * 705 * Well known service id's are unique on a given HCA, but can be registered 706 * only at some GID's. Hence can be multiple GID's per Service ID. For each 707 * such GID and PKEY combination registered, there will be an ibcm_svc_info_t 708 * entry in the CM global service list. 709 * 710 * Annex A of the spec constrains that there shall be one service provider per 711 * service id, which implies same svc_rc_handler for all such entries 712 * There can be multiple transport types (svc_tran_type) per Service ID. For 713 * each such transport type, there will be an ibcm_svc_info_t entry in the 714 * CM global service list and cm handler can be different 715 * 716 * For locally allocated service id's (maintained by OS), there can be only 717 * one GID, where the service can be registered 718 * 719 * svc_id: Service ID 720 * svc_num_sids: Number (Range) of service-ids supported 721 * svc_flags: Service flags specified at registration time 722 * svc_link: Global AVL tree of ibcm_svc_info_t structs 723 * svc_rc_handler: Server handler for RC (only one is valid at a time) 724 * svc_ud_handler: Server handler for UD (only one is valid at a time) 725 * svc_ref_cnt: Reference count 726 * svc_to_delete: If 1, then the entry is marked to be deleted 727 * 728 * sbind_gid: GID 729 * sbind_pkey: P_Key 730 * sbind_lease: Service Lease 731 * sbind_name: Service Name 732 */ 733 typedef struct ibcm_svc_info_s { 734 avl_node_t svc_link; 735 struct ibcm_svc_bind_s *svc_bind_list; 736 ibt_cm_handler_t svc_rc_handler; 737 ibt_cm_ud_handler_t svc_ud_handler; 738 int svc_ref_cnt; 739 int svc_to_delete; 740 ib_svc_id_t svc_id; 741 int svc_num_sids; 742 ibt_service_flags_t svc_flags; 743 } ibcm_svc_info_t; 744 745 typedef struct ibcm_svc_bind_s { 746 struct ibcm_svc_bind_s *sbind_link; 747 void *sbind_cm_private; 748 ib_gid_t sbind_gid; 749 ib_guid_t sbind_hcaguid; 750 uint64_t sbind_key[2]; 751 /* sbind_data is assumed to be 8-byte aligned */ 752 uint8_t sbind_data[IB_SVC_DATA_LEN]; /* ServiceData */ 753 uint32_t sbind_lease; 754 ib_pkey_t sbind_pkey; 755 uint8_t sbind_port; 756 uint8_t sbind_rewrite_state; 757 char sbind_name[IB_SVC_NAME_LEN]; 758 } ibcm_svc_bind_t; 759 760 /* 761 * Service records may be lost by the SM/SA (reboot, change in who 762 * is the master, etc.). When any of the above occurs, a PORT_UP 763 * async event is supposed to occur, at which point we mark all of 764 * our service record information as stale (REWRITE_NEEDED), and 765 * subsequently make the necessary sa_update calls to get the 766 * SM/SA in sync with all the service records we previously wrote. 767 * 768 * Values for sbind_rewrite_state follow. This field is protected by 769 * ibcm_svc_info_lock. ibt_unbind_service has to wait until a service 770 * binding is either idle or needed, sleeping on ibcm_svc_info_cv if 771 * busy (rewrite in progress). 772 */ 773 #define IBCM_REWRITE_IDLE 0 774 #define IBCM_REWRITE_NEEDED 1 775 #define IBCM_REWRITE_BUSY 2 776 777 typedef struct ibcm_port_up_s { 778 ib_guid_t pup_hca_guid; 779 uint8_t pup_port; 780 } ibcm_port_up_t; 781 782 /* arg is a pointer to ibcm_port_up_t */ 783 extern void ibcm_service_record_rewrite_task(void *); 784 785 #define IBCM_SVC_INCR(svcinfop) (svcinfop)->svc_ref_cnt++ 786 #define IBCM_SVC_DECR(svcinfop) \ 787 if (--((svcinfop)->svc_ref_cnt) == 0 && \ 788 (svcinfop)->svc_to_delete) \ 789 cv_broadcast(&ibcm_svc_info_cv); \ 790 ASSERT(svcinfop->svc_ref_cnt >= 0); 791 792 _NOTE(READ_ONLY_DATA(ibcm_svc_info_s::{svc_rc_handler svc_ud_handler svc_id 793 svc_num_sids svc_flags})) 794 795 _NOTE(READ_ONLY_DATA(ibcm_svc_bind_s::{sbind_cm_private sbind_gid sbind_hcaguid 796 sbind_key sbind_data sbind_lease sbind_pkey sbind_port sbind_name})) 797 798 /* for avl tree search */ 799 typedef struct ibcm_svc_lookup_s { 800 ib_svc_id_t sid; 801 int num_sids; 802 } ibcm_svc_lookup_t; 803 804 typedef struct ibcm_ar_ref_s { 805 struct ibcm_ar_ref_s *ar_ref_link; 806 ibt_clnt_hdl_t ar_ibt_hdl; 807 } ibcm_ar_ref_t; 808 809 typedef struct ibcm_ar_s { 810 ibt_ar_t ar; 811 int ar_flags; /* 1 = INITING, 2 = FAILED */ 812 int ar_waiters; /* # of waiters */ 813 kcondvar_t ar_cv; 814 uint8_t ar_port; 815 uint8_t ar_rewrite_state; /* see sbind_rewrite_state */ 816 ibcm_ar_ref_t *ar_ibt_hdl_list; 817 struct ibcm_ar_s *ar_link; 818 sa_service_record_t *ar_srv_recp; 819 ibmf_saa_handle_t ar_saa_handle; 820 struct ibcm_hca_info_s *ar_hcap; 821 } ibcm_ar_t; 822 823 /* ar_flags */ 824 #define IBCM_AR_SUCCESS 0 825 #define IBCM_AR_FAILED 1 826 #define IBCM_AR_INITING 2 827 828 829 /* 830 * These flags are used for adding (if an entry does not exist) or 831 * for just looking one up 832 */ 833 typedef enum ibcm_lookup_flag_e { 834 IBCM_FLAG_LOOKUP = 0, /* just lookup */ 835 IBCM_FLAG_ADD = 1, /* just add */ 836 IBCM_FLAG_LOOKUP_AND_ADD = 2 /* lookup first. add if */ 837 /* lookup failed */ 838 } ibcm_lookup_flag_t; 839 840 typedef enum ibcm_finit_state_e { 841 IBCM_FINIT_INIT, /* CM's init is not yet completed */ 842 IBCM_FINIT_IDLE, /* CM not in either init or fini */ 843 IBCM_FINIT_BUSY, /* CM busy either in init or fini */ 844 IBCM_FINIT_FAIL, /* Init failed */ 845 IBCM_FINIT_SUCCESS /* Fini has succeeded */ 846 } ibcm_finit_state_t; 847 848 /* 849 * Identifies HCA's state. Used in the definition of ibcm_hca_info_t 850 * If HCA is in ACTIVE state only does CM allow any MAD processing. 851 */ 852 typedef enum ibcm_hca_state_e { 853 IBCM_HCA_INIT, 854 IBCM_HCA_ACTIVE, 855 IBCM_HCA_NOT_ACTIVE 856 } ibcm_hca_state_t; 857 858 /* QP information per pkey, stored in port information */ 859 typedef struct ibcm_qp_list_s { 860 ib_pkey_t qp_pkey; 861 ibmf_qp_handle_t qp_cm; 862 uint32_t qp_ref_cnt; 863 struct ibcm_port_info_s *qp_port; 864 struct ibcm_qp_list_s *qp_next; 865 } ibcm_qp_list_t; 866 867 _NOTE(READ_ONLY_DATA(ibcm_qp_list_s::{qp_pkey qp_cm qp_port qp_next})) 868 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibcm_qp_list_s)) 869 870 /* 871 * port information per HCA 872 * port_ibmf_hdl - contains IBMF handle for that port if valid 873 * otherwise is NULL 874 * port_ibmf_saa_hdl - contains SA Access handle for that port if valid 875 * otherwise is NULL 876 */ 877 typedef struct ibcm_port_info_s { 878 ibmf_handle_t port_ibmf_hdl; 879 ibmf_saa_handle_t port_ibmf_saa_hdl; 880 ib_gid_t port_sgid0; 881 uint8_t port_event_status; 882 uint8_t port_saa_open_in_progress; 883 uint8_t port_num; 884 ibmf_register_info_t port_ibmf_reg; 885 ibmf_impl_caps_t port_ibmf_caps; 886 ibcm_qp_list_t port_qp1; 887 ibcm_qp_list_t *port_qplist; 888 struct ibcm_hca_info_s *port_hcap; 889 } ibcm_port_info_t; 890 891 _NOTE(READ_ONLY_DATA(ibcm_port_info_s::{port_num port_ibmf_caps port_qp1 892 port_hcap})) 893 894 /* Value to indicate to exit the timeout list processing thread */ 895 #define IBCM_TIMEOUT_THREAD_EXIT 01 896 897 /* 898 * IBCM code relies on AVL routines already in kernel for faster lookups. 899 * AVL was chosen over mod hashing mechanism based on the its internal 900 * limitations in the kernel (no support for over 100,000 keys). 901 * 902 * IBCM uses two AVL trees on the passive side and one on active side per HCA. 903 * The two trees are need on the passive side because the tree lookup criteria 904 * changes based on the type of message being processed. On passive side it is 905 * based on remote_qpn and remote_hca_guid for only incoming REQ message and for 906 * for all other messages the search criteria is based upon remote_comid. 907 * On active side the lookup criteria remains static based upon local_comid. 908 * 909 * AVL tree insertions are done by grabbing the writer lock (hca_state_rwlock) 910 * and lookups are done by grabbing the reader lock. 911 */ 912 913 /* 914 * CM's per HCA data structure. 915 * 916 * One such entry is added/removed on hca attach/detach notifications to CM 917 * respectively. 918 * 919 * Comids are used for all connections. Req ids are used for SIDR REQ and 920 * SIDR REP messages. These are simple counters that wrap around INT_MAX. 921 * NOTE: The starting value for comid, per HCA, is 2. 922 * 923 * hca_state: HCA's current state (ibcm_hca_state_t) - whether 924 * IBT_HCA_ACTIVE, IBT_HCA_NOT_ACTIVE, 925 * hca_guid: Active HCA guid 926 * hca_caps: HCA capability mask 927 * hca_ack_delay: HCA ack delay 928 * hca_max_rdma_rd Max RDMA in Reads 929 * hca_max_rdma_dpt Max RDMA out Reads 930 * hca_active_tree: This tree is used for lookups on Active/Passive side 931 * CM based on communication id ONLY. 932 * hca_passive_tree: This tree is used to lookup/create ibcm_state_data_t on 933 * Passive Side CM based on remote_qpn and remote_hca_guid. 934 * hca_passive_comid_tree: 935 * This tree is used to lookup/create ibcm_state_data_t on 936 * Passive Side CM based on remote_comid and 937 * remote_hca_guid. 938 * hca_state_rwlock: reader/writer Lock for the hca entry 939 * for hca_active_tree 940 * for hca_passive_tree 941 * for hca_next_comid 942 * hca_sidr_list: List for UD side 943 * hca_sidr_list_lock: List lock for UD side 944 * for hca_sidr_list 945 * for hca_next_reqid 946 * hca_next_reqid: Next active ReqId 947 * hca_next_comid: Next active ComID 948 * hca_next: Pointer to the next HCA 949 * hca_svc_cnt: A count of services registered on this hca 950 * hca_acc_cnt: A count of active references to this ibcm_hca_info_t 951 * hca_res_cnt: A count of client's active resources on this hca 952 * hca_num_ports: Number of ports that this HCA has 953 * hca_port_info: Per port information (IBMA/SA access handles etc.) 954 * 955 * Note : The global mutex ibcm_global_hca_mutex declared in CM is used for 956 * accesses to the following fields : 957 * hca_acc_cnt, hca_res_cnt, hca_svc_cnt, hca_state 958 */ 959 typedef struct ibcm_hca_info_s { 960 ibcm_hca_state_t hca_state; /* Is HCA attached? */ 961 ib_guid_t hca_guid; /* HCA's guid value */ 962 ibt_hca_flags_t hca_caps; /* HCA capabilities */ 963 uint32_t hca_vendor_id:24; 964 uint16_t hca_device_id; 965 ib_time_t hca_ack_delay; /* HCA ack delay */ 966 uint8_t hca_max_rdma_in_qp; /* Max RDMA in Reads */ 967 uint8_t hca_max_rdma_out_qp; /* Max RDMA out Reads */ 968 vmem_t *hca_comid_arena; /* arena for com ids */ 969 vmem_t *hca_reqid_arena; /* arena for req ids */ 970 avl_tree_t hca_active_tree; /* active node tree */ 971 avl_tree_t hca_passive_tree; /* passive node tree */ 972 avl_tree_t hca_passive_comid_tree; /* passive comid tree */ 973 krwlock_t hca_state_rwlock; /* per HCA lock */ 974 ibcm_ud_state_data_t *hca_sidr_list; /* SIDR state list */ 975 krwlock_t hca_sidr_list_lock; 976 977 struct ibcm_hca_info_s *hca_next; /* Next HCA entry */ 978 979 int hca_svc_cnt; /* # of */ 980 /* services allocated */ 981 int hca_acc_cnt; /* active references */ 982 int hca_res_cnt; /* total resources */ 983 uint8_t hca_num_ports; /* #ports on this HCA */ 984 ibcm_port_info_t hca_port_info[1]; /* Per portinfo array */ 985 } ibcm_hca_info_t; 986 987 _NOTE(RWLOCK_PROTECTS_DATA(ibcm_hca_info_s::hca_state_rwlock, 988 ibcm_hca_info_s::{hca_active_tree hca_passive_tree hca_passive_comid_tree})) 989 990 _NOTE(SCHEME_PROTECTS_DATA("hca_sidr_list_lock protects hca_sidr_list", 991 ibcm_hca_info_s::{hca_sidr_list})) 992 993 _NOTE(READ_ONLY_DATA(ibcm_hca_info_s::{hca_guid hca_caps hca_ack_delay 994 hca_max_rdma_in_qp hca_max_rdma_out_qp hca_comid_arena hca_reqid_arena 995 hca_passive_tree hca_active_tree hca_passive_comid_tree hca_num_ports })) 996 997 /* Are we on Tavor HCA */ 998 #define IBCM_IS_HCA_TAVOR(hcap) \ 999 (((hcap)->hca_device_id == 0x5a44) && ((hcap)->hca_vendor_id == 0x15b3)) 1000 1001 /* 1002 * called to ensure that HCA is in "attached" state and is willing to 1003 * process connections etc. 1004 */ 1005 #define IBCM_ACCESS_HCA_OK(s) ((s)->hca_state == IBCM_HCA_ACTIVE) 1006 1007 /* 1008 * Passive AVL tree lookup info (for hca_passive_tree) 1009 * CM needs this structure as passive tree lookups are based on 1010 * QPN and HCA GUID. 1011 */ 1012 typedef struct ibcm_passive_node_info_s { 1013 ib_qpn_t info_qpn; 1014 ib_guid_t info_hca_guid; 1015 } ibcm_passive_node_info_t; 1016 1017 /* 1018 * Passive Com ID AVL tree lookup info (for hca_passive_comid_tree) 1019 * CM needs this structure as passive comid tree lookups are based on 1020 * Remote Com ID and Remote HCA GUID. 1021 */ 1022 typedef struct ibcm_passive_comid_node_info_s { 1023 ib_com_id_t info_comid; 1024 ib_guid_t info_hca_guid; 1025 } ibcm_passive_comid_node_info_t; 1026 1027 /* CM proceed task args structure definition */ 1028 typedef struct ibcm_proceed_targs_s { 1029 ibt_cm_event_type_t event; 1030 ibt_cm_status_t status; 1031 union tst_t { 1032 struct rc_s { 1033 ibcm_state_data_t *statep; 1034 ibt_cm_proceed_reply_t rc_cm_event_data; 1035 } rc; 1036 struct ud_s { 1037 ibcm_ud_state_data_t *ud_statep; 1038 ib_qpn_t ud_qpn; 1039 ib_qkey_t ud_qkey; 1040 ibt_redirect_info_t ud_redirect_info; 1041 } ud; 1042 } tst; 1043 ibt_priv_data_len_t priv_data_len; 1044 /* keep priv_data as the last field */ 1045 uint8_t priv_data[IBT_MAX_PRIV_DATA_SZ]; 1046 } ibcm_proceed_targs_t; 1047 1048 _NOTE(READ_ONLY_DATA(ibcm_proceed_targs_s)) 1049 1050 1051 /* 1052 * function prototypes for AVL tree compares 1053 */ 1054 int ibcm_active_node_compare(const void *, const void *); 1055 int ibcm_passive_node_compare(const void *, const void *); 1056 int ibcm_passive_comid_node_compare(const void *, const void *); 1057 1058 /* 1059 * function prototypes to allocate IBMF/SA_ACCESS handles 1060 */ 1061 ibt_status_t ibcm_hca_reinit_port(ibcm_hca_info_t *hca_p, 1062 uint8_t port_index); 1063 1064 /* function prototypes to Manage CM's IBMF QP's */ 1065 1066 ibcm_qp_list_t *ibcm_find_qp(ibcm_hca_info_t *hcap, int port_no, 1067 ib_pkey_t pkey); 1068 1069 void ibcm_release_qp(ibcm_qp_list_t *cm_qp_entry); 1070 1071 ibcm_status_t ibcm_free_qp(ibcm_qp_list_t *cm_qp_entry); 1072 1073 ibcm_status_t ibcm_free_allqps(ibcm_hca_info_t *hcap, int port_no); 1074 1075 /* 1076 * function prototypes to allocate and free outgoing CM messages 1077 */ 1078 ibt_status_t 1079 ibcm_alloc_out_msg(ibmf_handle_t ibmf_handle, ibmf_msg_t **ibmf_msgpp, 1080 uint8_t method); 1081 ibcm_status_t 1082 ibcm_free_out_msg(ibmf_handle_t ibmf_handle, ibmf_msg_t **ibmf_msgpp); 1083 1084 /* 1085 * Definition for CM state transition processing function 1086 */ 1087 typedef void (*ibcm_state_handler_t)(ibcm_hca_info_t *hcap, 1088 uint8_t *cm_input_mad, ibcm_mad_addr_t *cm_mad_addr); 1089 1090 /* 1091 * CM REQ Message structure 1092 * 1093 * Request for communication. 1094 * 1095 * Things of interest are:- 1096 * ib_qpn_t cannot be used - it is typecast to uint32_t but is 24 bits 1097 * ib_eecn_t cannot be used - it is typecast to uint32_t but is 24 bits 1098 * 1099 * (See Table 85 REQ Message Contents - chapter 12 in IB Spec v1.0a) 1100 * 1101 */ 1102 typedef struct ibcm_req_msg_s { 1103 ib_com_id_t req_local_comm_id; /* Local communication id */ 1104 /* 32 bits */ 1105 uint32_t req_rsvd1; /* Reserved1 - 32 bits */ 1106 ib_svc_id_t req_svc_id; /* Service Id - 64 bits */ 1107 ib_guid_t req_local_ca_guid; /* Local CA GUID - 64 bits */ 1108 uint32_t req_rsvd1p; /* Reserved1+ - 32 bits */ 1109 ib_qkey_t req_local_qkey; /* Local Q_KEY - 32 bits */ 1110 uint32_t req_local_qpn_plus; /* QPN_24 RESP_RSRC_8 */ 1111 /* local side QPN - 24 bits */ 1112 /* Offered responder */ 1113 /* resources - 8 bits */ 1114 uint32_t req_local_eec_no_plus; /* LOCAL_EECN_24 INIT_DEPTH_8 */ 1115 /* Local side EECN - 24 bits */ 1116 /* Offered initiator */ 1117 /* depth - 8 bits */ 1118 uint32_t req_remote_eecn_plus; /* REM_EECN_24 TO_5 TT_2 EE_1 */ 1119 /* Remote side EECN - 24 bits */ 1120 /* Remote CM timeout - 5 bits */ 1121 /* Transport srvtype - 2 bits */ 1122 /* End-to-End flow - 1 bit */ 1123 uint32_t req_starting_psn_plus; /* START_PSN_24 TO_5 RETRY_3 */ 1124 /* Starting PSN - 24 bits */ 1125 /* Local CM timeout - 5 bits */ 1126 /* Retry count - 3 bits */ 1127 ib_pkey_t req_part_key; /* Partition key - 16 bits */ 1128 uint8_t req_mtu_plus; /* PATH_MTU_4 RDC_1 RNR_3 */ 1129 /* Path Pkt MTU - 4 bits */ 1130 /* Does RDC exist? - 1 bits */ 1131 /* RNR retry count - 3 bits */ 1132 uint8_t req_max_cm_retries_plus; /* MAX_CM_RET_4 SRQ_1 RSV_3 */ 1133 /* Max CM retries - 4 bits */ 1134 /* SRQ Exists - 1 bit */ 1135 /* Reserved2 - 3 bits */ 1136 ib_lid_t req_primary_l_port_lid; /* Primary local port LID */ 1137 ib_lid_t req_primary_r_port_lid; /* Primary Remote port LID */ 1138 ib_gid_t req_primary_l_port_gid; /* Primary local port GID */ 1139 ib_gid_t req_primary_r_port_gid; /* Primary remote port GID */ 1140 uint32_t req_primary_flow_label_plus; /* FLOW_20 RSV_4 SRATE_6 */ 1141 /* Prim. flow label - 20 bits */ 1142 /* Reserved3 - 6 bits */ 1143 /* Primary rate - 6 bits */ 1144 uint8_t req_primary_traffic_class; 1145 /* Primary Traffic class */ 1146 uint8_t req_primary_hop_limit; /* Prim Hop Limit */ 1147 uint8_t req_primary_sl_plus; /* PRIMARY_SL_4 LOCAL_1 RSV_3 */ 1148 /* Primary SL - 4 bits */ 1149 /* Prim. subnet local - 1 bit */ 1150 /* Reserved4 - 3 bits */ 1151 uint8_t req_primary_localtime_plus; /* LOCAL_TO_5 RSV_3 */ 1152 /* Primary local */ 1153 /* timeout - 5 bits */ 1154 /* Reserved5 - 3 bits */ 1155 ib_lid_t req_alt_l_port_lid; /* Alt local port LID */ 1156 ib_lid_t req_alt_r_port_lid; /* Alt Remote port LID */ 1157 /* Note: req_alt_l_port_gid/req_alt_r_port_gid are not 8-byte aligned */ 1158 uint8_t req_alt_l_port_gid[16]; /* Alt local port GID */ 1159 uint8_t req_alt_r_port_gid[16]; /* Alt remote port GID */ 1160 uint32_t req_alt_flow_label_plus; /* ALT_FLOW_20 RSV_6 ARATE_6 */ 1161 /* Alt flow label - 20 bits */ 1162 /* Reserved6 - 6 bits */ 1163 /* Alternate rate - 6 bits */ 1164 uint8_t req_alt_traffic_class; /* Alt traffic class */ 1165 uint8_t req_alt_hop_limit; /* Alt hop limit */ 1166 uint8_t req_alt_sl_plus; /* ALT_SL_4 A_LOCAL_1 RSV_3 */ 1167 /* Alternate SL - 4 bits */ 1168 /* Alt subnet local - 1 bit */ 1169 /* Reserved7 - 3 bits */ 1170 uint8_t req_alt_localtime_plus; /* ALT_LOCAL_ACK_TO_5 RSV_3 */ 1171 /* Alt Local ACK */ 1172 /* timeout - 5 bits */ 1173 /* Reserved8 - 3 bits */ 1174 uint8_t req_private_data[IBT_REQ_PRIV_DATA_SZ]; 1175 /* Private data */ 1176 } ibcm_req_msg_t; 1177 1178 1179 /* 1180 * The following set of defines are short-cuts to CEP_PATH or GRH info 1181 */ 1182 #define IBCM_PRIM_CEP_PATH(s) (s)->oc_path->pi_prim_cep_path 1183 #define IBCM_PRIM_ADDS_VECT(s) (s)->oc_path->pi_prim_cep_path.cep_adds_vect 1184 1185 #define IBCM_ALT_CEP_PATH(s) (s)->oc_path->pi_alt_cep_path 1186 #define IBCM_ALT_ADDS_VECT(s) (s)->oc_path->pi_alt_cep_path.cep_adds_vect 1187 1188 #define IBCM_UD_CEP_PATH(s) (s)->us_path_info->ai_cep_path 1189 #define IBCM_UD_ADDS_VECT(s) (s)->us_path_info->ai_cep_path.cep_adds_vect 1190 1191 /* 1192 * The following set of defines are short-cuts to ibt_cm_event_t 1193 */ 1194 #define IBCM_EVT_REQ(e) (e).cm_event.req 1195 #define IBCM_EVT_REP(e) (e).cm_event.rep 1196 1197 /* 1198 * The following set of defines are short-cuts to qp_attrs or qp_info 1199 */ 1200 #define IBCM_QP_RC(q) (q).qp_info.qp_transport.rc 1201 #define IBCM_QP_UD(q) (q).qp_info.qp_transport.ud 1202 #define IBCM_QP_UC(q) (q).qp_info.qp_transport.uc 1203 1204 #define IBCM_QPINFO(q) (q).qp_transport 1205 #define IBCM_QPINFO_RC(q) (q).qp_transport.rc 1206 #define IBCM_QPINFO_RC_PATH(q) (q).qp_transport.rc.rc_path 1207 #define IBCM_QPINFO_UC(q) (q).qp_transport.uc 1208 #define IBCM_QPINFO_UC_PATH(q) (q).qp_transport.uc.uc_path 1209 #define IBCM_QPINFO_UD(q) (q).qp_transport.ud 1210 1211 1212 /* The following set of defines are short-cuts to RC and SIDR MAD HDRs */ 1213 1214 #define IBCM_OUT_MADP(msgp) (msgp->im_msgbufs_send.im_bufs_mad_hdr) 1215 #define IBCM_OUT_HDRP(msgp) ((ib_mad_hdr_t *)IBCM_OUT_MADP(msgp)) 1216 #define IBCM_OUT_MSGP(msgp) (msgp->im_msgbufs_send.im_bufs_cl_data) 1217 1218 #define IBCM_IN_MADP(msgp) (msgp->im_msgbufs_recv.im_bufs_mad_hdr) 1219 #define IBCM_IN_HDRP(msgp) ((ib_mad_hdr_t *)IBCM_IN_MADP(msgp)) 1220 #define IBCM_IN_MSGP(msgp) (msgp->im_msgbufs_recv.im_bufs_cl_data) 1221 1222 #define IBCM_REJ_PRIV(msgp) &(((ibcm_rej_msg_t *) \ 1223 IBCM_OUT_MSGP(statep->stored_msg))->rej_private_data[0]) 1224 /* 1225 * CM MRA Message structure 1226 * 1227 * Message Receipt Acknowledgement (MRA). 1228 * 1229 * NOTE: IB hosts and targets are required to be able to receive and 1230 * act upon an MRA, but the ability to send an MRA is optional. 1231 */ 1232 typedef struct ibcm_mra_msg_s { 1233 ib_com_id_t mra_local_comm_id; /* Local communication id */ 1234 ib_com_id_t mra_remote_comm_id; /* Remote communication id */ 1235 uint8_t mra_message_type_plus; /* Message Type - 2 bits */ 1236 /* Reserved1 - 6 bits */ 1237 uint8_t mra_service_timeout_plus; /* SVC_TO_5 RSV_3 */ 1238 /* Service timeout - 5 bits */ 1239 /* Reserved2 - 3 bits */ 1240 uint8_t mra_private_data[IBT_MRA_PRIV_DATA_SZ]; 1241 /* Private data */ 1242 } ibcm_mra_msg_t; 1243 1244 /* 1245 * CM REJ Message structure 1246 * REJ indicates that the sender will not continue through the communication 1247 * establishment sequence and the reason why it will not. 1248 * 1249 * NOTE: See ibt_cm_reason_t in common/sys/ib/ib_cm.h for complete list 1250 * of rejection reasons supported. 1251 */ 1252 typedef struct ibcm_rej_msg_s { 1253 ib_com_id_t rej_local_comm_id; /* Local communication id */ 1254 ib_com_id_t rej_remote_comm_id; /* Remote communication id */ 1255 uint8_t rej_msg_type_plus; /* REJ_MSG_TYPE_2 RSV_6 */ 1256 /* Msg being REJed - 2 bits */ 1257 /* Reserved1 - 6 bits */ 1258 uint8_t rej_reject_info_len_plus; /* REJ_INFO_LEN_7 RSV_1 */ 1259 /* Rej. Info Length - 7 bits */ 1260 /* Reserved2 - 1 bit */ 1261 uint16_t rej_rejection_reason; /* Reject err code - 16 bits */ 1262 uint8_t rej_addl_rej_info[IBT_CM_ADDL_REJ_LEN]; 1263 /* Additional Reject Info */ 1264 uint8_t rej_private_data[IBT_REJ_PRIV_DATA_SZ]; 1265 /* Private data */ 1266 } ibcm_rej_msg_t; 1267 1268 /* 1269 * CM REP Message structure 1270 * 1271 * REP is returned in response to REQ, indicating that the respondent 1272 * accepts the Service-ID, proposed primary port, and any parameters 1273 * specified in the PrivateData of the REQ. 1274 */ 1275 typedef struct ibcm_rep_msg_s { 1276 ib_com_id_t rep_local_comm_id; /* Local communication id */ 1277 ib_com_id_t rep_remote_comm_id; /* Remote communication id */ 1278 ib_qkey_t rep_local_qkey; /* Local Q_KEY */ 1279 uint32_t rep_local_qpn_plus; /* LOCAL_QPN_24 RSV_8 */ 1280 /* Local side QPN - 24 bits */ 1281 /* Reserved1 - 8 bits */ 1282 uint32_t rep_local_eecn_plus; /* LOCAL_EECN_24 RSV_8 */ 1283 /* Local side EECN - 24 bits */ 1284 /* Reserved2 - 8 bits */ 1285 uint32_t rep_starting_psn_plus; /* STARTING_PSN_24 RSV_8 */ 1286 /* Starting PSN - 24 bits */ 1287 /* Reserved3 - 8 bits */ 1288 uint8_t rep_resp_resources; /* Responder resources 8 bits */ 1289 uint8_t rep_initiator_depth; /* Initiator depth - 8 bits */ 1290 uint8_t rep_target_delay_plus; /* TGT_ACK_DLY_5 FAIL_2 EE_1 */ 1291 /* Target ACK delay - 5 bits */ 1292 /* Failover accepted - 2 bits */ 1293 /* End-to-End flow control - */ 1294 /* 1 bit */ 1295 uint8_t rep_rnr_retry_cnt_plus; /* RNR_COUNT_3 SRQ_1 RSV_4 */ 1296 /* RNR retry count - 3 bits */ 1297 /* SRQ Exists - 1 bit */ 1298 /* Reserved4 - 4 bits */ 1299 uint8_t rep_local_ca_guid[8]; /* Local CA GUID - 64 bits */ 1300 uint8_t rep_private_data[IBT_REP_PRIV_DATA_SZ]; 1301 /* Private data */ 1302 } ibcm_rep_msg_t; 1303 1304 1305 /* 1306 * CM RTU Message structure 1307 * 1308 * RTU indicates that the connection is established, and that the 1309 * recipient may begin transmitting. 1310 */ 1311 typedef struct ibcm_rtu_msg_s { 1312 ib_com_id_t rtu_local_comm_id; /* Local communication id */ 1313 ib_com_id_t rtu_remote_comm_id; /* Remote communication id */ 1314 uint8_t rtu_private_data[IBT_RTU_PRIV_DATA_SZ]; 1315 /* Private data */ 1316 } ibcm_rtu_msg_t; 1317 1318 1319 /* 1320 * CM DREQ Message structure 1321 * 1322 * DREQ is sent to initiate the connection release sequence. 1323 */ 1324 typedef struct ibcm_dreq_msg_s { 1325 ib_com_id_t dreq_local_comm_id; /* Local communication id */ 1326 ib_com_id_t dreq_remote_comm_id; /* Remote communication id */ 1327 uint32_t dreq_remote_qpn_eecn_plus; /* REM_EECN_24 RSV_8 */ 1328 /* Remote QPN/EECN - 24 bits */ 1329 /* reserved - 8 bits */ 1330 uint8_t dreq_private_data[IBT_DREQ_PRIV_DATA_SZ]; 1331 /* Private data */ 1332 } ibcm_dreq_msg_t; 1333 1334 1335 /* 1336 * CM DREP Message structure 1337 * 1338 * DREP is sent in response to DREQ, and signifies that the sender has 1339 * received DREQ. 1340 */ 1341 typedef struct ibcm_drep_msg_s { 1342 ib_com_id_t drep_local_comm_id; /* Local communication id */ 1343 ib_com_id_t drep_remote_comm_id; /* Remote communication id */ 1344 uint8_t drep_private_data[IBT_DREP_PRIV_DATA_SZ]; 1345 /* Private Data */ 1346 } ibcm_drep_msg_t; 1347 1348 1349 /* 1350 * CM LAP Message structure 1351 * 1352 * NOTE: LAP and APR messages are optional. These are needed if CM 1353 * accepts REQ messages and agrees to perform Automatic Path Migration. 1354 * 1355 * This message is used to change the alternate path information for a 1356 * specific connection. 1357 */ 1358 typedef struct ibcm_lap_msg_s { 1359 ib_com_id_t lap_local_comm_id; /* Local communication id */ 1360 ib_com_id_t lap_remote_comm_id; /* Remote communication id */ 1361 uint32_t lap_rsvd1; /* Reserved - 32 bits */ 1362 uint32_t lap_remote_qpn_eecn_plus; /* REM_EECN_24 TO_5 RSV_3 */ 1363 /* Remote QPN/EECN - 24 bits */ 1364 /* Remote CM response */ 1365 /* timeout - 5 bits */ 1366 /* Reserved1 - 3 bits */ 1367 uint32_t lap_rsvd2; /* Reserved2 - 32 bits */ 1368 ib_lid_t lap_alt_l_port_lid; /* Alt local port LID */ 1369 ib_lid_t lap_alt_r_port_lid; /* Alt Remote port LID */ 1370 ib_gid_t lap_alt_l_port_gid; /* Alt local port GID */ 1371 ib_gid_t lap_alt_r_port_gid; /* Alt remote port GID */ 1372 uint32_t lap_alt_flow_label_plus; /* ALT_FLOW_20 RSV_4 TCL_8 */ 1373 /* Alt flow label - 20 bits */ 1374 /* Reserved3 - 4 bits */ 1375 /* Alt traffic class - 8 bits */ 1376 uint8_t lap_alt_hop_limit; /* Alt hop limit */ 1377 uint8_t lap_alt_srate_plus; /* Reserved4 - 2 bits */ 1378 /* Alt. static rate - 6 bits */ 1379 uint8_t lap_alt_sl_plus; /* ALT_SL_4 A_LOCAL_1 RSV_3 */ 1380 /* Alternate SL - 4 bits */ 1381 /* Alt subnet local - 1 bit */ 1382 /* Reserved5 - 3 bits */ 1383 uint8_t lap_alt_local_acktime_plus; /* ALT_TO_5 RSV_3 */ 1384 /* Alt Local ACK */ 1385 /* timeout - 5 bits */ 1386 /* Reserved6 - 3 bits */ 1387 uint8_t lap_private_data[IBT_LAP_PRIV_DATA_SZ]; 1388 /* Private data */ 1389 } ibcm_lap_msg_t; 1390 1391 1392 /* 1393 * CM APR Message structure 1394 * 1395 * APR is sent in response to a LAP request. MRA may be sent to allow 1396 * processing of the LAP. 1397 */ 1398 typedef struct ibcm_apr_msg_s { 1399 ib_com_id_t apr_local_comm_id; /* Local communication id */ 1400 ib_com_id_t apr_remote_comm_id; /* Remote communication id */ 1401 uint8_t apr_addl_info_len; /* Add'l Info Len - 8 bits */ 1402 uint8_t apr_ap_status; /* AP status - 8 bits */ 1403 uint16_t apr_rsvd1; /* Reserved1 - 16 bits */ 1404 uint8_t apr_addl_info[IBT_CM_APR_ADDL_LEN]; 1405 /* Additional Information */ 1406 uint8_t apr_private_data[IBT_APR_PRIV_DATA_SZ]; 1407 /* Private data */ 1408 } ibcm_apr_msg_t; 1409 1410 1411 /* 1412 * CM SIDR_REQ Message structure 1413 * 1414 * NOTE: SIDR_REQ and SIDR_REP messages are conditionally required. 1415 * These are needed if non-management services are provided on the Channel 1416 * Adapter other than fixed QPNs. Management services include those 1417 * provided thru Subnet Manager Packets or thru General Management Packets. 1418 * 1419 * SIDR_REQ requests that the recipient return the information necessary 1420 * to communicate via UD messages with the entity specified by 1421 * SIDR_REQ:ServiceID 1422 */ 1423 typedef struct ibcm_sidr_req_msg_s { 1424 uint32_t sidr_req_request_id; /* Request id */ 1425 ib_pkey_t sidr_req_pkey; /* P_Key */ 1426 uint8_t sidr_req_reserved[2]; /* Reserved */ 1427 ib_svc_id_t sidr_req_service_id; /* Service Id */ 1428 uint8_t sidr_req_private_data[IBT_SIDR_REQ_PRIV_DATA_SZ]; 1429 /* Private Data */ 1430 } ibcm_sidr_req_msg_t; 1431 1432 1433 /* 1434 * CM SIDR_REP Message structure 1435 * 1436 * SIDR_REP returns the information necessary to communicate via UD 1437 * messages with the entity specified by SIDR_REQ:ServiceID 1438 */ 1439 typedef struct ibcm_sidr_rep_msg_s { 1440 uint32_t sidr_rep_request_id; /* Request id */ 1441 uint8_t sidr_rep_rep_status; /* Status */ 1442 uint8_t sidr_rep_add_info_len; /* Length of Add Info */ 1443 uint8_t sidr_rep_reserved1[2]; /* Reserved */ 1444 uint32_t sidr_rep_qpn_plus; /* QPN_24 RSV_8 */ 1445 /* since the 64-bit SID is not aligned, treat it as a byte array */ 1446 uint8_t sidr_rep_service_id[8]; /* Service Id */ 1447 ib_qkey_t sidr_rep_qkey; /* Q_KEY */ 1448 uint8_t sidr_rep_class_port_info[IBT_CM_SIDR_CP_LEN]; 1449 /* Class Port Info */ 1450 /* aka., add'l info */ 1451 uint8_t sidr_rep_private_data[IBT_SIDR_REP_PRIV_DATA_SZ]; 1452 /* Private data */ 1453 } ibcm_sidr_rep_msg_t; 1454 1455 typedef struct ibcm_classportinfo_msg_s { 1456 uint8_t BaseVersion; /* ver. of MAD base format */ 1457 uint8_t ClassVersion; /* ver. of MAD class format */ 1458 uint16_t CapabilityMask; /* capabilities of this class */ 1459 uint32_t RespTimeValue_plus; /* reserved : 27 bits */ 1460 /* resptime value : 5 bits */ 1461 uint64_t RedirectGID_hi; /* dest gid of redirect msgs */ 1462 uint64_t RedirectGID_lo; /* dest gid of redirect msgs */ 1463 uint32_t RedirectTC_plus; /* traffic class: 8 bits */ 1464 /* SL: 4 bits */ 1465 /* Flow label: 20 bits */ 1466 ib_lid_t RedirectLID; /* dlid for class services */ 1467 ib_pkey_t RedirectP_Key; /* p_key for class services */ 1468 uint32_t RedirectQP_plus; /* Reserved: 8 bits */ 1469 /* QPN: 24 bits */ 1470 ib_qkey_t RedirectQ_Key; /* q_key for class services */ 1471 uint64_t TrapGID_hi; /* dest gid of trap msgs */ 1472 uint64_t TrapGID_lo; /* dest gid of trap msgs */ 1473 uint32_t TrapTC_plus; /* Trap traffic class, etc., */ 1474 ib_lid_t TrapLID; /* dlid for traps */ 1475 ib_pkey_t TrapP_Key; /* p_key for traps */ 1476 uint32_t TrapHL_plus; /* Trap hop limit,etc., */ 1477 ib_qkey_t TrapQ_Key; /* q_key for traps */ 1478 } ibcm_classportinfo_msg_t; 1479 1480 /* All msgs are readonly on receiving side */ 1481 _NOTE(READ_ONLY_DATA(ibcm_req_msg_s)) 1482 _NOTE(READ_ONLY_DATA(ibcm_rep_msg_s)) 1483 _NOTE(READ_ONLY_DATA(ibcm_mra_msg_s)) 1484 _NOTE(READ_ONLY_DATA(ibcm_rej_msg_s)) 1485 _NOTE(READ_ONLY_DATA(ibcm_lap_msg_s)) 1486 _NOTE(READ_ONLY_DATA(ibcm_apr_msg_s)) 1487 _NOTE(READ_ONLY_DATA(ibcm_sidr_req_msg_s)) 1488 _NOTE(READ_ONLY_DATA(ibcm_sidr_rep_msg_s)) 1489 _NOTE(READ_ONLY_DATA(ibcm_rtu_msg_s)) 1490 _NOTE(READ_ONLY_DATA(ibcm_dreq_msg_s)) 1491 _NOTE(READ_ONLY_DATA(ibcm_drep_msg_s)) 1492 _NOTE(READ_ONLY_DATA(ibcm_classportinfo_msg_s)) 1493 1494 /* Prototype definitions for CM implementation functions */ 1495 1496 /* 1497 * The callback from IBMF to CM. This routines calls one of the CM 1498 * state processing functions depending upon mesg/attribute id 1499 * 1500 * ibmf_handle : IBMF handle on which CM MAD was received 1501 * pktp : MAD packet 1502 * args : IBMF receive mad callback arg 1503 */ 1504 void ibcm_recv_cb(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, void *args); 1505 1506 /* 1507 * Prototypes for CM state transition handling functions 1508 */ 1509 1510 /* 1511 * The following are the CM state processing functions called on an 1512 * incoming REQ/REP/RTU/MRA/REJ/DREQ/DREP on active/passive sides 1513 * (Also handled are SIDR_REP and SIDR_REQ) 1514 * The brief description of these functions 1515 * Search based on CM message fields in CM's HCA entry. 1516 * Create/Delete state structures based on incoming message 1517 * Handle duplicate messages and state transitions 1518 * Set and Cancel timeouts 1519 * Handle stale connections 1520 * Change CM connection state 1521 * Call CM CEP state transition functions to update CEP state 1522 * and set CEP attributes 1523 * 1524 * INPUTS: 1525 * hcap: - IBMF callback argument 1526 * cm_input_mad: - ibmf message pointer of incoming MAD 1527 * cm_mad_addr - CM MAD address 1528 * 1529 * The state transition processing is specified in different functions based 1530 * on incoming message type rather than as one function because, the CM 1531 * processing is different for each of them. 1532 * 1533 * A global call table is initialized with these function addresses 1534 * (is defined in ibcm_impl.c), and invoked from ibcm_recv_cb 1535 * (IBMF's recv callback to CM) based on mesg/attribute id. 1536 */ 1537 void ibcm_process_req_msg(ibcm_hca_info_t *hcap, uint8_t *cm_input_mad, 1538 ibcm_mad_addr_t *cm_mad_addr); 1539 void ibcm_process_rep_msg(ibcm_hca_info_t *hcap, uint8_t *cm_input_mad, 1540 ibcm_mad_addr_t *cm_mad_addr); 1541 void ibcm_process_rtu_msg(ibcm_hca_info_t *hcap, uint8_t *cm_input_mad, 1542 ibcm_mad_addr_t *cm_mad_addr); 1543 void ibcm_process_dreq_msg(ibcm_hca_info_t *hcap, uint8_t *cm_input_mad, 1544 ibcm_mad_addr_t *cm_mad_addr); 1545 void ibcm_process_drep_msg(ibcm_hca_info_t *hcap, uint8_t *cm_input_mad, 1546 ibcm_mad_addr_t *cm_mad_addr); 1547 void ibcm_process_rej_msg(ibcm_hca_info_t *hcap, uint8_t *cm_input_mad, 1548 ibcm_mad_addr_t *cm_mad_addr); 1549 void ibcm_process_mra_msg(ibcm_hca_info_t *hcap, uint8_t *cm_input_mad, 1550 ibcm_mad_addr_t *cm_mad_addr); 1551 void ibcm_process_apr_msg(ibcm_hca_info_t *hcap, uint8_t *cm_input_mad, 1552 ibcm_mad_addr_t *cm_mad_addr); 1553 void ibcm_process_lap_msg(ibcm_hca_info_t *hcap, uint8_t *cm_input_mad, 1554 ibcm_mad_addr_t *cm_mad_addr); 1555 void ibcm_process_sidr_req_msg(ibcm_hca_info_t *hcap, 1556 uint8_t *cm_input_mad, ibcm_mad_addr_t *cm_mad_addr); 1557 void ibcm_process_sidr_rep_msg(ibcm_hca_info_t *hcap, 1558 uint8_t *cm_input_mad, ibcm_mad_addr_t *cm_mad_addr); 1559 1560 typedef enum ibcm_proceed_error_e { 1561 IBCM_PROCEED_INVALID_NONE = 0, 1562 IBCM_PROCEED_INVALID_EVENT, 1563 IBCM_PROCEED_INVALID_EVENT_STATE, 1564 IBCM_PROCEED_INVALID_PRIV_SZ, 1565 IBCM_PROCEED_INVALID_LAP 1566 } ibcm_proceed_error_t; 1567 1568 /* Encapsulates the information that client returns back from CM callback */ 1569 typedef struct ibcm_clnt_reply_info_s { 1570 ibt_cm_proceed_reply_t *reply_event; 1571 void *priv_data; 1572 ibt_priv_data_len_t priv_data_len; 1573 } ibcm_clnt_reply_info_t; 1574 1575 /* Encapsulates the information that UD client returns back from CM callback */ 1576 typedef struct ibcm_ud_clnt_reply_info_s { 1577 ib_qpn_t ud_qpn; 1578 ib_qkey_t ud_qkey; 1579 ibt_redirect_info_t *redirect_infop; 1580 void *priv_data; 1581 ibt_priv_data_len_t priv_data_len; 1582 } ibcm_ud_clnt_reply_info_t; 1583 1584 /* 1585 * Prototypes for CM CEP state transition handling functions. These are 1586 * called from CM connection state transition handling functions. 1587 * 1588 * The brief description of these functions : 1589 * Validate CEP related attributes in the messages 1590 * Change CEP state 1591 * Set CEP attributes (modify CEP) 1592 * Call client/server callback handlers 1593 * Fill up the response MADs 1594 * 1595 * The arguments are : 1596 * statep: Connection state structure 1597 * cm_req/rep/rtu/rej msg : Received CM message 1598 * cm_output_mad : The response CM MAD with some of the fields filled in 1599 * The cm output mad is allocated by CM state transition 1600 * functions and has generic MAD header 1601 * Certain fields like com id, etc., are filled by CM 1602 * connection state transition functions that are above 1603 */ 1604 1605 /* QP state transition function called for an incoming REQ on passive side */ 1606 ibcm_status_t ibcm_cep_state_req(ibcm_state_data_t *statep, 1607 ibcm_req_msg_t *cm_req_msg, ibt_cm_reason_t *reason, 1608 uint8_t *arej_info_len); 1609 1610 /* Processes QP state machine based on return values from cm handler */ 1611 ibcm_status_t ibcm_process_cep_req_cm_hdlr(ibcm_state_data_t *statep, 1612 ibt_cm_status_t cb_status, 1613 ibcm_clnt_reply_info_t *clnt_info, 1614 ibt_cm_reason_t *reject_reason, uint8_t *arej_len, 1615 ibcm_req_msg_t *cm_req_msgp); 1616 1617 /* Processes CM state machine based on return values from ibcm_cep_state_req */ 1618 void ibcm_handle_cep_req_response(ibcm_state_data_t *statep, 1619 ibcm_status_t response, ibt_cm_reason_t reject_reason, 1620 uint8_t arej_info_len); 1621 1622 /* QP state transition function called for an incoming REP on active side */ 1623 ibcm_status_t ibcm_cep_state_rep(ibcm_state_data_t *statep, 1624 ibcm_rep_msg_t *cm_rep_msg, ibt_cm_reason_t *reason, 1625 uint8_t *arej_info_len); 1626 1627 /* Processes QP state machine based on return values from cm handler */ 1628 ibcm_status_t ibcm_process_cep_rep_cm_hdlr(ibcm_state_data_t *statep, 1629 ibt_cm_status_t cb_status, 1630 ibcm_clnt_reply_info_t *clnt_info, 1631 ibt_cm_reason_t *reject_reason, uint8_t *arej_len, 1632 ibcm_rep_msg_t *cm_rep_msgp); 1633 1634 /* Processes CM state machine based on return values from ibcm_cep_state_rep */ 1635 void ibcm_handle_cep_rep_response(ibcm_state_data_t *statep, 1636 ibcm_status_t response, ibt_cm_reason_t reject_reason, 1637 uint8_t arej_info_len, ibcm_rep_msg_t *rep_msgp); 1638 1639 /* QP state transition function called for an incoming RTU on passive side */ 1640 void ibcm_cep_state_rtu(ibcm_state_data_t *statep, 1641 ibcm_rtu_msg_t *cm_rtu_msg); 1642 1643 /* QP state transition func called for an incoming REJ on active/passive side */ 1644 void ibcm_cep_state_rej(ibcm_state_data_t *statep, 1645 ibcm_rej_msg_t *cm_rej_msg, ibcm_conn_state_t rej_state); 1646 1647 /* QP state transition func for an incoming REJ on active side in est state */ 1648 void ibcm_cep_state_rej_est(ibcm_state_data_t *statep); 1649 1650 /* 1651 * QP state transition function called for an outgoing RTU on active side, 1652 * after setting CEP to RTS state active/passive side 1653 */ 1654 void ibcm_cep_send_rtu(ibcm_state_data_t *statep); 1655 1656 1657 /* QP state transition function called for an incoming LAP */ 1658 ibcm_status_t ibcm_cep_state_lap(ibcm_state_data_t *statep, 1659 ibcm_lap_msg_t *lap_msg, ibcm_apr_msg_t *apr_msg); 1660 1661 /* Processes QP state machine based on return value from cm handler for LAP */ 1662 void ibcm_process_cep_lap_cm_hdlr(ibcm_state_data_t *statep, 1663 ibt_cm_status_t cb_status, 1664 ibcm_clnt_reply_info_t *clnt_info, 1665 ibcm_lap_msg_t *lap_msg, ibcm_apr_msg_t *apr_msg); 1666 1667 void ibcm_post_apr_mad(ibcm_state_data_t *statep); 1668 1669 void ibcm_cep_state_apr(ibcm_state_data_t *statep, 1670 ibcm_lap_msg_t *lap_msg, ibcm_apr_msg_t *apr_msg); 1671 1672 /* Processes CM state machine based on return value from cm handler */ 1673 void ibcm_handle_cep_dreq_response(ibcm_state_data_t *statep, 1674 void *priv_data, ibt_priv_data_len_t priv_data_len); 1675 1676 /* Processes CM UD state machine based on return values from cm handler */ 1677 void ibcm_process_sidr_req_cm_hdlr(ibcm_ud_state_data_t *ud_statep, 1678 ibt_cm_status_t cb_status, 1679 ibcm_ud_clnt_reply_info_t *ud_clnt_info, 1680 ibt_sidr_status_t *sidr_status, 1681 ibcm_sidr_rep_msg_t *sidr_repp); 1682 1683 void ibcm_proceed_via_taskq(void *targs); 1684 void ibcm_ud_proceed_via_taskq(void *targs); 1685 1686 /* 1687 * Builds the reply MAD address based on "incoming mad addr" that is 1688 * supplied to it as an arg. 1689 * Swaps the source and destination lids in ibmf_addr_info_t 1690 * Swaps the source and destination gids in ib_grh_t 1691 * 1692 * INPUTS: 1693 * incoming_cm_mad_addr - Address information in the incoming MAD 1694 * reply_cm_mad_addr - Derived address for the reply MAD 1695 * The reply MAD address is derived based 1696 * address information of incoming CM MAD 1697 */ 1698 void ibcm_build_reply_mad_addr(ibcm_mad_addr_t *incoming_cm_mad_addr, 1699 ibcm_mad_addr_t *reply_cm_mad_addr); 1700 1701 /* Posts RC CM MAD using IBMF */ 1702 void ibcm_post_rc_mad(ibcm_state_data_t *statep, ibmf_msg_t *msgp, 1703 ibmf_msg_cb_t post_cb, void *args); 1704 1705 /* Posts UD CM MAD using IBMF */ 1706 void ibcm_post_ud_mad(ibcm_ud_state_data_t *ud_statep, ibmf_msg_t *msgp, 1707 ibmf_msg_cb_t ud_post_cb, void *args); 1708 1709 /* Posts CM MAD using IBMF */ 1710 ibt_status_t ibcm_post_mad(ibmf_msg_t *msgp, ibcm_mad_addr_t *cm_mad_addr, 1711 ibmf_msg_cb_t post_cb, void *args); 1712 1713 /* Post REJ MAD */ 1714 void ibcm_post_rej_mad(ibcm_state_data_t *statep, ibt_cm_reason_t reason, 1715 int who, void *addl_rej_info, uint8_t arej_info_len); 1716 1717 /* Post REP MAD */ 1718 void ibcm_post_rep_mad(ibcm_state_data_t *statep); 1719 1720 /* Post RTU MAD */ 1721 ibcm_status_t ibcm_post_rtu_mad(ibcm_state_data_t *statep); 1722 1723 /* Post DREQ MAD */ 1724 void ibcm_post_dreq_mad(void *statep); 1725 1726 /* Post LAP MAD */ 1727 void ibcm_post_lap_mad(ibcm_state_data_t *statep); 1728 1729 1730 /* 1731 * Posts CM SIDR MAD using IBMF in blocking mode 1732 * 1733 * INPUTS: 1734 * ud_statep: UD statep which is posting the mad 1735 * cm_mad_addr: Address information for the MAD to be posted 1736 * status: SIDR status 1737 */ 1738 void ibcm_post_sidr_rep_mad(ibcm_ud_state_data_t *ud_statep, 1739 ibt_sidr_status_t status); 1740 1741 /* prototypes to resend RC mad and UD MAD */ 1742 void ibcm_resend_rep_mad(ibcm_state_data_t *statep); 1743 void ibcm_resend_rtu_mad(ibcm_state_data_t *statep); 1744 void ibcm_resend_rej_mad(ibcm_state_data_t *statep); 1745 void ibcm_resend_mra_mad(ibcm_state_data_t *statep); 1746 void ibcm_resend_srep_mad(ibcm_ud_state_data_t *statep); 1747 1748 1749 /* Helper function used in connection abort processing */ 1750 void ibcm_process_abort(ibcm_state_data_t *statep); 1751 1752 /* 1753 * Prototypes for CM functions that lookup for a connection state structure 1754 */ 1755 1756 /* 1757 * ibcm_lookup_msg: 1758 * 1759 * Retrieves an existing state structure or creates a new one if none found. 1760 * This function is used during passive side of connection establishment for 1761 * INCOMING REQ/REJ/RTU/MRA 1762 * This function is used during active side of connection establishment for 1763 * INCOMING REP/REJ/MRA 1764 * This function is used during active side of connection establishment for 1765 * an outgoing REQ. 1766 * 1767 * NOTE: IBCM_LOOKP_FAIL is only returned if a new entry wasn't created and 1768 * a match wasn't found. 1769 * 1770 * Arguments are:- 1771 * ibcm_event_type_t - what type of message 1772 * incoming REQ, REP, REJ, MRA, RTU, DREQ, DREP 1773 * local_comid - ONLY *NOT* valid for incoming REQ. 1774 * needed for others 1775 * remote_qpn - Remote CM's QP number 1776 * remote_hca_guid - ONLY VALID FOR incoming REQ. 1777 * Ignored for others 1778 * hcap - HCA entry table pointer 1779 * statep - "return"ed state pointer 1780 * 1781 * Return Values: 1782 * IBCM_LOOKUP_NEW - new statep allocated 1783 * IBCM_LOOKUP_EXISTS - found an existing entry 1784 * IBCM_LOOKUP_FAIL - failed to find an entry 1785 * IBCM_MEMORY_FAILURE - failed to get memory 1786 * iff flags != IBT_CHAN_BLOCKING 1787 */ 1788 ibcm_status_t ibcm_lookup_msg(ibcm_event_type_t event_type, 1789 ib_com_id_t local_comid, ib_qpn_t remote_qpn, 1790 ib_guid_t remote_hca_guid, ibcm_hca_info_t *hcap, 1791 ibcm_state_data_t **statep); 1792 1793 1794 /* 1795 * Routines for CM SIDR state structure list manipulation 1796 * Wherever possible, the list routines of ibtl are used 1797 * for list manipulation 1798 */ 1799 1800 /* 1801 * Finds an entry based on lid, gid and grh exists fields 1802 * lid: LID of incoming SIDR REQ 1803 * gid: GID of incoming SIDR REQ 1804 * grh_exists: TRUE if GRH exists in the incoming SIDR REQ 1805 * hcap: CM State HCA entry ptr to search for SIDR state structure 1806 * statep: Returns a valid state structure, if one exists based 1807 * on lid, gid and grh_exists fields 1808 * flag: whether to just look OR to look and add if it doesn't exist. 1809 */ 1810 ibcm_status_t ibcm_find_sidr_entry(ibcm_sidr_srch_t *srch_param, 1811 ibcm_hca_info_t *hcap, 1812 ibcm_ud_state_data_t **statep, 1813 ibcm_lookup_flag_t flag); 1814 1815 ibcm_ud_state_data_t *ibcm_add_sidr_entry(ibcm_sidr_srch_t *srch_param, 1816 ibcm_hca_info_t *hcap); 1817 1818 /* 1819 * Deletes a given state structure, from both hca state and passive trees 1820 * If ref cnt is zero, deallocates all buffers and memory of state data 1821 */ 1822 void ibcm_delete_state_data(ibcm_state_data_t *statep); 1823 1824 /* 1825 * Deallocates all the buffers and memory of state data. 1826 * This function must be called, only when ref_cnt is zero. 1827 */ 1828 void ibcm_dealloc_state_data(ibcm_state_data_t *statep); 1829 1830 /* 1831 * Deletes a given UD state structure, from SIDR list. 1832 * The routine acquires and releases the SIDR list lock. 1833 */ 1834 void ibcm_delete_ud_state_data(ibcm_ud_state_data_t *statep); 1835 void ibcm_dealloc_ud_state_data(ibcm_ud_state_data_t *statep); 1836 1837 /* 1838 * Service ID entry create and lookup functions 1839 */ 1840 1841 /* 1842 * Adds/looks-up an ibcm_svc_info_t entry in the CM's global table. 1843 * This global table is defined in ibcm_impl.c. 1844 * 1845 * svc_info_list_lock must be held for RW_READER by caller of 1846 * ibcm_find_svc_entry(). 1847 * 1848 * Arguments are:- 1849 * sid - service id 1850 * num_sids - Number (Range) of service-ids 1851 * 1852 * Return values: 1853 * Pointer to ibcm_svc_info_t on success, otherwise NULL. 1854 */ 1855 int ibcm_svc_compare(const void *p1, const void *p2); 1856 ibcm_svc_info_t *ibcm_create_svc_entry(ib_svc_id_t sid, int num_sids); 1857 ibcm_svc_info_t *ibcm_find_svc_entry(ib_svc_id_t sid); 1858 1859 /* 1860 * The following are the function prototypes for various id initialization, 1861 * allocation, free and destroy operations. The cm id allocations are based 1862 * on vmem operations 1863 * The service id's are maintained globally per host 1864 * The com id and req id's are maintained per hca 1865 * To maintain compatibility with intel, service ids are allocated on a 32 bit 1866 * range, though spec has 64 bit range for service id's 1867 */ 1868 ibcm_status_t ibcm_init_ids(); 1869 void ibcm_fini_ids(); 1870 1871 ibcm_status_t ibcm_init_hca_ids(ibcm_hca_info_t *hcap); 1872 void ibcm_fini_hca_ids(ibcm_hca_info_t *hcap); 1873 1874 ibcm_status_t ibcm_alloc_comid(ibcm_hca_info_t *hcap, ib_com_id_t *comid); 1875 void ibcm_free_comid(ibcm_hca_info_t *hcap, ib_com_id_t comid); 1876 1877 ibcm_status_t ibcm_alloc_reqid(ibcm_hca_info_t *hcap, uint32_t *reqid); 1878 void ibcm_free_reqid(ibcm_hca_info_t *hcap, uint32_t reqid); 1879 1880 ib_svc_id_t ibcm_alloc_local_sids(int num_sids); 1881 void ibcm_free_local_sids(ib_svc_id_t service_id, int num_sids); 1882 1883 ib_svc_id_t ibcm_alloc_ip_sid(); 1884 void ibcm_free_ip_sid(ib_svc_id_t sid); 1885 1886 uint64_t ibcm_generate_tranid(uint8_t event, uint32_t id, 1887 uint32_t cm_tran_priv); 1888 1889 void ibcm_decode_tranid(uint64_t tran_id, uint32_t *cm_tran_priv); 1890 1891 ibcm_status_t ibcm_ar_init(void); 1892 ibcm_status_t ibcm_ar_fini(void); 1893 1894 /* 1895 * These functions are called to do timeout processing from CM connection 1896 * state transitions. (Also for SIDR REQ and SIDR REP processing) 1897 * 1898 * Brief description : 1899 * If retry count is below max retry value, then post the stored response 1900 * MAD using IBMF in blocking mode, adjusts remaining retry counters. 1901 * If retry counter reaches max value, then retry failure handling is 1902 * done here 1903 * 1904 * CM will ensure that the state data structure of the associated 1905 * timeout is valid when this timeout function is called. 1906 * (See timer_stored_state in ibcm_state_data_t and 1907 * ud_timer_stored_state in ibcm_ud_state_data_t) 1908 */ 1909 void ibcm_timeout_cb(void *arg); 1910 void ibcm_sidr_timeout_cb(void *arg); 1911 1912 /* 1913 * function prototypes for IBMF send completion callbacks on non-blocking 1914 * MAD posts 1915 */ 1916 void ibcm_post_req_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, 1917 void *args); 1918 void ibcm_post_rep_wait_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, 1919 void *args); /* MRA Rcvd on active side */ 1920 void ibcm_post_rep_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, 1921 void *args); 1922 void ibcm_resend_post_rep_complete(ibmf_handle_t ibmf_handle, 1923 ibmf_msg_t *msgp, void *args); 1924 void ibcm_post_mra_rep_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, 1925 void *args); /* MRA Rcvd on passive side */ 1926 void ibcm_post_rej_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, 1927 void *args); 1928 void ibcm_post_dreq_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, 1929 void *args); 1930 void ibcm_post_drep_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, 1931 void *args); 1932 void ibcm_post_lap_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, 1933 void *args); 1934 void ibcm_post_apr_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, 1935 void *args); 1936 void ibcm_post_stored_apr_complete(ibmf_handle_t ibmf_handle, 1937 ibmf_msg_t *msgp, void *args); 1938 void ibcm_post_mra_lap_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, 1939 void *args); /* MRA Rcvd for LAP on active side */ 1940 void ibcm_post_mra_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, 1941 void *args); /* for MRA sender */ 1942 void ibcm_post_rtu_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, 1943 void *args); 1944 1945 void ibcm_post_sidr_req_complete(ibmf_handle_t ibmf_handle, 1946 ibmf_msg_t *msgp, void *args); 1947 1948 /* 1949 * ibcm_find_hca_entry: 1950 * Given a HCA's GUID find out ibcm_hca_info_t entry for that HCA 1951 * This entry can be then used to access AVL tree/SIDR list etc. 1952 * 1953 * NOTE: This entry is not removed from the "ibcm_hca_listp". 1954 * And this function is called with ibcm_hca_list_mutex mutex held. 1955 * 1956 * INPUTS: 1957 * hca_guid - HCA's guid 1958 * 1959 * RETURN VALUE: 1960 * hcap - if a match is found, else NULL 1961 */ 1962 ibcm_hca_info_t *ibcm_find_hca_entry(ib_guid_t hca_guid); 1963 ibcm_hca_info_t *ibcm_find_hcap_entry(ib_guid_t hca_guid); 1964 void ibcm_delete_hca_entry(ibcm_hca_info_t *hcap); 1965 1966 /* Routines that manage the hca's temporary access count */ 1967 ibcm_status_t ibcm_inc_hca_acc_cnt(ibcm_hca_info_t *hca); 1968 void ibcm_dec_hca_acc_cnt(ibcm_hca_info_t *hca); 1969 1970 /* Routines that manage the hca's resource count */ 1971 void ibcm_inc_hca_res_cnt(ibcm_hca_info_t *hca); 1972 void ibcm_dec_hca_res_cnt(ibcm_hca_info_t *hca); 1973 1974 /* Routines that manage the hca's service count */ 1975 void ibcm_inc_hca_svc_cnt(ibcm_hca_info_t *hca); 1976 void ibcm_dec_hca_svc_cnt(ibcm_hca_info_t *hca); 1977 1978 /* Routine to fetch the saa_handle */ 1979 ibmf_saa_handle_t ibcm_get_saa_handle(ibcm_hca_info_t *hcap, uint8_t port); 1980 1981 /* Allow some flow control of RC connection initiations */ 1982 void ibcm_flow_inc(void); 1983 void ibcm_flow_dec(hrtime_t delta, char *mad_type); 1984 1985 /* Allow some flow control of SA requests */ 1986 void ibcm_sa_access_enter(void); 1987 void ibcm_sa_access_exit(void); 1988 1989 /* 1990 * ibcm_cep_to_error_state: 1991 * Helper function to transition a CEP to ERROR state 1992 * 1993 * NOTE: This function checks if ch_qp is valid or ch_eec and calls 1994 * into IBTL to transition the CEP. 1995 * 1996 * INPUTS: 1997 * statep - Connection state pointer 1998 * 1999 * RETURN VALUE: 2000 * IBT_SUCCESS - if CEP transition succeeded; else error 2001 */ 2002 ibt_status_t ibcm_cep_to_error_state(ibcm_state_data_t *statep); 2003 2004 /* 2005 * Processes the pending stateps in a linked list. The operations are to 2006 * invoke a cm handler or delete statep 2007 * When the above operations are required on statep from a timeout handler, 2008 * they are linked for later processing by an independent thread 2009 */ 2010 void ibcm_process_tlist(); 2011 /* Links RC stateps to an RC timeout processing list */ 2012 void ibcm_add_tlist(ibcm_state_data_t *statep); 2013 2014 /* Links SIDR/UD stateps to an SIDR/UD timeout processing list */ 2015 void ibcm_add_ud_tlist(ibcm_ud_state_data_t *ud_statep); 2016 2017 /* 2018 * This call either aborts a pending or completes a in-progress LAP/APR 2019 * operation 2020 */ 2021 void ibcm_sync_lapr_idle(ibcm_state_data_t *statep); 2022 2023 void ibcm_process_rc_recycle(void *recycle_arg); 2024 2025 /* 2026 * Helper function to handle endianess in case of Service Data. 2027 * Used by ibt_bind_service() and ibt_get_paths(). 2028 */ 2029 void ibcm_swizzle_from_srv(ibt_srv_data_t *sb_data, uint8_t *service_bytes); 2030 void ibcm_swizzle_to_srv(uint8_t *service_bytes, ibt_srv_data_t *sb_data); 2031 2032 /* Misc ibcm global variables */ 2033 extern char cmlog[]; 2034 extern ibt_clnt_hdl_t ibcm_ibt_handle; 2035 extern taskq_t *ibcm_taskq; 2036 extern ibcm_state_handler_t ibcm_sm_funcs_tbl[]; 2037 extern uint8_t ibcm_timeout_list_flags; 2038 extern ibcm_classportinfo_msg_t ibcm_clpinfo; 2039 2040 /* Global lists */ 2041 extern avl_tree_t ibcm_svc_avl_tree; /* global service id tree */ 2042 extern ibcm_state_data_t *ibcm_timeout_list_hdr, *ibcm_timeout_list_tail; 2043 extern ibcm_ud_state_data_t *ibcm_ud_timeout_list_hdr, 2044 *ibcm_ud_timeout_list_tail; 2045 /* Default global retry counts */ 2046 extern uint32_t ibcm_max_retries; 2047 extern uint32_t ibcm_max_sa_retries; 2048 extern int ibcm_sa_timeout_delay; /* in ticks */ 2049 2050 /* Various default global timers */ 2051 extern ibt_rnr_nak_time_t ibcm_default_rnr_nak_time; 2052 2053 extern clock_t ibcm_local_processing_time; /* usecs */ 2054 extern clock_t ibcm_remote_response_time; 2055 extern ib_time_t ibcm_max_sidr_rep_proctime; 2056 extern ib_time_t ibcm_max_sidr_rep_store_time; 2057 extern uint32_t ibcm_adj_btime; 2058 extern uint32_t ibcm_sw_delay; 2059 2060 extern ib_time_t ibcm_max_ib_pkt_lt; 2061 extern ib_time_t ibcm_max_ib_mad_pkt_lt; 2062 2063 /* Global locks */ 2064 extern kmutex_t ibcm_svc_info_lock; 2065 extern kmutex_t ibcm_global_hca_lock; 2066 extern kmutex_t ibcm_qp_list_lock; 2067 extern kmutex_t ibcm_timeout_list_lock; 2068 extern kmutex_t ibcm_recv_mutex; 2069 2070 /* Global cond variables */ 2071 extern kcondvar_t ibcm_global_hca_cv; 2072 extern kcondvar_t ibcm_svc_info_cv; 2073 extern kcondvar_t ibcm_timeout_list_cv; 2074 extern kcondvar_t ibcm_timeout_thread_done_cv; 2075 2076 _NOTE(LOCK_ORDER(ibcm_state_data_s::state_mutex ibcm_timeout_list_lock)) 2077 _NOTE(LOCK_ORDER(ibcm_ud_state_data_s::ud_state_mutex ibcm_timeout_list_lock)) 2078 _NOTE(LOCK_ORDER(ibcm_hca_info_s::hca_state_rwlock 2079 ibcm_state_data_s::state_mutex)) 2080 _NOTE(LOCK_ORDER(ibcm_hca_info_s::hca_sidr_list_lock 2081 ibcm_ud_state_data_s::ud_state_mutex)) 2082 2083 _NOTE(READ_ONLY_DATA(ibcm_local_processing_time ibcm_remote_response_time 2084 ibcm_max_sidr_rep_proctime ibcm_max_sidr_rep_store_time ibcm_adj_btime 2085 ibcm_sw_delay ibcm_max_retries ibcm_max_sa_retries)) 2086 2087 /* 2088 * miscellaneous defines for retries, times etc. 2089 */ 2090 #define IBCM_MAX_RETRIES 11 /* Max CM retries for a msg */ 2091 #define IBCM_LOCAL_RESPONSE_TIME 300000 /* Local CM processing time */ 2092 /* in usecs */ 2093 #define IBCM_REMOTE_RESPONSE_TIME 300000 /* Remote CM response time */ 2094 /* in usecs */ 2095 #define IBCM_MAX_SIDR_PROCESS_TIME 16 /* Time to process SIDR REP */ 2096 #define IBCM_MAX_SIDR_PKT_LIFE_TIME 9 /* Approx pkt lt for UD srver */ 2097 2098 #define IBCM_MAX_IB_PKT_LT 20 /* 4 second */ 2099 #define IBCM_MAX_IB_MAD_PKT_LT 18 /* 1 second */ 2100 2101 #define IBCM_MAX_SA_RETRIES 0 /* Max CM retry for SA update */ 2102 2103 /* versions for CM MADs */ 2104 #define IBCM_MAD_BASE_VERSION 1 2105 #define IBCM_MAD_CLASS_VERSION 2 2106 2107 /* for Class_Port_Info stuff - see section 16.7.3.1 in Vol1 IB Spec */ 2108 #define IBCM_CPINFO_CAP_RC 0x0200 /* RC is supported */ 2109 #define IBCM_CPINFO_CAP_RD 0x0400 /* RD is supported */ 2110 #define IBCM_CPINFO_CAP_RAW 0x0800 /* Raw Datagrams supported */ 2111 #define IBCM_CPINFO_CAP_UC 0x1000 /* UC supported */ 2112 #define IBCM_CPINFO_CAP_SIDR 0x2000 /* SIDR supported */ 2113 2114 #define IBCM_V4_PART_OF_V6(v6) v6.s6_addr32[3] 2115 /* RDMA CM IP Service's Private Data Format. */ 2116 #ifdef _BIG_ENDIAN 2117 typedef struct ibcm_ip_pvtdata_s { 2118 uint8_t ip_MajV:4, 2119 ip_MinV:4; 2120 uint8_t ip_ipv:4, 2121 ip_rsvd:4; /* 0-3: rsvd, 4-7: ipv */ 2122 uint16_t ip_srcport; /* Source Port */ 2123 in6_addr_t ip_srcip; /* Source IP address. */ 2124 in6_addr_t ip_dstip; /* Remote IP address. */ 2125 #define ip_srcv4 IBCM_V4_PART_OF_V6(ip_srcip) 2126 #define ip_dstv4 IBCM_V4_PART_OF_V6(ip_dstip) 2127 #define ip_srcv6 ip_srcip 2128 #define ip_dstv6 ip_dstip 2129 } ibcm_ip_pvtdata_t; 2130 #else 2131 typedef struct ibcm_ip_pvtdata_s { 2132 uint8_t ip_MinV:4, 2133 ip_MajV:4; 2134 uint8_t ip_rsvd:4, 2135 ip_ipv:4; /* 0-3: rsvd, 4-7: ipv */ 2136 uint16_t ip_srcport; /* Source Port */ 2137 in6_addr_t ip_srcip; /* Source IP address. */ 2138 in6_addr_t ip_dstip; /* Remote IP address. */ 2139 #define ip_srcv4 IBCM_V4_PART_OF_V6(ip_srcip) 2140 #define ip_dstv4 IBCM_V4_PART_OF_V6(ip_dstip) 2141 #define ip_srcv6 ip_srcip 2142 #define ip_dstv6 ip_dstip 2143 } ibcm_ip_pvtdata_t; 2144 #endif 2145 2146 /* 2147 * for debug purposes 2148 */ 2149 #ifdef DEBUG 2150 extern int ibcm_test_mode; 2151 2152 void ibcm_query_qp(ibmf_handle_t ibmf_hdl, ibmf_qp_handle_t ibmf_qp); 2153 void ibcm_dump_raw_message(uchar_t *); 2154 void ibcm_dump_srvrec(sa_service_record_t *); 2155 void ibcm_dump_pathrec(sa_path_record_t *); 2156 void ibcm_dump_noderec(sa_node_record_t *); 2157 2158 void ibcm_query_classport_info(ibt_channel_hdl_t channel); 2159 2160 #define IBCM_DUMP_RAW_MSG ibcm_dump_raw_message 2161 #define IBCM_DUMP_SERVICE_REC ibcm_dump_srvrec 2162 #define IBCM_DUMP_PATH_REC ibcm_dump_pathrec 2163 #define IBCM_DUMP_NODE_REC ibcm_dump_noderec 2164 #else 2165 #define IBCM_DUMP_RAW_MSG 0 && 2166 #define IBCM_DUMP_SERVICE_REC 0 && 2167 #define IBCM_DUMP_PATH_REC 0 && 2168 #define IBCM_DUMP_NODE_REC 0 && 2169 #endif 2170 2171 ibt_status_t ibcm_ibmf_analyze_error(int ibmf_status); 2172 2173 ibt_status_t ibcm_contact_sa_access(ibmf_saa_handle_t saa_handle, 2174 ibmf_saa_access_args_t *access_args, size_t *length, void **results_p); 2175 2176 void ibcm_path_cache_init(void); 2177 void ibcm_path_cache_fini(void); 2178 void ibcm_path_cache_purge(void); 2179 2180 #ifdef __cplusplus 2181 } 2182 #endif 2183 2184 2185 #endif /* _SYS_IB_MGT_IBCM_IBCM_IMPL_H */ 2186