1 /*- 2 * Copyright (c) 2017 Broadcom. All rights reserved. 3 * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 * 31 * $FreeBSD$ 32 */ 33 34 /** 35 * @file 36 * Contains declarations shared between the alex layer and HW/SLI4 37 */ 38 39 #if !defined(__OCS_COMMON_H__) 40 #define __OCS_COMMON_H__ 41 42 #include "ocs_sm.h" 43 #include "ocs_utils.h" 44 45 #define OCS_CTRLMASK_XPORT_DISABLE_AUTORSP_TSEND (1U << 0) 46 #define OCS_CTRLMASK_XPORT_DISABLE_AUTORSP_TRECEIVE (1U << 1) 47 #define OCS_CTRLMASK_XPORT_ENABLE_TARGET_RSCN (1U << 3) 48 #define OCS_CTRLMASK_TGT_ALWAYS_VERIFY_DIF (1U << 4) 49 #define OCS_CTRLMASK_TGT_SET_DIF_REF_TAG_CRC (1U << 5) 50 #define OCS_CTRLMASK_TEST_CHAINED_SGLS (1U << 6) 51 #define OCS_CTRLMASK_ISCSI_ISNS_ENABLE (1U << 7) 52 #define OCS_CTRLMASK_ENABLE_FABRIC_EMULATION (1U << 8) 53 #define OCS_CTRLMASK_INHIBIT_INITIATOR (1U << 9) 54 #define OCS_CTRLMASK_CRASH_RESET (1U << 10) 55 56 #define enable_target_rscn(ocs) \ 57 ((ocs->ctrlmask & OCS_CTRLMASK_XPORT_ENABLE_TARGET_RSCN) != 0) 58 59 /* Used for error injection testing. */ 60 typedef enum { 61 NO_ERR_INJECT = 0, 62 INJECT_DROP_CMD, 63 INJECT_FREE_DROPPED, 64 INJECT_DROP_DATA, 65 INJECT_DROP_RESP, 66 INJECT_DELAY_CMD, 67 } ocs_err_injection_e; 68 69 #define MAX_OCS_DEVICES 64 70 71 typedef enum {OCS_XPORT_FC, OCS_XPORT_ISCSI} ocs_xport_e; 72 73 #define OCS_SERVICE_PARMS_LENGTH 0x74 74 #define OCS_DISPLAY_NAME_LENGTH 32 75 #define OCS_DISPLAY_BUS_INFO_LENGTH 16 76 77 #define OCS_WWN_LENGTH 32 78 79 typedef struct ocs_hw_s ocs_hw_t; 80 typedef struct ocs_domain_s ocs_domain_t; 81 typedef struct ocs_sli_port_s ocs_sli_port_t; 82 typedef struct ocs_sli_port_s ocs_sport_t; 83 typedef struct ocs_remote_node_s ocs_remote_node_t; 84 typedef struct ocs_remote_node_group_s ocs_remote_node_group_t; 85 typedef struct ocs_node_s ocs_node_t; 86 typedef struct ocs_io_s ocs_io_t; 87 typedef struct ocs_xport_s ocs_xport_t; 88 typedef struct ocs_node_cb_s ocs_node_cb_t; 89 typedef struct ocs_ns_s ocs_ns_t; 90 91 /* Node group data structure */ 92 typedef struct ocs_node_group_dir_s ocs_node_group_dir_t; 93 94 #include "ocs_cam.h" 95 96 /*-------------------------------------------------- 97 * Shared HW/SLI objects 98 * 99 * Several objects used by the HW/SLI layers are communal; part of the 100 * object is for the sole use of the lower layers, but implementations 101 * are free to add their own fields if desired. 102 */ 103 104 /** 105 * @brief Description of discovered Fabric Domain 106 * 107 * @note Not all fields are valid for all mediums (FC/ethernet). 108 */ 109 typedef struct ocs_domain_record_s { 110 uint32_t index; /**< FCF table index (used in REG_FCFI) */ 111 uint32_t priority; /**< FCF reported priority */ 112 uint8_t address[6]; /**< Switch MAC/FC address */ 113 uint8_t wwn[8]; /**< Switch WWN */ 114 union { 115 uint8_t vlan[512]; /**< bitmap of valid VLAN IDs */ 116 uint8_t loop[128]; /**< FC-AL position map */ 117 } map; 118 uint32_t speed; /**< link speed */ 119 uint32_t fc_id; /**< our ports fc_id */ 120 uint32_t is_fc:1, /**< Connection medium is native FC */ 121 is_ethernet:1, /**< Connection medium is ethernet (FCoE) */ 122 is_loop:1, /**< Topology is FC-AL */ 123 is_nport:1, /**< Topology is N-PORT */ 124 :28; 125 } ocs_domain_record_t; 126 127 /** 128 * @brief Node group directory entry 129 */ 130 struct ocs_node_group_dir_s { 131 uint32_t instance_index; /*<< instance index */ 132 ocs_sport_t *sport; /*<< pointer to sport */ 133 uint8_t service_params[OCS_SERVICE_PARMS_LENGTH]; /**< Login parameters */ 134 ocs_list_link_t link; /**< linked list link */ 135 ocs_list_t node_group_list; /**< linked list of node groups */ 136 uint32_t node_group_list_count; /**< current number of elements on the node group list */ 137 uint32_t next_idx; /*<< index of the next node group in list */ 138 }; 139 140 typedef enum { 141 OCS_SPORT_TOPOLOGY_UNKNOWN=0, 142 OCS_SPORT_TOPOLOGY_FABRIC, 143 OCS_SPORT_TOPOLOGY_P2P, 144 OCS_SPORT_TOPOLOGY_LOOP, 145 } ocs_sport_topology_e; 146 147 /** 148 * @brief SLI Port object 149 * 150 * The SLI Port object represents the connection between the driver and the 151 * FC/FCoE domain. In some topologies / hardware, it is possible to have 152 * multiple connections to the domain via different WWN. Each would require 153 * a separate SLI port object. 154 */ 155 struct ocs_sli_port_s { 156 ocs_t *ocs; /**< pointer to ocs */ 157 uint32_t tgt_id; /**< target id */ 158 uint32_t index; /**< ??? */ 159 uint32_t instance_index; 160 char display_name[OCS_DISPLAY_NAME_LENGTH]; /**< sport display name */ 161 ocs_domain_t *domain; /**< current fabric domain */ 162 uint32_t is_vport:1; /**< this SPORT is a virtual port */ 163 uint64_t wwpn; /**< WWPN from HW (host endian) */ 164 uint64_t wwnn; /**< WWNN from HW (host endian) */ 165 ocs_list_t node_list; /**< list of nodes */ 166 ocs_scsi_ini_sport_t ini_sport; /**< initiator backend private sport data */ 167 ocs_scsi_tgt_sport_t tgt_sport; /**< target backend private sport data */ 168 void *tgt_data; /**< target backend private pointer */ 169 void *ini_data; /**< initiator backend private pointer */ 170 ocs_mgmt_functions_t *mgmt_functions; 171 172 /* 173 * Members private to HW/SLI 174 */ 175 ocs_sm_ctx_t ctx; /**< state machine context */ 176 ocs_hw_t *hw; /**< pointer to HW */ 177 uint32_t indicator; /**< VPI */ 178 uint32_t fc_id; /**< FC address */ 179 ocs_dma_t dma; /**< memory for Service Parameters */ 180 181 uint8_t wwnn_str[OCS_WWN_LENGTH]; /**< WWN (ASCII) */ 182 uint64_t sli_wwpn; /**< WWPN (wire endian) */ 183 uint64_t sli_wwnn; /**< WWNN (wire endian) */ 184 uint32_t sm_free_req_pending:1; /**< Free request received while waiting for attach response */ 185 186 /* 187 * Implementation specific fields allowed here 188 */ 189 ocs_sm_ctx_t sm; /**< sport context state machine */ 190 sparse_vector_t lookup; /**< fc_id to node lookup object */ 191 ocs_list_link_t link; 192 uint32_t enable_ini:1, /**< SCSI initiator enabled for this node */ 193 enable_tgt:1, /**< SCSI target enabled for this node */ 194 enable_rscn:1, /**< This SPORT will be expecting RSCN */ 195 shutting_down:1, /**< sport in process of shutting down */ 196 p2p_winner:1; /**< TRUE if we're the point-to-point winner */ 197 ocs_sport_topology_e topology; /**< topology: fabric/p2p/unknown */ 198 uint8_t service_params[OCS_SERVICE_PARMS_LENGTH]; /**< Login parameters */ 199 uint32_t p2p_remote_port_id; /**< Remote node's port id for p2p */ 200 uint32_t p2p_port_id; /**< our port's id */ 201 202 /* List of remote node group directory entries (used by high login mode) */ 203 ocs_lock_t node_group_lock; 204 uint32_t node_group_dir_next_instance; /**< HLM next node group directory instance value */ 205 uint32_t node_group_next_instance; /**< HLM next node group instance value */ 206 ocs_list_t node_group_dir_list; 207 }; 208 209 /** 210 * @brief Fibre Channel domain object 211 * 212 * This object is a container for the various SLI components needed 213 * to connect to the domain of a FC or FCoE switch 214 */ 215 struct ocs_domain_s { 216 ocs_t *ocs; /**< pointer back to ocs */ 217 uint32_t instance_index; /**< unique instance index value */ 218 char display_name[OCS_DISPLAY_NAME_LENGTH]; /**< Node display name */ 219 ocs_list_t sport_list; /**< linked list of SLI ports */ 220 ocs_scsi_ini_domain_t ini_domain; /**< initiator backend private domain data */ 221 ocs_scsi_tgt_domain_t tgt_domain; /**< target backend private domain data */ 222 ocs_mgmt_functions_t *mgmt_functions; 223 224 /* Declarations private to HW/SLI */ 225 ocs_hw_t *hw; /**< pointer to HW */ 226 ocs_sm_ctx_t sm; /**< state machine context */ 227 uint32_t fcf; /**< FC Forwarder table index */ 228 uint32_t fcf_indicator; /**< FCFI */ 229 uint32_t vlan_id; /**< VLAN tag for this domain */ 230 uint32_t indicator; /**< VFI */ 231 ocs_dma_t dma; /**< memory for Service Parameters */ 232 uint32_t req_rediscover_fcf:1; /**< TRUE if fcf rediscover is needed (in response 233 * to Vlink Clear async event */ 234 235 /* Declarations private to FC transport */ 236 uint64_t fcf_wwn; /**< WWN for FCF/switch */ 237 ocs_list_link_t link; 238 ocs_sm_ctx_t drvsm; /**< driver domain sm context */ 239 uint32_t attached:1, /**< set true after attach completes */ 240 is_fc:1, /**< is FC */ 241 is_loop:1, /**< is loop topology */ 242 is_nlport:1, /**< is public loop */ 243 domain_found_pending:1, /**< A domain found is pending, drec is updated */ 244 req_domain_free:1, /**< True if domain object should be free'd */ 245 req_accept_frames:1, /**< set in domain state machine to enable frames */ 246 domain_notify_pend:1; /** Set in domain SM to avoid duplicate node event post */ 247 ocs_domain_record_t pending_drec; /**< Pending drec if a domain found is pending */ 248 uint8_t service_params[OCS_SERVICE_PARMS_LENGTH]; /**< any sports service parameters */ 249 uint8_t flogi_service_params[OCS_SERVICE_PARMS_LENGTH]; /**< Fabric/P2p service parameters from FLOGI */ 250 uint8_t femul_enable; /**< TRUE if Fabric Emulation mode is enabled */ 251 252 /* Declarations shared with back-ends */ 253 sparse_vector_t lookup; /**< d_id to node lookup object */ 254 ocs_lock_t lookup_lock; 255 256 ocs_sli_port_t *sport; /**< Pointer to first (physical) SLI port (also at the head of sport_list) */ 257 uint32_t sport_instance_count; /**< count of sport instances */ 258 259 /* Fabric Emulation */ 260 ocs_bitmap_t *portid_pool; 261 ocs_ns_t *ocs_ns; /*>> Directory(Name) services data */ 262 }; 263 264 /** 265 * @brief Remote Node object 266 * 267 * This object represents a connection between the SLI port and another 268 * Nx_Port on the fabric. Note this can be either a well known port such 269 * as a F_Port (i.e. ff:ff:fe) or another N_Port. 270 */ 271 struct ocs_remote_node_s { 272 /* 273 * Members private to HW/SLI 274 */ 275 uint32_t indicator; /**< RPI */ 276 uint32_t index; 277 uint32_t fc_id; /**< FC address */ 278 279 uint32_t attached:1, /**< true if attached */ 280 node_group:1, /**< true if in node group */ 281 free_group:1; /**< true if the node group should be free'd */ 282 283 ocs_sli_port_t *sport; /**< associated SLI port */ 284 285 /* 286 * Implementation specific fields allowed here 287 */ 288 void *node; /**< associated node */ 289 }; 290 291 struct ocs_remote_node_group_s { 292 /* 293 * Members private to HW/SLI 294 */ 295 uint32_t indicator; /**< RPI */ 296 uint32_t index; 297 298 /* 299 * Implementation specific fields allowed here 300 */ 301 302 uint32_t instance_index; /*<< instance index */ 303 ocs_node_group_dir_t *node_group_dir; /*<< pointer to the node group directory */ 304 ocs_list_link_t link; /*<< linked list link */ 305 }; 306 307 typedef enum { 308 OCS_NODE_SHUTDOWN_DEFAULT = 0, 309 OCS_NODE_SHUTDOWN_EXPLICIT_LOGO, 310 OCS_NODE_SHUTDOWN_IMPLICIT_LOGO, 311 } ocs_node_shutd_rsn_e; 312 313 typedef enum { 314 OCS_NODE_SEND_LS_ACC_NONE = 0, 315 OCS_NODE_SEND_LS_ACC_PLOGI, 316 OCS_NODE_SEND_LS_ACC_PRLI, 317 } ocs_node_send_ls_acc_e; 318 319 /** 320 * @brief FC Node object 321 * 322 */ 323 struct ocs_node_s { 324 ocs_t *ocs; /**< pointer back to ocs structure */ 325 uint32_t instance_index; /**< unique instance index value */ 326 char display_name[OCS_DISPLAY_NAME_LENGTH]; /**< Node display name */ 327 ocs_sport_t *sport; 328 uint32_t hold_frames:1; /**< hold incoming frames if true */ 329 ocs_rlock_t lock; /**< node wide lock */ 330 ocs_lock_t active_ios_lock; /**< active SCSI and XPORT I/O's for this node */ 331 ocs_list_t active_ios; /**< active I/O's for this node */ 332 uint32_t max_wr_xfer_size; /**< Max write IO size per phase for the transport */ 333 ocs_scsi_ini_node_t ini_node; /**< backend initiator private node data */ 334 ocs_scsi_tgt_node_t tgt_node; /**< backend target private node data */ 335 ocs_mgmt_functions_t *mgmt_functions; 336 337 /* Declarations private to HW/SLI */ 338 ocs_remote_node_t rnode; /**< Remote node */ 339 340 /* Declarations private to FC transport */ 341 ocs_sm_ctx_t sm; /**< state machine context */ 342 uint32_t evtdepth; /**< current event posting nesting depth */ 343 uint32_t req_free:1, /**< this node is to be free'd */ 344 attached:1, /**< node is attached (REGLOGIN complete) */ 345 fcp_enabled:1, /**< node is enabled to handle FCP */ 346 rscn_pending:1, /**< for name server node RSCN is pending */ 347 send_plogi:1, /**< if initiator, send PLOGI at node initialization */ 348 send_plogi_acc:1,/**< send PLOGI accept, upon completion of node attach */ 349 io_alloc_enabled:1, /**< TRUE if ocs_scsi_io_alloc() and ocs_els_io_alloc() are enabled */ 350 sent_prli:1; /**< if initiator, sent prli. */ 351 ocs_node_send_ls_acc_e send_ls_acc; /**< type of LS acc to send */ 352 ocs_io_t *ls_acc_io; /**< SCSI IO for LS acc */ 353 uint32_t ls_acc_oxid; /**< OX_ID for pending accept */ 354 uint32_t ls_acc_did; /**< D_ID for pending accept */ 355 ocs_node_shutd_rsn_e shutdown_reason;/**< reason for node shutdown */ 356 ocs_dma_t sparm_dma_buf; /**< service parameters buffer */ 357 uint8_t service_params[OCS_SERVICE_PARMS_LENGTH]; /**< plogi/acc frame from remote device */ 358 ocs_lock_t pend_frames_lock; /**< lock for inbound pending frames list */ 359 ocs_list_t pend_frames; /**< inbound pending frames list */ 360 uint32_t pend_frames_processed; /**< count of frames processed in hold frames interval */ 361 uint32_t ox_id_in_use; /**< used to verify one at a time us of ox_id */ 362 uint32_t els_retries_remaining; /**< for ELS, number of retries remaining */ 363 uint32_t els_req_cnt; /**< number of outstanding ELS requests */ 364 uint32_t els_cmpl_cnt; /**< number of outstanding ELS completions */ 365 uint32_t abort_cnt; /**< Abort counter for debugging purpose */ 366 367 char current_state_name[OCS_DISPLAY_NAME_LENGTH]; /**< current node state */ 368 char prev_state_name[OCS_DISPLAY_NAME_LENGTH]; /**< previous node state */ 369 ocs_sm_event_t current_evt; /**< current event */ 370 ocs_sm_event_t prev_evt; /**< current event */ 371 uint32_t targ:1, /**< node is target capable */ 372 init:1, /**< node is initiator capable */ 373 refound:1, /**< Handle node refound case when node is being deleted */ 374 fcp2device:1, /* FCP2 device */ 375 reserved:4, 376 fc_type:8; 377 ocs_list_t els_io_pend_list; /**< list of pending (not yet processed) ELS IOs */ 378 ocs_list_t els_io_active_list; /**< list of active (processed) ELS IOs */ 379 380 ocs_sm_function_t nodedb_state; /**< Node debugging, saved state */ 381 382 ocs_timer_t gidpt_delay_timer; /**< GIDPT delay timer */ 383 time_t time_last_gidpt_msec; /**< Start time of last target RSCN GIDPT */ 384 385 /* WWN */ 386 char wwnn[OCS_WWN_LENGTH]; /**< remote port WWN (uses iSCSI naming) */ 387 char wwpn[OCS_WWN_LENGTH]; /**< remote port WWN (uses iSCSI naming) */ 388 389 /* Statistics */ 390 uint32_t chained_io_count; /**< count of IOs with chained SGL's */ 391 392 ocs_list_link_t link; /**< node list link */ 393 394 ocs_remote_node_group_t *node_group; /**< pointer to node group (if HLM enabled) */ 395 }; 396 397 /** 398 * @brief Virtual port specification 399 * 400 * Collection of the information required to restore a virtual port across 401 * link events 402 */ 403 404 typedef struct ocs_vport_spec_s ocs_vport_spec_t; 405 struct ocs_vport_spec_s { 406 uint32_t domain_instance; /*>> instance index of this domain for the sport */ 407 uint64_t wwnn; /*>> node name */ 408 uint64_t wwpn; /*>> port name */ 409 uint32_t fc_id; /*>> port id */ 410 uint32_t enable_tgt:1, /*>> port is a target */ 411 enable_ini:1; /*>> port is an initiator */ 412 ocs_list_link_t link; /*>> link */ 413 void *tgt_data; /**< target backend pointer */ 414 void *ini_data; /**< initiator backend pointer */ 415 ocs_sport_t *sport; /**< Used to match record after attaching for update */ 416 }; 417 418 #endif /* __OCS_COMMON_H__*/ 419