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_IBDM_IBDM_IMPL_H 27 #define _SYS_IB_MGT_IBDM_IBDM_IMPL_H 28 29 #pragma ident "%Z%%M% %I% %E% SMI" 30 31 /* 32 * ibdm_impl.h 33 * 34 * This file contains definitions of the data structures, macros etc 35 * related to the IBDM module. 36 */ 37 38 #include <sys/ib/mgt/ibdm/ibdm_ibnex.h> 39 #include <sys/ib/ibtl/impl/ibtl_util.h> 40 41 #ifdef __cplusplus 42 extern "C" { 43 #endif 44 45 typedef struct ibdm_mad_classportinfo_s { 46 uint8_t BaseVersion; /* ver. of MAD base format */ 47 uint8_t ClassVersion; /* ver. of MAD class format */ 48 uint16_t CapabilityMask; /* capabilities of this class */ 49 uint32_t RespTimeValue; /* reserved : 27 bits */ 50 /* resptime value : 5 bits */ 51 uint64_t RedirectGID_hi; /* dest gid of redirect msgs */ 52 uint64_t RedirectGID_lo; /* dest gid of redirect msgs */ 53 uint32_t RedirectTC; /* traffic class: 8 bits */ 54 /* SL: 4 bits */ 55 /* Flow label: 20 bits */ 56 ib_lid_t RedirectLID; /* dlid for class services */ 57 ib_pkey_t RedirectP_Key; /* p_key for class services */ 58 uint32_t RedirectQP; /* Reserved: 8 bits */ 59 /* QPN: 24 bits */ 60 ib_qkey_t RedirectQ_Key; /* q_key for class services */ 61 uint64_t TrapGID_hi; /* dest gid of trap msgs */ 62 uint64_t TrapGID_lo; /* dest gid of trap msgs */ 63 uint32_t TrapTC; /* Trap traffic class, etc., */ 64 ib_lid_t TrapLID; /* dlid for traps */ 65 ib_pkey_t TrapP_Key; /* p_key for traps */ 66 uint32_t TrapHL; /* Trap hop limit,etc., */ 67 ib_qkey_t TrapQ_Key; /* q_key for traps */ 68 } ibdm_mad_classportinfo_t; 69 70 /* values for "cb_req_type" */ 71 #define IBDM_REQ_TYPE_INVALID 0x0 72 #define IBDM_REQ_TYPE_CLASSPORTINFO 0x1 73 #define IBDM_REQ_TYPE_IOUINFO 0x2 74 #define IBDM_REQ_TYPE_IOCINFO 0x4 75 #define IBDM_REQ_TYPE_SRVENTS 0x8 76 #define IBDM_REQ_TYPE_IOU_DIAGCODE 0x10 77 #define IBDM_REQ_TYPE_IOC_DIAGCODE 0x20 78 79 typedef struct ibdm_taskq_args_s { 80 ibmf_handle_t tq_ibmf_handle; 81 ibmf_msg_t *tq_ibmf_msg; 82 void *tq_args; 83 } ibdm_taskq_args_t; 84 _NOTE(SCHEME_PROTECTS_DATA("unique per call", ibdm_taskq_args_t)) 85 _NOTE(SCHEME_PROTECTS_DATA("unique per call", ib_mad_hdr_t)) 86 _NOTE(SCHEME_PROTECTS_DATA("unique per call", ibmf_msg_t)) 87 88 #define IBDM_GID_PRESENT 0x1 89 #define IBDM_GID_NOT_PRESENT 0x0 90 91 #define IBDM_IBMF_PKT_DUP_RESP 0x1 92 #define IBDM_IBMF_PKT_REUSED 0x2 93 #define IBDM_IBMF_PKT_UNEXP_RESP 0x4 94 95 #define IBDM_MAX_SERV_ENTRIES_PER_REQ 4 96 97 typedef struct ibdm_gid_s { 98 uint64_t gid_dgid_hi; 99 uint64_t gid_dgid_lo; 100 struct ibdm_gid_s *gid_next; 101 } ibdm_gid_t; 102 103 #define IBDM_GID_PROBE_NOT_DONE 0x00 104 #define IBDM_GET_CLASSPORTINFO 0x01 105 #define IBDM_GET_IOUNITINFO 0x02 106 #define IBDM_GET_IOC_DETAILS 0x04 107 #define IBDM_GID_PROBING_COMPLETE 0x08 108 #define IBDM_GID_PROBING_SKIPPED 0x10 109 #define IBDM_GID_PROBING_FAILED 0x20 110 111 /* 112 * The state diagram for the gl_state 113 * 114 * IBDM_GID_PROBE_NOT_DONE --- 1 -> IBDM_GID_GET_CLASSPORTINFO 115 * | | | 116 * | 2 3 117 * | | | 118 * | v v 119 * | IBDM_GID_PROBING_FAILED IBDM_GET_IOUNITINFO 120 * | | 121 * 6 4 122 * | | 123 * v v 124 * IBDM_GID_PROBING_SKIPPLED IBDM_GET_IOC_DETAILS 125 * | 126 * 5 127 * | 128 * v 129 * IBDM_GID_PROBE_COMPLETE 130 * 131 * Initial state : IBDM_GID_PROBE_NOT_DONE 132 * 1 = Port supports DM MAD's and a request to ClassportInfor is sent 133 * 3 = Received ClassPortInfo and sent IOUnitInfo 134 * 4 = Recevied IOUunitInfo and sent IOC profile, diagcodes, and 135 * service entries requests 136 * 5 = Received all the IOC information 137 * 2 = Failed to probe the GID 138 * Port does not support DM MAD's 139 * Port did not respond property 140 * 6 = A different GID for the same port, skip the probe 141 * 142 * Reprobe state transition : 143 * 144 * IBDM_GID_PROBE_COMPLETE 145 * | 146 * 7 147 * | 148 * v 149 * IBDM_GET_IOC_DETAILS 150 * | 151 * 8 152 * | 153 * v 154 * IBDM_GID_PROBE_COMPLETE 155 * 156 * 7 = Reprobe request for one or more IOCs initiated. 157 * 8 = Reprobe done(IOC COntroller Profile & Service entries) 158 */ 159 160 typedef struct ibdm_dp_gidinfo_s { 161 kmutex_t gl_mutex; 162 uint_t gl_state; 163 int gl_reprobe_flag; /* pass this to taskq */ 164 struct ibdm_dp_gidinfo_s *gl_next; 165 struct ibdm_dp_gidinfo_s *gl_prev; 166 ibdm_iou_info_t *gl_iou; 167 int gl_pending_cmds; 168 ibmf_qp_handle_t gl_qp_hdl; 169 uint64_t gl_transactionID; 170 ibdm_timeout_cb_args_t gl_iou_cb_args; 171 ib_lid_t gl_dlid; 172 ib_lid_t gl_slid; 173 uint64_t gl_dgid_hi; 174 uint64_t gl_dgid_lo; 175 uint64_t gl_sgid_hi; 176 uint64_t gl_sgid_lo; 177 ib_guid_t gl_nodeguid; 178 ib_guid_t gl_portguid; 179 ib_pkey_t gl_p_key; 180 boolean_t gl_redirected; 181 uint32_t gl_redirect_dlid; 182 uint32_t gl_redirect_QP; 183 ib_pkey_t gl_redirect_pkey; 184 ib_qkey_t gl_redirect_qkey; 185 uint64_t gl_redirectGID_hi; 186 uint64_t gl_redirectGID_lo; 187 ibmf_handle_t gl_ibmf_hdl; 188 ibmf_saa_handle_t gl_sa_hdl; 189 timeout_id_t gl_timeout_id; 190 ibdm_timeout_cb_args_t gl_cpi_cb_args; 191 uint32_t gl_ngids; 192 ibdm_gid_t *gl_gid; 193 uint32_t gl_resp_timeout; 194 int gl_num_iocs; 195 ibdm_hca_list_t *gl_hca_list; 196 int gl_disconnected; 197 uint64_t gl_min_transactionID; 198 uint64_t gl_max_transactionID; 199 ibdm_iou_info_t *gl_prev_iou; 200 } ibdm_dp_gidinfo_t; 201 _NOTE(MUTEX_PROTECTS_DATA(ibdm_dp_gidinfo_s::gl_mutex, 202 ibdm_dp_gidinfo_s::{gl_state gl_timeout_id gl_pending_cmds})) 203 _NOTE(SCHEME_PROTECTS_DATA("Serialized access by cv", ibdm_dp_gidinfo_s)) 204 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibdm_dp_gidinfo_s::{gl_ibmf_hdl gl_sa_hdl})) 205 206 /* 207 * The transaction ID for the GID contains of two parts : 208 * 1. Upper 32 bits which is unique for each GID. 209 * 2. Lower 32 bits which is unique for each MAD. 210 * The assumptions are : 211 * 1. At most 2 power 32 DM capable GIDs on the IB fabric 212 * 2. IBDM sends maximum of 2 power 32 MADs to the same DM GID 213 * The limits are sufficient for practical configurations. 214 */ 215 #define IBDM_GID_TRANSACTIONID_SHIFT ((ulong_t)32) 216 #define IBDM_GID_TRANSACTIONID_MASK 0xFFFFFFFF00000000ULL 217 218 typedef struct ibdm_s { 219 /* Protects IBDM's critical data */ 220 kmutex_t ibdm_mutex; 221 uint32_t ibdm_hca_count; 222 kmutex_t ibdm_hl_mutex; 223 kmutex_t ibdm_ibnex_mutex; 224 ibdm_hca_list_t *ibdm_hca_list_head; 225 ibdm_hca_list_t *ibdm_hca_list_tail; 226 227 ibdm_dp_gidinfo_t *ibdm_dp_gidlist_head; 228 ibdm_dp_gidinfo_t *ibdm_dp_gidlist_tail; 229 230 kcondvar_t ibdm_probe_cv; 231 kcondvar_t ibdm_busy_cv; 232 uint32_t ibdm_ngid_probes_in_progress; 233 uint64_t ibdm_transactionID; 234 uint32_t ibdm_ngids; 235 uint32_t ibdm_busy; 236 int ibdm_state; 237 ibt_clnt_hdl_t ibdm_ibt_clnt_hdl; 238 239 /* 240 * These are callback routines registered by the IB nexus driver. 241 * These callbacks are used to inform the IB nexus driver about 242 * the arrival/removal of HCA and IOC's 243 */ 244 ibdm_callback_t ibdm_ibnex_callback; 245 246 /* Flag indicating - prev_iou during sweep */ 247 int ibdm_prev_iou; 248 } ibdm_t; 249 _NOTE(MUTEX_PROTECTS_DATA(ibdm_s::ibdm_mutex, ibdm_s::{ibdm_ibt_clnt_hdl 250 ibdm_busy ibdm_state})) 251 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibdm_s::ibdm_ibt_clnt_hdl)) 252 _NOTE(MUTEX_PROTECTS_DATA(ibdm_s::ibdm_hl_mutex, 253 ibdm_s::{ibdm_hca_list_head ibdm_hca_list_tail})) 254 _NOTE(MUTEX_PROTECTS_DATA(ibdm_s::ibdm_ibnex_mutex, 255 ibdm_s::ibdm_ibnex_callback)) 256 _NOTE(SCHEME_PROTECTS_DATA("Serialized access by cv", ibdm_s)) 257 _NOTE(LOCK_ORDER(ibdm_s::ibdm_mutex ibdm_dp_gidinfo_s::gl_mutex)) 258 259 /* valid values for ibdm_state */ 260 #define IBDM_LOCKS_ALLOCED 0x01 /* global locks alloced */ 261 #define IBDM_CVS_ALLOCED 0x02 /* global "cv"s alloced */ 262 #define IBDM_IBT_ATTACHED 0x04 /* ibt_attach() called */ 263 #define IBDM_HCA_ATTACHED 0x08 /* ibdm_handle_hca() called */ 264 265 #define IBDM_8_BIT_MASK 0x00FF 266 #define IBDM_16_BIT_MASK 0xFFFF 267 #define IBDM_RETRY_COUNT 0x2 268 269 #define IBDM_BUSY 0x1 270 #define IBDM_PROBE_IN_PROGRESS 0x2 271 272 #define IBDM_MAD_SIZE 256 273 #define DM_CLASSPORTINFO_SZ 72 274 275 #define IBDM_DFT_TIMEOUT 4 276 #define IBDM_DFT_NRETRIES 3 277 278 #define IBDM_ENABLE_TASKQ_HANDLING 1 279 #define IBDM_DISABLE_TASKQ_HANLDING 0 280 281 typedef struct ibdm_saa_event_arg_s { 282 ibmf_saa_handle_t ibmf_saa_handle; 283 ibmf_saa_subnet_event_t ibmf_saa_event; 284 ibmf_saa_event_details_t event_details; 285 void *callback_arg; 286 } ibdm_saa_event_arg_t; 287 288 #define IBDM_TIMEOUT_VALUE(t) (drv_usectohz(t * 1000000)) 289 290 #define IBDM_OUT_IBMFMSG_MADHDR(msg)\ 291 (msg->im_msgbufs_send.im_bufs_mad_hdr) 292 293 #define IBDM_IN_IBMFMSG_MADHDR(msg)\ 294 (msg->im_msgbufs_recv.im_bufs_mad_hdr) 295 296 #define IBDM_IN_IBMFMSG_STATUS(msg)\ 297 b2h16(msg->im_msgbufs_recv.im_bufs_mad_hdr->Status) 298 299 #define IBDM_IN_IBMFMSG_ATTR(msg)\ 300 b2h16(msg->im_msgbufs_recv.im_bufs_mad_hdr->AttributeID) 301 302 #define IBDM_IN_IBMFMSG_ATTRMOD(msg)\ 303 b2h32(msg->im_msgbufs_recv.im_bufs_mad_hdr->AttributeModifier) 304 305 #define IBDM_IN_IBMFMSG2IOU(msg) (ib_dm_io_unitinfo_t *)\ 306 (msg->im_msgbufs_recv.im_bufs_cl_data) 307 308 #define IBDM_IN_IBMFMSG2IOC(msg) (ib_dm_ioc_ctrl_profile_t *)\ 309 (msg->im_msgbufs_recv.im_bufs_cl_data) 310 311 #define IBDM_IN_IBMFMSG2SRVENT(msg) (ib_dm_srv_t *)\ 312 (msg->im_msgbufs_recv.im_bufs_cl_data) 313 314 #define IBDM_IN_IBMFMSG2DIAGCODE(msg) (uint32_t *)\ 315 (msg->im_msgbufs_recv.im_bufs_cl_data) 316 317 #define IBDM_GIDINFO2IOCINFO(gid_info, idx) \ 318 (ibdm_ioc_info_t *)&gid_info->gl_iou->iou_ioc_info[idx]; 319 320 #define IBDM_IS_IOC_NUM_INVALID(ioc_no, gid_info)\ 321 ((ioc_no < 1) || (ioc_no >\ 322 gid_info->gl_iou->iou_info.iou_num_ctrl_slots)) 323 324 #define IBDM_INVALID_PKEY(pkey) \ 325 (((pkey) == IB_PKEY_INVALID_FULL) || \ 326 ((pkey) == IB_PKEY_INVALID_LIMITED)) 327 328 #ifdef DEBUG 329 330 void ibdm_dump_ibmf_msg(ibmf_msg_t *, int); 331 void ibdm_dump_path_info(sa_path_record_t *); 332 void ibdm_dump_classportinfo(ibdm_mad_classportinfo_t *); 333 void ibdm_dump_iounitinfo(ib_dm_io_unitinfo_t *); 334 void ibdm_dump_ioc_profile(ib_dm_ioc_ctrl_profile_t *); 335 void ibdm_dump_service_entries(ib_dm_srv_t *); 336 void ibdm_dump_sweep_fabric_timestamp(int); 337 338 #define ibdm_dump_ibmf_msg(a, b) ibdm_dump_ibmf_msg(a, b) 339 #define ibdm_dump_path_info(a) ibdm_dump_path_info(a) 340 #define ibdm_dump_classportinfo(a) ibdm_dump_classportinfo(a) 341 #define ibdm_dump_iounitinfo(a) ibdm_dump_iounitinfo(a) 342 #define ibdm_dump_ioc_profile(a) ibdm_dump_ioc_profile(a) 343 #define ibdm_dump_service_entries(a) ibdm_dump_service_entries(a) 344 345 #else 346 347 #define ibdm_dump_ibmf_msg(a, b) 348 #define ibdm_dump_path_info(a) 349 #define ibdm_dump_classportinfo(a) 350 #define ibdm_dump_iounitinfo(a) 351 #define ibdm_dump_ioc_profile(a) 352 #define ibdm_dump_service_entries(a) 353 #define ibdm_dump_sweep_fabric_timestamp(a) 354 355 #endif 356 357 #ifdef __cplusplus 358 } 359 #endif 360 361 #endif /* _SYS_IB_MGT_IBDM_IBDM_IMPL_H */ 362