1331766Sken/*-
2331766Sken * Copyright (c) 2017 Broadcom. All rights reserved.
3331766Sken * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries.
4331766Sken *
5331766Sken * Redistribution and use in source and binary forms, with or without
6331766Sken * modification, are permitted provided that the following conditions are met:
7331766Sken *
8331766Sken * 1. Redistributions of source code must retain the above copyright notice,
9331766Sken *    this list of conditions and the following disclaimer.
10331766Sken *
11331766Sken * 2. Redistributions in binary form must reproduce the above copyright notice,
12331766Sken *    this list of conditions and the following disclaimer in the documentation
13331766Sken *    and/or other materials provided with the distribution.
14331766Sken *
15331766Sken * 3. Neither the name of the copyright holder nor the names of its contributors
16331766Sken *    may be used to endorse or promote products derived from this software
17331766Sken *    without specific prior written permission.
18331766Sken *
19331766Sken * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20331766Sken * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21331766Sken * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22331766Sken * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23331766Sken * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24331766Sken * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25331766Sken * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26331766Sken * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27331766Sken * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28331766Sken * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29331766Sken * POSSIBILITY OF SUCH DAMAGE.
30331766Sken *
31331766Sken * $FreeBSD: stable/11/sys/dev/ocs_fc/ocs_node.h 331766 2018-03-30 15:28:25Z ken $
32331766Sken */
33331766Sken
34331766Sken/**
35331766Sken * @file
36331766Sken * OCS linux driver remote node callback declarations
37331766Sken */
38331766Sken
39331766Sken#if !defined(__OCS_NODE_H__)
40331766Sken#define __OCS_NODE_H__
41331766Sken
42331766Sken
43331766Sken#define node_sm_trace()  \
44331766Sken	do { \
45331766Sken		if (OCS_LOG_ENABLE_SM_TRACE(node->ocs)) \
46331766Sken			ocs_log_info(node->ocs, "[%s] %-20s\n", node->display_name, ocs_sm_event_name(evt)); \
47331766Sken	} while (0)
48331766Sken
49331766Sken#define node_printf(node, fmt, ...) ocs_log_debug(node->ocs, "[%s] " fmt, node->display_name, ##__VA_ARGS__)
50331766Sken
51331766Sken#define std_node_state_decl(...) \
52331766Sken	ocs_node_t *node = NULL; \
53331766Sken	ocs_t *ocs = NULL; \
54331766Sken	node = ctx->app; \
55331766Sken	ocs_assert(node, NULL); \
56331766Sken	ocs = node->ocs; \
57331766Sken	ocs_assert(ocs, NULL); \
58331766Sken	if (evt == OCS_EVT_ENTER) { \
59331766Sken		ocs_strncpy(node->current_state_name, __func__, sizeof(node->current_state_name)); \
60331766Sken	} else if (evt == OCS_EVT_EXIT) { \
61331766Sken		ocs_strncpy(node->prev_state_name, node->current_state_name, sizeof(node->prev_state_name)); \
62331766Sken		ocs_strncpy(node->current_state_name, "invalid", sizeof(node->current_state_name)); \
63331766Sken	} \
64331766Sken	node->prev_evt = node->current_evt; \
65331766Sken	node->current_evt = evt;
66331766Sken
67331766Sken#define OCS_NODEDB_PAUSE_FABRIC_LOGIN		(1U << 0)
68331766Sken#define OCS_NODEDB_PAUSE_NAMESERVER		(1U << 1)
69331766Sken#define OCS_NODEDB_PAUSE_NEW_NODES		(1U << 2)
70331766Sken
71331766Sken/**
72331766Sken * @brief Node SM IO Context Callback structure
73331766Sken *
74331766Sken * Structure used as callback argument
75331766Sken */
76331766Sken
77331766Skenstruct ocs_node_cb_s {
78331766Sken	ocs_io_t *io;			/**< SCSI IO for sending response */
79331766Sken	int32_t status;			/**< completion status */
80331766Sken	int32_t ext_status;		/**< extended completion status */
81331766Sken	ocs_hw_rq_buffer_t *header;	/**< completion header buffer */
82331766Sken	ocs_hw_rq_buffer_t *payload;	/**< completion payload buffers */
83331766Sken	ocs_io_t *els;			/**< ELS IO object */
84331766Sken};
85331766Sken
86331766Sken/**
87331766Sken * @brief hold frames in pending frame list
88331766Sken *
89331766Sken * Unsolicited receive frames are held on the node pending frame list, rather than
90331766Sken * being processed.
91331766Sken *
92331766Sken * @param node pointer to node structure
93331766Sken *
94331766Sken * @return none
95331766Sken */
96331766Sken
97331766Skenstatic inline void
98331766Skenocs_node_hold_frames(ocs_node_t *node)
99331766Sken{
100331766Sken	ocs_assert(node);
101331766Sken	node->hold_frames = TRUE;
102331766Sken}
103331766Sken
104331766Sken/**
105331766Sken * @brief accept frames
106331766Sken *
107331766Sken * Unsolicited receive frames processed rather than being held on the node
108331766Sken * pending frame list.
109331766Sken *
110331766Sken * @param node pointer to node structure
111331766Sken *
112331766Sken * @return none
113331766Sken */
114331766Sken
115331766Skenstatic inline void
116331766Skenocs_node_accept_frames(ocs_node_t *node)
117331766Sken{
118331766Sken	ocs_assert(node);
119331766Sken	node->hold_frames = FALSE;
120331766Sken}
121331766Sken
122331766Skenextern int32_t ocs_node_create_pool(ocs_t *ocs, uint32_t node_count);
123331766Skenextern void ocs_node_free_pool(ocs_t *ocs);
124331766Skenextern ocs_node_t *ocs_node_get_instance(ocs_t *ocs, uint32_t index);
125331766Sken
126331766Skenstatic inline void
127331766Skenocs_node_lock_init(ocs_node_t *node)
128331766Sken{
129331766Sken	ocs_rlock_init(node->ocs, &node->lock, "node rlock");
130331766Sken}
131331766Sken
132331766Skenstatic inline void
133331766Skenocs_node_lock_free(ocs_node_t *node)
134331766Sken{
135331766Sken	ocs_rlock_free(&node->lock);
136331766Sken}
137331766Sken
138331766Skenstatic inline int32_t
139331766Skenocs_node_lock_try(ocs_node_t *node)
140331766Sken{
141331766Sken	return ocs_rlock_try(&node->lock);
142331766Sken}
143331766Sken
144331766Skenstatic inline void
145331766Skenocs_node_lock(ocs_node_t *node)
146331766Sken{
147331766Sken	ocs_rlock_acquire(&node->lock);
148331766Sken}
149331766Skenstatic inline void
150331766Skenocs_node_unlock(ocs_node_t *node)
151331766Sken{
152331766Sken	ocs_rlock_release(&node->lock);
153331766Sken}
154331766Sken
155331766Sken/**
156331766Sken * @brief Node initiator/target enable defines
157331766Sken *
158331766Sken * All combinations of the SLI port (sport) initiator/target enable, and remote
159331766Sken * node initiator/target enable are enumerated.
160331766Sken *
161331766Sken */
162331766Sken
163331766Skentypedef enum {
164331766Sken	OCS_NODE_ENABLE_x_TO_x,
165331766Sken	OCS_NODE_ENABLE_x_TO_T,
166331766Sken	OCS_NODE_ENABLE_x_TO_I,
167331766Sken	OCS_NODE_ENABLE_x_TO_IT,
168331766Sken	OCS_NODE_ENABLE_T_TO_x,
169331766Sken	OCS_NODE_ENABLE_T_TO_T,
170331766Sken	OCS_NODE_ENABLE_T_TO_I,
171331766Sken	OCS_NODE_ENABLE_T_TO_IT,
172331766Sken	OCS_NODE_ENABLE_I_TO_x,
173331766Sken	OCS_NODE_ENABLE_I_TO_T,
174331766Sken	OCS_NODE_ENABLE_I_TO_I,
175331766Sken	OCS_NODE_ENABLE_I_TO_IT,
176331766Sken	OCS_NODE_ENABLE_IT_TO_x,
177331766Sken	OCS_NODE_ENABLE_IT_TO_T,
178331766Sken	OCS_NODE_ENABLE_IT_TO_I,
179331766Sken	OCS_NODE_ENABLE_IT_TO_IT,
180331766Sken} ocs_node_enable_e;
181331766Sken
182331766Skenstatic inline ocs_node_enable_e ocs_node_get_enable(ocs_node_t *node)
183331766Sken{
184331766Sken	uint32_t retval = 0;
185331766Sken
186331766Sken	if (node->sport->enable_ini) retval |= (1U << 3);
187331766Sken	if (node->sport->enable_tgt) retval |= (1U << 2);
188331766Sken	if (node->init) retval |= (1U << 1);
189331766Sken	if (node->targ) retval |= (1U << 0);
190331766Sken	return (ocs_node_enable_e) retval;
191331766Sken}
192331766Sken
193331766Skentypedef void* (*ocs_node_common_func_t)(const char *funcname, ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg);
194331766Sken
195331766Skenextern 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);
196331766Skenextern 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);
197331766Skenextern int32_t ocs_remote_node_cb(void *arg, ocs_hw_remote_node_event_e event, void *data);
198331766Skenextern int32_t ocs_node_attach(ocs_node_t *node);
199331766Skenextern ocs_node_t *ocs_node_find(ocs_sport_t *sport, uint32_t port_id);
200331766Skenextern ocs_node_t *ocs_node_find_wwpn(ocs_sport_t *sport, uint64_t wwpn);
201331766Skenextern void ocs_node_dump(ocs_t *ocs);
202331766Skenextern ocs_node_t *ocs_node_alloc(ocs_sport_t *sport, uint32_t port_id, uint8_t init, uint8_t targ);
203331766Skenextern int32_t ocs_node_free(ocs_node_t *node);
204331766Skenextern void ocs_node_force_free(ocs_node_t *node);
205331766Skenextern void ocs_node_fcid_display(uint32_t fc_id, char *buffer, uint32_t buffer_length);
206331766Skenextern void ocs_node_update_display_name(ocs_node_t *node);
207331766Sken
208331766Skenextern void *__ocs_node_shutdown(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg);
209331766Skenextern void * __ocs_node_wait_node_free(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg);
210331766Skenextern void *__ocs_node_wait_els_shutdown(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg);
211331766Skenextern void *__ocs_node_wait_ios_shutdown(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg);
212331766Skenextern void ocs_node_save_sparms(ocs_node_t *node, void *payload);
213331766Skenextern void ocs_node_post_event(ocs_node_t *node, ocs_sm_event_t evt, void *arg);
214331766Skenextern void ocs_node_transition(ocs_node_t *node, ocs_sm_function_t state, void *data);
215331766Skenextern void *__ocs_node_common(const char *funcname, ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg);
216331766Sken
217331766Sken
218331766Skenextern void ocs_node_initiate_cleanup(ocs_node_t *node);
219331766Skenextern int ocs_ddump_node(ocs_textbuf_t *textbuf, ocs_node_t *node);
220331766Sken
221331766Skenextern void ocs_node_build_eui_name(char *buffer, uint32_t buffer_len, uint64_t eui_name);
222331766Skenextern uint64_t ocs_node_get_wwpn(ocs_node_t *node);
223331766Skenextern uint64_t ocs_node_get_wwnn(ocs_node_t *node);
224331766Skenextern void ocs_node_abort_all_els(ocs_node_t *node);
225331766Sken
226331766Skenextern void ocs_node_pause(ocs_node_t *node, ocs_sm_function_t state);
227331766Skenextern int32_t ocs_node_resume(ocs_node_t *node);
228331766Skenextern void *__ocs_node_paused(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg);
229331766Sken
230331766Skenextern int ocs_node_active_ios_empty(ocs_node_t *node);
231331766Skenextern void ocs_node_send_ls_io_cleanup(ocs_node_t *node);
232331766Sken
233331766Skenextern int32_t ocs_node_recv_link_services_frame(ocs_node_t *node, ocs_hw_sequence_t *seq);
234331766Skenextern int32_t ocs_node_recv_abts_frame(ocs_node_t *node, ocs_hw_sequence_t *seq);
235331766Skenextern int32_t ocs_node_recv_els_frame(ocs_node_t *node, ocs_hw_sequence_t *seq);
236331766Skenextern int32_t ocs_node_recv_ct_frame(ocs_node_t *node, ocs_hw_sequence_t *seq);
237331766Skenextern int32_t ocs_node_recv_fcp_cmd(ocs_node_t *node, ocs_hw_sequence_t *seq);
238331766Skenextern int32_t ocs_node_recv_bls_no_sit(ocs_node_t *node, ocs_hw_sequence_t *seq);
239331766Sken
240331766Sken#endif
241