xref: /freebsd/sys/dev/ocs_fc/ocs_node.h (revision 4f52dfbb8d6c4d446500c5b097e3806ec219fbd4)
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  * OCS linux driver remote node callback declarations
37  */
38 
39 #if !defined(__OCS_NODE_H__)
40 #define __OCS_NODE_H__
41 
42 
43 #define node_sm_trace()  \
44 	do { \
45 		if (OCS_LOG_ENABLE_SM_TRACE(node->ocs)) \
46 			ocs_log_info(node->ocs, "[%s] %-20s\n", node->display_name, ocs_sm_event_name(evt)); \
47 	} while (0)
48 
49 #define node_printf(node, fmt, ...) ocs_log_debug(node->ocs, "[%s] " fmt, node->display_name, ##__VA_ARGS__)
50 
51 #define std_node_state_decl(...) \
52 	ocs_node_t *node = NULL; \
53 	ocs_t *ocs = NULL; \
54 	node = ctx->app; \
55 	ocs_assert(node, NULL); \
56 	ocs = node->ocs; \
57 	ocs_assert(ocs, NULL); \
58 	if (evt == OCS_EVT_ENTER) { \
59 		ocs_strncpy(node->current_state_name, __func__, sizeof(node->current_state_name)); \
60 	} else if (evt == OCS_EVT_EXIT) { \
61 		ocs_strncpy(node->prev_state_name, node->current_state_name, sizeof(node->prev_state_name)); \
62 		ocs_strncpy(node->current_state_name, "invalid", sizeof(node->current_state_name)); \
63 	} \
64 	node->prev_evt = node->current_evt; \
65 	node->current_evt = evt;
66 
67 #define OCS_NODEDB_PAUSE_FABRIC_LOGIN		(1U << 0)
68 #define OCS_NODEDB_PAUSE_NAMESERVER		(1U << 1)
69 #define OCS_NODEDB_PAUSE_NEW_NODES		(1U << 2)
70 
71 /**
72  * @brief Node SM IO Context Callback structure
73  *
74  * Structure used as callback argument
75  */
76 
77 struct ocs_node_cb_s {
78 	ocs_io_t *io;			/**< SCSI IO for sending response */
79 	int32_t status;			/**< completion status */
80 	int32_t ext_status;		/**< extended completion status */
81 	ocs_hw_rq_buffer_t *header;	/**< completion header buffer */
82 	ocs_hw_rq_buffer_t *payload;	/**< completion payload buffers */
83 	ocs_io_t *els;			/**< ELS IO object */
84 };
85 
86 /**
87  * @brief hold frames in pending frame list
88  *
89  * Unsolicited receive frames are held on the node pending frame list, rather than
90  * being processed.
91  *
92  * @param node pointer to node structure
93  *
94  * @return none
95  */
96 
97 static inline void
98 ocs_node_hold_frames(ocs_node_t *node)
99 {
100 	ocs_assert(node);
101 	node->hold_frames = TRUE;
102 }
103 
104 /**
105  * @brief accept frames
106  *
107  * Unsolicited receive frames processed rather than being held on the node
108  * pending frame list.
109  *
110  * @param node pointer to node structure
111  *
112  * @return none
113  */
114 
115 static inline void
116 ocs_node_accept_frames(ocs_node_t *node)
117 {
118 	ocs_assert(node);
119 	node->hold_frames = FALSE;
120 }
121 
122 extern int32_t ocs_node_create_pool(ocs_t *ocs, uint32_t node_count);
123 extern void ocs_node_free_pool(ocs_t *ocs);
124 extern ocs_node_t *ocs_node_get_instance(ocs_t *ocs, uint32_t index);
125 
126 static inline void
127 ocs_node_lock_init(ocs_node_t *node)
128 {
129 	ocs_rlock_init(node->ocs, &node->lock, "node rlock");
130 }
131 
132 static inline void
133 ocs_node_lock_free(ocs_node_t *node)
134 {
135 	ocs_rlock_free(&node->lock);
136 }
137 
138 static inline int32_t
139 ocs_node_lock_try(ocs_node_t *node)
140 {
141 	return ocs_rlock_try(&node->lock);
142 }
143 
144 static inline void
145 ocs_node_lock(ocs_node_t *node)
146 {
147 	ocs_rlock_acquire(&node->lock);
148 }
149 static inline void
150 ocs_node_unlock(ocs_node_t *node)
151 {
152 	ocs_rlock_release(&node->lock);
153 }
154 
155 /**
156  * @brief Node initiator/target enable defines
157  *
158  * All combinations of the SLI port (sport) initiator/target enable, and remote
159  * node initiator/target enable are enumerated.
160  *
161  */
162 
163 typedef enum {
164 	OCS_NODE_ENABLE_x_TO_x,
165 	OCS_NODE_ENABLE_x_TO_T,
166 	OCS_NODE_ENABLE_x_TO_I,
167 	OCS_NODE_ENABLE_x_TO_IT,
168 	OCS_NODE_ENABLE_T_TO_x,
169 	OCS_NODE_ENABLE_T_TO_T,
170 	OCS_NODE_ENABLE_T_TO_I,
171 	OCS_NODE_ENABLE_T_TO_IT,
172 	OCS_NODE_ENABLE_I_TO_x,
173 	OCS_NODE_ENABLE_I_TO_T,
174 	OCS_NODE_ENABLE_I_TO_I,
175 	OCS_NODE_ENABLE_I_TO_IT,
176 	OCS_NODE_ENABLE_IT_TO_x,
177 	OCS_NODE_ENABLE_IT_TO_T,
178 	OCS_NODE_ENABLE_IT_TO_I,
179 	OCS_NODE_ENABLE_IT_TO_IT,
180 } ocs_node_enable_e;
181 
182 static inline ocs_node_enable_e ocs_node_get_enable(ocs_node_t *node)
183 {
184 	uint32_t retval = 0;
185 
186 	if (node->sport->enable_ini) retval |= (1U << 3);
187 	if (node->sport->enable_tgt) retval |= (1U << 2);
188 	if (node->init) retval |= (1U << 1);
189 	if (node->targ) retval |= (1U << 0);
190 	return (ocs_node_enable_e) retval;
191 }
192 
193 typedef void* (*ocs_node_common_func_t)(const char *funcname, ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg);
194 
195 extern int32_t node_check_els_req(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg, uint8_t cmd, ocs_node_common_func_t node_common_func, const char *funcname);
196 extern int32_t node_check_ns_req(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg, uint32_t cmd, ocs_node_common_func_t node_common_func, const char *funcname);
197 extern int32_t ocs_remote_node_cb(void *arg, ocs_hw_remote_node_event_e event, void *data);
198 extern int32_t ocs_node_attach(ocs_node_t *node);
199 extern ocs_node_t *ocs_node_find(ocs_sport_t *sport, uint32_t port_id);
200 extern ocs_node_t *ocs_node_find_wwpn(ocs_sport_t *sport, uint64_t wwpn);
201 extern void ocs_node_dump(ocs_t *ocs);
202 extern ocs_node_t *ocs_node_alloc(ocs_sport_t *sport, uint32_t port_id, uint8_t init, uint8_t targ);
203 extern int32_t ocs_node_free(ocs_node_t *node);
204 extern void ocs_node_force_free(ocs_node_t *node);
205 extern void ocs_node_fcid_display(uint32_t fc_id, char *buffer, uint32_t buffer_length);
206 extern void ocs_node_update_display_name(ocs_node_t *node);
207 
208 extern void *__ocs_node_shutdown(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg);
209 extern void * __ocs_node_wait_node_free(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg);
210 extern void *__ocs_node_wait_els_shutdown(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg);
211 extern void *__ocs_node_wait_ios_shutdown(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg);
212 extern void ocs_node_save_sparms(ocs_node_t *node, void *payload);
213 extern void ocs_node_post_event(ocs_node_t *node, ocs_sm_event_t evt, void *arg);
214 extern void ocs_node_transition(ocs_node_t *node, ocs_sm_function_t state, void *data);
215 extern void *__ocs_node_common(const char *funcname, ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg);
216 
217 
218 extern void ocs_node_initiate_cleanup(ocs_node_t *node);
219 extern int ocs_ddump_node(ocs_textbuf_t *textbuf, ocs_node_t *node);
220 
221 extern void ocs_node_build_eui_name(char *buffer, uint32_t buffer_len, uint64_t eui_name);
222 extern uint64_t ocs_node_get_wwpn(ocs_node_t *node);
223 extern uint64_t ocs_node_get_wwnn(ocs_node_t *node);
224 extern void ocs_node_abort_all_els(ocs_node_t *node);
225 
226 extern void ocs_node_pause(ocs_node_t *node, ocs_sm_function_t state);
227 extern int32_t ocs_node_resume(ocs_node_t *node);
228 extern void *__ocs_node_paused(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg);
229 
230 extern int ocs_node_active_ios_empty(ocs_node_t *node);
231 extern void ocs_node_send_ls_io_cleanup(ocs_node_t *node);
232 
233 extern int32_t ocs_node_recv_link_services_frame(ocs_node_t *node, ocs_hw_sequence_t *seq);
234 extern int32_t ocs_node_recv_abts_frame(ocs_node_t *node, ocs_hw_sequence_t *seq);
235 extern int32_t ocs_node_recv_els_frame(ocs_node_t *node, ocs_hw_sequence_t *seq);
236 extern int32_t ocs_node_recv_ct_frame(ocs_node_t *node, ocs_hw_sequence_t *seq);
237 extern int32_t ocs_node_recv_fcp_cmd(ocs_node_t *node, ocs_hw_sequence_t *seq);
238 extern int32_t ocs_node_recv_bls_no_sit(ocs_node_t *node, ocs_hw_sequence_t *seq);
239 
240 #endif
241