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 2008 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 /* values for "cb_req_type" */ 46 #define IBDM_REQ_TYPE_INVALID 0x0 47 #define IBDM_REQ_TYPE_CLASSPORTINFO 0x1 48 #define IBDM_REQ_TYPE_IOUINFO 0x2 49 #define IBDM_REQ_TYPE_IOCINFO 0x4 50 #define IBDM_REQ_TYPE_SRVENTS 0x8 51 #define IBDM_REQ_TYPE_IOU_DIAGCODE 0x10 52 #define IBDM_REQ_TYPE_IOC_DIAGCODE 0x20 53 54 typedef struct ibdm_taskq_args_s { 55 ibmf_handle_t tq_ibmf_handle; 56 ibmf_msg_t *tq_ibmf_msg; 57 void *tq_args; 58 } ibdm_taskq_args_t; 59 _NOTE(SCHEME_PROTECTS_DATA("unique per call", ibdm_taskq_args_t)) 60 _NOTE(SCHEME_PROTECTS_DATA("unique per call", ib_mad_hdr_t)) 61 _NOTE(SCHEME_PROTECTS_DATA("unique per call", ibmf_msg_t)) 62 63 #define IBDM_GID_PRESENT 0x1 64 #define IBDM_GID_NOT_PRESENT 0x0 65 66 #define IBDM_IBMF_PKT_DUP_RESP 0x1 67 #define IBDM_IBMF_PKT_REUSED 0x2 68 #define IBDM_IBMF_PKT_UNEXP_RESP 0x4 69 70 #define IBDM_MAX_SERV_ENTRIES_PER_REQ 4 71 72 typedef struct ibdm_gid_s { 73 uint64_t gid_dgid_hi; 74 uint64_t gid_dgid_lo; 75 struct ibdm_gid_s *gid_next; 76 } ibdm_gid_t; 77 78 #define IBDM_GID_PROBE_NOT_DONE 0x00 79 #define IBDM_GET_CLASSPORTINFO 0x01 80 #define IBDM_GET_IOUNITINFO 0x02 81 #define IBDM_GET_IOC_DETAILS 0x04 82 #define IBDM_GID_PROBING_COMPLETE 0x08 83 #define IBDM_GID_PROBING_SKIPPED 0x10 84 #define IBDM_GID_PROBING_FAILED 0x20 85 #define IBDM_SET_CLASSPORTINFO 0x40 86 87 /* 88 * Identifiers to distinguish a Cisco FC GW from others. 89 * Used to filter a setclassportinfo request. 90 */ 91 #define IBDM_CISCO_COMPANY_ID (0x5ad) 92 #define IBDM_CISCO_DEVICE_ID (0xa87c) 93 94 /* 95 * the bit-shift value for OUI in GUID 96 * A 64 bit globally unique identifier (GUID) composed of a 24 bit company id 97 * and an 48 bit extension identifier, and this value is used to extract 98 * the company id from the GUID. 99 */ 100 #define IBDM_OUI_GUID_SHIFT (40) 101 102 /* 103 * The state diagram for the gl_state 104 * 105 * (in case of Cisco FC GW) 106 * IBDM_GID_PROBE_NOT_DONE ---------- 40 -> IBDM_SET_CLASSPORTINFO 107 * ----. | 108 * | | | (others) | 109 * | | 1 | 110 * | | | 1 111 * | | `-------------. | 112 * | | v v 113 * | | IBDM_GET_CLASSPORTINFO 114 * | | 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 * 40 = Port sends setClassPortInfo to activate Cisco FC GW 133 * 1 = Port supports DM MAD's and a request to ClassportInfo is sent 134 * 3 = Received ClassPortInfo and sent IOUnitInfo 135 * 4 = Recevied IOUunitInfo and sent IOC profile, diagcodes, and 136 * service entries requests 137 * 5 = Received all the IOC information 138 * 2 = Failed to probe the GID 139 * Port does not support DM MAD's 140 * Port did not respond property 141 * 6 = A different GID for the same port, skip the probe 142 * 143 * Reprobe state transition : 144 * 145 * IBDM_GID_PROBE_COMPLETE 146 * | 147 * 7 148 * | 149 * v 150 * IBDM_GET_IOC_DETAILS 151 * | 152 * 8 153 * | 154 * v 155 * IBDM_GID_PROBE_COMPLETE 156 * 157 * 7 = Reprobe request for one or more IOCs initiated. 158 * 8 = Reprobe done(IOC COntroller Profile & Service entries) 159 */ 160 161 typedef struct ibdm_dp_gidinfo_s { 162 kmutex_t gl_mutex; 163 uint_t gl_state; 164 int gl_reprobe_flag; /* pass this to taskq */ 165 struct ibdm_dp_gidinfo_s *gl_next; 166 struct ibdm_dp_gidinfo_s *gl_prev; 167 ibdm_iou_info_t *gl_iou; 168 int gl_pending_cmds; 169 ibmf_qp_handle_t gl_qp_hdl; 170 uint64_t gl_transactionID; 171 ibdm_timeout_cb_args_t gl_iou_cb_args; 172 ib_lid_t gl_dlid; 173 ib_lid_t gl_slid; 174 uint64_t gl_dgid_hi; 175 uint64_t gl_dgid_lo; 176 uint64_t gl_sgid_hi; 177 uint64_t gl_sgid_lo; 178 ib_guid_t gl_nodeguid; 179 ib_guid_t gl_portguid; 180 ib_pkey_t gl_p_key; 181 boolean_t gl_redirected; 182 uint32_t gl_redirect_dlid; 183 uint32_t gl_redirect_QP; 184 ib_pkey_t gl_redirect_pkey; 185 ib_qkey_t gl_redirect_qkey; 186 uint64_t gl_redirectGID_hi; 187 uint64_t gl_redirectGID_lo; 188 ibmf_handle_t gl_ibmf_hdl; 189 ibmf_saa_handle_t gl_sa_hdl; 190 timeout_id_t gl_timeout_id; 191 ibdm_timeout_cb_args_t gl_cpi_cb_args; 192 uint32_t gl_ngids; 193 ibdm_gid_t *gl_gid; 194 uint32_t gl_resp_timeout; 195 int gl_num_iocs; 196 ibdm_hca_list_t *gl_hca_list; 197 int gl_disconnected; 198 uint64_t gl_min_transactionID; 199 uint64_t gl_max_transactionID; 200 ibdm_iou_info_t *gl_prev_iou; 201 uint16_t gl_devid; /* device ID info */ 202 kcondvar_t gl_probe_cv; /* sync for Cisco FC GW */ 203 uint32_t gl_flag; 204 } ibdm_dp_gidinfo_t; 205 _NOTE(MUTEX_PROTECTS_DATA(ibdm_dp_gidinfo_s::gl_mutex, 206 ibdm_dp_gidinfo_s::{gl_state gl_timeout_id gl_pending_cmds})) 207 _NOTE(SCHEME_PROTECTS_DATA("Serialized access by cv", ibdm_dp_gidinfo_s)) 208 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibdm_dp_gidinfo_s::{gl_ibmf_hdl gl_sa_hdl})) 209 210 /* 211 * The transaction ID for the GID contains of two parts : 212 * 1. Upper 32 bits which is unique for each GID. 213 * 2. Lower 32 bits which is unique for each MAD. 214 * The assumptions are : 215 * 1. At most 2 power 32 DM capable GIDs on the IB fabric 216 * 2. IBDM sends maximum of 2 power 32 MADs to the same DM GID 217 * The limits are sufficient for practical configurations. 218 */ 219 #define IBDM_GID_TRANSACTIONID_SHIFT ((ulong_t)32) 220 #define IBDM_GID_TRANSACTIONID_MASK 0xFFFFFFFF00000000ULL 221 222 typedef struct ibdm_s { 223 /* Protects IBDM's critical data */ 224 kmutex_t ibdm_mutex; 225 uint32_t ibdm_hca_count; 226 kmutex_t ibdm_hl_mutex; 227 kmutex_t ibdm_ibnex_mutex; 228 ibdm_hca_list_t *ibdm_hca_list_head; 229 ibdm_hca_list_t *ibdm_hca_list_tail; 230 231 ibdm_dp_gidinfo_t *ibdm_dp_gidlist_head; 232 ibdm_dp_gidinfo_t *ibdm_dp_gidlist_tail; 233 234 kcondvar_t ibdm_probe_cv; 235 kcondvar_t ibdm_busy_cv; 236 uint32_t ibdm_ngid_probes_in_progress; 237 uint64_t ibdm_transactionID; 238 uint32_t ibdm_ngids; 239 uint32_t ibdm_busy; 240 int ibdm_state; 241 ibt_clnt_hdl_t ibdm_ibt_clnt_hdl; 242 243 /* 244 * These are callback routines registered by the IB nexus driver. 245 * These callbacks are used to inform the IB nexus driver about 246 * the arrival/removal of HCA and IOC's 247 */ 248 ibdm_callback_t ibdm_ibnex_callback; 249 250 /* Flag indicating - prev_iou during sweep */ 251 int ibdm_prev_iou; 252 } ibdm_t; 253 _NOTE(MUTEX_PROTECTS_DATA(ibdm_s::ibdm_mutex, ibdm_s::{ibdm_ibt_clnt_hdl 254 ibdm_busy ibdm_state})) 255 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibdm_s::ibdm_ibt_clnt_hdl)) 256 _NOTE(MUTEX_PROTECTS_DATA(ibdm_s::ibdm_hl_mutex, 257 ibdm_s::{ibdm_hca_list_head ibdm_hca_list_tail})) 258 _NOTE(MUTEX_PROTECTS_DATA(ibdm_s::ibdm_ibnex_mutex, 259 ibdm_s::ibdm_ibnex_callback)) 260 _NOTE(SCHEME_PROTECTS_DATA("Serialized access by cv", ibdm_s)) 261 _NOTE(LOCK_ORDER(ibdm_s::ibdm_mutex ibdm_dp_gidinfo_s::gl_mutex)) 262 263 /* valid values for ibdm_state */ 264 #define IBDM_LOCKS_ALLOCED 0x01 /* global locks alloced */ 265 #define IBDM_CVS_ALLOCED 0x02 /* global "cv"s alloced */ 266 #define IBDM_IBT_ATTACHED 0x04 /* ibt_attach() called */ 267 #define IBDM_HCA_ATTACHED 0x08 /* ibdm_handle_hca() called */ 268 269 #define IBDM_8_BIT_MASK 0x00FF 270 #define IBDM_16_BIT_MASK 0xFFFF 271 #define IBDM_RETRY_COUNT 0x2 272 273 #define IBDM_BUSY 0x1 274 #define IBDM_PROBE_IN_PROGRESS 0x2 275 #define IBDM_CISCO_PROBE 0x4 276 #define IBDM_CISCO_PROBE_DONE 0x8 277 278 /* 279 * Device Management MAD packet format 280 * +--------+------------+------------+------------+------------+ 281 * | offset | byte 0 | byte 1 | byte 2 | byte 3 | 282 * +--------+------------+------------+------------+------------+ -- 283 * | 0 | | ^ 284 * +--------+ | sizeof( 285 * | ... | Common MAD Header | ib_mad_hdr_t) 286 * +--------+ | | (A) 287 * | 20 | | v 288 * +--------+------------+------------+------------+------------+ -- 289 * | 24 | | ^ 290 * +--------+ | | 291 * | ... | RMPP Header | | 292 * +--------+ | | 293 * | 32 | | | 294 * +--------+------------+------------+------------+------------+ | 295 * | 36 | | | 296 * +--------+ Access_Key | 297 * | 40 | | IBDM_DM_MAD_ 298 * +--------+------------+------------+------------+------------+ HDR_SZ 299 * | 44 | KeyType | reserved | (B) 300 * +--------+------------+------------+------------+------------+ | 301 * | 48 | | | 302 * +--------+ | | 303 * | 52 | Reserved | | 304 * +--------+ | | 305 * | 56 | | | 306 * +--------+------------+------------+------------+------------+ | 307 * | 60 | Change_ID | ComponentMask | v 308 * +--------+------------+------------+------------+------------+ -- 309 * | 64 | | ^ 310 * +--------+ | IBDM_MAD_SIZE 311 * | ... | Device Management Data | - (A) - (B) 312 * +--------+ | | 313 * | 252 | | v 314 * +--------+------------+------------+------------+------------+ -- 315 */ 316 #define IBDM_MAD_SIZE 256 317 #define IBDM_DM_MAD_HDR_SZ 40 318 319 #define IBDM_DFT_TIMEOUT 4 320 #define IBDM_DFT_NRETRIES 3 321 322 #define IBDM_ENABLE_TASKQ_HANDLING 1 323 #define IBDM_DISABLE_TASKQ_HANLDING 0 324 325 typedef struct ibdm_saa_event_arg_s { 326 ibmf_saa_handle_t ibmf_saa_handle; 327 ibmf_saa_subnet_event_t ibmf_saa_event; 328 ibmf_saa_event_details_t event_details; 329 void *callback_arg; 330 } ibdm_saa_event_arg_t; 331 332 #define IBDM_TIMEOUT_VALUE(t) (drv_usectohz(t * 1000000)) 333 334 #define IBDM_OUT_IBMFMSG_MADHDR(msg)\ 335 (msg->im_msgbufs_send.im_bufs_mad_hdr) 336 337 #define IBDM_IN_IBMFMSG_MADHDR(msg)\ 338 (msg->im_msgbufs_recv.im_bufs_mad_hdr) 339 340 #define IBDM_IN_IBMFMSG_STATUS(msg)\ 341 b2h16(msg->im_msgbufs_recv.im_bufs_mad_hdr->Status) 342 343 #define IBDM_IN_IBMFMSG_ATTR(msg)\ 344 b2h16(msg->im_msgbufs_recv.im_bufs_mad_hdr->AttributeID) 345 346 #define IBDM_IN_IBMFMSG_ATTRMOD(msg)\ 347 b2h32(msg->im_msgbufs_recv.im_bufs_mad_hdr->AttributeModifier) 348 349 #define IBDM_IN_IBMFMSG2IOU(msg) (ib_dm_io_unitinfo_t *)\ 350 (msg->im_msgbufs_recv.im_bufs_cl_data) 351 352 #define IBDM_IN_IBMFMSG2IOC(msg) (ib_dm_ioc_ctrl_profile_t *)\ 353 (msg->im_msgbufs_recv.im_bufs_cl_data) 354 355 #define IBDM_IN_IBMFMSG2SRVENT(msg) (ib_dm_srv_t *)\ 356 (msg->im_msgbufs_recv.im_bufs_cl_data) 357 358 #define IBDM_IN_IBMFMSG2DIAGCODE(msg) (uint32_t *)\ 359 (msg->im_msgbufs_recv.im_bufs_cl_data) 360 361 #define IBDM_GIDINFO2IOCINFO(gid_info, idx) \ 362 (ibdm_ioc_info_t *)&gid_info->gl_iou->iou_ioc_info[idx]; 363 364 #define IBDM_IS_IOC_NUM_INVALID(ioc_no, gid_info)\ 365 ((ioc_no < 1) || (ioc_no >\ 366 gid_info->gl_iou->iou_info.iou_num_ctrl_slots)) 367 368 #define IBDM_INVALID_PKEY(pkey) \ 369 (((pkey) == IB_PKEY_INVALID_FULL) || \ 370 ((pkey) == IB_PKEY_INVALID_LIMITED)) 371 372 #ifdef DEBUG 373 374 void ibdm_dump_mad_hdr(ib_mad_hdr_t *); 375 void ibdm_dump_ibmf_msg(ibmf_msg_t *, int); 376 void ibdm_dump_path_info(sa_path_record_t *); 377 void ibdm_dump_classportinfo(ib_mad_classportinfo_t *); 378 void ibdm_dump_iounitinfo(ib_dm_io_unitinfo_t *); 379 void ibdm_dump_ioc_profile(ib_dm_ioc_ctrl_profile_t *); 380 void ibdm_dump_service_entries(ib_dm_srv_t *); 381 void ibdm_dump_sweep_fabric_timestamp(int); 382 383 #define ibdm_dump_mad_hdr(a) ibdm_dump_mad_hdr(a) 384 #define ibdm_dump_ibmf_msg(a, b) ibdm_dump_ibmf_msg(a, b) 385 #define ibdm_dump_path_info(a) ibdm_dump_path_info(a) 386 #define ibdm_dump_classportinfo(a) ibdm_dump_classportinfo(a) 387 #define ibdm_dump_iounitinfo(a) ibdm_dump_iounitinfo(a) 388 #define ibdm_dump_ioc_profile(a) ibdm_dump_ioc_profile(a) 389 #define ibdm_dump_service_entries(a) ibdm_dump_service_entries(a) 390 391 #else 392 393 #define ibdm_dump_mad_hdr(a) 394 #define ibdm_dump_ibmf_msg(a, b) 395 #define ibdm_dump_path_info(a) 396 #define ibdm_dump_classportinfo(a) 397 #define ibdm_dump_iounitinfo(a) 398 #define ibdm_dump_ioc_profile(a) 399 #define ibdm_dump_service_entries(a) 400 #define ibdm_dump_sweep_fabric_timestamp(a) 401 402 #endif 403 404 #ifdef __cplusplus 405 } 406 #endif 407 408 #endif /* _SYS_IB_MGT_IBDM_IBDM_IMPL_H */ 409