xref: /freebsd/sys/dev/ocs_fc/ocs_node.h (revision 95ee2897e98f5d444f26ed2334cc7c439f9c16c6)
1*ef270ab1SKenneth D. Merry /*-
2*ef270ab1SKenneth D. Merry  * Copyright (c) 2017 Broadcom. All rights reserved.
3*ef270ab1SKenneth D. Merry  * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries.
4*ef270ab1SKenneth D. Merry  *
5*ef270ab1SKenneth D. Merry  * Redistribution and use in source and binary forms, with or without
6*ef270ab1SKenneth D. Merry  * modification, are permitted provided that the following conditions are met:
7*ef270ab1SKenneth D. Merry  *
8*ef270ab1SKenneth D. Merry  * 1. Redistributions of source code must retain the above copyright notice,
9*ef270ab1SKenneth D. Merry  *    this list of conditions and the following disclaimer.
10*ef270ab1SKenneth D. Merry  *
11*ef270ab1SKenneth D. Merry  * 2. Redistributions in binary form must reproduce the above copyright notice,
12*ef270ab1SKenneth D. Merry  *    this list of conditions and the following disclaimer in the documentation
13*ef270ab1SKenneth D. Merry  *    and/or other materials provided with the distribution.
14*ef270ab1SKenneth D. Merry  *
15*ef270ab1SKenneth D. Merry  * 3. Neither the name of the copyright holder nor the names of its contributors
16*ef270ab1SKenneth D. Merry  *    may be used to endorse or promote products derived from this software
17*ef270ab1SKenneth D. Merry  *    without specific prior written permission.
18*ef270ab1SKenneth D. Merry  *
19*ef270ab1SKenneth D. Merry  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20*ef270ab1SKenneth D. Merry  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*ef270ab1SKenneth D. Merry  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*ef270ab1SKenneth D. Merry  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23*ef270ab1SKenneth D. Merry  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*ef270ab1SKenneth D. Merry  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*ef270ab1SKenneth D. Merry  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*ef270ab1SKenneth D. Merry  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*ef270ab1SKenneth D. Merry  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*ef270ab1SKenneth D. Merry  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*ef270ab1SKenneth D. Merry  * POSSIBILITY OF SUCH DAMAGE.
30*ef270ab1SKenneth D. Merry  */
31*ef270ab1SKenneth D. Merry 
32*ef270ab1SKenneth D. Merry /**
33*ef270ab1SKenneth D. Merry  * @file
34*ef270ab1SKenneth D. Merry  * OCS linux driver remote node callback declarations
35*ef270ab1SKenneth D. Merry  */
36*ef270ab1SKenneth D. Merry 
37*ef270ab1SKenneth D. Merry #if !defined(__OCS_NODE_H__)
38*ef270ab1SKenneth D. Merry #define __OCS_NODE_H__
39*ef270ab1SKenneth D. Merry 
40*ef270ab1SKenneth D. Merry #define node_sm_trace()  \
41*ef270ab1SKenneth D. Merry 	do { \
42*ef270ab1SKenneth D. Merry 		if (OCS_LOG_ENABLE_SM_TRACE(node->ocs)) \
43*ef270ab1SKenneth D. Merry 			ocs_log_info(node->ocs, "[%s] %-20s\n", node->display_name, ocs_sm_event_name(evt)); \
44*ef270ab1SKenneth D. Merry 	} while (0)
45*ef270ab1SKenneth D. Merry 
46*ef270ab1SKenneth D. Merry #define node_printf(node, fmt, ...) ocs_log_debug(node->ocs, "[%s] " fmt, node->display_name, ##__VA_ARGS__)
47*ef270ab1SKenneth D. Merry 
48*ef270ab1SKenneth D. Merry #define std_node_state_decl(...) \
49*ef270ab1SKenneth D. Merry 	ocs_node_t *node = NULL; \
50*ef270ab1SKenneth D. Merry 	ocs_t *ocs = NULL; \
51*ef270ab1SKenneth D. Merry 	node = ctx->app; \
52*ef270ab1SKenneth D. Merry 	ocs_assert(node, NULL); \
53*ef270ab1SKenneth D. Merry 	ocs = node->ocs; \
54*ef270ab1SKenneth D. Merry 	ocs_assert(ocs, NULL); \
55*ef270ab1SKenneth D. Merry 	if (evt == OCS_EVT_ENTER) { \
56*ef270ab1SKenneth D. Merry 		ocs_strncpy(node->current_state_name, __func__, sizeof(node->current_state_name)); \
57*ef270ab1SKenneth D. Merry 	} else if (evt == OCS_EVT_EXIT) { \
58*ef270ab1SKenneth D. Merry 		ocs_strncpy(node->prev_state_name, node->current_state_name, sizeof(node->prev_state_name)); \
59*ef270ab1SKenneth D. Merry 		ocs_strncpy(node->current_state_name, "invalid", sizeof(node->current_state_name)); \
60*ef270ab1SKenneth D. Merry 	} \
61*ef270ab1SKenneth D. Merry 	node->prev_evt = node->current_evt; \
62*ef270ab1SKenneth D. Merry 	node->current_evt = evt;
63*ef270ab1SKenneth D. Merry 
64*ef270ab1SKenneth D. Merry #define OCS_NODEDB_PAUSE_FABRIC_LOGIN		(1U << 0)
65*ef270ab1SKenneth D. Merry #define OCS_NODEDB_PAUSE_NAMESERVER		(1U << 1)
66*ef270ab1SKenneth D. Merry #define OCS_NODEDB_PAUSE_NEW_NODES		(1U << 2)
67*ef270ab1SKenneth D. Merry 
68*ef270ab1SKenneth D. Merry /**
69*ef270ab1SKenneth D. Merry  * @brief Node SM IO Context Callback structure
70*ef270ab1SKenneth D. Merry  *
71*ef270ab1SKenneth D. Merry  * Structure used as callback argument
72*ef270ab1SKenneth D. Merry  */
73*ef270ab1SKenneth D. Merry 
74*ef270ab1SKenneth D. Merry struct ocs_node_cb_s {
75*ef270ab1SKenneth D. Merry 	ocs_io_t *io;			/**< SCSI IO for sending response */
76*ef270ab1SKenneth D. Merry 	int32_t status;			/**< completion status */
77*ef270ab1SKenneth D. Merry 	int32_t ext_status;		/**< extended completion status */
78*ef270ab1SKenneth D. Merry 	ocs_hw_rq_buffer_t *header;	/**< completion header buffer */
79*ef270ab1SKenneth D. Merry 	ocs_hw_rq_buffer_t *payload;	/**< completion payload buffers */
80*ef270ab1SKenneth D. Merry 	ocs_io_t *els;			/**< ELS IO object */
81*ef270ab1SKenneth D. Merry };
82*ef270ab1SKenneth D. Merry 
83*ef270ab1SKenneth D. Merry /**
84*ef270ab1SKenneth D. Merry  * @brief hold frames in pending frame list
85*ef270ab1SKenneth D. Merry  *
86*ef270ab1SKenneth D. Merry  * Unsolicited receive frames are held on the node pending frame list, rather than
87*ef270ab1SKenneth D. Merry  * being processed.
88*ef270ab1SKenneth D. Merry  *
89*ef270ab1SKenneth D. Merry  * @param node pointer to node structure
90*ef270ab1SKenneth D. Merry  *
91*ef270ab1SKenneth D. Merry  * @return none
92*ef270ab1SKenneth D. Merry  */
93*ef270ab1SKenneth D. Merry 
94*ef270ab1SKenneth D. Merry static inline void
ocs_node_hold_frames(ocs_node_t * node)95*ef270ab1SKenneth D. Merry ocs_node_hold_frames(ocs_node_t *node)
96*ef270ab1SKenneth D. Merry {
97*ef270ab1SKenneth D. Merry 	ocs_assert(node);
98*ef270ab1SKenneth D. Merry 	node->hold_frames = TRUE;
99*ef270ab1SKenneth D. Merry }
100*ef270ab1SKenneth D. Merry 
101*ef270ab1SKenneth D. Merry /**
102*ef270ab1SKenneth D. Merry  * @brief accept frames
103*ef270ab1SKenneth D. Merry  *
104*ef270ab1SKenneth D. Merry  * Unsolicited receive frames processed rather than being held on the node
105*ef270ab1SKenneth D. Merry  * pending frame list.
106*ef270ab1SKenneth D. Merry  *
107*ef270ab1SKenneth D. Merry  * @param node pointer to node structure
108*ef270ab1SKenneth D. Merry  *
109*ef270ab1SKenneth D. Merry  * @return none
110*ef270ab1SKenneth D. Merry  */
111*ef270ab1SKenneth D. Merry 
112*ef270ab1SKenneth D. Merry static inline void
ocs_node_accept_frames(ocs_node_t * node)113*ef270ab1SKenneth D. Merry ocs_node_accept_frames(ocs_node_t *node)
114*ef270ab1SKenneth D. Merry {
115*ef270ab1SKenneth D. Merry 	ocs_assert(node);
116*ef270ab1SKenneth D. Merry 	node->hold_frames = FALSE;
117*ef270ab1SKenneth D. Merry }
118*ef270ab1SKenneth D. Merry 
119*ef270ab1SKenneth D. Merry extern int32_t ocs_node_create_pool(ocs_t *ocs, uint32_t node_count);
120*ef270ab1SKenneth D. Merry extern void ocs_node_free_pool(ocs_t *ocs);
121*ef270ab1SKenneth D. Merry extern ocs_node_t *ocs_node_get_instance(ocs_t *ocs, uint32_t index);
122*ef270ab1SKenneth D. Merry 
123*ef270ab1SKenneth D. Merry static inline void
ocs_node_lock_init(ocs_node_t * node)124*ef270ab1SKenneth D. Merry ocs_node_lock_init(ocs_node_t *node)
125*ef270ab1SKenneth D. Merry {
126*ef270ab1SKenneth D. Merry 	ocs_rlock_init(node->ocs, &node->lock, "node rlock");
127*ef270ab1SKenneth D. Merry }
128*ef270ab1SKenneth D. Merry 
129*ef270ab1SKenneth D. Merry static inline void
ocs_node_lock_free(ocs_node_t * node)130*ef270ab1SKenneth D. Merry ocs_node_lock_free(ocs_node_t *node)
131*ef270ab1SKenneth D. Merry {
132*ef270ab1SKenneth D. Merry 	ocs_rlock_free(&node->lock);
133*ef270ab1SKenneth D. Merry }
134*ef270ab1SKenneth D. Merry 
135*ef270ab1SKenneth D. Merry static inline int32_t
ocs_node_lock_try(ocs_node_t * node)136*ef270ab1SKenneth D. Merry ocs_node_lock_try(ocs_node_t *node)
137*ef270ab1SKenneth D. Merry {
138*ef270ab1SKenneth D. Merry 	return ocs_rlock_try(&node->lock);
139*ef270ab1SKenneth D. Merry }
140*ef270ab1SKenneth D. Merry 
141*ef270ab1SKenneth D. Merry static inline void
ocs_node_lock(ocs_node_t * node)142*ef270ab1SKenneth D. Merry ocs_node_lock(ocs_node_t *node)
143*ef270ab1SKenneth D. Merry {
144*ef270ab1SKenneth D. Merry 	ocs_rlock_acquire(&node->lock);
145*ef270ab1SKenneth D. Merry }
146*ef270ab1SKenneth D. Merry static inline void
ocs_node_unlock(ocs_node_t * node)147*ef270ab1SKenneth D. Merry ocs_node_unlock(ocs_node_t *node)
148*ef270ab1SKenneth D. Merry {
149*ef270ab1SKenneth D. Merry 	ocs_rlock_release(&node->lock);
150*ef270ab1SKenneth D. Merry }
151*ef270ab1SKenneth D. Merry 
152*ef270ab1SKenneth D. Merry /**
153*ef270ab1SKenneth D. Merry  * @brief Node initiator/target enable defines
154*ef270ab1SKenneth D. Merry  *
155*ef270ab1SKenneth D. Merry  * All combinations of the SLI port (sport) initiator/target enable, and remote
156*ef270ab1SKenneth D. Merry  * node initiator/target enable are enumerated.
157*ef270ab1SKenneth D. Merry  *
158*ef270ab1SKenneth D. Merry  */
159*ef270ab1SKenneth D. Merry 
160*ef270ab1SKenneth D. Merry typedef enum {
161*ef270ab1SKenneth D. Merry 	OCS_NODE_ENABLE_x_TO_x,
162*ef270ab1SKenneth D. Merry 	OCS_NODE_ENABLE_x_TO_T,
163*ef270ab1SKenneth D. Merry 	OCS_NODE_ENABLE_x_TO_I,
164*ef270ab1SKenneth D. Merry 	OCS_NODE_ENABLE_x_TO_IT,
165*ef270ab1SKenneth D. Merry 	OCS_NODE_ENABLE_T_TO_x,
166*ef270ab1SKenneth D. Merry 	OCS_NODE_ENABLE_T_TO_T,
167*ef270ab1SKenneth D. Merry 	OCS_NODE_ENABLE_T_TO_I,
168*ef270ab1SKenneth D. Merry 	OCS_NODE_ENABLE_T_TO_IT,
169*ef270ab1SKenneth D. Merry 	OCS_NODE_ENABLE_I_TO_x,
170*ef270ab1SKenneth D. Merry 	OCS_NODE_ENABLE_I_TO_T,
171*ef270ab1SKenneth D. Merry 	OCS_NODE_ENABLE_I_TO_I,
172*ef270ab1SKenneth D. Merry 	OCS_NODE_ENABLE_I_TO_IT,
173*ef270ab1SKenneth D. Merry 	OCS_NODE_ENABLE_IT_TO_x,
174*ef270ab1SKenneth D. Merry 	OCS_NODE_ENABLE_IT_TO_T,
175*ef270ab1SKenneth D. Merry 	OCS_NODE_ENABLE_IT_TO_I,
176*ef270ab1SKenneth D. Merry 	OCS_NODE_ENABLE_IT_TO_IT,
177*ef270ab1SKenneth D. Merry } ocs_node_enable_e;
178*ef270ab1SKenneth D. Merry 
ocs_node_get_enable(ocs_node_t * node)179*ef270ab1SKenneth D. Merry static inline ocs_node_enable_e ocs_node_get_enable(ocs_node_t *node)
180*ef270ab1SKenneth D. Merry {
181*ef270ab1SKenneth D. Merry 	uint32_t retval = 0;
182*ef270ab1SKenneth D. Merry 
183*ef270ab1SKenneth D. Merry 	if (node->sport->enable_ini) retval |= (1U << 3);
184*ef270ab1SKenneth D. Merry 	if (node->sport->enable_tgt) retval |= (1U << 2);
185*ef270ab1SKenneth D. Merry 	if (node->init) retval |= (1U << 1);
186*ef270ab1SKenneth D. Merry 	if (node->targ) retval |= (1U << 0);
187*ef270ab1SKenneth D. Merry 	return (ocs_node_enable_e) retval;
188*ef270ab1SKenneth D. Merry }
189*ef270ab1SKenneth D. Merry 
190*ef270ab1SKenneth D. Merry typedef void* (*ocs_node_common_func_t)(const char *funcname, ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg);
191*ef270ab1SKenneth D. Merry 
192*ef270ab1SKenneth D. Merry 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);
193*ef270ab1SKenneth D. Merry 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);
194*ef270ab1SKenneth D. Merry extern int32_t ocs_remote_node_cb(void *arg, ocs_hw_remote_node_event_e event, void *data);
195*ef270ab1SKenneth D. Merry extern int32_t ocs_node_attach(ocs_node_t *node);
196*ef270ab1SKenneth D. Merry extern ocs_node_t *ocs_node_find(ocs_sport_t *sport, uint32_t port_id);
197*ef270ab1SKenneth D. Merry extern ocs_node_t *ocs_node_find_wwpn(ocs_sport_t *sport, uint64_t wwpn);
198*ef270ab1SKenneth D. Merry extern void ocs_node_dump(ocs_t *ocs);
199*ef270ab1SKenneth D. Merry extern ocs_node_t *ocs_node_alloc(ocs_sport_t *sport, uint32_t port_id, uint8_t init, uint8_t targ);
200*ef270ab1SKenneth D. Merry extern int32_t ocs_node_free(ocs_node_t *node);
201*ef270ab1SKenneth D. Merry extern void ocs_node_force_free(ocs_node_t *node);
202*ef270ab1SKenneth D. Merry extern void ocs_node_fcid_display(uint32_t fc_id, char *buffer, uint32_t buffer_length);
203*ef270ab1SKenneth D. Merry extern void ocs_node_update_display_name(ocs_node_t *node);
204*ef270ab1SKenneth D. Merry 
205*ef270ab1SKenneth D. Merry extern void *__ocs_node_shutdown(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg);
206*ef270ab1SKenneth D. Merry extern void * __ocs_node_wait_node_free(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg);
207*ef270ab1SKenneth D. Merry extern void *__ocs_node_wait_els_shutdown(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg);
208*ef270ab1SKenneth D. Merry extern void *__ocs_node_wait_ios_shutdown(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg);
209*ef270ab1SKenneth D. Merry extern void ocs_node_save_sparms(ocs_node_t *node, void *payload);
210*ef270ab1SKenneth D. Merry extern void ocs_node_post_event(ocs_node_t *node, ocs_sm_event_t evt, void *arg);
211*ef270ab1SKenneth D. Merry extern void ocs_node_transition(ocs_node_t *node, ocs_sm_function_t state, void *data);
212*ef270ab1SKenneth D. Merry extern void *__ocs_node_common(const char *funcname, ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg);
213*ef270ab1SKenneth D. Merry 
214*ef270ab1SKenneth D. Merry extern void ocs_node_initiate_cleanup(ocs_node_t *node);
215*ef270ab1SKenneth D. Merry extern int ocs_ddump_node(ocs_textbuf_t *textbuf, ocs_node_t *node);
216*ef270ab1SKenneth D. Merry 
217*ef270ab1SKenneth D. Merry extern void ocs_node_build_eui_name(char *buffer, uint32_t buffer_len, uint64_t eui_name);
218*ef270ab1SKenneth D. Merry extern uint64_t ocs_node_get_wwpn(ocs_node_t *node);
219*ef270ab1SKenneth D. Merry extern uint64_t ocs_node_get_wwnn(ocs_node_t *node);
220*ef270ab1SKenneth D. Merry extern void ocs_node_abort_all_els(ocs_node_t *node);
221*ef270ab1SKenneth D. Merry 
222*ef270ab1SKenneth D. Merry extern void ocs_node_pause(ocs_node_t *node, ocs_sm_function_t state);
223*ef270ab1SKenneth D. Merry extern int32_t ocs_node_resume(ocs_node_t *node);
224*ef270ab1SKenneth D. Merry extern void *__ocs_node_paused(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg);
225*ef270ab1SKenneth D. Merry 
226*ef270ab1SKenneth D. Merry extern int ocs_node_active_ios_empty(ocs_node_t *node);
227*ef270ab1SKenneth D. Merry extern void ocs_node_send_ls_io_cleanup(ocs_node_t *node);
228*ef270ab1SKenneth D. Merry 
229*ef270ab1SKenneth D. Merry extern int32_t ocs_node_recv_link_services_frame(ocs_node_t *node, ocs_hw_sequence_t *seq);
230*ef270ab1SKenneth D. Merry extern int32_t ocs_node_recv_abts_frame(ocs_node_t *node, ocs_hw_sequence_t *seq);
231*ef270ab1SKenneth D. Merry extern int32_t ocs_node_recv_els_frame(ocs_node_t *node, ocs_hw_sequence_t *seq);
232*ef270ab1SKenneth D. Merry extern int32_t ocs_node_recv_ct_frame(ocs_node_t *node, ocs_hw_sequence_t *seq);
233*ef270ab1SKenneth D. Merry extern int32_t ocs_node_recv_fcp_cmd(ocs_node_t *node, ocs_hw_sequence_t *seq);
234*ef270ab1SKenneth D. Merry extern int32_t ocs_node_recv_bls_no_sit(ocs_node_t *node, ocs_hw_sequence_t *seq);
235*ef270ab1SKenneth D. Merry 
236*ef270ab1SKenneth D. Merry #endif
237