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