]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/ocs_fc/ocs_common.h
Import atf 0.22 snapshot ca73d08c3fc1ecffc1f1c97458c31ab82c12bb01
[FreeBSD/FreeBSD.git] / sys / dev / ocs_fc / ocs_common.h
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__*/